Browse Source

i t e m r e f a c t o r

pbs
jake 4 years ago
parent
commit
7ae8976c10
  1. 97
      src/bin/main.rs
  2. 27
      src/entity/gateway/entitygateway.rs
  3. 152
      src/entity/gateway/inmemory.rs
  4. 16
      src/entity/gateway/postgres/models.rs
  5. 32
      src/entity/gateway/postgres/postgres.rs
  6. 137
      src/entity/item/mod.rs
  7. 45
      src/login/character.rs
  8. 38
      src/ship/items/bank.rs
  9. 70
      src/ship/items/inventory.rs
  10. 199
      src/ship/items/manager.rs
  11. 4
      src/ship/packet/handler/message.rs
  12. 863
      tests/test_bank.rs
  13. 4
      tests/test_character.rs
  14. 16
      tests/test_exp_gain.rs
  15. 202
      tests/test_item_actions.rs
  16. 286
      tests/test_item_pickup.rs
  17. 206
      tests/test_item_use.rs
  18. 127
      tests/test_mags.rs
  19. 25
      tests/test_rooms.rs
  20. 108
      tests/test_shops.rs

97
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");

27
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<Vec<ItemEntity>, GatewayError> {
unimplemented!();
}
*/
async fn get_character_inventory(&mut self, _char_id: &CharacterEntityId) -> Result<InventoryEntity, GatewayError> {
unimplemented!();
}
async fn get_character_bank(&mut self, _char_id: &CharacterEntityId, _bank_name: BankName) -> Result<BankEntity, GatewayError> {
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<EquippedEntity, GatewayError> {
unimplemented!();
}
async fn set_character_equips(&mut self, _char_id: &CharacterEntityId, _equips: &EquippedEntity) -> Result<(), GatewayError> {
unimplemented!();
}
}

152
src/entity/gateway/inmemory.rs

