From 4b8a75ca93368900cc7a66d658bb47f9320c065f Mon Sep 17 00:00:00 2001 From: Pilcrow182 Date: Tue, 13 Nov 2018 16:38:47 -0600 Subject: [PATCH] fix movement 'bouncing' on servers --- README.md | 6 +++--- init.lua | 38 ++++++++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 391a1e0..7ddec62 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,6 @@ version 0.9, This mod adds a flying saucer vehicle to the Minetest game, using the same basic concept as the [cars mod](https://forum.minetest.net/viewtopic.php?t=13988) by cheapie: it changes the player character's model and movement ability/controls rather than spawning a new entity and attaching the player to it. Theoretically, this means less lag. This mod was originally intended to become a drop-in replacement for the [helicopter mod](https://forum.minetest.net/viewtopic.php?f=11&t=6183) by Pavel_S, but was later changed to a flying saucer. The 3D model was taken from Zeg9's [UFOs mod](https://forum.minetest.net/viewtopic.php?f=11&t=4086), though none of our code or textures are shared, and our controls are nothing alike. -Please report any issues at the [Flying Saucer GitHub page](https://github.com/Pilcrow182/flying_saucer) or the [Release thread on the Minetest forums](https://forum.minetest.net/viewtopic.php?f=9&t=21330). - ------------------------------------------------------------------------------- ### Controls: @@ -36,10 +34,12 @@ None (though the [crafting recipe](https://raw.githubusercontent.com/Pilcrow182/ ### Known bugs: -Holding shift cuts the player's horizontal movement to 1/3 speed. This is a side-effect of using the player entity's controls, since shift is normally used for 'sneaking' (which is *supposed* to slow the player's movement). If anyone can figure out how to disable this feature during saucer mode, I'd be happy to hear it. +Holding shift cuts the player's horizontal movement to 1/3 speed. This is a side-effect of using the player entity's controls, since shift is normally used for 'sneaking' (which is *supposed* to slow the player's movement). If anyone can figure out how to disable this feature during saucer mode, I'd be happy to hear it. Unlike horizontal movement (which is managed client-side), the vertical movement is dependent on server cycles. This means if there is anything causing excessive lag, it may negatively affect the user's ability to move up/down (or to *stop* moving, regardless of the `flying_saucer_passive_stop` setting). +Please report any other issues at the [Flying Saucer GitHub page](https://github.com/Pilcrow182/flying_saucer) or the [Release thread on the Minetest forums](https://forum.minetest.net/viewtopic.php?f=9&t=21330). + ------------------------------------------------------------------------------- ### Credits: diff --git a/init.lua b/init.lua index 3c59b68..2cbcb1d 100644 --- a/init.lua +++ b/init.lua @@ -20,7 +20,10 @@ flying_saucer = {} -flying_saucer.speed = minetest.settings:get("flying_saucer_speed") or 8 +flying_saucer.delay = tonumber(minetest.settings:get("flying_saucer_delay") or 0.2) +minetest.settings:set("flying_saucer_delay", flying_saucer.delay) + +flying_saucer.speed = tonumber(minetest.settings:get("flying_saucer_speed") or 8) minetest.settings:set("flying_saucer_speed", flying_saucer.speed) flying_saucer.passive_stop = minetest.settings:get_bool("flying_saucer_passive_stop", false) @@ -28,9 +31,12 @@ minetest.settings:set_bool("flying_saucer_passive_stop", flying_saucer.passive_s flying_saucer.storage = {} +local DEBUG = false local debug_msg = function(message) - minetest.chat_send_all(message) - minetest.log("action", message) + if DEBUG then + minetest.chat_send_all(message) + minetest.log("action", message) + end end local activate_flying_saucer = function(player, name) @@ -74,33 +80,45 @@ minetest.register_entity("flying_saucer:stopper_entity", { local timer = 0 minetest.register_globalstep(function(dtime) + local delay = flying_saucer.delay timer = timer + dtime - if timer >= 0.2 then + if timer >= delay then timer = 0 for name,_ in pairs(flying_saucer.storage) do local player = minetest.get_player_by_name(name) if player then + local saucer_speed = flying_saucer.speed local ctrl = player:get_player_control() local velocity = player:get_player_velocity() - local saucer_speed = tonumber(flying_saucer.speed) local physics = {speed = saucer_speed/4, jump = 0, gravity = 0, sneak = false, sneak_glitch = false} - if (ctrl.jump or (flying_saucer.storage[name].state == "ascending" and velocity.y ~= 0)) and not (ctrl.sneak or ctrl.aux1) then + if (ctrl.jump or (flying_saucer.storage[name].state == "ascending" and velocity.y > 0 and not flying_saucer.passive_stop)) and not (ctrl.sneak or ctrl.aux1) then flying_saucer.storage[name].state = "ascending" - physics.gravity = -(saucer_speed-velocity.y)/saucer_speed + physics.gravity = -(math.min(saucer_speed, math.max(0, saucer_speed-velocity.y))/saucer_speed)*(1-math.min(0.7, math.max(0, delay))) + debug_msg("boosting "..name.."'s upward speed by "..physics.gravity) player:set_physics_override(physics) - elseif (ctrl.sneak or (flying_saucer.storage[name].state == "descending" and velocity.y ~= 0)) and not (ctrl.jump or ctrl.aux1) then + + elseif (ctrl.sneak or (flying_saucer.storage[name].state == "descending" and velocity.y < 0 and not flying_saucer.passive_stop)) and not (ctrl.jump or ctrl.aux1) then flying_saucer.storage[name].state = "descending" - physics.gravity = (saucer_speed+velocity.y)/saucer_speed + physics.gravity = (math.min(saucer_speed, math.max(0, saucer_speed+velocity.y))/saucer_speed)*(1-math.min(0.7, math.max(0, delay))) + debug_msg("boosting "..name.."'s downward speed by "..physics.gravity) player:set_physics_override(physics) + elseif ((ctrl.aux1 or flying_saucer.passive_stop or velocity.y == 0) and flying_saucer.storage[name].state ~= "idle") or not flying_saucer.storage[name].state then + debug_msg("stopping player "..name) + stopping_player = name + minetest.add_entity(player:get_pos(), "flying_saucer:stopper_entity") + player:set_physics_override(physics) + + elseif velocity.y > math.max(saucer_speed, 14) or velocity.y < -math.max(saucer_speed, 14) then + minetest.chat_send_player(name, "Flying Saucer to "..name..": unsafe speeds detected; halting vertical movement.") stopping_player = name minetest.add_entity(player:get_pos(), "flying_saucer:stopper_entity") player:set_physics_override(physics) end local state = flying_saucer.storage[name].state or "idle" --- debug_msg("player '"..name.."' is "..state.." (physics="..minetest.pos_to_string({x=physics.speed, y=physics.jump,z=physics.gravity})..", velocity="..minetest.pos_to_string(velocity)..")...") + debug_msg("player '"..name.."' is "..state.." (physics="..minetest.pos_to_string({x=physics.speed, y=physics.jump,z=physics.gravity})..", velocity="..minetest.pos_to_string(velocity)..")...") end end end