use elseware::common::serverstate::{ClientId, ServerState}; use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; use elseware::ship::ship::{ShipServerState, RecvShipPacket}; use elseware::entity::item; use libpso::packet::ship::*; use libpso::packet::messages::*; #[path = "common.rs"] mod common; use common::*; #[async_std::test] async fn test_equip_unit_from_equip_menu() { let mut entity_gateway = InMemoryGateway::new(); let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Armor( item::armor::Armor{ armor: item::armor::ArmorType::Frame, dfp: 0, evp: 0, slots: 4, modifiers: Vec::new(), }), location: item::ItemLocation::Inventory { character_id: char1.id, slot: 0, equipped: true, } }).await.unwrap(); entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ unit: item::unit::UnitType::KnightPower, modifier: None, armor_slot: 0, }), location: item::ItemLocation::Inventory { character_id: char1.id, slot: 1, equipped: false, } }).await.unwrap(); entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ unit: item::unit::UnitType::KnightPower, modifier: Some(item::unit::UnitModifier::Plus), armor_slot: 0, }), location: item::ItemLocation::Inventory { character_id: char1.id, slot: 2, equipped: false, } }).await.unwrap(); let mut ship = ShipServerState::builder() .gateway(entity_gateway.clone()) .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; ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerEquipItem(PlayerEquipItem { client: 0, target: 0, item_id: 0x10001, sub_menu: 9, unknown1: 0, })))).await.unwrap().for_each(drop); // case when someone tries to send invalid submenu? submenu is 9-12 in normal gameplay ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerEquipItem(PlayerEquipItem { client: 0, target: 0, item_id: 0x10002, sub_menu: 14, unknown1: 0, })))).await.unwrap().for_each(drop); let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); let (unit1, unit2) = (&items[1], &items[2]); let unit1_equipped = match unit1.location { item::ItemLocation::Inventory{equipped, ..} => equipped, _ => false, }; let unit2_equipped = match unit2.location { item::ItemLocation::Inventory{equipped, ..} => equipped, _ => false, }; assert!({ match unit1.item { item::ItemDetail::Unit(u) => { if u.armor_slot == 0 && unit1_equipped { true } else { false } }, _ => false, } }); assert!({ match unit2.item { item::ItemDetail::Unit(u) => { if u.armor_slot == 1 && unit2_equipped { true } else { false } }, _ => false, } }); } #[async_std::test] async fn test_unequip_armor_with_units() { let mut entity_gateway = InMemoryGateway::new(); let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Armor( item::armor::Armor{ armor: item::armor::ArmorType::Frame, dfp: 0, evp: 0, slots: 4, modifiers: Vec::new(), }), location: item::ItemLocation::Inventory { character_id: char1.id, slot: 0, equipped: true, } }).await; entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ unit: item::unit::UnitType::KnightPower, modifier: None, armor_slot: 0, }), location: item::ItemLocation::Inventory { character_id: char1.id, slot: 1, equipped: true, } }).await.unwrap(); entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ unit: item::unit::UnitType::KnightPower, modifier: Some(item::unit::UnitModifier::Plus), armor_slot: 1, }), location: item::ItemLocation::Inventory { character_id: char1.id, slot: 2, equipped: true, } }).await.unwrap(); let mut ship = ShipServerState::builder() .gateway(entity_gateway.clone()) .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; ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerUnequipItem(PlayerUnequipItem { client: 0, target: 0, item_id: 0x10000, unknown1: 0, })))).await.unwrap().for_each(drop); let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); let (armor, unit1, unit2) = (&items[0], &items[1], &items[2]); let armor_equipped = match armor.location { item::ItemLocation::Inventory{equipped, ..} => equipped, _ => true, }; let unit1_equipped = match unit1.location { item::ItemLocation::Inventory{equipped, ..} => equipped, _ => true, }; let unit2_equipped = match unit2.location { item::ItemLocation::Inventory{equipped, ..} => equipped, _ => true, }; assert!(armor_equipped == false); assert!(unit1_equipped == false); assert!(unit2_equipped == false); } #[async_std::test] async fn test_sort_items() { let mut entity_gateway = InMemoryGateway::new(); let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Armor( item::armor::Armor{ armor: item::armor::ArmorType::Frame, dfp: 0, evp: 0, slots: 4, modifiers: Vec::new(), }), location: item::ItemLocation::Inventory { character_id: char1.id, slot: 0, equipped: true, } }).await; entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ unit: item::unit::UnitType::KnightPower, modifier: None, armor_slot: 0, }), location: item::ItemLocation::Inventory { character_id: char1.id, slot: 1, equipped: false, } }).await; entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ unit: item::unit::UnitType::KnightPower, modifier: Some(item::unit::UnitModifier::Plus), armor_slot: 0, }), location: item::ItemLocation::Inventory { character_id: char1.id, slot: 2, equipped: false, } }).await; let mut ship = ShipServerState::builder() .gateway(entity_gateway.clone()) .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 old_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); assert!(old_items[0].item.item_type() == item::ItemType::Armor(item::armor::ArmorType::Frame)); assert!(old_items[0].location == item::ItemLocation::Inventory{ character_id: char1.id, slot: 0, equipped: true, }); ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::SortItems(SortItems { client: 255, target: 255, item_ids: [0x10001u32, 0x10002, 0x10000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF], })))).await.unwrap().for_each(drop); let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); assert!(items[0].item.item_type() == item::ItemType::Armor(item::armor::ArmorType::Frame)); assert!(items[0].location == item::ItemLocation::Inventory{ character_id: char1.id, slot: 2, equipped: true, }); }