From 20576431e183465adb67f405795dbd1d1e49d8a9 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 8 Mar 2019 20:22:01 +0100 Subject: [PATCH] More death messages, more reliable --- mods/ENTITIES/mobs_mc/ender_dragon.lua | 2 +- mods/ENTITIES/mobs_mc/wither.lua | 2 +- mods/HUD/mcl_death_messages/init.lua | 210 ++++++++++++------------- mods/ITEMS/mcl_nether/depends.txt | 2 +- mods/ITEMS/mcl_nether/init.lua | 6 +- mods/ITEMS/mcl_throwing/init.lua | 5 + mods/MISC/mcl_commands/depends.txt | 1 + mods/MISC/mcl_commands/init.lua | 20 ++- mods/PLAYER/mcl_hunger/depends.txt | 2 +- mods/PLAYER/mcl_hunger/hunger.lua | 7 + mods/PLAYER/mcl_hunger/init.lua | 13 +- mods/PLAYER/mcl_playerplus/init.lua | 6 +- 12 files changed, 148 insertions(+), 128 deletions(-) create mode 100644 mods/MISC/mcl_commands/depends.txt diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index 8bcd254164..dd81ab1459 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -124,7 +124,7 @@ mobs:register_arrow("mobs_mc:roar_of_the_dragon2", { for _,obj in ipairs(objects) do local name = self.name if name~="mobs_mc:roar_of_the_dragon2" and name ~= "mobs_mc:enderdragon" then - obj:set_hp(obj:get_hp()-0.05) + obj:set_hp(obj:get_hp()-5) if (obj:get_hp() <= 0) then if (not obj:is_player()) and name ~= self.object:get_luaentity().name then obj:remove() diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index d61237a9d2..a06510a945 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -94,7 +94,7 @@ mobs:register_arrow("mobs_mc:roar_of_the_dragon", { for _,obj in ipairs(objects) do local name = self.name if name~="mobs_mc:roar_of_the_dragon" and name ~= "mobs_mc:wither" then - obj:set_hp(obj:get_hp()-0.05) + obj:set_hp(obj:get_hp()-5) if (obj:get_hp() <= 0) then if (not obj:is_player()) and name ~= self.object:get_luaentity().name then obj:remove() diff --git a/mods/HUD/mcl_death_messages/init.lua b/mods/HUD/mcl_death_messages/init.lua index 302b1a670f..85e51c84c1 100644 --- a/mods/HUD/mcl_death_messages/init.lua +++ b/mods/HUD/mcl_death_messages/init.lua @@ -28,9 +28,6 @@ local msgs = { S("%s drowned."), S("%s ran out of oxygen."), }, - ["starve"] = { - S("%s starved."), - }, ["murder"] = { S("%s was killed by %s."), }, @@ -42,13 +39,13 @@ local msgs = { S("%s was killed by a fireball from a blaze."), }, ["fire_charge"] = { - S("%s was hit by a fire charge."), + S("%s was burned by a fire charge."), }, ["ghast_fireball"] = { S("A ghast scared %s to death."), S("%s has been fireballed by a ghast."), }, - ["fall_damage"] = { + ["fall"] = { S("%s fell from a high cliff."), S("%s took fatal fall damage."), S("%s fell victim to gravity."), @@ -117,132 +114,123 @@ end local last_damages = { } -minetest.register_on_dieplayer(function(player) +minetest.register_on_dieplayer(function(player, reason) -- Death message local message = minetest.settings:get_bool("mcl_showDeathMessages") - if message == nil then message = true end + if message == nil then + message = true + end if message then local name = player:get_player_name() if not name then return end - - local node = minetest.registered_nodes[minetest.get_node(player:get_pos()).name] local msg - -- Lava - if minetest.get_item_group(node.name, "lava") ~= 0 then - msg = dmsg("lava", name) - -- Drowning - elseif player:get_breath() == 0 then - msg = dmsg("drown", name) - -- Fire - elseif minetest.get_item_group(node.name, "fire") ~= 0 then - msg = dmsg("fire", name) - -- Other - else - -- Killed by entity - if last_damages[name] then - -- Mob - if last_damages[name].hittertype == "mob" then - if last_damages[name].hittername then - msg = dmsg("murder", name, last_damages[name].hittername) - else - msg = mmsg(last_damages[name].hittersubtype, name) - end - -- Player - elseif last_damages[name].hittertype == "player" then - if last_damages[name].hittername == name then - -- Workaround when player somehow punches self. Caused by creeper explosions in mobs mod. - -- FIXME: Remove when self-punching is no longer buggy. - msg = dmsg("other", name) - else - msg = dmsg("murder", name, last_damages[name].hittername) - end - -- Arrow - elseif last_damages[name].hittertype == "arrow" then - if last_damages[name].shooter == nil then - msg = dmsg("arrow", name) - elseif last_damages[name].shooter:is_player() then - msg = dmsg("arrow_name", name, last_damages[name].shooter:get_player_name()) - elseif last_damages[name].shooter:get_luaentity()._cmi_is_mob then - if last_damages[name].shooter:get_luaentity().nametag ~= "" then - msg = dmsg("arrow_name", name, last_damages[name].shooter:get_player_name()) - else - msg = dmsg("arrow", name) - end - else - msg = dmsg("arrow", name) - end - -- Fireball - elseif last_damages[name].hittertype == "blaze_fireball" then - msg = dmsg("blaze_fireball", name) - elseif last_damages[name].hittertype == "ghast_fireball" then - msg = dmsg("ghast_fireball", name) - elseif last_damages[name].hittertype == "fire_charge" then - msg = dmsg("fire_charge", name) - -- Custom death message - elseif last_damages[name].custom then - msg = last_damages[name].message + if reason.type == "node_damage" then + local pos = player:get_pos() + -- Check multiple nodes because players occupy multiple nodes + -- (we add one additional node because the check may fail if the player was + -- just barely touching the node with the head) + local posses = { pos, {x=pos.x,y=pos.y+1,z=pos.z}, {x=pos.x,y=pos.y+2,z=pos.z}} + for p=1, #posses do + local node = minetest.registered_nodes[minetest.get_node(posses[p]).name] + -- Lava + if minetest.get_item_group(node.name, "lava") ~= 0 then + msg = dmsg("lava", name) + break + -- Fire + elseif minetest.get_item_group(node.name, "fire") ~= 0 then + msg = dmsg("fire", name) + break end - -- Other reason - else - msg = dmsg("other", name) + end + elseif reason.type == "drown" then + msg = dmsg("drown", name) + elseif reason.type == "punch" then + -- Punches + local hitter = reason.object + local hittername, hittertype, hittersubtype, shooter + -- Unknown hitter + if hitter == nil then + msg = dmsg("murder_any") + -- Player + elseif hitter:is_player() then + hittername = hitter:get_player_name() + if hittername ~= nil then + msg = dmsg("murder", name, hittername) + else + msg = dmsg("murder_any", name) + end + -- Mob (according to Common Mob Interface) + elseif hitter:get_luaentity()._cmi_is_mob then + if hitter:get_luaentity().nametag and hitter:get_luaentity().nametag ~= "" then + hittername = hitter:get_luaentity().nametag + end + hittersubtype = hitter:get_luaentity().name + if hittername then + msg = dmsg("murder", name, hittername) + elseif hittersubtype ~= nil and hittersubtype ~= "" then + msg = mmsg(hittersubtype, name) + else + msg = dmsg("murder_any", name) + end + -- Arrow + elseif hitter:get_luaentity().name == "mcl_bows:arrow_entity" or hitter:get_luaentity().name == "mobs_mc:arrow_entity" then + local shooter + if hitter:get_luaentity()._shooter then + shooter = hitter:get_luaentity()._shooter + end + if shooter == nil then + msg = dmsg("arrow", name) + elseif shooter:is_player() then + msg = dmsg("arrow_name", name, shooter:get_player_name()) + elseif shooter:get_luaentity()._cmi_is_mob then + if shooter:get_luaentity().nametag ~= "" then + msg = dmsg("arrow_name", name, shooter:get_player_name()) + else + msg = dmsg("arrow", name) + end + else + msg = dmsg("arrow", name) + end + -- Blaze fireball + elseif hitter:get_luaentity().name == "mobs_mc:blaze_fireball" then + if hitter:get_luaentity()._shot_from_dispenser then + msg = dmsg("fire_charge", name) + else + msg = dmsg("blaze_fireball", name) + end + -- Ghast fireball + elseif hitter:get_luaentity().name == "mobs_monster:fireball" then + msg = dmsg("ghast_fireball", name) + end + -- Falling + elseif reason.type == "fall" then + msg = dmsg("fall", name) + -- Other + elseif reason.type == "set_hp" then + if last_damages[name] and last_damages[name].custom then + msg = last_damages[name].message end end - if msg then - minetest.chat_send_all(msg) + if not msg then + msg = dmsg("other", name) end + minetest.chat_send_all(msg) end end) local start_damage_reset_countdown = function (player) minetest.after(1, function(playername) - last_damages[playername] = nil + -- FIXME: Fix race condition with many damages in quick succession + if last_damages[playername] and last_damages[playername].custom then + last_damages[playername] = nil + end end, player:get_player_name()) end -minetest.register_on_punchplayer(function(player, hitter) - if not player or not player:is_player() or not hitter then - return - end - local msg - local hittername, hittertype, hittersubtype, shooter - -- Player - if hitter:is_player() then - hittername = hitter:get_player_name() - hittertype = "player" - -- Mob (according to Common Mob Interface) - elseif hitter:get_luaentity()._cmi_is_mob then - if hitter:get_luaentity().nametag and hitter:get_luaentity().nametag ~= "" then - hittername = hitter:get_luaentity().nametag - end - hittertype = "mob" - hittersubtype = hitter:get_luaentity().name - -- Arrow - elseif hitter:get_luaentity().name == "mcl_bows:arrow_entity" or hitter:get_luaentity().name == "mobs_mc:arrow_entity" then - hittertype = "arrow" - if hitter:get_luaentity()._shooter then - shooter = hitter:get_luaentity()._shooter - end - -- Blaze fireball - elseif hitter:get_luaentity().name == "mobs_mc:blaze_fireball" then - if hitter:get_luaentity()._shot_from_dispenser then - hittertype = "fire_charge" - else - hittertype = "blaze_fireball" - end - -- Ghast fireball - elseif hitter:get_luaentity().name == "mobs_monster:fireball" then - hittertype = "ghast_fireball" - else - return - end - - last_damages[player:get_player_name()] = { shooter = shooter, hittername = hittername, hittertype = hittertype, hittersubtype = hittersubtype } - start_damage_reset_countdown(player) -end) - --- To be called BEFORE damaging a player. If the player died, then message will be used as the death message. +-- To be called BEFORE damaging a player via set_hp. The next time the player dies due to a set_hp, +-- the message will be shown. This must happen within one second, otherwise it won't work. function mcl_death_messages.player_damage(player, message) last_damages[player:get_player_name()] = { custom = true, message = message } start_damage_reset_countdown(player) diff --git a/mods/ITEMS/mcl_nether/depends.txt b/mods/ITEMS/mcl_nether/depends.txt index 23488aae08..273e76e1da 100644 --- a/mods/ITEMS/mcl_nether/depends.txt +++ b/mods/ITEMS/mcl_nether/depends.txt @@ -2,6 +2,6 @@ mcl_core mcl_sounds mcl_util walkover -mcl_death_messages +mcl_death_messages? doc_items doc? diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index ee158945f6..15d5f9318f 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -1,5 +1,7 @@ local S = minetest.get_translator("mcl_nether") +local mod_death_messages = minetest.get_modpath("mcl_death_messages") + minetest.register_node("mcl_nether:glowstone", { description = S("Glowstone"), _doc_items_longdesc = S("Glowstone is a naturally-glowing block which is home to the Nether."), @@ -91,7 +93,9 @@ minetest.register_node("mcl_nether:magma", { on_walk_over = function(loc, nodeiamon, player) -- Hurt players standing on top of this block if player:get_hp() > 0 then - mcl_death_messages.player_damage(player, string.format("%s stood too long on a magma block.", player:get_player_name())) + if mod_death_messages then + mcl_death_messages.player_damage(player, string.format("%s stood too long on a magma block.", player:get_player_name())) + end player:set_hp(player:get_hp() - 1) end end, diff --git a/mods/ITEMS/mcl_throwing/init.lua b/mods/ITEMS/mcl_throwing/init.lua index 93e06ff053..8d3915c3a3 100644 --- a/mods/ITEMS/mcl_throwing/init.lua +++ b/mods/ITEMS/mcl_throwing/init.lua @@ -1,6 +1,7 @@ mcl_throwing = {} local S = minetest.get_translator("mcl_throwing") +local mod_death_messages = minetest.get_modpath("mcl_death_messages") -- -- Snowballs and other throwable items @@ -267,6 +268,10 @@ local pearl_on_step = function(self, dtime) local oldpos = player:get_pos() -- Teleport and hurt player player:set_pos(telepos) + if mod_death_messages then + mcl_death_messages.player_damage(player, S("@1 used the ender pearl too often.", player:get_player_name())) + end + -- TODO: Deal as fall damage player:set_hp(player:get_hp() - 5) -- 5% chance to spawn endermite at the player's origin diff --git a/mods/MISC/mcl_commands/depends.txt b/mods/MISC/mcl_commands/depends.txt new file mode 100644 index 0000000000..6e14ff1305 --- /dev/null +++ b/mods/MISC/mcl_commands/depends.txt @@ -0,0 +1 @@ +mcl_death_messages? diff --git a/mods/MISC/mcl_commands/init.lua b/mods/MISC/mcl_commands/init.lua index 50dd052648..1444abd737 100644 --- a/mods/MISC/mcl_commands/init.lua +++ b/mods/MISC/mcl_commands/init.lua @@ -2,6 +2,8 @@ local minecraftaliases = true local S = minetest.get_translator("mcl_commands") +local mod_death_messages = minetest.get_modpath("mcl_death_messages") + local function handle_kill_command(suspect, victim) if minetest.settings:get_bool("enable_damage") == false then return false, S("Players can't be killed right now, damage has been disabled.") @@ -16,17 +18,29 @@ local function handle_kill_command(suspect, victim) return false, S("@1 is already dead", victim) end end - if not suspect == victim then - minetest.log("action", S("@1 killed @2", suspect, victim)) - end -- If player holds a totem of undying, destroy it before killing, -- so it doesn't rescue the player. local wield = victimref:get_wielded_item() if wield:get_name() == "mobs_mc:totem" then victimref:set_wielded_item("") end + if mod_death_messages then + local msg + if suspect == victim then + msg = S("@1 committed suicide.", victim) + else + msg = S("@1 was killed by @2.", victim, suspect) + end + mcl_death_messages.player_damage(victimref, msg) + end -- DIE! victimref:set_hp(0) + -- Log + if not suspect == victim then + minetest.log("action", string.format("%s killed %s using /kill", suspect, victim)) + else + minetest.log("action", string.format("%s committed suicide using /kill", victim)) + end return true end diff --git a/mods/PLAYER/mcl_hunger/depends.txt b/mods/PLAYER/mcl_hunger/depends.txt index db4d6ccbab..ed8cc42366 100644 --- a/mods/PLAYER/mcl_hunger/depends.txt +++ b/mods/PLAYER/mcl_hunger/depends.txt @@ -1,2 +1,2 @@ hudbars -intllib? +mcl_death_messages? diff --git a/mods/PLAYER/mcl_hunger/hunger.lua b/mods/PLAYER/mcl_hunger/hunger.lua index 939aeed97a..d37d051423 100644 --- a/mods/PLAYER/mcl_hunger/hunger.lua +++ b/mods/PLAYER/mcl_hunger/hunger.lua @@ -1,3 +1,6 @@ +local S = minetest.get_translator("mcl_hunger") +local mod_death_messages = minetest.get_modpath("mcl_death_messages") + -- wrapper for minetest.item_eat (this way we make sure other mods can't break this one) local org_eat = minetest.do_item_eat minetest.do_item_eat = function(hp_change, replace_with_item, itemstack, user, pointed_thing) @@ -110,7 +113,11 @@ local function poisonp(tick, time, time_left, damage, exhaustion, name) end -- Deal damage and exhaust player + -- TODO: Introduce fatal poison at higher difficulties if player:get_hp()-damage > 0 then + if mod_death_messages then + mcl_death_messages.player_damage(player, S("@1 succumbed to the poison."), name) + end player:set_hp(player:get_hp()-damage) end diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 5df787e7df..87812b8d0a 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -1,10 +1,5 @@ -local S -if (minetest.get_modpath("intllib")) then - S = intllib.Getter() -else - S = function ( s ) return s end -end - +local S = minetest.get_translator("mcl_hunger") +local mod_death_messages = minetest.get_modpath("mcl_death_messages") mcl_hunger = {} @@ -172,7 +167,11 @@ minetest.register_globalstep(function(dtime) mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) elseif h == 0 then -- Damage hungry player down to 1 HP + -- TODO: Allow starvation at higher difficulty levels if hp-1 > 0 then + if mod_death_messages then + mcl_death_messages.player_damage(player, S("@1 starved to death."), name) + end player:set_hp(hp-1) end end diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index ea232129c7..c3315f42cd 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -1,3 +1,5 @@ +local S = minetest.get_translator("mcl_playerplus") + -- Internal player state local mcl_playerplus_internal = {} @@ -118,7 +120,7 @@ minetest.register_globalstep(function(dtime) -- Check privilege, too and (not minetest.check_player_privs(name, {noclip = true})) then if player:get_hp() > 0 then - mcl_death_messages.player_damage(player, string.format("%s suffocated to death.", name)) + mcl_death_messages.player_damage(player, S("@1 suffocated to death.", name)) player:set_hp(player:get_hp() - 1) end end @@ -134,7 +136,7 @@ minetest.register_globalstep(function(dtime) local dist_feet = vector.distance({x=pos.x, y=pos.y-1, z=pos.z}, near) if dist < 1.1 or dist_feet < 1.1 then if player:get_hp() > 0 then - mcl_death_messages.player_damage(player, string.format("%s was prickled by a cactus.", name)) + mcl_death_messages.player_damage(player, S("@1 was prickled to death by a cactus.", name)) player:set_hp(player:get_hp() - 1) end end