add remaining modifiers for item types and fix presents?

This commit is contained in:
andy 2021-01-23 04:56:24 +00:00
parent b29bb473d5
commit a238ae3846
16 changed files with 487 additions and 230 deletions

View File

@ -121,7 +121,7 @@ fn main() {
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}),
None,], None,],
tekked: false, tekked: false,
wrapping: Some(item::WrappingPaper::Black_Yellow), wrapping: Some(item::WrappingPaper::BlackYellow),
} }
), ),
location: ItemLocation::Inventory { location: ItemLocation::Inventory {
@ -243,7 +243,8 @@ fn main() {
item: ItemDetail::Tool ( item: ItemDetail::Tool (
item::tool::Tool { item::tool::Tool {
tool: item::tool::ToolType::CellOfMag502, tool: item::tool::ToolType::CellOfMag502,
wrapping: None, // wrapping: None,
wrapping: Some(item::WrappingPaper::PinkYellowGreen),
} }
), ),
location: item::ItemLocation::Consumed, location: item::ItemLocation::Consumed,
@ -292,7 +293,7 @@ fn main() {
shield: item::shield::ShieldType::Barrier, shield: item::shield::ShieldType::Barrier,
dfp: 0, dfp: 0,
evp: 0, evp: 0,
wrapping: Some(item::WrappingPaper::Yellow), wrapping: Some(item::WrappingPaper::Green),
} }
), ),
location: ItemLocation::Inventory { location: ItemLocation::Inventory {
@ -320,7 +321,8 @@ fn main() {
item::unit::Unit { item::unit::Unit {
unit: item::unit::UnitType::PriestMind, unit: item::unit::UnitType::PriestMind,
modifier: Some(item::unit::UnitModifier::Minus), modifier: Some(item::unit::UnitModifier::Minus),
wrapping: None, // wrapping: None,
wrapping: Some(item::WrappingPaper::YellowBlue),
} }
), ),
location: ItemLocation::Inventory { location: ItemLocation::Inventory {
@ -365,6 +367,56 @@ fn main() {
} }
).await.unwrap(); ).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,
}
}
).await.unwrap();
let equipped = item::EquippedEntity { let equipped = item::EquippedEntity {
weapon: Some(item2_w.id), weapon: Some(item2_w.id),
armor: Some(item7_a.id), armor: Some(item7_a.id),
@ -374,7 +426,7 @@ fn main() {
}; };
entity_gateway.set_character_equips(&character.id, &equipped).await.unwrap(); 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_inventory(&character.id, &inventory).await.unwrap();
entity_gateway.set_character_bank(&character.id, &item::BankEntity::default(), item::BankName("".into())).await.unwrap(); entity_gateway.set_character_bank(&character.id, &item::BankEntity::default(), item::BankName("".into())).await.unwrap();
} }

View File

