diff --git a/src/bin/main.rs b/src/bin/main.rs index fcd99af..529fdc2 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -185,7 +185,7 @@ fn main() { location: ItemLocation::Inventory { character_id: character.id, slot: 3, - equipped: true, + equipped: false, } }).await.unwrap(); entity_gateway.create_item( @@ -205,7 +205,7 @@ fn main() { location: ItemLocation::Inventory { character_id: character.id, slot: 4, - equipped: true, + equipped: false, } }).await.unwrap(); diff --git a/src/ship/items/inventory.rs b/src/ship/items/inventory.rs index b4dcc58..6360037 100644 --- a/src/ship/items/inventory.rs +++ b/src/ship/items/inventory.rs @@ -631,5 +631,9 @@ impl CharacterInventory { pub fn items(&self) -> &Vec { &self.items } + + pub fn set_items(&mut self, sorted_items: Vec) { + self.items = sorted_items; + } } diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index b037f59..642ec51 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -979,4 +979,22 @@ impl ItemManager { }).await; Ok(()) } + + pub async fn player_sorts_items(&mut self, + entity_gateway: &mut EG, + character: &CharacterEntity, + item_ids: [u32; 30]) + -> Result<(), ItemManagerError> { + let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; + let sorted_inventory_items: Vec = item_ids.iter() + .filter(|&client_item_id| *client_item_id < 0xFFFFFFFF) + .map(|&client_item_id| inventory.get_item_by_id(ClientItemId(client_item_id))) + .filter(|&x| x.is_some() == true) + .map(|x| x.cloned().unwrap()) + .collect(); + + inventory.set_items(sorted_inventory_items); + update_inventory_slots(entity_gateway, character, &inventory).await; + Ok(()) + } } diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index 8934b19..c1efe6b 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -6,7 +6,7 @@ use crate::common::serverstate::ClientId; use crate::common::leveltable::CharacterLevelTable; use crate::ship::ship::{SendShipPacket, ShipError, Rooms, Clients, ItemDropLocation}; use crate::ship::location::{ClientLocation, ClientLocationError}; -use crate::ship::items::{ItemManager, ClientItemId}; +use crate::ship::items::{ItemManager, ClientItemId, InventoryItem}; use crate::ship::packet::builder; pub async fn request_exp(id: ClientId, @@ -356,3 +356,17 @@ where Ok(Box::new(None.into_iter())) } + +pub async fn player_sorts_items(id: ClientId, + pkt: &SortItems, + entity_gateway: &mut EG, + clients: &Clients, + item_manager: &mut ItemManager) + -> Result + Send>, ShipError> +where + EG: EntityGateway +{ + let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; + item_manager.player_sorts_items(entity_gateway, &client.character, pkt.item_ids).await?; + Ok(Box::new(None.into_iter())) // Do clients care about the order of other clients items? +} \ No newline at end of file diff --git a/src/ship/ship.rs b/src/ship/ship.rs index d27c10f..610b1be 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -400,7 +400,9 @@ impl ShipServerState { GameMessage::PlayerUnequipItem(player_unequip_item) => { handler::message::player_unequips_item(id, &player_unequip_item, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager).await }, - + GameMessage::SortItems(sort_items) => { + handler::message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager).await + }, _ => { let cmsg = msg.clone(); Ok(Box::new(self.client_location.get_client_neighbors(id).unwrap().into_iter() diff --git a/tests/test_item_equip.rs b/tests/test_item_actions.rs similarity index 68% rename from tests/test_item_equip.rs rename to tests/test_item_actions.rs index 484c161..201f9fa 100644 --- a/tests/test_item_equip.rs +++ b/tests/test_item_actions.rs @@ -216,3 +216,88 @@ async fn test_unequip_armor_with_units() { assert!(unit1_equipped == false); assert!(unit2_equipped == false); } + +#[async_std::test] +async fn test_sort_items() { + let mut entity_gateway = InMemoryGateway::new(); + + let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; + + entity_gateway.create_item( + item::NewItemEntity { + item: item::ItemDetail::Armor( + item::armor::Armor{ + armor: item::armor::ArmorType::Frame, + dfp: 0, + evp: 0, + slots: 4, + modifiers: Vec::new(), + }), + location: item::ItemLocation::Inventory { + character_id: char1.id, + slot: 0, + equipped: true, + } + }).await; + + entity_gateway.create_item( + item::NewItemEntity { + item: item::ItemDetail::Unit( + item::unit::Unit{ + unit: item::unit::UnitType::KnightPower, + modifier: None, + armor_slot: 0, + }), + location: item::ItemLocation::Inventory { + character_id: char1.id, + slot: 1, + equipped: false, + } + }).await; + + entity_gateway.create_item( + item::NewItemEntity { + item: item::ItemDetail::Unit( + item::unit::Unit{ + unit: item::unit::UnitType::KnightPower, + modifier: Some(item::unit::UnitModifier::Plus), + armor_slot: 0, + }), + location: item::ItemLocation::Inventory { + character_id: char1.id, + slot: 2, + equipped: false, + } + }).await; + + let mut ship = ShipServerState::builder() + .gateway(entity_gateway.clone()) + .build(); + log_in_char(&mut ship, ClientId(1), "a1", "a").await; + join_lobby(&mut ship, ClientId(1)).await; + create_room(&mut ship, ClientId(1), "room", "").await; + + let old_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); + assert!(old_items[0].item.item_type() == item::ItemType::Armor(item::armor::ArmorType::Frame)); + assert!(old_items[0].location == item::ItemLocation::Inventory{ + character_id: char1.id, + slot: 0, + equipped: true, + }); + + ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::SortItems(SortItems { + client: 255, + target: 255, + item_ids: [0x10001u32, 0x10002, 0x10000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF], + })))).await.unwrap().for_each(drop); + + let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); + assert!(items[0].item.item_type() == item::ItemType::Armor(item::armor::ArmorType::Frame)); + assert!(items[0].location == item::ItemLocation::Inventory{ + character_id: char1.id, + slot: 2, + equipped: true, + }); +} \ No newline at end of file