diff --git a/src/entity/gateway/postgres/models.rs b/src/entity/gateway/postgres/models.rs index b017b3b..81de203 100644 --- a/src/entity/gateway/postgres/models.rs +++ b/src/entity/gateway/postgres/models.rs @@ -612,6 +612,9 @@ pub enum PgItemNoteDetail { Deposit { character_id: u32, bank: BankIdentifier, + }, + FloorLimitReached { + map_area: MapArea, } } @@ -658,7 +661,12 @@ impl From for PgItemNoteDetail { character_id: character_id.0, bank, } - } + }, + ItemNote::FloorLimitReached { map_area } => { + PgItemNoteDetail::FloorLimitReached { + map_area: map_area, + } + }, } } } @@ -703,6 +711,9 @@ impl From for ItemNote { character_id: CharacterEntityId(character_id), bank, }, + PgItemNoteDetail::FloorLimitReached { map_area } => ItemNote::FloorLimitReached { + map_area: map_area, + }, } } } diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index 6b7bf53..56bf21f 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -10,6 +10,7 @@ pub mod esweapon; use serde::{Serialize, Deserialize}; use crate::entity::character::CharacterEntityId; +use crate::ship::items::ClientItemId; use crate::ship::map::MapArea; use crate::ship::drops::ItemDropType; @@ -74,6 +75,9 @@ pub enum ItemNote { character_id: CharacterEntityId, bank: BankIdentifier, }, + FloorLimitReached { + map_area: MapArea, + }, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs index f9844bb..8bc3c86 100644 --- a/src/ship/items/actions.rs +++ b/src/ship/items/actions.rs @@ -1148,3 +1148,23 @@ where }) } } + +pub(super) fn delete_item_from_floor<'a, EG, TR>( + map_area: MapArea +) -> impl Fn((ItemStateProxy, TR), FloorItem) + -> BoxFuture<'a, Result<((ItemStateProxy, TR), ()), anyhow::Error>> +where + EG: EntityGateway, + TR: EntityGatewayTransaction + Clone + 'a, +{ + move |(item_state, transaction), floor_item| { + Box::pin(async move { + let transaction = floor_item.with_entity_id(transaction, |mut transaction, entity_id| { + async move { + transaction.gateway().add_item_note(&entity_id, ItemNote::FloorLimitReached { map_area: map_area }).await?; + Ok(transaction) + }}).await?; + Ok(((item_state, transaction), ())) + }) + } +} \ No newline at end of file diff --git a/src/ship/items/tasks.rs b/src/ship/items/tasks.rs index 3e0cf6a..67fd179 100644 --- a/src/ship/items/tasks.rs +++ b/src/ship/items/tasks.rs @@ -508,3 +508,27 @@ where Ok((transaction, item)) }) } + +pub async fn floor_item_limit_reached<'a, EG> ( + item_state: &'a mut ItemState, + entity_gateway: &'a mut EG, + character: &'a CharacterEntity, + item_id: &'a ClientItemId, + map_area: MapArea +) -> BoxFuture<'a, Result<(), anyhow::Error>> +where + EG: EntityGateway + 'static, + EG::Transaction<'a>: Clone, +{ + entity_gateway.with_transaction(move |transaction| async move { + let item_state_proxy = ItemStateProxy::new(item_state.clone()); + let((item_state_proxy, transaction), result) = ItemStateAction::default() + .act(actions::take_item_from_floor(character.id, *item_id)) + .act(actions::delete_item_from_floor(map_area)) + .commit((item_state_proxy, transaction)) + .await?; + + item_state_proxy.commit().await; + Ok((transaction, result)) + }) +} diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index f4e4d69..c219303 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -10,7 +10,7 @@ use crate::ship::location::{ClientLocation, ClientLocationError}; use crate::ship::items::ClientItemId; use crate::ship::packet::builder; use crate::ship::items::state::ItemState; -use crate::ship::items::tasks::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory, use_item, feed_mag, sell_item, take_meseta}; +use crate::ship::items::tasks::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory, use_item, feed_mag, sell_item, take_meseta, floor_item_limit_reached}; pub async fn request_exp(id: ClientId, request_exp: RequestExp, @@ -500,3 +500,28 @@ where })}).await??; Ok(Vec::new()) // TODO: send the packet to other clients } + +pub async fn floor_item_limit_deletion (id: ClientId, + floor_item_limit_delete: FloorItemLimitItemDeletion, + entity_gateway: &mut EG, + client_location: &ClientLocation, + clients: &Clients, + rooms: &Rooms, + item_state: &mut ItemState) + -> Result, anyhow::Error> +where + EG: EntityGateway + Clone + 'static, +{ + let room_id = client_location.get_room(id).await.map_err(|err| -> ClientLocationError { err.into() })?; + let map_area = rooms.with(room_id, |room| Box::pin(async move { + room.map_areas.get_area_map(floor_item_limit_delete.map_area) + })).await??; + + clients.with(id, |client| { + let mut entity_gateway = entity_gateway.clone(); + let mut item_state = item_state.clone(); + Box::pin(async move { + floor_item_limit_reached(&mut item_state, &mut entity_gateway, &client.character, &ClientItemId(floor_item_limit_delete.item_id), map_area).await + })}).await??; + Ok(Vec::new()) +} \ No newline at end of file diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 0b188ae..378196f 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -577,6 +577,10 @@ impl ShipServerState { GameMessage::PlayerSoldItem(player_sold_item) => { handler::message::player_sells_item(id, player_sold_item, &mut self.entity_gateway, &self.clients, &mut self.item_state).await? }, + GameMessage::FloorItemLimitItemDeletion(floor_item_limit_delete) => { + let block = self.blocks.get_from_client(id, &self.clients).await?; + handler::message::floor_item_limit_deletion(id, floor_item_limit_delete, &mut self.entity_gateway, &block.client_location, &self.clients, &block.rooms, &mut self.item_state).await? + }, _ => { let cmsg = msg.clone(); let block = self.blocks.get_from_client(id, &self.clients).await?;