diff --git a/src/common/mod.rs b/src/common/mod.rs index 769ff8b..bdf8962 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -4,6 +4,7 @@ use std::{ }; mod customize_data; +use binrw::binrw; pub use customize_data::CustomizeData; use physis::{ common::{Language, Platform}, @@ -17,8 +18,38 @@ pub mod custom_ipc; mod position; pub use position::Position; +#[binrw] +#[brw(little)] +#[derive(Debug, Clone)] +pub struct ObjectId(pub u32); + +impl Default for ObjectId { + fn default() -> Self { + INVALID_OBJECT_ID + } +} + +// See https://github.com/aers/FFXIVClientStructs/blob/main/FFXIVClientStructs/FFXIV/Client/Game/Object/GameObject.cs#L158 +#[binrw] +#[brw(little)] +#[derive(Debug, Clone)] +pub struct ObjectTypeId { + pub object_id: ObjectId, + #[brw(pad_after = 3)] + pub object_type: u8, +} + +impl Default for ObjectTypeId { + fn default() -> Self { + Self { + object_id: INVALID_OBJECT_ID, + object_type: 0, // TODO: not sure if correct? + } + } +} + /// An invalid actor/object id. -pub const INVALID_OBJECT_ID: u32 = 0xE0000000; +pub const INVALID_OBJECT_ID: ObjectId = ObjectId(0xE0000000); /// Maxmimum length of a character's name. pub const CHAR_NAME_MAX_LENGTH: usize = 32; diff --git a/src/world/chat_handler.rs b/src/world/chat_handler.rs index 91861f4..b826c0f 100644 --- a/src/world/chat_handler.rs +++ b/src/world/chat_handler.rs @@ -1,5 +1,5 @@ use crate::{ - common::{CustomizeData, INVALID_OBJECT_ID, Position, timestamp_secs}, + common::{CustomizeData, INVALID_OBJECT_ID, ObjectId, ObjectTypeId, Position, timestamp_secs}, config::get_config, packet::{PacketSegment, SegmentType}, world::ipc::{ @@ -191,9 +191,11 @@ impl ChatHandler { spawn_index: connection.get_free_spawn_index(), bnpc_base: 13498, bnpc_name: 10261, - spawner_id: connection.player_data.actor_id, - parent_actor_id: INVALID_OBJECT_ID, // TODO: make default? object_kind: ObjectKind::BattleNpc, + target_id: ObjectTypeId { + object_id: ObjectId(connection.player_data.actor_id), + object_type: 0, + }, // target the player level: 1, models: [ 0, // head @@ -241,10 +243,7 @@ impl ChatHandler { spawn_index: connection.get_free_spawn_index(), bnpc_base: 13498, // TODO: changing this prevents it from spawning... bnpc_name: 405, - spawner_id: connection.player_data.actor_id, - parent_actor_id: INVALID_OBJECT_ID, // TODO: make default? object_kind: ObjectKind::BattleNpc, - target_id: INVALID_OBJECT_ID as u64, level: 1, battalion: 4, model_chara: 297, diff --git a/src/world/ipc/common_spawn.rs b/src/world/ipc/common_spawn.rs index ef24ea9..9beb8ed 100644 --- a/src/world/ipc/common_spawn.rs +++ b/src/world/ipc/common_spawn.rs @@ -1,6 +1,9 @@ use binrw::binrw; -use crate::common::{CHAR_NAME_MAX_LENGTH, CustomizeData, Position, read_string, write_string}; +use crate::common::{ + CHAR_NAME_MAX_LENGTH, CustomizeData, INVALID_OBJECT_ID, ObjectId, ObjectTypeId, Position, + read_string, write_string, +}; use super::StatusEffect; @@ -58,7 +61,7 @@ pub struct CommonSpawn { pub u5b: u8, pub u5c: u8, - pub target_id: u64, + pub target_id: ObjectTypeId, pub u6: u32, pub u7: u32, pub main_weapon_model: u64, @@ -73,8 +76,8 @@ pub struct CommonSpawn { pub bnpc_name: u32, pub unk3: [u8; 8], pub director_id: u32, // FIXME: i think the next three are in the wrong order - pub spawner_id: u32, - pub parent_actor_id: u32, + pub spawner_id: ObjectId, + pub parent_actor_id: ObjectId, pub hp_max: u32, pub hp_curr: u32, pub display_flags: u32, // assumed