diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index 4decfa8..4055a5c 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -559,3 +559,41 @@ where }).await } +fn sort_inventory_items(character_id: CharacterEntityId, item_ids: Vec) + -> impl for<'a> Fn((ItemStateProxy<'a>, Box), ()) + -> Pin, Box), ()), ItemStateError>> + Send + 'a>> +{ + move |(mut item_state, mut transaction), _| { + let item_ids = item_ids.clone(); + Box::pin(async move { + let mut inventory = item_state.inventory(&character_id)?; + inventory.sort(&item_ids); + transaction.gateway().set_character_inventory(&character_id, &inventory.as_inventory_entity(&character_id)).await?; + item_state.set_inventory(inventory); + + Ok(((item_state, transaction), ())) + }) + } +} + + + +pub async fn sort_inventory<'a, EG> ( + item_state: &'a mut ItemState, + entity_gateway: &mut EG, + character: &CharacterEntity, + item_ids: Vec, +) -> Result<(), ItemStateError> +where + EG: EntityGateway, +{ + entity_gateway.with_transaction(|transaction| async move { + let item_state_proxy = ItemStateProxy::new(item_state); + let ((item_state_proxy, transaction), result) = ItemStateAction::default() + .act(sort_inventory_items(character.id, item_ids)) + .commit((item_state_proxy, transaction)) + .await?; + item_state_proxy.commit(); + Ok((transaction, result)) + }).await +} diff --git a/src/ship/items/state.rs b/src/ship/items/state.rs index 4905c05..0284b2a 100644 --- a/src/ship/items/state.rs +++ b/src/ship/items/state.rs @@ -701,6 +701,21 @@ impl InventoryState { } } + pub fn sort(&mut self, item_ids: &Vec) { + self.inventory.0.sort_by(|a, b| { + let a_index = item_ids.iter().position(|item_id| *item_id == a.item_id); + let b_index = item_ids.iter().position(|item_id| *item_id == b.item_id); + + match (a_index, b_index) { + (Some(a_index), Some(b_index)) => { + dbg!("sort!", a.item_id, a_index, b.item_id, b_index); + a_index.cmp(&b_index) + }, + _ => Ordering::Equal + } + }); + } + pub fn as_inventory_entity(&self, _character_id: &CharacterEntityId) -> InventoryEntity { InventoryEntity { items: self.inventory.0.iter() diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index 9686afb..875ce66 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -8,7 +8,7 @@ use crate::ship::location::{ClientLocation, ClientLocationError}; use crate::ship::items::{ItemManager, ClientItemId}; use crate::ship::packet::builder; use crate::ship::items::state::ItemState; -use crate::ship::items::actions::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item}; +use crate::ship::items::actions::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory}; pub async fn request_exp(id: ClientId, request_exp: &RequestExp, @@ -375,13 +375,24 @@ pub async fn player_sorts_items(id: ClientId, pkt: &SortItems, entity_gateway: &mut EG, clients: &Clients, - item_manager: &mut ItemManager) + item_state: &mut ItemState) -> Result + Send>, anyhow::Error> 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?; + let item_ids = pkt.item_ids + .iter() + .filter_map(|item_id| { + if *item_id != 0 { + Some(ClientItemId(*item_id)) + } + else { + None + } + }) + .collect(); + sort_inventory(item_state, entity_gateway, &client.character, item_ids).await?; Ok(Box::new(None.into_iter())) // TODO: clients probably care about each others item orders } diff --git a/src/ship/ship.rs b/src/ship/ship.rs index f03fe93..1d3b66e 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -518,7 +518,7 @@ impl ShipServerState { handler::message::player_unequips_item(id, player_unequip_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? }, GameMessage::SortItems(sort_items) => { - handler::message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &self.clients, &mut self.item_manager).await? + handler::message::player_sorts_items(id, sort_items, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? }, GameMessage::PlayerSoldItem(player_sold_item) => { handler::message::player_sells_item(id, player_sold_item, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager).await?