Compare commits

...

4 Commits

Author SHA1 Message Date
jake cd31052b9a remove bit of unsafe code 1 year ago
jake 04180d1d86 moved weapon logic to libpso 1 year ago
jake f1e1fd72af clippystuff 1 year ago
jake 88959c24f9 move characterclass/sectionid to libpso 1 year ago
  1. 2
      Cargo.toml
  2. 68
      src/bin/main.rs
  3. 17
      src/client/src/lib.rs
  4. 2
      src/drops/Cargo.toml
  5. 2
      src/drops/src/box_drop_table.rs
  6. 2
      src/drops/src/generic_armor.rs
  7. 2
      src/drops/src/generic_shield.rs
  8. 2
      src/drops/src/generic_unit.rs
  9. 4
      src/drops/src/generic_weapon.rs
  10. 5
      src/drops/src/lib.rs
  11. 4
      src/drops/src/rare_drop_table.rs
  12. 2
      src/drops/src/tech_table.rs
  13. 2
      src/drops/src/tool_table.rs
  14. 136
      src/entity/src/character.rs
  15. 2
      src/entity/src/gateway/inmemory.rs
  16. 5
      src/entity/src/gateway/postgres/models.rs
  17. 2
      src/entity/src/gateway/postgres/postgres.rs
  18. 4
      src/entity/src/item/esweapon.rs
  19. 2
      src/entity/src/item/mag.rs
  20. 6
      src/entity/src/item/mod.rs
  21. 1591
      src/entity/src/item/weapon.rs
  22. 3
      src/entity/src/room.rs
  23. 3
      src/items/src/actions.rs
  24. 4
      src/items/src/apply_item.rs
  25. 1
      src/items/src/bank.rs
  26. 2
      src/items/src/inventory.rs
  27. 7
      src/items/src/state.rs
  28. 4
      src/location/src/lib.rs
  29. 19
      src/login_server/src/character.rs
  30. 4
      src/pktbuilder/src/character.rs
  31. 4
      src/pktbuilder/src/message.rs
  32. 2
      src/room/Cargo.toml
  33. 2
      src/room/src/lib.rs
  34. 2
      src/ship_server/src/direct_message.rs
  35. 2
      src/ship_server/src/lib.rs
  36. 2
      src/ship_server/src/room.rs
  37. 2
      src/shops/Cargo.toml
  38. 2
      src/shops/src/lib.rs
  39. 3
      src/shops/src/tool.rs
  40. 4
      src/shops/src/weapon.rs
  41. 1
      src/stats/Cargo.toml
  42. 2
      src/stats/src/items.rs
  43. 2
      src/stats/src/leveltable.rs
  44. 22
      tests/common.rs
  45. 55
      tests/test_bank.rs
  46. 2
      tests/test_item_drop.rs
  47. 3
      tests/test_item_id.rs
  48. 11
      tests/test_item_pickup.rs
  49. 5
      tests/test_item_use.rs
  50. 2
      tests/test_mags.rs
  51. 29
      tests/test_shops.rs
  52. 93
      tests/test_trade.rs

2
Cargo.toml

@ -42,7 +42,7 @@ patch_server = { path = "./src/patch_server" }
login_server = { path = "./src/login_server" } login_server = { path = "./src/login_server" }
ship_server = { path = "./src/ship_server" } ship_server = { path = "./src/ship_server" }
libpso = { git = "http://git.sharnoth.com/jake/libpso", rev="90246b6" }
libpso = { git = "http://git.sharnoth.com/jake/libpso", rev="0e2cac0" }
async-std = { version = "1.9.0", features = ["unstable", "attributes"] } async-std = { version = "1.9.0", features = ["unstable", "attributes"] }
futures = "0.3.5" futures = "0.3.5"

68
src/bin/main.rs

@ -7,6 +7,8 @@ use login_server::character::CharacterServerState;
use patch_server::{PatchServerState, generate_patch_tree, load_config, load_motd}; use patch_server::{PatchServerState, generate_patch_tree, load_config, load_motd};
use ship_server::ShipServerStateBuilder; use ship_server::ShipServerStateBuilder;
use libpso::item::weapon::{Weapon, WeaponType, WeaponSpecial, WeaponAttribute, Attribute};
use maps::Holiday; use maps::Holiday;
use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::gateway::{EntityGateway, InMemoryGateway};
use entity::account::{NewUserAccountEntity, NewUserSettingsEntity}; use entity::account::{NewUserAccountEntity, NewUserSettingsEntity};
@ -81,8 +83,8 @@ fn main() {
entity_gateway.create_item( entity_gateway.create_item(
item::NewItemEntity { item::NewItemEntity {
item: item::ItemDetail::Weapon( item: item::ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Vulcan,
Weapon {
weapon: WeaponType::Vulcan,
grind: 0, grind: 0,
special: None, special: None,
attrs: [None, None, None], attrs: [None, None, None],
@ -106,12 +108,12 @@ fn main() {
let item0 = entity_gateway.create_item( let item0 = entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Raygun,
Weapon {
weapon: WeaponType::Raygun,
grind: 5, grind: 5,
special: Some(item::weapon::WeaponSpecial::Hell),
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}),
special: Some(WeaponSpecial::Hell),
attrs: [Some(WeaponAttribute{attr: Attribute::Hit, value: 40}),
Some(WeaponAttribute{attr: Attribute::Dark, value: 30}),
None,], None,],
tekked: false, tekked: false,
} }
@ -120,12 +122,12 @@ fn main() {
let item1 = entity_gateway.create_item( let item1 = entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Handgun,
Weapon {
weapon: WeaponType::Handgun,
grind: 5, grind: 5,
special: Some(item::weapon::WeaponSpecial::Charge),
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}),
special: Some(WeaponSpecial::Charge),
attrs: [Some(WeaponAttribute{attr: Attribute::Hit, value: 40}),
Some(WeaponAttribute{attr: Attribute::Dark, value: 30}),
None,], None,],
tekked: true, tekked: true,
} }
@ -134,12 +136,12 @@ fn main() {
let item2_w = entity_gateway.create_item( let item2_w = entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Vjaya,
Weapon {
weapon: WeaponType::Vjaya,
grind: 5, grind: 5,
special: Some(item::weapon::WeaponSpecial::Charge),
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
special: Some(WeaponSpecial::Charge),
attrs: [Some(WeaponAttribute{attr: Attribute::Hit, value: 40}),
Some(WeaponAttribute{attr: Attribute::Dark, value: 100}),
None,], None,],
tekked: true, tekked: true,
} }
@ -148,12 +150,12 @@ fn main() {
let item3 = entity_gateway.create_item( let item3 = entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Vulcan,
Weapon {
weapon: WeaponType::Vulcan,
grind: 5, grind: 5,
special: Some(item::weapon::WeaponSpecial::Charge),
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
special: Some(WeaponSpecial::Charge),
attrs: [Some(WeaponAttribute{attr: Attribute::Hit, value: 100}),
Some(WeaponAttribute{attr: Attribute::Dark, value: 100}),
None,], None,],
tekked: true, tekked: true,
} }
@ -162,13 +164,13 @@ fn main() {
let item4 = entity_gateway.create_item( let item4 = entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::DarkFlow,
Weapon {
weapon: WeaponType::DarkFlow,
grind: 0, grind: 0,
special: None, special: None,
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),],
attrs: [Some(WeaponAttribute{attr: Attribute::Hit, value: 100}),
Some(WeaponAttribute{attr: Attribute::Dark, value: 100}),
Some(WeaponAttribute{attr: Attribute::Native, value: 100}),],
tekked: true, tekked: true,
} }
), ),
@ -289,13 +291,13 @@ fn main() {
let item14 = entity_gateway.create_item( let item14 = entity_gateway.create_item(
NewItemEntity { NewItemEntity {
item: ItemDetail::Weapon( item: ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Vulcan,
Weapon {
weapon: WeaponType::Vulcan,
grind: 5, grind: 5,
special: Some(item::weapon::WeaponSpecial::Charge),
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),],
special: Some(WeaponSpecial::Charge),
attrs: [Some(WeaponAttribute{attr: Attribute::Hit, value: 100}),
Some(WeaponAttribute{attr: Attribute::Dark, value: 100}),
Some(WeaponAttribute{attr: Attribute::Native, value: 100}),],
tekked: true, tekked: true,
} }
), ),

17
src/client/src/lib.rs

@ -19,6 +19,8 @@ use shops::{WeaponShopItem, ToolShopItem, ArmorShopItem};
pub enum ClientError { pub enum ClientError {
#[error("not found {0}")] #[error("not found {0}")]
NotFound(ClientId), NotFound(ClientId),
#[error("failed to get multiple clients")]
WithManyFailed,
} }
@ -67,24 +69,19 @@ impl Clients {
.read() .read()
.await; .await;
let mut client_states: [std::mem::MaybeUninit<RwLockReadGuard<ClientState>>; N] = unsafe {
std::mem::MaybeUninit::uninit().assume_init()
};
let mut client_states = Vec::new();
for (cindex, client_id) in client_ids.iter().enumerate() {
for client_id in client_ids.iter() {
let c = clients let c = clients
.get(client_id) .get(client_id)
.ok_or(ClientError::NotFound(*client_id))? .ok_or(ClientError::NotFound(*client_id))?
.read() .read()
.await; .await;
client_states[cindex].write(c);
client_states.push(c);
} }
let client_states = unsafe {
std::mem::transmute_copy(&client_states)
};
Ok(func(client_states).await)
let result = func(client_states.try_into().map_err(|_| ClientError::WithManyFailed)?).await;
Ok(result)
} }
pub async fn with_mut<'a, T, F>(&'a self, client_id: ClientId, func: F) -> Result<T, anyhow::Error> pub async fn with_mut<'a, T, F>(&'a self, client_id: ClientId, func: F) -> Result<T, anyhow::Error>

