elseware/src/entity/character.rs

284 lines
6.5 KiB
Rust

use std::convert::{From, Into, TryFrom, TryInto};
use std::collections::HashMap;
use libpso::character::character;
use libpso::packet::ship::{UpdateConfig, WriteInfoboard};
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub enum CharacterClass {
HUmar,
HUnewearl,
HUcast,
HUcaseal,
RAmar,
RAmarl,
RAcast,
RAcaseal,
FOmar,
FOmarl,
FOnewm,
FOnewearl,
}
// TODO: TryFrom
impl From<u8> for CharacterClass {
fn from(f: u8) -> CharacterClass {
match f {
0 => CharacterClass::HUmar,
1 => CharacterClass::HUnewearl,
2 => CharacterClass::HUcast,
3 => CharacterClass::RAmar,
4 => CharacterClass::RAcast,
5 => CharacterClass::RAcaseal,
6 => CharacterClass::FOmarl,
7 => CharacterClass::FOnewm,
8 => CharacterClass::FOnewearl,
9 => CharacterClass::HUcaseal,
10 => CharacterClass::RAmarl,
11 => CharacterClass::FOmar,
_ => panic!("unknown class")
}
}
}
impl Into<u8> for CharacterClass {
fn into(self) -> u8 {
match self {
CharacterClass::HUmar => 0,
CharacterClass::HUnewearl => 1,
CharacterClass::HUcast => 2,
CharacterClass::RAmar => 3,
CharacterClass::RAcast => 4,
CharacterClass::RAcaseal => 5,
CharacterClass::FOmarl => 6,
CharacterClass::FOnewm => 7,
CharacterClass::FOnewearl => 8,
CharacterClass::HUcaseal => 9,
CharacterClass::RAmarl => 10,
CharacterClass::FOmar => 11,
}
}
}
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub enum SectionID {
Viridia,
Greenill,
Skyly,
Bluefull,
Purplenum,
Pinkal,
Redria,
Oran,
Yellowboze,
Whitill,
}
impl From<u8> for SectionID {
fn from(id: u8) -> SectionID {
match id {
0 => SectionID::Viridia,
1 => SectionID::Greenill,
2 => SectionID::Skyly,
3 => SectionID::Bluefull,
4 => SectionID::Purplenum,
5 => SectionID::Pinkal,
6 => SectionID::Redria,
7 => SectionID::Oran,
8 => SectionID::Yellowboze,
9 => SectionID::Whitill,
_ => panic!(),
}
}
}
impl Into<u8> for SectionID {
fn into(self) -> u8 {
match self {
SectionID::Viridia => 0,
SectionID::Greenill => 1,
SectionID::Skyly => 2,
SectionID::Bluefull => 3,
SectionID::Purplenum => 4,
SectionID::Pinkal => 5,
SectionID::Redria => 6,
SectionID::Oran => 7,
SectionID::Yellowboze => 8,
SectionID::Whitill => 9,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct CharacterAppearance {
pub costume: u16,
pub skin: u16,
pub face: u16,
pub head: u16,
pub hair: u16,
pub hair_r: u16,
pub hair_g: u16,
pub hair_b: u16,
pub prop_x: f32,
pub prop_y: f32,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Technique {
Foie,
Gifoie,
Rafoie,
Zonde,
Gizonde,
Razonde,
Barta,
Gibarta,
Rabarta,
Grants,
Megid,
Shifta,
Deband,
Jellen,
Zalure,
Resta,
Anti,
Reverser,
Ryuker,
}
#[derive(Clone, Debug)]
pub struct TechLevel(pub u8);
#[derive(Clone, Debug)]
pub struct CharacterTechniques {
techs: HashMap<Technique, TechLevel>
}
impl CharacterTechniques {
fn new() -> CharacterTechniques {
CharacterTechniques {
techs: HashMap::new(),
}
}
pub fn set_tech(&mut self, tech: Technique, level: TechLevel) {
self.techs.insert(tech, level);
}
// from_bytes
pub fn as_bytes(&self) -> [u8; 20] {
self.techs.iter()
.fold([0xFF; 20], |mut techlist, (tech, level)| {
let index = match tech {
Technique::Foie => 0,
Technique::Gifoie => 1,
Technique::Rafoie => 2,
Technique::Barta => 3,
Technique::Gibarta => 4,
Technique::Rabarta => 5,
Technique::Zonde => 6,
Technique::Gizonde => 7,
Technique::Razonde => 8,
Technique::Grants => 9,
Technique::Deband => 10,
Technique::Jellen => 11,
Technique::Zalure => 12,
Technique::Shifta => 13,
Technique::Ryuker => 14,
Technique::Resta => 15,
Technique::Anti => 16,
Technique::Reverser => 17,
Technique::Megid => 18,
};
techlist[index] = level.0 - 1;
techlist
})
}
}
#[derive(Clone)]
pub struct CharacterConfig {
raw_data: [u8; 0xE8],
}
impl CharacterConfig {
fn new() -> CharacterConfig {
CharacterConfig {
raw_data: [0; 0xE8],
}
}
pub fn update(&mut self, new_config: &UpdateConfig) {
self.raw_data = new_config.config;
}
pub fn as_bytes(&self) -> [u8; 0xE8] {
self.raw_data
}
}
#[derive(Clone)]
pub struct CharacterInfoboard {
board: [u16; 172],
}
impl CharacterInfoboard {
fn new() -> CharacterInfoboard {
CharacterInfoboard {
board: [0; 172]
}
}
pub fn as_bytes(&mut self) -> [u16; 172] {
self.board
}
pub fn update_infoboard(&mut self, new_board: &WriteInfoboard) {
self.board = libpso::utf8_to_utf16_array!(new_board.message, 172);
}
}
#[derive(Clone)]
pub struct Character {
pub id: u32,
pub user_id: u32,
pub slot: u32,
pub name: String,
pub exp: u32,
pub char_class: CharacterClass,
pub section_id: SectionID,
pub appearance: CharacterAppearance,
pub techs: CharacterTechniques,
pub config: CharacterConfig,
pub info_board: CharacterInfoboard,
}
impl std::default::Default for Character {
fn default() -> Character {
Character {
id: 0,
user_id: 0,
slot: 0,
name: "".into(),
exp: 0,
char_class: CharacterClass::HUmar,
section_id: SectionID::Viridia,
appearance: CharacterAppearance::default(),
techs: CharacterTechniques::new(),
config: CharacterConfig::new(),
info_board: CharacterInfoboard::new(),
}
}
}