enemy drop refactor
This commit is contained in:
		
							parent
							
								
									2a7b43df83
								
							
						
					
					
						commit
						eb0689a1fe
					
				| @ -10,9 +10,11 @@ use crate::ship::items::state::{ItemState, ItemStateProxy, ItemStateAction, Item | ||||
|                                 StackedItemDetail, BankItem, BankItemDetail, InventoryItemDetail, IndividualItemDetail}; | ||||
| use crate::ship::items::apply_item::apply_item; | ||||
| use crate::entity::item::{ItemDetail, NewItemEntity, TradeId}; | ||||
| use crate::entity::item::tool::Tool; | ||||
| use crate::ship::shops::ShopItem; | ||||
| use crate::ship::trade::TradeItem; | ||||
| use crate::ship::location::{AreaClient, RoomId}; | ||||
| use crate::ship::drops::{ItemDrop, ItemDropType}; | ||||
| 
 | ||||
| pub enum TriggerCreateItem { | ||||
|     Yes, | ||||
| @ -239,7 +241,7 @@ fn add_meseta_to_shared_floor(character_id: CharacterEntityId, amount: u32, map_ | ||||
|             }; | ||||
| 
 | ||||
|             let mut floor = item_state.floor(&character_id)?; | ||||
|             let floor_item = floor.add_item(floor_item).clone(); | ||||
|             let floor_item = floor.add_shared_item(floor_item).clone(); | ||||
|             item_state.set_floor(floor); | ||||
| 
 | ||||
|             Ok(((item_state, transaction), floor_item)) | ||||
| @ -1145,3 +1147,137 @@ where | ||||
|         Ok((transaction, ())) | ||||
|     }).await | ||||
| } | ||||
| 
 | ||||
