From ca45eb1c4c0911f38ee5344a930ab0601831c978 Mon Sep 17 00:00:00 2001 From: KaylebJay <44441970+KaylebJay@users.noreply.github.com> Date: Thu, 29 Oct 2020 12:56:50 -0600 Subject: [PATCH] Add mod `real_suffocation` with custom tweaks for CTF (#693) * add mod 'real_suffocation' * tiny nitpick, please squash * remove deprecated description, move to mod.conf * change license * fix luacheck error --- mods/other/real_suffocation/README.md | 24 +++++++++ mods/other/real_suffocation/init.lua | 56 ++++++++++++++++++++ mods/other/real_suffocation/mod.conf | 2 + mods/other/real_suffocation/settingtypes.txt | 4 ++ 4 files changed, 86 insertions(+) create mode 100644 mods/other/real_suffocation/README.md create mode 100644 mods/other/real_suffocation/init.lua create mode 100644 mods/other/real_suffocation/mod.conf create mode 100644 mods/other/real_suffocation/settingtypes.txt diff --git a/mods/other/real_suffocation/README.md b/mods/other/real_suffocation/README.md new file mode 100644 index 0000000..0be0a5c --- /dev/null +++ b/mods/other/real_suffocation/README.md @@ -0,0 +1,24 @@ +# Real Suffocation [`real_suffocation`] +Version: 1.0.0 + +This mod adds suffocation. Suffocation is basically the same as drowning, but it +is for being stuck inside solid blocks. If you're inside a solid block, you lose +breath. If you lost your breath completely and you're still inside, you suffer +10 HP (=5 “hearts”) of damage every 2 seconds. + +Specifically, suffocation is added to all blocks which: + +* Are solid +* Are full cubes +* Don't already have built-in damage or drowning damage +* Are not excluded from suffocations by mods + +## Info for modders +This mod will not add suffocation to all nodes with the group +`disable_suffocation=1`. + +This mod adds the group `real_suffocation=1` to all nodes it has modified, +this is mostly done for informational purposes. + +## License +Everything is under the MIT license. Forked from https://repo.or.cz/minetest_real_suffocation.git. diff --git a/mods/other/real_suffocation/init.lua b/mods/other/real_suffocation/init.lua new file mode 100644 index 0000000..96bb80b --- /dev/null +++ b/mods/other/real_suffocation/init.lua @@ -0,0 +1,56 @@ +-- 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) diff --git a/mods/other/real_suffocation/mod.conf b/mods/other/real_suffocation/mod.conf new file mode 100644 index 0000000..4e148d5 --- /dev/null +++ b/mods/other/real_suffocation/mod.conf @@ -0,0 +1,2 @@ +name = real_suffocation +description = The player will lose breath inside solid blocks. diff --git a/mods/other/real_suffocation/settingtypes.txt b/mods/other/real_suffocation/settingtypes.txt new file mode 100644 index 0000000..5e3d8b7 --- /dev/null +++ b/mods/other/real_suffocation/settingtypes.txt @@ -0,0 +1,4 @@ +# How much damage is caused by “suffocation” by default, that is, running +# out of breath while being inside solid blocks like dirt, gravel, sand, +# etc. Like for drowning, damage is caused every 2 seconds. +real_suffocation_damage (Suffocation damage) int 2 0