From 099dfbd134005199ce28a262bb2ad013470f30e0 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 14 Jul 2025 20:26:13 -0400 Subject: [PATCH] Remove most of the hardcoded effect durations and params --- resources/scripts/actions/Sprint.lua | 2 +- resources/scripts/effects/Sprint.lua | 2 +- src/bin/kawari-world.rs | 2 +- src/ipc/zone/action_result.rs | 24 +++++++++++++++--- src/ipc/zone/actor_control.rs | 2 +- src/ipc/zone/client_trigger.rs | 4 ++- src/world/common.rs | 6 ++--- src/world/connection.rs | 29 ++++++++++++++++----- src/world/lua.rs | 34 +++++++++++++++---------- src/world/server.rs | 38 +++++++++++++++++++++++----- 10 files changed, 104 insertions(+), 39 deletions(-) diff --git a/resources/scripts/actions/Sprint.lua b/resources/scripts/actions/Sprint.lua index 9d42ae0..b391466 100644 --- a/resources/scripts/actions/Sprint.lua +++ b/resources/scripts/actions/Sprint.lua @@ -3,7 +3,7 @@ EFFECT_SPRINT = 50 function doAction(player) effects = EffectsBuilder() - effects:gain_effect(EFFECT_SPRINT) + effects:gain_effect(EFFECT_SPRINT, 30, 20.0) return effects end diff --git a/resources/scripts/effects/Sprint.lua b/resources/scripts/effects/Sprint.lua index 38882ea..6388d64 100644 --- a/resources/scripts/effects/Sprint.lua +++ b/resources/scripts/effects/Sprint.lua @@ -5,5 +5,5 @@ function onGain(player) end function onLose(player) - player:gain_effect(EFFECT_JOG, 20.0) + player:gain_effect(EFFECT_JOG, 20, 0.0) end diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 80c6dc7..355dfc2 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -1191,7 +1191,7 @@ async fn client_loop( FromServer::UpdateConfig(actor_id, config) => connection.update_config(actor_id, config).await, FromServer::ActorEquip(actor_id, main_weapon_id, model_ids) => connection.update_equip(actor_id, main_weapon_id, model_ids).await, FromServer::ReplayPacket(segment) => connection.send_segment(segment).await, - FromServer::LoseEffect(effect_id) => connection.lose_effect(effect_id, &mut lua_player).await, + FromServer::LoseEffect(effect_id, effect_param, effect_source_actor_id) => connection.lose_effect(effect_id, effect_param, effect_source_actor_id, &mut lua_player).await, }, None => break, } diff --git a/src/ipc/zone/action_result.rs b/src/ipc/zone/action_result.rs index 73e2210..5fb56ab 100644 --- a/src/ipc/zone/action_result.rs +++ b/src/ipc/zone/action_result.rs @@ -1,7 +1,7 @@ use binrw::binrw; use serde::{Deserialize, Serialize}; -use crate::common::{ObjectTypeId, read_quantized_rotation, write_quantized_rotation}; +use crate::common::{ObjectId, ObjectTypeId, read_quantized_rotation, write_quantized_rotation}; // TODO: this might be a flag? #[binrw] @@ -15,7 +15,7 @@ pub enum DamageKind { } #[binrw] -#[derive(Debug, Eq, PartialEq, Clone, Copy, Default)] +#[derive(Debug, PartialEq, Clone, Copy, Default)] pub enum EffectKind { #[default] #[brw(magic = 0u8)] @@ -39,8 +39,22 @@ pub enum EffectKind { }, #[brw(magic = 27u8)] BeginCombo, + /// seen during sprint #[brw(magic = 14u8)] - Unk1 { unk1: u8, unk2: u32, effect_id: u16 }, // seen during sprint + Unk1 { + unk1: u8, + unk2: u32, + effect_id: u16, + + // NOTE: the following is for our internal usage, this is not an actual part of the packet + // TODO: this shouldn't be here, instead we should maybe create a lua-specific struct for all of this information + #[brw(ignore)] + duration: f32, + #[brw(ignore)] + param: u16, + #[brw(ignore)] + source_actor_id: ObjectId, + }, } #[derive(Debug, Eq, PartialEq, Clone, Copy, Default, Deserialize, Serialize)] @@ -223,7 +237,9 @@ mod tests { EffectKind::Unk1 { unk1: 0, unk2: 7728, - effect_id: 50 + effect_id: 50, + duration: 0.0, + param: 0, } ); diff --git a/src/ipc/zone/actor_control.rs b/src/ipc/zone/actor_control.rs index 902f7a7..fb3a118 100644 --- a/src/ipc/zone/actor_control.rs +++ b/src/ipc/zone/actor_control.rs @@ -167,7 +167,7 @@ pub enum ActorControlCategory { GainEffect { #[brw(pad_before = 2)] // padding effect_id: u32, - unk2: u32, + param: u32, source_actor_id: ObjectId, }, #[brw(magic = 0x11u16)] diff --git a/src/ipc/zone/client_trigger.rs b/src/ipc/zone/client_trigger.rs index 31bd3f3..ae61a5a 100644 --- a/src/ipc/zone/client_trigger.rs +++ b/src/ipc/zone/client_trigger.rs @@ -1,6 +1,6 @@ use binrw::binrw; -use crate::common::{read_bool_from, write_bool_as}; +use crate::common::{ObjectId, read_bool_from, write_bool_as}; #[binrw] #[derive(Debug, Eq, PartialEq, Clone)] @@ -66,6 +66,8 @@ pub enum ClientTriggerCommand { ManuallyRemoveEffect { #[brw(pad_before = 2)] // padding effect_id: u32, + unk1: u32, + source_actor_id: ObjectId, }, Unknown { category: u16, diff --git a/src/world/common.rs b/src/world/common.rs index 0b49346..fae660f 100644 --- a/src/world/common.rs +++ b/src/world/common.rs @@ -9,7 +9,7 @@ use std::{ use tokio::sync::mpsc::Sender; use crate::{ - common::Position, + common::{ObjectId, Position}, ipc::zone::{ ActionRequest, ActorControl, ActorControlSelf, ActorControlTarget, ClientTrigger, CommonSpawn, Config, NpcSpawn, ServerZoneIpcSegment, @@ -48,7 +48,7 @@ pub enum FromServer { /// Informs the connection to replay packet data to the client. ReplayPacket(PacketSegment), /// The player should lose this effect. - LoseEffect(u16), + LoseEffect(u16, u16, ObjectId), } #[derive(Debug, Clone)] @@ -114,7 +114,7 @@ pub enum ToServer { /// Begins a packet replay. BeginReplay(ClientId, String), /// The player gains an effect. - GainEffect(ClientId, u32, u16, f32), + GainEffect(ClientId, u32, u16, f32, u16, ObjectId), } #[derive(Clone, Debug)] diff --git a/src/world/connection.rs b/src/world/connection.rs index cd5653d..80ff861 100644 --- a/src/world/connection.rs +++ b/src/world/connection.rs @@ -1403,14 +1403,21 @@ impl ZoneConnection { let mut entries = [EffectEntry::default(); 4]; for effect in &effects_builder.effects { - if let EffectKind::Unk1 { effect_id, .. } = effect.kind { + if let EffectKind::Unk1 { + effect_id, + duration, + param, + source_actor_id, + .. + } = effect.kind + { entries[num_entries as usize] = EffectEntry { index: num_entries, unk1: 0, id: effect_id, - param: 30, + param, unk2: 0, - duration: 20.0, + duration, source_actor_id: INVALID_OBJECT_ID, }; num_entries += 1; @@ -1421,7 +1428,9 @@ impl ZoneConnection { self.id, self.player_data.actor_id, effect_id, - 20.0, // TODO: fill out + duration, + param, + source_actor_id, )) .await; } @@ -1577,7 +1586,13 @@ impl ZoneConnection { .await; } - pub async fn lose_effect(&mut self, effect_id: u16, lua_player: &mut LuaPlayer) { + pub async fn lose_effect( + &mut self, + effect_id: u16, + effect_param: u16, + effect_source_actor_id: ObjectId, + lua_player: &mut LuaPlayer, + ) { // first, inform the effect script { let lua = self.lua.lock().unwrap(); @@ -1614,8 +1629,8 @@ impl ZoneConnection { self.actor_control_self(ActorControlSelf { category: ActorControlCategory::LoseEffect { effect_id: effect_id as u32, - unk2: 0, - source_actor_id: INVALID_OBJECT_ID, // TODO: fill + unk2: effect_param as u32, + source_actor_id: effect_source_actor_id, }, }) .await; diff --git a/src/world/lua.rs b/src/world/lua.rs index af2fb0b..72f15c0 100644 --- a/src/world/lua.rs +++ b/src/world/lua.rs @@ -116,12 +116,12 @@ impl LuaPlayer { self.create_segment_self(op_code, data); } - fn give_status_effect(&mut self, effect_id: u16, duration: f32) { + fn give_status_effect(&mut self, effect_id: u16, effect_param: u16, duration: f32) { let op_code = ServerZoneIpcType::ActorControlSelf; let data = ServerZoneIpcData::ActorControlSelf(ActorControlSelf { category: ActorControlCategory::GainEffect { effect_id: effect_id as u32, - unk2: 0, + param: effect_param as u32, source_actor_id: INVALID_OBJECT_ID, // TODO: fill }, }); @@ -298,8 +298,8 @@ impl UserData for LuaPlayer { ); methods.add_method_mut( "gain_effect", - |_, this, (effect_id, duration): (u16, f32)| { - this.give_status_effect(effect_id, duration); + |_, this, (effect_id, param, duration): (u16, u16, f32)| { + this.give_status_effect(effect_id, param, duration); Ok(()) }, ); @@ -586,16 +586,22 @@ impl UserData for EffectsBuilder { }); Ok(()) }); - methods.add_method_mut("gain_effect", |_, this, effect_id: u16| { - this.effects.push(ActionEffect { - kind: EffectKind::Unk1 { - unk1: 0, - unk2: 7728, - effect_id, - }, - }); - Ok(()) - }); + methods.add_method_mut( + "gain_effect", + |_, this, (effect_id, param, duration): (u16, u16, f32)| { + this.effects.push(ActionEffect { + kind: EffectKind::Unk1 { + unk1: 0, + unk2: 7728, + effect_id, + duration, + param, + source_actor_id: INVALID_OBJECT_ID, + }, + }); + Ok(()) + }, + ); } } diff --git a/src/world/server.rs b/src/world/server.rs index 4506586..a98319f 100644 --- a/src/world/server.rs +++ b/src/world/server.rs @@ -418,8 +418,13 @@ pub async fn server_main_loop(mut recv: Receiver) -> Result<(), std::i to_remove.push(id); } } - ClientTriggerCommand::ManuallyRemoveEffect { effect_id } => { - let msg = FromServer::LoseEffect(*effect_id as u16); + ClientTriggerCommand::ManuallyRemoveEffect { + effect_id, + source_actor_id, + .. + } => { + let msg = + FromServer::LoseEffect(*effect_id as u16, 0, *source_actor_id); if handle.send(msg).is_err() { to_remove.push(id); @@ -814,9 +819,20 @@ pub async fn server_main_loop(mut recv: Receiver) -> Result<(), std::i } }); } - ToServer::GainEffect(from_id, _from_actor_id, effect_id, effect_duration) => { + ToServer::GainEffect( + from_id, + _from_actor_id, + effect_id, + effect_duration, + effect_param, + effect_source_actor_id, + ) => { let send_lost_effect = - |from_id: ClientId, data: Arc>, effect_id: u16| { + |from_id: ClientId, + data: Arc>, + effect_id: u16, + effect_param: u16, + effect_source_actor_id: ObjectId| { let mut data = data.lock().unwrap(); tracing::info!("Now losing effect {}!", effect_id); @@ -825,7 +841,11 @@ pub async fn server_main_loop(mut recv: Receiver) -> Result<(), std::i let id = *id; if id == from_id { - let msg = FromServer::LoseEffect(effect_id); + let msg = FromServer::LoseEffect( + effect_id, + effect_param, + effect_source_actor_id, + ); if handle.send(msg).is_err() { data.to_remove.push(id); @@ -848,7 +868,13 @@ pub async fn server_main_loop(mut recv: Receiver) -> Result<(), std::i )); interval.tick().await; interval.tick().await; - send_lost_effect(from_id, data, effect_id); + send_lost_effect( + from_id, + data, + effect_id, + effect_param, + effect_source_actor_id, + ); }); } ToServer::Disconnected(from_id) => {