| fn convert_item_drop_to_floor_item(character_id: CharacterEntityId, item_drop: ItemDrop) | ||||
|                       -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), ()) | ||||
|                                          -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>> + Clone | ||||
| { | ||||
|     move |(mut item_state, mut transaction), _| { | ||||
|         let item_drop = item_drop.clone(); | ||||
|         Box::pin(async move { | ||||
|             enum ItemOrMeseta { | ||||
|                 Individual(ItemDetail), | ||||
|                 Stacked(Tool), | ||||
|                 Meseta(Meseta) | ||||
|             } | ||||
| 
 | ||||
|             let item = match item_drop.item { | ||||
|                 ItemDropType::Weapon(w) => ItemOrMeseta::Individual(ItemDetail::Weapon(w)), | ||||
|                 ItemDropType::Armor(w) => ItemOrMeseta::Individual(ItemDetail::Armor(w)), | ||||
|                 ItemDropType::Shield(w) => ItemOrMeseta::Individual(ItemDetail::Shield(w)), | ||||
|                 ItemDropType::Unit(w) => ItemOrMeseta::Individual(ItemDetail::Unit(w)), | ||||
|                 ItemDropType::TechniqueDisk(w) => ItemOrMeseta::Individual(ItemDetail::TechniqueDisk(w)), | ||||
|                 ItemDropType::Mag(w) => ItemOrMeseta::Individual(ItemDetail::Mag(w)), | ||||
|                 ItemDropType::Tool(t) => { | ||||
|                     if t.tool.is_stackable() { | ||||
|                         ItemOrMeseta::Stacked(t) | ||||
|                     } | ||||
|                     else { | ||||
|                         ItemOrMeseta::Individual(ItemDetail::Tool(t)) | ||||
|                     } | ||||
|                 }, | ||||
|                 ItemDropType::Meseta(m) => ItemOrMeseta::Meseta(Meseta(m)), | ||||
|             }; | ||||
| 
 | ||||
|             let item_id = item_state.new_item_id()?; | ||||
| 
 | ||||
|             let floor_item = match item { | ||||
|                 ItemOrMeseta::Individual(item_detail) => { | ||||
|                     let entity = transaction.gateway().create_item(NewItemEntity { | ||||
|                         item: item_detail.clone(), | ||||
|                     }).await?; | ||||
|                     transaction.gateway().add_item_note(&entity.id, ItemNote::EnemyDrop { | ||||
|                         character_id, | ||||
|                         map_area: item_drop.map_area, | ||||
|                         x: item_drop.x, | ||||
|                         y: item_drop.y, | ||||
|                         z: item_drop.z, | ||||
|                     }).await?; | ||||
|                     FloorItem { | ||||
|                         item_id, | ||||
|                         item: FloorItemDetail::Individual(IndividualItemDetail { | ||||
|                             entity_id: entity.id, | ||||
|                             item: item_detail, | ||||
|                         }), | ||||
|                         map_area: item_drop.map_area, | ||||
|                         x: item_drop.x, | ||||
|                         y: item_drop.y, | ||||
|                         z: item_drop.z, | ||||
|                     } | ||||
|                 }, | ||||
|                 ItemOrMeseta::Stacked(tool) => { | ||||
|                     let entity = transaction.gateway().create_item(NewItemEntity { | ||||
|                         item: ItemDetail::Tool(tool), | ||||
|                     }).await?; | ||||
|                     transaction.gateway().add_item_note(&entity.id, ItemNote::EnemyDrop { | ||||
|                         character_id, | ||||
|                         map_area: item_drop.map_area, | ||||
|                         x: item_drop.x, | ||||
|                         y: item_drop.y, | ||||
|                         z: item_drop.z, | ||||
|                     }).await?; | ||||
|                     FloorItem { | ||||
|                         item_id, | ||||
|                         item: FloorItemDetail::Stacked(StackedItemDetail{ | ||||
|                             entity_ids: vec![entity.id], | ||||
|                             tool, | ||||
|                         }), | ||||
|                         map_area: item_drop.map_area, | ||||
|                         x: item_drop.x, | ||||
|                         y: item_drop.y, | ||||
|                         z: item_drop.z, | ||||
|                     } | ||||
|                 }, | ||||
|                 ItemOrMeseta::Meseta(meseta) => { | ||||
|                     FloorItem { | ||||
|                         item_id, | ||||
|                         item: FloorItemDetail::Meseta(meseta), | ||||
|                         map_area: item_drop.map_area, | ||||
|                         x: item_drop.x, | ||||
|                         y: item_drop.y, | ||||
|                         z: item_drop.z, | ||||
|                     } | ||||
|                 }, | ||||
|             }; | ||||
| 
 | ||||
|             Ok(((item_state, transaction), floor_item)) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn add_item_to_local_floor(character_id: CharacterEntityId) | ||||
|                         -> impl for<'a> Fn((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem) | ||||
|                                            -> Pin<Box<dyn Future<Output=Result<((ItemStateProxy<'a>, Box<dyn EntityGatewayTransaction + 'a>), FloorItem), ItemStateError>> + Send + 'a>> | ||||
| { | ||||
|     move |(mut item_state, transaction) , floor_item| { | ||||
|         Box::pin(async move { | ||||
|             let mut floor = item_state.floor(&character_id)?; | ||||
|             let item = floor.add_local_item(floor_item).clone(); | ||||
|             item_state.set_floor(floor); | ||||
| 
 | ||||
|             Ok(((item_state, transaction), item)) | ||||
|         }) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub async fn enemy_drops_item<'a, EG> ( | ||||
|     item_state: &'a mut ItemState, | ||||
|     entity_gateway: &mut EG, | ||||
|     character_id: CharacterEntityId, | ||||
|     item_drop: ItemDrop) | ||||
|     -> Result<FloorItem, 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), floor_item) = ItemStateAction::default() | ||||
|             .act(convert_item_drop_to_floor_item(character_id, item_drop)) | ||||
|             .act(add_item_to_local_floor(character_id)) | ||||
|             .commit((item_state_proxy, transaction)) | ||||
|             .await?; | ||||
| 
 | ||||
|             item_state_proxy.commit(); | ||||
|         Ok((transaction, floor_item)) | ||||
|     }).await | ||||
| } | ||||
|  | ||||
| @ -1214,10 +1214,15 @@ impl FloorState { | ||||
|         &self.shared.0[self.shared.0.len()-1] | ||||
|     } | ||||
| 
 | ||||
