Browse Source

add kill counters to units (limiter)

kill_counters
andy 3 years ago
parent
commit
527cf50b9d
  1. 14
      src/bin/main.rs
  2. 3
      src/entity/gateway/postgres/models.rs
  3. 1
      src/entity/item/mod.rs
  4. 21
      src/entity/item/unit.rs
  5. 7
      src/entity/item/weapon.rs
  6. 2
      src/ship/drops/generic_unit.rs
  7. 1
      src/ship/drops/rare_drop_table.rs
  8. 8
      src/ship/items/inventory.rs
  9. 41
      src/ship/items/manager.rs
  10. 1
      src/ship/items/mod.rs
  11. 2
      src/ship/packet/handler/message.rs
  12. 1
      src/ship/shops/armor.rs

14
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,
}
),
}

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

@ -395,6 +395,7 @@ impl From<PgShield> for shield::Shield {
pub struct PgUnit {
unit: unit::UnitType,
modifier: Option<unit::UnitModifier>,
kills: Option<u16>,
}
impl From<unit::Unit> for PgUnit {
@ -402,6 +403,7 @@ impl From<unit::Unit> for PgUnit {
PgUnit {
unit: other.unit,
modifier: other.modifier,
kills: other.kills,
}
}
}
@ -411,6 +413,7 @@ impl From<PgUnit> for unit::Unit {
unit::Unit {
unit: other.unit,
modifier: other.modifier,
kills: other.kills,
}
}
}

1
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) => {},

21
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<UnitModifier>,
pub kills: Option<u16>,
}
@ -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<Unit, ItemParseError> {
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);
}
}
}

7
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 {

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

1
src/ship/drops/rare_drop_table.rs

@ -126,6 +126,7 @@ impl RareDropTable {
ItemDropType::Unit(Unit {
unit,
modifier: None,
kills: None,
})
},
RareDropItem::Tool(tool) => {

8
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)]

41
src/ship/items/manager.rs

@ -83,6 +83,8 @@ pub enum ItemManagerError {
#[error("invalid trade")]
InvalidTrade,
EntityIdNotInInventory(ItemEntityId),
WeaponCannotCombine,
NotEnoughKills(u16),
}
impl<E> std::convert::From<TransactionError<E>> 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<EG: EntityGateway> ItemAction<EG> 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(())
}
}

1
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)]

2
src/ship/packet/handler/message.rs

@ -399,7 +399,7 @@ where
}
pub async fn player_killed_monster<EG>( id: ClientId,
pkt: &KillMonster,
_pkt: &KillMonster, // use this later for turbo logging?
entity_gateway: &mut EG,
clients: &Clients,
item_manager: &mut ItemManager)

1
src/ship/shops/armor.rs

@ -92,6 +92,7 @@ impl ShopItem for ArmorShopItem {
ItemDetail::Unit(Unit {
unit: unit.unit,
modifier: None,
kills: None,
})
},
}

Loading…
Cancel
Save