diff --git a/README.md b/README.md index 20ff3d1..a0252d2 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,13 @@ This sprinting mod was inspired by GunshipPenguin's own [sprinting mod](https:// The speed and jump multipliers, as well as hotkeys, can be configured directly from the advanced settings menu in the sprint subsection of the top-level Mods section. You can also configure sprint directly from `minetest.conf` with the settings listed below. -| Name | Type | Description | -| -------------- | ------ | --------------------- | -| sprint_primary | string | Primary sprinting key | -| sprint_speed | float | Speed multiplier | -| sprint_jump | float | Jump multiplier | -| sprint_dir | bool | Directional sprinting | +| Name | Type | Description | +| -------------------- | ------ | -------------------------- | +| sprint_primary | string | Primary sprinting key | +| sprint_second | string | Secondary sprinting key | +| sprint_enable_second | bool | Allow secondary sprint key | +| sprint_speed | float | Speed multiplier | +| sprint_jump | float | Jump multiplier | +| sprint_dir | bool | Directional sprinting | -`sprint_primary` is the codename of the primary sprint key which causes the speed and jump multipliers to be applied to the player while it is held. If `sprint_dir` is set to `true`, players can only sprint while moving forward. +`sprint_primary` is the codename of the primary sprint key which causes the speed and jump multipliers to be applied to the player while it is held. If `sprint_dir` is set to `true`, players can only sprint while moving forward. `sprint_second` defines a key that if `sprint_enable_second` is set to `true` (default) triggers sprinting when pressed twice within 0.8 seconds. diff --git a/init.lua b/init.lua index d816819..ed0f7b1 100644 --- a/init.lua +++ b/init.lua @@ -1,23 +1,26 @@ -- sprint/init.lua local sprinting = {} -local SPEED = minetest.settings:get("sprint_speed") or 1.8 -local JUMP = minetest.settings:get("sprint_jump") or 1.1 -local PRIMARY = minetest.settings:get("sprint_primary") or "aux1" -local DIR = minetest.settings:get("sprint_dir") or true +local secondary = {} +local SPEED = minetest.settings:get("sprint_speed") or 1.8 +local JUMP = minetest.settings:get("sprint_jump") or 1.1 +local PRIMARY = minetest.settings:get("sprint_primary") or "aux1" +local SECOND = minetest.settings:get("sprint_second") or "up" +local DIR = minetest.settings:get("sprint_dir") or true +local ALLOW_SEC = minetest.settings:get("sprint_enable_second") --- --- Functions --- -local function start_sprint(player, name) +local function start_sprint(player, name, trigger) player:set_physics_override({speed = SPEED, jump = JUMP}) - sprinting[name] = true + sprinting[name] = {is = true, trigger = trigger} end local function stop_sprint(player, name) player:set_physics_override({speed = 1, jump = 1}) - sprinting[name] = false + sprinting[name] = {is = false} end --- @@ -29,6 +32,12 @@ minetest.register_globalstep(function(dtime) local name = player:get_player_name() local ctrl = player:get_player_control() + if not sprinting[name] then + sprinting[name] = {is = false} + end + + local spr = sprinting[name] + local allow = true if DIR == true then if not ctrl.up then @@ -36,11 +45,45 @@ minetest.register_globalstep(function(dtime) end end - if ctrl[PRIMARY] and allow and not sprinting[name] then - start_sprint(player, name) - elseif (not ctrl[PRIMARY] and sprinting[name] == true) or - (ctrl[PRIMARY] and not allow and sprinting[name] == true) then + -- Primary Key + if ctrl[PRIMARY] and allow and not spr.is then + start_sprint(player, name, "primary") + elseif ((not ctrl[PRIMARY] and spr.is) or + (ctrl[PRIMARY] and not allow and spr.is)) + and spr.trigger == "primary" then stop_sprint(player, name) end + + -- Secondary Key + if ALLOW_SEC ~= "false" and SECOND and SECOND ~= "" and spr.trigger ~= "primary" then + if not secondary[name] then + secondary[name] = {count = 0, time = 0, last = false} + end + + if ctrl[SECOND] ~= secondary[name].last then + if secondary[name].time > 0.8 and not spr.is and + secondary[name].count > 0 and secondary[name].count < 3 then + secondary[name] = {count = 0, time = 0, last = false} + return + end + + if secondary[name].count < 3 and ctrl[SECOND] ~= secondary[name].last then + secondary[name].count = secondary[name].count + 1 + secondary[name].last = ctrl[SECOND] + end + + if (secondary[name].count == 3 and ctrl[SECOND]) and allow and not spr.is then + start_sprint(player, name, "secondary") + elseif ((secondary[name].count > 3 or not ctrl[SECOND]) or not allow) and + spr.is then + stop_sprint(player, name) + secondary[name] = {count = 0, time = 0, last = false} + end + end + + if not spr.is and secondary[name].count ~= 0 then + secondary[name].time = secondary[name].time + dtime + end + end end end) diff --git a/settingtypes.txt b/settingtypes.txt index 9bdc166..7e9d63d 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -4,6 +4,15 @@ # This defaults to aux1, which is also used if fast_move is enabled. sprint_primary (Primary Sprint Key) string aux1 +# Secondary key that triggers the speed and jump multipliers when double-pressed +# and held for the duration. This is most convenient to map to the "up" ("forward") +# key, as it allows seemlessly enabling sprint by simply double-tapping forward +# without having to move your hand to reach another key. +sprint_second (Secondary Sprint Key) string up + +# If disabled, the secondary sprint key (sprint_second) is not allowed. +sprint_enable_second (Allow Secondary Sprint Key) bool true + # Speed multiplier applied when sprinting. # Sprint key configured with the sprint_primary setting. sprint_speed (Speed Multiplier) float 1.8