elseware/src/entity/character.rs

343 lines
8.4 KiB
Rust
Raw Normal View History

use std::convert::{From, Into};
use std::collections::HashMap;
use serde::{Serialize, Deserialize};
use libpso::packet::ship::{UpdateConfig, WriteInfoboard};
use libpso::character::character::{DEFAULT_PALETTE_CONFIG, DEFAULT_TECH_MENU};
2020-03-18 18:21:34 -07:00
use crate::entity::item::tech::Technique;
use crate::entity::account::UserAccountId;
2021-09-27 23:06:21 -06:00
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, enum_utils::FromStr, derive_more::Display, Serialize, Deserialize, Default)]
pub enum CharacterClass {
2021-09-27 23:06:21 -06:00
#[default]
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,
2020-03-21 21:44:48 -07:00
10 => CharacterClass::FOmar,
11 => CharacterClass::RAmarl,
_ => panic!("unknown class")
}
}
}
2021-06-18 19:09:14 -06:00
impl From<CharacterClass> for u8 {
fn from(other: CharacterClass) -> u8 {
match other {
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,
2020-03-21 21:44:48 -07:00
CharacterClass::FOmar => 10,
CharacterClass::RAmarl => 11,
}
}
}
2020-11-14 15:30:37 -04:00
impl CharacterClass {
pub fn is_human(&self) -> bool {
2021-06-18 19:09:14 -06:00
matches!(self,
CharacterClass::HUmar |
CharacterClass::RAmar |
CharacterClass::RAmarl |
CharacterClass::FOmar |
CharacterClass::FOmarl)
2020-11-14 15:30:37 -04:00
}
pub fn is_newman(&self) -> bool {
2021-06-18 19:09:14 -06:00
matches!(self,
CharacterClass::HUnewearl |
CharacterClass::FOnewm |
CharacterClass::FOnewearl)
2020-11-14 15:30:37 -04:00
}
pub fn is_android(&self) -> bool {
2021-06-18 19:09:14 -06:00
matches!(self,
CharacterClass::HUcast |
CharacterClass::HUcaseal |
CharacterClass::RAcast |
CharacterClass::RAcaseal)
2020-11-14 15:30:37 -04:00
}
}
2021-09-27 23:06:21 -06:00
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, enum_utils::FromStr, derive_more::Display, Serialize, Deserialize, Default)]
pub enum SectionID {
2021-09-27 23:06:21 -06:00
#[default]
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!(),
}
}
}
2021-06-18 19:09:14 -06:00
impl From<SectionID> for u8 {
fn from(other: SectionID) -> u8 {
match other {
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)]
pub struct TechLevel(pub u8);
#[derive(Clone, Debug)]
pub struct CharacterTechniques {
pub techs: HashMap<Technique, TechLevel>
}
2021-09-27 23:06:21 -06:00
impl Default for CharacterTechniques {
fn default() -> CharacterTechniques {
CharacterTechniques {
techs: HashMap::new(),
}
}
2021-09-27 23:06:21 -06:00
}
2021-09-27 23:06:21 -06:00
impl CharacterTechniques {
pub fn set_tech(&mut self, tech: Technique, level: TechLevel) {
self.techs.insert(tech, TechLevel(level.0 - 1));
}
// from_bytes
pub fn as_bytes(&self) -> [u8; 20] {
self.techs.iter()
.fold([0xFF; 20], |mut techlist, (tech, level)| {
2020-04-27 06:55:18 -06:00
let index = tech.as_value();
techlist[index as usize] = level.0;
techlist
})
}
}
2021-12-10 13:14:50 -07:00
#[derive(Debug, Clone)]
pub struct CharacterConfig {
pub raw_data: [u8; 0xE8],
}
2021-09-27 23:06:21 -06:00
impl Default for CharacterConfig {
fn default() -> CharacterConfig {
CharacterConfig {
raw_data: DEFAULT_PALETTE_CONFIG,
}
}
2021-09-27 23:06:21 -06:00
}
2021-09-27 23:06:21 -06:00
impl CharacterConfig {
pub fn update(&mut self, new_config: &UpdateConfig) {
self.raw_data = new_config.config;
}
pub fn as_bytes(&self) -> [u8; 0xE8] {
self.raw_data
}
}
2021-12-10 13:14:50 -07:00
#[derive(Debug, Clone)]
pub struct CharacterInfoboard {
pub board: [u16; 172],
}
2021-09-27 23:06:21 -06:00
impl Default for CharacterInfoboard {
fn default() -> CharacterInfoboard {
CharacterInfoboard {
board: [0; 172]
}
}
2021-09-27 23:06:21 -06:00
}
2021-09-27 23:06:21 -06:00
impl CharacterInfoboard {
2020-03-01 02:57:18 -04:00
pub fn as_bytes(&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);
}
}
2021-12-10 13:14:50 -07:00
#[derive(Debug, Clone, Default)]
pub struct CharacterGuildCard {
pub description: String,
}
2021-12-10 13:14:50 -07:00
#[derive(Debug, Clone)]
2020-04-20 00:29:23 -03:00
pub struct CharacterTechMenu {
pub tech_menu: [u8; 40],
}
2021-09-27 23:06:21 -06:00
impl Default for CharacterTechMenu {
fn default() -> CharacterTechMenu {
2020-04-20 00:29:23 -03:00
CharacterTechMenu {
tech_menu: DEFAULT_TECH_MENU,
2020-04-20 00:29:23 -03:00
}
}
2021-09-27 23:06:21 -06:00
}
2020-04-20 00:29:23 -03:00
2021-09-27 23:06:21 -06:00
impl CharacterTechMenu {
2020-04-20 00:29:23 -03:00
pub fn as_bytes(&self) -> [u8; 40] {
self.tech_menu
}
}
2021-12-10 13:14:50 -07:00
#[derive(Clone, Default, Debug)]
2020-06-10 21:23:10 -06:00
pub struct CharacterMaterials {
pub power: u32,
pub mind: u32,
pub def: u32,
pub evade: u32,
pub luck: u32,
pub hp: u32,
pub tp: u32,
}
2020-03-29 14:40:24 -07:00
2021-12-10 23:41:17 -07:00
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Default, derive_more::Display)]
2020-03-29 14:40:24 -07:00
pub struct CharacterEntityId(pub u32);
#[derive(Clone)]
pub struct NewCharacterEntity {
pub user_id: UserAccountId,
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,
pub guildcard: CharacterGuildCard,
2020-06-10 21:23:10 -06:00
pub materials: CharacterMaterials,
2020-04-20 00:29:23 -03:00
pub tech_menu: CharacterTechMenu,
2020-10-02 21:24:32 -03:00
pub option_flags: u32,
}
impl NewCharacterEntity {
pub fn new(user: UserAccountId) -> NewCharacterEntity {
NewCharacterEntity {
2020-03-29 22:00:07 -07:00
user_id: user,
slot: 0,
name: "".into(),
exp: 0,
char_class: CharacterClass::HUmar,
section_id: SectionID::Viridia,
appearance: CharacterAppearance::default(),
2021-09-27 23:06:21 -06:00
techs: CharacterTechniques::default(),
config: CharacterConfig::default(),
info_board: CharacterInfoboard::default(),
guildcard: CharacterGuildCard::default(),
2020-06-10 21:23:10 -06:00
materials: CharacterMaterials::default(),
2021-09-27 23:06:21 -06:00
tech_menu: CharacterTechMenu::default(),
2020-10-02 21:24:32 -03:00
option_flags: 0,
}
}
2019-11-20 22:49:13 -08:00
}
2021-12-10 13:14:50 -07:00
#[derive(Clone, Default, Debug)]
pub struct CharacterEntity {
pub id: CharacterEntityId,
pub user_id: UserAccountId,
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,
pub guildcard: CharacterGuildCard,
2020-06-10 21:23:10 -06:00
pub materials: CharacterMaterials,
2020-04-20 00:29:23 -03:00
pub tech_menu: CharacterTechMenu,
2020-10-02 21:24:32 -03:00
pub option_flags: u32,
}