This commit is contained in:
philipmi 2021-02-09 08:11:16 +01:00
commit 63d2b14d37
11 changed files with 151 additions and 40 deletions

View file

@ -18,7 +18,7 @@ globals = {
"ctf_match", "ctf_stats", "ctf_treasure", "ctf_playertag", "chatplus", "irc", "ctf_match", "ctf_stats", "ctf_treasure", "ctf_playertag", "chatplus", "irc",
"armor", "vote", "give_initial_stuff", "hud_score", "physics", "tsm_chests", "armor", "vote", "give_initial_stuff", "hud_score", "physics", "tsm_chests",
"armor", "shooter", "grenades", "ctf_classes", "ctf_bandages", "ctf_respawn_immunity", "armor", "shooter", "grenades", "ctf_classes", "ctf_bandages", "ctf_respawn_immunity",
"ctf_marker", "ctf_marker", "kill_assist"
} }
read_globals = { read_globals = {

View file

@ -445,6 +445,15 @@ function ctf.register_on_killedplayer(func)
end end
table.insert(ctf.registered_on_killedplayer, func) table.insert(ctf.registered_on_killedplayer, func)
end 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 = {} local dead_players = {}
minetest.register_on_respawnplayer(function(player) minetest.register_on_respawnplayer(function(player)
dead_players[player:get_player_name()] = nil dead_players[player:get_player_name()] = nil
@ -453,7 +462,7 @@ minetest.register_on_joinplayer(function(player)
dead_players[player:get_player_name()] = nil dead_players[player:get_player_name()] = nil
end) 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, 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()
@ -487,5 +496,12 @@ minetest.register_on_punchplayer(function(player, hitter,
end end
return false return false
end 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
end) end)

View file

@ -10,26 +10,31 @@ minetest.register_craftitem("ctf_bandages:bandage", {
inventory_image = "ctf_bandages_bandage.png", inventory_image = "ctf_bandages_bandage.png",
stack_max = 1, stack_max = 1,
on_use = function(itemstack, player, pointed_thing) on_use = function(itemstack, player, pointed_thing)
if pointed_thing.type ~= "object" then if pointed_thing.type ~= "object" then return end
return
end
local object = pointed_thing.ref local object = pointed_thing.ref
if not object:is_player() then if not object:is_player() then return end
return
end
local pname = object:get_player_name() local pname = object:get_player_name()
local name = player:get_player_name() local name = player:get_player_name()
if ctf.player(pname).team == ctf.player(name).team then if ctf.player(pname).team == ctf.player(name).team then
local hp = object:get_hp() local hp = object:get_hp()
local limit = ctf_bandages.heal_percent * local limit = ctf_bandages.heal_percent * object:get_properties().hp_max
object:get_properties().hp_max
if hp > 0 and hp < limit then 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 if hp > limit then
hp = limit hp = limit
end end
object:set_hp(hp) object:set_hp(hp)
minetest.chat_send_player(pname, minetest.colorize("#C1FF44", name .. " has healed you!")) minetest.chat_send_player(pname, minetest.colorize("#C1FF44", name .. " has healed you!"))
return itemstack return itemstack
else else
minetest.chat_send_player(name, pname .. " has " .. hp .. " HP. You can't heal them.") minetest.chat_send_player(name, pname .. " has " .. hp .. " HP. You can't heal them.")

View file

@ -373,7 +373,7 @@ local function invHasGoodWeapons(inv)
return false return false
end end
local function calculateKillReward(victim, killer, toolcaps) function ctf_stats.calculateKillReward(victim, killer, toolcaps)
local vmain, victim_match = ctf_stats.player(victim) local vmain, victim_match = ctf_stats.player(victim)
if not vmain or not victim_match then return 5 end if not vmain or not victim_match then return 5 end
@ -417,33 +417,9 @@ local function calculateKillReward(victim, killer, toolcaps)
return reward return reward
end 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) minetest.register_on_dieplayer(function(player)
local main, match = ctf_stats.player(player:get_player_name()) local main, match = ctf_stats.player(player:get_player_name())
if main and match then if main and match then
main.deaths = main.deaths + 1 main.deaths = main.deaths + 1
match.deaths = match.deaths + 1 match.deaths = match.deaths + 1

View file

@ -3,6 +3,7 @@
potential_cowards = {} potential_cowards = {}
local TIMER_UPDATE_INTERVAL = 2 local TIMER_UPDATE_INTERVAL = 2
local COMBAT_TIMEOUT_TIME = 20 local COMBAT_TIMEOUT_TIME = 20
local COMBATLOG_SCORE_PENALTY = 10
-- --
--- Make suicides and combat logs award last puncher with kill --- Make suicides and combat logs award last puncher with kill
@ -136,6 +137,17 @@ minetest.register_on_leaveplayer(function(player, timeout)
) )
end end
local main, match = ctf_stats.player(pname)
if main and match then
main.deaths = main.deaths + 1
match.deaths = match.deaths + 1
main.score = main.score - COMBATLOG_SCORE_PENALTY
match.score = match.score - COMBATLOG_SCORE_PENALTY
match.kills_since_death = 0
ctf_stats.request_save()
end
potential_cowards[pname] = nil potential_cowards[pname] = nil
end end
end) end)
@ -156,6 +168,7 @@ minetest.register_globalstep(function(dtime)
end end
potential_cowards[k] = nil potential_cowards[k] = nil
kill_assist.clear_assists(k)
end end
end end

View file

@ -1,2 +1,2 @@
name = anticoward name = anticoward
depends = ctf, ctf_classes, ctf_match depends = ctf, ctf_classes, ctf_match, kill_assist

View file

@ -16,8 +16,10 @@ local function regen_all()
local newhp = oldhp + hpregen.amount local newhp = oldhp + hpregen.amount
if newhp > player:get_properties().hp_max then if newhp > player:get_properties().hp_max then
newhp = player:get_properties().hp_max newhp = player:get_properties().hp_max
kill_assist.clear_assists(player:get_player_name())
end end
if oldhp ~= newhp then if oldhp ~= newhp then
kill_assist.add_heal_assist(player:get_player_name(), hpregen.amount)
player:set_hp(newhp) player:set_hp(newhp)
end end
end end

View file

@ -1 +1,2 @@
name = hpregen name = hpregen
depends = kill_assist

View file

@ -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)

View file

@ -0,0 +1,2 @@
name = kill_assist
depends = ctf, ctf_match, ctf_stats, hud_score

View file

@ -117,6 +117,7 @@ minetest.register_globalstep(function(dtime)
if pstat then if pstat then
local hp = player:get_hp() local hp = player:get_hp()
if hp < pstat.regen_max then 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)) player:set_hp(math.min(hp + regen_step, pstat.regen_max))
else else
stop_healing(player) stop_healing(player)