2025-03-12 17:47:58 -04:00
|
|
|
use binrw::binrw;
|
|
|
|
|
2025-03-13 00:18:00 -04:00
|
|
|
use crate::CHAR_NAME_MAX_LENGTH;
|
2025-03-13 00:02:37 -04:00
|
|
|
use crate::client_select_data::ClientCustomizeData;
|
2025-03-12 19:34:15 -04:00
|
|
|
use crate::common::{read_string, write_string};
|
|
|
|
|
2025-03-12 17:47:58 -04:00
|
|
|
use super::position::Position;
|
|
|
|
use super::status_effect::StatusEffect;
|
|
|
|
|
|
|
|
#[binrw]
|
2025-03-13 00:02:37 -04:00
|
|
|
#[brw(little)]
|
2025-03-12 19:34:15 -04:00
|
|
|
#[derive(Debug, Clone, Default)]
|
2025-03-12 18:05:41 -04:00
|
|
|
pub struct PlayerSpawn {
|
2025-03-13 00:02:37 -04:00
|
|
|
pub aafafaf: [u8; 16],
|
|
|
|
|
2025-03-12 17:47:58 -04:00
|
|
|
pub title: u16,
|
|
|
|
pub u1b: u16,
|
|
|
|
pub current_world_id: u16,
|
|
|
|
pub home_world_id: u16,
|
|
|
|
|
|
|
|
pub gm_rank: u8,
|
|
|
|
pub u3c: u8,
|
|
|
|
pub u4: u8,
|
|
|
|
pub online_status: u8,
|
|
|
|
|
|
|
|
pub pose: u8,
|
|
|
|
pub u5a: u8,
|
|
|
|
pub u5b: u8,
|
|
|
|
pub u5c: u8,
|
|
|
|
|
|
|
|
pub target_id: u64,
|
|
|
|
pub u6: u32,
|
|
|
|
pub u7: u32,
|
|
|
|
pub main_weapon_model: u64,
|
|
|
|
pub sec_weapon_model: u64,
|
|
|
|
pub craft_tool_model: u64,
|
|
|
|
|
|
|
|
pub u14: u32,
|
|
|
|
pub u15: u32,
|
|
|
|
pub b_npc_base: u32,
|
|
|
|
pub b_npc_name: u32,
|
|
|
|
pub u18: u32,
|
|
|
|
pub u19: u32,
|
|
|
|
pub director_id: u32,
|
|
|
|
pub owner_id: u32,
|
|
|
|
pub u22: u32,
|
|
|
|
pub hp_max: u32,
|
|
|
|
pub hp_curr: u32,
|
|
|
|
pub display_flags: u32,
|
|
|
|
pub fate_id: u16,
|
|
|
|
pub mp_curr: u16,
|
|
|
|
pub mp_max: u16,
|
|
|
|
pub unk: u16,
|
|
|
|
pub model_chara: u16,
|
|
|
|
pub rotation: u16,
|
|
|
|
pub current_mount: u16,
|
|
|
|
pub active_minion: u16,
|
|
|
|
pub u23: u8,
|
|
|
|
pub u24: u8,
|
|
|
|
pub u25: u8,
|
|
|
|
pub u26: u8,
|
|
|
|
pub spawn_index: u8,
|
|
|
|
pub state: u8,
|
|
|
|
pub persistent_emote: u8,
|
|
|
|
pub model_type: u8,
|
|
|
|
pub subtype: u8,
|
|
|
|
pub voice: u8,
|
|
|
|
pub enemy_type: u8,
|
|
|
|
pub unk27: u8,
|
|
|
|
pub level: u8,
|
|
|
|
pub class_job: u8,
|
|
|
|
pub unk28: u8,
|
|
|
|
pub unk29: u8,
|
|
|
|
pub mount_head: u8,
|
|
|
|
pub mount_body: u8,
|
|
|
|
pub mount_feet: u8,
|
|
|
|
pub mount_color: u8,
|
|
|
|
pub scale: u8,
|
|
|
|
pub element_data: [u8; 6],
|
2025-03-13 00:02:37 -04:00
|
|
|
pub padding2: [u8; 1],
|
2025-03-12 17:47:58 -04:00
|
|
|
pub effect: [StatusEffect; 30],
|
|
|
|
pub pos: Position,
|
|
|
|
pub models: [u32; 10],
|
|
|
|
pub unknown6_58: [u8; 10],
|
2025-03-13 00:02:37 -04:00
|
|
|
pub padding3: [u8; 4],
|
2025-03-13 00:18:00 -04:00
|
|
|
#[br(count = CHAR_NAME_MAX_LENGTH)]
|
|
|
|
#[bw(pad_size_to = CHAR_NAME_MAX_LENGTH)]
|
2025-03-12 19:34:15 -04:00
|
|
|
#[br(map = read_string)]
|
|
|
|
#[bw(map = write_string)]
|
|
|
|
pub name: String,
|
2025-03-14 00:30:37 -04:00
|
|
|
pub look: ClientCustomizeData,
|
2025-03-13 00:02:37 -04:00
|
|
|
#[br(count = 6)]
|
|
|
|
#[bw(pad_size_to = 6)]
|
|
|
|
#[br(map = read_string)]
|
|
|
|
#[bw(map = write_string)]
|
|
|
|
pub fc_tag: String,
|
|
|
|
pub padding: [u8; 2],
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2025-03-13 19:54:43 -04:00
|
|
|
use std::{fs::read, io::Cursor, path::PathBuf};
|
2025-03-13 00:02:37 -04:00
|
|
|
|
|
|
|
use binrw::BinRead;
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn read_playerspawn() {
|
2025-03-13 19:54:43 -04:00
|
|
|
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
|
|
d.push("resources/tests/player_spawn.dat");
|
|
|
|
|
|
|
|
let buffer = read(d).unwrap();
|
2025-03-13 00:02:37 -04:00
|
|
|
let mut buffer = Cursor::new(&buffer);
|
|
|
|
|
|
|
|
let player_spawn = PlayerSpawn::read_le(&mut buffer).unwrap();
|
|
|
|
assert_eq!(player_spawn.current_world_id, 0x4F);
|
|
|
|
assert_eq!(player_spawn.home_world_id, 0x4F);
|
|
|
|
assert_eq!(player_spawn.hp_curr, 159);
|
|
|
|
assert_eq!(player_spawn.hp_max, 159);
|
|
|
|
assert_eq!(player_spawn.mp_curr, 10000);
|
|
|
|
assert_eq!(player_spawn.mp_max, 10000);
|
|
|
|
assert_eq!(player_spawn.state, 1);
|
|
|
|
assert_eq!(player_spawn.level, 1);
|
|
|
|
assert_eq!(player_spawn.class_job, 1); // adventurer
|
|
|
|
assert_eq!(player_spawn.scale, 36);
|
|
|
|
assert_eq!(player_spawn.pos.x, 40.519722);
|
|
|
|
assert_eq!(player_spawn.pos.y, 4.0);
|
|
|
|
assert_eq!(player_spawn.pos.z, -150.33124);
|
|
|
|
assert_eq!(player_spawn.name, "Lavenaa Warren");
|
|
|
|
assert_eq!(player_spawn.look.race, 1);
|
|
|
|
assert_eq!(player_spawn.look.gender, 1);
|
|
|
|
assert_eq!(player_spawn.look.bust, 100);
|
|
|
|
assert_eq!(player_spawn.fc_tag, "");
|
|
|
|
}
|
2025-03-12 17:47:58 -04:00
|
|
|
}
|