Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
c8b9564009 | |||
b6cc50360a | |||
a238ae3846 | |||
b29bb473d5 | |||
9e8e10d434 | |||
e774b9c950 | |||
fc84db5393 | |||
ba0b827c24 | |||
637e182224 | |||
98b2ebfdd8 | |||
7e9b989078 | |||
c9160f177d | |||
a77b9874ff | |||
fe0f7ba41e |
@ -1,6 +1,6 @@
|
||||
[Extermination]
|
||||
list_order = 1
|
||||
description = "I am a description"
|
||||
description = "kill some shit"
|
||||
|
||||
[[Extermination.quests]]
|
||||
bin = "q058-ret-bb.bin"
|
||||
@ -32,4 +32,13 @@ dat = "q233-ext-bb.dat"
|
||||
[[Retrieval.quests]]
|
||||
bin = "q236-ext-bb.bin"
|
||||
dat = "q236-ext-bb.dat"
|
||||
#drop_table = "q102-drops"
|
||||
#drop_table = "q102-drops"
|
||||
|
||||
[Shop]
|
||||
list_order = 3
|
||||
description = "buy some shit"
|
||||
|
||||
[[Shop.quests]]
|
||||
bin = "q219-shp-bb.bin"
|
||||
dat = "q219-shp-bb.dat"
|
||||
#drop_table = "q204-drops"
|
||||
|
@ -74,7 +74,7 @@ fn main() {
|
||||
character.meseta = 999999;
|
||||
let character = entity_gateway.create_character(character).await.unwrap();
|
||||
|
||||
for _ in 0..3 {
|
||||
for _ in 0..3usize {
|
||||
entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Weapon(
|
||||
@ -84,6 +84,7 @@ fn main() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -93,12 +94,13 @@ fn main() {
|
||||
}).await.unwrap();
|
||||
}
|
||||
|
||||
for _ in 0..8 {
|
||||
for _ in 0..8usize {
|
||||
entity_gateway.create_item(
|
||||
NewItemEntity {
|
||||
item: ItemDetail::Tool (
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -119,6 +121,7 @@ fn main() {
|
||||
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}),
|
||||
None,],
|
||||
tekked: false,
|
||||
wrapping: Some(item::WrappingPaper::BlackYellow),
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -136,6 +139,7 @@ fn main() {
|
||||
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}),
|
||||
None,],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -153,6 +157,7 @@ fn main() {
|
||||
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
|
||||
None,],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -170,6 +175,7 @@ fn main() {
|
||||
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
|
||||
None,],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -187,6 +193,7 @@ fn main() {
|
||||
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
|
||||
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -208,6 +215,7 @@ fn main() {
|
||||
item: ItemDetail::Tool (
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::FedToMag {
|
||||
@ -223,6 +231,7 @@ fn main() {
|
||||
item: ItemDetail::Tool (
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::CellOfMag502,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -234,6 +243,8 @@ fn main() {
|
||||
item: ItemDetail::Tool (
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::CellOfMag502,
|
||||
// wrapping: None,
|
||||
wrapping: Some(item::WrappingPaper::PinkYellowGreen),
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Consumed,
|
||||
@ -251,6 +262,7 @@ fn main() {
|
||||
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 80}),
|
||||
None,],
|
||||
tekked: false,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Bank {
|
||||
@ -266,6 +278,7 @@ fn main() {
|
||||
dfp: 0,
|
||||
evp: 0,
|
||||
slots: 4,
|
||||
wrapping: Some(item::WrappingPaper::Green),
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -280,6 +293,7 @@ fn main() {
|
||||
shield: item::shield::ShieldType::Barrier,
|
||||
dfp: 0,
|
||||
evp: 0,
|
||||
wrapping: Some(item::WrappingPaper::Green),
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -293,6 +307,7 @@ fn main() {
|
||||
item::unit::Unit {
|
||||
unit: item::unit::UnitType::PriestMind,
|
||||
modifier: Some(item::unit::UnitModifier::Minus),
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -306,6 +321,8 @@ fn main() {
|
||||
item::unit::Unit {
|
||||
unit: item::unit::UnitType::PriestMind,
|
||||
modifier: Some(item::unit::UnitModifier::Minus),
|
||||
// wrapping: None,
|
||||
wrapping: Some(item::WrappingPaper::YellowBlue),
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -319,6 +336,7 @@ fn main() {
|
||||
item::unit::Unit {
|
||||
unit: item::unit::UnitType::PriestMind,
|
||||
modifier: Some(item::unit::UnitModifier::Minus),
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -332,6 +350,7 @@ fn main() {
|
||||
item::unit::Unit {
|
||||
unit: item::unit::UnitType::PriestMind,
|
||||
modifier: Some(item::unit::UnitModifier::Minus),
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
@ -341,8 +360,56 @@ fn main() {
|
||||
).await.unwrap();
|
||||
let item13 = entity_gateway.create_item(
|
||||
NewItemEntity {
|
||||
item: ItemDetail::Mag(
|
||||
item::mag::Mag::baby_mag(5)
|
||||
item: item::ItemDetail::Mag(item::mag::Mag::wrapped_baby_mag(5)),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: character.id,
|
||||
}
|
||||
}
|
||||
).await.unwrap();
|
||||
|
||||
// wrapping monomates doesn't do anything
|
||||
let item14 = entity_gateway.create_item(
|
||||
NewItemEntity {
|
||||
item: ItemDetail::Tool (
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
// wrapping: None,
|
||||
wrapping: Some(item::WrappingPaper::Yellow),
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: character.id,
|
||||
}
|
||||
}
|
||||
).await.unwrap();
|
||||
|
||||
/* wrapping techs is no bueno */
|
||||
// let item15 = entity_gateway.create_item(
|
||||
// NewItemEntity {
|
||||
// item: ItemDetail::TechniqueDisk (
|
||||
// item::tech::TechniqueDisk {
|
||||
// tech: item::tech::Technique::Foie,
|
||||
// level: 5,
|
||||
// // wrapping: None,
|
||||
// wrapping: Some(item::WrappingPaper::Blue),
|
||||
// }
|
||||
// ),
|
||||
// location: ItemLocation::Inventory {
|
||||
// character_id: character.id,
|
||||
// }
|
||||
// }
|
||||
// ).await.unwrap();
|
||||
|
||||
let item16 = entity_gateway.create_item(
|
||||
NewItemEntity {
|
||||
item: ItemDetail::ESWeapon (
|
||||
item::esweapon::ESWeapon {
|
||||
esweapon: item::esweapon::ESWeaponType::Hammer,
|
||||
special: Some(item::esweapon::ESWeaponSpecial::Hell),
|
||||
name: "BAN".to_owned(),
|
||||
grind: 69u8,
|
||||
wrapping: Some(item::WrappingPaper::LightBlueOrange),
|
||||
}
|
||||
),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: character.id,
|
||||
@ -359,7 +426,7 @@ fn main() {
|
||||
};
|
||||
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]);
|
||||
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, item14, /*item15,*/ item16]);
|
||||
entity_gateway.set_character_inventory(&character.id, &inventory).await.unwrap();
|
||||
entity_gateway.set_character_bank(&character.id, &item::BankEntity::default(), item::BankName("".into())).await.unwrap();
|
||||
}
|
||||
|
@ -85,6 +85,33 @@ pub trait EntityGateway: Send + Sync + Clone {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
async fn add_esweapon_modifier(&mut self, _item_id: &ItemEntityId, _modifier: esweapon::ESWeaponModifier) -> Result<(), GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
async fn add_armor_modifier(&mut self, _item_id: &ItemEntityId, _modifier: armor::ArmorModifier) -> Result<(), GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
async fn add_unit_modifier(&mut self, _item_id: &ItemEntityId, _modifier: unit::UnitModifier) -> Result<(), GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
async fn add_shield_modifier(&mut self, _item_id: &ItemEntityId, _modifier: shield::ShieldModifier) -> Result<(), GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
async fn add_mag_modifier(&mut self, _item_id: &ItemEntityId, _modifier: mag::MagModifier) -> Result<(), GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
async fn add_tech_modifier(&mut self, _item_id: &ItemEntityId, _modifier: tech::TechModifier) -> Result<(), GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
async fn add_tool_modifier(&mut self, _item_id: &ItemEntityId, _modifier: tool::ToolModifier) -> Result<(), GatewayError> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
/*
|
||||
async fn get_items_by_character(&self, _char_id: &CharacterEntityId) -> Result<Vec<ItemEntity>, GatewayError> {
|
||||
|
@ -17,8 +17,14 @@ pub struct InMemoryGateway {
|
||||
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>>>>,
|
||||
weapon_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<weapon::WeaponModifier>>>>,
|
||||
esweapon_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<esweapon::ESWeaponModifier>>>>,
|
||||
armor_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<armor::ArmorModifier>>>>,
|
||||
unit_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<unit::UnitModifier>>>>,
|
||||
shield_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<shield::ShieldModifier>>>>,
|
||||
mag_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<mag::MagModifier>>>>,
|
||||
tech_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<tech::TechModifier>>>>,
|
||||
tool_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<tool::ToolModifier>>>>,
|
||||
}
|
||||
|
||||
impl InMemoryGateway {
|
||||
@ -31,8 +37,14 @@ impl InMemoryGateway {
|
||||
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())),
|
||||
weapon_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
esweapon_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
armor_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
unit_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
shield_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
mag_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
tech_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
tool_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -52,8 +64,46 @@ impl InMemoryGateway {
|
||||
}
|
||||
ItemDetail::Weapon(weapon)
|
||||
},
|
||||
ItemDetail::ESWeapon(mut esweapon) => {
|
||||
if let Some(esweapon_modifiers) = self.esweapon_modifiers.lock().unwrap().get(&item.id) {
|
||||
for esweapon_modifier in esweapon_modifiers.iter() {
|
||||
esweapon.apply_modifier(&esweapon_modifier);
|
||||
}
|
||||
}
|
||||
ItemDetail::ESWeapon(esweapon)
|
||||
},
|
||||
ItemDetail::Armor(mut armor) => {
|
||||
if let Some(armor_modifiers) = self.armor_modifiers.lock().unwrap().get(&item.id) {
|
||||
for armor_modifier in armor_modifiers.iter() {
|
||||
armor.apply_modifier(&armor_modifier);
|
||||
}
|
||||
}
|
||||
ItemDetail::Armor(armor)
|
||||
},
|
||||
ItemDetail::Unit(mut unit) => {
|
||||
if let Some(unit_modifiers) = self.unit_modifiers.lock().unwrap().get(&item.id) {
|
||||
for unit_modifier in unit_modifiers.iter() {
|
||||
unit.apply_modifier(&unit_modifier);
|
||||
}
|
||||
}
|
||||
ItemDetail::Unit(unit)
|
||||
},
|
||||
ItemDetail::Shield(mut shield) => {
|
||||
if let Some(shield_modifiers) = self.shield_modifiers.lock().unwrap().get(&item.id) {
|
||||
for shield_modifier in shield_modifiers.iter() {
|
||||
shield.apply_modifier(&shield_modifier);
|
||||
}
|
||||
}
|
||||
ItemDetail::Shield(shield)
|
||||
},
|
||||
ItemDetail::Mag(mag) => {
|
||||
let mut mag = mag::Mag::baby_mag(mag.color as u16);
|
||||
let mut mag = {
|
||||
if mag.wrapping.is_some() {
|
||||
mag::Mag::wrapped_baby_mag(mag.color as u16)
|
||||
} else {
|
||||
mag::Mag::baby_mag(mag.color as u16)
|
||||
}
|
||||
};
|
||||
if let Some(mag_modifiers) = self.mag_modifiers.lock().unwrap().get(&item.id) {
|
||||
for mag_modifier in mag_modifiers.iter() {
|
||||
match mag_modifier {
|
||||
@ -81,12 +131,24 @@ impl InMemoryGateway {
|
||||
}
|
||||
}
|
||||
ItemDetail::Mag(mag)
|
||||
}
|
||||
_ => {
|
||||
item.item
|
||||
}
|
||||
},
|
||||
ItemDetail::TechniqueDisk(mut tech) => {
|
||||
if let Some(tech_modifiers) = self.tech_modifiers.lock().unwrap().get(&item.id) {
|
||||
for tech_modifier in tech_modifiers.iter() {
|
||||
tech.apply_modifier(&tech_modifier);
|
||||
}
|
||||
}
|
||||
ItemDetail::TechniqueDisk(tech)
|
||||
},
|
||||
ItemDetail::Tool(mut tool) => {
|
||||
if let Some(tool_modifiers) = self.tool_modifiers.lock().unwrap().get(&item.id) {
|
||||
for tool_modifier in tool_modifiers.iter() {
|
||||
tool.apply_modifier(&tool_modifier);
|
||||
}
|
||||
}
|
||||
ItemDetail::Tool(tool)
|
||||
},
|
||||
};
|
||||
|
||||
item
|
||||
})
|
||||
})
|
||||
@ -273,6 +335,62 @@ impl EntityGateway for InMemoryGateway {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_esweapon_modifier(&mut self, item_id: &ItemEntityId, modifier: esweapon::ESWeaponModifier) -> Result<(), GatewayError> {
|
||||
self.esweapon_modifiers.lock().unwrap()
|
||||
.entry(*item_id)
|
||||
.or_insert(Vec::new())
|
||||
.push(modifier);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_armor_modifier(&mut self, item_id: &ItemEntityId, modifier: armor::ArmorModifier) -> Result<(), GatewayError> {
|
||||
self.armor_modifiers.lock().unwrap()
|
||||
.entry(*item_id)
|
||||
.or_insert(Vec::new())
|
||||
.push(modifier);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_unit_modifier(&mut self, item_id: &ItemEntityId, modifier: unit::UnitModifier) -> Result<(), GatewayError> {
|
||||
self.unit_modifiers.lock().unwrap()
|
||||
.entry(*item_id)
|
||||
.or_insert(Vec::new())
|
||||
.push(modifier);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_shield_modifier(&mut self, item_id: &ItemEntityId, modifier: shield::ShieldModifier) -> Result<(), GatewayError> {
|
||||
self.shield_modifiers.lock().unwrap()
|
||||
.entry(*item_id)
|
||||
.or_insert(Vec::new())
|
||||
.push(modifier);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_mag_modifier(&mut self, item_id: &ItemEntityId, modifier: mag::MagModifier) -> Result<(), GatewayError> {
|
||||
self.mag_modifiers.lock().unwrap()
|
||||
.entry(*item_id)
|
||||
.or_insert(Vec::new())
|
||||
.push(modifier);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_tech_modifier(&mut self, item_id: &ItemEntityId, modifier: tech::TechModifier) -> Result<(), GatewayError> {
|
||||
self.tech_modifiers.lock().unwrap()
|
||||
.entry(*item_id)
|
||||
.or_insert(Vec::new())
|
||||
.push(modifier);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_tool_modifier(&mut self, item_id: &ItemEntityId, modifier: tool::ToolModifier) -> Result<(), GatewayError> {
|
||||
self.tool_modifiers.lock().unwrap()
|
||||
.entry(*item_id)
|
||||
.or_insert(Vec::new())
|
||||
.push(modifier);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_character_inventory(&mut self, char_id: &CharacterEntityId) -> Result<InventoryEntity, GatewayError> {
|
||||
println!("getting inv");
|
||||
let inventories = self.inventories.lock().unwrap();
|
||||
@ -299,7 +417,7 @@ impl EntityGateway for InMemoryGateway {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// TOOD: impl bank name
|
||||
// TODO: 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());
|
||||
|
@ -50,7 +50,7 @@ create table player_character (
|
||||
prop_y real not null,
|
||||
|
||||
techs bytea not null,
|
||||
|
||||
|
||||
config bytea not null,
|
||||
infoboard varchar(172) not null,
|
||||
guildcard varchar(172) not null,
|
||||
@ -93,14 +93,14 @@ create table weapon_modifier (
|
||||
created_at timestamptz default current_timestamp not null
|
||||
);
|
||||
|
||||
create table armor_modifier (
|
||||
armor integer references item (id) not null,
|
||||
create table esweapon_modifier (
|
||||
esweapon integer references item (id) not null,
|
||||
modifier jsonb not null,
|
||||
created_at timestamptz default current_timestamp not null
|
||||
);
|
||||
|
||||
create table shield_modifier (
|
||||
shield integer references item (id) not null,
|
||||
create table armor_modifier (
|
||||
armor integer references item (id) not null,
|
||||
modifier jsonb not null,
|
||||
created_at timestamptz default current_timestamp not null
|
||||
);
|
||||
@ -111,8 +111,8 @@ create table unit_modifier (
|
||||
created_at timestamptz default current_timestamp not null
|
||||
);
|
||||
|
||||
create table esweapon_modifier (
|
||||
esweapon integer references item (id) not null,
|
||||
create table shield_modifier (
|
||||
shield integer references item (id) not null,
|
||||
modifier jsonb not null,
|
||||
created_at timestamptz default current_timestamp not null
|
||||
);
|
||||
@ -122,3 +122,15 @@ create table mag_modifier (
|
||||
modifier jsonb not null,
|
||||
created_at timestamptz default current_timestamp not null
|
||||
);
|
||||
|
||||
create table tech_modifier (
|
||||
tech integer references item (id) not null,
|
||||
modifier jsonb not null,
|
||||
created_at timestamptz default current_timestamp not null
|
||||
);
|
||||
|
||||
create table tool_modifier (
|
||||
tool integer references item (id) not null,
|
||||
modifier jsonb not null,
|
||||
created_at timestamptz default current_timestamp not null
|
||||
);
|
||||
|
@ -178,7 +178,6 @@ impl From<SectionID> for PgSectionId {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PgCharacter {
|
||||
pub id: i32,
|
||||
@ -277,8 +276,6 @@ impl Into<CharacterEntity> for PgCharacter {
|
||||
pub struct PgGuildCard {
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgWeapon {
|
||||
weapon: weapon::WeaponType,
|
||||
@ -286,6 +283,7 @@ pub struct PgWeapon {
|
||||
grind: u8,
|
||||
attrs: HashMap<weapon::Attribute, i8>,
|
||||
tekked: bool,
|
||||
wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
impl From<weapon::Weapon> for PgWeapon {
|
||||
@ -296,6 +294,7 @@ impl From<weapon::Weapon> for PgWeapon {
|
||||
grind: other.grind,
|
||||
attrs: other.attrs.iter().flatten().map(|attr| (attr.attr, attr.value)).collect(),
|
||||
tekked: other.tekked,
|
||||
wrapping: other.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -316,6 +315,7 @@ impl Into<weapon::Weapon> for PgWeapon {
|
||||
grind: self.grind,
|
||||
attrs: attrs,
|
||||
tekked: self.tekked,
|
||||
wrapping: self.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -326,177 +326,13 @@ pub struct PgWeaponModifier {
|
||||
pub modifier: sqlx::types::Json<weapon::WeaponModifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgArmor {
|
||||
armor: armor::ArmorType,
|
||||
dfp: u8,
|
||||
evp: u8,
|
||||
slots: u8,
|
||||
}
|
||||
|
||||
impl From<armor::Armor> for PgArmor {
|
||||
fn from(other: armor::Armor) -> PgArmor {
|
||||
PgArmor {
|
||||
armor: other.armor,
|
||||
dfp: other.dfp,
|
||||
evp: other.evp,
|
||||
slots: other.slots,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<armor::Armor> for PgArmor {
|
||||
fn into(self) -> armor::Armor {
|
||||
armor::Armor {
|
||||
armor: self.armor,
|
||||
dfp: self.dfp,
|
||||
evp: self.evp,
|
||||
slots: self.slots,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgShield {
|
||||
shield: shield::ShieldType,
|
||||
dfp: u8,
|
||||
evp: u8,
|
||||
}
|
||||
|
||||
impl From<shield::Shield> for PgShield {
|
||||
fn from(other: shield::Shield) -> PgShield {
|
||||
PgShield {
|
||||
shield: other.shield,
|
||||
dfp: other.dfp,
|
||||
evp: other.evp,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<shield::Shield> for PgShield {
|
||||
fn into(self) -> shield::Shield {
|
||||
shield::Shield {
|
||||
shield: self.shield,
|
||||
dfp: self.dfp,
|
||||
evp: self.evp,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgUnit {
|
||||
unit: unit::UnitType,
|
||||
modifier: Option<unit::UnitModifier>,
|
||||
}
|
||||
|
||||
impl From<unit::Unit> for PgUnit {
|
||||
fn from(other: unit::Unit) -> PgUnit {
|
||||
PgUnit {
|
||||
unit: other.unit,
|
||||
modifier: other.modifier,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<unit::Unit> for PgUnit {
|
||||
fn into(self) -> unit::Unit {
|
||||
unit::Unit {
|
||||
unit: self.unit,
|
||||
modifier: self.modifier,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgTool {
|
||||
pub tool: tool::ToolType,
|
||||
}
|
||||
|
||||
impl From<tool::Tool> for PgTool {
|
||||
fn from(other: tool::Tool) -> PgTool {
|
||||
PgTool {
|
||||
tool: other.tool,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<tool::Tool> for PgTool {
|
||||
fn into(self) -> tool::Tool {
|
||||
tool::Tool {
|
||||
tool: self.tool,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgTechDisk {
|
||||
tech: tech::Technique,
|
||||
level: u32,
|
||||
}
|
||||
|
||||
impl From<tech::TechniqueDisk> for PgTechDisk {
|
||||
fn from(other: tech::TechniqueDisk) -> PgTechDisk {
|
||||
PgTechDisk {
|
||||
tech: other.tech,
|
||||
level: other.level,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<tech::TechniqueDisk> for PgTechDisk {
|
||||
fn into(self) -> tech::TechniqueDisk {
|
||||
tech::TechniqueDisk {
|
||||
tech: self.tech,
|
||||
level: self.level
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgMag {
|
||||
mag: mag::MagType,
|
||||
synchro: u8,
|
||||
color: u8,
|
||||
}
|
||||
|
||||
impl From<mag::Mag> for PgMag {
|
||||
fn from(other: mag::Mag) -> PgMag {
|
||||
PgMag {
|
||||
mag: other.mag,
|
||||
synchro: other.synchro,
|
||||
color: other.color,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<mag::Mag> for PgMag {
|
||||
fn into(self) -> mag::Mag {
|
||||
/*mag::Mag {
|
||||
mag: self.mag,
|
||||
synchro: self.synchro,
|
||||
color: self.color,
|
||||
def: 500,
|
||||
pow: 0,
|
||||
dex: 0,
|
||||
mnd: 0,
|
||||
iq: 0,
|
||||
photon_blast: [None; 3],
|
||||
class: CharacterClass::HUmar,
|
||||
id: SectionID::Viridia,
|
||||
}*/
|
||||
let mut mag = mag::Mag::baby_mag(self.color as u16);
|
||||
mag.mag = self.mag;
|
||||
mag.synchro = self.synchro;
|
||||
mag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgESWeapon {
|
||||
esweapon: esweapon::ESWeaponType,
|
||||
special: Option<esweapon::ESWeaponSpecial>,
|
||||
name: String,
|
||||
grind: u8,
|
||||
wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
impl From<esweapon::ESWeapon> for PgESWeapon {
|
||||
@ -506,6 +342,7 @@ impl From<esweapon::ESWeapon> for PgESWeapon {
|
||||
special: other.special,
|
||||
name: other.name,
|
||||
grind: other.grind,
|
||||
wrapping: other.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -517,33 +354,240 @@ impl Into<esweapon::ESWeapon> for PgESWeapon {
|
||||
special: self.special,
|
||||
name: self.name,
|
||||
grind: self.grind,
|
||||
wrapping: self.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PgESWeaponModifier {
|
||||
pub esweapon: i32,
|
||||
pub modifier: sqlx::types::Json<esweapon::ESWeaponModifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgArmor {
|
||||
armor: armor::ArmorType,
|
||||
dfp: u8,
|
||||
evp: u8,
|
||||
slots: u8,
|
||||
wrapping: Option<WrappingPaper>, // TODO: check if this clobbers slots
|
||||
}
|
||||
|
||||
impl From<armor::Armor> for PgArmor {
|
||||
fn from(other: armor::Armor) -> PgArmor {
|
||||
PgArmor {
|
||||
armor: other.armor,
|
||||
dfp: other.dfp,
|
||||
evp: other.evp,
|
||||
slots: other.slots,
|
||||
wrapping: other.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<armor::Armor> for PgArmor {
|
||||
fn into(self) -> armor::Armor {
|
||||
armor::Armor {
|
||||
armor: self.armor,
|
||||
dfp: self.dfp,
|
||||
evp: self.evp,
|
||||
slots: self.slots,
|
||||
wrapping: self.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PgArmorModifier {
|
||||
pub armor: i32,
|
||||
pub modifier: sqlx::types::Json<armor::ArmorModifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgUnit {
|
||||
unit: unit::UnitType,
|
||||
modifier: Option<unit::UnitModifier>,
|
||||
wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
impl From<unit::Unit> for PgUnit {
|
||||
fn from(other: unit::Unit) -> PgUnit {
|
||||
PgUnit {
|
||||
unit: other.unit,
|
||||
modifier: other.modifier,
|
||||
wrapping: other.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<unit::Unit> for PgUnit {
|
||||
fn into(self) -> unit::Unit {
|
||||
unit::Unit {
|
||||
unit: self.unit,
|
||||
modifier: self.modifier,
|
||||
wrapping: self.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PgUnitModifier {
|
||||
pub unit: i32,
|
||||
pub modifier: sqlx::types::Json<unit::UnitModifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgShield {
|
||||
shield: shield::ShieldType,
|
||||
dfp: u8,
|
||||
evp: u8,
|
||||
wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
impl From<shield::Shield> for PgShield {
|
||||
fn from(other: shield::Shield) -> PgShield {
|
||||
PgShield {
|
||||
shield: other.shield,
|
||||
dfp: other.dfp,
|
||||
evp: other.evp,
|
||||
wrapping: other.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<shield::Shield> for PgShield {
|
||||
fn into(self) -> shield::Shield {
|
||||
shield::Shield {
|
||||
shield: self.shield,
|
||||
dfp: self.dfp,
|
||||
evp: self.evp,
|
||||
wrapping: self.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PgShieldModifier {
|
||||
pub shield: i32,
|
||||
pub modifier: sqlx::types::Json<shield::ShieldModifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgMag {
|
||||
mag: mag::MagType,
|
||||
synchro: u8,
|
||||
color: u8,
|
||||
wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
impl From<mag::Mag> for PgMag {
|
||||
fn from(other: mag::Mag) -> PgMag {
|
||||
PgMag {
|
||||
mag: other.mag,
|
||||
synchro: other.synchro,
|
||||
color: other.color,
|
||||
wrapping: other.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<mag::Mag> for PgMag {
|
||||
fn into(self) -> mag::Mag {
|
||||
let mut mag = mag::Mag::baby_mag(self.color as u16);
|
||||
mag.mag = self.mag;
|
||||
mag.synchro = self.synchro;
|
||||
mag.wrapping = self.wrapping;
|
||||
mag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgTechDisk {
|
||||
tech: tech::Technique,
|
||||
level: u32,
|
||||
wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
impl From<tech::TechniqueDisk> for PgTechDisk {
|
||||
fn from(other: tech::TechniqueDisk) -> PgTechDisk {
|
||||
PgTechDisk {
|
||||
tech: other.tech,
|
||||
level: other.level,
|
||||
wrapping: other.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<tech::TechniqueDisk> for PgTechDisk {
|
||||
fn into(self) -> tech::TechniqueDisk {
|
||||
tech::TechniqueDisk {
|
||||
tech: self.tech,
|
||||
level: self.level,
|
||||
wrapping: self.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PgTechModifier {
|
||||
pub tool: i32,
|
||||
pub modifier: sqlx::types::Json<tech::TechModifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PgTool {
|
||||
pub tool: tool::ToolType,
|
||||
wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
impl From<tool::Tool> for PgTool {
|
||||
fn from(other: tool::Tool) -> PgTool {
|
||||
PgTool {
|
||||
tool: other.tool,
|
||||
wrapping: other.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<tool::Tool> for PgTool {
|
||||
fn into(self) -> tool::Tool {
|
||||
tool::Tool {
|
||||
tool: self.tool,
|
||||
wrapping: self.wrapping,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PgToolModifier {
|
||||
pub tool: i32,
|
||||
pub modifier: sqlx::types::Json<tool::ToolModifier>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum PgItemDetail {
|
||||
Weapon(PgWeapon),
|
||||
Armor(PgArmor),
|
||||
Shield(PgShield),
|
||||
Unit(PgUnit),
|
||||
Tool(PgTool),
|
||||
TechDisk(PgTechDisk),
|
||||
Mag(PgMag),
|
||||
ESWeapon(PgESWeapon),
|
||||
Armor(PgArmor),
|
||||
Unit(PgUnit),
|
||||
Shield(PgShield),
|
||||
Mag(PgMag),
|
||||
TechDisk(PgTechDisk),
|
||||
Tool(PgTool),
|
||||
}
|
||||
|
||||
impl From<ItemDetail> for PgItemDetail {
|
||||
fn from(other: ItemDetail) -> PgItemDetail {
|
||||
match other {
|
||||
ItemDetail::Weapon(weapon) => PgItemDetail::Weapon(weapon.into()),
|
||||
ItemDetail::Armor(armor) => PgItemDetail::Armor(armor.into()),
|
||||
ItemDetail::Shield(shield) => PgItemDetail::Shield(shield.into()),
|
||||
ItemDetail::Unit(unit) => PgItemDetail::Unit(unit.into()),
|
||||
ItemDetail::Tool(tool) => PgItemDetail::Tool(tool.into()),
|
||||
ItemDetail::TechniqueDisk(tech_disk) => PgItemDetail::TechDisk(tech_disk.into()),
|
||||
ItemDetail::Mag(mag) => PgItemDetail::Mag(mag.into()),
|
||||
ItemDetail::ESWeapon(esweapon) => PgItemDetail::ESWeapon(esweapon.into()),
|
||||
ItemDetail::Armor(armor) => PgItemDetail::Armor(armor.into()),
|
||||
ItemDetail::Unit(unit) => PgItemDetail::Unit(unit.into()),
|
||||
ItemDetail::Shield(shield) => PgItemDetail::Shield(shield.into()),
|
||||
ItemDetail::Mag(mag) => PgItemDetail::Mag(mag.into()),
|
||||
ItemDetail::TechniqueDisk(tech_disk) => PgItemDetail::TechDisk(tech_disk.into()),
|
||||
ItemDetail::Tool(tool) => PgItemDetail::Tool(tool.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -552,13 +596,13 @@ impl Into<ItemDetail> for PgItemDetail {
|
||||
fn into(self) -> ItemDetail {
|
||||
match self {
|
||||
PgItemDetail::Weapon(weapon) => ItemDetail::Weapon(weapon.into()),
|
||||
PgItemDetail::Armor(armor) => ItemDetail::Armor(armor.into()),
|
||||
PgItemDetail::Shield(shield) => ItemDetail::Shield(shield.into()),
|
||||
PgItemDetail::Unit(unit) => ItemDetail::Unit(unit.into()),
|
||||
PgItemDetail::Tool(tool) => ItemDetail::Tool(tool.into()),
|
||||
PgItemDetail::TechDisk(tech_disk) => ItemDetail::TechniqueDisk(tech_disk.into()),
|
||||
PgItemDetail::Mag(mag) => ItemDetail::Mag(mag.into()),
|
||||
PgItemDetail::ESWeapon(esweapon) => ItemDetail::ESWeapon(esweapon.into()),
|
||||
PgItemDetail::Armor(armor) => ItemDetail::Armor(armor.into()),
|
||||
PgItemDetail::Unit(unit) => ItemDetail::Unit(unit.into()),
|
||||
PgItemDetail::Shield(shield) => ItemDetail::Shield(shield.into()),
|
||||
PgItemDetail::Mag(mag) => ItemDetail::Mag(mag.into()),
|
||||
PgItemDetail::TechDisk(tech_disk) => ItemDetail::TechniqueDisk(tech_disk.into()),
|
||||
PgItemDetail::Tool(tool) => ItemDetail::Tool(tool.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -569,7 +613,6 @@ pub struct PgItem {
|
||||
pub item: sqlx::types::Json<PgItemDetail>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum PgItemLocationDetail {
|
||||
Inventory {
|
||||
@ -627,7 +670,6 @@ impl Into<ItemLocation> for PgItemLocationDetail {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PgItemLocation {
|
||||
//pub id: i32,
|
||||
@ -635,13 +677,14 @@ pub struct PgItemLocation {
|
||||
created_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum PgMagModifierDetail {
|
||||
FeedMag(i32),
|
||||
BankMag,
|
||||
MagCell(i32),
|
||||
OwnerChange(CharacterClass, SectionID)
|
||||
OwnerChange(CharacterClass, SectionID),
|
||||
WrapPresent,
|
||||
UnwrapPresent,
|
||||
}
|
||||
|
||||
impl From<mag::MagModifier> for PgMagModifierDetail {
|
||||
@ -651,6 +694,8 @@ impl From<mag::MagModifier> for PgMagModifierDetail {
|
||||
mag::MagModifier::BankMag => PgMagModifierDetail::BankMag,
|
||||
mag::MagModifier::MagCell(cell) => PgMagModifierDetail::MagCell(cell.0 as i32),
|
||||
mag::MagModifier::OwnerChange(class, section_id) => PgMagModifierDetail::OwnerChange(class, section_id),
|
||||
mag::MagModifier::WrapPresent => PgMagModifierDetail::WrapPresent,
|
||||
mag::MagModifier::UnwrapPresent => PgMagModifierDetail::UnwrapPresent,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -662,6 +707,8 @@ impl Into<mag::MagModifier> for PgMagModifierDetail {
|
||||
PgMagModifierDetail::BankMag => mag::MagModifier::BankMag,
|
||||
PgMagModifierDetail::MagCell(cell) => mag::MagModifier::MagCell(ItemEntityId(cell as u32)),
|
||||
PgMagModifierDetail::OwnerChange(class, section_id) => mag::MagModifier::OwnerChange(class, section_id),
|
||||
PgMagModifierDetail::WrapPresent => mag::MagModifier::WrapPresent,
|
||||
PgMagModifierDetail::UnwrapPresent => mag::MagModifier::UnwrapPresent,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -673,7 +720,6 @@ pub struct PgMagModifier {
|
||||
created_at: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PgItemEntity {
|
||||
pub id: i32,
|
||||
@ -697,7 +743,6 @@ impl Into<ItemEntity> for PgItemWithLocation {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PgMagModifierWithParameters {
|
||||
pub mag: i32,
|
||||
@ -706,7 +751,6 @@ pub struct PgMagModifierWithParameters {
|
||||
pub cell: Option<sqlx::types::Json<PgTool>>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum PgInventoryItemEntity {
|
||||
@ -732,11 +776,11 @@ pub struct PgEquipped {
|
||||
pchar: i32,
|
||||
weapon: Option<i32>,
|
||||
armor: Option<i32>,
|
||||
shield: Option<i32>,
|
||||
unit0: Option<i32>,
|
||||
unit1: Option<i32>,
|
||||
unit2: Option<i32>,
|
||||
unit3: Option<i32>,
|
||||
shield: Option<i32>,
|
||||
mag: Option<i32>,
|
||||
}
|
||||
|
||||
@ -745,12 +789,12 @@ impl Into<EquippedEntity> for PgEquipped {
|
||||
EquippedEntity {
|
||||
weapon: self.weapon.map(|i| ItemEntityId(i as u32)),
|
||||
armor: self.armor.map(|i| ItemEntityId(i as u32)),
|
||||
shield: self.shield.map(|i| ItemEntityId(i as u32)),
|
||||
unit: [self.unit0.map(|i| ItemEntityId(i as u32)),
|
||||
self.unit1.map(|i| ItemEntityId(i as u32)),
|
||||
self.unit2.map(|i| ItemEntityId(i as u32)),
|
||||
self.unit3.map(|i| ItemEntityId(i as u32)),
|
||||
self.unit1.map(|i| ItemEntityId(i as u32)),
|
||||
self.unit2.map(|i| ItemEntityId(i as u32)),
|
||||
self.unit3.map(|i| ItemEntityId(i as u32)),
|
||||
],
|
||||
shield: self.shield.map(|i| ItemEntityId(i as u32)),
|
||||
mag: self.mag.map(|i| ItemEntityId(i as u32)),
|
||||
}
|
||||
}
|
||||
@ -762,13 +806,12 @@ impl From<(CharacterEntityId, EquippedEntity)> for PgEquipped {
|
||||
pchar: char_equips.0.0 as i32,
|
||||
weapon: char_equips.1.weapon.map(|i| i.0 as i32),
|
||||
armor: char_equips.1.armor.map(|i| i.0 as i32),
|
||||
shield: char_equips.1.shield.map(|i| i.0 as i32),
|
||||
unit0: char_equips.1.unit[0].map(|i| i.0 as i32),
|
||||
unit1: char_equips.1.unit[1].map(|i| i.0 as i32),
|
||||
unit2: char_equips.1.unit[2].map(|i| i.0 as i32),
|
||||
unit3: char_equips.1.unit[3].map(|i| i.0 as i32),
|
||||
shield: char_equips.1.shield.map(|i| i.0 as i32),
|
||||
mag: char_equips.1.mag.map(|i| i.0 as i32),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,74 @@ impl PostgresGateway {
|
||||
|
||||
ItemDetail::Weapon(weapon)
|
||||
},
|
||||
ItemDetail::ESWeapon(mut esweapon) => {
|
||||
let q = r#"select esweapon, modifier
|
||||
from esweapon_modifier
|
||||
where esweapon = $1
|
||||
order by created_at"#;
|
||||
let esweapon_modifiers = sqlx::query_as::<_, PgESWeaponModifier>(q)
|
||||
.bind(id.0 as i32)
|
||||
.fetch(&self.pool);
|
||||
|
||||
esweapon_modifiers.for_each(|modifier| {
|
||||
if let Ok(modifier) = modifier {
|
||||
esweapon.apply_modifier(&modifier.modifier);
|
||||
}
|
||||
}).await;
|
||||
|
||||
ItemDetail::ESWeapon(esweapon)
|
||||
},
|
||||
ItemDetail::Armor(mut armor) => {
|
||||
let q = r#"select armor, modifier
|
||||
from armor_modifier
|
||||
where armor = $1
|
||||
order by created_at"#;
|
||||
let armor_modifiers = sqlx::query_as::<_, PgArmorModifier>(q)
|
||||
.bind(id.0 as i32)
|
||||
.fetch(&self.pool);
|
||||
|
||||
armor_modifiers.for_each(|modifier| {
|
||||
if let Ok(modifier) = modifier {
|
||||
armor.apply_modifier(&modifier.modifier);
|
||||
}
|
||||
}).await;
|
||||
|
||||
ItemDetail::Armor(armor)
|
||||
},
|
||||
ItemDetail::Unit(mut unit) => {
|
||||
let q = r#"select unit, modifier
|
||||
from unit_modifier
|
||||
where unit = $1
|
||||
order by created_at"#;
|
||||
let unit_modifiers = sqlx::query_as::<_, PgUnitModifier>(q)
|
||||
.bind(id.0 as i32)
|
||||
.fetch(&self.pool);
|
||||
|
||||
unit_modifiers.for_each(|modifier| {
|
||||
if let Ok(modifier) = modifier {
|
||||
unit.apply_modifier(&modifier.modifier);
|
||||
}
|
||||
}).await;
|
||||
|
||||
ItemDetail::Unit(unit)
|
||||
},
|
||||
ItemDetail::Shield(mut shield) => {
|
||||
let q = r#"select shield, modifier
|
||||
from shield_modifier
|
||||
where shield = $1
|
||||
order by created_at"#;
|
||||
let shield_modifiers = sqlx::query_as::<_, PgShieldModifier>(q)
|
||||
.bind(id.0 as i32)
|
||||
.fetch(&self.pool);
|
||||
|
||||
shield_modifiers.for_each(|modifier| {
|
||||
if let Ok(modifier) = modifier {
|
||||
shield.apply_modifier(&modifier.modifier);
|
||||
}
|
||||
}).await;
|
||||
|
||||
ItemDetail::Shield(shield)
|
||||
},
|
||||
ItemDetail::Mag(mut mag) => {
|
||||
let q = r#"select mag, modifier, item.item -> 'Tool' as feed, item2.item -> 'Tool' as cell
|
||||
from mag_modifier
|
||||
@ -91,6 +159,8 @@ impl PostgresGateway {
|
||||
mag::MagModifier::OwnerChange(class, section_id) => {
|
||||
mag.change_owner(class, section_id)
|
||||
},
|
||||
mag::MagModifier::WrapPresent => {mag.apply_modifier(&modifier)},
|
||||
mag::MagModifier::UnwrapPresent => {mag.apply_modifier(&modifier)},
|
||||
}
|
||||
}).await;
|
||||
|
||||
@ -416,6 +486,62 @@ impl EntityGateway for PostgresGateway {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_esweapon_modifier(&mut self, item_id: &ItemEntityId, modifier: esweapon::ESWeaponModifier) -> Result<(), GatewayError> {
|
||||
sqlx::query("insert into esweapon_modifier (esweapon, modifier) values ($1, $2);")
|
||||
.bind(item_id.0)
|
||||
.bind(sqlx::types::Json(modifier))
|
||||
.execute(&self.pool).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_armor_modifier(&mut self, item_id: &ItemEntityId, modifier: armor::ArmorModifier) -> Result<(), GatewayError> {
|
||||
sqlx::query("insert into armor_modifier (armor, modifier) values ($1, $2);")
|
||||
.bind(item_id.0)
|
||||
.bind(sqlx::types::Json(modifier))
|
||||
.execute(&self.pool).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_unit_modifier(&mut self, item_id: &ItemEntityId, modifier: unit::UnitModifier) -> Result<(), GatewayError> {
|
||||
sqlx::query("insert into unit_modifier (unit, modifier) values ($1, $2);")
|
||||
.bind(item_id.0)
|
||||
.bind(sqlx::types::Json(modifier))
|
||||
.execute(&self.pool).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_shield_modifier(&mut self, item_id: &ItemEntityId, modifier: shield::ShieldModifier) -> Result<(), GatewayError> {
|
||||
sqlx::query("insert into shield_modifier (shield, modifier) values ($1, $2);")
|
||||
.bind(item_id.0)
|
||||
.bind(sqlx::types::Json(modifier))
|
||||
.execute(&self.pool).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_mag_modifier(&mut self, item_id: &ItemEntityId, modifier: mag::MagModifier) -> Result<(), GatewayError> {
|
||||
sqlx::query("insert into mag_modifier (mag, modifier) values ($1, $2);")
|
||||
.bind(item_id.0)
|
||||
.bind(sqlx::types::Json(modifier))
|
||||
.execute(&self.pool).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_tech_modifier(&mut self, item_id: &ItemEntityId, modifier: tech::TechModifier) -> Result<(), GatewayError> {
|
||||
sqlx::query("insert into tech_modifier (tech, modifier) values ($1, $2);")
|
||||
.bind(item_id.0)
|
||||
.bind(sqlx::types::Json(modifier))
|
||||
.execute(&self.pool).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn add_tool_modifier(&mut self, item_id: &ItemEntityId, modifier: tool::ToolModifier) -> Result<(), GatewayError> {
|
||||
sqlx::query("insert into tool_modifier (tool, modifier) values ($1, $2);")
|
||||
.bind(item_id.0)
|
||||
.bind(sqlx::types::Json(modifier))
|
||||
.execute(&self.pool).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/*
|
||||
async fn get_items_by_character(&self, char_id: &CharacterEntityId) -> Result<Vec<ItemEntity>, GatewayError> {
|
||||
let q = r#"select * from (
|
||||
@ -540,7 +666,6 @@ impl EntityGateway for PostgresGateway {
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
sqlx::query("insert into inventory (pchar, items) values ($1, $2) on conflict (pchar) do update set items = $2")
|
||||
.bind(char_id.0)
|
||||
.bind(sqlx::types::Json(inventory))
|
||||
@ -582,16 +707,16 @@ impl EntityGateway for PostgresGateway {
|
||||
}
|
||||
|
||||
async fn set_character_equips(&mut self, char_id: &CharacterEntityId, equips: &EquippedEntity) -> Result<(), GatewayError> {
|
||||
sqlx::query(r#"insert into equipped (pchar, weapon, armor, shield, unit0, unit1, unit2, unit3, mag) values ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
sqlx::query(r#"insert into equipped (pchar, weapon, armor, unit0, unit1, unit2, unit3, shield, mag) values ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
||||
on conflict (pchar) do update set weapon=$2, armor=$3, shield=$4, unit0=$5, unit1=$6, unit2=$7, unit3=$8, mag=$9"#)
|
||||
.bind(char_id.0)
|
||||
.bind(equips.weapon.map(|i| i.0 as i32))
|
||||
.bind(equips.armor.map(|i| i.0 as i32))
|
||||
.bind(equips.shield.map(|i| i.0 as i32))
|
||||
.bind(equips.unit[0].map(|i| i.0 as i32))
|
||||
.bind(equips.unit[1].map(|i| i.0 as i32))
|
||||
.bind(equips.unit[2].map(|i| i.0 as i32))
|
||||
.bind(equips.unit[3].map(|i| i.0 as i32))
|
||||
.bind(equips.shield.map(|i| i.0 as i32))
|
||||
.bind(equips.mag.map(|i| i.0 as i32))
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::entity::item::ItemEntityId;
|
||||
use crate::entity::item::{ItemEntityId, WrappingPaper};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ItemParseError {
|
||||
@ -288,27 +288,31 @@ impl ArmorType {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ArmorModifier {
|
||||
AddSlot {
|
||||
addslot: ItemEntityId,
|
||||
}
|
||||
},
|
||||
WrapPresent,
|
||||
UnwrapPresent,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Armor {
|
||||
pub armor: ArmorType,
|
||||
pub dfp: u8,
|
||||
pub evp: u8,
|
||||
pub slots: u8,
|
||||
pub wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
impl Armor {
|
||||
pub fn as_bytes(&self) -> [u8; 16] {
|
||||
let mut result = [0; 16];
|
||||
result[0..3].copy_from_slice(&self.armor.value());
|
||||
if self.wrapping.is_some() {
|
||||
result[4] += 0x40;
|
||||
}
|
||||
result[5] = self.slots;
|
||||
result[6] = self.dfp;
|
||||
result[8] = self.evp;
|
||||
@ -317,16 +321,32 @@ impl Armor {
|
||||
|
||||
pub fn from_bytes(data: [u8; 16]) -> Result<Armor, ItemParseError> {
|
||||
let a = ArmorType::parse_type([data[0], data[1], data[2]]);
|
||||
let w = {
|
||||
if data[4] & 0x40 == 0x40 {
|
||||
WrappingPaper::from(0) // always use default wrapping paper to preserve slot info
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
if a.is_ok() {
|
||||
Ok(Armor {
|
||||
armor: a.unwrap(),
|
||||
dfp: data[6],
|
||||
evp: data[8],
|
||||
slots: data[5],
|
||||
wrapping: w,
|
||||
})
|
||||
}
|
||||
else {
|
||||
Err(ItemParseError::InvalidArmorBytes) // TODO: error handling if wrong bytes are given
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_modifier(&mut self, modifier: &ArmorModifier) {
|
||||
match modifier {
|
||||
ArmorModifier::WrapPresent => {self.wrapping = Some(WrappingPaper::WhitePink)},
|
||||
ArmorModifier::UnwrapPresent => {self.wrapping = None},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::entity::item::{WrappingPaper};
|
||||
// TODO: actually use this
|
||||
#[derive(Debug)]
|
||||
pub enum ItemParseError {
|
||||
@ -169,12 +170,21 @@ impl ESWeaponSpecial {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum ESWeaponModifier {
|
||||
WrapPresent {
|
||||
paper: WrappingPaper,
|
||||
},
|
||||
UnwrapPresent,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ESWeapon {
|
||||
pub esweapon: ESWeaponType,
|
||||
pub special: Option<ESWeaponSpecial>,
|
||||
pub name: String,
|
||||
pub grind: u8,
|
||||
pub wrapping: Option<WrappingPaper>
|
||||
}
|
||||
|
||||
impl ESWeapon {
|
||||
@ -184,6 +194,7 @@ impl ESWeapon {
|
||||
special: None,
|
||||
name: "".to_owned(),
|
||||
grind: 0,
|
||||
wrapping: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,7 +252,10 @@ impl ESWeapon {
|
||||
result[1] = 0x70 + self.esweapon.to_value();
|
||||
result[2] = self.special.map(|s| s.to_value()).unwrap_or(0);
|
||||
result[3] = self.grind;
|
||||
//result[4] = tekked/untekked flag
|
||||
if self.wrapping.is_some() {
|
||||
result[4] += 0x40;
|
||||
result[5] = self.wrapping.unwrap().value();
|
||||
}
|
||||
result[6..12].clone_from_slice(&self.bytes_from_name());
|
||||
result
|
||||
}
|
||||
@ -252,12 +266,28 @@ impl ESWeapon {
|
||||
let special = ESWeaponSpecial::from_value(bytes[2]);
|
||||
let grind = bytes[3];
|
||||
let name = ESWeapon::name_from_bytes(&bytes[6..12]);
|
||||
let wrapping = {
|
||||
if bytes[4] & 0x40 == 0x40 {
|
||||
WrappingPaper::from(bytes[5])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
ESWeapon {
|
||||
esweapon: esweapon,
|
||||
special: special.ok(),
|
||||
grind: grind,
|
||||
name: name,
|
||||
wrapping: wrapping,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_modifier(&mut self, modifier: &ESWeaponModifier) {
|
||||
match modifier {
|
||||
ESWeaponModifier::WrapPresent{paper} => {self.wrapping = Some(*paper)},
|
||||
ESWeaponModifier::UnwrapPresent => {self.wrapping = None},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -276,6 +306,7 @@ mod test {
|
||||
special: Some(ESWeaponSpecial::Berserk),
|
||||
grind: 137u8,
|
||||
name: "JAKESERV".to_owned(),
|
||||
wrapping: None,
|
||||
});
|
||||
}
|
||||
|
||||
@ -287,6 +318,7 @@ mod test {
|
||||
special: Some(ESWeaponSpecial::Chaos),
|
||||
grind: 72u8,
|
||||
name: "PSYCHO".to_owned(),
|
||||
wrapping: None,
|
||||
};
|
||||
let bytes = testweapon.as_bytes();
|
||||
assert_eq!(bytes, [0x00, 0x7B, 0x09, 0x48, 0x00, 0x00, 0x82, 0x13, 0xE4, 0x68, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||
@ -300,10 +332,9 @@ mod test {
|
||||
special: Some(ESWeaponSpecial::Spirit),
|
||||
grind: 105u8,
|
||||
name: "YUGIOH".to_owned(),
|
||||
wrapping: None,
|
||||
};
|
||||
let bytes = testweapon.as_bytes();
|
||||
assert_eq!(bytes, [0x00, 0xA7, 0x0B, 0x69, 0x00, 0x00, 0x83, 0x35, 0x9D, 0x2F, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::entity::item::tool::ToolType;
|
||||
use crate::entity::character::{CharacterClass, SectionID};
|
||||
use crate::entity::item::ItemEntityId;
|
||||
use crate::entity::item::{ItemEntityId, WrappingPaper};
|
||||
use std::io::Read;
|
||||
|
||||
use std::cmp::Ordering::{Less, Greater, Equal};
|
||||
@ -56,8 +56,6 @@ lazy_static::lazy_static! {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ItemParseError {
|
||||
InvalidMagType,
|
||||
@ -509,14 +507,16 @@ impl MagAttributeOrdering {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||
pub enum MagModifier {
|
||||
FeedMag{
|
||||
food: ItemEntityId,
|
||||
},
|
||||
BankMag, // when putting a mag in the bank it truncates the values which has applications when raising degenerate mags
|
||||
MagCell(ItemEntityId),
|
||||
OwnerChange(CharacterClass, SectionID)
|
||||
OwnerChange(CharacterClass, SectionID),
|
||||
WrapPresent,
|
||||
UnwrapPresent,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, enum_utils::FromStr)]
|
||||
@ -529,7 +529,7 @@ pub enum PhotonBlast {
|
||||
MyllaYoulla,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Mag {
|
||||
pub mag: MagType,
|
||||
def: u16,
|
||||
@ -543,9 +543,9 @@ pub struct Mag {
|
||||
//modifiers: Vec<MagModifier>,
|
||||
pub class: CharacterClass,
|
||||
pub id: SectionID,
|
||||
pub wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
|
||||
impl Mag {
|
||||
pub fn baby_mag(skin: u16) -> Mag {
|
||||
Mag {
|
||||
@ -561,6 +561,25 @@ impl Mag {
|
||||
//modifiers: Vec::new(),
|
||||
class: CharacterClass::HUmar,
|
||||
id: SectionID::Viridia,
|
||||
wrapping: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wrapped_baby_mag(skin: u16) -> Mag {
|
||||
Mag {
|
||||
mag: MagType::Mag,
|
||||
def: 500,
|
||||
pow: 0,
|
||||
dex: 0,
|
||||
mnd: 0,
|
||||
synchro: 20,
|
||||
iq: 0,
|
||||
photon_blast: [None; 3],
|
||||
color: (skin % 18) as u8,
|
||||
//modifiers: Vec::new(),
|
||||
class: CharacterClass::HUmar,
|
||||
id: SectionID::Viridia,
|
||||
wrapping: WrappingPaper::from((skin % 10) as u8),
|
||||
}
|
||||
}
|
||||
|
||||
@ -575,6 +594,9 @@ impl Mag {
|
||||
result[12] = self.synchro;
|
||||
result[13] = self.iq;
|
||||
result[14] = self.photon_blast_count();
|
||||
if self.wrapping.is_some() {
|
||||
result[14] += 0x40;
|
||||
}
|
||||
result[15] = self.color;
|
||||
result
|
||||
}
|
||||
@ -648,6 +670,13 @@ impl Mag {
|
||||
|
||||
let sync = data[12] % 121; // TODO: handle invalid values.
|
||||
let iq = data[13] % 201; // TODO: handle invalid values.
|
||||
let wp = {
|
||||
if data[14] & 0x40 == 0x40 {
|
||||
WrappingPaper::from(data[15] % 10) // % 10 to have valid wrapping paper colour.
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Mag{
|
||||
mag: m.unwrap(),
|
||||
@ -660,8 +689,9 @@ impl Mag {
|
||||
photon_blast: [None, None, None], // TODO: actually get PBs from bytes
|
||||
color: data[15] % 18,
|
||||
//modifiers: Vec::new(),
|
||||
class: CharacterClass::HUmar,
|
||||
id: SectionID::Viridia,
|
||||
class: CharacterClass::HUmar, // TODO: determine character class
|
||||
id: SectionID::Viridia, // TODO: determine section id
|
||||
wrapping: wp,
|
||||
})
|
||||
}
|
||||
else {
|
||||
@ -1097,6 +1127,14 @@ impl Mag {
|
||||
MagCell::LibertaKit => MagType::Agastya,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_modifier(&mut self, modifier: &MagModifier) {
|
||||
match modifier {
|
||||
MagModifier::WrapPresent => {self.wrapping = WrappingPaper::from(self.color % 10)}, // prevents mag color from crashing wrapping papers. client always shows mags in default paper colour ?
|
||||
MagModifier::UnwrapPresent => {self.wrapping = None},
|
||||
_ => {}, // TODO: other modifiers are already handled elsewhere. do they need to be moved here?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1167,6 +1205,7 @@ mod test {
|
||||
color: 0,
|
||||
class: CharacterClass::FOmarl,
|
||||
id: SectionID::Whitill,
|
||||
wrapping: None,
|
||||
});
|
||||
}
|
||||
|
||||
@ -1174,4 +1213,3 @@ mod test {
|
||||
fn test_mag_does_not_level_down() {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,6 @@ impl Meseta {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum ItemType {
|
||||
Weapon(weapon::WeaponType),
|
||||
@ -159,6 +158,34 @@ impl ItemDetail {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_wrapped(&mut self) -> bool {
|
||||
match self {
|
||||
ItemDetail::Weapon(w) => w.wrapping.is_some(),
|
||||
ItemDetail::Armor(a) => a.wrapping.is_some(),
|
||||
ItemDetail::Shield(s) => s.wrapping.is_some(),
|
||||
ItemDetail::Unit(u) => u.wrapping.is_some(),
|
||||
ItemDetail::Tool(t) => t.wrapping.is_some(),
|
||||
ItemDetail::TechniqueDisk(d) => d.wrapping.is_some(),
|
||||
ItemDetail::Mag(m) => m.wrapping.is_some(),
|
||||
ItemDetail::ESWeapon(e) => e.wrapping.is_some(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_present(&mut self) {
|
||||
match self {
|
||||
ItemDetail::Weapon(ref mut w) => w.wrapping = None,
|
||||
ItemDetail::Armor(ref mut a) => a.wrapping = None,
|
||||
ItemDetail::Shield(ref mut s) => s.wrapping = None,
|
||||
ItemDetail::Unit(ref mut u) => u.wrapping = None,
|
||||
ItemDetail::Tool(ref mut t) => t.wrapping = None,
|
||||
ItemDetail::TechniqueDisk(ref mut d) => d.wrapping = None,
|
||||
ItemDetail::Mag(ref mut m) => m.wrapping = None,
|
||||
ItemDetail::ESWeapon(ref mut e) => e.wrapping = None,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -200,7 +227,7 @@ impl InventoryItemEntity {
|
||||
_ => 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)),
|
||||
@ -208,7 +235,6 @@ impl InventoryItemEntity {
|
||||
}
|
||||
}
|
||||
|
||||
//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)),
|
||||
@ -252,7 +278,6 @@ impl InventoryEntity {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum BankItemEntity {
|
||||
Individual(ItemEntity),
|
||||
@ -287,10 +312,8 @@ impl BankItemEntity {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct BankEntity {
|
||||
//pub items: [Option<CharacterBankItem>; 30],
|
||||
pub items: Vec<BankItemEntity>,
|
||||
}
|
||||
|
||||
@ -301,3 +324,41 @@ impl BankEntity {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, Serialize, Deserialize)]
|
||||
pub enum WrappingPaper {
|
||||
WhitePink, // 0
|
||||
YellowBlue, // 1
|
||||
BlackYellow, // 2
|
||||
LightBlueOrange, // 3
|
||||
PinkYellowGreen, // 4
|
||||
RedGreen, // 5
|
||||
Magenta, // 6
|
||||
Blue, // 7
|
||||
Yellow, // 8
|
||||
Vermillion, // 9
|
||||
Green, // 10
|
||||
}
|
||||
|
||||
impl WrappingPaper {
|
||||
pub fn value(&self) -> u8 {
|
||||
*self as u8
|
||||
}
|
||||
|
||||
pub fn from(data: u8) -> Option<WrappingPaper> {
|
||||
match data {
|
||||
0 => Some(WrappingPaper::WhitePink),
|
||||
1 => Some(WrappingPaper::YellowBlue),
|
||||
2 => Some(WrappingPaper::BlackYellow),
|
||||
3 => Some(WrappingPaper::LightBlueOrange),
|
||||
4 => Some(WrappingPaper::PinkYellowGreen),
|
||||
5 => Some(WrappingPaper::RedGreen),
|
||||
6 => Some(WrappingPaper::Magenta),
|
||||
7 => Some(WrappingPaper::Blue),
|
||||
8 => Some(WrappingPaper::Yellow),
|
||||
9 => Some(WrappingPaper::Vermillion),
|
||||
10 => Some(WrappingPaper::Green),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::entity::item::{WrappingPaper};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ItemParseError {
|
||||
@ -518,18 +519,30 @@ impl ShieldType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ShieldModifier {
|
||||
WrapPresent {
|
||||
paper: WrappingPaper,
|
||||
},
|
||||
UnwrapPresent,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Shield {
|
||||
pub shield: ShieldType,
|
||||
pub dfp: u8,
|
||||
pub evp: u8,
|
||||
pub wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
impl Shield {
|
||||
pub fn as_bytes(&self) -> [u8; 16] {
|
||||
let mut result = [0; 16];
|
||||
result[0..3].copy_from_slice(&self.shield.value());
|
||||
if self.wrapping.is_some() {
|
||||
result[4] += 0x40;
|
||||
result[5] = self.wrapping.unwrap().value();
|
||||
};
|
||||
result[6] = self.dfp;
|
||||
result[8] = self.evp;
|
||||
result
|
||||
@ -537,15 +550,30 @@ impl Shield {
|
||||
|
||||
pub fn from_bytes(data: [u8; 16]) -> Result<Shield, ItemParseError> {
|
||||
let s = ShieldType::parse_type([data[0], data[1], data[2]]);
|
||||
let wrapping = {
|
||||
if data[4] & 0x40 == 0x40 {
|
||||
WrappingPaper::from(data[5])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
if s.is_ok() {
|
||||
Ok(Shield{
|
||||
shield: s.unwrap(),
|
||||
dfp: data[6],
|
||||
evp: data[8],
|
||||
wrapping: wrapping,
|
||||
})
|
||||
}
|
||||
else {
|
||||
Err(ItemParseError::InvalidShieldBytes) // TODO: error handling if wrong bytes are given
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_modifier(&mut self, modifier: &ShieldModifier) {
|
||||
match modifier {
|
||||
ShieldModifier::WrapPresent{paper} => {self.wrapping = Some(*paper)}, // TODO: client always shows shields in default paper colour ?
|
||||
ShieldModifier::UnwrapPresent => {self.wrapping = None},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::entity::item::{WrappingPaper};
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, enum_utils::FromStr, derive_more::Display, strum_macros::EnumIter)]
|
||||
@ -75,10 +76,19 @@ impl Technique {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub enum TechModifier {
|
||||
WrapPresent {
|
||||
paper: WrappingPaper,
|
||||
},
|
||||
UnwrapPresent,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct TechniqueDisk {
|
||||
pub tech: Technique,
|
||||
pub level: u32,
|
||||
pub wrapping: Option<WrappingPaper>, // TODO: validate if this clobbers tech value?
|
||||
}
|
||||
|
||||
impl TechniqueDisk {
|
||||
@ -88,6 +98,17 @@ impl TechniqueDisk {
|
||||
result[1] = 2;
|
||||
result[2] = self.level as u8 - 1;
|
||||
result[4] = self.tech.as_value();
|
||||
if self.wrapping.is_some() {
|
||||
result[4] += 0x40;
|
||||
result[5] = self.wrapping.unwrap().value();
|
||||
};
|
||||
result
|
||||
}
|
||||
|
||||
pub fn apply_modifier(&mut self, modifier: &TechModifier) {
|
||||
match modifier {
|
||||
TechModifier::WrapPresent{paper} => {self.wrapping = Some(*paper)},
|
||||
TechModifier::UnwrapPresent => {self.wrapping = None},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::entity::item::{WrappingPaper};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ItemParseError {
|
||||
@ -647,10 +648,18 @@ impl ToolType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub enum ToolModifier {
|
||||
WrapPresent {
|
||||
paper: WrappingPaper,
|
||||
},
|
||||
UnwrapPresent,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Tool {
|
||||
pub tool: ToolType,
|
||||
pub wrapping: Option<WrappingPaper>, // TODO: what happens if a present is N monomates and the inventory already has 10?
|
||||
}
|
||||
|
||||
impl Tool {
|
||||
@ -668,10 +677,18 @@ impl Tool {
|
||||
}
|
||||
|
||||
pub fn from_bytes(data: [u8; 16]) -> Result<Tool, ItemParseError> {
|
||||
let t = ToolType::parse_type([data[0], data[1], data[2]]);
|
||||
let t = ToolType::parse_type([data[0], data[1], data[2]]);
|
||||
let w = {
|
||||
if data[4] & 0x40 == 0x40 {
|
||||
WrappingPaper::from(data[5])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
if t.is_ok() {
|
||||
Ok(Tool {
|
||||
tool: t.unwrap(),
|
||||
wrapping: w,
|
||||
})
|
||||
}
|
||||
else {
|
||||
@ -686,4 +703,11 @@ impl Tool {
|
||||
pub fn max_stack(&self) -> usize {
|
||||
self.tool.max_stack()
|
||||
}
|
||||
|
||||
pub fn apply_modifier(&mut self, modifier: &ToolModifier) {
|
||||
match modifier {
|
||||
ToolModifier::WrapPresent{paper} => {self.wrapping = Some(*paper)},
|
||||
ToolModifier::UnwrapPresent => {self.wrapping = None},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::entity::item::{WrappingPaper};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ItemParseError {
|
||||
@ -329,15 +330,19 @@ pub enum UnitModifier {
|
||||
Plus,
|
||||
Minus,
|
||||
MinusMinus,
|
||||
WrapPresent {
|
||||
paper: WrappingPaper,
|
||||
},
|
||||
UnwrapPresent,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Unit {
|
||||
pub unit: UnitType,
|
||||
pub modifier: Option<UnitModifier>,
|
||||
pub wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
|
||||
impl Unit {
|
||||
pub fn as_bytes(&self) -> [u8; 16] {
|
||||
let mut result = [0; 16];
|
||||
@ -359,8 +364,15 @@ impl Unit {
|
||||
result[6] = 0xFE;
|
||||
result[7] = 0xFF;
|
||||
},
|
||||
_ => {}, // handling wrapping here is weird?
|
||||
}
|
||||
}
|
||||
|
||||
if self.wrapping.is_some() {
|
||||
result[4] += 0x40;
|
||||
result[5] = self.wrapping.unwrap().value();
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
@ -375,13 +387,30 @@ impl Unit {
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let w = {
|
||||
if data[4] & 0x40 == 0x40 {
|
||||
WrappingPaper::from(data[5])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Unit{
|
||||
unit: u.unwrap(),
|
||||
modifier: m,
|
||||
wrapping: w,
|
||||
})
|
||||
}
|
||||
else {
|
||||
Err(ItemParseError::InvalidUnitBytes) // TODO: error handling if wrong bytes are given
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_modifier(&mut self, modifier: &UnitModifier) {
|
||||
match modifier {
|
||||
UnitModifier::WrapPresent{paper} => {self.wrapping = Some(*paper)},
|
||||
UnitModifier::UnwrapPresent => {self.wrapping = None},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::entity::item::ItemEntityId;
|
||||
use crate::entity::item::{ItemEntityId, WrappingPaper};
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@ -44,7 +44,6 @@ impl WeaponAttribute {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, strum_macros::EnumIter)]
|
||||
pub enum WeaponSpecial {
|
||||
Draw = 1,
|
||||
@ -1420,7 +1419,6 @@ impl WeaponType {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum TekSpecialModifier {
|
||||
Plus,
|
||||
@ -1452,18 +1450,22 @@ pub enum WeaponModifier {
|
||||
percent: TekPercentModifier,
|
||||
grind: i32,
|
||||
},
|
||||
WrapPresent {
|
||||
paper: WrappingPaper,
|
||||
},
|
||||
UnwrapPresent,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Weapon {
|
||||
pub weapon: WeaponType,
|
||||
pub special: Option<WeaponSpecial>,
|
||||
pub grind: u8,
|
||||
pub attrs: [Option<WeaponAttribute>; 3],
|
||||
pub tekked: bool,
|
||||
pub wrapping: Option<WrappingPaper>,
|
||||
}
|
||||
|
||||
|
||||
impl Weapon {
|
||||
pub fn new(wep: WeaponType) -> Weapon {
|
||||
Weapon {
|
||||
@ -1472,6 +1474,7 @@ impl Weapon {
|
||||
grind: 0,
|
||||
attrs: [None; 3],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1516,15 +1519,30 @@ impl Weapon {
|
||||
self.grind = std::cmp::max(self.grind as i32 + grind, 0) as u8;
|
||||
self.tekked = true;
|
||||
},
|
||||
WeaponModifier::WrapPresent{paper} => {self.wrapping = Some(*paper)},
|
||||
WeaponModifier::UnwrapPresent => {self.wrapping = None},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wrap_present(&mut self, value: u8) {
|
||||
self.wrapping = WrappingPaper::from(value);
|
||||
}
|
||||
|
||||
pub fn unwrap_present(&mut self) {
|
||||
self.wrapping = None;
|
||||
}
|
||||
|
||||
pub fn as_bytes(&self) -> [u8; 16] {
|
||||
let mut result = [0u8; 16];
|
||||
result[0..3].copy_from_slice(&self.weapon.value());
|
||||
result[3] = self.grind;
|
||||
result[4] = self.special.map(|s| s.value()).unwrap_or(0);
|
||||
|
||||
if self.wrapping.is_some() {
|
||||
result[4] += 0x40;
|
||||
result[5] = self.wrapping.unwrap().value();
|
||||
};
|
||||
|
||||
if self.tekked == false {
|
||||
result[4] += 0x80
|
||||
@ -1545,17 +1563,18 @@ impl Weapon {
|
||||
let mut t = true;
|
||||
let g = data[3];
|
||||
|
||||
if data[4] >= 0x81 && data[4] <= 0xA8 {
|
||||
if data[4] & 0x80 == 0x80 {
|
||||
s = WeaponSpecial::from(data[4] - 0x80);
|
||||
t = false;
|
||||
}
|
||||
else if data[4] >= 0x01 && data[4] <= 0x28 {
|
||||
s = WeaponSpecial::from(data[4]);
|
||||
t = true;
|
||||
}
|
||||
// else {
|
||||
// return Err(ItemParseError::InvalidSpecial)
|
||||
// }
|
||||
|
||||
let p = {
|
||||
if data[4] & 0x40 == 0x40 {
|
||||
WrappingPaper::from(data[5])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let mut a = [
|
||||
None,
|
||||
@ -1585,6 +1604,7 @@ impl Weapon {
|
||||
a[2],
|
||||
],
|
||||
tekked: t,
|
||||
wrapping: p,
|
||||
})
|
||||
}
|
||||
else {
|
||||
@ -1592,5 +1612,3 @@ impl Weapon {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -220,6 +220,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
|
||||
special: None,
|
||||
attrs: [None; 3],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: character.id,
|
||||
@ -233,6 +234,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
|
||||
dfp: 0,
|
||||
evp: 0,
|
||||
slots: 0,
|
||||
wrapping: None,
|
||||
}),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: character.id,
|
||||
@ -260,6 +262,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
|
||||
item: ItemDetail::Tool (
|
||||
Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: character.id,
|
||||
@ -273,6 +276,7 @@ async fn new_character<EG: EntityGateway>(entity_gateway: &mut EG, user: &UserAc
|
||||
item: ItemDetail::Tool (
|
||||
Tool {
|
||||
tool: item::tool::ToolType::Monofluid,
|
||||
wrapping: None,
|
||||
}),
|
||||
location: ItemLocation::Inventory {
|
||||
character_id: character.id,
|
||||
|
@ -107,6 +107,7 @@ impl GenericArmorTable {
|
||||
dfp: dfp_modifier as u8,
|
||||
evp: evp_modifier as u8,
|
||||
slots: slots as u8,
|
||||
wrapping: None,
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -126,24 +127,28 @@ mod test {
|
||||
dfp: 0,
|
||||
evp: 0,
|
||||
slots: 1,
|
||||
wrapping: None,
|
||||
})));
|
||||
assert!(gat.get_drop(&MapArea::Caves3, &mut rng) == Some(ItemDropType::Armor(Armor {
|
||||
armor: ArmorType::AbsorbArmor,
|
||||
dfp: 1,
|
||||
evp: 1,
|
||||
slots: 1,
|
||||
wrapping: None,
|
||||
})));
|
||||
assert!(gat.get_drop(&MapArea::Forest2, &mut rng) == Some(ItemDropType::Armor(Armor {
|
||||
armor: ArmorType::HyperFrame,
|
||||
dfp: 0,
|
||||
evp: 0,
|
||||
slots: 0,
|
||||
wrapping: None,
|
||||
})));
|
||||
assert!(gat.get_drop(&MapArea::DarkFalz, &mut rng) == Some(ItemDropType::Armor(Armor {
|
||||
armor: ArmorType::ImperialArmor,
|
||||
dfp: 2,
|
||||
evp: 1,
|
||||
slots: 0,
|
||||
wrapping: None,
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ impl GenericShieldTable {
|
||||
shield: shield_type,
|
||||
dfp: dfp_modifier as u8,
|
||||
evp: evp_modifier as u8,
|
||||
wrapping: None,
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -105,21 +106,25 @@ mod test {
|
||||
shield: ShieldType::FreezeBarrier,
|
||||
dfp: 4,
|
||||
evp: 1,
|
||||
wrapping: None,
|
||||
})));
|
||||
assert!(gst.get_drop(&MapArea::Caves3, &mut rng) == Some(ItemDropType::Shield(Shield {
|
||||
shield: ShieldType::PsychicBarrier,
|
||||
dfp: 3,
|
||||
evp: 2,
|
||||
wrapping: None,
|
||||
})));
|
||||
assert!(gst.get_drop(&MapArea::Mines2, &mut rng) == Some(ItemDropType::Shield(Shield {
|
||||
shield: ShieldType::ImperialBarrier,
|
||||
dfp: 0,
|
||||
evp: 4,
|
||||
wrapping: None,
|
||||
})));
|
||||
assert!(gst.get_drop(&MapArea::DarkFalz, &mut rng) == Some(ItemDropType::Shield(Shield {
|
||||
shield: ShieldType::DivinityBarrier,
|
||||
dfp: 1,
|
||||
evp: 0,
|
||||
wrapping: None,
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,7 @@ impl GenericUnitTable {
|
||||
ItemDropType::Unit(Unit {
|
||||
unit: unit_type,
|
||||
modifier: unit_modifier,
|
||||
wrapping: None,
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -116,6 +117,7 @@ mod test {
|
||||
assert!(gut.get_drop(&area, &mut rng) == Some(ItemDropType::Unit(Unit {
|
||||
unit: unit,
|
||||
modifier: umod,
|
||||
wrapping: None,
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
@ -503,6 +503,7 @@ impl GenericWeaponTable {
|
||||
grind: weapon_grind as u8,
|
||||
attrs: weapon_attributes,
|
||||
tekked: weapon_special.is_none(),
|
||||
wrapping: None,
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -524,6 +525,7 @@ mod test {
|
||||
grind: 0,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
})));
|
||||
|
||||
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Hard, SectionID::Skyly);
|
||||
@ -533,6 +535,7 @@ mod test {
|
||||
grind: 2,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
})));
|
||||
|
||||
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::VeryHard, SectionID::Skyly);
|
||||
@ -542,6 +545,7 @@ mod test {
|
||||
grind: 0,
|
||||
attrs: [None, None, None],
|
||||
tekked: false,
|
||||
wrapping: None,
|
||||
})));
|
||||
|
||||
let gwt = GenericWeaponTable::new(Episode::One, Difficulty::Ultimate, SectionID::Skyly);
|
||||
@ -551,6 +555,7 @@ mod test {
|
||||
grind: 0,
|
||||
attrs: [Some(WeaponAttribute {attr: Attribute::ABeast, value: 30}), Some(WeaponAttribute {attr: Attribute::Dark, value: 30}), None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +104,7 @@ impl RareDropTable {
|
||||
grind: 0,
|
||||
attrs: self.attribute_table.generate_rare_attributes(map_area, rng),
|
||||
tekked: false,
|
||||
wrapping: None,
|
||||
})
|
||||
|
||||
},
|
||||
@ -113,6 +114,7 @@ impl RareDropTable {
|
||||
dfp: self.armor_stats.dfp_modifier(&armor, rng) as u8,
|
||||
evp: self.armor_stats.evp_modifier(&armor, rng) as u8,
|
||||
slots: self.armor_stats.slots(map_area, rng) as u8,
|
||||
wrapping: None,
|
||||
})
|
||||
},
|
||||
RareDropItem::Shield(shield) => {
|
||||
@ -120,17 +122,20 @@ impl RareDropTable {
|
||||
shield: shield,
|
||||
dfp: self.shield_stats.dfp_modifier(&shield, rng) as u8,
|
||||
evp: self.shield_stats.evp_modifier(&shield, rng) as u8,
|
||||
wrapping: None,
|
||||
})
|
||||
},
|
||||
RareDropItem::Unit(unit) => {
|
||||
ItemDropType::Unit(Unit {
|
||||
unit: unit,
|
||||
modifier: None,
|
||||
wrapping: None,
|
||||
})
|
||||
},
|
||||
RareDropItem::Tool(tool) => {
|
||||
ItemDropType::Tool(Tool {
|
||||
tool: tool,
|
||||
wrapping: None,
|
||||
})
|
||||
},
|
||||
RareDropItem::Mag(_mag) => {
|
||||
|
@ -103,7 +103,8 @@ impl TechniqueTable {
|
||||
|
||||
Some(ItemDropType::TechniqueDisk(TechniqueDisk {
|
||||
tech: *tech,
|
||||
level: level as u32
|
||||
level: level as u32,
|
||||
wrapping: None,
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -127,7 +128,8 @@ mod test {
|
||||
assert!(tt.get_drop(&area, &mut rng) == Some(ItemDropType::TechniqueDisk(
|
||||
TechniqueDisk {
|
||||
tech: tech,
|
||||
level: level
|
||||
level: level,
|
||||
wrapping: None,
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +158,8 @@ impl ToolTable {
|
||||
};
|
||||
|
||||
Some(ItemDropType::Tool(Tool {
|
||||
tool: tool_type
|
||||
tool: tool_type,
|
||||
wrapping: None,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,14 @@ use thiserror::Error;
|
||||
use libpso::character::character;//::InventoryItem;
|
||||
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::entity::item::weapon::Weapon;
|
||||
use crate::entity::item::esweapon::ESWeapon;
|
||||
use crate::entity::item::armor::Armor; // TODO: cleanup uses
|
||||
use crate::entity::item::unit::Unit;
|
||||
use crate::entity::item::shield::Shield;
|
||||
use crate::entity::item::mag::Mag;
|
||||
use crate::entity::item::tech::TechniqueDisk;
|
||||
use crate::entity::item::tool::Tool;
|
||||
use crate::ship::items::{ClientItemId, BankItem, BankItemHandle};
|
||||
use crate::ship::items::floor::{IndividualFloorItem, StackedFloorItem};
|
||||
|
||||
@ -38,12 +43,69 @@ impl IndividualInventoryItem {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn weapon_mut(&mut self) -> Option<&mut Weapon> {
|
||||
match self.item {
|
||||
ItemDetail::Weapon(ref mut weapon) => Some(weapon),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn esweapon_mut(&mut self) -> Option<&mut ESWeapon> {
|
||||
match self.item {
|
||||
ItemDetail::ESWeapon(ref mut esweapon) => Some(esweapon),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn armor_mut(&mut self) -> Option<&mut Armor> {
|
||||
match self.item {
|
||||
ItemDetail::Armor(ref mut armor) => Some(armor),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unit_mut(&mut self) -> Option<&mut Unit> {
|
||||
match self.item {
|
||||
ItemDetail::Unit(ref mut unit) => Some(unit),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shield_mut(&mut self) -> Option<&mut Shield> {
|
||||
match self.item {
|
||||
ItemDetail::Shield(ref mut shield) => Some(shield),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mag_mut(&mut self) -> Option<&mut Mag> {
|
||||
match self.item {
|
||||
ItemDetail::Mag(ref mut mag) => Some(mag),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tech_mut(&mut self) -> Option<&mut TechniqueDisk> {
|
||||
match self.item {
|
||||
ItemDetail::TechniqueDisk(ref mut tech) => Some(tech),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tool_mut(&mut self) -> Option<&mut Tool> {
|
||||
match self.item {
|
||||
ItemDetail::Tool(ref mut tool) => Some(tool),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_wrapped(&mut self) -> bool {
|
||||
self.item.is_wrapped()
|
||||
}
|
||||
|
||||
pub fn unwrap_present(&mut self) {
|
||||
self.item.unwrap_present();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -66,6 +128,14 @@ impl StackedInventoryItem {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_wrapped(&self) -> bool {
|
||||
self.tool.wrapping.is_some()
|
||||
}
|
||||
|
||||
pub fn unwrap_present(&mut self) {
|
||||
self.tool.wrapping = None;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -127,7 +197,7 @@ impl InventoryItem {
|
||||
}
|
||||
}
|
||||
|
||||
// TOOD: delete?
|
||||
// TODO: delete?
|
||||
pub fn are_same_stackable_tool(&self, other_stacked_item: &StackedFloorItem) -> bool {
|
||||
match self {
|
||||
InventoryItem::Stacked(self_stacked_item) => {
|
||||
@ -138,7 +208,7 @@ impl InventoryItem {
|
||||
}
|
||||
}
|
||||
|
||||
// TOOD: delete?
|
||||
// TODO: delete?
|
||||
pub fn can_combine_stacks(&self, other_stacked_item: &StackedFloorItem) -> bool {
|
||||
match self {
|
||||
InventoryItem::Stacked(self_stacked_item) => {
|
||||
@ -151,7 +221,7 @@ impl InventoryItem {
|
||||
}
|
||||
|
||||
// TODO: result
|
||||
// TOOD: delete?
|
||||
// TODO: delete?
|
||||
pub fn combine_stacks(&mut self, other_stacked_item: &mut StackedFloorItem) {
|
||||
match self {
|
||||
InventoryItem::Stacked(self_stacked_item) => {
|
||||
@ -167,13 +237,13 @@ impl InventoryItem {
|
||||
InventoryItem::Individual(item) => {
|
||||
match &item.item {
|
||||
ItemDetail::Weapon(w) => w.as_bytes(),
|
||||
ItemDetail::Armor(a) => a.as_bytes(),
|
||||
ItemDetail::Shield(s) => s.as_bytes(),
|
||||
ItemDetail::Unit(u) => u.as_bytes(),
|
||||
ItemDetail::Tool(t) => t.as_individual_bytes(),
|
||||
ItemDetail::TechniqueDisk(d) => d.as_bytes(),
|
||||
ItemDetail::Mag(m) => m.as_bytes(),
|
||||
ItemDetail::ESWeapon(e) => e.as_bytes(),
|
||||
ItemDetail::Armor(a) => a.as_bytes(),
|
||||
ItemDetail::Unit(u) => u.as_bytes(),
|
||||
ItemDetail::Shield(s) => s.as_bytes(),
|
||||
ItemDetail::Mag(m) => m.as_bytes(),
|
||||
ItemDetail::TechniqueDisk(d) => d.as_bytes(),
|
||||
ItemDetail::Tool(t) => t.as_individual_bytes(),
|
||||
}
|
||||
},
|
||||
InventoryItem::Stacked(item) => {
|
||||
@ -219,6 +289,41 @@ impl InventoryItem {
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn item_detail(&self) -> ItemDetail {
|
||||
match self {
|
||||
InventoryItem::Individual(individual_inventory_item) => individual_inventory_item.item.clone(),
|
||||
InventoryItem::Stacked(stacked_inventory_item) => ItemDetail::Tool(stacked_inventory_item.tool),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_consumed_item(&self) -> ConsumedItem {
|
||||
match self {
|
||||
InventoryItem::Individual(individual_inventory_item) => {ConsumedItem::Individual(IndividualConsumedItem {
|
||||
entity_id: individual_inventory_item.entity_id,
|
||||
item: individual_inventory_item.item.clone(),
|
||||
})},
|
||||
InventoryItem::Stacked(stacked_inventory_item) => {ConsumedItem::Stacked(StackedConsumedItem {
|
||||
entity_ids: stacked_inventory_item.entity_ids.clone(),
|
||||
tool: stacked_inventory_item.tool,
|
||||
})},
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: validate if wrapping stacked items & tools are valid in the client. Gallons shop allows users to wrap tools (eg techs) but then the client may not be able to unwrap it afterwards?
|
||||
pub fn is_wrapped(&mut self) -> bool {
|
||||
match self {
|
||||
InventoryItem::Individual(i) => i.is_wrapped(),
|
||||
InventoryItem::Stacked(s) => s.is_wrapped(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_present(&mut self) {
|
||||
match self {
|
||||
InventoryItem::Individual(i) => i.unwrap_present(),
|
||||
InventoryItem::Stacked(s) => s.unwrap_present(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,10 +4,9 @@ use thiserror::Error;
|
||||
use crate::entity::gateway::EntityGateway;
|
||||
use crate::entity::character::{CharacterEntity, CharacterEntityId, TechLevel};
|
||||
use crate::entity::item::{ItemDetail, ItemLocation, BankName};
|
||||
use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity, EquippedEntity, InventoryEntity, BankItemEntity, BankEntity};
|
||||
use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity, EquippedEntity, InventoryEntity, BankItemEntity, BankEntity, ItemType};
|
||||
use crate::entity::item::tool::{Tool, ToolType};
|
||||
use crate::entity::item::unit;
|
||||
use crate::entity::item::weapon;
|
||||
use crate::entity::item::{unit, weapon, armor, shield, mag, tech, tool, esweapon};
|
||||
use crate::ship::map::MapArea;
|
||||
use crate::ship::ship::ItemDropLocation;
|
||||
use crate::ship::drops::{ItemDrop, ItemDropType};
|
||||
@ -503,7 +502,6 @@ impl ItemManager {
|
||||
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||
let used_item = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?;
|
||||
let consumed_item = used_item.consume(amount)?;
|
||||
|
||||
if let ItemDetail::TechniqueDisk(tech_disk) = consumed_item.item() {
|
||||
// TODO: validate tech level in packet is in bounds [1..30]
|
||||
character.techs.set_tech(tech_disk.tech, TechLevel(tech_disk.level as u8));
|
||||
@ -636,114 +634,149 @@ impl ItemManager {
|
||||
}
|
||||
|
||||
pub async fn use_item<EG: EntityGateway>(&mut self,
|
||||
used_item: ConsumedItem,
|
||||
entity_gateway: &mut EG,
|
||||
character: &mut CharacterEntity) -> Result<(), anyhow::Error> {
|
||||
character: &mut CharacterEntity,
|
||||
client_item_id: ClientItemId) -> Result<(), anyhow::Error> {
|
||||
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||
match &used_item.item() {
|
||||
ItemDetail::Weapon(_w) => {
|
||||
// something like when items are used to combine/transform them?
|
||||
//_ => {}
|
||||
},
|
||||
ItemDetail::Tool(t) => {
|
||||
match t.tool {
|
||||
ToolType::PowerMaterial => {
|
||||
use_tool::power_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::MindMaterial => {
|
||||
use_tool::mind_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::EvadeMaterial => {
|
||||
use_tool::evade_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::DefMaterial => {
|
||||
use_tool::def_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::LuckMaterial => {
|
||||
use_tool::luck_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::HpMaterial => {
|
||||
use_tool::hp_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::TpMaterial => {
|
||||
use_tool::tp_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::CellOfMag502 => {
|
||||
use_tool::cell_of_mag_502(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::CellOfMag213 => {
|
||||
use_tool::cell_of_mag_213(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::PartsOfRobochao => {
|
||||
use_tool::parts_of_robochao(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeartOfOpaOpa => {
|
||||
use_tool::heart_of_opaopa(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeartOfPian => {
|
||||
use_tool::heart_of_pian(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeartOfChao=> {
|
||||
use_tool::heart_of_chao(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeartOfAngel => {
|
||||
use_tool::heart_of_angel(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfHamburger => {
|
||||
use_tool::kit_of_hamburger(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::PanthersSpirit => {
|
||||
use_tool::panthers_spirit(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfMark3 => {
|
||||
use_tool::kit_of_mark3(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfMasterSystem=> {
|
||||
use_tool::kit_of_master_system(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfGenesis => {
|
||||
use_tool::kit_of_genesis(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfSegaSaturn => {
|
||||
use_tool::kit_of_sega_saturn(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfDreamcast => {
|
||||
use_tool::kit_of_dreamcast(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::Tablet => {
|
||||
use_tool::tablet(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::DragonScale => {
|
||||
use_tool::dragon_scale(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeavenStrikerCoat => {
|
||||
use_tool::heaven_striker_coat(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::PioneerParts => {
|
||||
use_tool::pioneer_parts(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::AmitiesMemo => {
|
||||
use_tool::amities_memo(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeartOfMorolian => {
|
||||
use_tool::heart_of_morolian(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::RappysBeak => {
|
||||
use_tool::rappys_beak(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::YahoosEngine => {
|
||||
use_tool::yahoos_engine(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::DPhotonCore => {
|
||||
use_tool::d_photon_core(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
ToolType::LibertaKit => {
|
||||
use_tool::liberta_kit(entity_gateway, &used_item, inventory).await?;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
let mut used_item_handle = inventory.get_item_handle_by_id(client_item_id).ok_or(ItemManagerError::ItemIdNotInInventory(client_item_id))?;
|
||||
let used_item = used_item_handle.item_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
|
||||
if used_item.is_wrapped() {
|
||||
used_item.unwrap_present();
|
||||
} else {
|
||||
match used_item.item_type() {
|
||||
ItemType::Weapon(_) => {
|
||||
let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.weapon_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
|
||||
// combining / unsealing?
|
||||
},
|
||||
ItemType::ESWeapon(_) => { // TODO: wrap srank weapons
|
||||
let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.esweapon_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
|
||||
// combining / unsealing?
|
||||
},
|
||||
ItemType::Armor(_) => {
|
||||
let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.armor_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
|
||||
// combining / unsealing?
|
||||
},
|
||||
ItemType::Unit(_) => {
|
||||
let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.unit_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
|
||||
// combining / unsealing?
|
||||
},
|
||||
ItemType::Shield(_) => {
|
||||
let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.shield_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
|
||||
// combining / unsealing?
|
||||
},
|
||||
ItemType::Mag(_) => {
|
||||
let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.mag_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
|
||||
// combining / unsealing?
|
||||
},
|
||||
ItemType::TechniqueDisk(_) => {
|
||||
let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.tech_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
|
||||
// combining / unsealing?
|
||||
},
|
||||
ItemType::Tool(_) => {
|
||||
let consumed_item = used_item.as_consumed_item();
|
||||
match &used_item.item_detail() {
|
||||
ItemDetail::Tool(t) => {
|
||||
match t.tool {
|
||||
ToolType::PowerMaterial => {
|
||||
use_tool::power_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::MindMaterial => {
|
||||
use_tool::mind_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::EvadeMaterial => {
|
||||
use_tool::evade_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::DefMaterial => {
|
||||
use_tool::def_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::LuckMaterial => {
|
||||
use_tool::luck_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::HpMaterial => {
|
||||
use_tool::hp_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::TpMaterial => {
|
||||
use_tool::tp_material(entity_gateway, character).await;
|
||||
},
|
||||
ToolType::CellOfMag502 => {
|
||||
use_tool::cell_of_mag_502(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::CellOfMag213 => {
|
||||
use_tool::cell_of_mag_213(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::PartsOfRobochao => {
|
||||
use_tool::parts_of_robochao(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeartOfOpaOpa => {
|
||||
use_tool::heart_of_opaopa(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeartOfPian => {
|
||||
use_tool::heart_of_pian(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeartOfChao=> {
|
||||
use_tool::heart_of_chao(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeartOfAngel => {
|
||||
use_tool::heart_of_angel(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfHamburger => {
|
||||
use_tool::kit_of_hamburger(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::PanthersSpirit => {
|
||||
use_tool::panthers_spirit(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfMark3 => {
|
||||
use_tool::kit_of_mark3(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfMasterSystem=> {
|
||||
use_tool::kit_of_master_system(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfGenesis => {
|
||||
use_tool::kit_of_genesis(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfSegaSaturn => {
|
||||
use_tool::kit_of_sega_saturn(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::KitOfDreamcast => {
|
||||
use_tool::kit_of_dreamcast(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::Tablet => {
|
||||
use_tool::tablet(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::DragonScale => {
|
||||
use_tool::dragon_scale(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeavenStrikerCoat => {
|
||||
use_tool::heaven_striker_coat(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::PioneerParts => {
|
||||
use_tool::pioneer_parts(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::AmitiesMemo => {
|
||||
use_tool::amities_memo(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::HeartOfMorolian => {
|
||||
use_tool::heart_of_morolian(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::RappysBeak => {
|
||||
use_tool::rappys_beak(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::YahoosEngine => {
|
||||
use_tool::yahoos_engine(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::DPhotonCore => {
|
||||
use_tool::d_photon_core(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
ToolType::LibertaKit => {
|
||||
use_tool::liberta_kit(entity_gateway, &consumed_item, inventory).await?;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
|
||||
Ok(())
|
||||
@ -923,4 +956,9 @@ impl ItemManager {
|
||||
|
||||
Ok(weapon)
|
||||
}
|
||||
|
||||
pub fn get_inventory_item_by_id(&mut self, character: &CharacterEntity, item_id: ClientItemId) -> Result<&InventoryItem, anyhow::Error> {
|
||||
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
|
||||
Ok(inventory.get_item_by_id(item_id).ok_or(ItemManagerError::ItemIdNotInInventory(item_id))?)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// TOOD: `pub(super) for most of these?`
|
||||
// TODO: `pub(super) for most of these?`
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::collections::HashMap;
|
||||
use thiserror::Error;
|
||||
|
@ -1,12 +1,9 @@
|
||||
// TOOD: `pub(super) for most of these?`
|
||||
// TODO: `pub(super) for most of these?`
|
||||
use std::io::{Read};
|
||||
|
||||
use byteorder::{LittleEndian, ReadBytesExt};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::ship::monster::MonsterType;
|
||||
use crate::ship::room::Episode;
|
||||
|
||||
use crate::ship::map::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@ -62,7 +59,6 @@ impl RawMapEnemy {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[error("")]
|
||||
pub enum MapEnemyError {
|
||||
@ -70,7 +66,6 @@ pub enum MapEnemyError {
|
||||
MapAreaError(#[from] MapAreaError),
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct MapEnemy {
|
||||
pub monster: MonsterType,
|
||||
@ -194,7 +189,6 @@ impl MapEnemy {
|
||||
_ => return Err(MapEnemyError::UnknownEnemyId(enemy.id))
|
||||
}
|
||||
},
|
||||
|
||||
MapArea::Tower => {
|
||||
match (enemy, episode) {
|
||||
(RawMapEnemy {id: 97, ..}, _) => MonsterType::DelLily,
|
||||
|
@ -1,4 +1,4 @@
|
||||
// TOOD: `pub(super) for most of these?`
|
||||
// TODO: `pub(super) for most of these?`
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::io::{Read};
|
||||
@ -96,7 +96,7 @@ fn parse_enemy(episode: &Episode, map_area: &MapArea, raw_enemy: RawMapEnemy) ->
|
||||
monsters.push(Some(MapEnemy::new(MonsterType::VolOptCore, monster.map_area)));
|
||||
monsters.push(Some(MapEnemy::new(MonsterType::VolOptUnused, monster.map_area)));
|
||||
},
|
||||
// TOOD: this cares about difficulty (theres an ult-specific darvant?)
|
||||
// TODO: this cares about difficulty (theres an ult-specific darvant?)
|
||||
MonsterType::DarkFalz => {
|
||||
for _ in 0..509 {
|
||||
monsters.push(Some(MapEnemy::new(MonsterType::Darvant, monster.map_area)));
|
||||
|
@ -1,4 +1,4 @@
|
||||
// TOOD: `pub(super) for most of these?`
|
||||
// TODO: `pub(super) for most of these?`
|
||||
|
||||
use std::io::{Read};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// TOOD: `pub(super) for most of these?`
|
||||
// TODO: `pub(super) for most of these?`
|
||||
|
||||
use rand::Rng;
|
||||
|
||||
|
@ -119,7 +119,7 @@ pub fn character_leveled_up(area_client: AreaClient, level: u32, before_stats: C
|
||||
}
|
||||
}
|
||||
|
||||
// TOOD: checksum?
|
||||
// TODO: checksum?
|
||||
pub fn bank_item_list(bank: &CharacterBank, char_bank_meseta: u32) -> BankItemList {
|
||||
BankItemList {
|
||||
aflag: 0,
|
||||
|
@ -1,12 +1,12 @@
|
||||
use libpso::packet::ship::*;
|
||||
use libpso::packet::messages::*;
|
||||
use crate::entity::gateway::EntityGateway;
|
||||
use crate::entity::item::{ItemType};
|
||||
use crate::entity::item::{ItemType, ItemDetail};
|
||||
use crate::common::serverstate::ClientId;
|
||||
use crate::common::leveltable::CharacterLevelTable;
|
||||
use crate::ship::ship::{SendShipPacket, ShipError, Rooms, Clients, ItemDropLocation};
|
||||
use crate::ship::location::{ClientLocation, ClientLocationError};
|
||||
use crate::ship::items::{ItemManager, ClientItemId, InventoryItem};
|
||||
use crate::ship::items::{ItemManager, ClientItemId, InventoryItem, ItemManagerError};
|
||||
use crate::ship::packet::builder;
|
||||
|
||||
pub async fn request_exp<EG: EntityGateway>(id: ClientId,
|
||||
@ -272,9 +272,12 @@ where
|
||||
EG: EntityGateway
|
||||
{
|
||||
let client = clients.get_mut(&id).ok_or(ShipError::ClientNotFound(id))?;
|
||||
let item_used_type = item_manager.player_consumes_tool(entity_gateway, &mut client.character, ClientItemId(player_use_tool.item_id), 1).await?;
|
||||
item_manager.use_item(entity_gateway, &mut client.character, ClientItemId(player_use_tool.item_id)).await?;
|
||||
|
||||
item_manager.use_item(item_used_type, entity_gateway, &mut client.character).await?;
|
||||
if let ItemDetail::Tool(_t) = item_manager.get_inventory_item_by_id(&client.character, ClientItemId(player_use_tool.item_id))?.item_detail() {
|
||||
item_manager.player_consumes_tool(entity_gateway, &mut client.character, ClientItemId(player_use_tool.item_id), 1).await?;
|
||||
}
|
||||
|
||||
Ok(Box::new(None.into_iter()))
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ use crate::ship::location::{ClientLocation, ClientLocationError};
|
||||
use crate::ship::packet::builder::quest;
|
||||
use libpso::util::array_to_utf8;
|
||||
|
||||
// TOOD: enum
|
||||
// TODO: enum
|
||||
enum QuestFileType {
|
||||
Bin,
|
||||
Dat
|
||||
|
@ -653,7 +653,7 @@ impl<EG: EntityGateway> ServerState for ShipServerState<EG> {
|
||||
handler::room::cool_62(id, cool62, &block.client_location)
|
||||
},
|
||||
RecvShipPacket::ClientCharacterData(_) => {
|
||||
// TOOD: validate this in some way?
|
||||
// TODO: validate this in some way?
|
||||
Box::new(None.into_iter())
|
||||
},
|
||||
RecvShipPacket::DoneBursting(_) => {
|
||||
|
@ -71,6 +71,7 @@ impl ShopItem for ArmorShopItem {
|
||||
dfp: 0,
|
||||
evp: 0,
|
||||
slots: *slot as u8,
|
||||
wrapping: None,
|
||||
})
|
||||
},
|
||||
ArmorShopItem::Barrier(barrier) => {
|
||||
@ -78,12 +79,14 @@ impl ShopItem for ArmorShopItem {
|
||||
shield: *barrier,
|
||||
dfp: 0,
|
||||
evp: 0,
|
||||
wrapping: None,
|
||||
})
|
||||
},
|
||||
ArmorShopItem::Unit(unit) => {
|
||||
ItemDetail::Unit(Unit {
|
||||
unit: *unit,
|
||||
modifier: None,
|
||||
wrapping: None,
|
||||
})
|
||||
},
|
||||
}
|
||||
|
@ -22,11 +22,11 @@ pub enum ToolShopItem {
|
||||
impl Ord for ToolShopItem {
|
||||
fn cmp(&self, other: &ToolShopItem) -> std::cmp::Ordering {
|
||||
let a = match self {
|
||||
ToolShopItem::Tool(t) => Tool{tool : *t}.as_individual_bytes(),
|
||||
ToolShopItem::Tool(t) => Tool{tool : *t, wrapping: None,}.as_individual_bytes(),
|
||||
ToolShopItem::Tech(t) => t.as_bytes(),
|
||||
};
|
||||
let b = match other {
|
||||
ToolShopItem::Tool(t) => Tool{tool : *t}.as_individual_bytes(),
|
||||
ToolShopItem::Tool(t) => Tool{tool : *t, wrapping: None,}.as_individual_bytes(),
|
||||
ToolShopItem::Tech(t) => t.as_bytes(),
|
||||
};
|
||||
|
||||
@ -37,11 +37,11 @@ impl Ord for ToolShopItem {
|
||||
impl PartialOrd for ToolShopItem {
|
||||
fn partial_cmp(&self, other: &ToolShopItem) -> Option<std::cmp::Ordering> {
|
||||
let a = match self {
|
||||
ToolShopItem::Tool(t) => Tool{tool : *t}.as_individual_bytes(),
|
||||
ToolShopItem::Tool(t) => Tool{tool : *t, wrapping: None,}.as_individual_bytes(),
|
||||
ToolShopItem::Tech(t) => t.as_bytes(),
|
||||
};
|
||||
let b = match other {
|
||||
ToolShopItem::Tool(t) => Tool{tool : *t}.as_individual_bytes(),
|
||||
ToolShopItem::Tool(t) => Tool{tool : *t, wrapping: None,}.as_individual_bytes(),
|
||||
ToolShopItem::Tech(t) => t.as_bytes(),
|
||||
};
|
||||
|
||||
@ -73,7 +73,8 @@ impl ShopItem for ToolShopItem {
|
||||
match self {
|
||||
ToolShopItem::Tool(tool) => {
|
||||
Tool {
|
||||
tool: *tool
|
||||
tool: *tool,
|
||||
wrapping: None,
|
||||
}.as_individual_bytes()[0..12].try_into().unwrap()
|
||||
},
|
||||
ToolShopItem::Tech(tech) => {
|
||||
@ -86,7 +87,8 @@ impl ShopItem for ToolShopItem {
|
||||
match self {
|
||||
ToolShopItem::Tool(tool) => {
|
||||
ItemDetail::Tool(Tool {
|
||||
tool: *tool
|
||||
tool: *tool,
|
||||
wrapping: None,
|
||||
})
|
||||
},
|
||||
ToolShopItem::Tech(tech) => {
|
||||
@ -262,6 +264,7 @@ impl<R: Rng + SeedableRng> ToolShop<R> {
|
||||
ToolShopItem::Tech(TechniqueDisk {
|
||||
tech: tech,
|
||||
level: level as u32,
|
||||
wrapping: None,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
|
@ -142,6 +142,7 @@ impl ShopItem for WeaponShopItem {
|
||||
grind: self.grind as u8,
|
||||
attrs: [self.attributes[0], self.attributes[1], None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ async fn test_bank_items_sent_in_character_login() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -68,6 +69,7 @@ async fn test_request_bank_items() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -116,6 +118,7 @@ async fn test_request_stacked_bank_items() {
|
||||
item: item::ItemDetail::Tool (
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -165,6 +168,7 @@ async fn test_request_bank_items_sorted() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -177,6 +181,7 @@ async fn test_request_bank_items_sorted() {
|
||||
item: item::ItemDetail::Tool (
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -193,6 +198,7 @@ async fn test_request_bank_items_sorted() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -243,6 +249,7 @@ async fn test_deposit_individual_item() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -258,6 +265,7 @@ async fn test_deposit_individual_item() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -320,6 +328,7 @@ async fn test_deposit_stacked_item() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -384,6 +393,7 @@ async fn test_deposit_partial_stacked_item() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -458,6 +468,7 @@ async fn test_deposit_stacked_item_with_stack_already_in_bank() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -470,6 +481,7 @@ async fn test_deposit_stacked_item_with_stack_already_in_bank() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -535,6 +547,7 @@ async fn test_deposit_stacked_item_with_full_stack_in_bank() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -550,6 +563,7 @@ async fn test_deposit_stacked_item_with_full_stack_in_bank() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -617,6 +631,7 @@ async fn test_deposit_individual_item_in_full_bank() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -635,6 +650,7 @@ async fn test_deposit_individual_item_in_full_bank() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -695,6 +711,7 @@ async fn test_deposit_stacked_item_in_full_bank() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -714,6 +731,7 @@ async fn test_deposit_stacked_item_in_full_bank() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -775,6 +793,7 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -790,6 +809,7 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -810,6 +830,7 @@ async fn test_deposit_stacked_item_in_full_bank_with_partial_stack() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -988,6 +1009,7 @@ async fn test_withdraw_individual_item() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -1051,6 +1073,7 @@ async fn test_withdraw_stacked_item() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -1115,6 +1138,7 @@ async fn test_withdraw_partial_stacked_item() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -1186,6 +1210,7 @@ async fn test_withdraw_stacked_item_with_stack_already_in_inventory() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -1198,6 +1223,7 @@ async fn test_withdraw_stacked_item_with_stack_already_in_inventory() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -1265,6 +1291,7 @@ async fn test_withdraw_stacked_item_with_full_stack_in_inventory() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -1281,6 +1308,7 @@ async fn test_withdraw_stacked_item_with_full_stack_in_inventory() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -1347,6 +1375,7 @@ async fn test_withdraw_individual_item_in_full_inventory() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -1366,6 +1395,7 @@ async fn test_withdraw_individual_item_in_full_inventory() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -1421,6 +1451,7 @@ async fn test_withdraw_stacked_item_in_full_inventory() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -1441,6 +1472,7 @@ async fn test_withdraw_stacked_item_in_full_inventory() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -1502,6 +1534,7 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Bank {
|
||||
@ -1523,6 +1556,7 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -1538,6 +1572,7 @@ async fn test_withdraw_stacked_item_in_full_inventory_with_partial_stack() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
|
289
tests/test_item_modifiers.rs
Normal file
289
tests/test_item_modifiers.rs
Normal file
@ -0,0 +1,289 @@
|
||||
use elseware::common::serverstate::{ClientId, ServerState};
|
||||
use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
|
||||
use elseware::entity::item;
|
||||
use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket};
|
||||
|
||||
use libpso::packet::ship::*;
|
||||
use libpso::packet::messages::*;
|
||||
|
||||
#[path = "common.rs"]
|
||||
mod common;
|
||||
use common::*;
|
||||
|
||||
// unwrap presents
|
||||
#[async_std::test]
|
||||
async fn test_unwrap_weapon() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
|
||||
let wrapped_item = entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Weapon(item::weapon::Weapon {
|
||||
weapon: item::weapon::WeaponType::Saber,
|
||||
special: Some(item::weapon::WeaponSpecial::Burning),
|
||||
grind: 5,
|
||||
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Machine, value: 20}),
|
||||
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 30}),
|
||||
None],
|
||||
tekked: false,
|
||||
wrapping: Some(item::WrappingPaper::RedGreen),
|
||||
}),
|
||||
location: item::ItemLocation::Inventory{
|
||||
character_id: char1.id,
|
||||
}
|
||||
}).await.unwrap();
|
||||
|
||||
assert!(wrapped_item.item.as_client_bytes() == [0x00,0x01,0x00,0x05,0xDA,0x05,0x03,0x14,0x05,0x1E,0x00,0x00,0x00,0x00,0x00,0x00]);
|
||||
|
||||
let mut inventory = Vec::<item::ItemEntity>::new();
|
||||
inventory.push(wrapped_item.into());
|
||||
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());
|
||||
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x10000,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
|
||||
|
||||
inventory_items.items[0].with_individual(|item| {
|
||||
match &item.item {
|
||||
item::ItemDetail::Weapon(weapon) => {
|
||||
assert!(weapon.as_bytes() == [0x00, 0x01, 0x00, 0x05, 0x9A, 0x00, 0x03, 0x14, 0x05, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_unwrap_armor() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
|
||||
let wrapped_item = entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Armor(item::armor::Armor {
|
||||
armor: item::armor::ArmorType::PerfectFrame,
|
||||
dfp: 3u8,
|
||||
evp: 2u8,
|
||||
slots: 4u8,
|
||||
wrapping: Some(item::WrappingPaper::RedGreen), // 5
|
||||
}),
|
||||
location: item::ItemLocation::Inventory{
|
||||
character_id: char1.id,
|
||||
}
|
||||
}).await.unwrap();
|
||||
|
||||
// slots should be untouched when wrapped regardless of wrapping paper colour
|
||||
assert!(wrapped_item.item.as_client_bytes() == [0x01,0x01,0x10,0x00,0x40,0x04,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00]);
|
||||
|
||||
let mut inventory = Vec::<item::ItemEntity>::new();
|
||||
inventory.push(wrapped_item.into());
|
||||
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());
|
||||
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x10000,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
|
||||
|
||||
inventory_items.items[0].with_individual(|item| {
|
||||
match &item.item {
|
||||
item::ItemDetail::Armor(armor) => {
|
||||
assert!(armor.as_bytes() == [0x01,0x01,0x10,0x00,0x00,0x04,0x03,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00]);
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_unwrap_shield() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
|
||||
let wrapped_item = entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Shield(item::shield::Shield {
|
||||
shield: item::shield::ShieldType::CoreShield,
|
||||
dfp: 2u8,
|
||||
evp: 3u8,
|
||||
wrapping: Some(item::WrappingPaper::RedGreen), // 5
|
||||
}),
|
||||
location: item::ItemLocation::Inventory{
|
||||
character_id: char1.id,
|
||||
}
|
||||
}).await.unwrap();
|
||||
|
||||
assert!(wrapped_item.item.as_client_bytes() == [0x01,0x02,0x02,0x00,0x40,0x05,0x02,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00]);
|
||||
|
||||
let mut inventory = Vec::<item::ItemEntity>::new();
|
||||
inventory.push(wrapped_item.into());
|
||||
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());
|
||||
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x10000,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
|
||||
|
||||
inventory_items.items[0].with_individual(|item| {
|
||||
match &item.item {
|
||||
item::ItemDetail::Shield(shield) => {
|
||||
assert!(shield.as_bytes() == [0x01,0x02,0x02,0x00,0x00,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00]);
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_unwrap_unit() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
|
||||
let wrapped_item = entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Unit(item::unit::Unit {
|
||||
unit: item::unit::UnitType::KnightPower,
|
||||
modifier: Some(item::unit::UnitModifier::MinusMinus),
|
||||
wrapping: Some(item::WrappingPaper::RedGreen), // 5
|
||||
}),
|
||||
location: item::ItemLocation::Inventory{
|
||||
character_id: char1.id,
|
||||
}
|
||||
}).await.unwrap();
|
||||
|
||||
assert!(wrapped_item.item.as_client_bytes() == [0x01,0x03,0x00,0x00,0x40,0x05,0xFE,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]);
|
||||
|
||||
let mut inventory = Vec::<item::ItemEntity>::new();
|
||||
inventory.push(wrapped_item.into());
|
||||
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());
|
||||
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x10000,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
|
||||
|
||||
inventory_items.items[0].with_individual(|item| {
|
||||
match &item.item {
|
||||
item::ItemDetail::Unit(unit) => {
|
||||
assert!(unit.as_bytes() == [0x01,0x03,0x00,0x00,0x00,0x00,0xFE,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00]);
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
// mag cells are covered in test_mags.rs
|
||||
#[async_std::test]
|
||||
async fn test_unwrap_mag() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
||||
let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
|
||||
|
||||
let wrapped_item = entity_gateway.create_item(
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Mag(item::mag::Mag::wrapped_baby_mag(12)), //turquoise
|
||||
location: item::ItemLocation::Inventory{
|
||||
character_id: char1.id,
|
||||
}
|
||||
}).await.unwrap();
|
||||
|
||||
assert!(wrapped_item.item.as_client_bytes() == [0x02,0x00,0x00,0x00,0xF4,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x40,0x0C]); // item maker is wrong?
|
||||
|
||||
let mut inventory = Vec::<item::ItemEntity>::new();
|
||||
inventory.push(wrapped_item.into());
|
||||
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());
|
||||
|
||||
log_in_char(&mut ship, ClientId(1), "a1", "a").await;
|
||||
join_lobby(&mut ship, ClientId(1)).await;
|
||||
create_room(&mut ship, ClientId(1), "room", "").await;
|
||||
|
||||
ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerUseItem(PlayerUseItem {
|
||||
client: 0,
|
||||
target: 0,
|
||||
item_id: 0x10000,
|
||||
})))).await.unwrap().for_each(drop);
|
||||
|
||||
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!(mag.as_bytes() == [0x02,0x00,0x00,0x00,0xF4,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x0C]);
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
// TODO: implement wrapping packet (message 0xD6) (gallons shop quest)
|
||||
// wrap presents
|
||||
#[async_std::test]
|
||||
async fn test_wrap_weapon() {}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_wrap_armor() {}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_wrap_shield() {}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_wrap_unit() {}
|
||||
|
||||
// mag cells are covered in test_mags.rs
|
||||
#[async_std::test]
|
||||
async fn test_wrap_mag() {}
|
||||
|
||||
|
||||
// item combinations?
|
@ -22,7 +22,8 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() {
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -38,7 +39,8 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() {
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: tool
|
||||
tool: tool,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -104,7 +106,8 @@ async fn test_pick_up_item_stack_of_items_not_already_held() {
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -172,6 +175,7 @@ async fn test_pick_up_meseta_when_inventory_full() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -251,6 +255,7 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -264,6 +269,7 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -277,6 +283,7 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -343,6 +350,7 @@ async fn test_can_not_pick_up_item_when_inventory_full() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -361,6 +369,7 @@ async fn test_can_not_pick_up_item_when_inventory_full() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -476,6 +485,7 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -491,6 +501,7 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -671,6 +682,7 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
|
@ -26,7 +26,8 @@ async fn test_use_monomate() {
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: tool
|
||||
tool: tool,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -76,7 +77,8 @@ async fn test_use_monomate_twice() {
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: tool
|
||||
tool: tool,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -129,7 +131,8 @@ async fn test_use_last_monomate() {
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: tool
|
||||
tool: tool,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -174,6 +177,7 @@ async fn test_use_nonstackable_tool() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::MagicStoneIritista,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -214,7 +218,8 @@ async fn test_use_materials() {
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: tool
|
||||
tool: tool,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
|
@ -35,6 +35,7 @@ async fn test_mag_feed() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -180,6 +181,7 @@ async fn test_mag_cell() {
|
||||
item: item::ItemDetail::Tool (
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::FedToMag {
|
||||
@ -193,6 +195,7 @@ async fn test_mag_cell() {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::CellOfMag502,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
|
@ -25,6 +25,7 @@ async fn test_equip_unit_from_equip_menu() {
|
||||
dfp: 0,
|
||||
evp: 0,
|
||||
slots: 4,
|
||||
wrapping: None,
|
||||
}),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
@ -37,6 +38,7 @@ async fn test_equip_unit_from_equip_menu() {
|
||||
item::unit::Unit{
|
||||
unit: item::unit::UnitType::KnightPower,
|
||||
modifier: None,
|
||||
wrapping: None,
|
||||
}),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
@ -49,6 +51,7 @@ async fn test_equip_unit_from_equip_menu() {
|
||||
item::unit::Unit{
|
||||
unit: item::unit::UnitType::KnightPower,
|
||||
modifier: Some(item::unit::UnitModifier::Plus),
|
||||
wrapping: None,
|
||||
}),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
@ -111,6 +114,7 @@ async fn test_unequip_armor_with_units() {
|
||||
dfp: 0,
|
||||
evp: 0,
|
||||
slots: 4,
|
||||
wrapping: None,
|
||||
}),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
@ -123,6 +127,7 @@ async fn test_unequip_armor_with_units() {
|
||||
item::unit::Unit{
|
||||
unit: item::unit::UnitType::KnightPower,
|
||||
modifier: None,
|
||||
wrapping: None,
|
||||
}),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
@ -135,6 +140,7 @@ async fn test_unequip_armor_with_units() {
|
||||
item::unit::Unit{
|
||||
unit: item::unit::UnitType::KnightPower,
|
||||
modifier: Some(item::unit::UnitModifier::Plus),
|
||||
wrapping: None,
|
||||
}),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
@ -188,6 +194,7 @@ async fn test_sort_items() {
|
||||
dfp: 0,
|
||||
evp: 0,
|
||||
slots: 4,
|
||||
wrapping: None,
|
||||
}),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
@ -200,6 +207,7 @@ async fn test_sort_items() {
|
||||
item::unit::Unit{
|
||||
unit: item::unit::UnitType::KnightPower,
|
||||
modifier: None,
|
||||
wrapping: None,
|
||||
}),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
||||
@ -212,6 +220,7 @@ async fn test_sort_items() {
|
||||
item::unit::Unit{
|
||||
unit: item::unit::UnitType::KnightPower,
|
||||
modifier: Some(item::unit::UnitModifier::Plus),
|
||||
wrapping: None,
|
||||
}),
|
||||
location: item::ItemLocation::Inventory {
|
||||
character_id: char1.id,
|
@ -29,6 +29,7 @@ async fn test_item_ids_reset_when_rejoining_rooms() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -48,6 +49,7 @@ async fn test_item_ids_reset_when_rejoining_rooms() {
|
||||
special: None,
|
||||
attrs: [None, None, None],
|
||||
tekked: true,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
|
@ -318,7 +318,8 @@ async fn test_other_clients_see_stacked_purchase() {
|
||||
item::NewItemEntity {
|
||||
item: item::ItemDetail::Tool(
|
||||
item::tool::Tool {
|
||||
tool: item::tool::ToolType::Monomate
|
||||
tool: item::tool::ToolType::Monomate,
|
||||
wrapping: None,
|
||||
}
|
||||
),
|
||||
location: item::ItemLocation::Inventory {
|
||||
@ -522,7 +523,7 @@ async fn test_techs_disappear_from_shop_when_bought() {
|
||||
}).unwrap();
|
||||
}
|
||||
|
||||
// TOOD: this is not deterministic and can randomly fail
|
||||
// TODO: this is not deterministic and can randomly fail
|
||||
#[async_std::test]
|
||||
async fn test_units_disappear_from_shop_when_bought() {
|
||||
let mut entity_gateway = InMemoryGateway::new();
|
||||
|
Loading…
x
Reference in New Issue
Block a user