capturetheflag/mods/other/real_suffocation/init.lua

57 lines
2.7 KiB
Lua
Raw Normal View History

-- Load setting
local suffocation_damage = 2
local setting = minetest.settings:get("real_suffocation_damage")
if tonumber(setting) ~= nil then
suffocation_damage = tonumber(setting)
end
-- Skip the rest if suffocation damage is 0, no point in overwriting stuff
if suffocation_damage > 0 then
-- Checks all nodes and adds suffocation (drowning damage) for suitable nodes
local function add_suffocation()
-- For debugging output
local suffocate_nodes = {}
local no_suffocate_nodes = {}
-- Check ALL the nodes!
for itemstring, def in pairs(minetest.registered_nodes) do
--[[ Here comes the HUGE conditional deciding whether we use suffocation. We want to catch as many nodes as possible
while avoiding bad nodes. We care mostly about physical properties, we don't care about visual appearance.
Here's what it checks and why:
- Walkable: Must be walkable, which means player can get stuck inside. If player can move freely, suffocation does not make sense
- Drowning and damage: If node has set any of those explicitly, it probably knows why. We don't want to mess with it.
- collision_box, node_box: Checks whether we deal with full-sized standard cubes, since only care about those.
Everything else is probably too small for suffocation to seem real.
- disable_suffocation group: If set to 1, we bail out. This makes it possible for nodes to defend themselves against hacking. :-)
]]
if (def.walkable == nil or def.walkable == true)
and (def.drowning == nil or def.drowning == 0)
and (def.damage_per_second == nil or def.damage_per_second <= 0)
and (def.collision_box == nil or def.collision_box.type == "regular")
and (def.node_box == nil or def.node_box.type == "regular")
and (def.groups.disable_suffocation ~= 1)
then
-- Add “real_suffocation” group so other mods know this node was touched by this mod
local marked_groups = def.groups
marked_groups.real_suffocation = 1
-- Let's hack the node!
minetest.override_item(itemstring, { drowning = suffocation_damage, groups = marked_groups })
table.insert(suffocate_nodes, itemstring)
else
table.insert(no_suffocate_nodes, itemstring)
end
end
minetest.log("info", "[real_suffocation] Suffocation has been hacked into "..#suffocate_nodes.." nodes.")
minetest.log("verbose", "[real_suffocation] Nodes with suffocation: "..dump(suffocate_nodes))
minetest.log("verbose", "[real_suffocation] Suffocation has not been hacked into "..#no_suffocate_nodes.." nodes: "..dump(no_suffocate_nodes))
end
-- This is a minor hack to make sure our loop runs after all nodes have been registered
minetest.after(0, add_suffocation)
end
minetest.register_on_joinplayer(function(player)
player:set_properties({max_breath = 10})
end)