123 lines
4.8 KiB
Lua
123 lines
4.8 KiB
Lua
--local bc = better_commands
|
|
|
|
---Deals damage; copied from Mineclonia's mcl_util.deal_damage
|
|
---@param target minetest.ObjectRef
|
|
---@param damage integer
|
|
---@param reason table?
|
|
---@param damage_immortal? boolean
|
|
function better_commands.deal_damage(target, damage, reason, damage_immortal)
|
|
local luaentity = target:get_luaentity()
|
|
|
|
if luaentity then
|
|
if luaentity.deal_damage then -- Mobs Redo/Mobs MC
|
|
luaentity:deal_damage(damage, reason or {type = "generic"})
|
|
minetest.log("deal_damage")
|
|
return
|
|
elseif luaentity.hurt then -- Animalia
|
|
luaentity:hurt(damage)
|
|
minetest.log("hurt")
|
|
luaentity:indicate_damage()
|
|
return
|
|
elseif luaentity.health then -- Mobs Redo/Mobs MC/NSSM
|
|
-- local puncher = mcl_reason and mcl_reason.direct or target
|
|
-- target:punch(puncher, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = damage}}, vector.direction(puncher:get_pos(), target:get_pos()), damage)
|
|
if luaentity.health > 0 then
|
|
minetest.log("luaentity.health")
|
|
luaentity.health = luaentity.health - damage
|
|
end
|
|
return
|
|
end
|
|
end
|
|
|
|
local hp = target:get_hp()
|
|
local armorgroups = target:get_armor_groups()
|
|
|
|
if hp > 0 and armorgroups and (damage_immortal or not armorgroups.immortal) then
|
|
minetest.log("set_hp")
|
|
target:set_hp(hp - damage, reason)
|
|
end
|
|
end
|
|
|
|
minetest.register_on_dieplayer(function(player, reason)
|
|
local player_name = player:get_player_name()
|
|
for _, def in pairs(better_commands.scoreboard.objectives) do
|
|
if def.criterion == "deathCount" then
|
|
if def.scores[player_name] then
|
|
def.scores[player_name].score = def.scores[player_name].score + 1
|
|
end
|
|
end
|
|
end
|
|
local killer
|
|
if reason._mcl_reason then
|
|
killer = reason._mcl_reason.source
|
|
else
|
|
killer = reason.object
|
|
end
|
|
if killer and killer:is_player() then
|
|
local player_name = player:get_player_name()
|
|
local killer_name = killer:get_player_name()
|
|
local player_team = better_commands.teams.players[player_name]
|
|
local killer_team = better_commands.teams.players[killer_name]
|
|
for _, def in pairs(better_commands.scoreboard.objectives) do
|
|
if def.criterion == "playerKillCount" or (player_team and def.criterion == "teamkill."..player_team) then
|
|
if def.scores[killer_name] then
|
|
def.scores[killer_name].score = def.scores[killer_name].score + 1
|
|
end
|
|
elseif killer_team and def.criterion == "killedByTeam."..killer_team then
|
|
if def.scores[player_name] then
|
|
def.scores[player_name].score = def.scores[player_name].score + 1
|
|
end
|
|
elseif def.criterion == "killed_by.player" then
|
|
if def.scores[player_name] then
|
|
def.scores[player_name].score = def.scores[player_name].score + 1
|
|
end
|
|
end
|
|
end
|
|
elseif killer then
|
|
local killer_type = killer:get_luaentity().name
|
|
for _, def in pairs(better_commands.scoreboard.objectives) do
|
|
local killed_by = def.criterion:match("^killed_by%.(.*)$")
|
|
if killed_by and (killer_type == killed_by or
|
|
(better_commands.entity_aliases[killer_type] and better_commands.entity_aliases[killer_type][killed_by])) then
|
|
if def.scores[player_name] then
|
|
def.scores[player_name].score = def.scores[player_name].score + 1
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- Make sure players always die when /killed, also track hp
|
|
minetest.register_on_player_hpchange(function(player, hp_change, reason)
|
|
if reason.better_commands == "kill" then
|
|
return -player:get_properties().hp_max, true
|
|
end
|
|
local player_name = player:get_player_name()
|
|
for _, def in pairs(better_commands.scoreboard.objectives) do
|
|
if def.criterion == "health" then
|
|
if def.scores[player_name] then
|
|
minetest.after(0, function() def.scores[player_name].score = player:get_hp() end)
|
|
end
|
|
end
|
|
end
|
|
if hp_change < 0 then
|
|
local attacker
|
|
if reason._mcl_reason then
|
|
attacker = reason._mcl_reason.source
|
|
else
|
|
attacker = reason.object
|
|
end
|
|
if attacker and attacker:is_player() then
|
|
local player_name = player:get_player_name()
|
|
local attacker_name = attacker:get_player_name()
|
|
local player_team = better_commands.teams.players[player_name]
|
|
local attacker_team = better_commands.teams.players[attacker_name]
|
|
if player_team == attacker_team then
|
|
if better_commands.teams.teams[player_team].pvp == false then
|
|
return 0, true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return hp_change
|
|
end, true) |