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.

1226 lines
52 KiB

use std::collections::HashMap;
use serde::{Serialize, Deserialize};
use crate::entity::item::tool::ToolType;
use crate::entity::character::{CharacterClass, SectionID};
use crate::entity::item::ItemEntityId;
use std::io::Read;
use std::cmp::Ordering::{Less, Greater, Equal};
#[derive(Debug, Deserialize)]
struct MagStats {
feed_table: usize,
photon_blast: Option<PhotonBlast>
}
#[derive(Debug, Deserialize)]
struct MagFeedTable {
def: i16,
pow: i16,
dex: i16,
mnd: i16,
iq: i8,
syn: i8,
}
lazy_static::lazy_static! {
static ref MAG_STATS: HashMap<MagType, MagStats> = {
let mut f = std::fs::File::open("data/item_stats/mag_stats.toml").unwrap();
let mut s = String::new();
f.read_to_string(&mut s).unwrap();
let mag_stats: HashMap<String, MagStats> = toml::from_str(&s).unwrap();
mag_stats.into_iter()
.map(|(name, stats)| {
(name.parse().unwrap(), stats)
})
.collect::<HashMap<MagType, MagStats>>()
};
static ref MAG_FEEDING_TABLES: Vec<HashMap<ToolType, MagFeedTable>> = {
let mut f = std::fs::File::open("data/item_stats/mag_feed_table.toml").unwrap();
let mut s = String::new();
f.read_to_string(&mut s).unwrap();
let mut feed: HashMap<String, Vec<HashMap<String, MagFeedTable>>> = toml::from_str(&s).unwrap();
let feed = feed.remove("feedtable").unwrap();
feed.into_iter()
.map(|table| {
table.into_iter()
.map(|(tool, stats)| {
(tool.parse().unwrap(), stats)
})
.collect()
})
.collect::<Vec<HashMap<ToolType, MagFeedTable>>>()
};
}
#[derive(Debug, Copy, Clone)]
pub enum ItemParseError {
InvalidMagType,
InvalidMagBytes,
}
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, enum_utils::FromStr, derive_more::Display, strum_macros::EnumIter)]
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,
GeungSi,
Tellusis,
StrikerUnit,
Pioneer,
Puyo,
Moro,
Rappy,
Yahoo,
GaelGiel,
Agastya,
}
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],
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],
}
}
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),
}
}
pub fn can_evolve(&self) -> bool {
match self {
MagType::Mag => true,
MagType::Varuna => true,
MagType::Mitra => true,
MagType::Surya => true,
MagType::Vayu => true,
MagType::Varaha => true,
MagType::Kama => true,
MagType::Ushasu => true,
MagType::Apsaras => true,
MagType::Kumara => true,
MagType::Kaitabha => true,
MagType::Tapas => true,
MagType::Bhirava => true,
MagType::Kalki => true,
MagType::Rudra => true,
MagType::Marutah => true,
MagType::Yaksa => true,
MagType::Sita => true,
MagType::Garuda => true,
MagType::Nandin => true,
MagType::Ashvinau => true,
MagType::Ribhava => true,
MagType::Soma => true,
MagType::Ila => true,
MagType::Durga => true,
MagType::Vritra => true,
MagType::Namuci => true,
MagType::Sumba => true,
MagType::Naga => true,
MagType::Pitri => true,
MagType::Kabanda => true,
MagType::Ravana => true,
MagType::Marica => true,
MagType::Soniti => true,
MagType::Preta => true,
MagType::Andhaka => true,
MagType::Bana => true,
MagType::Naraka => true,
MagType::Madhu => true,
MagType::Churel => false,
MagType::Robochao => false,
MagType::OpaOpa => false,
MagType::Pian => false,
MagType::Chao => false,
MagType::ChuChu => false,
MagType::KapuKapu => false,
MagType::AngelsWing => false,
MagType::DevilsWing => false,
MagType::Elenor => false,
MagType::MarkIII => false,
MagType::MasterSystem => false,
MagType::Genesis => false,
MagType::SegaSaturn => false,
MagType::Dreamcast => false,
MagType::Hamburger => false,
MagType::PanzersTail => false,
MagType::DevilsTail => false,
MagType::Deva => false,
MagType::Rati => false,
MagType::Savitri => false,
MagType::Rukmin => false,
MagType::Pushan => false,
MagType::Diwari => false,
MagType::Sato => false,
MagType::Bhima => false,
MagType::Nidra => false,
MagType::GeungSi => false,
MagType::Tellusis => false,
MagType::StrikerUnit => false,
MagType::Pioneer => false,
MagType::Puyo => false,
MagType::Moro => false,
MagType::Rappy => false,
MagType::Yahoo => false,
MagType::GaelGiel => false,
MagType::Agastya => false,
}
}
}
pub enum MagCell {
CellOfMag502,
CellOfMag213,
PartsOfRobochao,
HeartOfOpaOpa,
HeartOfPian,
HeartOfChao,
HeartOfAngel,
HeartOfDevil,
KitOfHamburger,
PanthersSpirit,
KitOfMark3,
KitOfMasterSystem,
KitOfGenesis,
KitOfSegaSaturn,
KitOfDreamcast,
Tablet,
DragonScale,
HeavenStrikerCoat,
PioneerParts,
AmitiesMemo,
HeartOfMorolian,
RappysBeak,
YahoosEngine,
DPhotonCore,
LibertaKit,
}
impl std::convert::TryFrom<ToolType> for MagCell {
type Error = ();
fn try_from(tool: ToolType) -> Result<MagCell, ()> {
match tool {
ToolType::CellOfMag502 => Ok(MagCell::CellOfMag502),
ToolType::CellOfMag213 => Ok(MagCell::CellOfMag213),
ToolType::PartsOfRobochao => Ok(MagCell::PartsOfRobochao),
ToolType::HeartOfOpaOpa => Ok(MagCell::HeartOfOpaOpa),
ToolType::HeartOfPian => Ok(MagCell::HeartOfPian),
ToolType::HeartOfChao => Ok(MagCell::HeartOfChao),
ToolType::HeartOfAngel => Ok(MagCell::HeartOfAngel),
ToolType::HeartOfDevil => Ok(MagCell::HeartOfDevil),
ToolType::KitOfHamburger => Ok(MagCell::KitOfHamburger),
ToolType::PanthersSpirit => Ok(MagCell::PanthersSpirit),
ToolType::KitOfMark3 => Ok(MagCell::KitOfMark3),
ToolType::KitOfMasterSystem => Ok(MagCell::KitOfMasterSystem),
ToolType::KitOfGenesis => Ok(MagCell::KitOfGenesis),
ToolType::KitOfSegaSaturn => Ok(MagCell::KitOfSegaSaturn),
ToolType::KitOfDreamcast => Ok(MagCell::KitOfDreamcast),
ToolType::Tablet => Ok(MagCell::Tablet),
ToolType::DragonScale => Ok(MagCell::DragonScale),
ToolType::HeavenStrikerCoat => Ok(MagCell::HeavenStrikerCoat),
ToolType::PioneerParts => Ok(MagCell::PioneerParts),
ToolType::AmitiesMemo => Ok(MagCell::AmitiesMemo),
ToolType::HeartOfMorolian => Ok(MagCell::HeartOfMorolian),
ToolType::RappysBeak => Ok(MagCell::RappysBeak),
ToolType::YahoosEngine => Ok(MagCell::YahoosEngine),
ToolType::DPhotonCore => Ok(MagCell::DPhotonCore),
ToolType::LibertaKit => Ok(MagCell::LibertaKit),
_ => Err(()),
}
}
}
enum MagAttribute {
//Def,
Pow,
Dex,
Mind,
}
// one day I hope to be cool enough to figure how to enforce that each magattribute in sequence must be unique
// (to not need the _ in the match)
enum MagAttributeOrdering {
Sequence(MagAttribute, MagAttribute, MagAttribute),
Primary(MagAttribute),
MultiPrimary
}
impl MagAttributeOrdering {
fn new(pow: u16, dex: u16, mnd: u16) -> MagAttributeOrdering {
let primary = if pow > dex && pow > mnd {
MagAttribute::Pow
}
else if dex > pow && dex > mnd{
MagAttribute::Dex
}
else if mnd > pow && mnd > dex {
MagAttribute::Mind
}
else {
return MagAttributeOrdering::MultiPrimary
};
match primary {
MagAttribute::Pow => {
match dex.cmp(&mnd) {
Greater => MagAttributeOrdering::Sequence(primary, MagAttribute::Dex, MagAttribute::Mind),
Equal => MagAttributeOrdering::Primary(primary),
Less => MagAttributeOrdering::Sequence(primary, MagAttribute::Mind, MagAttribute::Dex),
}
},
MagAttribute::Dex => {
match pow.cmp(&mnd) {
Greater => MagAttributeOrdering::Sequence(primary, MagAttribute::Pow, MagAttribute::Mind),
Equal => MagAttributeOrdering::Primary(primary),
Less => MagAttributeOrdering::Sequence(primary, MagAttribute::Mind, MagAttribute::Pow),
}
},
MagAttribute::Mind => {
match pow.cmp(&dex) {
Greater => MagAttributeOrdering::Sequence(primary, MagAttribute::Pow, MagAttribute::Dex),
Equal => MagAttributeOrdering::Primary(primary),
Less => MagAttributeOrdering::Sequence(primary, MagAttribute::Dex, MagAttribute::Pow),
}
},
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum MagModifier {
FeedMag{
food: ItemEntityId,
},
BankMag, // when putting a mag in the bank it truncates the values which has applications when raising degenerate mags
MagCell(ItemEntityId),
OwnerChange(CharacterClass, SectionID)
}
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, enum_utils::FromStr)]
pub enum PhotonBlast {
Farlla,
Estlla,
Leilla,
Pilla,
Golla,
MyllaYoulla,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Mag {
pub mag: MagType,
def: u16,
pow: u16,
dex: u16,
mnd: u16,
pub synchro: u8,
iq: u8,
photon_blast: [Option<PhotonBlast>; 3],
pub color: u8,
//modifiers: Vec<MagModifier>,
pub class: CharacterClass,
pub id: SectionID,
}
impl Mag {
pub fn baby_mag(skin: u16) -> Mag {
Mag {
mag: MagType::Mag,
def: 500,
pow: 0,
dex: 0,
mnd: 0,
synchro: 20,
iq: 0,
photon_blast: [None; 3],
color: (skin % 18) as u8,
//modifiers: Vec::new(),
class: CharacterClass::HUmar,
id: SectionID::Viridia,
}
}
pub fn as_bytes(&self) -> [u8; 16] {
let mut result = [0; 16];
result[0..3].copy_from_slice(&self.mag.value());
result[2] = self.level() as u8;
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;
result[13] = self.iq;
result[14] = self.photon_blast_count();
result[15] = self.color;
result
}
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 self.photon_blast[i].is_some() {
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 let Ok(m) = m {
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,
def,
pow,
dex,
mnd: mind,
synchro: sync,
iq,
photon_blast: [None, None, None], // TODO: actually get PBs from bytes
color: data[15] % 18,
//modifiers: Vec::new(),
class: CharacterClass::HUmar,
id: SectionID::Viridia,
})
}
else {
Err(ItemParseError::InvalidMagBytes) // TODO: error handling if wrong bytes are given
}
}
pub fn def(&self) -> u16 {
self.def/100
}
pub fn pow(&self) -> u16 {
self.pow/100
}
pub fn dex(&self) -> u16 {
self.dex/100
}
pub fn mind(&self) -> u16 {
self.mnd/100
}
pub fn level(&self) -> u16 {
self.def() + self.pow() + self.dex() + self.mind()
}
fn change_mag_type(&mut self, previous_level: u16) {
if !self.mag.can_evolve() {
return
}
if self.level() >= 10 && previous_level < 10 {
match self.class {
CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => {
self.mag = MagType::Varuna
},
CharacterClass::RAmar | CharacterClass::RAmarl | CharacterClass::RAcast | CharacterClass::RAcaseal => {
self.mag = MagType::Kalki
},
CharacterClass::FOmar | CharacterClass::FOmarl | CharacterClass::FOnewm | CharacterClass::FOnewearl => {
self.mag = MagType::Vritra
},
}
}
if self.level() >= 35 && previous_level < 35 {
match self.mag {
MagType::Varuna => {
if self.pow > self.dex && self.pow > self.mnd {
self.mag = MagType::Rudra
}
else if self.dex > self.pow && self.dex > self.mnd {
self.mag = MagType::Marutah
}
else if self.mnd > self.pow && self.mnd > self.dex {
self.mag = MagType::Vayu
}
else {
self.mag = MagType::Rudra
}
},
MagType::Kalki => {
if self.pow > self.dex && self.pow > self.mnd {
self.mag = MagType::Surya
}
else if self.dex > self.pow && self.dex > self.mnd {
self.mag = MagType::Mitra
}
else if self.mnd > self.pow && self.mnd > self.dex {
self.mag = MagType::Tapas
}
else {
self.mag = MagType::Mitra
}
},
MagType::Vritra => {
#[allow(clippy::if_same_then_else)]
if self.pow > self.dex && self.pow > self.mnd {
self.mag = MagType::Sumba
}
else if self.dex > self.pow && self.dex > self.mnd {
self.mag = MagType::Ashvinau
}
else if self.mnd > self.pow && self.mnd > self.dex {
self.mag = MagType::Namuci
}
else {
self.mag = MagType::Namuci
}
},
_ => unreachable!(),
}
}
if self.level() >= 50 && self.level() % 5 == 0 {
let mag_attr_ordering = MagAttributeOrdering::new(self.pow, self.dex, self.mnd);
self.mag = match self.id {
SectionID::Viridia | SectionID::Skyly | SectionID::Purplenum | SectionID::Redria | SectionID::Yellowboze => {
match self.class {
CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => {
match mag_attr_ordering {
MagAttributeOrdering::Primary(MagAttribute::Pow) => MagType::Varaha,
MagAttributeOrdering::Primary(MagAttribute::Dex) => MagType::Nandin,
MagAttributeOrdering::Primary(MagAttribute::Mind) => MagType::Kabanda,
MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Dex, MagAttribute::Mind) => MagType::Varaha,
MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Mind, MagAttribute::Dex) => MagType::Bhirava,
MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Pow, MagAttribute::Mind) => MagType::Ila,
MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Mind, MagAttribute::Pow) => MagType::Nandin,
MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Pow, MagAttribute::Dex) => MagType::Kabanda,
MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Dex, MagAttribute::Pow) => MagType::Ushasu,
MagAttributeOrdering::MultiPrimary => {
if self.dex >= self.mnd {
MagType::Varaha
}
else {
MagType::Bhirava
}
},
_ => unreachable!()
}
},
CharacterClass::RAmar | CharacterClass::RAmarl | CharacterClass::RAcast | CharacterClass::RAcaseal => {
match mag_attr_ordering {
MagAttributeOrdering::Primary(MagAttribute::Pow) => MagType::Kama,
MagAttributeOrdering::Primary(MagAttribute::Dex) => MagType::Kama,
MagAttributeOrdering::Primary(MagAttribute::Mind) => MagType::Varaha,
MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Dex, MagAttribute::Mind) => MagType::Kama,
MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Mind, MagAttribute::Dex) => MagType::Bhirava,
MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Pow, MagAttribute::Mind) => MagType::Bhirava,
MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Mind, MagAttribute::Pow) => MagType::Kama,
MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Pow, MagAttribute::Dex) => MagType::Varaha,
MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Dex, MagAttribute::Pow) => MagType::Apsaras,
MagAttributeOrdering::MultiPrimary => {
if self.mnd >= self.pow {
MagType::Kama
}
else {
MagType::Bhirava
}
}
_ => unreachable!()
}
},
CharacterClass::FOmar | CharacterClass::FOmarl | CharacterClass::FOnewm | CharacterClass::FOnewearl => {
match (mag_attr_ordering, self.def() >= 45) {
(MagAttributeOrdering::Primary(MagAttribute::Pow), true) => MagType::Andhaka,
(MagAttributeOrdering::Primary(MagAttribute::Dex), true) => MagType::Bana,
(MagAttributeOrdering::Primary(MagAttribute::Mind), true) => MagType::Bana,
(MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Dex, MagAttribute::Mind), true) => MagType::Andhaka,
(MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Mind, MagAttribute::Dex), true) => MagType::Andhaka,
(MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Pow, MagAttribute::Mind), true) => MagType::Bana,
(MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Mind, MagAttribute::Pow), true) => MagType::Bana,
(MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Pow, MagAttribute::Dex), true) => MagType::Bana,
(MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Dex, MagAttribute::Pow), true) => MagType::Bana,
(MagAttributeOrdering::MultiPrimary, true) => MagType::Bana,
(MagAttributeOrdering::Primary(MagAttribute::Pow), false) => MagType::Naraka,
(MagAttributeOrdering::Primary(MagAttribute::Dex), false) => MagType::Sita,
(MagAttributeOrdering::Primary(MagAttribute::Mind), false) => MagType::Naga,
(MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Dex, MagAttribute::Mind), false) => MagType::Naraka,
(MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Mind, MagAttribute::Dex), false) => MagType::Ravana,
(MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Pow, MagAttribute::Mind), false) => MagType::Ribhava,
(MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Mind, MagAttribute::Pow), false) => MagType::Sita,
(MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Pow, MagAttribute::Dex), false) => MagType::Naga,
(MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Dex, MagAttribute::Pow), false) => MagType::Kabanda,
(MagAttributeOrdering::MultiPrimary, false) => {
if self.pow >= self.dex {
MagType::Naga
}
else {
MagType::Kabanda
}
}
_ => unreachable!()
}
},
}
},
SectionID::Greenill | SectionID::Bluefull | SectionID::Pinkal | SectionID::Oran | SectionID::Whitill => {
match self.class {
CharacterClass::HUmar | CharacterClass::HUnewearl | CharacterClass::HUcast | CharacterClass::HUcaseal => {
match mag_attr_ordering {
MagAttributeOrdering::Primary(MagAttribute::Pow) => MagType::Kama,
MagAttributeOrdering::Primary(MagAttribute::Dex) => MagType::Yaksa,
MagAttributeOrdering::Primary(MagAttribute::Mind) => MagType::Bana,
MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Dex, MagAttribute::Mind) => MagType::Kama,
MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Mind, MagAttribute::Dex) => MagType::Apsaras,
MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Pow, MagAttribute::Mind) => MagType::Garuda,
MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Mind, MagAttribute::Pow) => MagType::Yaksa,
MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Pow, MagAttribute::Dex) => MagType::Bana,
MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Dex, MagAttribute::Pow) => MagType::Soma,
MagAttributeOrdering::MultiPrimary => {
if self.dex >= self.mnd {
MagType::Kama
}
else {
MagType::Apsaras
}
}
_ => unreachable!()
}
},
CharacterClass::RAmar | CharacterClass::RAmarl | CharacterClass::RAcast | CharacterClass::RAcaseal => {
match mag_attr_ordering {
MagAttributeOrdering::Primary(MagAttribute::Pow) => MagType::Madhu,
MagAttributeOrdering::Primary(MagAttribute::Dex) => MagType::Varaha,
MagAttributeOrdering::Primary(MagAttribute::Mind) => MagType::Kabanda,
MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Dex, MagAttribute::Mind) => MagType::Madhu,
MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Mind, MagAttribute::Dex) => MagType::Kaitabha,
MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Pow, MagAttribute::Mind) => MagType::Kaitabha,
MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Mind, MagAttribute::Pow) => MagType::Varaha,
MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Pow, MagAttribute::Dex) => MagType::Kabanda,
MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Dex, MagAttribute::Pow) => MagType::Durga,
MagAttributeOrdering::MultiPrimary => {
if self.pow > self.mnd {
MagType::Kaitabha
}
else {
MagType::Varaha
}
}
_ => unreachable!()
}
},
CharacterClass::FOmar | CharacterClass::FOmarl | CharacterClass::FOnewm | CharacterClass::FOnewearl => {
match (mag_attr_ordering, self.def() >= 45) {
(MagAttributeOrdering::Primary(MagAttribute::Pow), true) => MagType::Andhaka,
(MagAttributeOrdering::Primary(MagAttribute::Dex), true) => MagType::Bana,
(MagAttributeOrdering::Primary(MagAttribute::Mind), true) => MagType::Bana,
(MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Dex, MagAttribute::Mind), true) => MagType::Andhaka,
(MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Mind, MagAttribute::Dex), true) => MagType::Andhaka,
(MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Pow, MagAttribute::Mind), true) => MagType::Bana,
(MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Mind, MagAttribute::Pow), true) => MagType::Bana,
(MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Pow, MagAttribute::Dex), true) => MagType::Bana,
(MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Dex, MagAttribute::Pow), true) => MagType::Bana,
(MagAttributeOrdering::MultiPrimary, true) => MagType::Bana,
(MagAttributeOrdering::Primary(MagAttribute::Pow), false) => MagType::Marica,
(MagAttributeOrdering::Primary(MagAttribute::Dex), false) => MagType::Bhirava,
(MagAttributeOrdering::Primary(MagAttribute::Mind), false) => MagType::Kumara,
(MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Dex, MagAttribute::Mind), false) => MagType::Marica,
(MagAttributeOrdering::Sequence(MagAttribute::Pow, MagAttribute::Mind, MagAttribute::Dex), false) => MagType::Naga,
(MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Pow, MagAttribute::Mind), false) => MagType::Garuda,
(MagAttributeOrdering::Sequence(MagAttribute::Dex, MagAttribute::Mind, MagAttribute::Pow), false) => MagType::Bhirava,
(MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Pow, MagAttribute::Dex), false) => MagType::Kumara,
(MagAttributeOrdering::Sequence(MagAttribute::Mind, MagAttribute::Dex, MagAttribute::Pow), false) => MagType::Ila,
(MagAttributeOrdering::MultiPrimary, false) => {
if self.pow >= self.dex {
MagType::Kumara
}
else {
MagType::Ila
}
}
_ => unreachable!()
}
},
}
}
};
}
if self.level() >= 100 && self.level() % 5 == 0 {
match self.id {
SectionID::Skyly | SectionID::Pinkal | SectionID::Yellowboze => {
if self.def() + self.pow() == self.dex() + self.mind() {
self.mag = match self.class {
CharacterClass::HUmar | CharacterClass::HUcast => {
MagType::Rati
},
CharacterClass::HUnewearl | CharacterClass::HUcaseal => {
MagType::Savitri
},
CharacterClass::RAmar | CharacterClass::RAcast => {
MagType::Pushan
},
CharacterClass::RAmarl | CharacterClass::RAcaseal => {
MagType::Diwari
},
CharacterClass::FOmar | CharacterClass::FOnewm => {
MagType::Nidra
},
CharacterClass::FOmarl | CharacterClass::FOnewearl => {
MagType::Bhima
},
}
}
},
SectionID::Viridia | SectionID::Bluefull | SectionID::Redria | SectionID::Whitill => {
if self.def() + self.dex() == self.pow() + self.mind() {
self.mag = match self.class {
CharacterClass::HUmar | CharacterClass::HUcast => {
MagType::Deva
},
CharacterClass::HUnewearl | CharacterClass::HUcaseal => {
MagType::Savitri
},
CharacterClass::RAmar | CharacterClass::RAcast => {
MagType::Pushan
},
CharacterClass::RAmarl | CharacterClass::RAcaseal => {
MagType::Rukmin
},
CharacterClass::FOmar | CharacterClass::FOnewm => {
MagType::Nidra
},
CharacterClass::FOmarl | CharacterClass::FOnewearl => {
MagType::Sato // best mag
},
}
}
},
SectionID::Greenill | SectionID::Purplenum | SectionID::Oran => {
if self.def() + self.mind() == self.pow() + self.dex() {
self.mag = match self.class {
CharacterClass::HUmar | CharacterClass::HUcast => {
MagType::Rati
},
CharacterClass::HUnewearl | CharacterClass::HUcaseal => {
MagType::Savitri
},
CharacterClass::RAmar | CharacterClass::RAcast => {
MagType::Pushan
},
CharacterClass::RAmarl | CharacterClass::RAcaseal => {
MagType::Rukmin
},
CharacterClass::FOmar | CharacterClass::FOnewm => {
MagType::Nidra
},
CharacterClass::FOmarl | CharacterClass::FOnewearl => {
MagType::Bhima
},
}
}
}
}
}
}
pub fn assign_photon_blast(&mut self) {
MAG_STATS.get(&self.mag).map(|stats| {
stats.photon_blast.map(|photon_blast| {
if !self.photon_blast.contains(&Some(photon_blast)) {
if let Some(pb_slot) = self.photon_blast.iter_mut().find(|k| k.is_none()) {
*pb_slot = Some(photon_blast)
}
}
})
});
}
pub fn feed(&mut self, tool: ToolType) {
let previous_level = self.level();
MAG_STATS.get(&self.mag).map(|stats| {
MAG_FEEDING_TABLES.get(stats.feed_table).map(|feeding_table| {
feeding_table.get(&tool).map(|feed_stats| {
self.def = std::cmp::max(std::cmp::max((self.def as i16) + feed_stats.def, 0) as u16, self.def()*100);
self.pow = std::cmp::max(std::cmp::max((self.pow as i16) + feed_stats.pow, 0) as u16, self.pow()*100);
self.dex = std::cmp::max(std::cmp::max((self.dex as i16) + feed_stats.dex, 0) as u16, self.dex()*100);
self.mnd = std::cmp::max(std::cmp::max((self.mnd as i16) + feed_stats.mnd, 0) as u16, self.mind()*100);
self.iq = std::cmp::min(((self.iq as i16) + feed_stats.iq as i16) as u8, 200);
self.synchro = std::cmp::min(((self.synchro as i8) + feed_stats.syn) as u8, 120);
})
})
});
//if previous_level != self.level() {
self.change_mag_type(previous_level);
self.assign_photon_blast();
//}
}
pub fn change_owner(&mut self, class: CharacterClass, id: SectionID) {
self.class = class;
self.id = id;
}
pub fn bank(&mut self) {
self.def &= 0xFFFE;
self.pow &= 0xFFFE;
self.dex &= 0xFFFE;
self.mnd &= 0xFFFE;
}
// TODO: this needs more checks on validity
pub fn apply_mag_cell(&mut self, mag_cell: MagCell) {
self.mag = match mag_cell {
MagCell::CellOfMag502 => {
match self.id {
SectionID::Viridia | SectionID::Skyly | SectionID::Purplenum | SectionID::Redria | SectionID::Yellowboze => {
MagType::Soniti
},
SectionID::Greenill | SectionID::Bluefull | SectionID::Pinkal | SectionID::Oran | SectionID::Whitill => {
MagType::Pitri
}
}
}
MagCell::CellOfMag213 => {
match self.id {
SectionID::Viridia | SectionID::Skyly | SectionID::Purplenum | SectionID::Redria | SectionID::Yellowboze => {
MagType::Churel
},
SectionID::Greenill | SectionID::Bluefull | SectionID::Pinkal | SectionID::Oran | SectionID::Whitill => {
MagType::Preta
}
}
},
MagCell::PartsOfRobochao => MagType::Robochao,
MagCell::HeartOfOpaOpa => MagType::OpaOpa,
MagCell::HeartOfPian => MagType::Pian,
MagCell::HeartOfChao => MagType::Chao,
MagCell::HeartOfAngel => MagType::AngelsWing,
MagCell::HeartOfDevil => if self.mag == MagType::DevilsWing {
MagType::DevilsTail
}
else {
MagType::DevilsWing
},
MagCell::KitOfHamburger => MagType::Hamburger,
MagCell::PanthersSpirit => MagType::PanzersTail,
MagCell::KitOfMark3 => MagType::MarkIII,
MagCell::KitOfMasterSystem => MagType::MasterSystem,
MagCell::KitOfGenesis => MagType::Genesis,
MagCell::KitOfSegaSaturn => MagType::SegaSaturn,
MagCell::KitOfDreamcast => MagType::Dreamcast,
MagCell::Tablet => MagType::GeungSi,
MagCell::DragonScale => MagType::Tellusis,
MagCell::HeavenStrikerCoat => MagType::StrikerUnit,
MagCell::PioneerParts => MagType::Pioneer,
MagCell::AmitiesMemo => MagType::Puyo,
MagCell::HeartOfMorolian => MagType::Moro,
MagCell::RappysBeak => MagType::Rappy,
MagCell::YahoosEngine => MagType::Yahoo,
MagCell::DPhotonCore => MagType::GaelGiel,
MagCell::LibertaKit => MagType::Agastya,
}
}
// TODO: is this even needed? mags are not shop sellable...yet
pub fn is_rare_item(self) -> bool {
matches!(
self.mag,
MagType::Pitri
| MagType::Soniti
| MagType::Preta
| MagType::Churel
| MagType::Robochao
| MagType::OpaOpa
| MagType::Pian
| MagType::Chao
| MagType::ChuChu
| MagType::KapuKapu
| MagType::AngelsWing
| MagType::DevilsWing
| MagType::Elenor
| MagType::MarkIII
| MagType::MasterSystem
| MagType::Genesis
| MagType::SegaSaturn
| MagType::Dreamcast
| MagType::Hamburger
| MagType::PanzersTail
| MagType::DevilsTail
| MagType::Deva
| MagType::Rati
| MagType::Savitri
| MagType::Rukmin
| MagType::Pushan
| MagType::Diwari
| MagType::Sato
| MagType::Bhima
| MagType::Nidra
| MagType::GeungSi
| MagType::Tellusis
| MagType::StrikerUnit
| MagType::Pioneer
| MagType::Puyo
| MagType::Moro
| MagType::Rappy
| MagType::Yahoo
| MagType::GaelGiel
| MagType::Agastya
)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::io::Read;
#[test]
fn test_load_mag_stats() {
let mut f = std::fs::File::open("data/item_stats/mag_stats.toml").unwrap();
let mut s = String::new();
f.read_to_string(&mut s).unwrap();
let mags: HashMap<String, MagStats> = toml::from_str(&s).unwrap();
let _mags = mags.into_iter()
.map(|(name, stats)| {
(name.parse().unwrap(), stats)
})
.collect::<HashMap<MagType, MagStats>>();
}
#[test]
fn test_load_mag_feed_table() {
let mut f = std::fs::File::open("data/item_stats/mag_feed_table.toml").unwrap();
let mut s = String::new();
f.read_to_string(&mut s).unwrap();
let mut feed: HashMap<String, Vec<HashMap<String, MagFeedTable>>> = toml::from_str(&s).unwrap();
let feed = feed.remove("feedtable".into()).unwrap();
let _feed = feed.into_iter()
.map(|table| {
table.into_iter()
.map(|(tool, stats)| {
(tool.parse().unwrap(), stats)
})
.collect()
})
.collect::<Vec<HashMap<ToolType, MagFeedTable>>>();
}
#[test]
fn test_raise_a_sato() {
let mut mag = Mag::baby_mag(0);
mag.change_owner(CharacterClass::RAcaseal, SectionID::Whitill);
for _ in 0..137 {
mag.feed(ToolType::Antidote);
}
for _ in 0..75 {
mag.feed(ToolType::Antiparalysis);
}
mag.change_owner(CharacterClass::FOmarl, SectionID::Whitill);
for _ in 0..51 {
mag.feed(ToolType::Antiparalysis);
}
for _ in 0..284 {
mag.feed(ToolType::Dimate);
}
assert!(mag == Mag {
mag: MagType::Sato,
def: 507,
pow: 5019,
dex: 4505,
mnd: 0,
synchro: 120,
iq: 200,
photon_blast: [Some(PhotonBlast::Estlla), Some(PhotonBlast::Pilla), Some(PhotonBlast::MyllaYoulla)],
color: 0,
class: CharacterClass::FOmarl,
id: SectionID::Whitill,
});
}
#[test]
fn test_mag_does_not_level_down() {
}
}