--[[ walking on ice makes player walk faster, stepping through snow slows player down, touching a cactus hurts player, suffocation when head is inside solid node, player knock-back effects when punched. PlayerPlus by TenPlus1 ]] playerplus = {} -- detect minetest 5.0 local mt50 = minetest.registered_nodes["default:permafrost"] -- get node but use fallback for nil or unknown local node_ok = function(pos, fallback) fallback = fallback or "air" local node = minetest.get_node_or_nil(pos) if node and minetest.registered_nodes[node.name] then return node.name end return fallback end local time = 0 minetest.register_globalstep(function(dtime) time = time + dtime -- every 1 second if time < 1 then return end -- reset time for next check time = 0 -- define locals outside loop local name, pos, ndef, def, nslow, nfast, prop -- get list of players local players = minetest.get_connected_players() -- loop through players for _,player in pairs(players) do -- who am I? name = player:get_player_name() if name and playerplus[name] then -- where am I? pos = player:get_pos() -- what is around me? playerplus[name].nod_stand = node_ok({ x = pos.x, y = pos.y - 0.1, z = pos.z}) -- Does the node below me have an on_walk_over function set? ndef = minetest.registered_nodes[playerplus[name].nod_stand] if ndef and ndef.on_walk_over then ndef.on_walk_over(pos, ndef, player) end prop = player:get_properties() -- node at eye level playerplus[name].nod_head = node_ok({ x = pos.x, y = pos.y + prop.eye_height, z = pos.z}) -- node at foot level playerplus[name].nod_feet = node_ok({ x = pos.x, y = pos.y + 0.2, z = pos.z}) -- are we standing on any nodes that speed player up? nfast = nil if playerplus[name].nod_stand == "default:ice" then nfast = true end -- are we standing on any nodes that slow player down? nslow = nil if playerplus[name].nod_stand == "default:snow" or playerplus[name].nod_stand == "default:snowblock" then nslow = true end -- apply speed changes if nfast and not playerplus[name].nfast then physics.set(name, "playerplus:nfast", {speed = 1.2}) playerplus[name].nfast = true elseif not nfast and playerplus[name].nfast then physics.remove(name, "playerplus:nfast") playerplus[name].nfast = nil end -- apply slowdown changes if nslow and not playerplus[name].nslow then physics.set(name, "playerplus:nslow", {speed = 0.85}) playerplus[name].nslow = true elseif not nslow and playerplus[name].nslow then physics.remove(name, "playerplus:nslow") playerplus[name].nslow = nil end -- Is player suffocating inside a normal node without no_clip privs? local ndef = minetest.registered_nodes[playerplus[name].nod_head] if not ctf_match.is_in_build_time() and ndef.walkable == true and ndef.drowning == 0 and ndef.damage_per_second <= 0 and ndef.groups.disable_suffocation ~= 1 and ndef.drawtype == "normal" and not minetest.check_player_privs(name, {noclip = true}) then if player:get_hp() > 0 then player:set_hp(player:get_hp() - 2) end end -- am I near a cactus? local near = minetest.find_node_near(pos, 1, "default:cactus") if near then -- am I touching the cactus? if so it hurts for _,object in pairs(minetest.get_objects_inside_radius(near, 1.1)) do if object:get_hp() > 0 then object:set_hp(object:get_hp() - 2) end end end end -- END if name end end) -- check for old sneak_glitch setting local old_sneak = minetest.settings:get_bool("old_sneak") -- set to blank on join (for 3rd party mods) minetest.register_on_joinplayer(function(player) local name = player:get_player_name() playerplus[name] = {} playerplus[name].nod_head = "" playerplus[name].nod_feet = "" playerplus[name].nod_stand = "" -- apply old sneak glitch if enabled if old_sneak then player:set_physics_override({new_move = false, sneak_glitch = true}) end end) -- clear when player leaves minetest.register_on_leaveplayer(function(player) playerplus[ player:get_player_name() ] = nil end) -- add privelage to disable knock-back minetest.register_privilege("no_knockback", { description = "Disables player knock-back effect", give_to_singleplayer = false}) -- is player knock-back effect enabled? if minetest.settings:get_bool("player_knockback") == true then -- player knock-back function local punchy = function( player, hitter, time_from_last_punch, tool_capabilities, dir, damage) -- disable knockback during build time if ctf_match.is_in_build_time() then return end -- check if player and hitter are in the same team if ctf.player(player:get_player_name()).team == ctf.player(hitter:get_player_name()).team then return end if not dir then return end -- check if player has 'no_knockback' privelage local privs = minetest.get_player_privs(player:get_player_name()) if privs["no_knockback"] then return end local damage = 0 -- get tool damage if tool_capabilities then local armor = player:get_armor_groups() or {} local tmp for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do tmp = time_from_last_punch / (tool_capabilities.full_punch_interval or 1.4) if tmp < 0 then tmp = 0.0 elseif tmp > 1 then tmp = 1.0 end damage = damage + (tool_capabilities.damage_groups[group] or 0) * tmp -- limit knockback if damage > 8 then damage = 8 end end -- disable knockback for swords if tool_capabilities.damage_groups["sword"] then damage = 0 end -- check for knockback value if tool_capabilities.damage_groups["knockback"] then damage = tool_capabilities.damage_groups["knockback"] end end -- END tool damage -- print ("---", player:get_player_name(), damage) -- knock back player player:add_velocity({ x = dir.x * (damage * 2), y = -1, z = dir.z * (damage * 2) }) end minetest.register_on_punchplayer(punchy) end -- END if minetest.register_tool("playerplus:stick", { description = "KB Stick", inventory_image = "default_stick.png", wield_image = "default_stick.png", tool_capabilities = { full_punch_interval = 1.4, damage_groups = {fleshy = 0, knockback = 11}, }, }) --[[ minetest.override_item("default:mese", { on_walk_over = function(pos, node, player) print ("---", node.name, player:get_player_name() ) end }) ]]