2020-05-02 22:08:37 -03:00
|
|
|
#![allow(dead_code)]
|
2020-02-06 23:03:51 -08:00
|
|
|
pub mod weapon;
|
|
|
|
pub mod armor;
|
|
|
|
pub mod shield;
|
|
|
|
pub mod tool;
|
2020-03-18 18:21:34 -07:00
|
|
|
pub mod tech;
|
2020-02-29 14:50:17 -08:00
|
|
|
pub mod unit;
|
2020-03-14 20:26:12 -07:00
|
|
|
pub mod mag;
|
2020-09-06 23:46:52 -03:00
|
|
|
pub mod esweapon;
|
2020-02-06 23:03:51 -08:00
|
|
|
|
2020-10-29 19:09:22 -06:00
|
|
|
use serde::{Serialize, Deserialize};
|
2020-03-29 14:40:24 -07:00
|
|
|
use crate::entity::character::CharacterEntityId;
|
2020-04-26 22:01:05 -06:00
|
|
|
use crate::ship::map::MapArea;
|
2020-05-22 18:58:51 -03:00
|
|
|
use crate::ship::drops::ItemDropType;
|
2020-03-29 14:40:24 -07:00
|
|
|
|
2020-10-29 19:09:22 -06:00
|
|
|
#[derive(PartialEq, Copy, Clone, Debug, Hash, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
2020-01-18 23:36:28 -08:00
|
|
|
pub struct ItemEntityId(pub u32);
|
|
|
|
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
|
|
|
|
pub struct ItemId(u32);
|
2021-12-10 23:41:17 -07:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, derive_more::Display)]
|
2020-07-19 14:14:07 -06:00
|
|
|
pub struct BankName(pub String);
|
2021-11-12 10:42:33 -07:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
|
|
|
|
pub struct TradeId(pub u32);
|
2020-01-18 23:36:28 -08:00
|
|
|
|
2020-11-09 18:54:44 -07:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
2021-11-12 10:42:33 -07:00
|
|
|
pub enum ItemNote {
|
|
|
|
CharacterCreation {
|
2020-03-29 14:40:24 -07:00
|
|
|
character_id: CharacterEntityId,
|
2019-12-09 23:11:27 -08:00
|
|
|
},
|
2021-11-12 10:42:33 -07:00
|
|
|
EnemyDrop {
|
2020-05-05 21:53:04 -06:00
|
|
|
character_id: CharacterEntityId,
|
2021-11-12 10:42:33 -07:00
|
|
|
//monster_type: MonsterType,
|
|
|
|
//droprate: f32,
|
2020-05-05 21:53:04 -06:00
|
|
|
map_area: MapArea,
|
|
|
|
x: f32,
|
|
|
|
y: f32,
|
|
|
|
z: f32,
|
|
|
|
},
|
2021-11-12 10:42:33 -07:00
|
|
|
Pickup {
|
|
|
|
character_id: CharacterEntityId,
|
|
|
|
},
|
|
|
|
PlayerDrop {
|
2022-04-29 22:52:23 -06:00
|
|
|
character_id: CharacterEntityId,
|
2020-04-26 22:01:05 -06:00
|
|
|
map_area: MapArea,
|
|
|
|
x: f32,
|
|
|
|
y: f32,
|
|
|
|
z: f32,
|
2019-12-09 23:11:27 -08:00
|
|
|
},
|
2022-06-20 15:40:30 -06:00
|
|
|
Consumed, // TODO: character_id
|
2020-08-31 23:46:15 -06:00
|
|
|
FedToMag {
|
2022-06-20 15:40:30 -06:00
|
|
|
//character_id: CharacterEntityId,
|
2020-08-31 23:46:15 -06:00
|
|
|
mag: ItemEntityId,
|
2020-09-27 18:16:27 -06:00
|
|
|
},
|
2021-11-12 10:42:33 -07:00
|
|
|
BoughtAtShop {
|
|
|
|
character_id: CharacterEntityId,
|
|
|
|
},
|
|
|
|
SoldToShop,
|
2020-12-12 19:55:27 -07:00
|
|
|
Trade {
|
2021-11-12 10:42:33 -07:00
|
|
|
id: TradeId,
|
2020-12-12 19:55:27 -07:00
|
|
|
character_to: CharacterEntityId,
|
|
|
|
character_from: CharacterEntityId,
|
|
|
|
},
|
2022-05-14 13:06:40 -06:00
|
|
|
Withdraw {
|
|
|
|
character_id: CharacterEntityId,
|
|
|
|
bank: BankName,
|
|
|
|
},
|
|
|
|
Deposit {
|
|
|
|
character_id: CharacterEntityId,
|
|
|
|
bank: BankName,
|
|
|
|
},
|
2019-12-09 23:11:27 -08:00
|
|
|
}
|
|
|
|
|
2021-12-26 23:31:12 -07:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
2020-04-03 22:56:14 -07:00
|
|
|
pub struct Meseta(pub u32);
|
|
|
|
|
|
|
|
impl Meseta {
|
|
|
|
pub fn as_bytes(&self) -> [u8; 16] {
|
|
|
|
let mut result = [0; 16];
|
2020-04-26 22:51:09 -06:00
|
|
|
result[0] = 4;
|
2020-04-03 22:56:14 -07:00
|
|
|
result[12..16].copy_from_slice(&u32::to_le_bytes(self.0));
|
|
|
|
result
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-18 23:36:28 -08:00
|
|
|
|
2020-03-21 17:47:28 -07:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
|
|
|
pub enum ItemType {
|
|
|
|
Weapon(weapon::WeaponType),
|
|
|
|
Armor(armor::ArmorType),
|
|
|
|
Shield(shield::ShieldType),
|
|
|
|
Unit(unit::UnitType),
|
|
|
|
Tool(tool::ToolType),
|
2020-03-21 21:46:52 -07:00
|
|
|
TechniqueDisk(tech::Technique),
|
|
|
|
Mag(mag::MagType),
|
2020-09-06 23:46:52 -03:00
|
|
|
ESWeapon(esweapon::ESWeaponType),
|
2020-01-18 23:36:28 -08:00
|
|
|
}
|
|
|
|
|
2020-05-22 18:58:51 -03:00
|
|
|
#[derive(Clone, Debug, PartialEq)]
|
|
|
|
pub enum ItemParseError {
|
|
|
|
InvalidBytes
|
|
|
|
}
|
2020-03-21 17:47:28 -07:00
|
|
|
|
2020-10-29 19:09:22 -06:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
2020-01-18 23:36:28 -08:00
|
|
|
pub enum ItemDetail {
|
2020-03-16 20:34:50 -07:00
|
|
|
Weapon(weapon::Weapon),
|
2020-03-16 20:57:19 -07:00
|
|
|
Armor(armor::Armor),
|
2020-03-16 21:48:26 -07:00
|
|
|
Shield(shield::Shield),
|
|
|
|
Unit(unit::Unit),
|
2020-03-21 17:47:28 -07:00
|
|
|
Tool(tool::Tool),
|
2020-03-21 21:46:52 -07:00
|
|
|
TechniqueDisk(tech::TechniqueDisk),
|
|
|
|
Mag(mag::Mag),
|
2020-09-06 23:46:52 -03:00
|
|
|
ESWeapon(esweapon::ESWeapon),
|
2020-01-18 23:36:28 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ItemDetail {
|
|
|
|
pub fn is_stackable(&self) -> bool {
|
|
|
|
match self {
|
2020-03-16 20:34:50 -07:00
|
|
|
ItemDetail::Tool(tool) => tool.tool.is_stackable(),
|
2020-01-18 23:36:28 -08:00
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-21 17:47:28 -07:00
|
|
|
pub fn item_type(&self) -> ItemType {
|
2020-01-18 23:36:28 -08:00
|
|
|
match self {
|
2020-03-21 17:47:28 -07:00
|
|
|
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),
|
2020-03-21 21:46:52 -07:00
|
|
|
ItemDetail::Mag(m) => ItemType::Mag(m.mag),
|
2020-09-06 23:46:52 -03:00
|
|
|
ItemDetail::ESWeapon(e) => ItemType::ESWeapon(e.esweapon),
|
2020-01-18 23:36:28 -08:00
|
|
|
}
|
|
|
|
}
|
2020-05-22 18:58:51 -03:00
|
|
|
|
|
|
|
pub fn parse_item_from_bytes(data: [u8; 16]) -> Option<ItemDropType> {
|
2021-06-18 19:01:29 -06:00
|
|
|
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()?;
|
2020-05-22 18:58:51 -03:00
|
|
|
|
|
|
|
match item_type {
|
2020-05-23 01:16:02 -03:00
|
|
|
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()?)),
|
2020-05-22 18:58:51 -03:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2020-06-29 19:26:35 -06:00
|
|
|
|
|
|
|
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(),
|
2020-09-06 23:46:52 -03:00
|
|
|
ItemDetail::ESWeapon(e) => e.as_bytes(),
|
2020-06-29 19:26:35 -06:00
|
|
|
}
|
|
|
|
}
|
2020-11-05 16:36:39 -07:00
|
|
|
|
|
|
|
pub fn as_tool(self) -> Option<tool::Tool> {
|
|
|
|
match self {
|
|
|
|
ItemDetail::Tool(tool) => Some(tool),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2021-12-10 13:15:33 -07:00
|
|
|
|
|
|
|
pub fn tool(&self) -> Option<&tool::Tool> {
|
|
|
|
match self {
|
|
|
|
ItemDetail::Tool(tool) => Some(tool),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2020-01-18 23:36:28 -08:00
|
|
|
}
|
|
|
|
|
2020-04-26 21:58:43 -06:00
|
|
|
#[derive(Clone, Debug)]
|
2020-03-30 19:28:49 -07:00
|
|
|
pub struct NewItemEntity {
|
|
|
|
pub item: ItemDetail,
|
|
|
|
}
|
2020-01-18 23:36:28 -08:00
|
|
|
|
2020-11-09 18:54:44 -07:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
2020-03-29 14:53:51 -07:00
|
|
|
pub struct ItemEntity {
|
2020-03-30 19:28:49 -07:00
|
|
|
pub id: ItemEntityId,
|
2020-01-18 23:36:28 -08:00
|
|
|
pub item: ItemDetail,
|
2019-12-09 23:11:27 -08:00
|
|
|
}
|
2020-11-05 16:36:39 -07:00
|
|
|
|
|
|
|
|
2020-11-09 18:54:44 -07:00
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
2020-11-05 16:36:39 -07:00
|
|
|
pub enum InventoryItemEntity {
|
|
|
|
Individual(ItemEntity),
|
|
|
|
Stacked(Vec<ItemEntity>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::convert::From<ItemEntity> for InventoryItemEntity {
|
|
|
|
fn from(item: ItemEntity) -> InventoryItemEntity {
|
|
|
|
InventoryItemEntity::Individual(item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::convert::From<Vec<ItemEntity>> for InventoryItemEntity {
|
|
|
|
fn from(items: Vec<ItemEntity>) -> InventoryItemEntity {
|
|
|
|
InventoryItemEntity::Stacked(items)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl InventoryItemEntity {
|
2021-12-29 15:46:22 -07:00
|
|
|
#[must_use]
|
2020-11-05 16:36:39 -07:00
|
|
|
pub fn map_individual<F: Fn(ItemEntity) -> ItemEntity>(self, func: F) -> InventoryItemEntity {
|
|
|
|
match self {
|
|
|
|
InventoryItemEntity::Individual(item) => InventoryItemEntity::Individual(func(item)),
|
|
|
|
_ => 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)),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//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)),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2021-12-27 00:43:25 -07:00
|
|
|
|
2021-12-28 01:37:24 -07:00
|
|
|
pub fn individual(&self) -> Option<&ItemEntity> {
|
2021-12-27 00:43:25 -07:00
|
|
|
match self {
|
|
|
|
InventoryItemEntity::Individual(i) => Some(i),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2020-11-05 16:36:39 -07:00
|
|
|
}
|
|
|
|
|
2020-11-12 17:13:42 -07:00
|
|
|
#[derive(Clone, Debug, Default)]
|
2020-11-05 16:36:39 -07:00
|
|
|
pub struct EquippedEntity {
|
|
|
|
pub weapon: Option<ItemEntityId>,
|
|
|
|
pub armor: Option<ItemEntityId>,
|
|
|
|
pub shield: Option<ItemEntityId>,
|
|
|
|
pub unit: [Option<ItemEntityId>; 4],
|
|
|
|
pub mag: Option<ItemEntityId>,
|
|
|
|
}
|
|
|
|
|
|
|
|
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<InventoryItemEntity>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl InventoryEntity {
|
|
|
|
pub fn new<T: Into<InventoryItemEntity>>(items: Vec<T>) -> InventoryEntity {
|
|
|
|
InventoryEntity {
|
|
|
|
items: items.into_iter().map(|i| i.into()).collect(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub enum BankItemEntity {
|
|
|
|
Individual(ItemEntity),
|
|
|
|
Stacked(Vec<ItemEntity>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::convert::From<ItemEntity> for BankItemEntity {
|
|
|
|
fn from(item: ItemEntity) -> BankItemEntity {
|
|
|
|
BankItemEntity::Individual(item)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::convert::From<Vec<ItemEntity>> for BankItemEntity {
|
|
|
|
fn from(items: Vec<ItemEntity>) -> BankItemEntity {
|
|
|
|
BankItemEntity::Stacked(items)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BankItemEntity {
|
|
|
|
pub fn with_individual<T>(&self, func: fn(&ItemEntity) -> T) -> Option<T> {
|
|
|
|
match self {
|
|
|
|
BankItemEntity::Individual(item) => Some(func(item)),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_stacked<T>(&self, func: fn(&Vec<ItemEntity>) -> T) -> Option<T> {
|
|
|
|
match self {
|
|
|
|
BankItemEntity::Stacked(items) => Some(func(items)),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Default)]
|
|
|
|
pub struct BankEntity {
|
|
|
|
//pub items: [Option<CharacterBankItem>; 30],
|
|
|
|
pub items: Vec<BankItemEntity>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BankEntity {
|
|
|
|
pub fn new<T: Into<BankItemEntity>>(items: Vec<T>) -> BankEntity {
|
|
|
|
BankEntity {
|
|
|
|
items: items.into_iter().map(|i| i.into()).collect(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|