@ -14,6 +14,9 @@ pub struct InMemoryGateway {
user_settings: Arc<Mutex<BTreeMap<UserSettingsId, UserSettingsEntity>>>,
characters: Arc<Mutex<BTreeMap<CharacterEntityId, CharacterEntity>>>,
items: Arc<Mutex<BTreeMap<ItemEntityId, ItemEntity>>>,
inventories: Arc<Mutex<BTreeMap<CharacterEntityId, InventoryEntity>>>,
banks: Arc<Mutex<BTreeMap<CharacterEntityId, BankEntity>>>,
equips: Arc<Mutex<BTreeMap<CharacterEntityId, EquippedEntity>>>,
mag_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<mag::MagModifier>>>>,
}
@ -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<UserAccountEntity, GatewayError> {
@ -208,55 +266,51 @@ impl EntityGateway for InMemoryGateway {
Ok(())
}
async fn get_items_by_character(&self, char_id: &CharacterEntityId) -> Result<Vec<ItemEntity>, GatewayError> {
let items = self.items.lock().unwrap();
Ok(items
async fn get_character_inventory(&mut self, char_id: &CharacterEntityId) -> Result<InventoryEntity, GatewayError> {
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<BankEntity, GatewayError> {
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<EquippedEntity, GatewayError> {
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(())
}
}

16
src/entity/gateway/postgres/models.rs

@ -383,7 +383,7 @@ impl Into<shield::Shield> for PgShield {
pub struct PgUnit {
unit: unit::UnitType,
modifier: Option<unit::UnitModifier>,
armor_slot: u8,
//armor_slot: u8,
}
impl From<unit::Unit> for PgUnit {
@ -391,7 +391,7 @@ impl From<unit::Unit> 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<unit::Unit> 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<ItemLocation> 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<ItemLocation> for PgItemLocationDetail {
impl Into<ItemLocation> 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},

32
src/entity/gateway/postgres/postgres.rs

@ -272,6 +272,8 @@ impl EntityGateway for PostgresGateway {
}
async fn create_item(&mut self, item: NewItemEntity) -> Result<ItemEntity, GatewayError> {
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<Vec<ItemEntity>, 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<InventoryEntity, GatewayError> {
unimplemented!();
}
async fn get_character_bank(&mut self, _char_id: &CharacterEntityId, _bank_name: BankName) -> Result<BankEntity, GatewayError> {
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<EquippedEntity, GatewayError> {
unimplemented!();
}
async fn set_character_equips(&mut self, _char_id: &CharacterEntityId, _equips: &EquippedEntity) -> Result<(), GatewayError> {
unimplemented!();
}
}

137
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<tool::Tool> {
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<ItemEntity>),
}
impl std::convert::From<ItemEntity> for InventoryItemEntity {
fn from(item: ItemEntity) -> InventoryItemEntity {
InventoryItemEntity::Individual(item)
}
}
impl std::convert::From<Vec<ItemEntity>> for InventoryItemEntity {
fn from(items: Vec<ItemEntity>) -> InventoryItemEntity {
InventoryItemEntity::Stacked(items)
}
}
impl InventoryItemEntity {
pub fn map_individual<F: Fn(ItemEntity) -> ItemEntity>(self, func: F) -> InventoryItemEntity {
match self {
InventoryItemEntity::Individual(item) => InventoryItemEntity::Individual(func(item)),
_ => self,
}
}
//pub fn with_individual<T>(&self, func: fn(&ItemEntity) -> T) -> Option<T> {
pub fn with_individual<F: Fn(&ItemEntity) -> T, T>(&self, func: F) -> Option<T> {
match self {
InventoryItemEntity::Individual(item) => Some(func(item)),
_ => None,
}
}
//pub fn with_stacked<T>(&self, func: fn(&Vec<ItemEntity>) -> T) -> Option<T> {
pub fn with_stacked<F: Fn(&Vec<ItemEntity>) -> T, T>(&self, func: F) -> Option<T> {
match self {
InventoryItemEntity::Stacked(items) => Some(func(items)),
_ => None,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct EquippedEntity {
pub weapon: Option<ItemEntityId>,
pub armor: Option<ItemEntityId>,
pub shield: Option<ItemEntityId>,
pub unit: [Option<ItemEntityId>; 4],
pub mag: Option<ItemEntityId>,
}
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<InventoryItemEntity>,
}
impl InventoryEntity {
pub fn new<T: Into<InventoryItemEntity>>(items: Vec<T>) -> InventoryEntity {
InventoryEntity {
items: items.into_iter().map(|i| i.into()).collect(),
}
}
}
#[derive(Clone, Debug)]
pub enum BankItemEntity {
Individual(ItemEntity),
Stacked(Vec<ItemEntity>),
}
impl std::convert::From<ItemEntity> for BankItemEntity {
fn from(item: ItemEntity) -> BankItemEntity {
BankItemEntity::Individual(item)
}
}
impl std::convert::From<Vec<ItemEntity>> for BankItemEntity {
fn from(items: Vec<ItemEntity>) -> BankItemEntity {
BankItemEntity::Stacked(items)
}
}
impl BankItemEntity {
pub fn with_individual<T>(&self, func: fn(&ItemEntity) -> T) -> Option<T> {
match self {
BankItemEntity::Individual(item) => Some(func(item)),
_ => None,
}
}
pub fn with_stacked<T>(&self, func: fn(&Vec<ItemEntity>) -> T) -> Option<T> {
match self {
BankItemEntity::Stacked(items) => Some(func(items)),
_ => None,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct BankEntity {
//pub items: [Option<CharacterBankItem>; 30],
pub items: Vec<BankItemEntity>,
}
impl BankEntity {
pub fn new<T: Into<BankItemEntity>>(items: Vec<T>) -> BankEntity {
BankEntity {
items: items.into_iter().map(|i| i.into()).collect(),
}
}
}

45
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<EG: EntityGateway>(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<EG: EntityGateway>(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<EG: EntityGateway>(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<EG: EntityGateway>(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<EG: EntityGateway>(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);
}

38
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()
}
}
}

70
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<InventoryItemHandle<'a>> {
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<InventoryItem>) {
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
}
}

199
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<ItemEntity>),
}
async fn update_inventory_slots<EG: EntityGateway>(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<EG: EntityGateway>(&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<InventoryItem, ItemManagerError> {
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::<Result<Vec<_>, _>>()?;
let character_inventory = CharacterInventory::new(inventory_items);
let bank_items = bank.items.into_iter()
.map(|item| -> Result<BankItem, ItemManagerError> {
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::<Result<Vec<_>, _>>()?;
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<EG: EntityGateway>(&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(())
}
}

4
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?
}
}

863
tests/test_bank.rs
File diff suppressed because it is too large
View File

4
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;

16
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;

202
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,
});
}
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();
}

286
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::<Vec<_>>();
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<_>>(),
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::<Vec<_>>();
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::<Vec<_>>();
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::<Vec<_>>();
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<_>>(),
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<_>>(),
vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
}).unwrap();
}

206
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();

127
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();
}

25
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;

108
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();
}
Loading…
Cancel
Save