--[[ Sprint mod for Minetest by GunshipPenguin To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. ]] --Configuration variables, these are all explained in README.md mcl_sprint = {} mcl_sprint.SPEED = 1.3 local players = {} -- Returns true if the player with the given name is sprinting, false if not. -- Returns nil if player does not exist. mcl_sprint.is_sprinting = function(playername) if players[playername] then return players[playername].sprinting else return nil end end minetest.register_on_joinplayer(function(player) local playerName = player:get_player_name() players[playerName] = { sprinting = false, timeOut = 0, shouldSprint = false, lastPos = player:get_pos(), sprintDistance = 0, fov = 1.0 } end) minetest.register_on_leaveplayer(function(player) local playerName = player:get_player_name() players[playerName] = nil end) local function setSprinting(playerName, sprinting) --Sets the state of a player (0=stopped/moving, 1=sprinting) local player = minetest.get_player_by_name(playerName) if players[playerName] then players[playerName].sprinting = sprinting if sprinting == true then players[playerName].fov = math.min(players[playerName].fov + 0.03, 1.2) player:set_fov(players[playerName].fov, true, 0.15) playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED) elseif sprinting == false then players[playerName].fov = math.max(players[playerName].fov - 0.03, 1.0) player:set_fov(players[playerName].fov, true, 0.15) playerphysics.remove_physics_factor(player, "speed", "mcl_sprint:sprint") end return true end return false end minetest.register_globalstep(function(dtime) --Get the gametime local gameTime = minetest.get_gametime() --Loop through all connected players for playerName,playerInfo in pairs(players) do local player = minetest.get_player_by_name(playerName) if player ~= nil then local ctrl = player:get_player_control() --Check if the player should be sprinting if ctrl.aux1 and ctrl.up and not ctrl.sneak then players[playerName]["shouldSprint"] = true else players[playerName]["shouldSprint"] = false end local playerPos = player:get_pos() --If the player is sprinting, create particles behind and cause exhaustion if playerInfo["sprinting"] == true and gameTime % 0.1 == 0 then -- Exhaust player for sprinting local lastPos = players[playerName].lastPos local dist = vector.distance({x=lastPos.x, y=0, z=lastPos.z}, {x=playerPos.x, y=0, z=playerPos.z}) players[playerName].sprintDistance = players[playerName].sprintDistance + dist if players[playerName].sprintDistance >= 1 then local superficial = math.floor(players[playerName].sprintDistance) mcl_hunger.exhaust(playerName, mcl_hunger.EXHAUST_SPRINT * superficial) players[playerName].sprintDistance = players[playerName].sprintDistance - superficial end -- Sprint dirt particles local numParticles = math.random(1, 2) local playerNode = minetest.get_node({x=playerPos["x"], y=playerPos["y"]-1, z=playerPos["z"]}) local def = minetest.registered_nodes[playerNode.name] if def and def.walkable then for i=1, numParticles, 1 do minetest.add_particle({ pos = {x=playerPos["x"]+math.random(-1,1)*math.random()/2,y=playerPos["y"]+0.1,z=playerPos["z"]+math.random(-1,1)*math.random()/2}, velocity = {x=0, y=5, z=0}, acceleration = {x=0, y=-13, z=0}, expirationtime = math.random(), size = math.random()+0.5, collisiondetection = true, vertical = false, texture = "default_dirt.png", }) end end end --Adjust player states players[playerName].lastPos = playerPos if players[playerName]["shouldSprint"] == true then --Stopped local sprinting -- Prevent sprinting if hungry or sleeping if (mcl_hunger.active and mcl_hunger.get_hunger(player) <= 6) or (player:get_meta():get_string("mcl_beds:sleeping") == "true")then sprinting = false else sprinting = true end setSprinting(playerName, sprinting) elseif players[playerName]["shouldSprint"] == false then setSprinting(playerName, false) end end end end)