diff --git a/resources/scripts/Global.lua b/resources/scripts/Global.lua index f41a897..045df37 100644 --- a/resources/scripts/Global.lua +++ b/resources/scripts/Global.lua @@ -49,3 +49,4 @@ registerEvent(1245187, "opening/OpeningUldah.lua") registerCommand("setpos", "commands/debug/SetPos.lua") registerCommand("classjob", "commands/debug/ClassJob.lua") registerCommand("setspeed", "commands/debug/SetSpeed.lua") +registerCommand("nudge", "commands/debug/Nudge.lua") diff --git a/resources/scripts/commands/debug/Nudge.lua b/resources/scripts/commands/debug/Nudge.lua new file mode 100644 index 0000000..6c137ca --- /dev/null +++ b/resources/scripts/commands/debug/Nudge.lua @@ -0,0 +1,78 @@ +-- Ported from Ioncannon's Project Meteor Server +-- https://bitbucket.org/Ioncannon/project-meteor-server/src/develop/Data/scripts/commands/gm/nudge.lua + +function send_msg(message, player) + player:send_message(string.format("[nudge] %s", message)) +end + +function onCommand(args, player) + local parts = split(args) + local argc = table.getn(parts) + local pos = player.position + local angle = player.rotation + (math.pi / 2) + local distance = 5 + local direction = 0 + local arg1 = parts[1] + local arg2 = parts[2] + local checkArg1 = tonumber(arg1) + local checkArg2 = tonumber(arg2) + local vertical = { + ["UP"] = 1, + ["U"] = 1, + ["+"] = 1, + ["ASCEND"] = 1, + ["DOWN"] = -1, + ["D"] = -1, + ["-"] = -1, + ["DESCEND"] = -1, + } + + if argc == 1 then + if checkArg1 then + distance = checkArg1 + else + send_msg("Error parsing direction! Usage: !nudge ", player) + return + end + end + + if argc == 2 then + if checkArg1 and checkArg2 then + distance = checkArg1 + elseif checkArg1 and not checkArg2 then + distance = checkArg1 + if vertical[string.upper(arg2)] then + direction = vertical[string.upper(arg2)] + else + send_msg("Error parsing direction! Usage: !nudge ", player) + return + end + else + send_msg("Error parsing parameters! Usage: !nudge ", player) + return + end + end + + local message = string.format("Positioning forward %s yalms", distance) + local position = { x = 0.0, y = 0.0, z = 0.0 } + + if direction == 1 then + local py = pos.y + distance + message = string.format("Positioning up %s yalms.", distance) + position = { x = pos.x, y = py, z = pos.z } + elseif direction == -1 then + local py = pos.y - distance + message = string.format("Positioning down %s yalms.", distance) + position = { x = pos.x, y = py, z = pos.z } + else + local px = pos.x - distance * math.cos(angle) + local pz = pos.z + distance * math.sin(angle) + if distance < 1 then + message = string.format("Positioning back %s yalms.", distance) + end + position = { x = px, y = pos.y, z = pz } + end + + player:set_position(position, player.rotation) + send_msg(message, player) +end diff --git a/resources/scripts/commands/debug/SetPos.lua b/resources/scripts/commands/debug/SetPos.lua index 960bf14..5cfb508 100644 --- a/resources/scripts/commands/debug/SetPos.lua +++ b/resources/scripts/commands/debug/SetPos.lua @@ -1,4 +1,4 @@ function onCommand(args, player) local parts = split(args) - player:set_position({ x = tonumber(parts[1]), y = tonumber(parts[2]), z = tonumber(parts[3]) }) + player:set_position({ x = tonumber(parts[1]), y = tonumber(parts[2]), z = tonumber(parts[3]) }, 0) end diff --git a/src/world/lua.rs b/src/world/lua.rs index cfdc2c4..3655387 100644 --- a/src/world/lua.rs +++ b/src/world/lua.rs @@ -1,7 +1,7 @@ use mlua::{FromLua, Lua, LuaSerdeExt, UserData, UserDataFields, UserDataMethods, Value}; use crate::{ - common::{ObjectId, ObjectTypeId, Position, timestamp_secs, workdefinitions::RemakeMode}, + common::{ObjectId, ObjectTypeId, Position, timestamp_secs, workdefinitions::RemakeMode, write_quantized_rotation}, ipc::zone::{ ActionEffect, DamageElement, DamageKind, DamageType, EffectKind, EventScene, ServerZoneIpcData, ServerZoneIpcSegment, Warp, @@ -88,12 +88,13 @@ impl LuaPlayer { }); } - fn set_position(&mut self, position: Position) { + fn set_position(&mut self, position: Position, rotation: f32) { let ipc = ServerZoneIpcSegment { op_code: ServerZoneIpcType::Warp, timestamp: timestamp_secs(), data: ServerZoneIpcData::Warp(Warp { - position, + dir: write_quantized_rotation(&rotation), + position: position, ..Default::default() }), ..Default::default() @@ -156,9 +157,10 @@ impl UserData for LuaPlayer { Ok(()) }, ); - methods.add_method_mut("set_position", |lua, this, position: Value| { + methods.add_method_mut("set_position", |lua, this, (position, rotation): (Value, Value)| { let position: Position = lua.from_value(position).unwrap(); - this.set_position(position); + let rotation: f32 = lua.from_value(rotation).unwrap(); + this.set_position(position, rotation); Ok(()) }); methods.add_method_mut("change_territory", |_, this, zone_id: u16| { @@ -203,6 +205,12 @@ impl UserData for LuaPlayer { fields.add_field_method_get("teleport_query", |_, this| { Ok(this.player_data.teleport_query.clone()) }); + fields.add_field_method_get("rotation", |_, this| { + Ok(this.player_data.rotation) + }); + fields.add_field_method_get("position", |_, this| { + Ok(this.player_data.position) + }); } } @@ -212,7 +220,13 @@ impl UserData for TeleportQuery { } } -impl UserData for Position {} +impl UserData for Position { + fn add_fields>(fields: &mut F) { + fields.add_field_method_get("x", |_, this| Ok(this.x)); + fields.add_field_method_get("y", |_, this| Ok(this.y)); + fields.add_field_method_get("z", |_, this| Ok(this.z)); + } +} impl UserData for ObjectTypeId {}