From 3184c79c3c7d7e2511e2fd2e4cb90b0f80f472fc Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 28 Aug 2020 17:32:24 -0600 Subject: [PATCH] basic mag evolution --- src/entity/character.rs | 4 +- src/entity/item/mag.rs | 586 +++++++++++++++++++++++++++++++++++++++- src/entity/item/tool.rs | 36 +++ src/lib.rs | 2 + 4 files changed, 614 insertions(+), 14 deletions(-) diff --git a/src/entity/character.rs b/src/entity/character.rs index fc87569..4fc6383 100644 --- a/src/entity/character.rs +++ b/src/entity/character.rs @@ -7,7 +7,7 @@ use libpso::character::character::{DEFAULT_PALETTE_CONFIG, DEFAULT_TECH_MENU}; use crate::entity::item::tech::Technique; use crate::entity::account::UserAccountId; -#[derive(Copy, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum CharacterClass { HUmar, HUnewearl, @@ -64,7 +64,7 @@ impl Into for CharacterClass { } -#[derive(Copy, Clone, Hash, PartialEq, Eq, derive_more::Display)] +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, derive_more::Display)] pub enum SectionID { Viridia, Greenill, diff --git a/src/entity/item/mag.rs b/src/entity/item/mag.rs index 0669789..442bdc2 100644 --- a/src/entity/item/mag.rs +++ b/src/entity/item/mag.rs @@ -1,21 +1,25 @@ use std::collections::HashMap; use serde::{Serialize, Deserialize}; use crate::entity::item::tool::ToolType; +use crate::entity::character::{CharacterClass, SectionID}; use std::io::Read; +use std::cmp::Ordering::{Less, Greater, Equal}; + #[derive(Debug, Deserialize)] struct MagStats { - feed_table: u32, + feed_table: usize, + photon_blast: Option } #[derive(Debug, Deserialize)] struct MagFeedTable { - def: i32, - pow: i32, - dex: i32, - mnd: i32, - iq: i32, - syn: i32, + def: i16, + pow: i16, + dex: i16, + mnd: i16, + iq: i8, + syn: i8, } lazy_static::lazy_static! { @@ -302,6 +306,144 @@ impl MagType { _ => 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, + } + } +} + + +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)] @@ -311,9 +453,10 @@ pub enum MagModifier { }, BankMag, // when putting a mag in the bank it truncates the values which has applications when raising degenerate mags MagCell(ToolType), + OwnerChange(CharacterClass, SectionID) } -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Deserialize, enum_utils::FromStr)] pub enum PhotonBlast { Farlla, Estlla, @@ -334,7 +477,9 @@ pub struct Mag { iq: u8, photon_blast: [Option; 3], pub color: u8, - modifiers: Vec, + //modifiers: Vec, + class: CharacterClass, + id: SectionID, } @@ -350,7 +495,9 @@ impl Mag { iq: 0, photon_blast: [None; 3], color: (skin % 18) as u8, - modifiers: Vec::new(), + //modifiers: Vec::new(), + class: CharacterClass::HUmar, + id: SectionID::Viridia, } } @@ -422,7 +569,7 @@ impl Mag { } pub fn from_bytes(data: [u8; 16]) -> Result { - let m = MagType::parse_type([data[0], data[1], data[2]]); + 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]]); @@ -449,7 +596,9 @@ impl Mag { iq: iq, photon_blast: [None, None, None], // TODO: actually get PBs from bytes color: data[15] % 18, - modifiers: Vec::new(), + //modifiers: Vec::new(), + class: CharacterClass::HUmar, + id: SectionID::Viridia, }) } else { @@ -457,6 +606,382 @@ impl Mag { } } + 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 => { + 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)) { + self.photon_blast.iter_mut().find(|k| k.is_none()).map(|pb_slot| { + *pb_slot = Some(photon_blast) + }); + } + }) + }); + } + + pub fn feed(&mut self, tool: ToolType) { + if tool.is_mag_cell() { + //do_mag_cell_thing() + } + 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) { + // what is the truncation logic anyway + } +} + #[cfg(test)] mod test { @@ -496,4 +1021,41 @@ mod test { .collect::>>(); } + #[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); + } + //println!("mag! {:?}", mag); + 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() { + } } + diff --git a/src/entity/item/tool.rs b/src/entity/item/tool.rs index de92170..5b95dde 100644 --- a/src/entity/item/tool.rs +++ b/src/entity/item/tool.rs @@ -251,6 +251,42 @@ impl ToolType { } } + pub fn is_mag_cell(&self) -> bool { + match self { + ToolType::CellOfMag502 => true, + ToolType::CellOfMag213 => true, + ToolType::PartsOfRobochao => true, + ToolType::HeartOfOpaOpa => true, + ToolType::HeartOfPian => true, + ToolType::HeartOfChao => true, + ToolType::HeartOfAngel => true, + ToolType::HeartOfDevil => true, + ToolType::KitOfHamburger => true, + ToolType::PanthersSpirit => true, + ToolType::KitOfMark3 => true, + ToolType::KitOfMasterSystem => true, + ToolType::KitOfGenesis => true, + ToolType::KitOfSegaSaturn => true, + ToolType::KitOfDreamcast => true, + ToolType::Tablet => true, + ToolType::DragonScale => true, + ToolType::HeavenStrikerCoat => true, + ToolType::PioneerParts => true, + ToolType::AmitiesMemo => true, + ToolType::HeartOfMorolian => true, + ToolType::RappysBeak => true, + ToolType::YahoosEngine => true, + ToolType::DPhotonCore => true, + ToolType::LibertaKit => true, + ToolType::CellOfMag0503 => true, + ToolType::CellOfMag0504 => true, + ToolType::CellOfMag0505 => true, + ToolType::CellOfMag0506 => true, + ToolType::CellOfMag0507 => true, + _ => false, + } + } + pub fn value(&self) -> [u8; 3] { match self { ToolType::Monomate => [0x03, 0x00, 0x00], diff --git a/src/lib.rs b/src/lib.rs index 309b324..abd1d14 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,8 @@ #![feature(maybe_uninit_extra)] #![feature(const_in_array_repeat_expressions)] #![feature(drain_filter)] +#![feature(or_patterns)] +