diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index 0f37837..81f0146 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -117,7 +117,7 @@ where z: request_item.z, item: item_drop, }; - let character_id = clients.with(id, |client| Box::pin(async move { + let character_id = clients.with(area_client.client, |client| Box::pin(async move { client.character.id })).await?; diff --git a/tests/test_item_drop.rs b/tests/test_item_drop.rs index 49cd75b..02b01b1 100644 --- a/tests/test_item_drop.rs +++ b/tests/test_item_drop.rs @@ -71,6 +71,140 @@ async fn test_enemy_drops_item() { }, _ => panic!(), } - +} + +#[async_std::test] +async fn test_enemy_drops_item_for_two_players() { + let mut entity_gateway = InMemoryGateway::default(); + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + + let mut ship = Box::new(ShipServerState::builder() + .gateway(entity_gateway.clone()) + .map_builder(Box::new(|_room_mode, _event| { + Maps::new( + vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], + vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], + Vec::new(), + ) + })) + .drop_table_builder(Box::new(|episode, difficulty, section_id| { + DropTable::builder() + .monster_stat(MonsterType::Hildebear, MonsterDropStats { + dar: 100, + drop_type: MonsterDropType::Weapon, + min_meseta: 0, + max_meseta: 0, + }) + .rare_table(RareDropTable::builder() + .rate(MonsterType::Hildebear, RareDropRate { + rate: 1.0, + item: RareDropItem::Weapon(WeaponType::DarkFlow) + }) + .build(episode, difficulty, section_id)) + .build(episode, difficulty, section_id) + })) + .build()); + log_in_char(&mut ship, ClientId(1), "a1", "a").await; + log_in_char(&mut ship, ClientId(2), "a2", "a").await; + join_lobby(&mut ship, ClientId(1)).await; + join_lobby(&mut ship, ClientId(2)).await; + create_room(&mut ship, ClientId(1), "room", "").await; + join_room(&mut ship, ClientId(2), 0).await; + + let pkt = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::RequestItem(RequestItem { + client: 0, + target: 0, + map_area: 2, + pt_index: 0, + enemy_id: 0, + x: 0.0, + z: 0.0, + y: 0.0, + })))).await.unwrap(); + + assert_eq!(pkt[0].0, ClientId(1)); + match &pkt[0].1 { + SendShipPacket::Message(Message{msg: GameMessage::ItemDrop(item_drop)}) => { + assert_eq!(item_drop.item_id, 0x810001); + assert_eq!(item_drop.item_bytes[1], 0x9D); + }, + _ => panic!(), + } + assert_eq!(pkt[1].0, ClientId(2)); + match &pkt[1].1 { + SendShipPacket::Message(Message{msg: GameMessage::ItemDrop(item_drop)}) => { + assert_eq!(item_drop.item_id, 0x810002); + assert_eq!(item_drop.item_bytes[1], 0x9D); + }, + _ => panic!(), + } +} + +#[async_std::test] +async fn test_enemy_drops_item_for_two_players_and_pick_up() { + let mut entity_gateway = InMemoryGateway::default(); + let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await; + let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await; + + let mut ship = Box::new(ShipServerState::builder() + .gateway(entity_gateway.clone()) + .map_builder(Box::new(|_room_mode, _event| { + Maps::new( + vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)], + vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))], + Vec::new(), + ) + })) + .drop_table_builder(Box::new(|episode, difficulty, section_id| { + DropTable::builder() + .monster_stat(MonsterType::Hildebear, MonsterDropStats { + dar: 100, + drop_type: MonsterDropType::Weapon, + min_meseta: 0, + max_meseta: 0, + }) + .rare_table(RareDropTable::builder() + .rate(MonsterType::Hildebear, RareDropRate { + rate: 1.0, + item: RareDropItem::Weapon(WeaponType::DarkFlow) + }) + .build(episode, difficulty, section_id)) + .build(episode, difficulty, section_id) + })) + .build()); + log_in_char(&mut ship, ClientId(1), "a1", "a").await; + log_in_char(&mut ship, ClientId(2), "a2", "a").await; + join_lobby(&mut ship, ClientId(1)).await; + join_lobby(&mut ship, ClientId(2)).await; + create_room(&mut ship, ClientId(1), "room", "").await; + join_room(&mut ship, ClientId(2), 0).await; + + ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::RequestItem(RequestItem { + client: 0, + target: 0, + map_area: 2, + pt_index: 0, + enemy_id: 0, + x: 0.0, + z: 0.0, + y: 0.0, + })))).await.unwrap(); + + ship.handle(ClientId(2), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem { + client: 0, + target: 0, + item_id: 0x810002, + map_area: 0, + unknown: [0; 3] + })))).await.unwrap(); + + ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem { + client: 0, + target: 0, + item_id: 0x810001, + map_area: 0, + unknown: [0; 3] + })))).await.unwrap(); }