You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

364 lines
11 KiB

#![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::ship::map::MapArea;
use crate::ship::drops::ItemDropType;
#[derive(PartialEq, Copy, Clone, Debug, Hash, Eq, 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)]
pub struct BankName(pub String);
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum ItemLocation {
Inventory {
character_id: CharacterEntityId,
},
Bank {
character_id: CharacterEntityId,
name: BankName,
},
LocalFloor {
character_id: CharacterEntityId,
map_area: MapArea,
x: f32,
y: f32,
z: f32,
},
SharedFloor {
map_area: MapArea,
x: f32,
y: f32,
z: f32,
},
Consumed,
FedToMag {
mag: ItemEntityId,
},
Shop,
/*Destroyed {
// marks an item that has been consumed in some way
},
Transformed {
item_id,
change_event
}
*/
}
#[derive(Debug, Clone, PartialEq)]
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)]
pub enum ItemParseError {
InvalidBytes
}
#[derive(Clone, Debug, PartialEq, 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<ItemDropType> {
let item_type = weapon::WeaponType::parse_type([data[0],data[1],data[2]]).map(|w| ItemType::Weapon(w))
.or(armor::ArmorType::parse_type([data[0],data[1],data[2]]).map(|a| ItemType::Armor(a)))
.or(shield::ShieldType::parse_type([data[0],data[1],data[2]]).map(|s| ItemType::Shield(s)))
.or(unit::UnitType::parse_type([data[0],data[1],data[2]]).map(|u| ItemType::Unit(u)))
.or(mag::MagType::parse_type([data[0],data[1],data[2]]).map(|m| ItemType::Mag(m)))
.or(tool::ToolType::parse_type([data[0],data[1],data[2]]).map(|t| ItemType::Tool(t)))
.or(esweapon::ESWeaponType::parse_type([data[0],data[1],data[2]]).map(|e| ItemType::ESWeapon(e))).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<tool::Tool> {
match self {
ItemDetail::Tool(tool) => Some(tool),
_ => None,
}
}
pub fn is_wrapped(&mut self) -> bool {
match self {
ItemDetail::Weapon(w) => w.wrapping.is_some(),
ItemDetail::Armor(a) => a.wrapping.is_some(),
ItemDetail::Shield(s) => s.wrapping.is_some(),
ItemDetail::Unit(u) => u.wrapping.is_some(),
ItemDetail::Tool(t) => t.wrapping.is_some(),
ItemDetail::TechniqueDisk(d) => d.wrapping.is_some(),
ItemDetail::Mag(m) => m.wrapping.is_some(),
ItemDetail::ESWeapon(e) => e.wrapping.is_some(),
_ => unreachable!(),
}
}
pub fn unwrap_present(&mut self) {
match self {
ItemDetail::Weapon(ref mut w) => w.wrapping = None,
ItemDetail::Armor(ref mut a) => a.wrapping = None,
ItemDetail::Shield(ref mut s) => s.wrapping = None,
ItemDetail::Unit(ref mut u) => u.wrapping = None,
ItemDetail::Tool(ref mut t) => t.wrapping = None,
ItemDetail::TechniqueDisk(ref mut d) => d.wrapping = None,
ItemDetail::Mag(ref mut m) => m.wrapping = None,
ItemDetail::ESWeapon(ref mut e) => e.wrapping = None,
_ => unreachable!(),
};
}
}
#[derive(Clone, Debug)]
pub struct NewItemEntity {
pub location: ItemLocation,
pub item: ItemDetail,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ItemEntity {
pub id: ItemEntityId,
pub location: ItemLocation,
pub item: ItemDetail,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
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 {
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<F: Fn(&ItemEntity) -> T, T>(&self, func: F) -> Option<T> {
match self {
InventoryItemEntity::Individual(item) => Some(func(item)),
_ => None,
}
}
pub fn with_stacked<F: Fn(&Vec<ItemEntity>) -> T, T>(&self, func: F) -> Option<T> {
match self {
InventoryItemEntity::Stacked(items) => Some(func(items)),
_ => None,
}
}
}
#[derive(Clone, Debug, Default)]
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: Vec<BankItemEntity>,
}
impl BankEntity {
pub fn new<T: Into<BankItemEntity>>(items: Vec<T>) -> BankEntity {
BankEntity {
items: items.into_iter().map(|i| i.into()).collect(),
}
}
}
#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq, Serialize, Deserialize)]
pub enum WrappingPaper {
WhitePink, // 0
YellowBlue, // 1
BlackYellow, // 2
LightBlueOrange, // 3
PinkYellowGreen, // 4
RedGreen, // 5
Magenta, // 6
Blue, // 7
Yellow, // 8
Vermillion, // 9
Green, // 10
}
impl WrappingPaper {
pub fn value(&self) -> u8 {
*self as u8
}
pub fn from(data: u8) -> Option<WrappingPaper> {
match data {
0 => Some(WrappingPaper::WhitePink),
1 => Some(WrappingPaper::YellowBlue),
2 => Some(WrappingPaper::BlackYellow),
3 => Some(WrappingPaper::LightBlueOrange),
4 => Some(WrappingPaper::PinkYellowGreen),
5 => Some(WrappingPaper::RedGreen),
6 => Some(WrappingPaper::Magenta),
7 => Some(WrappingPaper::Blue),
8 => Some(WrappingPaper::Yellow),
9 => Some(WrappingPaper::Vermillion),
10 => Some(WrappingPaper::Green),
_ => None,
}
}
}