2020-08-20 22:53:34 -06:00
use std ::collections ::HashMap ;
2020-03-14 20:26:12 -07:00
use serde ::{ Serialize , Deserialize } ;
2020-08-20 22:18:31 -06:00
use crate ::entity ::item ::tool ::ToolType ;
2020-08-28 17:32:24 -06:00
use crate ::entity ::character ::{ CharacterClass , SectionID } ;
2020-12-06 04:19:26 +00:00
use crate ::entity ::item ::{ ItemEntityId , WrappingPaper } ;
2020-08-20 22:53:34 -06:00
use std ::io ::Read ;
2020-08-28 17:32:24 -06:00
use std ::cmp ::Ordering ::{ Less , Greater , Equal } ;
2020-08-20 22:53:34 -06:00
#[ derive(Debug, Deserialize) ]
struct MagStats {
2020-08-28 17:32:24 -06:00
feed_table : usize ,
photon_blast : Option < PhotonBlast >
2020-08-20 22:53:34 -06:00
}
#[ derive(Debug, Deserialize) ]
struct MagFeedTable {
2020-08-28 17:32:24 -06:00
def : i16 ,
pow : i16 ,
dex : i16 ,
mnd : i16 ,
iq : i8 ,
syn : i8 ,
2020-08-20 22:53:34 -06:00
}
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 " . into ( ) ) . unwrap ( ) ;
feed . into_iter ( )
. map ( | table | {
table . into_iter ( )
. map ( | ( tool , stats ) | {
( tool . parse ( ) . unwrap ( ) , stats )
} )
. collect ( )
} )
. collect ::< Vec < HashMap < ToolType , MagFeedTable > > > ( )
} ;
}
2020-05-22 18:58:51 -03:00
#[ derive(Debug, Copy, Clone) ]
pub enum ItemParseError {
InvalidMagType ,
InvalidMagBytes ,
}
2020-03-14 20:26:12 -07:00
2020-10-29 22:10:28 -06:00
#[ derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, enum_utils::FromStr, derive_more::Display, strum_macros::EnumIter) ]
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 ,
2020-03-16 23:06:11 -04:00
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 ] ,
2020-03-16 23:06:11 -04:00
MagType ::Bhima = > [ 0x02 , 0x40 , 0x00 ] ,
MagType ::Nidra = > [ 0x02 , 0x41 , 0x00 ] ,
2020-03-31 21:15:01 -07:00
MagType ::GeungSi = > [ 0x02 , 0x42 , 0x00 ] ,
2020-03-16 23:06:11 -04:00
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
}
}
2020-05-22 18:58:51 -03: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-08-28 17:32:24 -06:00
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 ,
}
}
}
2020-09-07 08:02:12 -06:00
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 ( ( ) ) ,
}
}
}
2020-08-28 17:32:24 -06:00
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 ) ,
}
} ,
}
}
2020-03-14 20:26:12 -07:00
}
2020-12-13 20:12:31 +00:00
#[ derive(Debug, Clone, PartialEq, Serialize) ]
2020-08-20 20:19:46 -06:00
pub enum MagModifier {
FeedMag {
2020-09-02 22:03:45 -06:00
food : ItemEntityId ,
2020-08-20 20:19:46 -06:00
} ,
2020-08-20 22:18:31 -06:00
BankMag , // when putting a mag in the bank it truncates the values which has applications when raising degenerate mags
2020-09-02 22:03:45 -06:00
MagCell ( ItemEntityId ) ,
2020-12-13 18:46:28 +00:00
OwnerChange ( CharacterClass , SectionID ) ,
WrapPresent ,
UnwrapPresent ,
2020-08-20 20:19:46 -06:00
}
2020-10-29 19:09:22 -06:00
#[ derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize, enum_utils::FromStr) ]
2020-03-14 20:26:12 -07:00
pub enum PhotonBlast {
Farlla ,
Estlla ,
Leilla ,
Pilla ,
Golla ,
MyllaYoulla ,
}
2021-01-23 04:56:24 +00:00
#[ derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize) ]
2020-03-14 20:26:12 -07:00
pub struct Mag {
2020-03-21 21:46:52 -07:00
pub mag : MagType ,
2020-08-20 22:59:40 -06:00
def : u16 ,
pow : u16 ,
dex : u16 ,
mnd : u16 ,
2020-03-14 20:26:12 -07:00
pub synchro : u8 ,
2020-08-20 22:59:40 -06:00
iq : u8 ,
photon_blast : [ Option < PhotonBlast > ; 3 ] ,
2020-04-19 23:37:48 -03:00
pub color : u8 ,
2020-08-28 17:32:24 -06:00
//modifiers: Vec<MagModifier>,
2020-09-02 22:03:45 -06:00
pub class : CharacterClass ,
pub id : SectionID ,
2020-12-07 02:12:24 +00:00
pub wrapping : Option < WrappingPaper > ,
2020-03-14 20:26:12 -07:00
}
impl Mag {
2020-08-20 22:59:40 -06:00
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 ,
2020-08-28 17:32:24 -06:00
//modifiers: Vec::new(),
class : CharacterClass ::HUmar ,
id : SectionID ::Viridia ,
2020-12-07 02:12:24 +00:00
wrapping : None ,
2020-08-20 22:59:40 -06:00
}
}
2020-12-13 20:12:31 +00:00
pub fn wrapped_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 ,
wrapping : WrappingPaper ::from ( ( skin % 10 ) as u8 ) ,
}
}
2020-03-14 20:26:12 -07:00
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 ( ) ;
2020-12-07 02:12:24 +00:00
if self . wrapping . is_some ( ) {
result [ 14 ] + = 0x40 ;
}
2020-04-19 23:37:48 -03:00
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
}
2020-05-22 18:58:51 -03:00
pub fn from_bytes ( data : [ u8 ; 16 ] ) -> Result < Mag , ItemParseError > {
2020-08-28 17:32:24 -06:00
let m = MagType ::parse_type ( [ data [ 0 ] , data [ 1 ] , data [ 2 ] ] ) ;
2020-05-22 18:58:51 -03:00
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.
2020-12-07 02:12:24 +00:00
let wp = {
if data [ 14 ] & 0x40 = = 0x40 {
WrappingPaper ::from ( data [ 15 ] % 10 ) // % 10 to have valid wrapping paper colour.
} else {
None
}
} ;
2020-05-22 18:58:51 -03:00
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-28 17:32:24 -06:00
//modifiers: Vec::new(),
2020-12-07 02:12:24 +00:00
class : CharacterClass ::HUmar , // TODO: determine character class
id : SectionID ::Viridia , // TODO: determine section id
wrapping : wp ,
2020-05-22 18:58:51 -03:00
} )
}
else {
Err ( ItemParseError ::InvalidMagBytes ) // TODO: error handling if wrong bytes are given
}
}
2020-08-20 22:53:34 -06:00
2020-08-28 17:32:24 -06:00
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 ) {
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 ) {
2020-09-08 18:40:18 -03:00
self . def = self . def & 0xFFFE ;
self . pow = self . pow & 0xFFFE ;
self . dex = self . dex & 0xFFFE ;
2020-09-08 18:40:58 -03:00
self . mnd = self . mnd & 0xFFFE ;
2020-08-28 17:32:24 -06:00
}
2020-09-07 08:02:12 -06:00
2020-09-07 21:46:40 -06:00
// TODO: this needs more checks on validity
2020-09-07 08:02:12 -06:00
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
}
}
}
2020-09-07 21:46:40 -06:00
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
}
}
} ,
2020-09-07 08:02:12 -06:00
MagCell ::PartsOfRobochao = > MagType ::Robochao ,
2020-09-07 21:46:40 -06:00
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 ,
2020-09-07 08:02:12 -06:00
}
}
2020-12-13 18:46:28 +00:00
pub fn apply_modifier ( & mut self , modifier : & MagModifier ) {
match modifier {
2021-01-23 04:56:24 +00:00
MagModifier ::WrapPresent = > { self . wrapping = WrappingPaper ::from ( self . color % 10 ) } , // prevents mag color from crashing wrapping papers. client always shows mags in default paper colour ?
2020-12-13 18:46:28 +00:00
MagModifier ::UnwrapPresent = > { self . wrapping = None } ,
2020-12-13 20:12:31 +00:00
_ = > { } , // TODO: other modifiers are already handled elsewhere. do they need to be moved here?
2020-12-13 18:46:28 +00:00
}
}
2020-08-28 17:32:24 -06:00
}
2020-08-20 22:53:34 -06:00
#[ 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 > > > ( ) ;
}
2020-08-28 17:32:24 -06:00
#[ 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 ,
2020-12-07 02:12:24 +00:00
wrapping : None ,
2020-08-28 17:32:24 -06:00
} ) ;
}
#[ test ]
fn test_mag_does_not_level_down ( ) {
}
2020-03-14 20:26:12 -07:00
}