diff --git a/resources/scripts/Global.lua b/resources/scripts/Global.lua index eb9ac3a..da8b71e 100644 --- a/resources/scripts/Global.lua +++ b/resources/scripts/Global.lua @@ -4,3 +4,4 @@ function onBeginLogin(player) end registerAction(3, "actions/Sprint.lua") +registerAction(9, "actions/FastBlade.lua") diff --git a/resources/scripts/actions/FastBlade.lua b/resources/scripts/actions/FastBlade.lua new file mode 100644 index 0000000..ee25683 --- /dev/null +++ b/resources/scripts/actions/FastBlade.lua @@ -0,0 +1,6 @@ +function doAction(player) + effects = EffectsBuilder() + effects:damage(20) + + return effects +end diff --git a/resources/scripts/actions/Sprint.lua b/resources/scripts/actions/Sprint.lua index 92fe718..fce4490 100644 --- a/resources/scripts/actions/Sprint.lua +++ b/resources/scripts/actions/Sprint.lua @@ -1,4 +1,9 @@ function doAction(player) + effects = EffectsBuilder() + + -- TODO: go through effectsbuilder -- give sprint player:give_status_effect(50, 5.0) + + return effects end diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 3e14171..8a181d1 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -27,7 +27,7 @@ use kawari::world::{ SocialList, }, }; -use kawari::world::{LuaPlayer, PlayerData, StatusEffects, WorldDatabase}; +use kawari::world::{EffectsBuilder, LuaPlayer, PlayerData, StatusEffects, WorldDatabase}; use mlua::{Function, Lua}; use physis::common::{Language, Platform}; use physis::gamedata::GameData; @@ -71,6 +71,13 @@ async fn main() { .set("registerAction", register_action_func) .unwrap(); + let effectsbuilder_constructor = lua + .create_function(|_, ()| Ok(EffectsBuilder::default())) + .unwrap(); + lua.globals() + .set("EffectsBuilder", effectsbuilder_constructor) + .unwrap(); + let file_name = format!("{}/Global.lua", &config.world.scripts_location); lua.load(std::fs::read(&file_name).expect("Failed to locate scripts directory!")) .set_name("@".to_string() + &file_name) @@ -778,6 +785,8 @@ async fn main() { .await; } + let mut effects_builder = None; + // run action script { let lua = lua.lock().unwrap(); @@ -807,7 +816,12 @@ async fn main() { let func: Function = lua.globals().get("doAction").unwrap(); - func.call::<()>(connection_data).unwrap(); + effects_builder = Some( + func.call::( + connection_data, + ) + .unwrap(), + ); Ok(()) }) @@ -816,14 +830,10 @@ async fn main() { } // tell them the action results - { + if let Some(effects_builder) = effects_builder { let mut effects = [ActionEffect::default(); 8]; - effects[0] = ActionEffect { - action_type: 3, - value: 22, - param1: 133, - ..Default::default() - }; + effects[..effects_builder.effects.len()] + .copy_from_slice(&effects_builder.effects); let ipc = ServerZoneIpcSegment { op_code: ServerZoneIpcType::ActionResult, @@ -843,7 +853,8 @@ async fn main() { rotation: connection.player_data.rotation, action_animation_id: 31, flag: 1, - effect_count: 1, + effect_count: effects_builder.effects.len() + as u8, effects, ..Default::default() }, diff --git a/src/world/lua.rs b/src/world/lua.rs index 4d7ce27..e7b3343 100644 --- a/src/world/lua.rs +++ b/src/world/lua.rs @@ -1,4 +1,4 @@ -use mlua::{FromLua, Lua, UserData, UserDataMethods, Value}; +use mlua::{FromLua, Lua, MetaMethod, UserData, UserDataMethods, Value}; use crate::{ common::{ObjectId, ObjectTypeId, Position, timestamp_secs}, @@ -8,7 +8,7 @@ use crate::{ use super::{ PlayerData, StatusEffects, Zone, - ipc::{ActorSetPos, EventPlay, ServerZoneIpcData, ServerZoneIpcSegment}, + ipc::{ActionEffect, ActorSetPos, EventPlay, ServerZoneIpcData, ServerZoneIpcSegment}, }; pub struct ChangeTerritoryTask { @@ -161,3 +161,31 @@ impl UserData for Zone { ); } } + +#[derive(Clone, Debug, Default)] +pub struct EffectsBuilder { + pub effects: Vec, +} + +impl UserData for EffectsBuilder { + fn add_methods>(methods: &mut M) { + methods.add_method_mut("damage", |_, this, amount: u16| { + this.effects.push(ActionEffect { + action_type: 3, + value: amount, + param1: 133, + ..Default::default() + }); + Ok(()) + }); + } +} + +impl FromLua for EffectsBuilder { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + match value { + Value::UserData(ud) => Ok(ud.borrow::()?.clone()), + _ => unreachable!(), + } + } +} diff --git a/src/world/mod.rs b/src/world/mod.rs index 3dd0d47..3730011 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -16,7 +16,7 @@ mod inventory; pub use inventory::{EquippedContainer, Inventory, Item}; mod lua; -pub use lua::LuaPlayer; +pub use lua::{EffectsBuilder, LuaPlayer}; mod event; pub use event::Event;