393 lines
14 KiB
Rust
Raw Normal View History

2020-03-14 20:26:12 -07:00
use serde::{Serialize, Deserialize};
2020-08-20 20:19:46 -06:00
use crate::entity::item::ItemEntityId;
2020-03-14 20:26:12 -07:00
#[derive(Debug, Copy, Clone)]
pub enum ItemParseError {
InvalidMagType,
InvalidMagBytes,
}
2020-03-14 20:26:12 -07:00
2020-03-21 21:46:52 -07:00
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, enum_utils::FromStr, derive_more::Display)]
2020-03-14 20:26:12 -07:00
pub enum MagType {
Mag,
Varuna,
Mitra,
Surya,
Vayu,
Varaha,
Kama,
Ushasu,
Apsaras,
Kumara,
Kaitabha,
Tapas,
Bhirava,
Kalki,
Rudra,
Marutah,
Yaksa,
Sita,
Garuda,
Nandin,
Ashvinau,
Ribhava,
Soma,
Ila,
Durga,
Vritra,
Namuci,
Sumba,
Naga,
Pitri,
Kabanda,
Ravana,
Marica,
Soniti,
Preta,
Andhaka,
Bana,
Naraka,
Madhu,
Churel,
Robochao,
OpaOpa,
Pian,
Chao,
ChuChu,
KapuKapu,
AngelsWing,
DevilsWing,
Elenor,
MarkIII,
MasterSystem,
Genesis,
SegaSaturn,
Dreamcast,
Hamburger,
PanzersTail,
DevilsTail,
Deva,
Rati,
Savitri,
Rukmin,
Pushan,
Diwari,
Sato,
Bhima,
Nidra,
2020-03-31 21:15:01 -07:00
GeungSi,
Tellusis,
StrikerUnit,
Pioneer,
Puyo,
Moro,
Rappy,
Yahoo,
GaelGiel,
Agastya,
2020-03-14 20:26:12 -07:00
}
impl MagType {
pub fn value(&self) -> [u8; 3] {
match self {
MagType::Mag => [0x02, 0x00, 0x00],
MagType::Varuna => [0x02, 0x01, 0x00],
MagType::Mitra => [0x02, 0x02, 0x00],
MagType::Surya => [0x02, 0x03, 0x00],
MagType::Vayu => [0x02, 0x04, 0x00],
MagType::Varaha => [0x02, 0x05, 0x00],
MagType::Kama => [0x02, 0x06, 0x00],
MagType::Ushasu => [0x02, 0x07, 0x00],
MagType::Apsaras => [0x02, 0x08, 0x00],
MagType::Kumara => [0x02, 0x09, 0x00],
MagType::Kaitabha => [0x02, 0x0A, 0x00],
MagType::Tapas => [0x02, 0x0B, 0x00],
MagType::Bhirava => [0x02, 0x0C, 0x00],
MagType::Kalki => [0x02, 0x0D, 0x00],
MagType::Rudra => [0x02, 0x0E, 0x00],
MagType::Marutah => [0x02, 0x0F, 0x00],
MagType::Yaksa => [0x02, 0x10, 0x00],
MagType::Sita => [0x02, 0x11, 0x00],
MagType::Garuda => [0x02, 0x12, 0x00],
MagType::Nandin => [0x02, 0x13, 0x00],
MagType::Ashvinau => [0x02, 0x14, 0x00],
MagType::Ribhava => [0x02, 0x15, 0x00],
MagType::Soma => [0x02, 0x16, 0x00],
MagType::Ila => [0x02, 0x17, 0x00],
MagType::Durga => [0x02, 0x18, 0x00],
MagType::Vritra => [0x02, 0x19, 0x00],
MagType::Namuci => [0x02, 0x1A, 0x00],
MagType::Sumba => [0x02, 0x1B, 0x00],
MagType::Naga => [0x02, 0x1C, 0x00],
MagType::Pitri => [0x02, 0x1D, 0x00],
MagType::Kabanda => [0x02, 0x1E, 0x00],
MagType::Ravana => [0x02, 0x1F, 0x00],
MagType::Marica => [0x02, 0x20, 0x00],
MagType::Soniti => [0x02, 0x21, 0x00],
MagType::Preta => [0x02, 0x22, 0x00],
MagType::Andhaka => [0x02, 0x23, 0x00],
MagType::Bana => [0x02, 0x24, 0x00],
MagType::Naraka => [0x02, 0x25, 0x00],
MagType::Madhu => [0x02, 0x26, 0x00],
MagType::Churel => [0x02, 0x27, 0x00],
MagType::Robochao => [0x02, 0x28, 0x00],
MagType::OpaOpa => [0x02, 0x29, 0x00],
MagType::Pian => [0x02, 0x2A, 0x00],
MagType::Chao => [0x02, 0x2B, 0x00],
MagType::ChuChu => [0x02, 0x2C, 0x00],
MagType::KapuKapu => [0x02, 0x2D, 0x00],
MagType::AngelsWing => [0x02, 0x2E, 0x00],
MagType::DevilsWing => [0x02, 0x2F, 0x00],
MagType::Elenor => [0x02, 0x30, 0x00],
MagType::MarkIII => [0x02, 0x31, 0x00],
MagType::MasterSystem => [0x02, 0x32, 0x00],
MagType::Genesis => [0x02, 0x33, 0x00],
MagType::SegaSaturn => [0x02, 0x34, 0x00],
MagType::Dreamcast => [0x02, 0x35, 0x00],
MagType::Hamburger => [0x02, 0x36, 0x00],
MagType::PanzersTail => [0x02, 0x37, 0x00],
MagType::DevilsTail => [0x02, 0x38, 0x00],
MagType::Deva => [0x02, 0x39, 0x00],
MagType::Rati => [0x02, 0x3A, 0x00],
MagType::Savitri => [0x02, 0x3B, 0x00],
MagType::Rukmin => [0x02, 0x3C, 0x00],
MagType::Pushan => [0x02, 0x3D, 0x00],
MagType::Diwari => [0x02, 0x3E, 0x00],
MagType::Sato => [0x02, 0x3F, 0x00],
MagType::Bhima => [0x02, 0x40, 0x00],
MagType::Nidra => [0x02, 0x41, 0x00],
2020-03-31 21:15:01 -07:00
MagType::GeungSi => [0x02, 0x42, 0x00],
MagType::Tellusis => [0x02, 0x44, 0x00],
MagType::StrikerUnit => [0x02, 0x45, 0x00],
MagType::Pioneer => [0x02, 0x46, 0x00],
MagType::Puyo => [0x02, 0x47, 0x00],
MagType::Moro => [0x02, 0x48, 0x00],
MagType::Rappy => [0x02, 0x49, 0x00],
MagType::Yahoo => [0x02, 0x4A, 0x00],
MagType::GaelGiel => [0x02, 0x4B, 0x00],
MagType::Agastya => [0x02, 0x4C, 0x00],
2020-03-14 20:26:12 -07:00
}
}
pub fn parse_type(data: [u8; 3]) -> Result<MagType, ItemParseError> {
match data {
[0x02, 0x00, 0x00] => Ok(MagType::Mag),
[0x02, 0x01, 0x00] => Ok(MagType::Varuna),
[0x02, 0x02, 0x00] => Ok(MagType::Mitra),
[0x02, 0x03, 0x00] => Ok(MagType::Surya),
[0x02, 0x04, 0x00] => Ok(MagType::Vayu),
[0x02, 0x05, 0x00] => Ok(MagType::Varaha),
[0x02, 0x06, 0x00] => Ok(MagType::Kama),
[0x02, 0x07, 0x00] => Ok(MagType::Ushasu),
[0x02, 0x08, 0x00] => Ok(MagType::Apsaras),
[0x02, 0x09, 0x00] => Ok(MagType::Kumara),
[0x02, 0x0A, 0x00] => Ok(MagType::Kaitabha),
[0x02, 0x0B, 0x00] => Ok(MagType::Tapas),
[0x02, 0x0C, 0x00] => Ok(MagType::Bhirava),
[0x02, 0x0D, 0x00] => Ok(MagType::Kalki),
[0x02, 0x0E, 0x00] => Ok(MagType::Rudra),
[0x02, 0x0F, 0x00] => Ok(MagType::Marutah),
[0x02, 0x10, 0x00] => Ok(MagType::Yaksa),
[0x02, 0x11, 0x00] => Ok(MagType::Sita),
[0x02, 0x12, 0x00] => Ok(MagType::Garuda),
[0x02, 0x13, 0x00] => Ok(MagType::Nandin),
[0x02, 0x14, 0x00] => Ok(MagType::Ashvinau),
[0x02, 0x15, 0x00] => Ok(MagType::Ribhava),
[0x02, 0x16, 0x00] => Ok(MagType::Soma),
[0x02, 0x17, 0x00] => Ok(MagType::Ila),
[0x02, 0x18, 0x00] => Ok(MagType::Durga),
[0x02, 0x19, 0x00] => Ok(MagType::Vritra),
[0x02, 0x1A, 0x00] => Ok(MagType::Namuci),
[0x02, 0x1B, 0x00] => Ok(MagType::Sumba),
[0x02, 0x1C, 0x00] => Ok(MagType::Naga),
[0x02, 0x1D, 0x00] => Ok(MagType::Pitri),
[0x02, 0x1E, 0x00] => Ok(MagType::Kabanda),
[0x02, 0x1F, 0x00] => Ok(MagType::Ravana),
[0x02, 0x20, 0x00] => Ok(MagType::Marica),
[0x02, 0x21, 0x00] => Ok(MagType::Soniti),
[0x02, 0x22, 0x00] => Ok(MagType::Preta),
[0x02, 0x23, 0x00] => Ok(MagType::Andhaka),
[0x02, 0x24, 0x00] => Ok(MagType::Bana),
[0x02, 0x25, 0x00] => Ok(MagType::Naraka),
[0x02, 0x26, 0x00] => Ok(MagType::Madhu),
[0x02, 0x27, 0x00] => Ok(MagType::Churel),
[0x02, 0x28, 0x00] => Ok(MagType::Robochao),
[0x02, 0x29, 0x00] => Ok(MagType::OpaOpa),
[0x02, 0x2A, 0x00] => Ok(MagType::Pian),
[0x02, 0x2B, 0x00] => Ok(MagType::Chao),
[0x02, 0x2C, 0x00] => Ok(MagType::ChuChu),
[0x02, 0x2D, 0x00] => Ok(MagType::KapuKapu),
[0x02, 0x2E, 0x00] => Ok(MagType::AngelsWing),
[0x02, 0x2F, 0x00] => Ok(MagType::DevilsWing),
[0x02, 0x30, 0x00] => Ok(MagType::Elenor),
[0x02, 0x31, 0x00] => Ok(MagType::MarkIII),
[0x02, 0x32, 0x00] => Ok(MagType::MasterSystem),
[0x02, 0x33, 0x00] => Ok(MagType::Genesis),
[0x02, 0x34, 0x00] => Ok(MagType::SegaSaturn),
[0x02, 0x35, 0x00] => Ok(MagType::Dreamcast),
[0x02, 0x36, 0x00] => Ok(MagType::Hamburger),
[0x02, 0x37, 0x00] => Ok(MagType::PanzersTail),
[0x02, 0x38, 0x00] => Ok(MagType::DevilsTail),
[0x02, 0x39, 0x00] => Ok(MagType::Deva),
[0x02, 0x3A, 0x00] => Ok(MagType::Rati),
[0x02, 0x3B, 0x00] => Ok(MagType::Savitri),
[0x02, 0x3C, 0x00] => Ok(MagType::Rukmin),
[0x02, 0x3D, 0x00] => Ok(MagType::Pushan),
[0x02, 0x3E, 0x00] => Ok(MagType::Diwari),
[0x02, 0x3F, 0x00] => Ok(MagType::Sato),
[0x02, 0x40, 0x00] => Ok(MagType::Bhima),
[0x02, 0x41, 0x00] => Ok(MagType::Nidra),
[0x02, 0x42, 0x00] => Ok(MagType::GeungSi),
[0x02, 0x44, 0x00] => Ok(MagType::Tellusis),
[0x02, 0x45, 0x00] => Ok(MagType::StrikerUnit),
[0x02, 0x46, 0x00] => Ok(MagType::Pioneer),
[0x02, 0x47, 0x00] => Ok(MagType::Puyo),
[0x02, 0x48, 0x00] => Ok(MagType::Moro),
[0x02, 0x49, 0x00] => Ok(MagType::Rappy),
[0x02, 0x4A, 0x00] => Ok(MagType::Yahoo),
[0x02, 0x4B, 0x00] => Ok(MagType::GaelGiel),
[0x02, 0x4C, 0x00] => Ok(MagType::Agastya),
_ => Err(ItemParseError::InvalidMagType),
}
}
2020-03-14 20:26:12 -07:00
}
2020-08-20 20:19:46 -06:00
#[derive(Debug, Clone, PartialEq)]
pub enum MagModifier {
FeedMag{
food: ItemEntityId,
},
BankMag,
MagCell(ItemEntityId),
}
2020-03-14 20:26:12 -07:00
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum PhotonBlast {
Farlla,
Estlla,
Leilla,
Pilla,
Golla,
MyllaYoulla,
}
2020-08-20 20:19:46 -06:00
#[derive(Debug, Clone, PartialEq)]
2020-03-14 20:26:12 -07:00
pub struct Mag {
2020-03-21 21:46:52 -07:00
pub mag: MagType,
pub def: u16,
pub pow: u16,
pub dex: u16,
pub mnd: u16,
2020-03-14 20:26:12 -07:00
pub synchro: u8,
pub iq: u8,
pub photon_blast: [Option<PhotonBlast>; 3],
2020-04-19 23:37:48 -03:00
pub color: u8,
2020-08-20 20:19:46 -06:00
pub modifiers: Vec<MagModifier>,
2020-03-14 20:26:12 -07:00
}
impl Mag {
pub fn as_bytes(&self) -> [u8; 16] {
let mut result = [0; 16];
2020-03-21 21:46:52 -07:00
result[0..3].copy_from_slice(&self.mag.value());
result[3] = self.photon_blast_value();
result[4..6].copy_from_slice(&self.def.to_le_bytes());
result[6..8].copy_from_slice(&self.pow.to_le_bytes());
result[8..10].copy_from_slice(&self.dex.to_le_bytes());
result[10..12].copy_from_slice(&self.mnd.to_le_bytes());
result[12] = self.synchro;
2020-04-19 23:37:48 -03:00
result[13] = self.iq;
result[14] = self.photon_blast_count();
result[15] = self.color;
2020-03-14 20:26:12 -07:00
result
}
2020-03-21 21:46:52 -07:00
fn photon_blast_value(&self) -> u8 {
let mut photon_blast_list = vec![PhotonBlast::Farlla,
PhotonBlast::Estlla,
PhotonBlast::Golla,
PhotonBlast::Pilla,
PhotonBlast::Leilla,
PhotonBlast::MyllaYoulla];
let mut photon_blast: u8 = 0;
if let Some(ref pb_mid) = self.photon_blast[0] {
match *pb_mid {
PhotonBlast::Farlla => {},
PhotonBlast::Estlla => photon_blast |= 1,
PhotonBlast::Golla => photon_blast |= 2,
PhotonBlast::Pilla => photon_blast |= 3,
PhotonBlast::Leilla => photon_blast |= 4,
PhotonBlast::MyllaYoulla => photon_blast |= 5,
}
photon_blast_list.retain(|k| k != pb_mid);
}
if let Some(ref pb_right) = self.photon_blast[1] {
match *pb_right {
PhotonBlast::Farlla => {}
PhotonBlast::Estlla => photon_blast |= 1 << 3,
PhotonBlast::Golla => photon_blast |= 2 << 3,
PhotonBlast::Pilla => photon_blast |= 3 << 3,
PhotonBlast::Leilla => photon_blast |= 4 << 3,
PhotonBlast::MyllaYoulla => photon_blast |= 5 << 3,
}
photon_blast_list.retain(|k| k != pb_right);
}
if let Some(ref pb_left) = self.photon_blast[2] {
if let Some(pos) = photon_blast_list.iter().position(|k| k == pb_left) {
photon_blast |= (pos as u8) << 6;
};
}
photon_blast
}
fn photon_blast_count(&self) -> u8 {
let mut count = 0;
for i in 0..3 {
if let Some(_) = self.photon_blast[i] {
count |= 1 << i
};
}
count
}
pub fn from_bytes(data: [u8; 16]) -> Result<Mag, ItemParseError> {
let m = MagType::parse_type([data[0], data[1], data[2]]);
if m.is_ok() {
let mut def = u16::from_le_bytes([data[4], data[5]]);
let mut pow = u16::from_le_bytes([data[6], data[7]]);
let mut dex = u16::from_le_bytes([data[8], data[9]]);
let mut mind = u16::from_le_bytes([data[10], data[11]]);
if (def/100 + dex/100 + pow/100 + mind/100) > 200 {
def = 0;
pow = 0;
dex = 0;
mind = 0;
}
let sync = data[12] % 121; // TODO: handle invalid values.
let iq = data[13] % 201; // TODO: handle invalid values.
Ok(Mag{
mag: m.unwrap(),
def: def,
pow: pow,
dex: dex,
mnd: mind,
synchro: sync,
iq: iq,
photon_blast: [None, None, None], // TODO: actually get PBs from bytes
color: data[15] % 18,
2020-08-20 20:19:46 -06:00
modifiers: Vec::new(),
})
}
else {
Err(ItemParseError::InvalidMagBytes) // TODO: error handling if wrong bytes are given
}
}
2020-03-14 20:26:12 -07:00
}