diff --git a/init.lua b/init.lua index 8b13789..a635790 100644 --- a/init.lua +++ b/init.lua @@ -1 +1,6 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +for _, f in ipairs({"sprint"}) do + dofile(modpath .. "/" .. f .. ".lua") +end diff --git a/sprint.lua b/sprint.lua new file mode 100644 index 0000000..2069228 --- /dev/null +++ b/sprint.lua @@ -0,0 +1,72 @@ +-- set up our initial values +local running = false +local run_discharge_timer = 0 +local old_up = false +local channel +local channel_name + +-- receive the server states +minetest.register_on_modchannel_message(function(cname, sender, message) + if sender == "" and cname == channel_name then + running = false + run_discharge_timer = 0 + end +end) + +-- check player's input on the "up" key +minetest.register_globalstep(function(dtime) + local player = minetest.localplayer + + if not player then + return + elseif not channel then + channel_name = "mcl_sprint:" .. player:get_name() + channel = minetest.mod_channel_join(channel_name) + end + + local old_running = running + + local control = player:get_control() + local velocity = player:get_velocity() + local last_velocity = player:get_last_velocity() + + -- cancel running if the player bumps into something + if running and (velocity.x == 0 and last_velocity.x ~= 0 or velocity.z == 0 and last_velocity.z ~= 0) then + running = false + run_discharge_timer = 0 + end + + -- reset the run flag + if running and (not control.up or control.sneak or control.down) then + running = false + end + + -- half second window to double tap running + if run_discharge_timer > 0 then + run_discharge_timer = run_discharge_timer - dtime + + -- initialize double tap run + if not old_up and control.up == true and velocity.x ~= 0 and velocity.z ~= 0 then + run_discharge_timer = 0 + running = true + end + end + + -- check if new input of walking forwards + if control.up and not control.down and not control.sneak and not old_up and not running and run_discharge_timer <= 0 then + run_discharge_timer = 0.2 + end + + -- add this here so the player can sneak + if control.sneak then + running = false + run_discharge_timer = 0 + end + + -- only send if state has changed + if running ~= old_running then + channel:send_all(running and "true" or "false") + end + + old_up = control.up +end)