1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-07-17 10:47:44 +00:00

Begin adding support for EffectResult IPC opcode

And other stuff I saw in my sprint retail capture.
This commit is contained in:
Joshua Goins 2025-07-14 19:00:26 -04:00
parent 3f55df789e
commit 1c2b757359
4 changed files with 111 additions and 0 deletions

View file

@ -304,6 +304,11 @@
"name": "UpdateInventorySlot",
"opcode": 435,
"size": 64
},
{
"name": "EffectResult",
"opcode": 431,
"size": 96
}
],
"ClientZoneIpcType": [

View file

@ -39,6 +39,8 @@ pub enum EffectKind {
},
#[brw(magic = 27u8)]
BeginCombo,
#[brw(magic = 14u8)]
Unk1 { unk1: u8, unk2: u32, effect_id: u8 }, // seen during sprint
}
#[derive(Debug, Eq, PartialEq, Clone, Copy, Default, Deserialize, Serialize)]
@ -190,4 +192,41 @@ mod tests {
ObjectId(0x40070E42)
);
}
#[test]
fn read_actionresult_sprint() {
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d.push("resources/tests/action_result_sprint.bin");
let buffer = read(d).unwrap();
let mut buffer = Cursor::new(&buffer);
let action_result = ActionResult::read_le(&mut buffer).unwrap();
assert_eq!(action_result.main_target.object_id, ObjectId(277554542));
assert_eq!(action_result.action_id, 3);
assert_eq!(action_result.unk1, 776386); // TODO: probably means this field is wrong
assert_eq!(action_result.animation_lock_time, 0.6);
assert_eq!(action_result.unk2, 3758096384); // TODO: ditto
assert_eq!(action_result.hidden_animation, 1);
assert_eq!(action_result.rotation, 2.6254003);
assert_eq!(action_result.action_animation_id, 3);
assert_eq!(action_result.variation, 0);
assert_eq!(action_result.flag, 1);
assert_eq!(action_result.unk3, 0);
assert_eq!(action_result.effect_count, 1);
assert_eq!(action_result.unk4, 0);
assert_eq!(action_result.unk5, [0; 6]);
// effect 0: unk
assert_eq!(
action_result.effects[0].kind,
EffectKind::Unk1 {
unk1: 0,
unk2: 7728,
effect_id: 50
}
);
assert_eq!(action_result.target_id_again.object_id, ObjectId(277554542));
}
}

View file

@ -0,0 +1,58 @@
use binrw::binrw;
use crate::common::ObjectId;
#[binrw]
#[brw(little)]
#[derive(Clone, Debug, Default)]
pub struct EffectEntry {
pub index: u8,
pub unk1: u8,
pub id: u16,
pub param: u16,
pub unk2: u16,
pub duration: f32,
pub source_actor_id: ObjectId,
}
#[binrw]
#[brw(little)]
#[derive(Clone, Debug, Default)]
pub struct EffectResult {
pub unk1: u32,
pub unk2: u32,
pub target_id: ObjectId,
pub current_hp: u32,
pub max_hp: u32,
pub current_mp: u16,
pub unk3: u8,
pub class_id: u8,
pub shield: u8,
pub entry_count: u8,
pub unk4: u16,
#[brw(pad_after = 4)] // padding
pub statuses: [EffectEntry; 4],
}
#[cfg(test)]
mod tests {
use std::{fs::read, io::Cursor, path::PathBuf};
use binrw::BinRead;
use super::*;
#[test]
fn read_effectresult() {
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
d.push("resources/tests/effect_result.bin");
let buffer = read(d).unwrap();
let mut buffer = Cursor::new(&buffer);
let effect_result = EffectResult::read_le(&mut buffer).unwrap();
assert_eq!(effect_result.unk1, 1);
assert_eq!(effect_result.unk2, 776386);
assert_eq!(effect_result.target_id, ObjectId(277554542));
}
}

View file

@ -94,6 +94,9 @@ pub use object_spawn::ObjectSpawn;
mod quest_active_list;
pub use quest_active_list::QuestActiveList;
mod effect_result;
pub use effect_result::EffectResult;
use crate::COMPLETED_LEVEQUEST_BITMASK_SIZE;
use crate::COMPLETED_QUEST_BITMASK_SIZE;
use crate::TITLE_UNLOCK_BITMASK_SIZE;
@ -523,6 +526,8 @@ pub enum ServerZoneIpcData {
/// Always 0x7530_0000
unk4: u32,
},
#[br(pre_assert(*magic == ServerZoneIpcType::EffectResult))]
EffectResult(EffectResult),
Unknown {
#[br(count = size - 32)]
unk: Vec<u8>,
@ -1034,6 +1039,10 @@ mod tests {
unk4: 0,
},
),
(
ServerZoneIpcType::EffectResult,
ServerZoneIpcData::EffectResult(EffectResult::default()),
),
];
for (opcode, data) in &ipc_types {