#![allow(dead_code)] pub mod weapon; pub mod armor; pub mod shield; pub mod tool; pub mod tech; pub mod unit; pub mod mag; pub mod esweapon; use serde::{Serialize, Deserialize}; use crate::entity::character::CharacterEntityId; use crate::entity::room::RoomEntityId; use crate::ship::map::MapArea; use crate::ship::monster::MonsterType; use crate::ship::drops::ItemDropType; #[derive(PartialEq, Eq, Copy, Clone, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] pub struct ItemEntityId(pub u32); #[derive(Hash, PartialEq, Eq, Debug, Clone)] pub struct ItemId(u32); #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, derive_more::Display)] pub struct BankName(pub String); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] pub struct TradeId(pub u32); #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, derive_more::Display)] pub enum BankIdentifier { Character, Shared(BankName), } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum ItemNote { CharacterCreation { character_id: CharacterEntityId, }, EnemyDrop { character_id: CharacterEntityId, room_id: RoomEntityId, monster_type: MonsterType, map_area: MapArea, x: f32, y: f32, z: f32, }, BoxDrop { character_id: CharacterEntityId, room_id: RoomEntityId, map_area: MapArea, x: f32, y: f32, z: f32, }, Pickup { character_id: CharacterEntityId, }, PlayerDrop { character_id: CharacterEntityId, map_area: MapArea, x: f32, y: f32, z: f32, }, Consumed { character_id: CharacterEntityId, }, FedToMag { character_id: CharacterEntityId, mag: ItemEntityId, }, BoughtAtShop { character_id: CharacterEntityId, }, SoldToShop { character_id: CharacterEntityId, }, Trade { trade_id: TradeId, character_to: CharacterEntityId, character_from: CharacterEntityId, }, Withdraw { character_id: CharacterEntityId, bank: BankIdentifier, }, Deposit { character_id: CharacterEntityId, bank: BankIdentifier, }, FloorLimitReached { map_area: MapArea, }, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct Meseta(pub u32); impl Meseta { pub fn as_bytes(&self) -> [u8; 16] { let mut result = [0; 16]; result[0] = 4; result[12..16].copy_from_slice(&u32::to_le_bytes(self.0)); result } } #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum ItemType { Weapon(weapon::WeaponType), Armor(armor::ArmorType), Shield(shield::ShieldType), Unit(unit::UnitType), Tool(tool::ToolType), TechniqueDisk(tech::Technique), Mag(mag::MagType), ESWeapon(esweapon::ESWeaponType), } #[derive(Clone, Debug, PartialEq, Eq)] pub enum ItemParseError { InvalidBytes } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum ItemDetail { Weapon(weapon::Weapon), Armor(armor::Armor), Shield(shield::Shield), Unit(unit::Unit), Tool(tool::Tool), TechniqueDisk(tech::TechniqueDisk), Mag(mag::Mag), ESWeapon(esweapon::ESWeapon), } impl ItemDetail { pub fn is_stackable(&self) -> bool { match self { ItemDetail::Tool(tool) => tool.tool.is_stackable(), _ => false, } } pub fn item_type(&self) -> ItemType { match self { ItemDetail::Weapon(w) => ItemType::Weapon(w.weapon), ItemDetail::Armor(a) => ItemType::Armor(a.armor), ItemDetail::Shield(s) => ItemType::Shield(s.shield), ItemDetail::Unit(u) => ItemType::Unit(u.unit), ItemDetail::Tool(t) => ItemType::Tool(t.tool), ItemDetail::TechniqueDisk(d) => ItemType::TechniqueDisk(d.tech), ItemDetail::Mag(m) => ItemType::Mag(m.mag), ItemDetail::ESWeapon(e) => ItemType::ESWeapon(e.esweapon), } } pub fn parse_item_from_bytes(data: [u8; 16]) -> Option { let item_type = weapon::WeaponType::parse_type([data[0],data[1],data[2]]).map(ItemType::Weapon) .or_else(|_| armor::ArmorType::parse_type([data[0],data[1],data[2]]).map(ItemType::Armor)) .or_else(|_| shield::ShieldType::parse_type([data[0],data[1],data[2]]).map(ItemType::Shield)) .or_else(|_| unit::UnitType::parse_type([data[0],data[1],data[2]]).map(ItemType::Unit)) .or_else(|_| mag::MagType::parse_type([data[0],data[1],data[2]]).map(ItemType::Mag)) .or_else(|_| tool::ToolType::parse_type([data[0],data[1],data[2]]).map(ItemType::Tool)) .or_else(|_| esweapon::ESWeaponType::parse_type([data[0],data[1],data[2]]).map(ItemType::ESWeapon)).ok()?; match item_type { ItemType::Weapon(_w) => Some(ItemDropType::Weapon(weapon::Weapon::from_bytes(data).ok()?)), ItemType::Armor(_a) => Some(ItemDropType::Armor(armor::Armor::from_bytes(data).ok()?)), ItemType::Shield(_s) => Some(ItemDropType::Shield(shield::Shield::from_bytes(data).ok()?)), ItemType::Unit(_u) => Some(ItemDropType::Unit(unit::Unit::from_bytes(data).ok()?)), ItemType::Mag(_m) => Some(ItemDropType::Mag(mag::Mag::from_bytes(data).ok()?)), ItemType::Tool(_t) => Some(ItemDropType::Tool(tool::Tool::from_bytes(data).ok()?)), _ => None, } } pub fn as_client_bytes(&self) -> [u8; 16] { match self { 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(), } } pub fn as_tool(self) -> Option { match self { ItemDetail::Tool(tool) => Some(tool), _ => None, } } pub fn tool(&self) -> Option<&tool::Tool> { match self { ItemDetail::Tool(tool) => Some(tool), _ => None, } } } #[derive(Clone, Debug)] pub struct NewItemEntity { pub item: ItemDetail, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct ItemEntity { pub id: ItemEntityId, pub item: ItemDetail, } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum InventoryItemEntity { Individual(ItemEntity), Stacked(Vec), } impl std::convert::From for InventoryItemEntity { fn from(item: ItemEntity) -> InventoryItemEntity { InventoryItemEntity::Individual(item) } } impl std::convert::From> for InventoryItemEntity { fn from(items: Vec) -> InventoryItemEntity { InventoryItemEntity::Stacked(items) } } impl InventoryItemEntity { #[must_use] pub fn map_individual ItemEntity>(self, func: F) -> InventoryItemEntity { match self { InventoryItemEntity::Individual(item) => InventoryItemEntity::Individual(func(item)), _ => self, } } //pub fn with_individual(&self, func: fn(&ItemEntity) -> T) -> Option { pub fn with_individual T, T>(&self, func: F) -> Option { match self { InventoryItemEntity::Individual(item) => Some(func(item)), _ => None, } } //pub fn with_stacked(&self, func: fn(&Vec) -> T) -> Option { pub fn with_stacked) -> T, T>(&self, func: F) -> Option { match self { InventoryItemEntity::Stacked(items) => Some(func(items)), _ => None, } } pub fn individual(&self) -> Option<&ItemEntity> { match self { InventoryItemEntity::Individual(i) => Some(i), _ => None, } } pub fn stacked(&self) -> Option<&Vec> { match self { InventoryItemEntity::Stacked(i) => Some(i), _ => None, } } } #[derive(Clone, Debug, Default)] pub struct EquippedEntity { pub weapon: Option, pub armor: Option, pub shield: Option, pub unit: [Option; 4], pub mag: Option, } impl EquippedEntity { pub fn is_equipped(&self, item: &ItemEntityId) -> bool { self.weapon == Some(*item) || self.armor == Some(*item) || self.shield == Some(*item) || self.unit[0] == Some(*item) || self.unit[1] == Some(*item) || self.unit[2] == Some(*item) || self.unit[3] == Some(*item) || self.mag == Some(*item) } } #[derive(Clone, Debug, Default)] pub struct InventoryEntity { pub items: Vec, } impl InventoryEntity { pub fn new>(items: Vec) -> InventoryEntity { InventoryEntity { items: items.into_iter().map(|i| i.into()).collect(), } } } #[derive(Clone, Debug)] pub enum BankItemEntity { Individual(ItemEntity), Stacked(Vec), } impl std::convert::From for BankItemEntity { fn from(item: ItemEntity) -> BankItemEntity { BankItemEntity::Individual(item) } } impl std::convert::From> for BankItemEntity { fn from(items: Vec) -> BankItemEntity { BankItemEntity::Stacked(items) } } impl BankItemEntity { pub fn with_individual(&self, func: fn(&ItemEntity) -> T) -> Option { match self { BankItemEntity::Individual(item) => Some(func(item)), _ => None, } } pub fn with_stacked(&self, func: fn(&Vec) -> T) -> Option { match self { BankItemEntity::Stacked(items) => Some(func(items)), _ => None, } } } #[derive(Clone, Debug, Default)] pub struct BankEntity { //pub items: [Option; 30], pub items: Vec, } impl BankEntity { pub fn new>(items: Vec) -> BankEntity { BankEntity { items: items.into_iter().map(|i| i.into()).collect(), } } } #[derive(Clone, Debug)] pub struct TradeEntity { pub id: TradeId, pub character1: CharacterEntityId, pub character2: CharacterEntityId, } #[derive(Clone, Debug)] pub enum ItemModifier { WeaponModifier(weapon::WeaponModifier), }