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

Remove most of the hardcoded effect durations and params

This commit is contained in:
Joshua Goins 2025-07-14 20:26:13 -04:00
parent f54fc126b3
commit 099dfbd134
10 changed files with 104 additions and 39 deletions

View file

@ -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

View file

@ -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

View file

@ -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,
}

View file

@ -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,
}
);

View file

@ -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)]

View file

@ -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,

View file

@ -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<ServerZoneIpcSegment>),
/// 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)]

View file

@ -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;

View file

@ -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| {
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(())
});
},
);
}
}

View file

@ -418,8 +418,13 @@ pub async fn server_main_loop(mut recv: Receiver<ToServer>) -> 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<ToServer>) -> 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<Mutex<WorldServer>>, effect_id: u16| {
|from_id: ClientId,
data: Arc<Mutex<WorldServer>>,
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<ToServer>) -> 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<ToServer>) -> 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) => {