minetest-mm/mods/playerplus/init.lua

325 lines
7.8 KiB
Lua
Raw Normal View History

2020-10-26 17:38:53 +01:00
--[[
2024-12-19 12:55:40 +01:00
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, check for node on_walk_over function.
2020-10-26 17:38:53 +01:00
PlayerPlus by TenPlus1
]]
playerplus = {}
-- get node but use fallback for nil or unknown
2024-12-19 12:55:40 +01:00
local node_ok = function(pos, fallback)
2020-10-26 17:38:53 +01:00
local node = minetest.get_node_or_nil(pos)
if node and minetest.registered_nodes[node.name] then
return node.name
end
2024-12-19 12:55:40 +01:00
return fallback or "air"
2020-10-26 17:38:53 +01:00
end
2024-12-19 12:55:40 +01:00
-- mod check and timer set
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
local monoids = minetest.get_modpath("player_monoids")
local pova_mod = minetest.get_modpath("pova")
2020-10-26 17:38:53 +01:00
local armor_mod = minetest.get_modpath("3d_armor")
2024-12-19 12:55:40 +01:00
local timer = 0
local math_min = math.min
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- main function run for each player
2020-10-26 17:38:53 +01:00
minetest.register_globalstep(function(dtime)
2024-12-19 12:55:40 +01:00
-- one second timer
timer = timer + dtime ; if timer < 1 then return end ; timer = 0
2020-10-26 17:38:53 +01:00
-- define locals outside loop
2021-04-10 09:51:05 +02:00
local name, pos, ndef, def, nslow, nfast, prop
2020-10-26 17:38:53 +01:00
-- loop through players
2024-12-19 12:55:40 +01:00
for _,player in pairs(minetest.get_connected_players()) do
2020-10-26 17:38:53 +01:00
-- who am I?
name = player:get_player_name()
2024-12-19 12:55:40 +01:00
if name and playerplus[name] then
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- where am I?
pos = player:get_pos()
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- node standing on
playerplus[name].nod_stand = node_ok(
{x = pos.x, y = pos.y - 0.1, z = pos.z})
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- Does the node below me have an on_walk_over function set?
ndef = minetest.registered_nodes[playerplus[name].nod_stand]
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if ndef and ndef.on_walk_over then
ndef.on_walk_over(pos, ndef, player)
end
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
prop = player:get_properties()
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- node at eye level
playerplus[name].nod_head = node_ok(
{x = pos.x, y = pos.y + prop.eye_height, z = pos.z})
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- node at foot level
playerplus[name].nod_feet = node_ok(
{x = pos.x, y = pos.y + 0.2, z = pos.z})
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- get player physics
def = player:get_physics_override()
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if armor_mod and armor and armor.def then
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- get player physics from armor
def.speed = armor.def[name].speed or def.speed
def.jump = armor.def[name].jump or def.jump
def.gravity = armor.def[name].gravity or def.gravity
end
-- are we standing on any nodes that speed player up?
nfast = nil
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if playerplus[name].nod_stand == "default:ice" then
nfast = true
2020-10-26 17:38:53 +01:00
end
2024-12-19 12:55:40 +01:00
-- are we standing on any nodes that slow player down?
nslow = nil
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if playerplus[name].nod_stand == "default:snow"
or playerplus[name].nod_stand == "default:snowblock" then
nslow = true
2020-10-26 17:38:53 +01:00
end
2024-12-19 12:55:40 +01:00
-- apply speed changes
if nfast and not playerplus[name].nfast then
if pova_mod then
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
pova.add_override(name, "playerplus:nfast", {speed = 0.4})
pova.do_override(player)
elseif monoids then
playerplus[name].nfast = player_monoids.speed:add_change(
player, def.speed + 0.4)
else
def.speed = def.speed + 0.4
end
playerplus[name].nfast = true
elseif not nfast and playerplus[name].nfast then
if pova_mod then
pova.del_override(name, "playerplus:nfast")
pova.do_override(player)
elseif monoids then
player_monoids.speed:del_change(player, playerplus[name].nfast)
playerplus[name].nfast = nil
else
def.speed = def.speed - 0.4
end
playerplus[name].nfast = nil
2020-10-26 17:38:53 +01:00
end
2024-12-19 12:55:40 +01:00
-- apply slowdown changes
if nslow and not playerplus[name].nslow then
if pova_mod then
pova.add_override(name, "playerplus:nslow", {speed = -0.3})
pova.do_override(player)
elseif monoids then
playerplus[name].nslow = player_monoids.speed:add_change(
player, def.speed - 0.3)
else
def.speed = def.speed - 0.3
end
playerplus[name].nslow = true
elseif not nslow and playerplus[name].nslow then
if pova_mod then
pova.del_override(name, "playerplus:nslow")
pova.do_override(player)
elseif monoids then
player_monoids.speed:del_change(player, playerplus[name].nslow)
playerplus[name].nslow = nil
else
def.speed = def.speed + 0.3
end
2020-10-26 17:38:53 +01:00
playerplus[name].nslow = nil
end
2024-12-19 12:55:40 +01:00
-- set player physics
if not monoids and not pova_mod then
2021-05-16 11:33:49 +02:00
2024-12-19 12:55:40 +01:00
player:set_physics_override(
{speed = def.speed, jump = def.jump, gravity = def.gravity})
2020-10-26 17:38:53 +01:00
end
2024-12-19 12:55:40 +01:00
--print ("Speed: " .. def.speed .. " / Jump: " .. def.jump .. " / Gravity: " .. def.gravity)
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- Is player suffocating inside a normal node without no_clip privs?
local ndef = minetest.registered_nodes[playerplus[name].nod_head]
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if 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
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if player:get_hp() > 0 then
player:set_hp(player:get_hp() - 2, {suffocation = true})
2020-10-26 17:38:53 +01:00
end
end
2024-12-19 12:55:40 +01:00
-- am I near a cactus?
local near = minetest.find_node_near(pos, 1, "default:cactus")
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if near and vector.distance(pos, near) < 1.1 then
player:set_hp(player:get_hp() - 2, {cactus = true})
end
end
2020-10-26 17:38:53 +01:00
end
end)
-- check for old sneak_glitch setting
2024-12-19 12:55:40 +01:00
2020-10-26 17:38:53 +01:00
local old_sneak = minetest.settings:get_bool("old_sneak")
2024-12-19 12:55:40 +01:00
-- set to blank on join and apply sneak glitch (for 3rd party mods)
2020-10-26 17:38:53 +01:00
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
2024-12-19 12:55:40 +01:00
playerplus[name] = {nod_head = "", nod_feet = "", nod_stand = ""}
2020-10-26 17:38:53 +01:00
-- 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
2024-12-19 12:55:40 +01:00
minetest.register_on_leaveplayer(function(player)
2020-10-26 17:38:53 +01:00
playerplus[ player:get_player_name() ] = nil
end)
-- add privelage to disable knock-back
2024-12-19 12:55:40 +01:00
minetest.register_privilege("no_knockback", {
description = "Disables player knock-back effect", give_to_singleplayer = false
})
2020-10-26 17:38:53 +01:00
2021-04-10 09:51:05 +02:00
-- player knock-back function
2024-12-19 12:55:40 +01:00
local function punchy(
2021-04-10 09:51:05 +02:00
player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if not dir then return end -- we need to know where to send player away from
local name = player:get_player_name()
-- is player attached to anything (mob, bed, boat etc.)
if player_api.player_attached[name] then return end
2020-10-26 17:38:53 +01:00
2021-04-10 09:51:05 +02:00
-- check if player has 'no_knockback' privelage
2024-12-19 12:55:40 +01:00
local privs = minetest.get_player_privs(name)
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if privs["no_knockback"] then return end
2020-10-26 17:38:53 +01:00
local damage = 0
if tool_capabilities then
local armor = player:get_armor_groups() or {}
local tmp
2024-12-19 12:55:40 +01:00
-- calculate knockback damage
2020-10-26 17:38:53 +01:00
for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do
tmp = time_from_last_punch / (tool_capabilities.full_punch_interval or 1.4)
2024-12-19 12:55:40 +01:00
if tmp < 0 then tmp = 0.0 elseif tmp > 1 then tmp = 1.0 end
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if group ~= "knockback" then
damage = damage + (tool_capabilities.damage_groups[group] or 0) * tmp
end
2020-10-26 17:38:53 +01:00
end
2024-12-19 12:55:40 +01:00
-- if custom value found then use instead
2020-10-26 17:38:53 +01:00
if tool_capabilities.damage_groups["knockback"] then
damage = tool_capabilities.damage_groups["knockback"]
end
end
-- END tool damage
2024-12-19 12:55:40 +01:00
local kb = math_min(32, damage * 2)
2021-07-24 12:22:10 +02:00
2024-12-19 12:55:40 +01:00
--print ("--- knockback", player:get_player_name(), damage, kb)
2020-10-26 17:38:53 +01:00
2021-04-10 09:51:05 +02:00
-- knock back player
2024-12-19 12:55:40 +01:00
player:add_velocity({x = dir.x * kb, y = -1, z = dir.z * kb})
2020-10-26 17:38:53 +01:00
end
2024-12-19 12:55:40 +01:00
-- is player knock-back effect enabled?
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if minetest.settings:get_bool("player_knockback") ~= false then
minetest.register_on_punchplayer(punchy)
end
2020-10-26 17:38:53 +01:00
minetest.register_tool("playerplus:stick", {
2024-12-19 12:55:40 +01:00
description = "Sword of Boing",
inventory_image = "playerplus_sword_boing.png",
wield_image = "playerplus_sword_boing.png",
groups = {not_in_creative_inventory = 1},
2020-10-26 17:38:53 +01:00
tool_capabilities = {
full_punch_interval = 1.4,
2024-12-19 12:55:40 +01:00
damage_groups = {knockback = 11},
groupcaps = {bouncy = {maxlevel = 0}} -- needed so 3d_armor doesnt damage armor
}
2020-10-26 17:38:53 +01:00
})
--[[
minetest.override_item("default:mese", {
on_walk_over = function(pos, node, player)
print ("---", node.name, player:get_player_name() )
end
})
]]
2024-12-19 12:55:40 +01:00
-- add lucky blocks (if damage and stamina active)
if minetest.get_modpath("lucky_block") then
dofile(minetest.get_modpath("playerplus") .. "/lucky_block.lua")
end