diff --git a/src/inventory/anvil_inventory.rs b/src/inventory/anvil.rs similarity index 100% rename from src/inventory/anvil_inventory.rs rename to src/inventory/anvil.rs diff --git a/src/inventory/beacon_inventory.rs b/src/inventory/beacon.rs similarity index 100% rename from src/inventory/beacon_inventory.rs rename to src/inventory/beacon.rs diff --git a/src/inventory/brewing_stand_inventory.rs b/src/inventory/brewing_stand.rs similarity index 87% rename from src/inventory/brewing_stand_inventory.rs rename to src/inventory/brewing_stand.rs index 6fb8bc0b..705ddfef 100644 --- a/src/inventory/brewing_stand_inventory.rs +++ b/src/inventory/brewing_stand.rs @@ -19,7 +19,6 @@ pub struct BrewingStandInventory { id: i32, client_state_id: i16, brew_time: u16, - last_brew_time: u16, fuel_time: u8, dirty: bool, } @@ -47,8 +46,8 @@ impl BrewingStandInventory { client_state_id: 0, name, id, - brew_time: 400, - last_brew_time: 0, + // brew progress in % + brew_time: 0, fuel_time: 0, dirty: true, } @@ -62,10 +61,7 @@ impl Inventory for BrewingStandInventory { fn handle_property_packet(&mut self, property: i16, value: i16) { match property { - 0 => { - self.last_brew_time = self.brew_time; - self.brew_time = value as u16; - } + 0 => self.brew_time = ((400 - value as u16) / 4) % 100, 1 => self.fuel_time = value as u8, _ => warn!("server sent invalid data for brewing stand"), } @@ -179,7 +175,10 @@ impl Inventory for BrewingStandInventory { top_left_x + 60.0 * icon_scale, top_left_y + 6.0 * icon_scale, ) - .text(self.name.to_string()) + .text(match self.name.as_str() { + "container.brewing" => "Brewing Stand".to_owned(), + name => name.to_owned(), + }) .colour((64, 64, 64, 255)) .shadow(false) .create(ui_container), @@ -209,9 +208,10 @@ impl Inventory for BrewingStandInventory { .unwrap() .borrow_mut(); fuel_bar.width = self.fuel_time as f64 * 0.9 * icon_scale; - fuel_bar.texture_coords.3 = fuel_bar.width / icon_scale; + // fuel_bar.texture_coords.2 = fuel_bar.width / icon_scale; } + dbg!(self.brew_time); { let mut arrow = inventory_window .elements @@ -220,26 +220,20 @@ impl Inventory for BrewingStandInventory { .get_mut(3) .unwrap() .borrow_mut(); - arrow.height = (400 - self.brew_time) as f64 * icon_scale * (28.0 / 400.0); + arrow.height = (self.brew_time) as f64 * icon_scale * (28.0 / 100.0); arrow.texture_coords.3 = arrow.height / icon_scale; } // bubble animation - if self.last_brew_time != self.brew_time { - let mut bubbles = inventory_window - .elements - .first_mut() - .unwrap() - .get_mut(2) - .unwrap() - .borrow_mut(); - bubbles.height += 1.0 * icon_scale; - bubbles.texture_coords.3 += 1.0; - if bubbles.texture_coords.3 >= 29.0 { - bubbles.height = 0.0; - bubbles.texture_coords.3 = 0.0; - } - } + let mut bubbles = inventory_window + .elements + .first_mut() + .unwrap() + .get_mut(2) + .unwrap() + .borrow_mut(); + bubbles.height = (self.brew_time % 10) as f64 * icon_scale * (29.0 / 10.0); + bubbles.texture_coords.3 = bubbles.height / icon_scale; } } diff --git a/src/inventory/chest_inventory.rs b/src/inventory/chest.rs similarity index 100% rename from src/inventory/chest_inventory.rs rename to src/inventory/chest.rs diff --git a/src/inventory/crafting_table_inventory.rs b/src/inventory/crafting_table.rs similarity index 100% rename from src/inventory/crafting_table_inventory.rs rename to src/inventory/crafting_table.rs diff --git a/src/inventory/dropper_inventory.rs b/src/inventory/dropper.rs similarity index 99% rename from src/inventory/dropper_inventory.rs rename to src/inventory/dropper.rs index b661efe9..7ccf5244 100644 --- a/src/inventory/dropper_inventory.rs +++ b/src/inventory/dropper.rs @@ -115,6 +115,7 @@ impl Inventory for DropperInventory { let title = match self.name.as_str() { "container.dispenser" => "Dispenser", "container.dropper" => "Dropper", + "container.hopper" => "Hopper", name => name, }; let title_offset = renderer.ui.lock().size_of_string(title) / 4.0; diff --git a/src/inventory/enchanting_table_inventory.rs b/src/inventory/enchanting_table.rs similarity index 99% rename from src/inventory/enchanting_table_inventory.rs rename to src/inventory/enchanting_table.rs index b8e2ab29..f5e38635 100644 --- a/src/inventory/enchanting_table_inventory.rs +++ b/src/inventory/enchanting_table.rs @@ -148,8 +148,8 @@ impl Inventory for EnchantmentTableInventory { if slot_id == 1 && is_lapis_or_none(&item) { self.slots.set_item(slot_id, item); - self.dirty = true; } + self.dirty = true; } fn get_slot(&self, x: f64, y: f64) -> Option { @@ -317,6 +317,7 @@ impl Inventory for EnchantmentTableInventory { ) { self.slots.tick(renderer, ui_container, inventory_window, 1); if self.dirty { + self.dirty = false; for i in 0..3 { if self.button_data[i].level_required.is_some() || self.button_data[i].enchantment_level.is_some() @@ -437,7 +438,6 @@ impl Inventory for EnchantmentTableInventory { .text = "".to_string(); } } - self.dirty = false; } } diff --git a/src/inventory/furnace_inventory.rs b/src/inventory/furnace.rs similarity index 100% rename from src/inventory/furnace_inventory.rs rename to src/inventory/furnace.rs diff --git a/src/inventory/grindstone.rs b/src/inventory/grindstone.rs new file mode 100644 index 00000000..c63c0450 --- /dev/null +++ b/src/inventory/grindstone.rs @@ -0,0 +1,163 @@ +use crate::inventory::slot_mapping::SlotMapping; +use crate::inventory::{Inventory, InventoryType, Item}; +use crate::render::hud::Hud; +use crate::render::inventory::InventoryWindow; +use crate::render::Renderer; +use crate::ui; +use crate::ui::{Container, HAttach, VAttach}; +use std::sync::Arc; + +use parking_lot::RwLock; + +const WINDOW_WIDTH: i32 = 176; +const WINDOW_HEIGHT: i32 = 166; + +pub struct GrindStoneInventory { + slots: SlotMapping, + client_state_id: i16, + id: i32, + dirty: bool, +} + +impl GrindStoneInventory { + pub fn new(renderer: &Arc, base_slots: Arc>, id: i32) -> Self { + let mut slots = SlotMapping::new((WINDOW_WIDTH, WINDOW_HEIGHT)); + slots.set_child(base_slots, (8, 84), (3..39).collect()); + + slots.add_slot(0, (49, 19)); + slots.add_slot(1, (49, 40)); + slots.add_slot(2, (129, 34)); + + slots.update_icons(renderer, (0, 0), None); + + Self { + slots, + client_state_id: 0, + id, + dirty: true, + } + } +} + +impl Inventory for GrindStoneInventory { + fn size(&self) -> u16 { + self.slots.size() + } + + fn handle_property_packet(&mut self, _property: i16, _value: i16) {} + + fn id(&self) -> i32 { + self.id + } + + fn get_client_state_id(&self) -> i16 { + self.client_state_id + } + + fn set_client_state_id(&mut self, client_state_id: i16) { + self.dirty = true; + self.client_state_id = client_state_id; + } + + fn get_item(&self, slot_id: u16) -> Option { + self.slots.get_item(slot_id) + } + + fn set_item(&mut self, slot_id: u16, item: Option) { + self.slots.set_item(slot_id, item); + self.dirty = true; + } + + fn get_slot(&self, x: f64, y: f64) -> Option { + self.slots.get_slot(x, y) + } + + fn init( + &mut self, + renderer: &Arc, + ui_container: &mut Container, + inventory_window: &mut InventoryWindow, + ) { + inventory_window.elements.push(vec![]); // Window texture + inventory_window.elements.push(vec![]); // Enchanting slots + inventory_window.elements.push(vec![]); // Base slots + inventory_window.text_elements.push(vec![]); + + let basic_elements = inventory_window.elements.get_mut(0).unwrap(); + let basic_text_elements = inventory_window.text_elements.get_mut(0).unwrap(); + let icon_scale = Hud::icon_scale(renderer); + + let top_left_x = + renderer.screen_data.read().center().0 as f64 - icon_scale * WINDOW_WIDTH as f64 / 2.0; + let top_left_y = + renderer.screen_data.read().center().1 as f64 - icon_scale * WINDOW_HEIGHT as f64 / 2.0; + basic_elements.push( + ui::ImageBuilder::new() + .texture_coords((0.0, 0.0, 176.0, 166.0)) + .position(top_left_x, top_left_y) + .alignment(ui::VAttach::Top, ui::HAttach::Left) + .size(icon_scale * 176.0, icon_scale * 166.0) + .texture("minecraft:gui/container/grindstone") + .create(ui_container), + ); + + basic_text_elements.push( + ui::TextBuilder::new() + .alignment(VAttach::Top, HAttach::Left) + .scale_x(icon_scale / 2.0) + .scale_y(icon_scale / 2.0) + .position( + top_left_x + 11.0 * icon_scale, + top_left_y + 5.0 * icon_scale, + ) + .text("Repair & Disenchant") + .colour((64, 64, 64, 255)) + .shadow(false) + .create(ui_container), + ); + + basic_elements.push( + ui::ImageBuilder::new() + .texture("minecraft:gui/container/grindstone") + .texture_coords((176.0, 0.0, 28.0, 21.0)) + .position( + top_left_x + 92.0 * icon_scale, + top_left_y + 31.0 * icon_scale, + ) + .alignment(ui::VAttach::Top, ui::HAttach::Left) + .size(icon_scale * 28.0, icon_scale * 21.0) + .create(ui_container), + ); + + self.slots.update_icons(renderer, (0, 0), None); + } + + fn tick( + &mut self, + renderer: &Arc, + ui_container: &mut Container, + inventory_window: &mut InventoryWindow, + ) { + self.slots.tick(renderer, ui_container, inventory_window, 1); + if self.dirty { + let mut arrow_crossed = inventory_window + .elements + .get_mut(0) + .unwrap() + .get_mut(1) + .unwrap() + .borrow_mut(); + if self.slots.get_item(2).is_none() + && (self.slots.get_item(0).is_some() || self.slots.get_item(1).is_some()) + { + arrow_crossed.colour.3 = 255; + } else { + arrow_crossed.colour.3 = 0; + } + } + } + + fn ty(&self) -> InventoryType { + InventoryType::Grindstone + } +} diff --git a/src/inventory/mod.rs b/src/inventory/mod.rs index bb117b6e..feb63ffa 100644 --- a/src/inventory/mod.rs +++ b/src/inventory/mod.rs @@ -1,23 +1,25 @@ -pub mod anvil_inventory; -pub mod beacon_inventory; -pub mod brewing_stand_inventory; -pub mod chest_inventory; -pub mod crafting_table_inventory; -pub mod dropper_inventory; -pub mod enchanting_table_inventory; -pub mod furnace_inventory; +pub mod anvil; +pub mod beacon; +pub mod brewing_stand; +pub mod chest; +pub mod crafting_table; +pub mod dropper; +pub mod enchanting_table; +pub mod furnace; +pub mod grindstone; pub(crate) mod material; pub mod player_inventory; pub mod slot_mapping; -use crate::inventory::anvil_inventory::AnvilInventory; -use crate::inventory::beacon_inventory::BeaconInventory; -use crate::inventory::brewing_stand_inventory::BrewingStandInventory; -use crate::inventory::chest_inventory::ChestInventory; -use crate::inventory::crafting_table_inventory::CraftingTableInventory; -use crate::inventory::dropper_inventory::DropperInventory; -use crate::inventory::enchanting_table_inventory::EnchantmentTableInventory; -use crate::inventory::furnace_inventory::FurnaceInventory; +use crate::inventory::anvil::AnvilInventory; +use crate::inventory::beacon::BeaconInventory; +use crate::inventory::brewing_stand::BrewingStandInventory; +use crate::inventory::chest::ChestInventory; +use crate::inventory::crafting_table::CraftingTableInventory; +use crate::inventory::dropper::DropperInventory; +use crate::inventory::enchanting_table::EnchantmentTableInventory; +use crate::inventory::furnace::FurnaceInventory; +use crate::inventory::grindstone::GrindStoneInventory; use crate::inventory::player_inventory::PlayerInventory; use crate::inventory::slot_mapping::SlotMapping; use crate::render::hud::{Hud, HudContext}; @@ -99,52 +101,63 @@ pub fn inventory_from_type( base_slots: Arc>, id: i32, ) -> Option>> { - match ty { + Some(match ty { /*InventoryType::Internal => {} InventoryType::Main => {}*/ - InventoryType::Chest(rows) => Some(Arc::new(RwLock::new(ChestInventory::new( + InventoryType::Chest(rows) => Arc::new(RwLock::new(ChestInventory::new( renderer, base_slots, rows, title.to_string(), id, - )))), - InventoryType::CraftingTable => Some(Arc::new(RwLock::new(CraftingTableInventory::new( + ))), + InventoryType::CraftingTable => Arc::new(RwLock::new(CraftingTableInventory::new( renderer, base_slots, id, - )))), - InventoryType::Dropper => Some(Arc::new(RwLock::new(DropperInventory::new( + ))), + + InventoryType::Dropper => Arc::new(RwLock::new(DropperInventory::new( + renderer, + base_slots, + title.to_string(), + id, + ))), + InventoryType::Hopper => Arc::new(RwLock::new(DropperInventory::new( renderer, base_slots, title.to_string(), id, - )))), - InventoryType::Furnace => Some(Arc::new(RwLock::new(FurnaceInventory::new( + ))), + InventoryType::Furnace => Arc::new(RwLock::new(FurnaceInventory::new( renderer, base_slots, ty, id, - )))), - InventoryType::Smoker => Some(Arc::new(RwLock::new(FurnaceInventory::new( + ))), + InventoryType::Smoker => Arc::new(RwLock::new(FurnaceInventory::new( renderer, base_slots, ty, id, - )))), - InventoryType::BlastFurnace => Some(Arc::new(RwLock::new(FurnaceInventory::new( + ))), + InventoryType::BlastFurnace => Arc::new(RwLock::new(FurnaceInventory::new( renderer, base_slots, ty, id, - )))), - InventoryType::EnchantingTable => Some(Arc::new(RwLock::new( - EnchantmentTableInventory::new(renderer, base_slots, title.to_string(), id), ))), - InventoryType::Anvil => Some(Arc::new(RwLock::new(AnvilInventory::new( - renderer, base_slots, id, - )))), - InventoryType::Beacon => Some(Arc::new(RwLock::new(BeaconInventory::new( - renderer, base_slots, id, - )))), - InventoryType::BrewingStand => Some(Arc::new(RwLock::new(BrewingStandInventory::new( + InventoryType::EnchantingTable => Arc::new(RwLock::new(EnchantmentTableInventory::new( + renderer, + base_slots, + title.to_string(), + id, + ))), + InventoryType::Anvil => { + Arc::new(RwLock::new(AnvilInventory::new(renderer, base_slots, id))) + } + InventoryType::Beacon => { + Arc::new(RwLock::new(BeaconInventory::new(renderer, base_slots, id))) + } + InventoryType::BrewingStand => Arc::new(RwLock::new(BrewingStandInventory::new( renderer, base_slots, title.to_string(), id, - )))), + ))), + InventoryType::Grindstone => Arc::new(RwLock::new(GrindStoneInventory::new( + renderer, base_slots, id, + ))), /* - InventoryType::Grindstone => {} - InventoryType::Hopper => {} InventoryType::Lectern => {} InventoryType::Loom => {} InventoryType::Merchant => {} @@ -153,8 +166,8 @@ pub fn inventory_from_type( InventoryType::CartographyTable => {} InventoryType::Stonecutter => {} InventoryType::Horse => {}*/ - _ => None, - } + _ => return None, + }) } #[derive(Debug)]