use networking::serverstate::{ClientId, ServerState}; use entity::gateway::InMemoryGateway; use ship_server::{SendShipPacket, RecvShipPacket}; use maps::monster::MonsterType; use drops::{StandardDropTable, MonsterDropStats, MonsterDropType}; use drops::rare_drop_table::{RareDropTable, RareDropRate, RareDropItem}; use maps::maps::Maps; use maps::area::MapArea; use maps::variant::{MapVariant, MapVariantMode}; use maps::enemy::MapEnemy; use entity::item::weapon::WeaponType; use libpso::packet::ship::*; use libpso::packet::messages::*; #[path = "common.rs"] mod common; use common::*; #[async_std::test] async fn test_enemy_drops_item() { let mut entity_gateway = InMemoryGateway::default(); let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let mut ship = standard_ship_buildable(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| { StandardDropTable::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; join_lobby(&mut ship, ClientId(1)).await; create_room(&mut ship, ClientId(1), "room", "").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(); 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!(), } } #[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").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut ship = standard_ship_buildable(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| { StandardDropTable::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").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let mut ship = standard_ship_buildable(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| { StandardDropTable::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(); }