From 2775f81cc97282191d66934de4105b06e7c2982a Mon Sep 17 00:00:00 2001
From: jake <jake@sharnoth.com>
Date: Mon, 18 Jul 2022 19:25:47 -0600
Subject: [PATCH] fix some meseta-taking things

---
 src/ship/items/actions.rs          | 22 ++++++++++++
 src/ship/packet/handler/message.rs | 57 +++++++++++++++---------------
 src/ship/ship.rs                   |  6 ++--
 3 files changed, 55 insertions(+), 30 deletions(-)

diff --git a/src/ship/items/actions.rs b/src/ship/items/actions.rs
index 43f41b2..544e17a 100644
--- a/src/ship/items/actions.rs
+++ b/src/ship/items/actions.rs
@@ -1123,3 +1123,25 @@ where
         Ok((transaction, (p1_new_items, p2_new_items)))
     }).await
 }
+
+
+pub async fn take_meseta<'a, EG> (
+    item_state: &'a mut ItemState,
+    entity_gateway: &mut EG,
+    character_id: &CharacterEntityId,
+    meseta: Meseta)
+    -> Result<(), ItemStateError>
+where
+    EG: EntityGateway,
+{
+    entity_gateway.with_transaction(|mut transaction| async move {
+        let item_state_proxy = ItemStateProxy::new(item_state);
+        let ((item_state_proxy, transaction), p1_removed_items) = ItemStateAction::default()
+            .act(take_meseta_from_inventory(*character_id, meseta.0))
+            .commit((item_state_proxy, transaction))
+            .await?;
+
+            item_state_proxy.commit();
+        Ok((transaction, ()))
+    }).await
+}
diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs
index 4680c6c..dbb4695 100644
--- a/src/ship/packet/handler/message.rs
+++ b/src/ship/packet/handler/message.rs
@@ -1,14 +1,15 @@
 use libpso::packet::ship::*;
 use libpso::packet::messages::*;
 use crate::entity::gateway::EntityGateway;
+use crate::entity::item::Meseta;
 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::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, sort_inventory, use_item, feed_mag, sell_item};
+use crate::ship::items::actions::{drop_item, drop_partial_item, drop_meseta, equip_item, unequip_item, sort_inventory, use_item, feed_mag, sell_item, take_meseta};
 
 pub async fn request_exp<EG: EntityGateway>(id: ClientId,
                                             request_exp: &RequestExp,
@@ -257,25 +258,25 @@ pub fn update_player_position(id: ClientId,
 }
 
 pub async fn charge_attack<EG>(id: ClientId,
-                        charge: &ChargeAttack,
-                        clients: &mut Clients,
-                        entity_gateway: &mut EG,
-                        item_manager: &mut ItemManager)
-                        -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
+                               charge: &ChargeAttack,
+                               entity_gateway: &mut EG,
+                               client_location: &ClientLocation,
+                               clients: &mut Clients,
+                               item_state: &mut ItemState)
+                               -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
 where
     EG: EntityGateway
 {
     let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
-    let meseta = item_manager.get_character_meseta_mut(&client.character.id)?;
-
-    if meseta.0 >= charge.meseta {
-        meseta.0 -= charge.meseta;
-        entity_gateway.set_character_meseta(&client.character.id, *meseta).await?;
-        // TODO: this should probably echo the packet
-        Ok(Box::new(None.into_iter()))
-    } else {
-        Err(ShipError::NotEnoughMeseta(id, meseta.0).into())
-    }
+
+    // TODO: should probably validate this to be a legit number, I'd just hardcode 200 but vjaya
+    take_meseta(item_state, entity_gateway, &client.character.id, Meseta(charge.meseta)).await?;
+
+    let charge = charge.clone();
+    Ok(Box::new(client_location.get_client_neighbors(id).unwrap().into_iter()
+                    .map(move |client| {
+                        (client.client, SendShipPacket::Message(Message::new(GameMessage::ChargeAttack(charge.clone()))))
+                    })))
 }
 
 pub async fn player_uses_item<EG>(id: ClientId,
@@ -294,24 +295,24 @@ where
 }
 
 pub async fn player_used_medical_center<EG>(id: ClientId,
-                                            _pumc: &PlayerUsedMedicalCenter, // not needed?
+                                            pumc: &PlayerUsedMedicalCenter,
                                             entity_gateway: &mut EG,
+                                            client_location: &ClientLocation,
                                             clients: &mut Clients,
-                                            item_manager: &mut ItemManager)
+                                            item_state: &mut ItemState)
                                             -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error>
 where
     EG: EntityGateway
 {
     let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
-    let meseta = item_manager.get_character_meseta_mut(&client.character.id)?;
-    if meseta.0 >= 10 {
-        meseta.0 -= 10;
-        entity_gateway.set_character_meseta(&client.character.id, *meseta).await?;
-        // TODO: this should probably echo the packet
-        Ok(Box::new(None.into_iter()))
-    } else {
-        Err(ShipError::NotEnoughMeseta(id, meseta.0).into())
-    }
+
+    take_meseta(item_state, entity_gateway, &client.character.id, Meseta(10)).await?;
+
+    let pumc = pumc.clone();
+    Ok(Box::new(client_location.get_client_neighbors(id).unwrap().into_iter()
+                    .map(move |client| {
+                        (client.client, SendShipPacket::Message(Message::new(GameMessage::PlayerUsedMedicalCenter(pumc.clone()))))
+                    })))
 }
 
 
diff --git a/src/ship/ship.rs b/src/ship/ship.rs
index 9909f63..9302fb7 100644
--- a/src/ship/ship.rs
+++ b/src/ship/ship.rs
@@ -502,14 +502,16 @@ impl<EG: EntityGateway> ShipServerState<EG> {
                 handler::message::update_player_position(id, msg, &mut self.clients, &block.client_location, &block.rooms)?
             },
             GameMessage::ChargeAttack(charge_attack) => {
-                handler::message::charge_attack(id, charge_attack, &mut self.clients, &mut self.entity_gateway, &mut self.item_manager).await?
+                let block = self.blocks.with_client(id, &self.clients)?;
+                handler::message::charge_attack(id, charge_attack, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await?
             },
             GameMessage::PlayerUseItem(player_use_item) => {
                 let block = self.blocks.with_client(id, &self.clients)?;
                 handler::message::player_uses_item(id, player_use_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await?
             },
             GameMessage::PlayerUsedMedicalCenter(player_used_medical_center) => {
-                handler::message::player_used_medical_center(id, player_used_medical_center, &mut self.entity_gateway, &mut self.clients, &mut self.item_manager).await?
+                let block = self.blocks.with_client(id, &self.clients)?;
+                handler::message::player_used_medical_center(id, player_used_medical_center, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await?
             },
             GameMessage::PlayerFeedMag(player_feed_mag) => {
                 let block = self.blocks.with_client(id, &self.clients)?;