diff --git a/src/bin/main.rs b/src/bin/main.rs index 70820a6..7a91eab 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -109,7 +109,7 @@ fn main() { }).await.unwrap(); } - entity_gateway.create_item( + let item0 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { @@ -125,11 +125,9 @@ fn main() { ), location: ItemLocation::Inventory { character_id: character.id, - slot: 0, - equipped: false, } }).await.unwrap(); - entity_gateway.create_item( + let item1 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { @@ -145,11 +143,9 @@ fn main() { ), location: ItemLocation::Inventory { character_id: character.id, - slot: 1, - equipped: false, } }).await.unwrap(); - entity_gateway.create_item( + let item2_w = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { @@ -165,11 +161,9 @@ fn main() { ), location: ItemLocation::Inventory { character_id: character.id, - slot: 2, - equipped: true, } }).await.unwrap(); - entity_gateway.create_item( + let item3 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { @@ -185,11 +179,9 @@ fn main() { ), location: ItemLocation::Inventory { character_id: character.id, - slot: 3, - equipped: false, } }).await.unwrap(); - entity_gateway.create_item( + let item4 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { @@ -205,22 +197,18 @@ fn main() { ), location: ItemLocation::Inventory { character_id: character.id, - slot: 4, - equipped: false, } }).await.unwrap(); - let mag = entity_gateway.create_item( + let item5_m = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Mag(item::mag::Mag::baby_mag(0)), location: item::ItemLocation::Inventory { character_id: character.id, - slot: 5, - equipped: true, } }).await.unwrap(); - for _ in 0..10 { + for _ in 0..10usize { let fed_tool = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Tool ( @@ -229,15 +217,14 @@ fn main() { } ), location: item::ItemLocation::FedToMag { - mag: mag.id, + mag: item5_m.id, } }).await.unwrap(); - entity_gateway.feed_mag(&mag.id, &fed_tool.id).await.unwrap(); + entity_gateway.feed_mag(&item5_m.id, &fed_tool.id).await.unwrap(); } - //entity_gateway.bank(&mag.id).await; - entity_gateway.change_mag_owner(&mag.id, &character).await.unwrap(); + entity_gateway.change_mag_owner(&item5_m.id, &character).await.unwrap(); - entity_gateway.create_item( + let item6 = entity_gateway.create_item( item::NewItemEntity { item: ItemDetail::Tool ( item::tool::Tool { @@ -246,8 +233,6 @@ fn main() { ), location: item::ItemLocation::Inventory { character_id: character.id, - slot: 6, - equipped: true, } }).await.unwrap(); let cell = entity_gateway.create_item( @@ -259,7 +244,7 @@ fn main() { ), location: item::ItemLocation::Consumed, }).await.unwrap(); - entity_gateway.use_mag_cell(&mag.id, &cell.id).await.unwrap(); + entity_gateway.use_mag_cell(&item5_m.id, &cell.id).await.unwrap(); entity_gateway.create_item( NewItemEntity { @@ -279,8 +264,8 @@ fn main() { character_id: character.id, name: item::BankName("".to_string()), } - }).await; - entity_gateway.create_item( + }).await.unwrap(); + let item7_a = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Armor( item::armor::Armor { @@ -293,12 +278,10 @@ fn main() { ), location: ItemLocation::Inventory { character_id: character.id, - slot: 5, - equipped: true, } } - ).await; - entity_gateway.create_item( + ).await.unwrap(); + let item8_s = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Shield( item::shield::Shield { @@ -309,28 +292,24 @@ fn main() { ), location: ItemLocation::Inventory { character_id: character.id, - slot: 6, - equipped: true, } } - ).await; - entity_gateway.create_item( + ).await.unwrap(); + let item9_u0 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { unit: item::unit::UnitType::PriestMind, modifier: Some(item::unit::UnitModifier::Minus), - armor_slot: 0, + armor_slot: 0, // TODO: get rid of this } ), location: ItemLocation::Inventory { character_id: character.id, - slot: 7, - equipped: true, } } - ).await; - entity_gateway.create_item( + ).await.unwrap(); + let item10_u1 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { @@ -341,12 +320,10 @@ fn main() { ), location: ItemLocation::Inventory { character_id: character.id, - slot: 8, - equipped: true, } } - ).await; - entity_gateway.create_item( + ).await.unwrap(); + let item11_u2 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { @@ -357,12 +334,10 @@ fn main() { ), location: ItemLocation::Inventory { character_id: character.id, - slot: 9, - equipped: true, } } - ).await; - entity_gateway.create_item( + ).await.unwrap(); + let item12_u3 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { @@ -373,23 +348,31 @@ fn main() { ), location: ItemLocation::Inventory { character_id: character.id, - slot: 10, - equipped: true, } } - ).await; - entity_gateway.create_item( + ).await.unwrap(); + let item13 = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Mag( item::mag::Mag::baby_mag(5) ), location: ItemLocation::Inventory { character_id: character.id, - slot: 11, - equipped: true, } } - ).await; + ).await.unwrap(); + + let equipped = item::EquippedEntity { + weapon: Some(item2_w.id), + armor: Some(item7_a.id), + shield: Some(item8_s.id), + unit: [Some(item9_u0.id), Some(item10_u1.id), Some(item11_u2.id), Some(item12_u3.id)], + mag: Some(item5_m.id), + }; + entity_gateway.set_character_equips(&character.id, &equipped).await.unwrap(); + + let inventory = item::InventoryEntity::new(vec![item0, item1, item2_w, item3, item4, item5_m, item6, item7_a, item8_s, item9_u0, item10_u1, item11_u2, item12_u3, item13]); + entity_gateway.set_character_inventory(&character.id, &inventory).await.unwrap(); } info!("[patch] starting server"); diff --git a/src/entity/gateway/entitygateway.rs b/src/entity/gateway/entitygateway.rs index 1327eaf..57d2b8c 100644 --- a/src/entity/gateway/entitygateway.rs +++ b/src/entity/gateway/entitygateway.rs @@ -65,6 +65,7 @@ pub trait EntityGateway: Send + Sync + Clone { unimplemented!(); } + // TODO: remove async fn change_item(&mut self, _id: &ItemEntityId, _item: &ItemDetail) -> Result<(), GatewayError> { unimplemented!(); } @@ -85,7 +86,33 @@ pub trait EntityGateway: Send + Sync + Clone { unimplemented!(); } + /* async fn get_items_by_character(&self, _char_id: &CharacterEntityId) -> Result, GatewayError> { unimplemented!(); } + */ + + async fn get_character_inventory(&mut self, _char_id: &CharacterEntityId) -> Result { + unimplemented!(); + } + + async fn get_character_bank(&mut self, _char_id: &CharacterEntityId, _bank_name: BankName) -> Result { + unimplemented!(); + } + + async fn set_character_inventory(&mut self, _char_id: &CharacterEntityId, _inventory: &InventoryEntity) -> Result<(), GatewayError> { + unimplemented!(); + } + + async fn set_character_bank(&mut self, _char_id: &CharacterEntityId, _inventory: &BankEntity, _bank_name: BankName) -> Result<(), GatewayError> { + unimplemented!(); + } + + async fn get_character_equips(&mut self, _char_id: &CharacterEntityId) -> Result { + unimplemented!(); + } + + async fn set_character_equips(&mut self, _char_id: &CharacterEntityId, _equips: &EquippedEntity) -> Result<(), GatewayError> { + unimplemented!(); + } } diff --git a/src/entity/gateway/inmemory.rs b/src/entity/gateway/inmemory.rs index e943376..04924ab 100644 --- a/src/entity/gateway/inmemory.rs +++ b/src/entity/gateway/inmemory.rs @@ -14,6 +14,9 @@ pub struct InMemoryGateway { user_settings: Arc>>, characters: Arc>>, items: Arc>>, + inventories: Arc>>, + banks: Arc>>, + equips: Arc>>, mag_modifiers: Arc>>>, } @@ -24,11 +27,66 @@ impl InMemoryGateway { user_settings: Arc::new(Mutex::new(BTreeMap::new())), characters: Arc::new(Mutex::new(BTreeMap::new())), items: Arc::new(Mutex::new(BTreeMap::new())), + inventories: Arc::new(Mutex::new(BTreeMap::new())), + banks: Arc::new(Mutex::new(BTreeMap::new())), + equips: Arc::new(Mutex::new(BTreeMap::new())), mag_modifiers: Arc::new(Mutex::new(BTreeMap::new())), } } } +impl InMemoryGateway { + fn apply_modifiers(&self, inventory: InventoryEntity ) -> InventoryEntity { + let items = self.items.lock().unwrap(); + let inventory_items = inventory.items.into_iter() + .map(|item| { + item.map_individual(|mut item| { + item.item = match item.item { + ItemDetail::Mag(mag) => { + let mut mag = mag::Mag::baby_mag(mag.color as u16); + println!("mag! {:?}", mag); + if let Some(mag_modifiers) = self.mag_modifiers.lock().unwrap().get(&item.id) { + for mag_modifier in mag_modifiers.iter() { + match mag_modifier { + mag::MagModifier::FeedMag {food} => { + items.get(&food).map(|mag_feed| { + match mag_feed.item { + ItemDetail::Tool(mag_feed) => mag.feed(mag_feed.tool), + _ => {} + } + }); + }, + mag::MagModifier::OwnerChange(class, section_id) => { + mag.change_owner(*class, *section_id) + }, + mag::MagModifier::MagCell(mag_cell_id) => { + items.get(&mag_cell_id).map(|mag_cell| { + match mag_cell.item { + ItemDetail::Tool(mag_cell) => mag.apply_mag_cell(mag_cell.tool.try_into().unwrap()), + _ => {} + } + }); + }, + _ => {} + } + println!("{:?} -> {:?}", mag_modifier, mag); + } + } + ItemDetail::Mag(mag) + } + _ => { + item.item + } + }; + + item + }) + }) + .collect(); + InventoryEntity::new(inventory_items) + } +} + #[async_trait::async_trait] impl EntityGateway for InMemoryGateway { async fn create_user(&mut self, user: NewUserAccountEntity) -> Result { @@ -208,55 +266,51 @@ impl EntityGateway for InMemoryGateway { Ok(()) } - async fn get_items_by_character(&self, char_id: &CharacterEntityId) -> Result, GatewayError> { - let items = self.items.lock().unwrap(); - Ok(items + async fn get_character_inventory(&mut self, char_id: &CharacterEntityId) -> Result { + println!("getting inv"); + let inventories = self.inventories.lock().unwrap(); + Ok(inventories + .iter() + .find(|(id, _)| **id == *char_id) + .map(|(_, inv)| inv.clone()) + .map(|inv| self.apply_modifiers(inv)) + .unwrap_or(InventoryEntity::default())) + } + + async fn get_character_bank(&mut self, char_id: &CharacterEntityId, _bank_name: BankName) -> Result { + let banks = self.banks.lock().unwrap(); + Ok(banks + .iter() + .find(|(id, _)| **id == *char_id) + .map(|(_, b)| b.clone()) + .unwrap_or(BankEntity::default())) + } + + async fn set_character_inventory(&mut self, char_id: &CharacterEntityId, inventory: &InventoryEntity) -> Result<(), GatewayError> { + let mut inventories = self.inventories.lock().unwrap(); + inventories.insert(*char_id, inventory.clone()); + Ok(()) + } + + // TOOD: impl bank name + async fn set_character_bank(&mut self, char_id: &CharacterEntityId, bank: &BankEntity, _bank_name: BankName) -> Result<(), GatewayError> { + let mut banks = self.banks.lock().unwrap(); + banks.insert(*char_id, bank.clone()); + Ok(()) + } + + async fn get_character_equips(&mut self, char_id: &CharacterEntityId) -> Result { + let equips = self.equips.lock().unwrap(); + Ok(equips .iter() - .filter(|(_, k)| { - match k.location { - ItemLocation::Inventory{character_id, ..} => character_id == *char_id, - ItemLocation::Bank{character_id, ..} => character_id == *char_id, - _ => false - } - }) - .map(|(_, k)| { - k.clone() - }) - .map(|mut item| { - item.item = match item.item { - ItemDetail::Mag(mut mag) => { - self.mag_modifiers.lock().unwrap().get(&item.id).map(|mag_modifiers| { - for mag_modifier in mag_modifiers.iter() { - match mag_modifier { - mag::MagModifier::FeedMag {food} => { - items.get(&food).map(|mag_feed| { - match mag_feed.item { - ItemDetail::Tool(mag_feed) => mag.feed(mag_feed.tool), - _ => {} - } - }); - }, - mag::MagModifier::OwnerChange(class, section_id) => { - mag.change_owner(*class, *section_id) - }, - mag::MagModifier::MagCell(mag_cell_id) => { - items.get(&mag_cell_id).map(|mag_cell| { - match mag_cell.item { - ItemDetail::Tool(mag_cell) => mag.apply_mag_cell(mag_cell.tool.try_into().unwrap()), - _ => {} - } - }); - }, - _ => {} - } - } - }); - ItemDetail::Mag(mag) - } - _ => item.item - }; - item - }) - .collect()) + .find(|(id, _)| **id == *char_id) + .map(|(_, inv)| inv.clone()) + .unwrap_or(EquippedEntity::default())) + } + + async fn set_character_equips(&mut self, char_id: &CharacterEntityId, equipped: &EquippedEntity) -> Result<(), GatewayError> { + let mut equips = self.equips.lock().unwrap(); + equips.insert(*char_id, equipped.clone()); + Ok(()) } } diff --git a/src/entity/gateway/postgres/models.rs b/src/entity/gateway/postgres/models.rs index b870da5..3f795a8 100644 --- a/src/entity/gateway/postgres/models.rs +++ b/src/entity/gateway/postgres/models.rs @@ -383,7 +383,7 @@ impl Into for PgShield { pub struct PgUnit { unit: unit::UnitType, modifier: Option, - armor_slot: u8, + //armor_slot: u8, } impl From for PgUnit { @@ -391,7 +391,7 @@ impl From for PgUnit { PgUnit { unit: other.unit, modifier: other.modifier, - armor_slot: other.armor_slot, + //armor_slot: other.armor_slot, } } } @@ -401,7 +401,7 @@ impl Into for PgUnit { unit::Unit { unit: self.unit, modifier: self.modifier, - armor_slot: self.armor_slot, + armor_slot: 0, } } } @@ -573,9 +573,9 @@ pub struct PgItem { pub enum PgItemLocationDetail { Inventory { character_id: u32, - #[serde(skip_serializing)] - slot: usize, - equipped: bool, + //#[serde(skip_serializing)] + //slot: usize, + //equipped: bool, }, Bank { character_id: u32, @@ -604,7 +604,7 @@ pub enum PgItemLocationDetail { impl From for PgItemLocationDetail { fn from(other: ItemLocation) -> PgItemLocationDetail { match other { - ItemLocation::Inventory{character_id, slot, equipped} => PgItemLocationDetail::Inventory{character_id: character_id.0, slot, equipped}, + ItemLocation::Inventory{character_id} => PgItemLocationDetail::Inventory{character_id: character_id.0}, ItemLocation::Bank{character_id, name} => PgItemLocationDetail::Bank{character_id: character_id.0, name: name.0}, ItemLocation::LocalFloor{character_id, map_area, x,y,z} => PgItemLocationDetail::LocalFloor{character_id: character_id.0, map_area, x,y,z}, ItemLocation::SharedFloor{map_area, x,y,z} => PgItemLocationDetail::SharedFloor{map_area, x,y,z}, @@ -618,7 +618,7 @@ impl From for PgItemLocationDetail { impl Into for PgItemLocationDetail { fn into(self) -> ItemLocation { match self { - PgItemLocationDetail::Inventory{character_id, slot, equipped} => ItemLocation::Inventory{character_id: CharacterEntityId(character_id), slot, equipped}, + PgItemLocationDetail::Inventory{character_id} => ItemLocation::Inventory{character_id: CharacterEntityId(character_id)}, PgItemLocationDetail::Bank{character_id, name} => ItemLocation::Bank{character_id: CharacterEntityId(character_id), name: BankName(name)}, PgItemLocationDetail::LocalFloor{character_id, map_area, x,y,z} => ItemLocation::LocalFloor{character_id: CharacterEntityId(character_id), map_area, x,y,z}, PgItemLocationDetail::SharedFloor{map_area, x,y,z} => ItemLocation::SharedFloor{map_area, x,y,z}, diff --git a/src/entity/gateway/postgres/postgres.rs b/src/entity/gateway/postgres/postgres.rs index bbc8d39..a999c94 100644 --- a/src/entity/gateway/postgres/postgres.rs +++ b/src/entity/gateway/postgres/postgres.rs @@ -272,6 +272,8 @@ impl EntityGateway for PostgresGateway { } async fn create_item(&mut self, item: NewItemEntity) -> Result { + unimplemented!(); + /* let mut tx = self.pool.begin().await?; let new_item = sqlx::query_as::<_, PgItem>("insert into item (item) values ($1) returning *;") .bind(sqlx::types::Json(PgItemDetail::from(item.item))) @@ -310,6 +312,7 @@ impl EntityGateway for PostgresGateway { item: new_item.item.0.into(), location: location.location.0.into(), }) + */ } async fn change_item(&mut self, id: &ItemEntityId, item: &ItemDetail) -> Result<(), GatewayError> { @@ -321,6 +324,8 @@ impl EntityGateway for PostgresGateway { } async fn change_item_location(&mut self, item_id: &ItemEntityId, item_location: ItemLocation) -> Result<(), GatewayError> { + unimplemented!(); + /* let mut tx = self.pool.begin().await?; if let ItemLocation::Inventory{slot, ..} = &item_location { sqlx::query("delete from inventory_slot where item = $1") @@ -346,6 +351,7 @@ impl EntityGateway for PostgresGateway { } tx.commit().await?; Ok(()) + */ } async fn feed_mag(&mut self, mag_item_id: &ItemEntityId, tool_item_id: &ItemEntityId) -> Result<(), GatewayError> { @@ -371,7 +377,7 @@ impl EntityGateway for PostgresGateway { .execute(&self.pool).await?; Ok(()) } - +/* async fn get_items_by_character(&self, char_id: &CharacterEntityId) -> Result, GatewayError> { let q = r#"select * from ( select distinct on (item_location.item) @@ -410,4 +416,28 @@ impl EntityGateway for PostgresGateway { .await ).await) } +*/ + async fn get_character_inventory(&mut self, _char_id: &CharacterEntityId) -> Result { + unimplemented!(); + } + + async fn get_character_bank(&mut self, _char_id: &CharacterEntityId, _bank_name: BankName) -> Result { + unimplemented!(); + } + + async fn set_character_inventory(&mut self, _char_id: &CharacterEntityId, _inventory: &InventoryEntity) -> Result<(), GatewayError> { + unimplemented!(); + } + + async fn set_character_bank(&mut self, _char_id: &CharacterEntityId, _inventory: &BankEntity, _bank_name: BankName) -> Result<(), GatewayError> { + unimplemented!(); + } + + async fn get_character_equips(&mut self, _char_id: &CharacterEntityId) -> Result { + unimplemented!(); + } + + async fn set_character_equips(&mut self, _char_id: &CharacterEntityId, _equips: &EquippedEntity) -> Result<(), GatewayError> { + unimplemented!(); + } } diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index d3629cc..a1aa305 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -24,8 +24,6 @@ pub struct BankName(pub String); pub enum ItemLocation { Inventory { character_id: CharacterEntityId, - slot: usize, - equipped: bool, }, Bank { character_id: CharacterEntityId, @@ -154,6 +152,13 @@ impl ItemDetail { ItemDetail::ESWeapon(e) => e.as_bytes(), } } + + pub fn as_tool(self) -> Option { + match self { + ItemDetail::Tool(tool) => Some(tool), + _ => None, + } + } } #[derive(Clone, Debug)] @@ -168,3 +173,131 @@ pub struct ItemEntity { pub location: ItemLocation, pub item: ItemDetail, } + + +#[derive(Clone, Debug)] +pub enum InventoryItemEntity { + Individual(ItemEntity), + Stacked(Vec), +} + +impl std::convert::From for InventoryItemEntity { + fn from(item: ItemEntity) -> InventoryItemEntity { + InventoryItemEntity::Individual(item) + } +} + +impl std::convert::From> for InventoryItemEntity { + fn from(items: Vec) -> InventoryItemEntity { + InventoryItemEntity::Stacked(items) + } +} + +impl InventoryItemEntity { + pub fn map_individual ItemEntity>(self, func: F) -> InventoryItemEntity { + match self { + InventoryItemEntity::Individual(item) => InventoryItemEntity::Individual(func(item)), + _ => self, + } + } + //pub fn with_individual(&self, func: fn(&ItemEntity) -> T) -> Option { + pub fn with_individual T, T>(&self, func: F) -> Option { + match self { + InventoryItemEntity::Individual(item) => Some(func(item)), + _ => None, + } + } + + //pub fn with_stacked(&self, func: fn(&Vec) -> T) -> Option { + pub fn with_stacked) -> T, T>(&self, func: F) -> Option { + match self { + InventoryItemEntity::Stacked(items) => Some(func(items)), + _ => None, + } + } +} + +#[derive(Clone, Debug, Default)] +pub struct EquippedEntity { + pub weapon: Option, + pub armor: Option, + pub shield: Option, + pub unit: [Option; 4], + pub mag: Option, +} + +impl EquippedEntity { + pub fn is_equipped(&self, item: &ItemEntityId) -> bool { + self.weapon == Some(*item) + || self.armor == Some(*item) + || self.shield == Some(*item) + || self.unit[0] == Some(*item) + || self.unit[1] == Some(*item) + || self.unit[2] == Some(*item) + || self.unit[3] == Some(*item) + || self.mag == Some(*item) + } +} + +#[derive(Clone, Debug, Default)] +pub struct InventoryEntity { + pub items: Vec, +} + +impl InventoryEntity { + pub fn new>(items: Vec) -> InventoryEntity { + InventoryEntity { + items: items.into_iter().map(|i| i.into()).collect(), + } + } +} + + +#[derive(Clone, Debug)] +pub enum BankItemEntity { + Individual(ItemEntity), + Stacked(Vec), +} + +impl std::convert::From for BankItemEntity { + fn from(item: ItemEntity) -> BankItemEntity { + BankItemEntity::Individual(item) + } +} + +impl std::convert::From> for BankItemEntity { + fn from(items: Vec) -> BankItemEntity { + BankItemEntity::Stacked(items) + } +} + +impl BankItemEntity { + pub fn with_individual(&self, func: fn(&ItemEntity) -> T) -> Option { + match self { + BankItemEntity::Individual(item) => Some(func(item)), + _ => None, + } + } + + pub fn with_stacked(&self, func: fn(&Vec) -> T) -> Option { + match self { + BankItemEntity::Stacked(items) => Some(func(items)), + _ => None, + } + } +} + + +#[derive(Clone, Debug, Default)] +pub struct BankEntity { + //pub items: [Option; 30], + pub items: Vec, +} + +impl BankEntity { + pub fn new>(items: Vec) -> BankEntity { + BankEntity { + items: items.into_iter().map(|i| i.into()).collect(), + } + } +} diff --git a/src/login/character.rs b/src/login/character.rs index d720e4e..3ec42b8 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -19,7 +19,7 @@ use libpso::{utf8_to_array, utf8_to_utf16_array}; use crate::entity::gateway::EntityGateway; use crate::entity::account::{UserAccountEntity, NewUserSettingsEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; -use crate::entity::item::{NewItemEntity, ItemDetail, ItemLocation}; +use crate::entity::item::{NewItemEntity, ItemDetail, ItemLocation, InventoryItemEntity, InventoryEntity, BankEntity, BankName, EquippedEntity}; use crate::entity::item::weapon::Weapon; use crate::entity::item::armor::Armor; use crate::entity::item::tech::Technique; @@ -198,7 +198,7 @@ async fn new_character(entity_gateway: &mut EG, user: &UserAc }; - entity_gateway.create_item( + let weapon = entity_gateway.create_item( NewItemEntity { item : ItemDetail::Weapon( Weapon { @@ -211,11 +211,9 @@ async fn new_character(entity_gateway: &mut EG, user: &UserAc }), location: ItemLocation::Inventory { character_id: character.id, - slot: 0, - equipped: true, }}).await.unwrap(); - entity_gateway.create_item( + let armor = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Armor ( Armor { @@ -227,23 +225,20 @@ async fn new_character(entity_gateway: &mut EG, user: &UserAc }), location: ItemLocation::Inventory { character_id: character.id, - slot: 1, - equipped: true, }}).await.unwrap(); let mut mag = Mag::baby_mag(character.appearance.skin); mag.change_owner(character.char_class, character.section_id); - entity_gateway.create_item( + let mag = entity_gateway.create_item( NewItemEntity { item: ItemDetail::Mag(mag), location: ItemLocation::Inventory { character_id: character.id, - slot: 2, - equipped: true, }}).await.unwrap(); - for _ in 0..4 { - entity_gateway.create_item( + let mut monomates = Vec::new(); + for _ in 0..4usize { + monomates.push(entity_gateway.create_item( NewItemEntity { item: ItemDetail::Tool ( Tool { @@ -251,10 +246,12 @@ async fn new_character(entity_gateway: &mut EG, user: &UserAc }), location: ItemLocation::Inventory { character_id: character.id, - slot: 3, - equipped: false, - }}).await.unwrap(); - entity_gateway.create_item( + }}).await.unwrap()) + } + + let mut monofluids = Vec::new(); + for _ in 0..4usize { + monofluids.push(entity_gateway.create_item( NewItemEntity { item: ItemDetail::Tool ( Tool { @@ -262,10 +259,20 @@ async fn new_character(entity_gateway: &mut EG, user: &UserAc }), location: ItemLocation::Inventory { character_id: character.id, - slot: 4, - equipped: false, - }}).await.unwrap(); + }}).await.unwrap()) } + + let inventory = InventoryEntity { + items: vec![InventoryItemEntity::Individual(weapon.clone()), InventoryItemEntity::Individual(armor.clone()), InventoryItemEntity::Individual(mag.clone()), + InventoryItemEntity::Stacked(monomates), InventoryItemEntity::Stacked(monofluids)], + }; + entity_gateway.set_character_inventory(&character.id, &inventory); + entity_gateway.set_character_bank(&character.id, &BankEntity::default(), BankName("".into())); + let mut equipped = EquippedEntity::default(); + equipped.weapon = Some(weapon.id); + equipped.armor = Some(armor.id); + equipped.mag = Some(mag.id); + entity_gateway.set_character_equips(&character.id, &equipped); } diff --git a/src/ship/items/bank.rs b/src/ship/items/bank.rs index 2bbe097..e5fc03e 100644 --- a/src/ship/items/bank.rs +++ b/src/ship/items/bank.rs @@ -1,6 +1,7 @@ use crate::ship::items::ClientItemId; use libpso::character::character;//::InventoryItem; -use crate::entity::item::{ItemEntityId, ItemDetail}; +use crate::entity::item::{ItemEntityId, ItemEntity, ItemDetail, ItemLocation, BankEntity, BankItemEntity, BankName}; +use crate::entity::character::CharacterEntityId; use crate::entity::item::tool::Tool; use crate::ship::items::inventory::{InventoryItemHandle, InventoryItem}; @@ -292,6 +293,41 @@ impl CharacterBank { self.items.last() } + + pub fn as_bank_entity(&self, character_id: &CharacterEntityId, bank_name: &BankName) -> BankEntity { + BankEntity { + items: self.items.iter() + .map(|item| { + match item { + BankItem::Individual(item) => { + BankItemEntity::Individual(ItemEntity { + id: item.entity_id, + location: ItemLocation::Bank { + character_id: *character_id, + name: bank_name.clone(), + }, + item: item.item.clone(), + }) + }, + BankItem::Stacked(items) => { + BankItemEntity::Stacked(items.entity_ids.iter() + .map(|id| { + ItemEntity { + id: *id, + location: ItemLocation::Bank { + character_id: *character_id, + name: bank_name.clone(), + }, + item: ItemDetail::Tool(items.tool) + } + }) + .collect()) + }, + } + }) + .collect() + } + } } diff --git a/src/ship/items/inventory.rs b/src/ship/items/inventory.rs index 6360037..d915c98 100644 --- a/src/ship/items/inventory.rs +++ b/src/ship/items/inventory.rs @@ -1,7 +1,8 @@ use std::cmp::Ordering; use thiserror::Error; use libpso::character::character;//::InventoryItem; -use crate::entity::item::{ItemEntityId, ItemDetail, ItemType}; +use crate::entity::character::CharacterEntityId; +use crate::entity::item::{ItemEntityId, ItemDetail, ItemEntity, ItemType, ItemLocation, InventoryEntity, InventoryItemEntity, EquippedEntity}; use crate::entity::item::tool::Tool; use crate::entity::item::mag::Mag; use crate::ship::items::{ClientItemId, BankItem, BankItemHandle}; @@ -217,6 +218,8 @@ impl InventoryItem { } + + #[derive(Error, Debug, Clone)] #[error("")] pub enum InventoryItemConsumeError { @@ -287,7 +290,7 @@ impl<'a> InventoryItemHandle<'a> { EntireThing(ConsumedItem), Partial(Tool), } - + let inventory_item = self.inventory.items.get(self.slot).ok_or(InventoryItemConsumeError::InconsistentState)?; let remove_method = match inventory_item { InventoryItem::Individual(individual_inventory_item) => { @@ -390,7 +393,7 @@ impl CharacterInventory { pub fn count(&self) -> usize { self.items.len() } - + pub fn get_item_handle_by_id<'a>(&'a mut self, item_id: ClientItemId) -> Option> { let (slot, _) = self.items.iter() .enumerate() @@ -549,7 +552,7 @@ impl CharacterInventory { item_id: floor_item.item_id, tool: floor_item.tool, }); - + self.items.push(new_stacked_item); if let Some(InventoryItem::Stacked(new_item)) = self.items.last() { Some((new_item, InventorySlot(self.count()-1))) @@ -572,7 +575,7 @@ impl CharacterInventory { item: individual_bank_item.item.clone(), equipped: false, })); - (true, self.count()) + (true, self.count()-1) }, BankItem::Stacked(stacked_bank_item) => { let existing_inventory_item = self.items.iter_mut() @@ -608,7 +611,7 @@ impl CharacterInventory { item_id: ClientItemId(self.item_id_counter), tool: stacked_bank_item.tool, })); - self.count() + self.count()-1 } }; (stacked_bank_item.count() == 0, slot) @@ -635,5 +638,60 @@ impl CharacterInventory { pub fn set_items(&mut self, sorted_items: Vec) { self.items = sorted_items; } + + pub fn as_inventory_entity(&self, character_id: &CharacterEntityId) -> InventoryEntity { + InventoryEntity { + items: self.items.iter() + .map(|item| { + match item { + InventoryItem::Individual(item) => { + InventoryItemEntity::Individual(ItemEntity { + id: item.entity_id, + location: ItemLocation::Inventory { + character_id: *character_id, + }, + item: item.item.clone(), + }) + }, + InventoryItem::Stacked(items) => { + InventoryItemEntity::Stacked(items.entity_ids.iter() + .map(|id| { + ItemEntity { + id: *id, + location: ItemLocation::Inventory { + character_id: *character_id, + }, + item: ItemDetail::Tool(items.tool) + } + }) + .collect()) + }, + } + }) + .collect() + } + } + + pub fn as_equipped_entity(&self) -> EquippedEntity { + self.items.iter() + .fold((EquippedEntity::default(), 0), |(mut equipped, mut unit_slot), item| { + if let InventoryItem::Individual(individual_item) = item { + if individual_item.equipped { + match individual_item.item { + ItemDetail::Weapon(_) => equipped.weapon = Some(individual_item.entity_id), + ItemDetail::Armor(_) => equipped.armor = Some(individual_item.entity_id), + ItemDetail::Shield(_) => equipped.shield = Some(individual_item.entity_id), + ItemDetail::Unit(_) => { + equipped.unit[unit_slot] = Some(individual_item.entity_id); + unit_slot += 1; + } + ItemDetail::Mag(_) => equipped.mag = Some(individual_item.entity_id), + _ => {}, + } + } + } + (equipped, unit_slot) + }).0 + } } diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index 46c45a0..fc84aa4 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -4,7 +4,7 @@ use thiserror::Error; use crate::entity::gateway::EntityGateway; use crate::entity::character::{CharacterEntity, CharacterEntityId}; use crate::entity::item::{ItemDetail, ItemLocation, BankName}; -use crate::entity::item::{Meseta, NewItemEntity, ItemEntity}; +use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity, EquippedEntity, InventoryEntity, BankItemEntity, BankEntity}; use crate::entity::item::tool::{Tool, ToolType}; use crate::entity::item::unit; use crate::ship::map::MapArea; @@ -48,40 +48,10 @@ pub enum ItemManagerError { CannotGetIndividualItem, InvalidSlot(u8, u8), // slots available, slot attempted NoArmorEquipped, - GatewayError(#[from] crate::entity::gateway::GatewayError) + GatewayError(#[from] crate::entity::gateway::GatewayError), + StackedItemError(Vec), } - -async fn update_inventory_slots(entity_gateway: &mut EG, character: &CharacterEntity, inventory: &CharacterInventory) -> Result<(), ItemManagerError> { - for (slot, item) in inventory.iter().enumerate() { - match item { - InventoryItem::Individual(individual_inventory_item) => { - entity_gateway.change_item_location( - &individual_inventory_item.entity_id, - ItemLocation::Inventory { - character_id: character.id, - slot: slot, - equipped: individual_inventory_item.equipped, - } - ).await? - }, - InventoryItem::Stacked(stacked_inventory_item) => { - for entity_id in stacked_inventory_item.entity_ids.iter() { - entity_gateway.change_item_location( - entity_id, - ItemLocation::Inventory { - character_id: character.id, - slot: slot, - equipped: false, - }).await? - } - } - } - } - Ok(()) -} - - pub struct ItemManager { id_counter: u32, @@ -115,6 +85,70 @@ impl ItemManager { // TODO: Result pub async fn load_character(&mut self, entity_gateway: &mut EG, character: &CharacterEntity) -> Result<(), ItemManagerError> { + let inventory = entity_gateway.get_character_inventory(&character.id).await?; + let bank = entity_gateway.get_character_bank(&character.id, BankName("".into())).await?; + let equipped = entity_gateway.get_character_equips(&character.id).await?; + + let inventory_items = inventory.items.into_iter() + .map(|item| -> Result { + Ok(match item { + InventoryItemEntity::Individual(item) => { + InventoryItem::Individual(IndividualInventoryItem { + entity_id: item.id, + item_id: self.next_global_item_id(), + item: item.item, + equipped: equipped.is_equipped(&item.id), + }) + }, + InventoryItemEntity::Stacked(items) => { + InventoryItem::Stacked(StackedInventoryItem { + entity_ids: items.iter().map(|i| i.id).collect(), + item_id: self.next_global_item_id(), + tool: items.get(0) + .ok_or(ItemManagerError::StackedItemError(items.clone()))? + .item + .clone() + .as_tool() + .ok_or(ItemManagerError::StackedItemError(items.clone()))? + }) + }, + }) + }) + .collect::, _>>()?; + let character_inventory = CharacterInventory::new(inventory_items); + + let bank_items = bank.items.into_iter() + .map(|item| -> Result { + Ok(match item { + BankItemEntity::Individual(item) => { + BankItem::Individual(IndividualBankItem { + entity_id: item.id, + item_id: self.next_global_item_id(), + item: item.item, + }) + }, + BankItemEntity::Stacked(items) => { + BankItem::Stacked(StackedBankItem { + entity_ids: items.iter().map(|i| i.id).collect(), + item_id: self.next_global_item_id(), + tool: items.get(0) + .ok_or(ItemManagerError::StackedItemError(items.clone()))? + .item + .clone() + .as_tool() + .ok_or(ItemManagerError::StackedItemError(items.clone()))? + }) + }, + }) + }) + .collect::, _>>()?; + let character_bank = CharacterBank::new(bank_items); + + self.character_inventory.insert(character.id, character_inventory); + self.character_bank.insert(character.id, character_bank); + Ok(()) + + /* let items = entity_gateway.get_items_by_character(&character.id).await?; let inventory_items = items.clone().into_iter() .filter_map(|item| { @@ -208,6 +242,7 @@ impl ItemManager { self.character_inventory.insert(character.id, inventory); self.character_bank.insert(character.id, bank_items.remove(&BankName("".to_string())).unwrap_or(CharacterBank::new(Vec::new()))); Ok(()) + */ } pub fn add_character_to_room(&mut self, room_id: RoomId, character: &CharacterEntity, area_client: AreaClient) { @@ -301,8 +336,6 @@ impl ItemManager { &new_inventory_item.entity_id, ItemLocation::Inventory { character_id: character.id, - slot: slot.0, - equipped: false, } ).await?; if let Some(_) = new_inventory_item.mag() { @@ -325,8 +358,6 @@ impl ItemManager { &entity_id, ItemLocation::Inventory { character_id: character.id, - slot: slot.0, - equipped: false, } ).await?; } @@ -356,6 +387,7 @@ impl ItemManager { } }; + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; floor_item.remove_from_floor(); Ok(trigger_create_item) } @@ -487,7 +519,7 @@ impl ItemManager { }, } - update_inventory_slots(entity_gateway, character, &inventory).await?; + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; Ok(()) } @@ -549,6 +581,7 @@ impl ItemManager { ).await?; } + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; Ok(stacked_floor_item) } @@ -567,7 +600,7 @@ impl ItemManager { ItemLocation::Consumed).await?; } - update_inventory_slots(entity_gateway, character, &inventory).await?; + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; Ok(consumed_item) } @@ -604,7 +637,8 @@ impl ItemManager { } } - update_inventory_slots(entity_gateway, character, &inventory).await?; + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; + entity_gateway.set_character_bank(&character.id, &bank.as_bank_entity(&character.id, &BankName("".into())), BankName("".into())).await?; Ok(()) } @@ -621,30 +655,31 @@ impl ItemManager { .ok_or(ItemManagerError::NoCharacter(character.id))?; let item_to_withdraw = bank.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?; - let inventory_item = inventory.withdraw_item(item_to_withdraw, amount).ok_or(ItemManagerError::Idunnoman)?; + let inventory_item_slot = { + let inventory_item = inventory.withdraw_item(item_to_withdraw, amount).ok_or(ItemManagerError::Idunnoman)?; - match inventory_item { - (InventoryItem::Individual(individual_inventory_item), slot) => { - entity_gateway.change_item_location(&individual_inventory_item.entity_id, - ItemLocation::Inventory { - character_id: character.id, - slot: slot, - equipped: false, - }).await?; - }, - (InventoryItem::Stacked(stacked_inventory_item), slot) => { - for entity_id in &stacked_inventory_item.entity_ids { - entity_gateway.change_item_location(entity_id, + match inventory_item { + (InventoryItem::Individual(individual_inventory_item), slot) => { + entity_gateway.change_item_location(&individual_inventory_item.entity_id, ItemLocation::Inventory { character_id: character.id, - slot: slot, - equipped: false, }).await?; + }, + (InventoryItem::Stacked(stacked_inventory_item), slot) => { + for entity_id in &stacked_inventory_item.entity_ids { + entity_gateway.change_item_location(entity_id, + ItemLocation::Inventory { + character_id: character.id, + }).await?; + } } } - } + inventory_item.1 + }; - Ok(inventory_item.0) + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; + entity_gateway.set_character_bank(&character.id, &bank.as_bank_entity(&character.id, &BankName("".into())), BankName("".into())).await?; + inventory.slot(inventory_item_slot).ok_or(ItemManagerError::Idunnoman) } pub async fn player_feeds_mag_item(&mut self, @@ -681,7 +716,7 @@ impl ItemManager { }).await?; } - update_inventory_slots(entity_gateway, character, &inventory).await?; + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; Ok(()) } @@ -795,7 +830,7 @@ impl ItemManager { } _ => {} } - update_inventory_slots(entity_gateway, character, &inventory).await?; + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; Ok(()) } @@ -835,8 +870,6 @@ impl ItemManager { entity_gateway.change_item_location(entity_id, ItemLocation::Inventory { character_id: character.id, - slot: slot.0, - equipped: false, }).await?; } picked_up_item.item_id @@ -863,8 +896,6 @@ impl ItemManager { entity_gateway.change_item_location(&picked_up_item.entity_id, ItemLocation::Inventory { character_id: character.id, - slot: slot.0, - equipped: false, }).await?; picked_up_item.item_id }; @@ -891,14 +922,14 @@ impl ItemManager { entity_gateway.change_item_location(&picked_up_item.entity_id, ItemLocation::Inventory { character_id: character.id, - slot: slot.0, - equipped: false, }).await?; picked_up_item.item_id }; inventory.get_item_by_id(item_id).ok_or(ItemManagerError::ItemIdNotInInventory(item_id))? }, }; + + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; Ok(inventory_item) } @@ -914,27 +945,7 @@ impl ItemManager { let slot = inventory_item_handle.get_slot(); let inventory_item = inventory_item_handle.item_mut().ok_or(ItemManagerError::CannotGetMutItem)?.individual().ok_or(ItemManagerError::CannotGetIndividualItem)?; inventory_item.equipped = true; - if let ItemDetail::Unit(u) = inventory_item.item { - if equip_slot > 0 { - inventory_item.item = ItemDetail::Unit(unit::Unit { - unit: u.unit, - modifier: u.modifier, - armor_slot: ((equip_slot & 0x7) - 1) % 4, // or just be lazy and do equip_slot - 9 - }); - } else { - inventory_item.item = ItemDetail::Unit(unit::Unit { - unit: u.unit, - modifier: u.modifier, - armor_slot: 0, - }); - } - }; - entity_gateway.change_item_location(&inventory_item.entity_id, ItemLocation::Inventory{ - character_id: character.id, - slot: slot, - equipped: true, - }).await?; - entity_gateway.change_item(&inventory_item.entity_id, &inventory_item.item).await?; + entity_gateway.set_character_equips(&character.id, &inventory.as_equipped_entity()).await?; Ok(()) } @@ -948,19 +959,7 @@ impl ItemManager { let slot = inventory_item_handle.get_slot(); let inventory_item = inventory_item_handle.item_mut().ok_or(ItemManagerError::CannotGetMutItem)?.individual().ok_or(ItemManagerError::CannotGetIndividualItem)?; inventory_item.equipped = false; - if let ItemDetail::Unit(u) = inventory_item.item { - inventory_item.item = ItemDetail::Unit(unit::Unit { - unit: u.unit, - modifier: u.modifier, - armor_slot: 0, - }); - }; - entity_gateway.change_item_location(&inventory_item.entity_id, ItemLocation::Inventory{ - character_id: character.id, - slot: slot, - equipped: false, - }).await; - entity_gateway.change_item(&inventory_item.entity_id, &inventory_item.item).await?; + entity_gateway.set_character_equips(&character.id, &inventory.as_equipped_entity()).await?; Ok(()) } @@ -978,7 +977,7 @@ impl ItemManager { .collect(); inventory.set_items(sorted_inventory_items); - update_inventory_slots(entity_gateway, character, &inventory).await; + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; Ok(()) } } diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index 937a08c..28a8370 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -351,7 +351,7 @@ where }; for unit_id in equipped_unit_ids { - item_manager.player_unequips_item(entity_gateway, &client.character, unit_id).await; + item_manager.player_unequips_item(entity_gateway, &client.character, unit_id).await?; } Ok(Box::new(None.into_iter())) @@ -369,4 +369,4 @@ where let client = clients.get(&id).ok_or(ShipError::ClientNotFound(id))?; item_manager.player_sorts_items(entity_gateway, &client.character, pkt.item_ids).await?; Ok(Box::new(None.into_iter())) // Do clients care about the order of other clients items? -} \ No newline at end of file +} diff --git a/tests/test_bank.rs b/tests/test_bank.rs index 7add54c..9300090 100644 --- a/tests/test_bank.rs +++ b/tests/test_bank.rs @@ -1,3 +1,4 @@ +use std::collections::BTreeSet; use elseware::common::serverstate::{ClientId, ServerState}; use elseware::entity::gateway::{EntityGateway, InMemoryGateway}; use elseware::entity::item; @@ -17,7 +18,7 @@ async fn test_bank_items_sent_in_character_login() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - entity_gateway.create_item( + let item = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -35,9 +36,11 @@ async fn test_bank_items_sent_in_character_login() { } }).await.unwrap(); - let mut ship = ShipServerState::builder() + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item]), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; let packets = ship.handle(ClientId(1), &RecvShipPacket::MenuSelect(MenuSelect { @@ -55,8 +58,9 @@ async fn test_request_bank_items() { 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 bank = Vec::new(); for _ in 0..3 { - entity_gateway.create_item( + bank.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -72,12 +76,14 @@ async fn test_request_bank_items() { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -105,8 +111,9 @@ async fn test_request_stacked_bank_items() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for _ in 0..3 { - entity_gateway.create_item( + let mut monomates = Vec::new(); + for _ in 0..3usize { + monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool ( item::tool::Tool { @@ -117,12 +124,14 @@ async fn test_request_stacked_bank_items() { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -149,7 +158,7 @@ async fn test_request_bank_items_sorted() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - entity_gateway.create_item( + let item1 = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -166,7 +175,7 @@ async fn test_request_bank_items_sorted() { name: item::BankName("".to_string()) } }).await.unwrap(); - entity_gateway.create_item( + let monomate = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool ( item::tool::Tool { @@ -178,7 +187,7 @@ async fn test_request_bank_items_sorted() { name: item::BankName("".to_string()) } }).await.unwrap(); - entity_gateway.create_item( + let item2 = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -196,9 +205,12 @@ async fn test_request_bank_items_sorted() { } }).await.unwrap(); - let mut ship = ShipServerState::builder() + let bank = vec![item::BankItemEntity::Individual(item1), vec![monomate].into(), item2.into()]; + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -226,7 +238,7 @@ async fn test_deposit_individual_item() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - entity_gateway.create_item( + let item0 = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -240,11 +252,9 @@ async fn test_deposit_individual_item() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } }).await.unwrap(); - entity_gateway.create_item( + let item1 = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -258,14 +268,14 @@ async fn test_deposit_individual_item() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 1, - equipped: false, } }).await.unwrap(); - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![item0, item1])).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -295,18 +305,11 @@ async fn test_deposit_individual_item() { && player_no_longer_has_item.amount == 0 )); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids == vec![item::ItemEntityId(2)]); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 1); + bank_items.items[0].with_individual(|item| { + assert_eq!(item.id, item::ItemEntityId(2)); + }).unwrap(); } #[async_std::test] @@ -316,8 +319,9 @@ async fn test_deposit_stacked_item() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for _ in 0..3 { - entity_gateway.create_item( + let mut monomates = Vec::new(); + for _ in 0..3usize { + monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -326,15 +330,15 @@ async fn test_deposit_stacked_item() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -364,18 +368,12 @@ async fn test_deposit_stacked_item() { && player_no_longer_has_item.amount == 3 )); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 1); + bank_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]); + }).unwrap(); } #[async_std::test] @@ -385,8 +383,9 @@ async fn test_deposit_partial_stacked_item() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for _ in 0..3 { - entity_gateway.create_item( + let mut monomates = Vec::new(); + for _ in 0..3usize { + monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -395,15 +394,15 @@ async fn test_deposit_partial_stacked_item() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -433,30 +432,20 @@ async fn test_deposit_partial_stacked_item() { && player_no_longer_has_item.amount == 2 )); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]); - - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids == vec![item::ItemEntityId(3)]); + + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 1); + bank_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2)]); + }).unwrap(); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(3)]); + }).unwrap(); } @@ -467,8 +456,10 @@ async fn test_deposit_stacked_item_with_stack_already_in_bank() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for _ in 0..2 { - entity_gateway.create_item( + let mut bank_monomates = Vec::new(); + let mut inventory_monomates = Vec::new(); + for _ in 0..2usize { + inventory_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -477,12 +468,10 @@ async fn test_deposit_stacked_item_with_stack_already_in_bank() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); - entity_gateway.create_item( + bank_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -493,12 +482,15 @@ async fn test_deposit_stacked_item_with_stack_already_in_bank() { character_id: char1.id, name: item::BankName("".into()), } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -528,18 +520,12 @@ async fn test_deposit_stacked_item_with_stack_already_in_bank() { && player_no_longer_has_item.amount == 2 )); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)]); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 1); + bank_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)].into_iter().collect::>() ); + }).unwrap(); } #[async_std::test] @@ -548,8 +534,9 @@ async fn test_deposit_stacked_item_with_full_stack_in_bank() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - for _ in 0..2 { - entity_gateway.create_item( + let mut inventory_monomates = Vec::new(); + for _ in 0..2usize { + inventory_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -558,14 +545,13 @@ async fn test_deposit_stacked_item_with_full_stack_in_bank() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } + let mut bank_monomates = Vec::new(); for _ in 0..10 { - entity_gateway.create_item( + bank_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -576,12 +562,15 @@ async fn test_deposit_stacked_item_with_full_stack_in_bank() { character_id: char1.id, name: item::BankName("".into()), } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -604,30 +593,18 @@ async fn test_deposit_stacked_item_with_full_stack_in_bank() { assert!(packets.is_err()); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids.len() == 10); - - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 1); + bank_items.items[0].with_stacked(|items| { + assert_eq!(items.len(), 10); + }).unwrap(); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2)]); + }).unwrap(); } #[async_std::test] @@ -636,7 +613,8 @@ async fn test_deposit_individual_item_in_full_bank() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - entity_gateway.create_item( + let mut inventory = Vec::new(); + inventory.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -650,13 +628,12 @@ async fn test_deposit_individual_item_in_full_bank() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); - for _ in 0..200 { - entity_gateway.create_item( + let mut bank = Vec::new(); + for _ in 0..200usize { + bank.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -672,12 +649,15 @@ async fn test_deposit_individual_item_in_full_bank() { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -700,30 +680,14 @@ async fn test_deposit_individual_item_in_full_bank() { assert!(packets.is_err()); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids.len() == 200); - - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids == vec![item::ItemEntityId(1)]); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 200); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_individual(|item| { + assert_eq!(item.id, item::ItemEntityId(1)); + }).unwrap(); } #[async_std::test] @@ -732,8 +696,9 @@ async fn test_deposit_stacked_item_in_full_bank() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - for _ in 0..2 { - entity_gateway.create_item( + let mut monomates = Vec::new(); + for _ in 0..2usize { + monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -742,14 +707,13 @@ async fn test_deposit_stacked_item_in_full_bank() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - for _ in 0..200 { - entity_gateway.create_item( + let mut full_bank = Vec::new(); + for _ in 0..200usize { + full_bank.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -765,12 +729,15 @@ async fn test_deposit_stacked_item_in_full_bank() { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(full_bank), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -793,30 +760,15 @@ async fn test_deposit_stacked_item_in_full_bank() { assert!(packets.is_err()); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids.len() == 200); - - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 200); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2)]); + }).unwrap(); } #[async_std::test] @@ -825,8 +777,9 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - for _ in 0..2 { - entity_gateway.create_item( + let mut monomates = Vec::new(); + for _ in 0..2usize { + monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -835,50 +788,54 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - for _ in 0..199 { - entity_gateway.create_item( + let mut bank_monomates = Vec::new(); + for _ in 0..2usize { + bank_monomates.push(entity_gateway.create_item( item::NewItemEntity { - item: item::ItemDetail::Weapon( - item::weapon::Weapon { - weapon: item::weapon::WeaponType::Vulcan, - grind: 0, - special: None, - attrs: [None, None, None], - tekked: true, - modifiers: Vec::new(), + item: item::ItemDetail::Tool( + item::tool::Tool { + tool: item::tool::ToolType::Monomate, } ), location: item::ItemLocation::Bank { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap()); } - for _ in 0..2 { - entity_gateway.create_item( + let mut almost_full_bank: Vec = Vec::new(); + for _ in 0..199usize { + almost_full_bank.push(entity_gateway.create_item( item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: item::tool::ToolType::Monomate, + item: item::ItemDetail::Weapon( + item::weapon::Weapon { + weapon: item::weapon::WeaponType::Vulcan, + grind: 0, + special: None, + attrs: [None, None, None], + tekked: true, + modifiers: Vec::new(), } ), location: item::ItemLocation::Bank { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap().into()); } + almost_full_bank.push(bank_monomates.into()); + + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(almost_full_bank), item::BankName("".into())).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -899,30 +856,14 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() { unknown: 0, })))).await.unwrap().for_each(drop); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids.len() == 203); - - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids.len() == 0); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 200); + bank_items.items[199].with_stacked(|items| { + assert_eq!(items.len(), 4); + }).unwrap(); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 0); } #[async_std::test] @@ -933,9 +874,9 @@ async fn test_deposit_meseta() { char1.meseta = 300; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -971,9 +912,9 @@ async fn test_deposit_too_much_meseta() { char1.bank_meseta = 999980; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1010,9 +951,9 @@ async fn test_deposit_meseta_when_bank_is_maxed() { char1.bank_meseta = 999999; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1047,7 +988,8 @@ async fn test_withdraw_individual_item() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - entity_gateway.create_item( + let mut bank = Vec::new(); + bank.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -1063,11 +1005,13 @@ async fn test_withdraw_individual_item() { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap()); - let mut ship = ShipServerState::builder() + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1096,18 +1040,12 @@ async fn test_withdraw_individual_item() { if create_item.item_id == 0x20000 )); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory{..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids == vec![item::ItemEntityId(1)]); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_individual(|item| { + assert_eq!(item.id, item::ItemEntityId(1)); + }).unwrap(); } #[async_std::test] @@ -1117,8 +1055,9 @@ async fn test_withdraw_stacked_item() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for _ in 0..3 { - entity_gateway.create_item( + let mut monomates = Vec::new(); + for _ in 0..3usize { + monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -1129,12 +1068,14 @@ async fn test_withdraw_stacked_item() { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1163,18 +1104,12 @@ async fn test_withdraw_stacked_item() { if create_item.item_id == 0x10002 )); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3)]); + }).unwrap(); } #[async_std::test] @@ -1184,8 +1119,9 @@ async fn test_withdraw_partial_stacked_item() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for _ in 0..3 { - entity_gateway.create_item( + let mut monomates = Vec::new(); + for _ in 0..3usize { + monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -1196,12 +1132,13 @@ async fn test_withdraw_partial_stacked_item() { character_id: char1.id, name: item::BankName("".into()) } - }).await.unwrap(); + }).await.unwrap()); } + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), item::BankName("".into())).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1230,30 +1167,19 @@ async fn test_withdraw_partial_stacked_item() { if create_item.item_id == 0x10002 )); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids == vec![item::ItemEntityId(3)]); - - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 1); + bank_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(3)]); + }).unwrap(); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2)]); + }).unwrap(); } #[async_std::test] @@ -1263,8 +1189,10 @@ async fn test_withdraw_stacked_item_with_stack_already_in_inventory() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for _ in 0..2 { - entity_gateway.create_item( + let mut inventory_monomates = Vec::new(); + let mut bank_monomates = Vec::new(); + for _ in 0..2usize { + inventory_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -1273,12 +1201,10 @@ async fn test_withdraw_stacked_item_with_stack_already_in_inventory() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); - entity_gateway.create_item( + bank_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -1289,12 +1215,15 @@ async fn test_withdraw_stacked_item_with_stack_already_in_inventory() { character_id: char1.id, name: item::BankName("".into()), } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1323,18 +1252,15 @@ async fn test_withdraw_stacked_item_with_stack_already_in_inventory() { if create_item.item_id == 0x10000 )); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)]); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 0); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4)].into_iter().collect::>()); + }).unwrap(); } #[async_std::test] @@ -1343,8 +1269,9 @@ async fn test_withdraw_stacked_item_with_full_stack_in_inventory() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - for _ in 0..2 { - entity_gateway.create_item( + let mut bank_monomates = Vec::new(); + for _ in 0..2usize { + bank_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -1355,11 +1282,12 @@ async fn test_withdraw_stacked_item_with_full_stack_in_inventory() { character_id: char1.id, name: item::BankName("".into()), } - }).await.unwrap(); + }).await.unwrap()); } - for _ in 0..10 { - entity_gateway.create_item( + let mut inventory_monomates = Vec::new(); + for _ in 0..10usize { + inventory_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -1368,15 +1296,16 @@ async fn test_withdraw_stacked_item_with_full_stack_in_inventory() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![inventory_monomates])).await.unwrap(); + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_monomates]), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1399,30 +1328,18 @@ async fn test_withdraw_stacked_item_with_full_stack_in_inventory() { assert!(packets.is_err()); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]); - - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids.len() == 10); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 1); + bank_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2)]); + }).unwrap(); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.len(), 10); + }).unwrap(); } #[async_std::test] @@ -1431,7 +1348,8 @@ async fn test_withdraw_individual_item_in_full_inventory() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - entity_gateway.create_item( + let mut bank = Vec::new(); + bank.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -1447,10 +1365,11 @@ async fn test_withdraw_individual_item_in_full_inventory() { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap()); - for i in 0..30 { - entity_gateway.create_item( + let mut inventory = Vec::new(); + for _ in 0..30usize { + inventory.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -1464,15 +1383,16 @@ async fn test_withdraw_individual_item_in_full_inventory() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: i, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(bank), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1492,33 +1412,13 @@ async fn test_withdraw_individual_item_in_full_inventory() { meseta_amount: 0, unknown: 0, })))).await; - assert!(packets.is_err()); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids == vec![item::ItemEntityId(1)]); - - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids.len() == 30); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 1); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 30); } #[async_std::test] @@ -1527,8 +1427,9 @@ async fn test_withdraw_stacked_item_in_full_inventory() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - for _ in 0..2 { - entity_gateway.create_item( + let mut monomates = Vec::new(); + for _ in 0..2usize { + monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -1539,11 +1440,12 @@ async fn test_withdraw_stacked_item_in_full_inventory() { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap()); } - for i in 0..30 { - entity_gateway.create_item( + let mut inventory = Vec::new(); + for _ in 0..30usize { + inventory.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -1557,15 +1459,16 @@ async fn test_withdraw_stacked_item_in_full_inventory() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: i, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![monomates]), item::BankName("".into())).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1588,30 +1491,16 @@ async fn test_withdraw_stacked_item_in_full_inventory() { assert!(packets.is_err()); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]); - - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids.len() == 30); + + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert_eq!(bank_items.items.len(), 1); + bank_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2)]); + }).unwrap(); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 30); } #[async_std::test] @@ -1620,8 +1509,9 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - for _ in 0..2 { - entity_gateway.create_item( + let mut bank_item = Vec::new(); + for _ in 0..2usize { + bank_item.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -1632,11 +1522,13 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() { character_id: char1.id, name: item::BankName("".to_string()) } - }).await.unwrap(); + }).await.unwrap()); } + entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![bank_item]), item::BankName("".into())).await.unwrap(); - for i in 0..29 { - entity_gateway.create_item( + let mut items = Vec::new(); + for i in 0..29usize { + items.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -1650,14 +1542,13 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: i, - equipped: false, } - }).await.unwrap(); + }).await.unwrap().into()); } - for _ in 0..2 { - entity_gateway.create_item( + let mut item29 = Vec::new(); + for _ in 0..2usize { + item29.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -1666,15 +1557,16 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 29, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } + items.push(item::InventoryItemEntity::Stacked(item29)); - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(items)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1695,30 +1587,17 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() { unknown: 0, })))).await.unwrap().for_each(drop); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let bank_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Bank {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(bank_item_ids.len() == 0); - - let inventory_item_ids = items.iter() - .filter_map(|item| { - if let item::ItemLocation::Inventory {..} = item.location { - Some(item.id) - } - else { - None - } - }) - .collect::>(); - assert!(inventory_item_ids.len() == 33); + let bank_items = entity_gateway.get_character_bank(&char1.id, item::BankName("".into())).await.unwrap(); + assert!(bank_items.items.len() == 0); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert!(inventory_items.items.len() == 30); + match &inventory_items.items[29] { + item::InventoryItemEntity::Stacked(items) => { + assert_eq!(items.len(), 4); + }, + _ => panic!(), + } } #[async_std::test] @@ -1729,9 +1608,9 @@ async fn test_withdraw_meseta() { char1.bank_meseta = 300; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1767,9 +1646,9 @@ async fn test_withdraw_too_much_meseta() { char1.bank_meseta = 300; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -1805,9 +1684,9 @@ async fn test_withdraw_meseta_inventory_is_maxed() { char1.bank_meseta = 300; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; diff --git a/tests/test_character.rs b/tests/test_character.rs index 8dca699..ba35270 100644 --- a/tests/test_character.rs +++ b/tests/test_character.rs @@ -14,9 +14,9 @@ async fn test_save_options() { let (user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; diff --git a/tests/test_exp_gain.rs b/tests/test_exp_gain.rs index 9614558..343d804 100644 --- a/tests/test_exp_gain.rs +++ b/tests/test_exp_gain.rs @@ -17,9 +17,9 @@ async fn test_character_gains_exp() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -56,9 +56,9 @@ async fn test_character_levels_up() { char1.exp = 49; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -94,9 +94,9 @@ async fn test_character_levels_up_multiple_times() { let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -139,9 +139,9 @@ async fn test_one_character_gets_full_exp_and_other_attacker_gets_partial() { 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 = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; diff --git a/tests/test_item_actions.rs b/tests/test_item_actions.rs index 201f9fa..f50a91b 100644 --- a/tests/test_item_actions.rs +++ b/tests/test_item_actions.rs @@ -16,7 +16,8 @@ async fn test_equip_unit_from_equip_menu() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - entity_gateway.create_item( + let mut p1_inv = Vec::new(); + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Armor( item::armor::Armor{ @@ -28,12 +29,10 @@ async fn test_equip_unit_from_equip_menu() { }), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: true, } - }).await.unwrap(); + }).await.unwrap()); - entity_gateway.create_item( + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ @@ -43,12 +42,10 @@ async fn test_equip_unit_from_equip_menu() { }), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 1, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); - entity_gateway.create_item( + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ @@ -58,14 +55,22 @@ async fn test_equip_unit_from_equip_menu() { }), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 2, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); + + let equipped = item::EquippedEntity { + weapon: Some(p1_inv[0].id), + armor: None, + shield: None, + unit: [None; 4], + mag: None, + }; + entity_gateway.set_character_equips(&char1.id, &equipped).await.unwrap(); + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -87,44 +92,11 @@ async fn test_equip_unit_from_equip_menu() { 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, - } - }); + let equips = entity_gateway.get_character_equips(&char1.id).await.unwrap(); + assert_eq!(equips.unit[0].unwrap(), item::ItemEntityId(2)); + assert_eq!(equips.unit[1].unwrap(), item::ItemEntityId(3)); + assert!(equips.unit[2].is_none()); + assert!(equips.unit[3].is_none()); } #[async_std::test] @@ -133,7 +105,8 @@ async fn test_unequip_armor_with_units() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - entity_gateway.create_item( + let mut p1_inv = Vec::new(); + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Armor( item::armor::Armor{ @@ -145,12 +118,10 @@ async fn test_unequip_armor_with_units() { }), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: true, } - }).await; + }).await.unwrap()); - entity_gateway.create_item( + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ @@ -160,12 +131,10 @@ async fn test_unequip_armor_with_units() { }), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 1, - equipped: true, } - }).await.unwrap(); + }).await.unwrap()); - entity_gateway.create_item( + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ @@ -175,14 +144,22 @@ async fn test_unequip_armor_with_units() { }), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 2, - equipped: true, } - }).await.unwrap(); + }).await.unwrap()); + + let equipped = item::EquippedEntity { + weapon: None, + armor: Some(p1_inv[0].id), + shield: None, + unit: [Some(p1_inv[1].id), Some(p1_inv[2].id), None, None], + mag: None, + }; + entity_gateway.set_character_equips(&char1.id, &equipped).await.unwrap(); + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -194,27 +171,12 @@ async fn test_unequip_armor_with_units() { 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); + let equips = entity_gateway.get_character_equips(&char1.id).await.unwrap(); + assert!(equips.armor.is_none()); + assert!(equips.unit[0].is_none()); + assert!(equips.unit[1].is_none()); + assert!(equips.unit[2].is_none()); + assert!(equips.unit[3].is_none()); } #[async_std::test] @@ -223,7 +185,8 @@ async fn test_sort_items() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - entity_gateway.create_item( + let mut p1_inv = Vec::new(); + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Armor( item::armor::Armor{ @@ -235,12 +198,10 @@ async fn test_sort_items() { }), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: true, } - }).await; + }).await.unwrap()); - entity_gateway.create_item( + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ @@ -250,12 +211,10 @@ async fn test_sort_items() { }), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 1, - equipped: false, } - }).await; + }).await.unwrap()); - entity_gateway.create_item( + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Unit( item::unit::Unit{ @@ -265,25 +224,30 @@ async fn test_sort_items() { }), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 2, - equipped: false, } - }).await; - - let mut ship = ShipServerState::builder() + }).await.unwrap()); + + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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, - }); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 3); + inventory_items.items[0].with_individual(|item| { + assert_eq!(item.id, item::ItemEntityId(1)); + }).unwrap(); + inventory_items.items[1].with_individual(|item| { + assert_eq!(item.id, item::ItemEntityId(2)); + }).unwrap(); + inventory_items.items[2].with_individual(|item| { + assert_eq!(item.id, item::ItemEntityId(3)); + }).unwrap(); + ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::SortItems(SortItems { client: 255, @@ -293,11 +257,15 @@ async fn test_sort_items() { 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, - }); -} \ No newline at end of file + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 3); + inventory_items.items[0].with_individual(|item| { + assert_eq!(item.id, item::ItemEntityId(2)); + }).unwrap(); + inventory_items.items[1].with_individual(|item| { + assert_eq!(item.id, item::ItemEntityId(3)); + }).unwrap(); + inventory_items.items[2].with_individual(|item| { + assert_eq!(item.id, item::ItemEntityId(1)); + }).unwrap(); +} diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index 51f1d47..03d0a3a 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -17,7 +17,8 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - entity_gateway.create_item( + let mut p1_monomate = Vec::new(); + p1_monomate.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -26,14 +27,14 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); + let mut p2_items = Vec::new(); for (slot, tool) in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter().enumerate() { - for _ in 0..5 { - entity_gateway.create_item( + let mut item = Vec::new(); + for _ in 0..5usize { + item.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -42,16 +43,18 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() { ), location: item::ItemLocation::Inventory { character_id: char2.id, - slot: slot, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } + p2_items.push(item); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_monomate])).await.unwrap(); + entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_items)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -80,21 +83,13 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() { unknown: [0; 3] })))).await.unwrap().for_each(drop); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(p1_items.len() == 6); - - let p1_item_ids = p1_items.iter().map(|item| { - item.id - }).collect::>(); - assert!(p1_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5), item::ItemEntityId(6)]); - - let all_items_are_monomates = p1_items.iter().all(|item| { - match item.item { - item::ItemDetail::Tool(tool) => tool.tool == item::tool::ToolType::Monomate, - _ => false - } - }); - assert!(all_items_are_monomates); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5), item::ItemEntityId(6)]); + assert!(items.iter().all(|item| item.item.item_type() == item::ItemType::Tool(item::tool::ToolType::Monomate))); + }).unwrap(); } #[async_std::test] @@ -104,7 +99,8 @@ async fn test_pick_up_item_stack_of_items_not_already_held() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - entity_gateway.create_item( + let mut p2_monomate = Vec::new(); + p2_monomate.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -113,14 +109,14 @@ async fn test_pick_up_item_stack_of_items_not_already_held() { ), location: item::ItemLocation::Inventory { character_id: char2.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); + + entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomate])).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -149,14 +145,13 @@ async fn test_pick_up_item_stack_of_items_not_already_held() { unknown: [0; 3] })))).await.unwrap().for_each(drop); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(p1_items.len() == 1); - - let first_item = p1_items.get(0).unwrap(); - assert!(first_item.id == item::ItemEntityId(1)); - assert!(first_item.item == item::ItemDetail::Tool(item::tool::Tool { - tool: item::tool::ToolType::Monomate, - })); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.len(), 1); + assert_eq!(items[0].id, item::ItemEntityId(1)); + assert_eq!(items[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Monomate)); + }).unwrap(); } #[async_std::test] @@ -166,8 +161,9 @@ async fn test_pick_up_meseta_when_inventory_full() { let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for slot in 0..30 { - entity_gateway.create_item( + let mut p1_items = Vec::new(); + for _ in 0..30usize { + p1_items.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -181,18 +177,18 @@ async fn test_pick_up_meseta_when_inventory_full() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: slot, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); + char2.meseta = 300; entity_gateway.save_character(&char2).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -227,8 +223,8 @@ async fn test_pick_up_meseta_when_inventory_full() { unknown: [0; 3] })))).await.unwrap().for_each(drop); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(p1_items.len() == 30); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 30); let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap(); let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap(); @@ -245,8 +241,9 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for slot in 0..29 { - entity_gateway.create_item( + let mut p1_inv = Vec::new(); + for slot in 0..29usize { + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -260,13 +257,11 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: slot, - equipped: false, } - }).await.unwrap(); + }).await.unwrap().into()); } - entity_gateway.create_item( + p1_inv.push(item::InventoryItemEntity::Stacked(vec![entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -275,11 +270,11 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 29, - equipped: false, } - }).await.unwrap(); - entity_gateway.create_item( + }).await.unwrap()])); + + let mut p2_monomates = Vec::new(); + p2_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -288,14 +283,15 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { ), location: item::ItemLocation::Inventory { character_id: char2.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); + + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); + entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomates])).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -324,17 +320,11 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { unknown: [0; 3] })))).await.unwrap().for_each(drop); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(p1_items.len() == 31); - - let monomate1 = p1_items.get(29).unwrap(); - assert!(monomate1.item == item::ItemDetail::Tool(item::tool::Tool { - tool: item::tool::ToolType::Monomate, - })); - let monomate2 = p1_items.get(30).unwrap(); - assert!(monomate2.item == item::ItemDetail::Tool(item::tool::Tool { - tool: item::tool::ToolType::Monomate, - })); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 30); + inventory_items.items[29].with_stacked(|items| { + assert_eq!(items.len(), 2); + }).unwrap(); } #[async_std::test] @@ -344,8 +334,9 @@ async fn test_can_not_pick_up_item_when_inventory_full() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for slot in 0..30 { - entity_gateway.create_item( + let mut p1_inv = Vec::new(); + for slot in 0..30usize { + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -359,13 +350,12 @@ async fn test_can_not_pick_up_item_when_inventory_full() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: slot, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - entity_gateway.create_item( + let mut p2_inv = Vec::new(); + p2_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -379,14 +369,15 @@ async fn test_can_not_pick_up_item_when_inventory_full() { ), location: item::ItemLocation::Inventory { character_id: char2.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); + entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -415,11 +406,10 @@ async fn test_can_not_pick_up_item_when_inventory_full() { unknown: [0; 3] })))).await.unwrap().for_each(drop); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(p1_items.len() == 30); - - let p2_items = entity_gateway.get_items_by_character(&char2.id).await.unwrap(); - assert!(p2_items.len() == 0); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 30); + let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); + assert_eq!(p2_items.items.len(), 0); ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem { client: 0, @@ -429,8 +419,10 @@ async fn test_can_not_pick_up_item_when_inventory_full() { unknown: [0; 3] })))).await.unwrap().for_each(drop); - let p2_items = entity_gateway.get_items_by_character(&char2.id).await.unwrap(); - assert!(p2_items.len() == 1); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 30); + let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); + assert_eq!(p2_items.items.len(), 1); } #[async_std::test] @@ -442,9 +434,9 @@ async fn test_can_not_drop_more_meseta_than_is_held() { char1.meseta = 300; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; @@ -481,8 +473,9 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for _ in 0..6 { - entity_gateway.create_item( + let mut p1_monomates = Vec::new(); + for _ in 0..6usize { + p1_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -491,13 +484,13 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - for _ in 0..6 { - entity_gateway.create_item( + + let mut p2_monomates = Vec::new(); + for _ in 0..6usize { + p2_monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -506,15 +499,15 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() { ), location: item::ItemLocation::Inventory { character_id: char2.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_monomates])).await.unwrap(); + entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomates])).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -544,11 +537,13 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() { })))).await.unwrap().collect::>(); assert!(packets.len() == 0); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(p1_items.len() == 6); - - let p2_items = entity_gateway.get_items_by_character(&char2.id).await.unwrap(); - assert!(p2_items.len() == 0); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 1); + p1_items.items[0].with_stacked(|items| { + assert_eq!(items.len(), 6); + }).unwrap(); + let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); + assert_eq!(p2_items.items.len(), 0); } #[async_std::test] @@ -563,9 +558,9 @@ async fn test_can_not_pick_up_meseta_when_full() { char2.meseta = 300; entity_gateway.save_character(&char2).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -621,9 +616,9 @@ async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() { char2.meseta = 300; entity_gateway.save_character(&char2).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -673,8 +668,9 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for _ in 0..5 { - entity_gateway.create_item( + let mut monomates = Vec::new(); + for _ in 0..5usize { + monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -683,15 +679,15 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; @@ -726,35 +722,17 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() { unknown: [0; 3] })))).await.unwrap().for_each(drop); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(p1_items.len() == 3); - - let p1_item_ids = p1_items.iter().map(|item| { - item.id - }).collect::>(); - assert!(p1_item_ids == vec![item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5)]); - - let all_items_are_monomates = p1_items.iter().all(|item| { - match item.item { - item::ItemDetail::Tool(tool) => tool.tool == item::tool::ToolType::Monomate, - _ => false - } - }); - assert!(all_items_are_monomates); - - let p2_items = entity_gateway.get_items_by_character(&char2.id).await.unwrap(); - assert!(p2_items.len() == 2); - - let p2_item_ids = p2_items.iter().map(|item| { - item.id - }).collect::>(); - assert!(p2_item_ids == vec![item::ItemEntityId(1), item::ItemEntityId(2)]); - - let all_items_are_monomates = p1_items.iter().all(|item| { - match item.item { - item::ItemDetail::Tool(tool) => tool.tool == item::tool::ToolType::Monomate, - _ => false - } - }); - assert!(all_items_are_monomates); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5)]); + }).unwrap(); + + let inventory_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.iter().map(|i| i.id).collect::>(), + vec![item::ItemEntityId(1), item::ItemEntityId(2)]); + }).unwrap(); } diff --git a/tests/test_item_use.rs b/tests/test_item_use.rs index bdee01f..8a51875 100644 --- a/tests/test_item_use.rs +++ b/tests/test_item_use.rs @@ -18,9 +18,11 @@ async fn test_use_monomate() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - for (slot, tool) in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter().enumerate() { - for _ in 0..2 { - entity_gateway.create_item( + let mut p1_items = Vec::new(); + for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { + let mut item = Vec::new(); + for _ in 0..2usize { + item.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -29,16 +31,17 @@ async fn test_use_monomate() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: slot, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } + p1_items.push(item::InventoryItemEntity::Stacked(item)); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -49,23 +52,14 @@ async fn test_use_monomate() { item_id: 0x10000, })))).await.unwrap().for_each(drop); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(items.iter().filter(|item| { - if let item::ItemDetail::Tool(t) = item.item { - t.tool == item::tool::ToolType::Monomate - } - else { - false - } - }).count() == 1); - assert!(items.iter().filter(|item| { - if let item::ItemDetail::Tool(t) = item.item { - t.tool == item::tool::ToolType::Monofluid - } - else { - false - } - }).count() == 2); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 2); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.len(), 1) + }).unwrap(); + inventory_items.items[1].with_stacked(|items| { + assert_eq!(items.len(), 2) + }).unwrap(); } #[async_std::test] @@ -74,9 +68,11 @@ async fn test_use_monomate_twice() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - for (slot, tool) in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter().enumerate() { - for _ in 0..3 { - entity_gateway.create_item( + let mut p1_items = Vec::new(); + for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { + let mut item = Vec::new(); + for _ in 0..3usize { + item.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -85,16 +81,17 @@ async fn test_use_monomate_twice() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: slot, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } + p1_items.push(item::InventoryItemEntity::Stacked(item)); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -110,23 +107,14 @@ async fn test_use_monomate_twice() { item_id: 0x10000, })))).await.unwrap().for_each(drop); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(items.iter().filter(|item| { - if let item::ItemDetail::Tool(t) = item.item { - t.tool == item::tool::ToolType::Monomate - } - else { - false - } - }).count() == 1); - assert!(items.iter().filter(|item| { - if let item::ItemDetail::Tool(t) = item.item { - t.tool == item::tool::ToolType::Monofluid - } - else { - false - } - }).count() == 3); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 2); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.len(), 1) + }).unwrap(); + inventory_items.items[1].with_stacked(|items| { + assert_eq!(items.len(), 3) + }).unwrap(); } #[async_std::test] @@ -135,27 +123,26 @@ async fn test_use_last_monomate() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - for (slot, tool) in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter().enumerate() { - for _ in 0..1 { - entity_gateway.create_item( - item::NewItemEntity { - item: item::ItemDetail::Tool( - item::tool::Tool { - tool: tool - } - ), - location: item::ItemLocation::Inventory { - character_id: char1.id, - slot: slot, - equipped: false, + let mut p1_inv = Vec::new(); + for tool in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter() { + p1_inv.push(item::InventoryItemEntity::Stacked(vec![entity_gateway.create_item( + item::NewItemEntity { + item: item::ItemDetail::Tool( + item::tool::Tool { + tool: tool } - }).await.unwrap(); - } + ), + location: item::ItemLocation::Inventory { + character_id: char1.id, + } + }).await.unwrap()])); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -166,23 +153,13 @@ async fn test_use_last_monomate() { item_id: 0x10000, })))).await.unwrap().for_each(drop); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(items.iter().filter(|item| { - if let item::ItemDetail::Tool(t) = item.item { - t.tool == item::tool::ToolType::Monomate - } - else { - false - } - }).count() == 0); - assert!(items.iter().filter(|item| { - if let item::ItemDetail::Tool(t) = item.item { - t.tool == item::tool::ToolType::Monofluid - } - else { - false - } - }).count() == 1); + + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.len(), 1); + assert_eq!(items[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Monofluid)); + }).unwrap(); } #[async_std::test] @@ -191,7 +168,8 @@ async fn test_use_nonstackable_tool() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - entity_gateway.create_item( + let mut p1_items = Vec::new(); + p1_items.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -200,14 +178,14 @@ async fn test_use_nonstackable_tool() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_items)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -218,8 +196,8 @@ async fn test_use_nonstackable_tool() { item_id: 0x10000, })))).await.unwrap().for_each(drop); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(items.len() == 0); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 0); } #[async_std::test] @@ -228,9 +206,11 @@ async fn test_use_materials() { let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - for (slot, tool) in vec![item::tool::ToolType::PowerMaterial, item::tool::ToolType::LuckMaterial].into_iter().enumerate() { - for _ in 0..5 { - entity_gateway.create_item( + let mut p1_inv = Vec::new(); + for tool in vec![item::tool::ToolType::PowerMaterial, item::tool::ToolType::LuckMaterial].into_iter() { + let mut item = Vec::new(); + for _ in 0..5usize { + item.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -239,16 +219,17 @@ async fn test_use_materials() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: slot, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } + p1_inv.push(item::InventoryItemEntity::Stacked(item)); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -269,23 +250,14 @@ async fn test_use_materials() { item_id: 0x10001, })))).await.unwrap().for_each(drop); - let items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(items.iter().filter(|item| { - if let item::ItemDetail::Tool(t) = item.item { - t.tool == item::tool::ToolType::PowerMaterial - } - else { - false - } - }).count() == 4); - assert!(items.iter().filter(|item| { - if let item::ItemDetail::Tool(t) = item.item { - t.tool == item::tool::ToolType::LuckMaterial - } - else { - false - } - }).count() == 3); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 2); + inventory_items.items[0].with_stacked(|items| { + assert_eq!(items.len(), 4) + }).unwrap(); + inventory_items.items[1].with_stacked(|items| { + assert_eq!(items.len(), 3) + }).unwrap(); let characters = entity_gateway.get_characters_by_user(&user1).await.unwrap(); let char = characters[0].as_ref().unwrap(); diff --git a/tests/test_mags.rs b/tests/test_mags.rs index a0f6fe8..51675cf 100644 --- a/tests/test_mags.rs +++ b/tests/test_mags.rs @@ -17,19 +17,20 @@ async fn test_mag_feed() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - entity_gateway.create_item( + let mag = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Mag( item::mag::Mag::baby_mag(0) ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: true, + //equipped: true, } }).await.unwrap(); - for _ in 0..7 { - entity_gateway.create_item( + + let mut monomates = Vec::new(); + for _ in 0..7usize { + monomates.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -38,20 +39,32 @@ async fn test_mag_feed() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 1, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + let equipped = item::EquippedEntity { + weapon: None, + armor: None, + shield: None, + unit: [None; 4], + mag: Some(mag.id), + }; + entity_gateway.set_character_equips(&char1.id, &equipped).await.unwrap(); + + let mut inventory = Vec::new(); + inventory.push(mag.into()); + inventory.push(item::InventoryItemEntity::Stacked(monomates)); + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(inventory)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; - for _ in 0..7 { + for _ in 0..7usize { ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerFeedMag(PlayerFeedMag { client: 0, target: 0, @@ -60,18 +73,21 @@ async fn test_mag_feed() { })))).await.unwrap().for_each(drop); } - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let mag = p1_items.get(0).unwrap(); - match &mag.item { - item::ItemDetail::Mag(mag) => { - assert!(mag.level() == 7); - assert!(mag.def() == 5); - assert!(mag.pow() == 2); - assert!(mag.dex() == 0); - assert!(mag.mind() == 0); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_individual(|item| { + match &item.item { + item::ItemDetail::Mag(mag) => { + println!("mag! {:?}", mag); + assert!(mag.level() == 7); + assert!(mag.def() == 5); + assert!(mag.pow() == 2); + assert!(mag.dex() == 0); + assert!(mag.mind() == 0); + } + _ => panic!() } - _ => panic!() - } + }).unwrap(); } #[async_std::test] @@ -87,21 +103,21 @@ async fn test_mag_change_owner() { char2.section_id = SectionID::Whitill; entity_gateway.save_character(&char2).await.unwrap(); - entity_gateway.create_item( + let mag = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Mag( item::mag::Mag::baby_mag(0) ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: true, } }).await.unwrap(); - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![mag])).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -128,15 +144,17 @@ async fn test_mag_change_owner() { unknown: [0; 3] })))).await.unwrap().for_each(drop); - let p2_items = entity_gateway.get_items_by_character(&char2.id).await.unwrap(); - let mag = p2_items.get(0).unwrap(); - match &mag.item { - item::ItemDetail::Mag(mag) => { - assert!(mag.class == CharacterClass::FOmarl); - assert!(mag.id == SectionID::Whitill); - }, - _ => panic!() - } + let inventory_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); + assert_eq!(inventory_items.items.len(), 1); + inventory_items.items[0].with_individual(|item| { + match &item.item { + item::ItemDetail::Mag(mag) => { + assert!(mag.class == CharacterClass::FOmarl); + assert!(mag.id == SectionID::Whitill); + } + _ => panic!() + } + }).unwrap(); } @@ -153,12 +171,10 @@ async fn test_mag_cell() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: true, } }).await.unwrap(); - for _ in 0..1000 { + for _ in 0..1000usize { let fed_tool = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool ( @@ -172,7 +188,7 @@ async fn test_mag_cell() { }).await.unwrap(); entity_gateway.feed_mag(&mag.id, &fed_tool.id).await.unwrap(); } - entity_gateway.create_item( + let mag_cell = entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Tool( item::tool::Tool { @@ -181,14 +197,22 @@ async fn test_mag_cell() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 1, - equipped: false, } }).await.unwrap(); - let mut ship = ShipServerState::builder() + let equipped = item::EquippedEntity { + weapon: None, + armor: None, + shield: None, + unit: [None; 4], + mag: Some(mag.id), + }; + entity_gateway.set_character_equips(&char1.id, &equipped).await.unwrap(); + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![mag, mag_cell])).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -199,12 +223,13 @@ async fn test_mag_cell() { item_id: 0x10001, })))).await.unwrap().for_each(drop); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - let mag = p1_items.get(0).unwrap(); - match &mag.item { - item::ItemDetail::Mag(mag) => { - assert!(mag.mag == item::mag::MagType::Soniti); + let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + inventory_items.items[0].with_individual(|item| { + match &item.item { + item::ItemDetail::Mag(mag) => { + assert_eq!(mag.mag, item::mag::MagType::Soniti); + } + _ => panic!() } - _ => panic!() - } + }).unwrap(); } diff --git a/tests/test_rooms.rs b/tests/test_rooms.rs index a21c754..0d652dc 100644 --- a/tests/test_rooms.rs +++ b/tests/test_rooms.rs @@ -18,8 +18,9 @@ async fn test_item_ids_reset_when_rejoining_rooms() { let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await; - for slot in 0..3 { - entity_gateway.create_item( + let mut p1_inv = Vec::new(); + for _ in 0..3usize { + p1_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -33,14 +34,13 @@ async fn test_item_ids_reset_when_rejoining_rooms() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: slot, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - for slot in 0..10 { - entity_gateway.create_item( + let mut p2_inv = Vec::new(); + for _ in 0..10usize { + p2_inv.push(entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( item::weapon::Weapon { @@ -54,15 +54,16 @@ async fn test_item_ids_reset_when_rejoining_rooms() { ), location: item::ItemLocation::Inventory { character_id: char2.id, - slot: slot, - equipped: false, } - }).await.unwrap(); + }).await.unwrap()); } - let mut ship = ShipServerState::builder() + entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap(); + entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap(); + + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; log_in_char(&mut ship, ClientId(2), "a2", "a").await; diff --git a/tests/test_shops.rs b/tests/test_shops.rs index 0574947..79aa438 100644 --- a/tests/test_shops.rs +++ b/tests/test_shops.rs @@ -19,9 +19,9 @@ async fn test_player_opens_weapon_shop() { char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -49,9 +49,9 @@ async fn test_player_opens_tool_shop() { char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -79,9 +79,9 @@ async fn test_player_opens_armor_shop() { char1.exp = 80000000; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -110,9 +110,9 @@ async fn test_player_buys_from_weapon_shop() { char1.meseta = 999999; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -135,8 +135,9 @@ async fn test_player_buys_from_weapon_shop() { let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap(); let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap(); assert!(c1.meseta < 999999); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert_eq!(p1_items.len(), 1); + //let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 1); } #[async_std::test] @@ -148,9 +149,9 @@ async fn test_player_buys_from_tool_shop() { char1.meseta = 999999; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -173,8 +174,8 @@ async fn test_player_buys_from_tool_shop() { let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap(); let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap(); assert!(c1.meseta < 999999); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert_eq!(p1_items.len(), 1); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 1); } #[async_std::test] @@ -186,9 +187,9 @@ async fn test_player_buys_multiple_from_tool_shop() { char1.meseta = 999999; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -211,8 +212,12 @@ async fn test_player_buys_multiple_from_tool_shop() { let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap(); let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap(); assert!(c1.meseta < 999999); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert_eq!(p1_items.len(), 5); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 1); + p1_items.items[0].with_stacked(|item| { + assert_eq!(item.len(), 5); + assert_eq!(item[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Monomate)); + }).unwrap(); } #[async_std::test] @@ -224,9 +229,9 @@ async fn test_player_buys_from_armor_shop() { char1.meseta = 999999; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -249,8 +254,8 @@ async fn test_player_buys_from_armor_shop() { let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap(); let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap(); assert!(c1.meseta < 999999); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert_eq!(p1_items.len(), 1); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 1); } #[async_std::test] @@ -267,9 +272,9 @@ async fn test_other_clients_see_purchase() { char1.meseta = 999999; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -318,14 +323,12 @@ async fn test_other_clients_see_stacked_purchase() { ), location: item::ItemLocation::Inventory { character_id: char1.id, - slot: 0, - equipped: false, } }).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .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; @@ -362,9 +365,9 @@ async fn test_buying_item_without_enough_mseseta() { let (user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -388,8 +391,8 @@ async fn test_buying_item_without_enough_mseseta() { let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap(); let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap(); assert_eq!(c1.meseta, 0); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert_eq!(p1_items.len(), 0); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 0); } #[async_std::test] @@ -401,9 +404,9 @@ async fn test_player_double_buys_from_tool_shop() { char1.meseta = 999999; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -444,11 +447,20 @@ async fn test_player_double_buys_from_tool_shop() { let characters1 = entity_gateway.get_characters_by_user(&user1).await.unwrap(); let c1 = characters1.get(0).as_ref().unwrap().as_ref().unwrap(); assert!(c1.meseta < 999999); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert_eq!(p1_items.len(), 9); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + assert_eq!(p1_items.items.len(), 2); + p1_items.items[0].with_stacked(|item| { + assert_eq!(item.len(), 7); + assert_eq!(item[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Monomate)); + }).unwrap(); + p1_items.items[1].with_stacked(|item| { + assert_eq!(item.len(), 2); + assert_eq!(item[0].item.item_type(), item::ItemType::Tool(item::tool::ToolType::Dimate)); + }).unwrap(); } + #[async_std::test] async fn test_techs_disappear_from_shop_when_bought() { let mut entity_gateway = InMemoryGateway::new(); @@ -458,9 +470,9 @@ async fn test_techs_disappear_from_shop_when_bought() { char1.meseta = 999999; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -502,8 +514,12 @@ async fn test_techs_disappear_from_shop_when_bought() { unknown1: 0, })))).await.unwrap().for_each(drop); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(p1_items[0].item != p1_items[1].item); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + p1_items.items[0].with_individual(|item1| { + p1_items.items[1].with_individual(|item2| { + assert_ne!(item1, item2); + }).unwrap(); + }).unwrap(); } // TOOD: this is not deterministic and can randomly fail @@ -516,9 +532,9 @@ async fn test_units_disappear_from_shop_when_bought() { char1.meseta = 999999; entity_gateway.save_character(&char1).await.unwrap(); - let mut ship = ShipServerState::builder() + let mut ship = Box::new(ShipServerState::builder() .gateway(entity_gateway.clone()) - .build(); + .build()); log_in_char(&mut ship, ClientId(1), "a1", "a").await; join_lobby(&mut ship, ClientId(1)).await; create_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await; @@ -560,6 +576,10 @@ async fn test_units_disappear_from_shop_when_bought() { unknown1: 0, })))).await.unwrap().for_each(drop); - let p1_items = entity_gateway.get_items_by_character(&char1.id).await.unwrap(); - assert!(p1_items[0].item != p1_items[1].item); + let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); + p1_items.items[0].with_individual(|item1| { + p1_items.items[1].with_individual(|item2| { + assert_ne!(item1, item2); + }).unwrap(); + }).unwrap(); }