// TODO: ch_class to CharacterClass enum // TODO: section_id to SectionId enum // TODO: techniques to enum use psopacket::PSOPacketData; use crate::{PSOPacketData, PacketParseError}; //use crate::PSOPacketData; #[derive(PSOPacketData, Default, Copy, Clone)] #[repr(C)] pub struct Character { pub atp: u16, pub mst: u16, pub evp: u16, pub hp: u16, pub dfp: u16, pub ata: u16, pub lck: u16, pub _unknown1: u16, pub _unknown2: [u32; 2], pub level: u32, pub exp: u32, pub meseta: u32, pub guildcard: [u8; 16], pub _unknown3: [u32; 2], pub name_color: u32, pub model: u8, pub _unused: [u8; 11], pub play_time: u32, pub name_color_checksum: u32, pub section_id: u8, pub ch_class: u8, pub v2flags: u8, pub version: u8, pub v1flags: u32, 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, pub name: [u16; 16], //pub config: [u8; 0xE8], pub techniques: [u8; 0x14], } impl Character { pub fn as_select_screen(self) -> SelectScreenCharacter { SelectScreenCharacter { exp: self.exp, level: self.level, guildcard: self.guildcard, _unknown: self._unknown3, name_color: self.name_color, model: self.model, _unused: [0; 15], name_color_checksum: self.name_color_checksum, section_id: self.section_id, ch_class: self.ch_class, v2flags: self.v2flags, version: self.version, v1flags: self.v1flags, costume: self.costume, skin: self.skin, face: self.face, head: self.head, hair: self.hair, hair_r: self.hair_r, hair_g: self.hair_g, hair_b: self.hair_b, prop_x: self.prop_x, prop_y: self.prop_y, name: self.name, play_time: self.play_time, } } } #[derive(Copy, Clone, Debug, PartialEq)] #[repr(C)] pub struct SelectScreenCharacter { pub exp: u32, pub level: u32, pub guildcard: [u8; 16], pub _unknown: [u32; 2], pub name_color: u32, pub model: u8, pub _unused: [u8; 15], pub name_color_checksum: u32, pub section_id: u8, pub ch_class: u8, pub v2flags: u8, pub version: u8, pub v1flags: u32, 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, pub name: [u16; 16], pub play_time: u32, } impl SelectScreenCharacter { pub const SIZE: usize = 0x7C; pub fn from_le_bytes(bytes: [u8; 0x7C]) -> Result { unsafe { Ok(std::mem::transmute(bytes)) } } pub fn to_le_bytes(&self) -> [u8; 0x7C] { unsafe { std::mem::transmute(*self) } } pub fn as_character(&self) -> Character { Character { exp: self.exp, level: self.level, guildcard: self.guildcard, _unknown3: self._unknown, name_color: self.name_color, model: self.model, name_color_checksum: self.name_color_checksum, section_id: self.section_id, ch_class: self.ch_class, v2flags: self.v2flags, version: self.version, v1flags: self.v1flags, costume: self.costume, skin: self.skin, face: self.face, head: self.head, hair: self.hair, hair_r: self.hair_r, hair_g: self.hair_g, hair_b: self.hair_b, prop_x: self.prop_x, prop_y: self.prop_y, name: self.name, play_time: self.play_time, ..Character::default() } } } #[derive(PSOPacketData, Default, Copy, Clone)] pub struct InventoryItem { pub equipped: u16, pub tech: u16, pub flags: u32, pub data1: [u8; 12], pub item_id: u32, pub data2: [u8; 4], } #[derive(PSOPacketData, Default, Copy, Clone)] pub struct BankItem { pub data1: [u8; 12], pub item_id: u32, pub data2: [u8; 4], pub amount: u16, pub flags: u16, } #[derive(PSOPacketData, Copy, Clone)] pub struct Inventory { pub item_count: u8, pub hp_mats_used: u8, pub tp_mats_used: u8, pub language: u8, pub items: [InventoryItem; 30], } #[derive(PSOPacketData, Copy, Clone)] pub struct Bank { pub item_count: u32, pub meseta: u32, pub items: [BankItem; 200], } #[derive(PSOPacketData, Copy, Clone)] pub struct KeyTeamConfig { pub _unknown: [u8; 0x114], pub key_config: [u8; 0x16C], pub joystick_config: [u8; 0x38], pub guildcard: u32, pub team_id: u32, pub team_info: [u32; 2], pub team_priv: u16, pub _reserved: u16, pub team_name: [u16; 16], pub team_flag: [u8; 2048], pub team_rewards: [u32; 2], } #[derive(PSOPacketData, Copy, Clone)] pub struct Player { pub inventory: Inventory, pub character: Character, pub c_rank: [u8; 0x174], pub info_board: [u16; 172], pub blacklist: [u32; 30], pub autoreply: [u16; 172], } #[derive(PSOPacketData, Copy, Clone)] pub struct FullCharacter { pub inventory: Inventory, pub character: Character, pub _unknown1: [u8; 16], pub option_flags: u32, pub quest_data1: [u8; 520], pub bank: Bank, pub guildcard: u32, pub name: [u16; 24], pub team_name: [u16; 16], pub guildcard_desc: [u16; 88], pub _reserved1: u8, pub _reserved2: u8, pub section_id: u8, pub char_class: u8, pub _unknown2: u32, pub symbol_chats: [u8; 1248], pub shortcuts: [u8; 2624], pub autoreply: [u16; 172], pub info_board: [u16; 172], pub _unknown3: [u8; 28], pub challenge_data: [u8; 320], pub tech_menu: [u8; 40], pub _unknown4: [u8; 44], pub quest_data2: [u8; 88], pub key_team_config: KeyTeamConfig, } #[derive(PSOPacketData, Copy, Clone)] pub struct DBChar { pub inventory: Inventory, pub character: Character, pub quest_data1: [u8; 520], pub bank: Bank, pub guildcard_desc: [u16; 88], pub autoreply: [u16; 172], pub info_board: [u16; 172], pub challenge_data: [u8; 320], pub tech_menu: [u8; 40], pub quest_data2: [u8; 88], } #[derive(PSOPacketData, Copy, Clone)] pub struct DBOpts { pub blocked: [u32; 30], pub key_config: [u8; 0x16C], pub joystick_config: [u8; 0x38], pub option_flags: u32, pub shortcuts: [u8; 0xA40], pub symbol_chats: [u8; 0x4E0], pub team_name: [u16; 16], }