Browse Source

some comments and tests

pbs
andy 4 years ago
parent
commit
f3e7599975
  1. 42
      src/ship/items/inventory.rs
  2. 5
      src/ship/items/manager.rs
  3. 2
      tests/test_character.rs
  4. 218
      tests/test_item_equip.rs

42
src/ship/items/inventory.rs

@ -418,6 +418,48 @@ impl CharacterInventory {
}) })
} }
pub fn get_equipped_armor_handle<'a>(&'a mut self) -> Option<InventoryItemHandle<'a>> {
let (slot, _) = self.items.iter()
.enumerate()
.filter(|(_, item)| {
if let InventoryItem::Individual(individual_inventory_item) = item {if let ItemDetail::Armor(_) = &individual_inventory_item.item {return individual_inventory_item.equipped }}
false
})
.nth(0)?;
Some(InventoryItemHandle {
inventory: self,
slot: slot,
})
}
pub fn get_equipped_shield_handle<'a>(&'a mut self) -> Option<InventoryItemHandle<'a>> {
let (slot, _) = self.items.iter()
.enumerate()
.filter(|(_, item)| {
if let InventoryItem::Individual(individual_inventory_item) = item {if let ItemDetail::Shield(_) = &individual_inventory_item.item {return individual_inventory_item.equipped }}
false
})
.nth(0)?;
Some(InventoryItemHandle {
inventory: self,
slot: slot,
})
}
pub fn get_equipped_weapon_handle<'a>(&'a mut self) -> Option<InventoryItemHandle<'a>> {
let (slot, _) = self.items.iter()
.enumerate()
.filter(|(_, item)| {
if let InventoryItem::Individual(individual_inventory_item) = item {if let ItemDetail::Weapon(_) = &individual_inventory_item.item {return individual_inventory_item.equipped }}
false
})
.nth(0)?;
Some(InventoryItemHandle {
inventory: self,
slot: slot,
})
}
pub fn get_item_by_id(&self, item_id: ClientItemId) -> Option<&InventoryItem> { pub fn get_item_by_id(&self, item_id: ClientItemId) -> Option<&InventoryItem> {
self.items.iter() self.items.iter()
.filter(|item| { .filter(|item| {

5
src/ship/items/manager.rs

@ -46,6 +46,8 @@ pub enum ItemManagerError {
ItemIdNotInInventory(ClientItemId), ItemIdNotInInventory(ClientItemId),
CannotGetMutItem, CannotGetMutItem,
CannotGetIndividualItem, CannotGetIndividualItem,
InvalidSlot(u8, u8), // slots available, slot attempted
NoArmorEquipped,
} }
@ -896,6 +898,7 @@ impl ItemManager {
Ok(inventory_item) Ok(inventory_item)
} }
// TODO: check if slot exists before putting units into it
pub async fn player_equips_item<EG: EntityGateway>(&mut self, pub async fn player_equips_item<EG: EntityGateway>(&mut self,
entity_gateway: &mut EG, entity_gateway: &mut EG,
character: &CharacterEntity, character: &CharacterEntity,
@ -912,7 +915,7 @@ impl ItemManager {
inventory_item.item = ItemDetail::Unit(unit::Unit { inventory_item.item = ItemDetail::Unit(unit::Unit {
unit: u.unit, unit: u.unit,
modifier: u.modifier, modifier: u.modifier,
armor_slot: ((equip_slot & 0x7) - 1) % 4,
armor_slot: ((equip_slot & 0x7) - 1) % 4, // or just be lazy and do equip_slot - 9
}); });
} else { } else {
inventory_item.item = ItemDetail::Unit(unit::Unit { inventory_item.item = ItemDetail::Unit(unit::Unit {

2
tests/test_character.rs

@ -9,7 +9,7 @@ mod common;
use common::*; use common::*;
#[async_std::test] #[async_std::test]
async fn test_save_options<EG: EntityGateway>(ship: &mut ShipServerState<EG>, id: ClientId, options: u32) {
async fn test_save_options() {
let mut entity_gateway = InMemoryGateway::new(); let mut entity_gateway = InMemoryGateway::new();
let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await;

218
tests/test_item_equip.rs

@ -0,0 +1,218 @@
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;
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).await;
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).await;
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);
}
Loading…
Cancel
Save