elseware/src/entity/item/esweapon.rs

226 lines
6.5 KiB
Rust
Raw Normal View History

2020-09-06 02:16:46 -03:00
// TODO: actually use this
#[derive(Debug)]
pub enum ESWeaponError {
InvalidESWeaponType,
InvalidESWeaponSpecial,
InvalidESWeaponName,
2020-09-06 02:16:46 -03:00
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ESWeaponType {
2020-09-06 02:16:46 -03:00
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 ESWeaponType {
2020-09-06 02:16:46 -03:00
pub fn to_value(&self) -> u8 {
*self as u8
}
pub fn from_value(value: u8) -> Result<ESWeaponType, ESWeaponError> {
2020-09-06 02:16:46 -03:00
match value {
0 => Ok(ESWeaponType::Saber),
1 => Ok(ESWeaponType::Sword),
2 => Ok(ESWeaponType::Blade),
3 => Ok(ESWeaponType::Partisan),
4 => Ok(ESWeaponType::Slicer),
5 => Ok(ESWeaponType::Gun),
6 => Ok(ESWeaponType::Rifle),
7 => Ok(ESWeaponType::Mechgun),
8 => Ok(ESWeaponType::Shot),
9 => Ok(ESWeaponType::Can),
10 => Ok(ESWeaponType::Rod),
11 => Ok(ESWeaponType::Wand),
12 => Ok(ESWeaponType::Twin),
13 => Ok(ESWeaponType::Claw),
14 => Ok(ESWeaponType::Bazooka),
15 => Ok(ESWeaponType::Needle),
16 => Ok(ESWeaponType::Scythe),
17 => Ok(ESWeaponType::Hammer),
18 => Ok(ESWeaponType::Moon),
19 => Ok(ESWeaponType::Psychogun),
20 => Ok(ESWeaponType::Punch),
21 => Ok(ESWeaponType::Windmill),
22 => Ok(ESWeaponType::Harisen),
23 => Ok(ESWeaponType::Katana),
24 => Ok(ESWeaponType::JCutter),
25 => Ok(ESWeaponType::Swords),
26 => Ok(ESWeaponType::Launcher),
27 => Ok(ESWeaponType::Cards),
28 => Ok(ESWeaponType::Knuckle),
29 => Ok(ESWeaponType::Axe),
_ => Err(ESWeaponError::InvalidESWeaponType),
2020-09-06 02:16:46 -03:00
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ESWeaponSpecial {
2020-09-06 02:16:46 -03:00
Jellen = 0,
Zalure,
HPRegen,
TPRegen,
Burning,
Tempest,
Blizzard,
Arrest,
Chaos,
Hell,
Spirit,
Berserk,
Demons,
Gush,
Geist,
Kings,
}
impl ESWeaponSpecial {
2020-09-06 02:16:46 -03:00
pub fn to_value(&self) -> u8 {
*self as u8
}
pub fn from_value(value: u8) -> Result<ESWeaponSpecial, ESWeaponError> {
2020-09-06 02:16:46 -03:00
match value{
0 => Ok(ESWeaponSpecial::Jellen),
1 => Ok(ESWeaponSpecial::Zalure),
2 => Ok(ESWeaponSpecial::HPRegen),
3 => Ok(ESWeaponSpecial::TPRegen),
4 => Ok(ESWeaponSpecial::Burning),
5 => Ok(ESWeaponSpecial::Tempest),
6 => Ok(ESWeaponSpecial::Blizzard),
7 => Ok(ESWeaponSpecial::Arrest),
8 => Ok(ESWeaponSpecial::Chaos),
9 => Ok(ESWeaponSpecial::Hell),
10 => Ok(ESWeaponSpecial::Spirit),
11 => Ok(ESWeaponSpecial::Berserk),
12 => Ok(ESWeaponSpecial::Demons),
13 => Ok(ESWeaponSpecial::Gush),
14 => Ok(ESWeaponSpecial::Geist),
15 => Ok(ESWeaponSpecial::Kings),
_ => Err(ESWeaponError::InvalidESWeaponSpecial),
2020-09-06 02:16:46 -03:00
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct ESWeapon {
pub esweapon: ESWeaponType,
pub special: Option<ESWeaponSpecial>,
2020-09-06 02:16:46 -03:00
pub name: String,
pub grind: u8,
}
impl ESWeapon {
pub fn new(t: ESWeaponType) -> ESWeapon {
ESWeapon {
esweapon: t,
2020-09-06 02:16:46 -03:00
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<u8> = 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.esweapon.to_value();
result[2] = self.special.map(|s| s.to_value()).unwrap_or(0);
2020-09-06 02:16:46 -03:00
result[3] = self.grind;
//result[4] = tekked/untekked flag
result[6..12].clone_from_slice(&self.bytes_from_name());
2020-09-06 02:16:46 -03:00
result
}
// TODO: return Result<ESWeapon, ESWeaponError>
pub fn from_bytes(bytes: [u8; 16]) -> ESWeapon {
let esweapon = ESWeaponType::from_value(bytes[1] - 0x70).unwrap();
let special = ESWeaponSpecial::from_value(bytes[2]);
2020-09-06 02:16:46 -03:00
let grind = bytes[3];
let name = ESWeapon::name_from_bytes(&bytes[6..12]);
2020-09-06 02:16:46 -03:00
ESWeapon {
esweapon: esweapon,
special: special.ok(),
2020-09-06 02:16:46 -03:00
grind: grind,
name: name,
}
}
}