2
src/drops/Cargo.toml

@ -9,6 +9,8 @@ entity = { workspace = true }
maps = { workspace = true } maps = { workspace = true }
stats = { workspace = true } stats = { workspace = true }
libpso = { workspace = true }
rand = { workspace = true } rand = { workspace = true }
rand_chacha = { workspace = true } rand_chacha = { workspace = true }
serde = { workspace = true } serde = { workspace = true }

2
src/drops/src/box_drop_table.rs

@ -2,7 +2,7 @@
use rand::{Rng}; use rand::{Rng};
use rand::distributions::{WeightedIndex, Distribution}; use rand::distributions::{WeightedIndex, Distribution};
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use entity::character::SectionID;
use libpso::character::SectionID;
use maps::room::{Difficulty, Episode}; use maps::room::{Difficulty, Episode};
use maps::area::MapArea; use maps::area::MapArea;
use crate::{ItemDropType, load_data_file}; use crate::{ItemDropType, load_data_file};

2
src/drops/src/generic_armor.rs

@ -3,7 +3,7 @@ use serde::{Serialize, Deserialize};
use rand::Rng; use rand::Rng;
use rand::distributions::{WeightedIndex, Distribution}; use rand::distributions::{WeightedIndex, Distribution};
use entity::character::SectionID;
use libpso::character::SectionID;
use entity::item::armor::{ArmorType, Armor}; use entity::item::armor::{ArmorType, Armor};
use maps::room::{Difficulty, Episode}; use maps::room::{Difficulty, Episode};
use maps::area::MapArea; use maps::area::MapArea;

2
src/drops/src/generic_shield.rs

@ -4,7 +4,7 @@ use rand::Rng;
use rand::distributions::{WeightedIndex, Distribution}; use rand::distributions::{WeightedIndex, Distribution};
use entity::item::shield::{ShieldType, Shield}; use entity::item::shield::{ShieldType, Shield};
use entity::character::SectionID;
use libpso::character::SectionID;
use maps::room::{Difficulty, Episode}; use maps::room::{Difficulty, Episode};
use maps::area::MapArea; use maps::area::MapArea;
use crate::{ItemDropType, load_data_file}; use crate::{ItemDropType, load_data_file};

2
src/drops/src/generic_unit.rs

@ -3,7 +3,7 @@ use serde::{Serialize, Deserialize};
use rand::Rng; use rand::Rng;
use rand::seq::IteratorRandom; use rand::seq::IteratorRandom;
use entity::character::SectionID;
use libpso::character::SectionID;
use entity::item::unit::{UnitType, Unit, UnitModifier}; use entity::item::unit::{UnitType, Unit, UnitModifier};
use maps::room::{Difficulty, Episode}; use maps::room::{Difficulty, Episode};
use maps::area::MapArea; use maps::area::MapArea;

4
src/drops/src/generic_weapon.rs

@ -4,8 +4,8 @@ use rand::Rng;
use rand::distributions::{WeightedIndex, Distribution}; use rand::distributions::{WeightedIndex, Distribution};
use rand::seq::SliceRandom; use rand::seq::SliceRandom;
use entity::character::SectionID;
use entity::item::weapon::{Weapon, WeaponType, Attribute, WeaponAttribute, WeaponSpecial};
use libpso::character::SectionID;
use libpso::item::weapon::{Weapon, WeaponType, Attribute, WeaponAttribute, WeaponSpecial};
use maps::room::{Difficulty, Episode}; use maps::room::{Difficulty, Episode};
use maps::area::MapArea; use maps::area::MapArea;
use crate::{ItemDropType, load_data_file}; use crate::{ItemDropType, load_data_file};

5
src/drops/src/lib.rs

