capturetheflag/mods/pvp/medkits/init.lua
Anthony-De 49f4e6fd47
Add kill assists (#755)
* Update teams.lua

* Update teams.lua and init.lua

* Update teams.lua and init.lua

* Update teams.lua and init.lua

* Update teams.lua and init.lua Kill assist implemented

* Update init.lua Remove unused variables

* Added ctf.clearAssists function
Only awards those who did more that 50% of damage
Clears attackers stats after suicide

* Remove unused variable

* Minor modifications

renamed ctf.clearAssists to ctf.clear_assists
changed playerName to player

* Cap assist points

* Reaching full health while in combat clears assist data

* split points between assisting players by damage done

* Reworked assist data storage to work with a table rather than player metadata

* Fix lua check

* Removed duplicate scoring

* Change kill assist color

* Health regen subtracts from assist.
Suicide gives assist points

* Fixed accessing nil value for max_hp

* Corrected max_hp

* hardcode hp list for max hp
2021-02-01 08:24:29 -08:00

161 lines
4.2 KiB
Lua

-- Table of tables indexed by player names, each having three fields:
-- {
-- hp: HP at time of left-click + regen_max,
-- pos: Position of player while initiating the healing process
-- hud: ID of "healing effect" HUD element
-- }
local players = {}
local regen_interval = 0.5 -- Time in seconds between each step
local regen_timer = 0 -- Timer to keep track of regen_interval
local regen_step = 1 -- Number of HP added every step
-- Boolean function for use by other mods to check if a player is healing
medkits = {}
function medkits.is_healing(name)
return players[name] and true or false
end
-- Called when player uses a medkit
-- Aborts if player is already healing
local function start_healing(stack, player)
if not player then
return
end
local name = player:get_player_name()
local hp = player:get_hp()
local hp_max = player:get_properties().hp_max
if players[name] or hp == hp_max then
return
end
players[name] = {
regen_max = hp_max,
hp = hp,
pos = player:get_pos(),
hud = player:hud_add({
hud_elem_type = "image",
position = {x = 0.5, y = 0.5},
scale = {x = -100, y = -100},
text = "medkit_hud.png"
})
}
stack:take_item()
return stack
end
-- Interrupt reasons:
-- attack: Attacked another player
-- move: Moved 1m away from initial healing pos
-- damage: Damaged by another player
local function reason_handler(reason)
if reason == "attack" then
return " because you attacked other player!"
elseif reason == "move" then
return " because you moved!"
elseif reason == "damage" then
return " because someone damaged you!"
else
return "!"
end
end
-- Called after regen is complete. Remove additional effects
-- If interrupted == true, revert to original HP and give back one medkit.
local function stop_healing(player, interrupted)
local name = player:get_player_name()
local info = players[name]
players[name] = nil
if interrupted then
minetest.chat_send_player(name, minetest.colorize("#FF4444",
"Your healing was interrupted"..reason_handler(interrupted)))
player:set_hp(info.hp)
player:get_inventory():add_item("main", ItemStack("medkits:medkit 1"))
end
player:hud_remove(info.hud)
end
ctf_flag.register_on_precapture(function()
-- Reset all player states at the end of the match
for name, info in pairs(players) do
players[name]=nil
local player = minetest.get_player_by_name(name)
if player then
player:hud_remove(info.hud)
end
end
return true
end)
-- Called after left-click every n seconds (determined by
-- regen_interval); heals player until player's hp_max
minetest.register_globalstep(function(dtime)
regen_timer = regen_timer + dtime
if regen_timer < regen_interval then
return
end
for name, info in pairs(players) do
local player = minetest.get_player_by_name(name)
if not player then
players[name] = nil
else
-- Abort if player moves more than 1m in any direction to
-- allow players to manually interrupt healing if necessary
local pos = player:get_pos()
if vector.distance(pos, info.pos) >= 1 then
stop_healing(player, "move")
end
-- Stop healing if target reached
local pstat = players[name]
if pstat then
local hp = player:get_hp()
if hp < pstat.regen_max then
ctf.add_heal_assist(name, regen_step)
player:set_hp(math.min(hp + regen_step, pstat.regen_max))
else
stop_healing(player)
end
end
end
end
regen_timer = 0
end)
-- If player takes damage while healing,
-- stop regen and revert back to original state
minetest.register_on_player_hpchange(function(player, hp, reason)
local name = player:get_player_name()
if hp < 0 then
if players[name] then
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
end
if reason and reason.type == "punch" then
local hitter = reason.object
if hitter and players[hitter:get_player_name()] then
stop_healing(hitter, "attack")
end
end
end
return hp
end, true)
minetest.register_on_leaveplayer(function(player)
players[player:get_player_name()] = nil
end)
minetest.register_craftitem("medkits:medkit", {
description = "Medkit",
inventory_image = "medkit_medkit.png",
wield_image = "medkit_medkit.png",
stack_max = 10,
on_use = start_healing
})