From afbadf85c444bdb57e7dfc611cd20aac4bc1329d Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 5 May 2025 21:15:03 -0400 Subject: [PATCH] Clean up talk event handling, use Event struct --- .../scripts/warp/WarpInnLimsaLominsa.lua | 4 +- src/bin/kawari-world.rs | 42 ++++--------------- src/world/event.rs | 16 ++++++- src/world/lua.rs | 26 +++++++----- 4 files changed, 42 insertions(+), 46 deletions(-) diff --git a/resources/scripts/warp/WarpInnLimsaLominsa.lua b/resources/scripts/warp/WarpInnLimsaLominsa.lua index 051e065..2c40b4f 100644 --- a/resources/scripts/warp/WarpInnLimsaLominsa.lua +++ b/resources/scripts/warp/WarpInnLimsaLominsa.lua @@ -1,9 +1,9 @@ --- TODO: find a way to hardcode it this way EVENT_ID = 131079 -function onTalk(actorId, player) +function onTalk(target, player) -- has inn access - player:play_scene(actorId, EVENT_ID, 00001, 8192, 0) + player:play_scene(target, EVENT_ID, 00001, 8192, 0) -- doesn't have inn access --player:play_scene(actorId, EVENT_ID, 00002, 8192, 0) diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index f1c641b..07a7fc2 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -21,7 +21,7 @@ use kawari::packet::{ ConnectionType, PacketSegment, PacketState, SegmentData, SegmentType, send_keep_alive, }; use kawari::world::{ - Actor, ClientHandle, EffectsBuilder, FromServer, LuaPlayer, PlayerData, ServerHandle, + Actor, ClientHandle, EffectsBuilder, Event, FromServer, LuaPlayer, PlayerData, ServerHandle, StatusEffects, ToServer, WorldDatabase, handle_custom_ipc, server_main_loop, }; use kawari::world::{ChatHandler, Zone, ZoneConnection}; @@ -726,7 +726,7 @@ async fn client_loop( connection.send_inventory(true).await; } ClientZoneIpcData::StartTalkEvent { actor_id, event_id } => { - // load scene + // load event { let ipc = ServerZoneIpcSegment { op_code: ServerZoneIpcType::EventStart, @@ -740,8 +740,6 @@ async fn client_loop( ..Default::default() }; - dbg!(&ipc); - connection .send_segment(PacketSegment { source_actor: connection.player_data.actor_id, @@ -758,35 +756,12 @@ async fn client_loop( if let Some(event_script) = state.event_scripts.get(event_id) { - // run script - lua.scope(|scope| { - let connection_data = scope - .create_userdata_ref_mut(&mut lua_player) - .unwrap(); - - let config = get_config(); - - let file_name = format!( - "{}/{}", - &config.world.scripts_location, event_script - ); - lua.load( - std::fs::read(&file_name) - .expect("Failed to locate scripts directory!"), - ) - .set_name("@".to_string() + &file_name) - .exec() - .unwrap(); - - let func: Function = - lua.globals().get("onTalk").unwrap(); - - func.call::<()>((actor_id.object_id.0, &connection_data)) - .unwrap(); - - Ok(()) - }) - .unwrap(); + connection.event = Some(Event::new(&event_script)); + connection + .event + .as_mut() + .unwrap() + .talk(*actor_id, &mut lua_player); } else { tracing::warn!("Event {event_id} isn't scripted yet! Ignoring..."); } @@ -818,6 +793,7 @@ async fn client_loop( .await; } + // give back control to the player { let ipc = ServerZoneIpcSegment { op_code: ServerZoneIpcType::Unk18, diff --git a/src/world/event.rs b/src/world/event.rs index 1c85905..ce4c5d5 100644 --- a/src/world/event.rs +++ b/src/world/event.rs @@ -1,6 +1,6 @@ use mlua::{Function, Lua}; -use crate::config::get_config; +use crate::{common::ObjectTypeId, config::get_config}; use super::{LuaPlayer, Zone}; @@ -50,4 +50,18 @@ impl Event { }) .unwrap(); } + + pub fn talk(&mut self, target_id: ObjectTypeId, player: &mut LuaPlayer) { + self.lua + .scope(|scope| { + let player = scope.create_userdata_ref_mut(player).unwrap(); + + let func: Function = self.lua.globals().get("onTalk").unwrap(); + + func.call::<()>((target_id, player)).unwrap(); + + Ok(()) + }) + .unwrap(); + } } diff --git a/src/world/lua.rs b/src/world/lua.rs index d6d919f..fc1bd5a 100644 --- a/src/world/lua.rs +++ b/src/world/lua.rs @@ -1,7 +1,7 @@ use mlua::{FromLua, Lua, LuaSerdeExt, UserData, UserDataMethods, Value}; use crate::{ - common::{ObjectId, ObjectTypeId, Position, timestamp_secs, workdefinitions::RemakeMode}, + common::{ObjectTypeId, Position, timestamp_secs, workdefinitions::RemakeMode}, ipc::zone::{ ActionEffect, DamageElement, DamageKind, DamageType, EffectKind, EventScene, ServerZoneIpcData, ServerZoneIpcSegment, Warp, @@ -55,7 +55,7 @@ impl LuaPlayer { fn play_scene( &mut self, - actor_id: u32, + target: ObjectTypeId, event_id: u32, scene: u16, scene_flags: u32, @@ -65,10 +65,7 @@ impl LuaPlayer { op_code: ServerZoneIpcType::EventScene, timestamp: timestamp_secs(), data: ServerZoneIpcData::EventScene(EventScene { - actor_id: ObjectTypeId { - object_id: ObjectId(actor_id), - object_type: 1, - }, + actor_id: target, event_id, scene, scene_flags, @@ -78,8 +75,6 @@ impl LuaPlayer { ..Default::default() }; - dbg!(&ipc); - self.queue_segment(PacketSegment { source_actor: self.player_data.actor_id, target_actor: self.player_data.actor_id, @@ -131,8 +126,8 @@ impl UserData for LuaPlayer { ); methods.add_method_mut( "play_scene", - |_, this, (actor_id, event_id, scene, scene_flags, param): (u32, u32, u16, u32, u8)| { - this.play_scene(actor_id, event_id, scene, scene_flags, param); + |_, this, (target, event_id, scene, scene_flags, param): (ObjectTypeId, u32, u16, u32, u8)| { + this.play_scene(target, event_id, scene, scene_flags, param); Ok(()) }, ); @@ -163,6 +158,17 @@ impl FromLua for Position { } } +impl UserData for ObjectTypeId {} + +impl FromLua for ObjectTypeId { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + match value { + Value::UserData(ud) => Ok(*ud.borrow::()?), + _ => unreachable!(), + } + } +} + impl UserData for Zone { fn add_methods>(methods: &mut M) { methods.add_method(