2025-03-18 23:30:59 -04:00
use binrw ::binrw ;
2025-04-11 08:46:54 -04:00
use crate ::common ::{ read_bool_from , write_bool_as } ;
2025-03-28 20:19:17 -04:00
use super ::OnlineStatus ;
2025-05-08 22:53:36 -04:00
// TODO: these are all somewhat related, but maybe should be separated?
2025-03-18 23:30:59 -04:00
// See https://github.com/awgil/ffxiv_reverse/blob/f35b6226c1478234ca2b7149f82d251cffca2f56/vnetlog/vnetlog/ServerIPC.cs#L266 for a REALLY useful list of known values
#[ binrw ]
2025-03-23 15:28:53 -04:00
#[ derive(Debug, Eq, PartialEq, Clone) ]
2025-03-18 23:30:59 -04:00
pub enum ActorControlCategory {
2025-06-22 10:08:29 -04:00
#[ brw(magic = 0x0u16) ]
ToggleWeapon {
#[ brw(pad_before = 2) ]
#[ br(map = read_bool_from::<u32>) ]
#[ bw(map = write_bool_as::<u32>) ]
shown : bool ,
} ,
2025-03-23 15:28:53 -04:00
#[ brw(magic = 0x26u16) ]
ToggleInvisibility {
#[ brw(pad_before = 2) ]
2025-04-11 08:46:54 -04:00
#[ br(map = read_bool_from::<u32>) ]
#[ bw(map = write_bool_as::<u32>) ]
invisible : bool ,
2025-03-23 15:28:53 -04:00
} ,
#[ brw(magic = 0xC8u16) ]
ZoneIn {
#[ brw(pad_before = 2) ]
warp_finish_anim : u32 ,
raise_anim : u32 ,
} ,
#[ brw(magic = 0x260u16) ]
SetCharaGearParamUI {
#[ brw(pad_before = 2) ]
unk1 : u32 ,
unk2 : u32 ,
} ,
2025-03-28 20:19:17 -04:00
#[ brw(magic = 0x01F8u16) ]
SetStatusIcon {
#[ brw(pad_before = 2) ]
icon : OnlineStatus ,
} ,
2025-03-29 00:39:00 -04:00
#[ brw(magic = 0x261u16) ]
ToggleWireframeRendering ( ) ,
2025-05-08 22:53:36 -04:00
#[ brw(magic = 0x32u16) ]
SetTarget {
#[ brw(pad_before = 22) ] // actually full of info, and 2 bytes of padding at the beginning
actor_id : u32 ,
} ,
2025-05-08 23:03:51 -04:00
#[ brw(magic = 0x127u16) ]
Pose {
#[ brw(pad_before = 2) ] //padding
unk1 : u32 ,
pose : u32 ,
} ,
2025-05-11 09:27:29 -04:00
#[ brw(magic = 0x1FDu16) ]
LearnTeleport {
#[ brw(pad_before = 2) ] //padding
id : u32 ,
#[ br(map = read_bool_from::<u32>) ]
#[ bw(map = write_bool_as::<u32>) ]
unlocked : bool ,
} ,
#[ brw(magic = 0x29u16) ]
2025-06-22 11:17:11 -04:00
ToggleUnlock {
/// Corresponds to an UnlockLink. Could be a spell, action, emote, etc.
// See https://github.com/Haselnussbomber/HaselDebug/blob/main/HaselDebug/Tabs/UnlocksTabs/UnlockLinks/UnlockLinksTable.cs
2025-05-11 09:27:29 -04:00
#[ brw(pad_before = 2) ] //padding
id : u32 ,
#[ br(map = read_bool_from::<u32>) ]
#[ bw(map = write_bool_as::<u32>) ]
unlocked : bool ,
} ,
2025-05-11 10:12:02 -04:00
#[ brw(magic = 0xCBu16) ]
TeleportStart {
#[ brw(pad_before = 2) ] //padding
insufficient_gil : u32 ,
aetheryte_id : u32 ,
} ,
2025-06-19 16:01:16 -04:00
#[ brw(magic = 0x1Bu16) ]
2025-06-19 09:53:21 -04:00
Flee {
#[ brw(pad_before = 2) ] // padding
speed : u16 ,
2025-06-19 12:29:10 -04:00
} ,
2025-06-19 16:01:16 -04:00
#[ brw(magic = 0x386u16) ]
2025-06-19 12:29:10 -04:00
SetFestival {
#[ brw(pad_before = 2) ] // padding
festival1 : u32 , // Multiple festivals can be set at the same time.
festival2 : u32 ,
festival3 : u32 ,
festival4 : u32 ,
} ,
2025-06-21 10:36:44 -04:00
#[ brw(magic = 0xFu16) ]
CancelCast { } ,
2025-06-22 12:46:11 +00:00
#[ brw(magic = 0x396u16) ]
ToggleOrchestrionUnlock {
#[ brw(pad_before = 2) ] // padding
song_id : u16 ,
/* TODO: guessed, Sapphire suggests it's an u32 item id,
* but it behaves as an unlock boolean like aetherytes , so
perhaps it ' s been repurposed since Shadowbringers . * /
#[ br(map = read_bool_from::<u32>) ]
#[ bw(map = write_bool_as::<u32>) ]
unlocked : bool ,
} ,
2025-06-22 09:45:24 -04:00
#[ brw(magic = 0x122u16) ]
Emote {
#[ brw(pad_before = 2) ] // padding
emote : u32 ,
} ,
2025-06-25 23:11:49 -04:00
#[ brw(magic = 0x207u16) ]
TestActorControl {
#[ brw(pad_before = 2) ] // padding
actor_id : u32 ,
unk1 : u32 ,
} ,
2025-06-26 20:59:46 -04:00
Unknown { } ,
2025-03-18 23:30:59 -04:00
}
#[ binrw ]
2025-03-23 15:28:53 -04:00
#[ derive(Debug, Clone) ]
2025-03-18 23:30:59 -04:00
pub struct ActorControl {
2025-03-23 15:28:53 -04:00
#[ brw(pad_after = 4) ]
#[ brw(pad_size_to = 20) ] // take into account categories without params
2025-03-18 23:30:59 -04:00
pub category : ActorControlCategory ,
2025-03-23 15:28:53 -04:00
}
impl Default for ActorControl {
fn default ( ) -> Self {
Self {
2025-04-11 08:46:54 -04:00
category : ActorControlCategory ::ToggleInvisibility { invisible : false } ,
2025-03-23 15:28:53 -04:00
}
}
}
// Has more padding than ActorControl?
#[ binrw ]
#[ derive(Debug, Clone) ]
pub struct ActorControlSelf {
#[ brw(pad_after = 12) ]
#[ brw(pad_size_to = 20) ] // take into account categories without params
pub category : ActorControlCategory ,
}
impl Default for ActorControlSelf {
fn default ( ) -> Self {
Self {
2025-04-11 08:46:54 -04:00
category : ActorControlCategory ::ToggleInvisibility { invisible : false } ,
2025-03-23 15:28:53 -04:00
}
}
2025-03-18 23:30:59 -04:00
}
2025-05-08 22:53:36 -04:00
// Has more padding than ActorControl?
#[ binrw ]
#[ derive(Debug, Clone) ]
pub struct ActorControlTarget {
#[ brw(pad_size_to = 28) ] // take into account categories without params
pub category : ActorControlCategory ,
}
impl Default for ActorControlTarget {
fn default ( ) -> Self {
Self {
category : ActorControlCategory ::ToggleInvisibility { invisible : false } ,
}
}
}