sprint/init.lua
Unknown 965bda22d4 Slow sprinting underwater
Completely configurable as documented in the README.
2018-03-15 12:30:09 -07:00

187 lines
5.6 KiB
Lua

-- sprint/init.lua
local sprinting = {}
local secondary = {}
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 SPEED = minetest.settings:get("sprint_speed")
local JUMP = minetest.settings:get("sprint_jump")
local WATER_SPEED = minetest.settings:get("sprint_water_speed")
local WATER_JUMP = minetest.settings:get("sprint_water_jump")
local PARTICLE_NUM = minetest.settings:get("sprint_particles")
local ALLOW_SEC = minetest.settings:get("sprint_enable_second")
local SLOW_IN_WATER = minetest.settings:get("sprint_slow_in_water") or "true"
SPEED = tonumber(SPEED) or 1.3
JUMP = tonumber(JUMP) or 1.1
WATER_SPEED = tonumber(WATER_SPEED) or 1.1
WATER_JUMP = tonumber(WATER_JUMP) or 1
PARTICLE_NUM = tonumber(PARTICLE_NUM) or 1
---
--- Functions
---
local function start_sprint(player, name, trigger, in_water, log)
local new_speed = SPEED
local new_jump = JUMP
if in_water then
new_speed = WATER_SPEED
new_jump = WATER_JUMP
end
if player_monoids then
player_monoids.speed:add_change(player, new_speed, "sprint:sprint")
player_monoids.jump:add_change(player, new_jump, "sprint:jump")
else
player:set_physics_override({speed = new_speed, jump = new_jump})
end
if log ~= false then
sprinting[name] = {is = true, trigger = trigger}
end
end
local function stop_sprint(player, name)
if player_monoids then
player_monoids.speed:del_change(player, "sprint:sprint")
player_monoids.jump:del_change(player, "sprint:jump")
else
player:set_physics_override({speed = 1, jump = 1})
end
sprinting[name] = {is = false}
end
---
--- Registrations
---
minetest.register_globalstep(function(dtime)
for _, player in pairs(minetest.get_connected_players()) do
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
allow = false
end
end
if spr.is then
-- Stop sprinting when movement controls are released even though
-- sprint key is still pressed
if DIR == "true" then
if not ctrl.up then
stop_sprint(player, name)
end
else
if not ctrl.up and not ctrl.down and not ctrl.right and not ctrl.left then
stop_sprint(player, name)
end
end
-- Check if in water
if SLOW_IN_WATER then
local node = minetest.registered_nodes[minetest.get_node(player:get_pos()).name]
if node then
if (node.liquidtype ~= "none" and node.liquidtype) and not spr.in_water then
spr.in_water = true
start_sprint(player, name, nil, true, false)
elseif spr.in_water and (node.liquidtype == "none" or not node.liquidtype) then
spr.in_water = false
start_sprint(player, name, nil, false, false)
end
end
end
end
-- Begin sprinting again when movement controls are pressed again even
-- if the sprint key has not been triggered again but is just being held
if ctrl[PRIMARY] and allow and not spr.is and (ctrl.up or ctrl.down or ctrl.right or
ctrl.left) then
start_sprint(player, name, spr.trigger)
end
-- Primary Key
if ctrl[PRIMARY] and allow and not spr.is and (ctrl.up or ctrl.down or ctrl.right or
ctrl.left) 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
-- Particles
if PARTICLE_NUM ~= 0 and spr.is then
local pos = player:get_pos()
pos.y = pos.y - 1
local node = minetest.get_node_or_nil(pos)
if node and node.name ~= "air" and node.name ~= "ignore" then
local def = minetest.registered_nodes[node.name]
local tile = def.tiles[1] or def.inventory_image or ""
if type(tile) == "string" then
minetest.add_particlespawner({
time = 0.5,
amount = PARTICLE_NUM,
minpos = {x = pos.x - 0.5, y = pos.y + 1.1, z = pos.z - 0.5},
maxpos = {x = pos.x + 0.5, y = pos.y + 1.1, z = pos.z + 0.5},
minvel = {x = 0, y = 3, z = 0},
maxvel = {x = 0, y = 5, z = 0},
minacc = {x = 0, y = -10, z = 0},
maxacc = {x = 0, y = -13, z = 0},
minexptime = 0.5,
maxexptime = 1,
minsize = 0.5,
maxsize = 2,
collisiondetection = true,
vertical = false,
texture = tile,
})
end
end
end
end
end)