diff --git a/src/bin/main.rs b/src/bin/main.rs index b96552a..c4eb697 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -116,7 +116,7 @@ fn main() { Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), None,], tekked: true, - kills: Some(22995), + kills: Some(22998), } ), }).await.unwrap(); @@ -124,8 +124,8 @@ fn main() { NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { - weapon: item::weapon::WeaponType::Handgun, - grind: 5, + weapon: item::weapon::WeaponType::Club, + grind: 10, special: Some(item::weapon::WeaponSpecial::Charge), attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), @@ -203,7 +203,7 @@ fn main() { item::NewItemEntity { item: ItemDetail::Tool ( item::tool::Tool { - tool: item::tool::ToolType::CellOfMag502, + tool: item::tool::ToolType::MagicRockMoola, } ), }).await.unwrap(); @@ -261,6 +261,7 @@ fn main() { item::unit::Unit { unit: item::unit::UnitType::Limiter, modifier: None, + kills: Some(19999), } ), } @@ -270,7 +271,8 @@ fn main() { item: ItemDetail::Unit( item::unit::Unit { unit: item::unit::UnitType::PriestMind, - modifier: Some(item::unit::UnitModifier::Plus), + modifier: Some(item::unit::UnitModifier::Minus), + kills: None, } ), } @@ -281,6 +283,7 @@ fn main() { item::unit::Unit { unit: item::unit::UnitType::PriestMind, modifier: Some(item::unit::UnitModifier::Minus), + kills: None, } ), } @@ -291,6 +294,7 @@ fn main() { item::unit::Unit { unit: item::unit::UnitType::PriestMind, modifier: Some(item::unit::UnitModifier::MinusMinus), + kills: None, } ), } diff --git a/src/entity/gateway/postgres/models.rs b/src/entity/gateway/postgres/models.rs index bbb7e88..e1e8950 100644 --- a/src/entity/gateway/postgres/models.rs +++ b/src/entity/gateway/postgres/models.rs @@ -395,6 +395,7 @@ impl From for shield::Shield { pub struct PgUnit { unit: unit::UnitType, modifier: Option, + kills: Option, } impl From for PgUnit { @@ -402,6 +403,7 @@ impl From for PgUnit { PgUnit { unit: other.unit, modifier: other.modifier, + kills: other.kills, } } } @@ -411,6 +413,7 @@ impl From for unit::Unit { unit::Unit { unit: other.unit, modifier: other.modifier, + kills: other.kills, } } } diff --git a/src/entity/item/mod.rs b/src/entity/item/mod.rs index b472594..26bbd60 100644 --- a/src/entity/item/mod.rs +++ b/src/entity/item/mod.rs @@ -184,6 +184,7 @@ impl ItemDetail { } } + // TODO: delete this pub fn increment_kill_counter(&self) { match self { ItemDetail::Weapon(w) => {}, diff --git a/src/entity/item/unit.rs b/src/entity/item/unit.rs index 371f450..99ebc17 100644 --- a/src/entity/item/unit.rs +++ b/src/entity/item/unit.rs @@ -321,6 +321,10 @@ impl UnitType { _ => Err(ItemParseError::InvalidUnitType), } } + + pub fn has_counter(&self) -> bool { + matches!(self, UnitType::Limiter) + } } #[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)] @@ -335,6 +339,7 @@ pub enum UnitModifier { pub struct Unit { pub unit: UnitType, pub modifier: Option, + pub kills: Option, } @@ -361,11 +366,16 @@ impl Unit { }, } } + if self.unit.has_counter() { + result[10..12].copy_from_slice(&self.kills.unwrap_or(0u16).to_be_bytes()); + result[10] += 0x80; + } result } pub fn from_bytes(data: [u8; 16]) -> Result { - let u = UnitType::parse_type([data[0], data[1], data[2]]); + let u = UnitType::parse_type([data[0], data[1], data[2]]); + let mut k = None; if let Ok(u) = u { let m = match u16::from_le_bytes([data[6], data[7]]) { 0x02 => Some(UnitModifier::PlusPlus), @@ -375,9 +385,14 @@ impl Unit { _ => None, }; + if data[10] & 0x80 == 0x80 { + k = Some(u16::from_be_bytes([data[10] - 0x80, data[11]])); + } + Ok(Unit{ unit: u, modifier: m, + kills: k, }) } else { @@ -456,4 +471,10 @@ impl Unit { _ => 0, } } + + pub fn increment_kill_counter(&mut self) { + if let Some(kills) = self.kills { + self.kills = Some(kills + 1); + } + } } diff --git a/src/entity/item/weapon.rs b/src/entity/item/weapon.rs index db4f8af..64f7e88 100644 --- a/src/entity/item/weapon.rs +++ b/src/entity/item/weapon.rs @@ -1541,7 +1541,8 @@ impl Weapon { if self.weapon.has_counter() { result[10..12].copy_from_slice(&self.kills.unwrap_or(0u16).to_be_bytes()); result[10] += 0x80; - + // TODO: what to do with the 3rd attr? + // self.attrs[2] = None; } else { result[10..12].copy_from_slice(&self.attrs[2].map(|s| s.value()).unwrap_or([0,0])); } @@ -1588,9 +1589,9 @@ impl Weapon { } } - if data[10] >= 0x80 { + if data[10] & 0x80 == 0x80 { attrs[2] = None; - kills = Some(u16::from_be_bytes([data[10], data[11]])); + kills = Some(u16::from_be_bytes([data[10] - 0x80, data[11]])); } Ok(Weapon { diff --git a/src/ship/drops/generic_unit.rs b/src/ship/drops/generic_unit.rs index 73bc4a6..eabde29 100644 --- a/src/ship/drops/generic_unit.rs +++ b/src/ship/drops/generic_unit.rs @@ -89,6 +89,7 @@ impl GenericUnitTable { ItemDropType::Unit(Unit { unit: unit_type, modifier: unit_modifier, + kills: None, }) }) } @@ -116,6 +117,7 @@ mod test { assert!(gut.get_drop(&area, &mut rng) == Some(ItemDropType::Unit(Unit { unit: unit, modifier: umod, + kills: None, }))); } } diff --git a/src/ship/drops/rare_drop_table.rs b/src/ship/drops/rare_drop_table.rs index af7b541..5104a7c 100644 --- a/src/ship/drops/rare_drop_table.rs +++ b/src/ship/drops/rare_drop_table.rs @@ -126,6 +126,7 @@ impl RareDropTable { ItemDropType::Unit(Unit { unit, modifier: None, + kills: None, }) }, RareDropItem::Tool(tool) => { diff --git a/src/ship/items/inventory.rs b/src/ship/items/inventory.rs index 5e25340..9b175f7 100644 --- a/src/ship/items/inventory.rs +++ b/src/ship/items/inventory.rs @@ -7,6 +7,7 @@ use crate::entity::item::tool::{Tool, ToolType}; use crate::entity::item::mag::Mag; use crate::entity::item::weapon::Weapon; use crate::ship::items::{ClientItemId, BankItem, BankItemHandle, ItemManagerError}; +use crate::entity::item::unit::Unit; use crate::ship::items::floor::{IndividualFloorItem, StackedFloorItem}; use crate::ship::shops::{ShopItem, ArmorShopItem, ToolShopItem, WeaponShopItem}; @@ -52,6 +53,13 @@ impl IndividualInventoryItem { _ => None } } + + pub fn unit_mut(&mut self) -> Option<&mut Unit> { + match self.item { + ItemDetail::Unit(ref mut unit) => Some(unit), + _ => None + } + } } #[derive(Debug, Clone)] diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index c852ad1..8b83b22 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -83,6 +83,8 @@ pub enum ItemManagerError { #[error("invalid trade")] InvalidTrade, EntityIdNotInInventory(ItemEntityId), + WeaponCannotCombine, + NotEnoughKills(u16), } impl std::convert::From> for ItemManagerError @@ -696,7 +698,6 @@ impl ItemManager { match &used_item.item() { ItemDetail::Weapon(_w) => { // something like when items are used to combine/transform them? - //_ => {} }, ItemDetail::Tool(t) => { match t.tool { @@ -793,7 +794,7 @@ impl ItemManager { ToolType::LibertaKit => { use_tool::liberta_kit(entity_gateway, &used_item, inventory).await?; }, - _ => {} + _ => {}, } } _ => {} @@ -1382,33 +1383,39 @@ impl ItemAction for TradeMeseta { equipped_items: &EquippedEntity) -> Result<(), anyhow::Error> { let inventory = self.character_inventory.get_mut(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; + // weapon if let Some(weapon_entity) = equipped_items.weapon { - println!("updating weapon kill counter for weapon {:?}", weapon_entity); - // weapon_entity = &InventoryItem - - // let weapon_id = weapon_entity.item_id(); let weapon_id = inventory.get_item_by_entity_id(weapon_entity).ok_or(ItemManagerError::EntityIdNotInInventory(weapon_entity))?.item_id(); let mut weapon_handle = inventory.get_item_handle_by_id(weapon_id).ok_or(ItemManagerError::NoSuchItemId(weapon_id))?; - // weapon_handle = InventoryItemHandle - let individual_item = weapon_handle.item_mut() + let individual_item_w = weapon_handle.item_mut() .ok_or(ItemManagerError::NoSuchItemId(weapon_id))? .individual_mut() .ok_or(ItemManagerError::WrongItemType(weapon_id))?; - let weapon = individual_item + let weapon = individual_item_w .weapon_mut() .ok_or(ItemManagerError::WrongItemType(weapon_id))?; weapon.increment_kill_counter(); entity_gateway.increment_kill_counter(&weapon_entity).await?; - entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; } - // for units in equipped_items.unit { - // if let Some(unit_id) = units { - // println!("UNIMPLEMENTED - updating unit kill counter for unit {:?}", unit_id); - // // entity_gateway.increase_kill_counter(&unit_id).await?; - // // let unit = inventory.get_item_by_entity_id(&unit_id) - // } - // } + // limiter + for units in equipped_items.unit { + if let Some(unit_entity) = units { + let unit_id = inventory.get_item_by_entity_id(unit_entity).ok_or(ItemManagerError::EntityIdNotInInventory(unit_entity))?.item_id(); + let mut unit_handle = inventory.get_item_handle_by_id(unit_id).ok_or(ItemManagerError::NoSuchItemId(unit_id))?; + let individual_item_u = unit_handle.item_mut() + .ok_or(ItemManagerError::NoSuchItemId(unit_id))? + .individual_mut() + .ok_or(ItemManagerError::WrongItemType(unit_id))?; + let unit = individual_item_u + .unit_mut() + .ok_or(ItemManagerError::WrongItemType(unit_id))?; + + unit.increment_kill_counter(); + entity_gateway.increment_kill_counter(&unit_entity).await?; + } + } + entity_gateway.set_character_inventory(&character.id, &inventory.as_inventory_entity(&character.id)).await?; Ok(()) } } diff --git a/src/ship/items/mod.rs b/src/ship/items/mod.rs index 8a917a8..aa88cf7 100644 --- a/src/ship/items/mod.rs +++ b/src/ship/items/mod.rs @@ -4,6 +4,7 @@ pub mod inventory; pub mod manager; pub mod transaction; pub mod use_tool; +// pub mod use_weapon; use serde::{Serialize, Deserialize}; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, derive_more::Display)] diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index 41fa90b..834657f 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -399,7 +399,7 @@ where } pub async fn player_killed_monster( id: ClientId, - pkt: &KillMonster, + _pkt: &KillMonster, // use this later for turbo logging? entity_gateway: &mut EG, clients: &Clients, item_manager: &mut ItemManager) diff --git a/src/ship/shops/armor.rs b/src/ship/shops/armor.rs index b85fe12..d13b2d1 100644 --- a/src/ship/shops/armor.rs +++ b/src/ship/shops/armor.rs @@ -92,6 +92,7 @@ impl ShopItem for ArmorShopItem { ItemDetail::Unit(Unit { unit: unit.unit, modifier: None, + kills: None, }) }, }