|     pub fn add_item(&mut self, floor_item: FloorItem) -> &FloorItem { | ||||
|     pub fn add_shared_item(&mut self, floor_item: FloorItem) -> &FloorItem { | ||||
|         self.shared.0.push(floor_item); | ||||
|         &self.shared.0[self.shared.0.len()-1] | ||||
|     } | ||||
| 
 | ||||
|     pub fn add_local_item(&mut self, floor_item: FloorItem) -> &FloorItem { | ||||
|         self.local.0.push(floor_item); | ||||
|         &self.local.0[self.local.0.len()-1] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -12,19 +12,19 @@ use std::convert::TryInto; | ||||
| use crate::ship::shops::ShopItem; | ||||
| 
 | ||||
| 
 | ||||
| pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem) -> Result<ItemDrop, ShipError> { | ||||
| pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem2) -> Result<ItemDrop, ShipError> { | ||||
|     let item_bytes = item_drop.as_client_bytes(); | ||||
|     Ok(ItemDrop { | ||||
|         client, | ||||
|         target, | ||||
|         map_area: item_drop.map_area().area_value(), | ||||
|         map_area: item_drop.map_area.area_value(), | ||||
|         variety: 0, | ||||
|         unknown: 0, | ||||
|         x: item_drop.x(), | ||||
|         z: item_drop.z(), | ||||
|         y: item_drop.y(), | ||||
|         x: item_drop.x, | ||||
|         z: item_drop.z, | ||||
|         y: item_drop.y, | ||||
|         item_bytes: item_bytes[0..12].try_into()?, | ||||
|         item_id: item_drop.item_id().0, | ||||
|         item_id: item_drop.item_id.0, | ||||
|         item_bytes2: item_bytes[12..16].try_into()?, | ||||
|         unknown2: 0, | ||||
|     }) | ||||
|  | ||||
| @ -15,7 +15,7 @@ use libpso::utf8_to_utf16_array; | ||||
| use crate::ship::packet::builder; | ||||
| use crate::ship::shops::{ShopItem, ToolShopItem, ArmorShopItem}; | ||||
| use crate::ship::items::state::{ItemState, FloorType, FloorItemDetail}; | ||||
| use crate::ship::items::actions::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, TriggerCreateItem}; | ||||
| use crate::ship::items::actions::{pick_up_item, withdraw_meseta, deposit_meseta, withdraw_item, deposit_item, buy_shop_item, enemy_drops_item, TriggerCreateItem}; | ||||
| 
 | ||||
| const BANK_ACTION_DEPOSIT: u8 = 0; | ||||
| const BANK_ACTION_WITHDRAW: u8 = 1; | ||||
| @ -76,7 +76,7 @@ pub async fn request_item<EG>(id: ClientId, | ||||
|                               client_location: &ClientLocation, | ||||
|                               clients: &mut Clients, | ||||
|                               rooms: &mut Rooms, | ||||
|                               item_manager: &mut ItemManager) | ||||
|                               item_state: &mut ItemState) | ||||
|                               -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> | ||||
| where | ||||
|     EG: EntityGateway | ||||
| @ -111,8 +111,8 @@ where | ||||
|             item: item_drop, | ||||
|         }; | ||||
|         let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; | ||||
|         let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).await?; | ||||
|         let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, floor_item)?; | ||||
|         let floor_item = enemy_drops_item(item_state, entity_gateway, client.character.id, item_drop).await?; | ||||
|         let item_drop_msg = builder::message::item_drop(request_item.client, request_item.target, &floor_item)?; | ||||
| 
 | ||||
|         item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))); | ||||
|     } | ||||
| @ -195,7 +195,7 @@ pub async fn request_box_item<EG>(id: ClientId, | ||||
|     client_location: &ClientLocation, | ||||
|     clients: &mut Clients, | ||||
|     rooms: &mut Rooms, | ||||
|     item_manager: &mut ItemManager) | ||||
|     item_state: &mut ItemState) | ||||
|     -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, anyhow::Error> | ||||
| where | ||||
| EG: EntityGateway | ||||
| @ -230,8 +230,8 @@ EG: EntityGateway | ||||
|             item: item_drop, | ||||
|         }; | ||||
|         let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?; | ||||
|         let floor_item = item_manager.enemy_drop_item_on_local_floor(entity_gateway, &client.character, item_drop).await?; // TODO: unwrap
 | ||||
|         let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, floor_item)?; | ||||
|         let floor_item = enemy_drops_item(item_state, entity_gateway, client.character.id, item_drop).await?; | ||||
|         let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, &floor_item)?; | ||||
|         item_drop_packets.push((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg))))) | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -546,13 +546,13 @@ impl<EG: EntityGateway> ShipServerState<EG> { | ||||
|                 handler::direct_message::guildcard_send(id, guildcard_send, target, &block.client_location, &self.clients) | ||||
|             }, | ||||
|             GameMessage::RequestItem(request_item) => { | ||||
|                 handler::direct_message::request_item(id, request_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_manager).await? | ||||
|                 handler::direct_message::request_item(id, request_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_state).await? | ||||
|             }, | ||||
|             GameMessage::PickupItem(pickup_item) => { | ||||
|                 handler::direct_message::pickup_item(id, pickup_item, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut self.item_state).await? | ||||
|             }, | ||||
|             GameMessage::BoxDropRequest(box_drop_request) => { | ||||
|                 handler::direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_manager).await? | ||||
|                 handler::direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &block.client_location, &mut self.clients, &mut block.rooms, &mut self.item_state).await? | ||||
|             }, | ||||
|             GameMessage::BankRequest(_bank_request) => { | ||||
|                 handler::direct_message::send_bank_list(id, &self.clients, &mut self.item_state).await? | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user