diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index b6add91..20bca41 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -43,6 +43,9 @@ pub enum ItemLocation { z: f32, }, Consumed, + FedToMag { + mag: ItemEntityId, + } /*Destroyed { // marks an item that has been consumed in some way }, diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index 69cd03b..9c3c83b 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -36,6 +36,7 @@ pub enum ItemManagerError { NotEnoughTools(Tool, usize, usize), // have, expected InventoryItemConsumeError(#[from] InventoryItemConsumeError), BankFull, + WrongItemType(ClientItemId), } pub struct ItemManager { @@ -595,4 +596,41 @@ impl ItemManager { Ok(inventory_item.0) } + + pub async fn player_feeds_mag_item(&mut self, + entity_gateway: &mut EG, + character: &CharacterEntity, + mag_id: ClientItemId, + tool_id: ClientItemId) + -> Result<(), ItemManagerError> { + let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; + let consumed_tool = { + let item_to_feed = inventory.get_item_handle_by_id(tool_id).ok_or(ItemManagerError::NoSuchItemId(tool_id))?; + item_to_feed.consume(1)? + }; + let mut mag_handle = inventory.get_item_handle_by_id(mag_id).ok_or(ItemManagerError::NoSuchItemId(mag_id))?; + + let individual_item = mag_handle.item_mut() + .ok_or(ItemManagerError::NoSuchItemId(mag_id))? + .individual() + .ok_or(ItemManagerError::WrongItemType(mag_id))?; + let mag = individual_item + .mag() + .ok_or(ItemManagerError::WrongItemType(mag_id))?; + + let consumed_tool_type = match &consumed_tool { + ConsumedItem::Stacked(stacked_consumed_item) => stacked_consumed_item.tool.tool, + _ => return Err(ItemManagerError::WrongItemType(tool_id)) + }; + mag.feed(consumed_tool_type); + + for entity_id in consumed_tool.entity_ids() { + entity_gateway.feed_mag(&individual_item.entity_id, &entity_id).await; + entity_gateway.change_item_location(&entity_id, ItemLocation::FedToMag { + mag: individual_item.entity_id, + }).await; + } + + Ok(()) + } } diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index 098f262..09bdd0e 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -326,4 +326,25 @@ EG: EntityGateway } else { Err(ShipError::NotEnoughMeseta(id, client.character.meseta)) } -} \ No newline at end of file +} + + +pub async fn player_feed_mag(id: ClientId, + mag_feed: &PlayerFeedMag, + entity_gateway: &mut EG, + client_location: &ClientLocation, + 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_feeds_mag_item(entity_gateway, &client.character, ClientItemId(mag_feed.mag_id), ClientItemId(mag_feed.item_id)).await?; + + let mag_feed = mag_feed.clone(); + Ok(Box::new(client_location.get_client_neighbors(id).unwrap().into_iter() + .map(move |client| { + (client.client, SendShipPacket::Message(Message::new(GameMessage::PlayerFeedMag(mag_feed.clone())))) + }))) +} diff --git a/src/ship/ship.rs b/src/ship/ship.rs index 766dfcb..643d662 100644 --- a/src/ship/ship.rs +++ b/src/ship/ship.rs @@ -348,6 +348,9 @@ impl ShipServerState { GameMessage::PlayerUsedMedicalCenter(player_used_medical_center) => { handler::message::player_used_medical_center(id, &player_used_medical_center, &mut self.entity_gateway, &mut self.clients).await }, + GameMessage::PlayerFeedMag(player_feed_mag) => { + handler::message::player_feed_mag(id, &player_feed_mag, &mut self.entity_gateway, &mut self.client_location, &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()