@ -24,7 +24,7 @@ use rand::{Rng, SeedableRng};
use maps::monster::MonsterType; use maps::monster::MonsterType;
use maps::room::{Difficulty, Episode}; use maps::room::{Difficulty, Episode};
use maps::area::MapArea; use maps::area::MapArea;
use entity::character::SectionID;
use libpso::character::SectionID;
use crate::generic_weapon::GenericWeaponTable; use crate::generic_weapon::GenericWeaponTable;
use crate::generic_armor::GenericArmorTable; use crate::generic_armor::GenericArmorTable;
use crate::generic_shield::GenericShieldTable; use crate::generic_shield::GenericShieldTable;
@ -33,7 +33,8 @@ use crate::tool_table::ToolTable;
use crate::rare_drop_table::RareDropTable; use crate::rare_drop_table::RareDropTable;
use crate::box_drop_table::BoxDropTable; use crate::box_drop_table::BoxDropTable;
use maps::object::MapObject; use maps::object::MapObject;
use entity::item::{ItemType, weapon, armor, shield, unit, mag, tool, tech, esweapon};
use entity::item::{ItemType, armor, shield, unit, mag, tool, tech, esweapon};
use libpso::item::weapon;
fn data_file_path(episode: Episode, difficulty: Difficulty, section_id: SectionID, filename: &str) -> PathBuf { fn data_file_path(episode: Episode, difficulty: Difficulty, section_id: SectionID, filename: &str) -> PathBuf {

4
src/drops/src/rare_drop_table.rs

@ -1,13 +1,13 @@
use std::collections::HashMap; use std::collections::HashMap;
use rand::Rng; use rand::Rng;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use entity::item::weapon::{Weapon, WeaponType};
use libpso::item::weapon::{Weapon, WeaponType};
use entity::item::armor::{Armor, ArmorType}; use entity::item::armor::{Armor, ArmorType};
use entity::item::shield::{Shield, ShieldType}; use entity::item::shield::{Shield, ShieldType};
use entity::item::unit::{Unit, UnitType}; use entity::item::unit::{Unit, UnitType};
use entity::item::tool::{Tool, ToolType}; use entity::item::tool::{Tool, ToolType};
use entity::item::mag::{Mag, MagType}; use entity::item::mag::{Mag, MagType};
use entity::character::SectionID;
use libpso::character::SectionID;
use maps::monster::MonsterType; use maps::monster::MonsterType;
use maps::room::{Difficulty, Episode}; use maps::room::{Difficulty, Episode};
use maps::area::MapArea; use maps::area::MapArea;

2
src/drops/src/tech_table.rs

@ -6,7 +6,7 @@ use rand::distributions::{WeightedIndex, Distribution};
use entity::item::tech::{Technique, TechniqueDisk}; use entity::item::tech::{Technique, TechniqueDisk};
use maps::room::{Difficulty, Episode}; use maps::room::{Difficulty, Episode};
use maps::area::MapArea; use maps::area::MapArea;
use entity::character::SectionID;
use libpso::character::SectionID;
use crate::{ItemDropType, load_data_file}; use crate::{ItemDropType, load_data_file};

2
src/drops/src/tool_table.rs

@ -6,7 +6,7 @@ use rand::distributions::{WeightedIndex, Distribution};
use entity::item::tool::{Tool, ToolType}; use entity::item::tool::{Tool, ToolType};
use maps::room::{Difficulty, Episode}; use maps::room::{Difficulty, Episode};
use maps::area::MapArea; use maps::area::MapArea;
use entity::character::SectionID;
use libpso::character::SectionID;
use crate::{ItemDropType, load_data_file}; use crate::{ItemDropType, load_data_file};
use crate::tech_table::TechniqueTable; use crate::tech_table::TechniqueTable;

136
src/entity/src/character.rs

@ -1,146 +1,12 @@
use std::convert::{From, Into};
use std::collections::HashMap; use std::collections::HashMap;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use libpso::packet::ship::{UpdateConfig, WriteInfoboard}; use libpso::packet::ship::{UpdateConfig, WriteInfoboard};
use libpso::character::{CharacterClass, SectionID};
use libpso::character::settings::{DEFAULT_PALETTE_CONFIG, DEFAULT_TECH_MENU}; use libpso::character::settings::{DEFAULT_PALETTE_CONFIG, DEFAULT_TECH_MENU};
use crate::item::tech::Technique; use crate::item::tech::Technique;
use crate::account::UserAccountId; use crate::account::UserAccountId;
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, enum_utils::FromStr, derive_more::Display, Serialize, Deserialize, Default)]
pub enum CharacterClass {
#[default]
HUmar,
HUnewearl,
HUcast,
HUcaseal,
RAmar,
RAmarl,
RAcast,
RAcaseal,
FOmar,
FOmarl,
FOnewm,
FOnewearl,
}
// TODO: TryFrom
impl From<u8> for CharacterClass {
fn from(f: u8) -> CharacterClass {
match f {
0 => CharacterClass::HUmar,
1 => CharacterClass::HUnewearl,
2 => CharacterClass::HUcast,
3 => CharacterClass::RAmar,
4 => CharacterClass::RAcast,
5 => CharacterClass::RAcaseal,
6 => CharacterClass::FOmarl,
7 => CharacterClass::FOnewm,
8 => CharacterClass::FOnewearl,
9 => CharacterClass::HUcaseal,
10 => CharacterClass::FOmar,
11 => CharacterClass::RAmarl,
_ => panic!("unknown class")
}
}
}
impl From<CharacterClass> for u8 {
fn from(other: CharacterClass) -> u8 {
match other {
CharacterClass::HUmar => 0,
CharacterClass::HUnewearl => 1,
CharacterClass::HUcast => 2,
CharacterClass::RAmar => 3,
CharacterClass::RAcast => 4,
CharacterClass::RAcaseal => 5,
CharacterClass::FOmarl => 6,
CharacterClass::FOnewm => 7,
CharacterClass::FOnewearl => 8,
CharacterClass::HUcaseal => 9,
CharacterClass::FOmar => 10,
CharacterClass::RAmarl => 11,
}
}
}
impl CharacterClass {
pub fn is_human(&self) -> bool {
matches!(self,
CharacterClass::HUmar |
CharacterClass::RAmar |
CharacterClass::RAmarl |
CharacterClass::FOmar |
CharacterClass::FOmarl)
}
pub fn is_newman(&self) -> bool {
matches!(self,
CharacterClass::HUnewearl |
CharacterClass::FOnewm |
CharacterClass::FOnewearl)
}
pub fn is_android(&self) -> bool {
matches!(self,
CharacterClass::HUcast |
CharacterClass::HUcaseal |
CharacterClass::RAcast |
CharacterClass::RAcaseal)
}
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, enum_utils::FromStr, derive_more::Display, Serialize, Deserialize, Default)]
pub enum SectionID {
#[default]
Viridia,
Greenill,
Skyly,
Bluefull,
Purplenum,
Pinkal,
Redria,
Oran,
Yellowboze,
Whitill,
}
impl From<u8> for SectionID {
fn from(id: u8) -> SectionID {
match id {
0 => SectionID::Viridia,
1 => SectionID::Greenill,
2 => SectionID::Skyly,
3 => SectionID::Bluefull,
4 => SectionID::Purplenum,
5 => SectionID::Pinkal,
6 => SectionID::Redria,
7 => SectionID::Oran,
8 => SectionID::Yellowboze,
9 => SectionID::Whitill,
_ => panic!(),
}
}
}
impl From<SectionID> for u8 {
fn from(other: SectionID) -> u8 {
match other {
SectionID::Viridia => 0,
SectionID::Greenill => 1,
SectionID::Skyly => 2,
SectionID::Bluefull => 3,
SectionID::Purplenum => 4,
SectionID::Pinkal => 5,
SectionID::Redria => 6,
SectionID::Oran => 7,
SectionID::Yellowboze => 8,
SectionID::Whitill => 9,
}
}
}
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct CharacterAppearance { pub struct CharacterAppearance {

2
src/entity/src/gateway/inmemory.rs

@ -271,7 +271,7 @@ fn apply_modifiers(items: &BTreeMap<ItemEntityId, ItemEntity>,
ItemDetail::Weapon(mut weapon) => { ItemDetail::Weapon(mut weapon) => {
if let Some(weapon_modifiers) = weapon_modifiers.get(&item.id) { if let Some(weapon_modifiers) = weapon_modifiers.get(&item.id) {
for weapon_modifier in weapon_modifiers.iter() { for weapon_modifier in weapon_modifiers.iter() {
weapon.apply_modifier(weapon_modifier);
weapon::apply_modifier(&mut weapon, weapon_modifier);
} }
} }
ItemDetail::Weapon(weapon) ItemDetail::Weapon(weapon)

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

@ -6,7 +6,10 @@ use libpso::character::settings;
use libpso::util::vec_to_array; use libpso::util::vec_to_array;
use crate::account::*; use crate::account::*;
use crate::character::*; use crate::character::*;
use libpso::character::{CharacterClass, SectionID};
use crate::item::*; use crate::item::*;
use crate::item::weapon::WeaponModifier;
use libpso::item::weapon;
use crate::room::*; use crate::room::*;
use maps::area::MapArea; use maps::area::MapArea;
use maps::room::{Episode, Difficulty}; use maps::room::{Episode, Difficulty};
@ -326,7 +329,7 @@ impl From<PgWeapon> for weapon::Weapon {
#[derive(Debug, sqlx::FromRow)] #[derive(Debug, sqlx::FromRow)]
pub struct PgWeaponModifier { pub struct PgWeaponModifier {
pub weapon: i32, pub weapon: i32,
pub modifier: sqlx::types::Json<weapon::WeaponModifier>,
pub modifier: sqlx::types::Json<WeaponModifier>,
} }
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]

2
src/entity/src/gateway/postgres/postgres.rs

@ -92,7 +92,7 @@ async fn apply_item_modifications(conn: &mut sqlx::PgConnection, item: ItemEntit
weapon_modifiers.for_each(|modifier| async move { weapon_modifiers.for_each(|modifier| async move {
if let Ok(modifier) = modifier { if let Ok(modifier) = modifier {
weapon.apply_modifier(&modifier.modifier);
weapon::apply_modifier(&mut weapon, &modifier.modifier);
} }
}).await; }).await;

4
src/entity/src/item/esweapon.rs

@ -9,7 +9,7 @@ pub enum ItemParseError {
InvalidESWeaponName, InvalidESWeaponName,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, strum_macros::EnumIter)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ESWeaponType { pub enum ESWeaponType {
Saber = 0, Saber = 0,
Sword, Sword,
@ -121,7 +121,7 @@ impl ESWeaponType {
} }
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, strum_macros::EnumIter)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum ESWeaponSpecial { pub enum ESWeaponSpecial {
Jellen = 1, Jellen = 1,
Zalure, Zalure,

2
src/entity/src/item/mag.rs

@ -1,8 +1,8 @@
use std::collections::HashMap; use std::collections::HashMap;
use thiserror::Error; use thiserror::Error;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use libpso::character::{CharacterClass, SectionID};
use crate::item::tool::ToolType; use crate::item::tool::ToolType;
use crate::character::{CharacterClass, SectionID};
use crate::item::ItemEntityId; use crate::item::ItemEntityId;
use std::io::Read; use std::io::Read;

6
src/entity/src/item/mod.rs

@ -1,4 +1,3 @@
#![allow(dead_code)]
pub mod weapon; pub mod weapon;
pub mod armor; pub mod armor;
pub mod shield; pub mod shield;
@ -13,6 +12,7 @@ use crate::character::CharacterEntityId;
use crate::room::RoomEntityId; use crate::room::RoomEntityId;
use maps::area::MapArea; use maps::area::MapArea;
use maps::monster::MonsterType; use maps::monster::MonsterType;
use libpso::item::ItemBytes;
//use crate::ship::drops::ItemDropType; //use crate::ship::drops::ItemDropType;
#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)]
@ -108,7 +108,7 @@ impl Meseta {
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ItemType { pub enum ItemType {
Weapon(weapon::WeaponType),
Weapon(libpso::item::weapon::WeaponType),
Armor(armor::ArmorType), Armor(armor::ArmorType),
Shield(shield::ShieldType), Shield(shield::ShieldType),
Unit(unit::UnitType), Unit(unit::UnitType),
@ -125,7 +125,7 @@ pub enum ItemParseError {
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum ItemDetail { pub enum ItemDetail {
Weapon(weapon::Weapon),
Weapon(libpso::item::weapon::Weapon),
Armor(armor::Armor), Armor(armor::Armor),
Shield(shield::Shield), Shield(shield::Shield),
Unit(unit::Unit), Unit(unit::Unit),

1591
src/entity/src/item/weapon.rs
File diff suppressed because it is too large
View File

3
src/entity/src/room.rs

@ -1,7 +1,8 @@
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use crate::character::{CharacterEntityId, SectionID};
use crate::character::CharacterEntityId;
use libpso::character::SectionID;
use maps::room::{Episode, Difficulty}; use maps::room::{Episode, Difficulty};

3
src/items/src/actions.rs

@ -13,6 +13,7 @@ use entity::gateway::{EntityGateway, EntityGatewayTransaction};
use entity::item::{ItemDetail, NewItemEntity, TradeId, ItemModifier}; use entity::item::{ItemDetail, NewItemEntity, TradeId, ItemModifier};
use entity::item::tool::Tool; use entity::item::tool::Tool;
use entity::room::RoomEntityId; use entity::room::RoomEntityId;
use entity::item::weapon::apply_modifier;
use maps::area::MapArea; use maps::area::MapArea;
use crate::state::{ItemStateProxy, ItemStateError, AddItemResult, StackedItemDetail, IndividualItemDetail}; use crate::state::{ItemStateProxy, ItemStateError, AddItemResult, StackedItemDetail, IndividualItemDetail};
use crate::bank::{BankItem, BankItemDetail}; use crate::bank::{BankItem, BankItemDetail};
@ -1112,7 +1113,7 @@ where
Box::pin(async move { Box::pin(async move {
match (&mut inventory_item.item, modifier) { match (&mut inventory_item.item, modifier) {
(InventoryItemDetail::Individual(IndividualItemDetail{entity_id, item: ItemDetail::Weapon(ref mut weapon), ..}), ItemModifier::WeaponModifier(modifier)) => { (InventoryItemDetail::Individual(IndividualItemDetail{entity_id, item: ItemDetail::Weapon(ref mut weapon), ..}), ItemModifier::WeaponModifier(modifier)) => {
weapon.apply_modifier(&modifier);
apply_modifier(weapon, &modifier);
transaction.gateway().add_weapon_modifier(entity_id, &modifier).await?; transaction.gateway().add_weapon_modifier(entity_id, &modifier).await?;
}, },
_ => return Err(ItemStateError::InvalidModifier.into()) _ => return Err(ItemStateError::InvalidModifier.into())

4
src/items/src/apply_item.rs

@ -10,7 +10,7 @@ use entity::item::mag::{MagCell, MagCellError};
use entity::item::tool::{Tool, ToolType}; use entity::item::tool::{Tool, ToolType};
use entity::item::tech::TechniqueDisk; use entity::item::tech::TechniqueDisk;
use entity::item::{ItemDetail, ItemEntityId}; use entity::item::{ItemDetail, ItemEntityId};
use entity::item::weapon::WeaponModifier;
use entity::item::weapon::{WeaponModifier, apply_modifier};
use crate::state::ItemStateProxy; use crate::state::ItemStateProxy;
use crate::inventory::InventoryItemDetail; use crate::inventory::InventoryItemDetail;
@ -259,7 +259,7 @@ where
let mut inventory = item_state.inventory(&character.id).await?; let mut inventory = item_state.inventory(&character.id).await?;
let (weapon_entity_id, weapon) = inventory.equipped_weapon_mut() let (weapon_entity_id, weapon) = inventory.equipped_weapon_mut()
.ok_or(ApplyItemError::ItemNotEquipped)?; .ok_or(ApplyItemError::ItemNotEquipped)?;
weapon.apply_modifier(&modifier);
apply_modifier(weapon, &modifier);
entity_gateway.add_weapon_modifier(&weapon_entity_id, &modifier).await?; entity_gateway.add_weapon_modifier(&weapon_entity_id, &modifier).await?;
item_state.set_inventory(inventory).await; item_state.set_inventory(inventory).await;

1
src/items/src/bank.rs

@ -1,4 +1,5 @@
use std::cmp::Ordering; use std::cmp::Ordering;
use libpso::item::ItemBytes;
use libpso::character::character; use libpso::character::character;
use crate::ClientItemId; use crate::ClientItemId;
use entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, BankEntity, BankItemEntity}; use entity::item::{Meseta, ItemEntityId, ItemDetail, ItemEntity, BankEntity, BankItemEntity};

2
src/items/src/inventory.rs

@ -8,7 +8,7 @@ use async_std::sync::{Arc, Mutex};
use entity::character::CharacterEntityId; use entity::character::CharacterEntityId;
use entity::item::tool::ToolType; use entity::item::tool::ToolType;
use entity::item::mag::Mag; use entity::item::mag::Mag;
use entity::item::weapon::Weapon;
use libpso::item::weapon::Weapon;
use shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem}; use shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem};
use crate::state::ItemStateError; use crate::state::ItemStateError;
use crate::state::{IndividualItemDetail, StackedItemDetail, AddItemResult}; use crate::state::{IndividualItemDetail, StackedItemDetail, AddItemResult};

7
src/items/src/state.rs

@ -4,11 +4,12 @@ use async_std::sync::{Arc, RwLock, Mutex};
use futures::stream::{FuturesOrdered, StreamExt}; use futures::stream::{FuturesOrdered, StreamExt};
use anyhow::Context; use anyhow::Context;
use libpso::item::ItemBytes;
use entity::gateway::{EntityGateway, GatewayError}; use entity::gateway::{EntityGateway, GatewayError};
use entity::character::{CharacterEntity, CharacterEntityId}; use entity::character::{CharacterEntity, CharacterEntityId};
use entity::item::{ItemEntityId, ItemDetail, ItemEntity, InventoryItemEntity, BankItemEntity, BankIdentifier}; use entity::item::{ItemEntityId, ItemDetail, ItemEntity, InventoryItemEntity, BankItemEntity, BankIdentifier};
use entity::item::tool::Tool; use entity::item::tool::Tool;
use entity::item::weapon::Weapon;
use libpso::item::weapon::Weapon;
use entity::item::mag::Mag; use entity::item::mag::Mag;
use drops::ItemDrop; use drops::ItemDrop;
use crate::ClientItemId; use crate::ClientItemId;
@ -240,7 +241,7 @@ impl ItemState {
item_id: ClientItemId(0), item_id: ClientItemId(0),
item: InventoryItemDetail::Stacked(StackedItemDetail { item: InventoryItemDetail::Stacked(StackedItemDetail {
entity_ids: items.iter().map(|i| i.id).collect(), entity_ids: items.iter().map(|i| i.id).collect(),
tool: items.get(0)
tool: items.first()
.ok_or_else(|| ItemStateError::StackedItemError(items.clone()))? .ok_or_else(|| ItemStateError::StackedItemError(items.clone()))?
.item .item
.clone() .clone()
@ -284,7 +285,7 @@ impl ItemState {
BankItemEntity::Stacked(items) => { BankItemEntity::Stacked(items) => {
BankItemDetail::Stacked(StackedItemDetail { BankItemDetail::Stacked(StackedItemDetail {
entity_ids: items.iter().map(|i| i.id).collect(), entity_ids: items.iter().map(|i| i.id).collect(),
tool: items.get(0)
tool: items.first()
.ok_or_else(|| ItemStateError::StackedItemError(items.clone()))? .ok_or_else(|| ItemStateError::StackedItemError(items.clone()))?
.item .item
.clone() .clone()

4
src/location/src/lib.rs

@ -317,7 +317,7 @@ impl ClientLocation {
.flatten() .flatten()
.collect::<Vec<_>>(); .collect::<Vec<_>>();
r.sort_by_key(|k| k.time_join); r.sort_by_key(|k| k.time_join);
let c = r.get(0)
let c = r.first()
.ok_or(GetLeaderError::NoClientInArea)?; .ok_or(GetLeaderError::NoClientInArea)?;
Ok(**c) Ok(**c)
} }
@ -332,7 +332,7 @@ impl ClientLocation {
.flatten() .flatten()
.collect::<Vec<_>>(); .collect::<Vec<_>>();
l.sort_by_key(|k| k.time_join); l.sort_by_key(|k| k.time_join);
let c = l.get(0).ok_or(GetLeaderError::NoClientInArea)?;
let c = l.first().ok_or(GetLeaderError::NoClientInArea)?;
Ok(**c) Ok(**c)
} }

19
src/login_server/src/character.rs

@ -13,6 +13,7 @@ use libpso::packet::ship::{MenuDetail, SmallLeftDialog};
use libpso::{PacketParseError, PSOPacket}; use libpso::{PacketParseError, PSOPacket};
use libpso::crypto::bb::PSOBBCipher; use libpso::crypto::bb::PSOBBCipher;
use libpso::character::character; use libpso::character::character;
use libpso::character::CharacterClass;
use entity::item; use entity::item;
use networking::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY}; use networking::cipherkeys::{ELSEWHERE_PRIVATE_KEY, ELSEWHERE_PARRAY};
@ -24,12 +25,12 @@ use libpso::util::{utf8_to_array, utf8_to_utf16_array};
use entity::gateway::{EntityGateway, GatewayError}; use entity::gateway::{EntityGateway, GatewayError};
use entity::account::{UserAccountId, UserAccountEntity, NewUserSettingsEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM}; use entity::account::{UserAccountId, UserAccountEntity, NewUserSettingsEntity, USERFLAG_NEWCHAR, USERFLAG_DRESSINGROOM};
use entity::item::{NewItemEntity, ItemDetail, ItemNote, InventoryItemEntity, InventoryEntity, BankEntity, BankIdentifier, EquippedEntity, Meseta}; use entity::item::{NewItemEntity, ItemDetail, ItemNote, InventoryItemEntity, InventoryEntity, BankEntity, BankIdentifier, EquippedEntity, Meseta};
use entity::item::weapon::Weapon;
use libpso::item::weapon::{Weapon, WeaponType};
use entity::item::armor::Armor; use entity::item::armor::Armor;
use entity::item::tech::Technique; use entity::item::tech::Technique;
use entity::item::tool::Tool; use entity::item::tool::Tool;
use entity::item::mag::Mag; use entity::item::mag::Mag;
use entity::character::{CharacterEntity, NewCharacterEntity, CharacterClass, TechLevel};
use entity::character::{CharacterEntity, NewCharacterEntity, TechLevel};
use crate::login::get_login_status; use crate::login::get_login_status;
use networking::interserver::AuthToken; use networking::interserver::AuthToken;
@ -215,9 +216,9 @@ async fn new_character<EG: EntityGateway + Clone>(entity_gateway: &mut EG, user:
entity_gateway.set_bank_meseta(&character.id, &BankIdentifier::Character, Meseta(0)).await?; entity_gateway.set_bank_meseta(&character.id, &BankIdentifier::Character, Meseta(0)).await?;
let new_weapon = match character.char_class { let new_weapon = match character.char_class {
CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => item::weapon::WeaponType::Saber,
CharacterClass::RAmar | CharacterClass::RAmarl | CharacterClass::RAcast | CharacterClass::RAcaseal => item::weapon::WeaponType::Handgun,
CharacterClass::FOmar | CharacterClass::FOmarl | CharacterClass::FOnewm | CharacterClass::FOnewearl => item::weapon::WeaponType::Cane,
CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => WeaponType::Saber,
CharacterClass::RAmar | CharacterClass::RAmarl | CharacterClass::RAcast | CharacterClass::RAcaseal => WeaponType::Handgun,
CharacterClass::FOmar | CharacterClass::FOmarl | CharacterClass::FOnewm | CharacterClass::FOnewearl => WeaponType::Cane,
}; };
@ -753,8 +754,8 @@ fn new_character_from_preview(user: &UserAccountEntity, preview: &CharacterPrevi
let mut character = NewCharacterEntity::new(user.id); let mut character = NewCharacterEntity::new(user.id);
character.slot = preview.slot; character.slot = preview.slot;
character.name = String::from_utf16_lossy(&preview.character.name).trim_matches(char::from(0)).into(); character.name = String::from_utf16_lossy(&preview.character.name).trim_matches(char::from(0)).into();
character.section_id = preview.character.section_id.into();
character.char_class = preview.character.ch_class.into();
character.section_id = preview.character.section_id;
character.char_class = preview.character.ch_class;
character.appearance.costume = preview.character.costume; character.appearance.costume = preview.character.costume;
character.appearance.skin = preview.character.skin; character.appearance.skin = preview.character.skin;
character.appearance.face = preview.character.face; character.appearance.face = preview.character.face;
@ -809,8 +810,8 @@ impl<'a> SelectScreenCharacterBuilder<'a> {
//model: character.model, //model: character.model,
//_unused: [0; 15], //_unused: [0; 15],
//name_color_checksum: character.name_color_checksum, //name_color_checksum: character.name_color_checksum,
section_id: character.section_id.into(),
ch_class: character.char_class.into(),
section_id: character.section_id,
ch_class: character.char_class,
//v2flags: character.v2flags, //v2flags: character.v2flags,
//version: character.version, //version: character.version,
//v1flags: character.v1flags, //v1flags: character.v1flags,

4
src/pktbuilder/src/character.rs

@ -62,8 +62,8 @@ impl<'a> CharacterBytesBuilder<'a> {
ata: stats.ata, ata: stats.ata,
lck: stats.lck + character.materials.luck as u16 * 2, lck: stats.lck + character.materials.luck as u16 * 2,
level, level,
section_id: character.section_id.into(),
ch_class: character.char_class.into(),
section_id: character.section_id,
ch_class: character.char_class,
costume: character.appearance.costume, costume: character.appearance.costume,
skin: character.appearance.skin, skin: character.appearance.skin,
face: character.appearance.face, face: character.appearance.face,

4
src/pktbuilder/src/message.rs

@ -1,5 +1,7 @@
use libpso::packet::messages::*; use libpso::packet::messages::*;
use libpso::packet::ship::*; use libpso::packet::ship::*;
use libpso::item::weapon;
use libpso::item::ItemBytes;
use entity::item; use entity::item;
use stats::leveltable::CharacterStats; use stats::leveltable::CharacterStats;
//use crate::ship::ship::{ShipError}; //use crate::ship::ship::{ShipError};
@ -215,7 +217,7 @@ pub fn shop_list<I: ShopItem>(shop_type: u8, items: &[I]) -> ShopList {
} }
} }
pub fn tek_preview(id: ClientItemId, weapon: &item::weapon::Weapon) -> TekPreview {
pub fn tek_preview(id: ClientItemId, weapon: &weapon::Weapon) -> TekPreview {
let bytes = weapon.as_bytes(); let bytes = weapon.as_bytes();
TekPreview { TekPreview {
client: 0x79, client: 0x79,

2
src/room/Cargo.toml

@ -10,6 +10,8 @@ quests = { workspace = true }
location = { workspace = true } location = { workspace = true }
drops = { workspace = true } drops = { workspace = true }
libpso = { workspace = true }
rand = { workspace = true } rand = { workspace = true }
async-std = { workspace = true } async-std = { workspace = true }
futures = { workspace = true } futures = { workspace = true }

2
src/room/src/lib.rs

@ -10,7 +10,7 @@ use rand::Rng;
use quests::{QuestList, QuestLoadError}; use quests::{QuestList, QuestLoadError};
use maps::maps::Maps; use maps::maps::Maps;
use drops::DropTable; use drops::DropTable;
use entity::character::SectionID;
use libpso::character::SectionID;
use entity::room::{RoomEntityId, RoomEntityMode}; use entity::room::{RoomEntityId, RoomEntityMode};
use maps::monster::{load_monster_stats_table, MonsterType, MonsterStats}; use maps::monster::{load_monster_stats_table, MonsterType, MonsterStats};
use maps::area::MapAreaLookup; use maps::area::MapAreaLookup;

2
src/ship_server/src/direct_message.rs

@ -482,7 +482,7 @@ where
.as_weapon() .as_weapon()
.ok_or_else(|| ItemStateError::WrongItemType(ClientItemId(tek_request.item_id)))?; .ok_or_else(|| ItemStateError::WrongItemType(ClientItemId(tek_request.item_id)))?;
weapon.apply_modifier(&item::weapon::WeaponModifier::Tekked {
item::weapon::apply_modifier(&mut weapon, &item::weapon::WeaponModifier::Tekked {
special: special_mod, special: special_mod,
percent: percent_mod, percent: percent_mod,
grind: grind_mod, grind: grind_mod,

2
src/ship_server/src/lib.rs

@ -30,7 +30,7 @@ use networking::serverstate::{SendServerPacket, RecvServerPacket, ServerState, O
use networking::interserver::{AuthToken, Ship, ServerId, InterserverActor, LoginMessage, ShipMessage}; use networking::interserver::{AuthToken, Ship, ServerId, InterserverActor, LoginMessage, ShipMessage};
use pktbuilder::ship::SHIP_MENU_ID; use pktbuilder::ship::SHIP_MENU_ID;
use entity::gateway::{EntityGateway, GatewayError}; use entity::gateway::{EntityGateway, GatewayError};
use entity::character::SectionID;
use libpso::character::SectionID;
use entity::room::RoomNote; use entity::room::RoomNote;
use location::{ClientLocation, RoomLobby, ClientLocationError, RoomId}; use location::{ClientLocation, RoomLobby, ClientLocationError, RoomId};
use drops::{DropTable, StandardDropTable}; use drops::{DropTable, StandardDropTable};

2
src/ship_server/src/room.rs

@ -8,7 +8,7 @@ use libpso::packet::messages::*;
use networking::serverstate::ClientId; use networking::serverstate::ClientId;
use stats::leveltable::LEVEL_TABLE; use stats::leveltable::LEVEL_TABLE;
use entity::gateway::EntityGateway; use entity::gateway::EntityGateway;
use entity::character::SectionID;
use libpso::character::SectionID;
use entity::room::{NewRoomEntity, RoomEntityMode, RoomNote}; use entity::room::{NewRoomEntity, RoomEntityMode, RoomNote};
use drops::DropTable; use drops::DropTable;
use crate::SendShipPacket; use crate::SendShipPacket;

2
src/shops/Cargo.toml

@ -8,6 +8,8 @@ maps = { workspace = true }
stats = { workspace = true } stats = { workspace = true }
entity = { workspace = true } entity = { workspace = true }
libpso = { workspace = true }
async-std = { workspace = true } async-std = { workspace = true }
async-trait = { workspace = true } async-trait = { workspace = true }
futures = { workspace = true } futures = { workspace = true }

2
src/shops/src/lib.rs

@ -7,7 +7,7 @@ use futures::future::OptionFuture;
use std::collections::HashMap; use std::collections::HashMap;
use entity::item::ItemDetail; use entity::item::ItemDetail;
use maps::room::Difficulty; use maps::room::Difficulty;
use entity::character::SectionID;
use libpso::character::SectionID;
pub use weapon::{WeaponShop, WeaponShopItem}; pub use weapon::{WeaponShop, WeaponShopItem};
pub use tool::{ToolShop, ToolShopItem}; pub use tool::{ToolShop, ToolShopItem};

3
src/shops/src/tool.rs

@ -231,9 +231,6 @@ impl<R: Rng + SeedableRng> ToolShop<R> {
else { else {
let mut techs = Vec::new(); let mut techs = Vec::new();
let tier = tier.techs.iter() let tier = tier.techs.iter()
.map(|(tech, entry)| {
(tech, entry)
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let tech_choice = WeightedIndex::new(tier.iter().map(|(_, e)| e.probability)).unwrap(); let tech_choice = WeightedIndex::new(tier.iter().map(|(_, e)| e.probability)).unwrap();

4
src/shops/src/weapon.rs

@ -8,10 +8,10 @@ use serde::Deserialize;
use rand::{Rng, SeedableRng}; use rand::{Rng, SeedableRng};
use rand::distributions::{WeightedIndex, Distribution}; use rand::distributions::{WeightedIndex, Distribution};
use rand::seq::{SliceRandom, IteratorRandom}; use rand::seq::{SliceRandom, IteratorRandom};
use entity::character::SectionID;
use libpso::character::SectionID;
use maps::room::Difficulty; use maps::room::Difficulty;
use entity::item::ItemDetail; use entity::item::ItemDetail;
use entity::item::weapon::{Weapon, WeaponType, WeaponSpecial, Attribute, WeaponAttribute};
use libpso::item::weapon::{Weapon, WeaponType, WeaponSpecial, Attribute, WeaponAttribute};
use crate::ShopItem; use crate::ShopItem;
use stats::items::WEAPON_STATS; use stats::items::WEAPON_STATS;

1
src/stats/Cargo.toml

@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
libpso = { workspace = true }
entity = { workspace = true } entity = { workspace = true }
toml = { workspace = true } toml = { workspace = true }
serde = { workspace = true } serde = { workspace = true }

2
src/stats/src/items.rs

@ -4,7 +4,7 @@ use serde::{Serialize, Deserialize};
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use entity::item::weapon::WeaponType;
use libpso::item::weapon::WeaponType;
use entity::item::armor::ArmorType; use entity::item::armor::ArmorType;
use entity::item::shield::ShieldType; use entity::item::shield::ShieldType;
use entity::item::unit::UnitType; use entity::item::unit::UnitType;

2
src/stats/src/leveltable.rs

@ -1,6 +1,6 @@
use std::fs::File; use std::fs::File;
use serde_json::Value; use serde_json::Value;
use entity::character::CharacterClass;
use libpso::character::CharacterClass;
use std::sync::LazyLock; use std::sync::LazyLock;
pub static LEVEL_TABLE: LazyLock<CharacterLevelTable> = LazyLock::new(CharacterLevelTable::default); pub static LEVEL_TABLE: LazyLock<CharacterLevelTable> = LazyLock::new(CharacterLevelTable::default);

22
tests/common.rs

@ -3,7 +3,8 @@
use networking::serverstate::{ClientId, ServerState}; use networking::serverstate::{ClientId, ServerState};
use entity::gateway::EntityGateway; use entity::gateway::EntityGateway;
use entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity}; use entity::account::{UserAccountEntity, NewUserAccountEntity, NewUserSettingsEntity};
use entity::character::{CharacterEntity, NewCharacterEntity, SectionID};
use entity::character::{CharacterEntity, NewCharacterEntity};
use libpso::character::SectionID;
use entity::item::{Meseta, BankIdentifier}; use entity::item::{Meseta, BankIdentifier};
use ship_server::{ShipServerState, ShipServerStateBuilder, RecvShipPacket}; use ship_server::{ShipServerState, ShipServerStateBuilder, RecvShipPacket};
use maps::room::{RoomMode, Difficulty, Episode}; use maps::room::{RoomMode, Difficulty, Episode};
@ -16,6 +17,7 @@ use drops::{DropTable, ItemDropType};
use shops::{ItemShops, WeaponShopItem, ToolShopItem, ArmorShopItem}; use shops::{ItemShops, WeaponShopItem, ToolShopItem, ArmorShopItem};
use entity::item; use entity::item;
use libpso::item::weapon;
use libpso::packet::ship::*; use libpso::packet::ship::*;
use libpso::packet::login::{Login, Session}; use libpso::packet::login::{Login, Session};
@ -159,16 +161,16 @@ pub async fn join_room<EG: EntityGateway + Clone>(ship: &mut ShipServerState<EG>
pub struct WeaponBuilder { pub struct WeaponBuilder {
weapon: item::weapon::WeaponType,
weapon: weapon::WeaponType,
grind: u8, grind: u8,
special: Option<item::weapon::WeaponSpecial>,
attributes: [Option<item::weapon::WeaponAttribute>; 3],
special: Option<weapon::WeaponSpecial>,
attributes: [Option<weapon::WeaponAttribute>; 3],
tekked: bool, tekked: bool,
} }
impl WeaponBuilder { impl WeaponBuilder {
fn new(weapon: item::weapon::WeaponType) -> WeaponBuilder {
fn new(weapon: weapon::WeaponType) -> WeaponBuilder {
WeaponBuilder { WeaponBuilder {
weapon, weapon,
grind: 0, grind: 0,
@ -185,19 +187,19 @@ impl WeaponBuilder {
} }
} }
pub fn special(self, special: item::weapon::WeaponSpecial) -> WeaponBuilder {
pub fn special(self, special: weapon::WeaponSpecial) -> WeaponBuilder {
WeaponBuilder { WeaponBuilder {
special: Some(special), special: Some(special),
..self ..self
} }
} }
pub fn attr(mut self, attr: item::weapon::Attribute, value: i8) -> WeaponBuilder {
pub fn attr(mut self, attr: weapon::Attribute, value: i8) -> WeaponBuilder {
self.attributes self.attributes
.iter_mut() .iter_mut()
.find(|k| k.is_none()) .find(|k| k.is_none())
.map(|empty_attr| { .map(|empty_attr| {
*empty_attr = Some(item::weapon::WeaponAttribute {
*empty_attr = Some(weapon::WeaponAttribute {
attr, attr,
value, value,
}) })
@ -216,7 +218,7 @@ impl WeaponBuilder {
pub fn as_new(self) -> item::NewItemEntity { pub fn as_new(self) -> item::NewItemEntity {
item::NewItemEntity { item::NewItemEntity {
item: item::ItemDetail::Weapon( item: item::ItemDetail::Weapon(
item::weapon::Weapon {
weapon::Weapon {
weapon: self.weapon, weapon: self.weapon,
grind: self.grind, grind: self.grind,
special: self.special, special: self.special,
@ -410,7 +412,7 @@ impl TechBuilder {
pub struct ItemBuilder; pub struct ItemBuilder;
impl ItemBuilder { impl ItemBuilder {
pub fn weapon(weapon: item::weapon::WeaponType) -> WeaponBuilder {
pub fn weapon(weapon: weapon::WeaponType) -> WeaponBuilder {
WeaponBuilder::new(weapon) WeaponBuilder::new(weapon)
} }

55
tests/test_bank.rs

@ -2,6 +2,7 @@ use std::collections::BTreeSet;
use networking::serverstate::{ClientId, ServerState}; use networking::serverstate::{ClientId, ServerState};
use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::gateway::{EntityGateway, InMemoryGateway};
use entity::item; use entity::item;
use libpso::item::weapon;
use ship_server::{RecvShipPacket, SendShipPacket}; use ship_server::{RecvShipPacket, SendShipPacket};
use shops::StandardItemShops; use shops::StandardItemShops;
@ -20,7 +21,7 @@ async fn test_bank_items_sent_in_character_login() {
let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
let item = entity_gateway.create_item( let item = entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap(); ).await.unwrap();
@ -47,7 +48,7 @@ async fn test_request_bank_items() {
let mut bank = Vec::new(); let mut bank = Vec::new();
for _ in 0..3 { for _ in 0..3 {
bank.push(entity_gateway.create_item( bank.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
} }
@ -120,7 +121,7 @@ async fn test_request_bank_items_sorted() {
let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
let item1 = entity_gateway.create_item( let item1 = entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap(); ).await.unwrap();
let monomate = entity_gateway.create_item( let monomate = entity_gateway.create_item(
@ -128,7 +129,7 @@ async fn test_request_bank_items_sorted() {
.as_new() .as_new()
).await.unwrap(); ).await.unwrap();
let item2 = entity_gateway.create_item( let item2 = entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Calibur)
ItemBuilder::weapon(weapon::WeaponType::Calibur)
.as_new() .as_new()
).await.unwrap(); ).await.unwrap();
@ -164,11 +165,11 @@ async fn test_deposit_individual_item() {
let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await; let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
let item0 = entity_gateway.create_item( let item0 = entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap(); ).await.unwrap();
let item1 = entity_gateway.create_item( let item1 = entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap(); ).await.unwrap();
@ -468,14 +469,14 @@ async fn test_deposit_individual_item_in_full_bank() {
let mut inventory = Vec::new(); let mut inventory = Vec::new();
inventory.push(entity_gateway.create_item( inventory.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
let mut bank = Vec::new(); let mut bank = Vec::new();
for _ in 0..200usize { for _ in 0..200usize {
bank.push(entity_gateway.create_item( bank.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
} }
@ -533,7 +534,7 @@ async fn test_deposit_stacked_item_in_full_bank() {
let mut full_bank = Vec::new(); let mut full_bank = Vec::new();
for _ in 0..200usize { for _ in 0..200usize {
full_bank.push(entity_gateway.create_item( full_bank.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
} }
@ -600,7 +601,7 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() {
let mut almost_full_bank: Vec<item::BankItemEntity> = Vec::new(); let mut almost_full_bank: Vec<item::BankItemEntity> = Vec::new();
for _ in 0..199usize { for _ in 0..199usize {
almost_full_bank.push(entity_gateway.create_item( almost_full_bank.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap().into()); ).await.unwrap().into());
} }
@ -758,7 +759,7 @@ async fn test_withdraw_individual_item() {
let mut bank = Vec::new(); let mut bank = Vec::new();
bank.push(entity_gateway.create_item( bank.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
@ -1049,14 +1050,14 @@ async fn test_withdraw_individual_item_in_full_inventory() {
let mut bank = Vec::new(); let mut bank = Vec::new();
bank.push(entity_gateway.create_item( bank.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
let mut inventory = Vec::new(); let mut inventory = Vec::new();
for _ in 0..30usize { for _ in 0..30usize {
inventory.push(entity_gateway.create_item( inventory.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
} }
@ -1110,7 +1111,7 @@ async fn test_withdraw_stacked_item_in_full_inventory() {
let mut inventory = Vec::new(); let mut inventory = Vec::new();
for _ in 0..30usize { for _ in 0..30usize {
inventory.push(entity_gateway.create_item( inventory.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
} }
@ -1171,7 +1172,7 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() {
let mut items = Vec::new(); let mut items = Vec::new();
for _i in 0..29usize { for _i in 0..29usize {
items.push(entity_gateway.create_item( items.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.as_new() .as_new()
).await.unwrap().into()); ).await.unwrap().into());
} }
@ -1389,12 +1390,12 @@ async fn test_deposit_items_into_shared_banks() {
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
let item0 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Saber).as_new()).await.unwrap();
let item1 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Buster).as_new()).await.unwrap();
let item2 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Rifle).as_new()).await.unwrap();
let item3 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Handgun).as_new()).await.unwrap();
let item4 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Autogun).as_new()).await.unwrap();
let item5 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Calibur).as_new()).await.unwrap();
let item0 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Saber).as_new()).await.unwrap();
let item1 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Buster).as_new()).await.unwrap();
let item2 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Rifle).as_new()).await.unwrap();
let item3 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Handgun).as_new()).await.unwrap();
let item4 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Autogun).as_new()).await.unwrap();
let item5 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Calibur).as_new()).await.unwrap();
entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![item0, item1, item2, item3, item4, item5])).await.unwrap(); entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![item0, item1, item2, item3, item4, item5])).await.unwrap();
@ -1586,12 +1587,12 @@ async fn test_withdraw_items_from_shared_banks() {
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
let item0 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Saber).as_new()).await.unwrap();
let item1 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Buster).as_new()).await.unwrap();
let item2 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Rifle).as_new()).await.unwrap();
let item3 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Handgun).as_new()).await.unwrap();
let item4 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Autogun).as_new()).await.unwrap();
let item5 = entity_gateway.create_item(ItemBuilder::weapon(item::weapon::WeaponType::Calibur).as_new()).await.unwrap();
let item0 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Saber).as_new()).await.unwrap();
let item1 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Buster).as_new()).await.unwrap();
let item2 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Rifle).as_new()).await.unwrap();
let item3 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Handgun).as_new()).await.unwrap();
let item4 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Autogun).as_new()).await.unwrap();
let item5 = entity_gateway.create_item(ItemBuilder::weapon(weapon::WeaponType::Calibur).as_new()).await.unwrap();
entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item0, item1]), &item::BankIdentifier::Character).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item0, item1]), &item::BankIdentifier::Character).await.unwrap();
entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item2, item3]), &item::BankIdentifier::Shared(item::BankName("asdf".into()))).await.unwrap(); entity_gateway.set_character_bank(&char1.id, &item::BankEntity::new(vec![item2, item3]), &item::BankIdentifier::Shared(item::BankName("asdf".into()))).await.unwrap();

2
tests/test_item_drop.rs

@ -8,7 +8,7 @@ use maps::maps::Maps;
use maps::area::MapArea; use maps::area::MapArea;
use maps::variant::{MapVariant, MapVariantMode}; use maps::variant::{MapVariant, MapVariantMode};
use maps::enemy::MapEnemy; use maps::enemy::MapEnemy;
use entity::item::weapon::WeaponType;
use libpso::item::weapon::WeaponType;
use libpso::packet::ship::*; use libpso::packet::ship::*;
use libpso::packet::messages::*; use libpso::packet::messages::*;

3
tests/test_item_id.rs

@ -1,6 +1,7 @@
use networking::serverstate::{ClientId, ServerState}; use networking::serverstate::{ClientId, ServerState};
use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::gateway::{EntityGateway, InMemoryGateway};
use entity::item; use entity::item;
use libpso::item::weapon;
use ship_server::RecvShipPacket; use ship_server::RecvShipPacket;
use libpso::packet::ship::*; use libpso::packet::ship::*;
@ -134,7 +135,7 @@ async fn test_using_some_monomates_after_a_convoluted_series_of_leaves_and_joins
p3_items.push( p3_items.push(
item::InventoryItemEntity::Individual( item::InventoryItemEntity::Individual(
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap() ).await.unwrap()
)); ));

11
tests/test_item_pickup.rs

@ -1,6 +1,7 @@
use networking::serverstate::{ClientId, ServerState}; use networking::serverstate::{ClientId, ServerState};
use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::gateway::{EntityGateway, InMemoryGateway};
use entity::item; use entity::item;
use libpso::item::weapon;
use ship_server::RecvShipPacket; use ship_server::RecvShipPacket;
use libpso::packet::ship::*; use libpso::packet::ship::*;
@ -19,7 +20,7 @@ async fn test_pick_up_individual_item() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
@ -200,7 +201,7 @@ async fn test_pick_up_meseta_when_inventory_full() {
let mut p1_items = Vec::new(); let mut p1_items = Vec::new();
for _ in 0..30usize { for _ in 0..30usize {
p1_items.push(entity_gateway.create_item( p1_items.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
} }
@ -263,7 +264,7 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
for _slot in 0..29usize { for _slot in 0..29usize {
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap().into()); ).await.unwrap().into());
} }
@ -328,14 +329,14 @@ async fn test_can_not_pick_up_item_when_inventory_full() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
for _slot in 0..30usize { for _slot in 0..30usize {
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
} }
let mut p2_inv = Vec::new(); let mut p2_inv = Vec::new();
p2_inv.push(entity_gateway.create_item( p2_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());

5
tests/test_item_use.rs

@ -1,6 +1,7 @@
use networking::serverstate::{ClientId, ServerState}; use networking::serverstate::{ClientId, ServerState};
use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::gateway::{EntityGateway, InMemoryGateway};
use entity::item; use entity::item;
use libpso::item::weapon;
use ship_server::RecvShipPacket; use ship_server::RecvShipPacket;
use entity::character::TechLevel; use entity::character::TechLevel;
@ -326,7 +327,7 @@ async fn test_use_monogrinder() {
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await; let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
let saber = entity_gateway.create_item( let saber = entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap(); ).await.unwrap();
@ -369,7 +370,7 @@ async fn test_use_monogrinder() {
let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
assert_eq!(inventory_items.items.len(), 2); assert_eq!(inventory_items.items.len(), 2);
assert!(matches!(inventory_items.items[0], item::InventoryItemEntity::Individual(item::ItemEntity{ item: item::ItemDetail::Weapon(item::weapon::Weapon {grind: 2, ..}), ..})));
assert!(matches!(inventory_items.items[0], item::InventoryItemEntity::Individual(item::ItemEntity{ item: item::ItemDetail::Weapon(weapon::Weapon {grind: 2, ..}), ..})));
} }

2
tests/test_mags.rs

@ -2,7 +2,7 @@ use networking::serverstate::{ClientId, ServerState};
use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::gateway::{EntityGateway, InMemoryGateway};
use entity::item; use entity::item;
use ship_server::RecvShipPacket; use ship_server::RecvShipPacket;
use entity::character::{CharacterClass, SectionID};
use libpso::character::{CharacterClass, SectionID};
use libpso::packet::ship::*; use libpso::packet::ship::*;
use libpso::packet::messages::*; use libpso::packet::messages::*;

29
tests/test_shops.rs

@ -1,6 +1,7 @@
use networking::serverstate::{ClientId, ServerState}; use networking::serverstate::{ClientId, ServerState};
use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::gateway::{EntityGateway, InMemoryGateway};
use entity::item; use entity::item;
use libpso::item::weapon;
use ship_server::{RecvShipPacket, SendShipPacket}; use ship_server::{RecvShipPacket, SendShipPacket};
use maps::room::Difficulty; use maps::room::Difficulty;
use items::state::ItemStateError; use items::state::ItemStateError;
@ -265,12 +266,12 @@ async fn test_player_sells_3_attr_weapon_to_shop() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.grind(5) .grind(5)
.special(item::weapon::WeaponSpecial::Charge)
.attr(item::weapon::Attribute::Hit, 100)
.attr(item::weapon::Attribute::Dark, 100)
.attr(item::weapon::Attribute::Native, 100)
.special(weapon::WeaponSpecial::Charge)
.attr(weapon::Attribute::Hit, 100)
.attr(weapon::Attribute::Dark, 100)
.attr(weapon::Attribute::Native, 100)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
@ -613,13 +614,13 @@ async fn test_player_sells_untekked_weapon() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Vulcan)
ItemBuilder::weapon(weapon::WeaponType::Vulcan)
.untekked() .untekked()
.grind(5) .grind(5)
.special(item::weapon::WeaponSpecial::Charge)
.attr(item::weapon::Attribute::Hit, 100)
.attr(item::weapon::Attribute::Dark, 100)
.attr(item::weapon::Attribute::Native, 100)
.special(weapon::WeaponSpecial::Charge)
.attr(weapon::Attribute::Hit, 100)
.attr(weapon::Attribute::Dark, 100)
.attr(weapon::Attribute::Native, 100)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
@ -651,11 +652,11 @@ async fn test_player_sells_rare_item() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::DarkFlow)
ItemBuilder::weapon(weapon::WeaponType::DarkFlow)
.grind(5) .grind(5)
.attr(item::weapon::Attribute::Hit, 100)
.attr(item::weapon::Attribute::Dark, 100)
.attr(item::weapon::Attribute::Native, 100)
.attr(weapon::Attribute::Hit, 100)
.attr(weapon::Attribute::Dark, 100)
.attr(weapon::Attribute::Native, 100)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());

93
tests/test_trade.rs

@ -2,6 +2,7 @@ use std::convert::TryInto;
use networking::serverstate::{ClientId, ServerState}; use networking::serverstate::{ClientId, ServerState};
use entity::gateway::{EntityGateway, InMemoryGateway}; use entity::gateway::{EntityGateway, InMemoryGateway};
use entity::item; use entity::item;
use libpso::item::weapon;
use ship_server::{ShipServerState, RecvShipPacket, SendShipPacket}; use ship_server::{ShipServerState, RecvShipPacket, SendShipPacket};
use entity::item::{Meseta, ItemEntity, InventoryItemEntity}; use entity::item::{Meseta, ItemEntity, InventoryItemEntity};
use ship_server::trade::TradeError; use ship_server::trade::TradeError;
@ -118,7 +119,7 @@ async fn test_trade_one_individual_item() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
@ -209,7 +210,7 @@ async fn test_trade_player2_to_player1() {
let mut p2_inv = Vec::new(); let mut p2_inv = Vec::new();
p2_inv.push(entity_gateway.create_item( p2_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
@ -300,7 +301,7 @@ async fn test_reverse_trade_ack_order() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
@ -590,12 +591,12 @@ async fn test_trade_individual_both() {
let p1_inv = vec![ let p1_inv = vec![
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap()]; ).await.unwrap()];
let p2_inv = vec![ let p2_inv = vec![
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()]; ).await.unwrap()];
@ -722,10 +723,10 @@ async fn test_trade_individual_both() {
let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
assert_eq!(p1_items.items.len(), 1); assert_eq!(p1_items.items.len(), 1);
assert!(matches!(p1_items.items[0].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(item::weapon::Weapon {weapon: item::weapon::WeaponType::Handgun, ..}), ..}));
assert!(matches!(p1_items.items[0].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(weapon::Weapon {weapon: weapon::WeaponType::Handgun, ..}), ..}));
let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
assert_eq!(p2_items.items.len(), 1); assert_eq!(p2_items.items.len(), 1);
assert!(matches!(p2_items.items[0].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(item::weapon::Weapon {weapon: item::weapon::WeaponType::Saber, ..}), ..}));
assert!(matches!(p2_items.items[0].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(weapon::Weapon {weapon: weapon::WeaponType::Saber, ..}), ..}));
} }
#[async_std::test] #[async_std::test]
@ -1355,7 +1356,7 @@ async fn test_trade_individual_for_stacked() {
let p1_inv = vec![ let p1_inv = vec![
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap()]; ).await.unwrap()];
@ -1499,7 +1500,7 @@ async fn test_trade_individual_for_stacked() {
assert!(matches!(p1_items.items[0].with_stacked(|i| i.clone()).unwrap()[0], item::ItemEntity{item: item::ItemDetail::Tool(item::tool::Tool {tool: item::tool::ToolType::Monomate, ..}), ..})); assert!(matches!(p1_items.items[0].with_stacked(|i| i.clone()).unwrap()[0], item::ItemEntity{item: item::ItemDetail::Tool(item::tool::Tool {tool: item::tool::ToolType::Monomate, ..}), ..}));
let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
assert_eq!(p2_items.items.len(), 1); assert_eq!(p2_items.items.len(), 1);
assert!(matches!(p2_items.items[0].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(item::weapon::Weapon {weapon: item::weapon::WeaponType::Saber, ..}), ..}));
assert!(matches!(p2_items.items[0].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(weapon::Weapon {weapon: weapon::WeaponType::Saber, ..}), ..}));
} }
#[async_std::test] #[async_std::test]
@ -1511,21 +1512,21 @@ async fn test_trade_multiple_individual() {
let p1_inv = vec![ let p1_inv = vec![
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Buster)
ItemBuilder::weapon(weapon::WeaponType::Buster)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
]; ];
let p2_inv = vec![ let p2_inv = vec![
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Autogun)
ItemBuilder::weapon(weapon::WeaponType::Autogun)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
]; ];
@ -1717,12 +1718,12 @@ async fn test_trade_multiple_individual() {
let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
assert_eq!(p1_items.items.len(), 2); assert_eq!(p1_items.items.len(), 2);
assert!(matches!(p1_items.items[0].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(item::weapon::Weapon {weapon: item::weapon::WeaponType::Handgun, ..}), ..}));
assert!(matches!(p1_items.items[1].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(item::weapon::Weapon {weapon: item::weapon::WeaponType::Autogun, ..}), ..}));
assert!(matches!(p1_items.items[0].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(weapon::Weapon {weapon: weapon::WeaponType::Handgun, ..}), ..}));
assert!(matches!(p1_items.items[1].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(weapon::Weapon {weapon: weapon::WeaponType::Autogun, ..}), ..}));
let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
assert_eq!(p2_items.items.len(), 2); assert_eq!(p2_items.items.len(), 2);
assert!(matches!(p2_items.items[0].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(item::weapon::Weapon {weapon: item::weapon::WeaponType::Saber, ..}), ..}));
assert!(matches!(p2_items.items[1].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(item::weapon::Weapon {weapon: item::weapon::WeaponType::Buster, ..}), ..}));
assert!(matches!(p2_items.items[0].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(weapon::Weapon {weapon: weapon::WeaponType::Saber, ..}), ..}));
assert!(matches!(p2_items.items[1].with_individual(|i| i.clone()).unwrap(), item::ItemEntity{item: item::ItemDetail::Weapon(weapon::Weapon {weapon: weapon::WeaponType::Buster, ..}), ..}));
} }
@ -1986,7 +1987,7 @@ async fn test_trade_not_enough_inventory_space_individual() {
let mut entity_gateway = entity_gateway.clone(); let mut entity_gateway = entity_gateway.clone();
async move { async move {
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await ).await
}})) }}))
@ -1999,7 +2000,7 @@ async fn test_trade_not_enough_inventory_space_individual() {
let mut entity_gateway = entity_gateway.clone(); let mut entity_gateway = entity_gateway.clone();
async move { async move {
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await ).await
}})) }}))
@ -2102,7 +2103,7 @@ async fn test_trade_not_enough_inventory_space_stacked() {
let mut entity_gateway = entity_gateway.clone(); let mut entity_gateway = entity_gateway.clone();
async move { async move {
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await ).await
}})) }}))
@ -2553,7 +2554,7 @@ async fn test_back_out_of_trade_last_minute() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
@ -2611,7 +2612,7 @@ async fn test_valid_trade_when_both_inventories_are_full() {
let mut entity_gateway = entity_gateway.clone(); let mut entity_gateway = entity_gateway.clone();
async move { async move {
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await ).await
}})) }}))
@ -2624,7 +2625,7 @@ async fn test_valid_trade_when_both_inventories_are_full() {
let mut entity_gateway = entity_gateway.clone(); let mut entity_gateway = entity_gateway.clone();
async move { async move {
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await ).await
}})) }}))
@ -2714,12 +2715,12 @@ async fn test_valid_trade_when_both_inventories_are_full() {
let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
assert_eq!(p1_items.items.len(), 30); assert_eq!(p1_items.items.len(), 30);
assert_eq!(p1_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(item::weapon::Weapon { weapon: item::weapon::WeaponType::Saber, ..}, ..))).count(), 28);
assert_eq!(p1_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(item::weapon::Weapon { weapon: item::weapon::WeaponType::Handgun, ..}, ..))).count(), 2);
assert_eq!(p1_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(weapon::Weapon { weapon: weapon::WeaponType::Saber, ..}, ..))).count(), 28);
assert_eq!(p1_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(weapon::Weapon { weapon: weapon::WeaponType::Handgun, ..}, ..))).count(), 2);
let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
assert_eq!(p2_items.items.len(), 30); assert_eq!(p2_items.items.len(), 30);
assert_eq!(p2_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(item::weapon::Weapon { weapon: item::weapon::WeaponType::Saber, ..}, ..))).count(), 2);
assert_eq!(p2_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(item::weapon::Weapon { weapon: item::weapon::WeaponType::Handgun, ..}, ..))).count(), 28);
assert_eq!(p2_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(weapon::Weapon { weapon: weapon::WeaponType::Saber, ..}, ..))).count(), 2);
assert_eq!(p2_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(weapon::Weapon { weapon: weapon::WeaponType::Handgun, ..}, ..))).count(), 28);
} }
#[async_std::test] #[async_std::test]
@ -2733,7 +2734,7 @@ async fn test_invalid_trade_when_both_inventories_are_full() {
let mut entity_gateway = entity_gateway.clone(); let mut entity_gateway = entity_gateway.clone();
async move { async move {
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await ).await
}})) }}))
@ -2746,7 +2747,7 @@ async fn test_invalid_trade_when_both_inventories_are_full() {
let mut entity_gateway = entity_gateway.clone(); let mut entity_gateway = entity_gateway.clone();
async move { async move {
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await ).await
}})) }}))
@ -2847,10 +2848,10 @@ async fn test_invalid_trade_when_both_inventories_are_full() {
let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap(); let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
assert_eq!(p1_items.items.len(), 30); assert_eq!(p1_items.items.len(), 30);
assert_eq!(p1_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(item::weapon::Weapon { weapon: item::weapon::WeaponType::Saber, ..}, ..))).count(), 30);
assert_eq!(p1_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(weapon::Weapon { weapon: weapon::WeaponType::Saber, ..}, ..))).count(), 30);
let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap(); let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
assert_eq!(p2_items.items.len(), 30); assert_eq!(p2_items.items.len(), 30);
assert_eq!(p2_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(item::weapon::Weapon { weapon: item::weapon::WeaponType::Handgun, ..}, ..))).count(), 30);
assert_eq!(p2_items.items.iter().filter(|i| matches!(i.individual().unwrap().item, item::ItemDetail::Weapon(weapon::Weapon { weapon: weapon::WeaponType::Handgun, ..}, ..))).count(), 30);
} }
@ -2932,7 +2933,7 @@ async fn test_add_then_remove_individual_item() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
for _ in 0..2 { for _ in 0..2 {
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
} }
@ -3357,7 +3358,7 @@ async fn test_items_to_trade_data_does_not_match() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
@ -3394,8 +3395,8 @@ async fn test_items_to_trade_data_does_not_match() {
ItemEntity { ItemEntity {
id: p1_items.items[0].with_individual(|i| i.id).unwrap(), id: p1_items.items[0].with_individual(|i| i.id).unwrap(),
item: item::ItemDetail::Weapon( item: item::ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Handgun,
weapon::Weapon {
weapon: weapon::WeaponType::Handgun,
grind: 2, grind: 2,
special: None, special: None,
attrs: [None, None, None], attrs: [None, None, None],
@ -3430,7 +3431,7 @@ async fn test_items_to_trade_id_does_not_match() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());
@ -3627,15 +3628,15 @@ async fn test_items_to_trade_count_less_than() {
let p1_inv = vec![ let p1_inv = vec![
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Brand)
ItemBuilder::weapon(weapon::WeaponType::Brand)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Buster)
ItemBuilder::weapon(weapon::WeaponType::Buster)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
]; ];
@ -3705,15 +3706,15 @@ async fn test_items_to_trade_count_greater_than() {
let p1_inv = vec![ let p1_inv = vec![
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Brand)
ItemBuilder::weapon(weapon::WeaponType::Brand)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Buster)
ItemBuilder::weapon(weapon::WeaponType::Buster)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
]; ];
@ -3787,15 +3788,15 @@ async fn test_items_to_trade_count_mismatch_with_meseta() {
let p1_inv = vec![ let p1_inv = vec![
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Saber)
ItemBuilder::weapon(weapon::WeaponType::Saber)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Brand)
ItemBuilder::weapon(weapon::WeaponType::Brand)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
entity_gateway.create_item( entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Buster)
ItemBuilder::weapon(weapon::WeaponType::Buster)
.as_new() .as_new()
).await.unwrap(), ).await.unwrap(),
]; ];
@ -3863,7 +3864,7 @@ async fn test_dropping_item_after_trade() {
let mut p1_inv = Vec::new(); let mut p1_inv = Vec::new();
p1_inv.push(entity_gateway.create_item( p1_inv.push(entity_gateway.create_item(
ItemBuilder::weapon(item::weapon::WeaponType::Handgun)
ItemBuilder::weapon(weapon::WeaponType::Handgun)
.as_new() .as_new()
).await.unwrap()); ).await.unwrap());

Loading…
Cancel
Save