andy/floor-limit #134

Merged
jake merged 4 commits from andy/floor-limit into master 2 years ago
  1. 2
      Cargo.lock
  2. 13
      src/entity/gateway/postgres/models.rs
  3. 3
      src/entity/item/mod.rs
  4. 22
      src/ship/items/actions.rs
  5. 24
      src/ship/items/tasks.rs
  6. 27
      src/ship/packet/handler/message.rs
  7. 4
      src/ship/ship.rs
  8. 5
      tests/test_item_pickup.rs

2
Cargo.lock

@ -1040,7 +1040,6 @@ checksum = "739e9d7726dc32173fed2d69d17eef3c54682169e4e20ff1d0a45dcd37063cef"
[[package]]
name = "libpso"
version = "0.1.0"
source = "git+http://git.sharnoth.com/jake/libpso#05222bbf9fe402675447bc163b45e07a327cdb1a"
dependencies = [
"chrono",
"psopacket",
@ -1399,7 +1398,6 @@ dependencies = [
[[package]]
name = "psopacket"
version = "1.0.0"
source = "git+http://git.sharnoth.com/jake/libpso#05222bbf9fe402675447bc163b45e07a327cdb1a"
dependencies = [
"proc-macro2",
"quote",

13
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<ItemNote> for PgItemNoteDetail {
character_id: character_id.0,
bank,
}
}
},
ItemNote::FloorLimitReached { map_area } => {
PgItemNoteDetail::FloorLimitReached {
map_area,
}
},
}
}
}
@ -703,6 +711,9 @@ impl From<PgItemNoteDetail> for ItemNote {
character_id: CharacterEntityId(character_id),
bank,
},
PgItemNoteDetail::FloorLimitReached { map_area } => ItemNote::FloorLimitReached {
map_area,
},
}
}
}

3
src/entity/item/mod.rs

@ -74,6 +74,9 @@ pub enum ItemNote {
character_id: CharacterEntityId,
bank: BankIdentifier,
},
FloorLimitReached {
map_area: MapArea,
},
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]

22
src/ship/items/actions.rs

@ -1148,3 +1148,25 @@ 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<ParentGateway = EG> + 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
}).await?;
Ok(transaction)
}}).await?;
Ok(((item_state, transaction), ()))
})
}
}

24
src/ship/items/tasks.rs

@ -508,3 +508,27 @@ where
Ok((transaction, item))
})
}
pub fn floor_item_limit_reached<'a, EG> (
item_state: &'a 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))
})
}

27
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<EG>(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<EG> (id: ClientId,
floor_item_limit_delete: FloorItemLimitItemDeletion,
entity_gateway: &mut EG,
client_location: &ClientLocation,
clients: &Clients,
rooms: &Rooms,
item_state: &mut ItemState)
-> Result<Vec<(ClientId, SendShipPacket)>, 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 item_state = item_state.clone();
Box::pin(async move {
floor_item_limit_reached(&item_state, &mut entity_gateway, &client.character, &ClientItemId(floor_item_limit_delete.item_id), map_area).await
})}).await??;
Ok(Vec::new())
}

4
src/ship/ship.rs

@ -575,6 +575,10 @@ impl<EG: EntityGateway + Clone + 'static> ShipServerState<EG> {
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?;

5
tests/test_item_pickup.rs

@ -262,6 +262,7 @@ async fn test_pick_up_meseta_when_inventory_full() {
room: 0,
x: 0.0,
z: 0.0,
amount: 23,
})))).await.unwrap();
ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
@ -486,6 +487,7 @@ async fn test_can_not_drop_more_meseta_than_is_held() {
room: 0,
x: 0.0,
z: 0.0,
amount: 301,
})))).await.unwrap();
let split_attempt = ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
@ -604,6 +606,7 @@ async fn test_can_not_pick_up_meseta_when_full() {
room: 0,
x: 0.0,
z: 0.0,
amount: 23,
})))).await.unwrap();
ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
@ -658,6 +661,7 @@ async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() {
room: 0,
x: 0.0,
z: 0.0,
amount: 23,
})))).await.unwrap();
ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
@ -722,6 +726,7 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() {
room: 0,
x: 0.0,
z: 0.0,
amount: 2,
})))).await.unwrap();
ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {

Loading…
Cancel
Save