// TODO: actually use this pub enum SrankError { InvalidSrankType, InvalidSrankSpecial, InvalidSrankName, } pub enum SrankType { Saber = 0, Sword, Blade, Partisan, Slicer, Gun, Rifle, Mechgun, Shot, Can, Rod, Wand, Twin, Claw, Bazooka, Needle, Scythe, Hammer, Moon, Psychogun, Punch, Windmill, Harisen, Katana, JCutter, Swords, Launcher, Cards, Knuckle, Axe, } impl SrankType { pub fn to_value(&self) -> u8 { *self as u8 } pub fn from_value(value: u8) -> Result { match value { 0 => Ok(SrankType::Saber), 1 => Ok(SrankType::Sword), 2 => Ok(SrankType::Blade), 3 => Ok(SrankType::Partisan), 4 => Ok(SrankType::Slicer), 5 => Ok(SrankType::Gun), 6 => Ok(SrankType::Rifle), 7 => Ok(SrankType::Mechgun), 8 => Ok(SrankType::Shot), 9 => Ok(SrankType::Can), 10 => Ok(SrankType::Rod), 11 => Ok(SrankType::Wand), 12 => Ok(SrankType::Twin), 13 => Ok(SrankType::Claw), 14 => Ok(SrankType::Bazooka), 15 => Ok(SrankType::Needle), 16 => Ok(SrankType::Scythe), 17 => Ok(SrankType::Hammer), 18 => Ok(SrankType::Moon), 19 => Ok(SrankType::Psychogun), 20 => Ok(SrankType::Punch), 21 => Ok(SrankType::Windmill), 22 => Ok(SrankType::Harisen), 23 => Ok(SrankType::Katana), 24 => Ok(SrankType::JCutter), 25 => Ok(SrankType::Swords), 26 => Ok(SrankType::Launcher), 27 => Ok(SrankType::Cards), 28 => Ok(SrankType::Knuckle), 29 => Ok(SrankType::Axe), _ => Err(SrankError::InvalidSrankype), } } } pub enum SrankSpecial { Jellen = 0, Zalure, HPRegen, TPRegen, Burning, Tempest, Blizzard, Arrest, Chaos, Hell, Spirit, Berserk, Demons, Gush, Geist, Kings, } impl SrankSpecial { pub fn to_value(&self) -> u8 { *self as u8 } pub fn from_value(value: u8) -> Result { match value{ 0 => Ok(SrankSpecial::Jellen), 1 => Ok(SrankSpecial::Zalure), 2 => Ok(SrankSpecial::HPRegen), 3 => Ok(SrankSpecial::TPRegen), 4 => Ok(SrankSpecial::Burning), 5 => Ok(SrankSpecial::Tempest), 6 => Ok(SrankSpecial::Blizzard), 7 => Ok(SrankSpecial::Arrest), 8 => Ok(SrankSpecial::Chaos), 9 => Ok(SrankSpecial::Hell), 10 => Ok(SrankSpecial::Spirit), 11 => Ok(SrankSpecial::Berserk), 12 => Ok(SrankSpecial::Demons), 13 => Ok(SrankSpecial::Gush), 14 => Ok(SrankSpecial::Geist), 15 => Ok(SrankSpecial::Kings), _ => Err(SrankError::InvalidSrankSpecial), } } } pub struct SRankWeapon { pub type: SrankType, pub special: Option, pub name: String, pub grind: u8, } impl SRankWeapon { pub fn new(t: SrankType) -> SRankWeapon { SRankWeapon { type: t, special: None, name: "".to_owned(), grind: 0, } } pub fn bytes_from_name(&self) -> [u8; 6] { let mut result = [0u16; 3]; let mut letters = [0u8; 8]; letters[0..self.name.len()].clone_from_slice(&self.name.to_uppercase().clone().into_bytes()); for letter in letters.iter_mut() { *letter = *letter & 0x3F; } result[0] = 0x8000 + (0x20 * letters[0] as u16) + (letters[1] as u16); result[1] = 0x8000 + (0x400 * letters[2] as u16) + (0x20 * letters[3] as u16) + (letters[4] as u16); result[2] = 0x8000 + (0x400 * letters[5] as u16) + (0x20 * letters[6] as u16) + (letters[7] as u16); [result[0].to_be_bytes()[0], result[0].to_be_bytes()[1], result[1].to_be_bytes()[0], result[1].to_be_bytes()[1], result[2].to_be_bytes()[0], result[2].to_be_bytes()[1]] } // TODO: error handling, ensure name is never more than 8 pub fn name_from_bytes(namebytes: &[u8]) -> String { let mut name: Vec = Vec::with_capacity(8); name.extend_from_slice(namebytes); for _ in name.len()..name.capacity() { name.push(0); } let buf: [u16; 3] = [ u16::from_be_bytes([namebytes[0], namebytes[1]]), u16::from_be_bytes([namebytes[2], namebytes[3]]), u16::from_be_bytes([namebytes[4], namebytes[5]]), ]; name[0] = ((buf[0] - 0x8000) / 0x20 + 0x40) as u8; name[1] = ((buf[0] - 0x8000) % 0x20 + 0x40) as u8; name[2] = ((buf[1] - 0x8000) / 0x400 + 0x40) as u8; name[3] = (((buf[1] - 0x8000) % 0x400) / 0x20 + 0x40) as u8; name[4] = (((buf[1] - 0x8000) % 0x400) % 0x20 + 0x40) as u8; name[5] = ((buf[2] - 0x8000) / 0x400 + 0x40) as u8; name[6] = (((buf[2] - 0x8000) % 0x400) / 0x20 + 0x40) as u8; name[7] = (((buf[2] - 0x8000) % 0x400) % 0x20 + 0x40) as u8; name.retain(|&x| x > 0x40 && x < 0x5B); String::from_utf8(name).unwrap() } pub fn as_bytes(&self) -> [u8; 16] { let mut result = [0u8; 16]; result[1] = 0x70 + self.type.to_value(); result[2] = self.special.to_value(); result[3] = self.grind; //result[4] = tekked/untekked flag result[6..12].clone_from_slice(self.name.bytes_from_name()); result } // TODO: return Result pub fn from_bytes(bytes: [u8; 16]) -> SRankWeapon { let type = SrankType.from_value(bytes[1] - 0x70).unwrap(); let special = SrankSpecial.from_value(bytes[2]).unwrap(); let grind = bytes[3]; let name = SRankWeapon::name_from_bytes(bytes[6..12]); SRankWeapon { type: type, special: special, grind: grind, name: name, } } }