@ -85,6 +85,10 @@ pub trait EntityGateway: Send + Sync + Clone {
unimplemented!(); 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> { async fn add_armor_modifier(&mut self, _item_id: &ItemEntityId, _modifier: armor::ArmorModifier) -> Result<(), GatewayError> {
unimplemented!(); unimplemented!();
} }
@ -101,6 +105,13 @@ pub trait EntityGateway: Send + Sync + Clone {
unimplemented!(); 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> { async fn get_items_by_character(&self, _char_id: &CharacterEntityId) -> Result<Vec<ItemEntity>, GatewayError> {

View File

@ -19,9 +19,12 @@ pub struct InMemoryGateway {
equips: Arc<Mutex<BTreeMap<CharacterEntityId, EquippedEntity>>>, equips: Arc<Mutex<BTreeMap<CharacterEntityId, EquippedEntity>>>,
mag_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<mag::MagModifier>>>>, mag_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<mag::MagModifier>>>>,
weapon_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<weapon::WeaponModifier>>>>, 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>>>>, armor_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<armor::ArmorModifier>>>>,
shield_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<shield::ShieldModifier>>>>, shield_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<shield::ShieldModifier>>>>,
unit_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<unit::UnitModifier>>>>, unit_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<unit::UnitModifier>>>>,
tech_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<tech::TechModifier>>>>,
tool_modifiers: Arc<Mutex<BTreeMap<ItemEntityId, Vec<tool::ToolModifier>>>>,
} }
impl InMemoryGateway { impl InMemoryGateway {
@ -36,9 +39,12 @@ impl InMemoryGateway {
equips: Arc::new(Mutex::new(BTreeMap::new())), equips: Arc::new(Mutex::new(BTreeMap::new())),
mag_modifiers: Arc::new(Mutex::new(BTreeMap::new())), mag_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
weapon_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())), armor_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
shield_modifiers: Arc::new(Mutex::new(BTreeMap::new())), shield_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
unit_modifiers: Arc::new(Mutex::new(BTreeMap::new())), unit_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
tech_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
tool_modifiers: Arc::new(Mutex::new(BTreeMap::new())),
} }
} }
} }
@ -58,8 +64,62 @@ impl InMemoryGateway {
} }
ItemDetail::Weapon(weapon) 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::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::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::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)
},
ItemDetail::Mag(mag) => { 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) { if let Some(mag_modifiers) = self.mag_modifiers.lock().unwrap().get(&item.id) {
for mag_modifier in mag_modifiers.iter() { for mag_modifier in mag_modifiers.iter() {
match mag_modifier { match mag_modifier {
@ -87,12 +147,11 @@ impl InMemoryGateway {
} }
} }
ItemDetail::Mag(mag) ItemDetail::Mag(mag)
} },
_ => { // _ => {
item.item // item.item
} // }
}; };
item item
}) })
}) })
@ -279,6 +338,14 @@ impl EntityGateway for InMemoryGateway {
Ok(()) 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> { async fn add_armor_modifier(&mut self, item_id: &ItemEntityId, modifier: armor::ArmorModifier) -> Result<(), GatewayError> {
self.armor_modifiers.lock().unwrap() self.armor_modifiers.lock().unwrap()
.entry(*item_id) .entry(*item_id)
@ -311,6 +378,22 @@ impl EntityGateway for InMemoryGateway {
Ok(()) 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> { async fn get_character_inventory(&mut self, char_id: &CharacterEntityId) -> Result<InventoryEntity, GatewayError> {
println!("getting inv"); println!("getting inv");
let inventories = self.inventories.lock().unwrap(); let inventories = self.inventories.lock().unwrap();

View File

@ -111,6 +111,18 @@ create table unit_modifier (
created_at timestamptz default current_timestamp 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
);
create table esweapon_modifier ( create table esweapon_modifier (
esweapon integer references item (id) not null, esweapon integer references item (id) not null,
modifier jsonb not null, modifier jsonb not null,

View File

@ -461,6 +461,12 @@ impl Into<tool::Tool> for PgTool {
} }
} }
#[derive(Debug, sqlx::FromRow)]
pub struct PgToolModifier {
pub tool: i32,
pub modifier: sqlx::types::Json<tool::ToolModifier>,
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct PgTechDisk { pub struct PgTechDisk {
tech: tech::Technique, tech: tech::Technique,
@ -488,6 +494,12 @@ impl Into<tech::TechniqueDisk> for PgTechDisk {
} }
} }
#[derive(Debug, sqlx::FromRow)]
pub struct PgTechModifier {
pub tool: i32,
pub modifier: sqlx::types::Json<tech::TechModifier>,
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct PgMag { pub struct PgMag {
mag: mag::MagType, mag: mag::MagType,
@ -563,6 +575,13 @@ impl Into<esweapon::ESWeapon> for PgESWeapon {
} }
} }
#[derive(Debug, sqlx::FromRow)]
pub struct PgESWeaponModifier {
pub esweapon: i32,
pub modifier: sqlx::types::Json<esweapon::ESWeaponModifier>,
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub enum PgItemDetail { pub enum PgItemDetail {
Weapon(PgWeapon), Weapon(PgWeapon),

View File

@ -65,6 +65,23 @@ impl PostgresGateway {
ItemDetail::Weapon(weapon) 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::Mag(mut mag) => { ItemDetail::Mag(mut mag) => {
let q = r#"select mag, modifier, item.item -> 'Tool' as feed, item2.item -> 'Tool' as cell let q = r#"select mag, modifier, item.item -> 'Tool' as feed, item2.item -> 'Tool' as cell
from mag_modifier from mag_modifier
@ -469,6 +486,14 @@ impl EntityGateway for PostgresGateway {
Ok(()) 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> { 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);") sqlx::query("insert into armor_modifier (armor, modifier) values ($1, $2);")
.bind(item_id.0) .bind(item_id.0)
@ -501,6 +526,22 @@ impl EntityGateway for PostgresGateway {
Ok(()) 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> { async fn get_items_by_character(&self, char_id: &CharacterEntityId) -> Result<Vec<ItemEntity>, GatewayError> {
let q = r#"select * from ( let q = r#"select * from (

View File

@ -299,7 +299,7 @@ pub enum ArmorModifier {
} }
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Armor { pub struct Armor {
pub armor: ArmorType, pub armor: ArmorType,
pub dfp: u8, pub dfp: u8,
@ -346,7 +346,7 @@ impl Armor {
pub fn apply_modifier(&mut self, modifier: &ArmorModifier) { pub fn apply_modifier(&mut self, modifier: &ArmorModifier) {
match modifier { match modifier {
ArmorModifier::WrapPresent => {self.wrapping = Some(WrappingPaper::White_Pink)}, ArmorModifier::WrapPresent => {self.wrapping = Some(WrappingPaper::WhitePink)},
ArmorModifier::UnwrapPresent => {self.wrapping = None}, ArmorModifier::UnwrapPresent => {self.wrapping = None},
_ => {}, _ => {},
} }

View File

@ -170,6 +170,14 @@ impl ESWeaponSpecial {
} }
} }
#[derive(Debug, Serialize, Deserialize)]
pub enum ESWeaponModifier {
WrapPresent {
paper: WrappingPaper,
},
UnwrapPresent,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ESWeapon { pub struct ESWeapon {
pub esweapon: ESWeaponType, pub esweapon: ESWeaponType,
@ -274,6 +282,14 @@ impl ESWeapon {
wrapping: wrapping, wrapping: wrapping,
} }
} }
pub fn apply_modifier(&mut self, modifier: &ESWeaponModifier) {
match modifier {
ESWeaponModifier::WrapPresent{paper} => {self.wrapping = Some(*paper)},
ESWeaponModifier::UnwrapPresent => {self.wrapping = None},
_ => {},
}
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -531,7 +531,7 @@ pub enum PhotonBlast {
MyllaYoulla, MyllaYoulla,
} }
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Mag { pub struct Mag {
pub mag: MagType, pub mag: MagType,
def: u16, def: u16,
@ -1133,7 +1133,7 @@ impl Mag {
pub fn apply_modifier(&mut self, modifier: &MagModifier) { pub fn apply_modifier(&mut self, modifier: &MagModifier) {
match modifier { match modifier {
MagModifier::WrapPresent => {self.wrapping = WrappingPaper::from(self.color % 10)}, // prevents mag color from crashing wrapping papers 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}, MagModifier::UnwrapPresent => {self.wrapping = None},
_ => {}, // TODO: other modifiers are already handled elsewhere. do they need to be moved here? _ => {}, // TODO: other modifiers are already handled elsewhere. do they need to be moved here?
} }

View File

@ -160,33 +160,32 @@ impl ItemDetail {
} }
} }
pub fn is_wrapped(self) -> bool { pub fn is_wrapped(&mut self) -> bool {
match self { match self {
ItemDetail::Weapon(w) => w.wrapping.is_some(), ItemDetail::Weapon(w) => w.wrapping.is_some(),
// ItemDetail::Armor(a) => a.wrapping.is_some(), ItemDetail::Armor(a) => a.wrapping.is_some(),
// ItemDetail::Shield(s) => s.wrapping.is_some(), ItemDetail::Shield(s) => s.wrapping.is_some(),
// ItemDetail::Unit(u) => u.wrapping.is_some(), ItemDetail::Unit(u) => u.wrapping.is_some(),
// ItemDetail::Tool(t) => t.wrapping.is_some(), ItemDetail::Tool(t) => t.wrapping.is_some(),
// ItemDetail::TechniqueDisk(d) => d.wrapping.is_some(), ItemDetail::TechniqueDisk(d) => d.wrapping.is_some(),
// ItemDetail::Mag(m) => m.wrapping.is_some(), ItemDetail::Mag(m) => m.wrapping.is_some(),
// ItemDetail::ESWeapon(e) => e.wrapping.is_some(), ItemDetail::ESWeapon(e) => e.wrapping.is_some(),
_ => false _ => unreachable!(),
} }
} }
pub fn unwrap_present(self) -> ItemDetail { pub fn unwrap_present(&mut self) {
match self { match self {
ItemDetail::Weapon(mut w) => w.wrapping = None, ItemDetail::Weapon(ref mut w) => w.wrapping = None,
// ItemDetail::Armor(a) => a.wrapping.is_some(), ItemDetail::Armor(ref mut a) => a.wrapping = None,
// ItemDetail::Shield(s) => s.wrapping.is_some(), ItemDetail::Shield(ref mut s) => s.wrapping = None,
// ItemDetail::Unit(u) => u.wrapping.is_some(), ItemDetail::Unit(ref mut u) => u.wrapping = None,
// ItemDetail::Tool(t) => t.wrapping.is_some(), ItemDetail::Tool(ref mut t) => t.wrapping = None,
// ItemDetail::TechniqueDisk(d) => d.wrapping.is_some(), ItemDetail::TechniqueDisk(ref mut d) => d.wrapping = None,
// ItemDetail::Mag(m) => m.wrapping.is_some(), ItemDetail::Mag(ref mut m) => m.wrapping = None,
// ItemDetail::ESWeapon(e) => e.wrapping.is_some(), ItemDetail::ESWeapon(ref mut e) => e.wrapping = None,
_ => {}, _ => unreachable!(),
}; };
self
} }
} }
@ -229,7 +228,7 @@ impl InventoryItemEntity {
_ => self, _ => 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> { pub fn with_individual<F: Fn(&ItemEntity) -> T, T>(&self, func: F) -> Option<T> {
match self { match self {
InventoryItemEntity::Individual(item) => Some(func(item)), InventoryItemEntity::Individual(item) => Some(func(item)),
@ -237,7 +236,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> { pub fn with_stacked<F: Fn(&Vec<ItemEntity>) -> T, T>(&self, func: F) -> Option<T> {
match self { match self {
InventoryItemEntity::Stacked(items) => Some(func(items)), InventoryItemEntity::Stacked(items) => Some(func(items)),
@ -319,7 +317,6 @@ impl BankItemEntity {
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct BankEntity { pub struct BankEntity {
//pub items: [Option<CharacterBankItem>; 30],
pub items: Vec<BankItemEntity>, pub items: Vec<BankItemEntity>,
} }
@ -333,12 +330,12 @@ impl BankEntity {
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum WrappingPaper { pub enum WrappingPaper {
White_Pink, // 0 WhitePink, // 0
Yellow_Blue, // 1 YellowBlue, // 1
Black_Yellow, // 2 BlackYellow, // 2
LightBlue_Orange, // 3 LightBlueOrange, // 3
Pink_YellowGreen, // 4 PinkYellowGreen, // 4
Red_Green, // 5 RedGreen, // 5
Magenta, // 6 Magenta, // 6
Blue, // 7 Blue, // 7
Yellow, // 8 Yellow, // 8
@ -353,12 +350,12 @@ impl WrappingPaper {
pub fn from(data: u8) -> Option<WrappingPaper> { pub fn from(data: u8) -> Option<WrappingPaper> {
match data { match data {
0 => Some(WrappingPaper::White_Pink), 0 => Some(WrappingPaper::WhitePink),
1 => Some(WrappingPaper::Yellow_Blue), 1 => Some(WrappingPaper::YellowBlue),
2 => Some(WrappingPaper::Black_Yellow), 2 => Some(WrappingPaper::BlackYellow),
3 => Some(WrappingPaper::LightBlue_Orange), 3 => Some(WrappingPaper::LightBlueOrange),
4 => Some(WrappingPaper::Pink_YellowGreen), 4 => Some(WrappingPaper::PinkYellowGreen),
5 => Some(WrappingPaper::Red_Green), 5 => Some(WrappingPaper::RedGreen),
6 => Some(WrappingPaper::Magenta), 6 => Some(WrappingPaper::Magenta),
7 => Some(WrappingPaper::Blue), 7 => Some(WrappingPaper::Blue),
8 => Some(WrappingPaper::Yellow), 8 => Some(WrappingPaper::Yellow),

View File

@ -572,9 +572,8 @@ impl Shield {
pub fn apply_modifier(&mut self, modifier: &ShieldModifier) { pub fn apply_modifier(&mut self, modifier: &ShieldModifier) {
match modifier { match modifier {
ShieldModifier::WrapPresent{paper} => {self.wrapping = Some(*paper)}, ShieldModifier::WrapPresent{paper} => {self.wrapping = Some(*paper)}, // TODO: client always shows shields in default paper colour ?
ShieldModifier::UnwrapPresent => {self.wrapping = None}, ShieldModifier::UnwrapPresent => {self.wrapping = None},
_ => {},
} }
} }
} }

View File

@ -76,6 +76,14 @@ impl Technique {
} }
} }
#[derive(Debug, Serialize)]
pub enum TechModifier {
WrapPresent {
paper: WrappingPaper,
},
UnwrapPresent,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct TechniqueDisk { pub struct TechniqueDisk {
pub tech: Technique, pub tech: Technique,
@ -96,4 +104,11 @@ impl TechniqueDisk {
}; };
result result
} }
pub fn apply_modifier(&mut self, modifier: &TechModifier) {
match modifier {
TechModifier::WrapPresent{paper} => {self.wrapping = Some(*paper)},
TechModifier::UnwrapPresent => {self.wrapping = None},
}
}
} }

View File

@ -648,6 +648,13 @@ impl ToolType {
} }
} }
#[derive(Debug, Serialize)]
pub enum ToolModifier {
WrapPresent {
paper: WrappingPaper,
},
UnwrapPresent,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Tool { pub struct Tool {
@ -696,4 +703,11 @@ impl Tool {
pub fn max_stack(&self) -> usize { pub fn max_stack(&self) -> usize {
self.tool.max_stack() 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},
}
}
} }

View File

@ -6,9 +6,11 @@ use crate::entity::item::{ItemEntityId, ItemDetail, ItemEntity, ItemType, ItemLo
use crate::entity::item::tool::Tool; use crate::entity::item::tool::Tool;
use crate::entity::item::mag::Mag; use crate::entity::item::mag::Mag;
use crate::entity::item::weapon::Weapon; 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::armor::Armor; // TODO: cleanup uses
use crate::entity::item::shield::Shield; use crate::entity::item::shield::Shield;
use crate::entity::item::unit::Unit; use crate::entity::item::unit::Unit;
use crate::entity::item::tech::TechniqueDisk;
use crate::ship::items::{ClientItemId, BankItem, BankItemHandle}; use crate::ship::items::{ClientItemId, BankItem, BankItemHandle};
use crate::ship::items::floor::{IndividualFloorItem, StackedFloorItem}; use crate::ship::items::floor::{IndividualFloorItem, StackedFloorItem};
@ -48,10 +50,6 @@ impl IndividualInventoryItem {
} }
} }
pub fn is_wrapped(self) -> bool {
self.clone().item.is_wrapped()
}
pub fn weapon_mut(&mut self) -> Option<&mut Weapon> { pub fn weapon_mut(&mut self) -> Option<&mut Weapon> {
match self.item { match self.item {
ItemDetail::Weapon(ref mut weapon) => Some(weapon), ItemDetail::Weapon(ref mut weapon) => Some(weapon),
@ -59,6 +57,13 @@ impl IndividualInventoryItem {
} }
} }
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> { pub fn armor_mut(&mut self) -> Option<&mut Armor> {
match self.item { match self.item {
ItemDetail::Armor(ref mut armor) => Some(armor), ItemDetail::Armor(ref mut armor) => Some(armor),
@ -80,6 +85,27 @@ impl IndividualInventoryItem {
} }
} }
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)] #[derive(Debug, Clone)]
@ -104,8 +130,11 @@ impl StackedInventoryItem {
} }
pub fn is_wrapped(&self) -> bool { pub fn is_wrapped(&self) -> bool {
// TODO: add wrapping to Tool self.tool.wrapping.is_some()
false }
pub fn unwrap_present(&mut self) {
self.tool.wrapping = None;
} }
} }
@ -281,26 +310,19 @@ impl InventoryItem {
} }
} }
pub fn is_wrapped(self) -> bool { // 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 { match self {
InventoryItem::Individual(i) => i.is_wrapped(), InventoryItem::Individual(i) => i.is_wrapped(),
InventoryItem::Stacked(s) => s.is_wrapped(), InventoryItem::Stacked(s) => s.is_wrapped(),
} }
} }
pub fn unwrap_present(self) -> InventoryItem { pub fn unwrap_present(&mut self) {
match self { match self {
InventoryItem::Individual(i) => InventoryItem::Individual(IndividualInventoryItem { InventoryItem::Individual(i) => i.unwrap_present(),
entity_id: i.entity_id, InventoryItem::Stacked(s) => s.unwrap_present(),
item_id: i.item_id, };
item: i.item.unwrap_present(),
}),
InventoryItem::Stacked(s) => InventoryItem::Stacked(StackedInventoryItem {
entity_ids: s.entity_ids,
item_id: s.item_id,
tool: s.tool, // s.unwrap_present()
}),
}
} }
} }

View File

@ -6,11 +6,7 @@ use crate::entity::character::{CharacterEntity, CharacterEntityId, TechLevel};
use crate::entity::item::{ItemDetail, ItemLocation, BankName}; use crate::entity::item::{ItemDetail, ItemLocation, BankName};
use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity, EquippedEntity, InventoryEntity, BankItemEntity, BankEntity, ItemType}; use crate::entity::item::{Meseta, NewItemEntity, ItemEntity, InventoryItemEntity, EquippedEntity, InventoryEntity, BankItemEntity, BankEntity, ItemType};
use crate::entity::item::tool::{Tool, ToolType}; use crate::entity::item::tool::{Tool, ToolType};
use crate::entity::item::unit; use crate::entity::item::{unit, weapon, armor, shield, mag, tech, tool, esweapon};
use crate::entity::item::weapon;
use crate::entity::item::armor;
use crate::entity::item::shield;
use crate::entity::item::mag;
use crate::ship::map::MapArea; use crate::ship::map::MapArea;
use crate::ship::ship::ItemDropLocation; use crate::ship::ship::ItemDropLocation;
use crate::ship::drops::{ItemDrop, ItemDropType}; use crate::ship::drops::{ItemDrop, ItemDropType};
@ -506,7 +502,7 @@ impl ItemManager {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; 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 used_item = inventory.get_item_handle_by_id(item_id).ok_or(ItemManagerError::NoSuchItemId(item_id))?;
let consumed_item = used_item.consume(amount)?; let consumed_item = used_item.consume(amount)?;
println!("consumed some item");
if let ItemDetail::TechniqueDisk(tech_disk) = consumed_item.item() { if let ItemDetail::TechniqueDisk(tech_disk) = consumed_item.item() {
// TODO: validate tech level in packet is in bounds [1..30] // TODO: validate tech level in packet is in bounds [1..30]
character.techs.set_tech(tech_disk.tech, TechLevel(tech_disk.level as u8)); character.techs.set_tech(tech_disk.tech, TechLevel(tech_disk.level as u8));
@ -645,39 +641,29 @@ impl ItemManager {
let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?;
let mut used_item_handle = inventory.get_item_handle_by_id(client_item_id).ok_or(ItemManagerError::ItemIdNotInInventory(client_item_id))?; 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)?; 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() { match used_item.item_type() {
ItemType::Armor(_) => { ItemType::Armor(_) => {
let actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.armor_mut().ok_or(ItemManagerError::CannotGetMutItem)?; let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.armor_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
if actual_used_item.wrapping.is_some() {
actual_used_item.apply_modifier(&armor::ArmorModifier::UnwrapPresent);
entity_gateway.add_armor_modifier(&used_item.entity_ids()[0], armor::ArmorModifier::UnwrapPresent).await?;
} else {
// combining / unsealing? // combining / unsealing?
}
}, },
ItemType::ESWeapon(_) => { 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::Mag(_) => { ItemType::Mag(_) => {
let actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.mag_mut().ok_or(ItemManagerError::CannotGetMutItem)?; let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.mag_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
if actual_used_item.wrapping.is_some() {
actual_used_item.apply_modifier(&mag::MagModifier::UnwrapPresent);
entity_gateway.add_mag_modifier(&used_item.entity_ids()[0], mag::MagModifier::UnwrapPresent).await?;
} else {
// combining / unsealing? // combining / unsealing?
}
}, },
ItemType::Shield(_) => { ItemType::Shield(_) => {
let actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.shield_mut().ok_or(ItemManagerError::CannotGetMutItem)?; let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.shield_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
if actual_used_item.wrapping.is_some() {
actual_used_item.apply_modifier(&shield::ShieldModifier::UnwrapPresent);
entity_gateway.add_shield_modifier(&used_item.entity_ids()[0], shield::ShieldModifier::UnwrapPresent).await?;
} else {
// combining / unsealing? // combining / unsealing?
}
}, },
ItemType::TechniqueDisk(_) => { ItemType::TechniqueDisk(_) => {
let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.tech_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
// combining / unsealing?
}, },
ItemType::Tool(_) => { ItemType::Tool(_) => {
let consumed_item = used_item.as_consumed_item(); let consumed_item = used_item.as_consumed_item();
@ -779,30 +765,20 @@ impl ItemManager {
}, },
_ => {} _ => {}
} }
} },
_ => {} _ => {},
} }
}, },
ItemType::Unit(_) => { ItemType::Unit(_) => {
let actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.unit_mut().ok_or(ItemManagerError::CannotGetMutItem)?; let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.unit_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
if actual_used_item.wrapping.is_some() {
actual_used_item.apply_modifier(&unit::UnitModifier::UnwrapPresent);
entity_gateway.add_unit_modifier(&used_item.entity_ids()[0], unit::UnitModifier::UnwrapPresent).await?;
} else {
// combining / unsealing? // combining / unsealing?
}
}, },
ItemType::Weapon(_) => { ItemType::Weapon(_) => {
let actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.weapon_mut().ok_or(ItemManagerError::CannotGetMutItem)?; let _actual_used_item = used_item.individual_mut().ok_or(ItemManagerError::CannotGetMutItem)?.weapon_mut().ok_or(ItemManagerError::CannotGetMutItem)?;
if actual_used_item.wrapping.is_some() {
actual_used_item.apply_modifier(&weapon::WeaponModifier::UnwrapPresent);
entity_gateway.add_weapon_modifier(&used_item.entity_ids()[0], weapon::WeaponModifier::UnwrapPresent).await?;
} else {
// combining / unsealing? // combining / unsealing?
}
}, },
} }
}
entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?;
Ok(()) Ok(())
} }

View File

@ -267,7 +267,7 @@ async fn test_unwrap_mag() {
}).unwrap(); }).unwrap();
} }
// TODO: implement wrapping packet (gallons shop quest) // TODO: implement wrapping packet (message 0xD6) (gallons shop quest)
// wrap presents // wrap presents
#[async_std::test] #[async_std::test]
async fn test_wrap_weapon() {} async fn test_wrap_weapon() {}