diff --git a/.luacheckrc b/.luacheckrc index 4ab1475..6f666c3 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -18,7 +18,7 @@ globals = { "ctf_match", "ctf_stats", "ctf_treasure", "ctf_playertag", "chatplus", "irc", "armor", "vote", "give_initial_stuff", "hud_score", "physics", "tsm_chests", "armor", "shooter", "grenades", "ctf_classes", "ctf_bandages", "ctf_respawn_immunity", - "ctf_marker", + "ctf_marker", "kill_assist" } read_globals = { diff --git a/mods/ctf/ctf/teams.lua b/mods/ctf/ctf/teams.lua index b13d7ea..69afa9c 100644 --- a/mods/ctf/ctf/teams.lua +++ b/mods/ctf/ctf/teams.lua @@ -445,6 +445,15 @@ function ctf.register_on_killedplayer(func) end table.insert(ctf.registered_on_killedplayer, func) end + +ctf.registered_on_punchplayer = {} +function ctf.register_on_punchplayer(func) + if ctf._mt_loaded then + error("You can't register callbacks at game time!") + end + table.insert(ctf.registered_on_punchplayer, func) +end + local dead_players = {} minetest.register_on_respawnplayer(function(player) dead_players[player:get_player_name()] = nil @@ -453,7 +462,7 @@ minetest.register_on_joinplayer(function(player) dead_players[player:get_player_name()] = nil end) minetest.register_on_punchplayer(function(player, hitter, - time_from_last_punch, tool_capabilities, dir, damage) + time_from_last_punch, tool_capabilities, dir, damage, ...) if player and hitter then local pname = player:get_player_name() local hname = hitter:get_player_name() @@ -487,5 +496,12 @@ minetest.register_on_punchplayer(function(player, hitter, end return false end + + for i = 1, #ctf.registered_on_punchplayer do + ctf.registered_on_punchplayer[i]( + player, hitter, time_from_last_punch, + tool_capabilities, dir, damage, ... + ) + end end end) diff --git a/mods/ctf/ctf_bandages/init.lua b/mods/ctf/ctf_bandages/init.lua index a6a4bec..34a72d2 100644 --- a/mods/ctf/ctf_bandages/init.lua +++ b/mods/ctf/ctf_bandages/init.lua @@ -1,7 +1,7 @@ --Inspired from Andrey's bandages mod ctf_bandages = {} -ctf_bandages.heal_percent = 0.75 --Percentage of total HP to be healed +ctf_bandages.heal_percent = 0.75 -- Percentage of total HP to be healed minetest.register_craftitem("ctf_bandages:bandage", { description = "Bandage\n\n" .. @@ -10,26 +10,31 @@ minetest.register_craftitem("ctf_bandages:bandage", { inventory_image = "ctf_bandages_bandage.png", stack_max = 1, on_use = function(itemstack, player, pointed_thing) - if pointed_thing.type ~= "object" then - return - end + if pointed_thing.type ~= "object" then return end + local object = pointed_thing.ref - if not object:is_player() then - return - end + if not object:is_player() then return end + local pname = object:get_player_name() local name = player:get_player_name() + if ctf.player(pname).team == ctf.player(name).team then local hp = object:get_hp() - local limit = ctf_bandages.heal_percent * - object:get_properties().hp_max + local limit = ctf_bandages.heal_percent * object:get_properties().hp_max + if hp > 0 and hp < limit then - hp = hp + math.random(3,4) + local hp_add = math.random(3,4) + + kill_assist.add_heal_assist(pname, hp_add) + hp = hp + hp_add + if hp > limit then hp = limit end + object:set_hp(hp) minetest.chat_send_player(pname, minetest.colorize("#C1FF44", name .. " has healed you!")) + return itemstack else minetest.chat_send_player(name, pname .. " has " .. hp .. " HP. You can't heal them.") diff --git a/mods/ctf/ctf_stats/init.lua b/mods/ctf/ctf_stats/init.lua index 19c4a07..e3ec456 100644 --- a/mods/ctf/ctf_stats/init.lua +++ b/mods/ctf/ctf_stats/init.lua @@ -373,7 +373,7 @@ local function invHasGoodWeapons(inv) return false end -local function calculateKillReward(victim, killer, toolcaps) +function ctf_stats.calculateKillReward(victim, killer, toolcaps) local vmain, victim_match = ctf_stats.player(victim) if not vmain or not victim_match then return 5 end @@ -417,33 +417,9 @@ local function calculateKillReward(victim, killer, toolcaps) return reward end -ctf.register_on_killedplayer(function(victim, killer, _, toolcaps) - -- Suicide is not encouraged here at CTF - if victim == killer then - return - end - local main, match = ctf_stats.player(killer) - if main and match then - local reward = calculateKillReward(victim, killer, toolcaps) - main.kills = main.kills + 1 - main.score = main.score + reward - match.kills = match.kills + 1 - match.score = match.score + reward - match.kills_since_death = match.kills_since_death + 1 - _needs_save = true - - reward = math.floor(reward * 100) / 100 - - hud_score.new(killer, { - name = "ctf_stats:kill_score", - color = "0x00FF00", - value = reward - }) - end -end) - minetest.register_on_dieplayer(function(player) local main, match = ctf_stats.player(player:get_player_name()) + if main and match then main.deaths = main.deaths + 1 match.deaths = match.deaths + 1 diff --git a/mods/pvp/anticoward/init.lua b/mods/pvp/anticoward/init.lua index 1dc70ec..c614e47 100644 --- a/mods/pvp/anticoward/init.lua +++ b/mods/pvp/anticoward/init.lua @@ -156,6 +156,7 @@ minetest.register_globalstep(function(dtime) end potential_cowards[k] = nil + kill_assist.clear_assists(k) end end diff --git a/mods/pvp/anticoward/mod.conf b/mods/pvp/anticoward/mod.conf index a8245cc..743a1ed 100644 --- a/mods/pvp/anticoward/mod.conf +++ b/mods/pvp/anticoward/mod.conf @@ -1,2 +1,2 @@ name = anticoward -depends = ctf, ctf_classes, ctf_match +depends = ctf, ctf_classes, ctf_match, kill_assist diff --git a/mods/pvp/hpregen/init.lua b/mods/pvp/hpregen/init.lua index 3b83e7e..6d2c48a 100644 --- a/mods/pvp/hpregen/init.lua +++ b/mods/pvp/hpregen/init.lua @@ -16,8 +16,10 @@ local function regen_all() local newhp = oldhp + hpregen.amount if newhp > player:get_properties().hp_max then newhp = player:get_properties().hp_max + kill_assist.clear_assists(player:get_player_name()) end if oldhp ~= newhp then + kill_assist.add_heal_assist(player:get_player_name(), hpregen.amount) player:set_hp(newhp) end end diff --git a/mods/pvp/hpregen/mod.conf b/mods/pvp/hpregen/mod.conf index 7fb7317..5ff8c6f 100644 --- a/mods/pvp/hpregen/mod.conf +++ b/mods/pvp/hpregen/mod.conf @@ -1 +1,2 @@ name = hpregen +depends = kill_assist diff --git a/mods/pvp/kill_assist/init.lua b/mods/pvp/kill_assist/init.lua new file mode 100644 index 0000000..166daa0 --- /dev/null +++ b/mods/pvp/kill_assist/init.lua @@ -0,0 +1,95 @@ +kill_assist = {} + +local kill_assists = {} + +function kill_assist.clear_assists(player) + if type(player) == "string" then + kill_assists[player] = nil + else + kill_assists = {} + end +end + +function kill_assist.add_assist(victim, attacker, damage) + if not kill_assists[victim] then + kill_assists[victim] = {} + end + + kill_assists[victim][attacker] = (kill_assists[victim][attacker] or 0) + damage +end + +function kill_assist.add_heal_assist(victim, healed_hp) + if not kill_assists[victim] then return end + + for name, damage in pairs(kill_assists[victim]) do + kill_assists[victim][name] = math.max(damage - healed_hp, 0) + end +end + +function kill_assist.reward_assists(victim, killer, reward) + if not kill_assists[victim] then return end + + for name, damage in pairs(kill_assists[victim]) do + if minetest.get_player_by_name(name) and name ~= victim then + local standard = 0 + local max_hp = minetest.get_player_by_name(victim):get_properties().max_hp or 20 + local help_percent = damage / max_hp + local main, match = ctf_stats.player(name) + local color = "0x00FFFF" + + if name ~= killer then + standard = 0.5 + help_percent = math.min(help_percent, 0.75) + else + help_percent = math.min(help_percent, 1) + end + + if help_percent >= standard then + reward = math.floor((reward * help_percent)*100)/100 + end + + if reward < 1 then + reward = 1 + end + + match.score = match.score + reward + main.score = main.score + reward + + if name == killer then + color = "0x00FF00" + main.kills = main.kills + 1 + match.kills = match.kills + 1 + match.kills_since_death = match.kills_since_death + 1 + end + + hud_score.new(name, { + name = "kill_assist:score", + color = color, + value = reward + }) + end + end + + ctf_stats.request_save() + kill_assist.clear_assists(victim) +end + +ctf.register_on_killedplayer(function(victim, killer, _, toolcaps) + local reward = ctf_stats.calculateKillReward(victim, killer, toolcaps) + reward = math.floor(reward * 100) / 100 + kill_assist.reward_assists(victim, killer, reward) +end) + +ctf.register_on_punchplayer(function(player, hitter, _, _, _, damage) + kill_assist.add_assist(player:get_player_name(), hitter:get_player_name(), damage) +end) + +ctf_match.register_on_new_match(function() + kill_assist.clear_assists() +end) +ctf.register_on_new_game(function() + kill_assist.clear_assists() +end) +minetest.register_on_leaveplayer(function(player) + kill_assist.clear_assists(player) +end) diff --git a/mods/pvp/kill_assist/mod.conf b/mods/pvp/kill_assist/mod.conf new file mode 100644 index 0000000..f6f4bda --- /dev/null +++ b/mods/pvp/kill_assist/mod.conf @@ -0,0 +1,2 @@ +name = kill_assist +depends = ctf, ctf_match, ctf_stats, hud_score diff --git a/mods/pvp/medkits/init.lua b/mods/pvp/medkits/init.lua index a9f6c11..fb25a7f 100644 --- a/mods/pvp/medkits/init.lua +++ b/mods/pvp/medkits/init.lua @@ -117,6 +117,7 @@ minetest.register_globalstep(function(dtime) if pstat then local hp = player:get_hp() if hp < pstat.regen_max then + kill_assist.add_heal_assist(name, regen_step) player:set_hp(math.min(hp + regen_step, pstat.regen_max)) else stop_healing(player)