diff --git a/Cargo.lock b/Cargo.lock index 576ff26..d4cc2c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -385,6 +385,7 @@ version = "0.1.0" dependencies = [ "axum", "binrw", + "bitflags 1.3.2", "md5", "minijinja", "physis", diff --git a/Cargo.toml b/Cargo.toml index 7d1289f..4f29b44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,3 +75,7 @@ physis = { git = "https://github.com/redstrate/physis" } # Used for data persistence rusqlite = { version = "0.34", features = ["bundled"], default-features = false } + +# needed for c-style bitflags +# cannot upgrade to 2.0.0, breaking changes that aren't recoverable: https://github.com/bitflags/bitflags/issues/314 +bitflags = { version = "1.3", default-features = false } diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 814be40..746a21e 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -11,9 +11,7 @@ use kawari::packet::{ send_packet, }; use kawari::world::ipc::{ - ClientZoneIpcData, CommonSpawn, GameMasterCommandType, GameMasterRank, ObjectKind, - OnlineStatus, PlayerSubKind, ServerZoneIpcData, ServerZoneIpcSegment, ServerZoneIpcType, - SocialListRequestType, StatusEffect, + ClientZoneIpcData, CommonSpawn, DisplayFlag, GameMasterCommandType, GameMasterRank, ObjectKind, OnlineStatus, PlayerSubKind, ServerZoneIpcData, ServerZoneIpcSegment, ServerZoneIpcType, SocialListRequestType, StatusEffect }; use kawari::world::{ ChatHandler, Zone, ZoneConnection, @@ -344,6 +342,7 @@ async fn main() { ), look: chara_details.chara_make.customize, fc_tag: "LOCAL".to_string(), + display_flags: DisplayFlag::UNK, models: [ 0, // head 89, // body diff --git a/src/world/chat_handler.rs b/src/world/chat_handler.rs index 7ae833e..b2637cf 100644 --- a/src/world/chat_handler.rs +++ b/src/world/chat_handler.rs @@ -111,10 +111,11 @@ impl ChatHandler { common: CommonSpawn { class_job: 35, name: "Test Actor".to_string(), - hp_curr: 100, - hp_max: 100, - mp_curr: 100, - mp_max: 100, + hp_curr: 250, + hp_max: 250, + mp_curr: 10000, + mp_max: 10000, + level: 5, object_kind: ObjectKind::Player(PlayerSubKind::Player), spawn_index: connection.get_free_spawn_index(), look: CUSTOMIZE_DATA, diff --git a/src/world/ipc/common_spawn.rs b/src/world/ipc/common_spawn.rs index ba5cc82..5abddb4 100644 --- a/src/world/ipc/common_spawn.rs +++ b/src/world/ipc/common_spawn.rs @@ -1,5 +1,7 @@ use binrw::binrw; +use bitflags::bitflags; + use crate::common::{ CHAR_NAME_MAX_LENGTH, CustomizeData, INVALID_OBJECT_ID, ObjectId, ObjectTypeId, Position, read_string, write_string, @@ -112,6 +114,26 @@ pub enum GameMasterRank { Debug = 90, } +bitflags! { + #[binrw] + pub struct DisplayFlag : u32 { + const NONE = 0x0; + // Can be made visible with ActorControl I think + const INVISIBLE = 0x20; + const HIDE_HEAD = 0x40; + const HIDE_WEAPON = 0x80; + const FADED = 0x100; + const VISOR = 0x800; + const UNK = 0x40000; // FIXME: what is this? + } +} + +impl Default for DisplayFlag { + fn default() -> Self { + Self::NONE + } +} + #[binrw] #[brw(little)] #[derive(Debug, Clone, Default)] @@ -135,8 +157,8 @@ pub struct CommonSpawn { pub parent_actor_id: ObjectId, pub hp_max: u32, pub hp_curr: u32, - pub display_flags: u32, // assumed - pub fate_id: u16, // assumed + pub display_flags: DisplayFlag, + pub fate_id: u16, // assumed pub mp_curr: u16, pub mp_max: u16, pub unk: u16, diff --git a/src/world/ipc/mod.rs b/src/world/ipc/mod.rs index 1d6b681..b5e2ebc 100644 --- a/src/world/ipc/mod.rs +++ b/src/world/ipc/mod.rs @@ -37,8 +37,8 @@ pub use npc_spawn::NpcSpawn; mod common_spawn; pub use common_spawn::{ - BattleNpcSubKind, CharacterMode, CommonSpawn, GameMasterRank, ObjectKind, OnlineStatus, - PlayerSubKind, + BattleNpcSubKind, CharacterMode, CommonSpawn, DisplayFlag, GameMasterRank, ObjectKind, + OnlineStatus, PlayerSubKind, }; mod status_effect_list; diff --git a/src/world/ipc/npc_spawn.rs b/src/world/ipc/npc_spawn.rs index ec72a32..fb6f8d9 100644 --- a/src/world/ipc/npc_spawn.rs +++ b/src/world/ipc/npc_spawn.rs @@ -31,7 +31,7 @@ mod tests { use crate::{ common::INVALID_OBJECT_ID, - world::ipc::{BattleNpcSubKind, CharacterMode, ObjectKind, OnlineStatus}, + world::ipc::{BattleNpcSubKind, CharacterMode, DisplayFlag, ObjectKind, OnlineStatus}, }; use super::*; @@ -49,7 +49,7 @@ mod tests { assert_eq!(npc_spawn.common.hp_curr, 1393); assert_eq!(npc_spawn.common.mp_curr, 10000); assert_eq!(npc_spawn.common.mp_max, 10000); - assert_eq!(npc_spawn.common.display_flags, 0); + assert_eq!(npc_spawn.common.display_flags, DisplayFlag::NONE); assert_eq!(npc_spawn.common.pos.x, -64.17707); assert_eq!(npc_spawn.common.pos.y, -2.0206506); assert_eq!(npc_spawn.common.pos.z, 15.913875); @@ -80,7 +80,7 @@ mod tests { assert_eq!(npc_spawn.common.hp_curr, 91); assert_eq!(npc_spawn.common.mp_curr, 0); assert_eq!(npc_spawn.common.mp_max, 0); - assert_eq!(npc_spawn.common.display_flags, 0); + assert_eq!(npc_spawn.common.display_flags, DisplayFlag::NONE); assert_eq!(npc_spawn.common.pos.x, 116.99154); assert_eq!(npc_spawn.common.pos.y, 76.64936); assert_eq!(npc_spawn.common.pos.z, -187.02414); diff --git a/src/world/ipc/player_spawn.rs b/src/world/ipc/player_spawn.rs index 2489f24..ee0eb17 100644 --- a/src/world/ipc/player_spawn.rs +++ b/src/world/ipc/player_spawn.rs @@ -39,7 +39,7 @@ mod tests { use binrw::BinRead; - use crate::world::ipc::{CharacterMode, ObjectKind, OnlineStatus, PlayerSubKind}; + use crate::world::ipc::{CharacterMode, DisplayFlag, ObjectKind, OnlineStatus, PlayerSubKind}; use super::*; @@ -76,7 +76,7 @@ mod tests { player_spawn.common.object_kind, ObjectKind::Player(PlayerSubKind::Player) ); - assert_eq!(player_spawn.common.display_flags, 262144); + assert_eq!(player_spawn.common.display_flags, DisplayFlag::UNK); assert_eq!(player_spawn.online_status, OnlineStatus::Offline); } }