Rework melee damage (#878)

This commit is contained in:
savilli 2021-09-03 17:22:20 +03:00 committed by GitHub
parent f06eca30f0
commit 84dc7da461
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 45 additions and 66 deletions

View file

@ -450,6 +450,10 @@ function ctf.can_attack(player, hitter, time_from_last_punch, tool_capabilities,
return true return true
end end
function ctf.get_damage_modifier(player, tool_capabilities)
return 0
end
ctf.registered_on_attack = {} ctf.registered_on_attack = {}
function ctf.register_on_attack(func) function ctf.register_on_attack(func)
if ctf._mt_loaded then if ctf._mt_loaded then
@ -458,15 +462,8 @@ function ctf.register_on_attack(func)
table.insert(ctf.registered_on_attack, func) table.insert(ctf.registered_on_attack, func)
end end
local dead_players = {}
minetest.register_on_respawnplayer(function(player)
dead_players[player:get_player_name()] = nil
end)
minetest.register_on_joinplayer(function(player)
dead_players[player:get_player_name()] = nil
end)
minetest.register_on_punchplayer(function(player, hitter, minetest.register_on_punchplayer(function(player, hitter,
time_from_last_punch, tool_capabilities, dir, damage, ...) time_from_last_punch, tool_capabilities, dir, orig_damage, ...)
if player and hitter then if player and hitter then
local pname = player:get_player_name() local pname = player:get_player_name()
local hname = hitter:get_player_name() local hname = hitter:get_player_name()
@ -474,10 +471,6 @@ minetest.register_on_punchplayer(function(player, hitter,
local to = ctf.player(pname) local to = ctf.player(pname)
local from = ctf.player(hname) local from = ctf.player(hname)
if dead_players[pname] then
return
end
if to.team == from.team and to.team ~= "" and if to.team == from.team and to.team ~= "" and
to.team ~= nil and to.name ~= from.name then to.team ~= nil and to.name ~= from.name then
hud_event.new(hname, { hud_event.new(hname, {
@ -491,31 +484,38 @@ minetest.register_on_punchplayer(function(player, hitter,
end end
if ctf.can_attack(player, hitter, time_from_last_punch, tool_capabilities, if ctf.can_attack(player, hitter, time_from_last_punch, tool_capabilities,
dir, damage, ...) == false dir, orig_damage, ...) == false
then then
return true return true
end end
local hp = player:get_hp() local hp = player:get_hp()
if hp == 0 then if hp <= 0 then
return false return true
end end
if hp - damage <= 0 then if tool_capabilities and tool_capabilities.damage_groups and tool_capabilities.damage_groups.fleshy then
dead_players[pname] = true local modifier = ctf.get_damage_modifier(hitter, tool_capabilities)
local wielded = hitter:get_wielded_item() tool_capabilities.damage_groups.fleshy = math.max(1, tool_capabilities.damage_groups.fleshy + modifier)
for i = 1, #ctf.registered_on_killedplayer do
ctf.registered_on_killedplayer[i](pname, hname,
wielded, tool_capabilities)
end
return false
end end
local damage = minetest.get_hit_params(player:get_armor_groups(), tool_capabilities, time_from_last_punch).hp
damage = math.min(damage, hp)
for i = 1, #ctf.registered_on_attack do for i = 1, #ctf.registered_on_attack do
ctf.registered_on_attack[i]( ctf.registered_on_attack[i](
player, hitter, time_from_last_punch, player, hitter, time_from_last_punch,
tool_capabilities, dir, damage, ... tool_capabilities, dir, damage, ...
) )
end end
if hp <= damage then
for i = 1, #ctf.registered_on_killedplayer do
ctf.registered_on_killedplayer[i](pname, hname, tool_capabilities)
end
end
player:set_hp(hp - damage)
return true
end end
end) end)

View file

@ -8,7 +8,7 @@ ctf_classes.register("knight", {
properties = { properties = {
max_hp = 30, max_hp = 30,
speed = 0.90, speed = 0.90,
melee_bonus = 1, sword_modifier = 1,
initial_stuff = { initial_stuff = {
"ctf_classes:sword_bronze", "ctf_classes:sword_bronze",

View file

@ -69,3 +69,16 @@ ctf_classes.register_on_changed(function(player, old, new)
ctf.chat_send_team(ctf.player(pname).team, ctf.chat_send_team(ctf.player(pname).team,
minetest.colorize("#ABCDEF", pname .. " is now a " .. new.description)) minetest.colorize("#ABCDEF", pname .. " is now a " .. new.description))
end) end)
local old_get_damage_modifier = ctf.get_damage_modifier
function ctf.get_damage_modifier(player, tool_capabilities)
local modifier = 0
if tool_capabilities.damage_groups.sword then
local class = ctf_classes.get(player)
if class.properties.sword_modifier then
modifier = class.properties.sword_modifier
end
end
return modifier + old_get_damage_modifier(player, tool_capabilities)
end

View file

@ -1,33 +1,3 @@
minetest.register_on_player_hpchange(function(player, hp_change, reason)
if reason.type ~= "punch" or not reason.object or not reason.object:is_player() then
return hp_change
end
local class = ctf_classes.get(reason.object)
if class.properties.melee_bonus and reason.object:get_wielded_item():get_name():find("sword") then
local change = hp_change - class.properties.melee_bonus
if player:get_hp() + change <= 0 and player:get_hp() + hp_change > 0 then
local wielded_item = reason.object:get_wielded_item()
for i = 1, #ctf.registered_on_killedplayer do
ctf.registered_on_killedplayer[i](
player:get_player_name(),
reason.object:get_player_name(),
wielded_item,
wielded_item:get_tool_capabilities()
)
end
end
return change
end
return hp_change
end, true)
local sword_special_timer = {} local sword_special_timer = {}
local SWORD_SPECIAL_COOLDOWN = 20 local SWORD_SPECIAL_COOLDOWN = 20
local function sword_special_timer_func(pname, timeleft) local function sword_special_timer_func(pname, timeleft)
@ -68,7 +38,6 @@ minetest.register_tool("ctf_classes:sword_bronze", {
end end
local pteam = ctf.player(pname).team local pteam = ctf.player(pname).team
if not pteam then -- can be nil during map change if not pteam then -- can be nil during map change
return return
end end

View file

@ -120,7 +120,7 @@ function ctf_events.update_all()
end end
end end
ctf.register_on_killedplayer(function(victim, killer, stack, tool_caps) ctf.register_on_killedplayer(function(victim, killer, tool_caps)
local victim_color = ctf_colors.get_color(ctf.player(victim)) local victim_color = ctf_colors.get_color(ctf.player(victim))
local killer_color = ctf_colors.get_color(ctf.player(killer)) local killer_color = ctf_colors.get_color(ctf.player(killer))

View file

@ -15,7 +15,7 @@ end
-- Kills -- Kills
-- --
local kill_counter = counter("ctf_kills", "Total kills") local kill_counter = counter("ctf_kills", "Total kills")
ctf.register_on_killedplayer(function(victim, killer, type) ctf.register_on_killedplayer(function(victim, killer)
kill_counter:increment() kill_counter:increment()
end) end)

View file

@ -38,12 +38,11 @@ ctf.register_on_attack(function(player, hitter,
potential_cowards[pname].timer = 0 potential_cowards[pname].timer = 0
potential_cowards[pname].puncher = hname potential_cowards[pname].puncher = hname
potential_cowards[pname].wielded_item = hitter:get_wielded_item()
potential_cowards[pname].toolcaps = tool_capabilities potential_cowards[pname].toolcaps = tool_capabilities
end end
end) end)
ctf.register_on_killedplayer(function(victim, killer, _, toolcaps) ctf.register_on_killedplayer(function(victim, killer, toolcaps)
if toolcaps.damage_groups.combat_log or toolcaps.damage_groups.suicide then if toolcaps.damage_groups.combat_log or toolcaps.damage_groups.suicide then
return return
end end
@ -72,7 +71,6 @@ function handle_leave_or_die(pname, leave)
ctf.registered_on_killedplayer[i]( ctf.registered_on_killedplayer[i](
pname, pname,
hname, hname,
potential_cowards[pname].wielded_item,
potential_cowards[pname].toolcaps potential_cowards[pname].toolcaps
) )
end end

View file

@ -69,7 +69,7 @@ function kill_assist.reward_assists(victim, killer, reward)
kill_assist.clear_assists(victim) kill_assist.clear_assists(victim)
end end
ctf.register_on_killedplayer(function(victim, killer, _, toolcaps) ctf.register_on_killedplayer(function(victim, killer, toolcaps)
local reward = ctf_stats.calculateKillReward(victim, killer, toolcaps) local reward = ctf_stats.calculateKillReward(victim, killer, toolcaps)
reward = math.floor(reward * 100) / 100 reward = math.floor(reward * 100) / 100
kill_assist.reward_assists(victim, killer, reward) kill_assist.reward_assists(victim, killer, reward)

View file

@ -133,22 +133,21 @@ end)
-- If player takes damage while healing, -- If player takes damage while healing,
-- stop regen and revert back to original state -- stop regen and revert back to original state
minetest.register_on_player_hpchange(function(player, hp, reason) minetest.register_on_player_hpchange(function(player, hp_change, reason)
local name = player:get_player_name() local name = player:get_player_name()
if hp < 0 then if hp_change < 0 then
if players[name] then if players[name] then
player:hud_remove(players[name].hud) player:hud_remove(players[name].hud)
players[name] = nil -- Don't use stop_healing(), it uses set_hp() and won't allocate deaths or score properly players[name] = nil -- Don't use stop_healing(), it uses set_hp() and won't allocate deaths or score properly
end end
if reason and reason.type == "punch" then if reason.type == "punch" then
local hitter = reason.object local hitter = reason.object
if hitter and players[hitter:get_player_name()] then if hitter and players[hitter:get_player_name()] then
stop_healing(hitter, "attack") stop_healing(hitter, "attack")
end end
end end
end end
return hp end)
end, true)
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
players[player:get_player_name()] = nil players[player:get_player_name()] = nil