Recharge coop wall chargers
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
local healthRechargeTime = CreateConVar(
|
||||
"gc_healthchargerrechargetime",
|
||||
"60",
|
||||
FCVAR_ARCHIVE,
|
||||
"Seconds before an emptied wall health charger refills; 0 disables automatic refills"
|
||||
)
|
||||
|
||||
local suitRechargeTime = CreateConVar(
|
||||
"gc_suitchargerrechargetime",
|
||||
"30",
|
||||
FCVAR_ARCHIVE,
|
||||
"Seconds before an emptied wall suit charger refills; 0 disables automatic refills"
|
||||
)
|
||||
|
||||
local chargerClasses = {
|
||||
item_healthcharger = healthRechargeTime,
|
||||
item_suitcharger = suitRechargeTime
|
||||
}
|
||||
|
||||
local chargerStates = {}
|
||||
|
||||
local function GetChargerJuice(charger)
|
||||
local juice = charger:GetInternalVariable("m_iJuice")
|
||||
return tonumber(juice)
|
||||
end
|
||||
|
||||
local function GetChargerCapacity(charger, juice)
|
||||
local maxJuice = charger:GetInternalVariable("m_iMaxJuice")
|
||||
local displayedJuice = charger:GetInternalVariable("m_flJuice")
|
||||
|
||||
return math.max(
|
||||
juice or 0,
|
||||
tonumber(maxJuice) or 0,
|
||||
tonumber(displayedJuice) or 0
|
||||
)
|
||||
end
|
||||
|
||||
local function RefillCharger(charger, state)
|
||||
charger:Fire("Recharge")
|
||||
|
||||
-- GMod's suit charger implements Recharge, but item_healthcharger does not
|
||||
-- on all engine branches. Give the native input a frame to run, then use
|
||||
-- its internal Source charge fields as a compatibility fallback.
|
||||
timer.Simple(0.1, function()
|
||||
if not IsValid(charger) or (GetChargerJuice(charger) or 0) > 0 then return end
|
||||
if not state.capacity or state.capacity <= 0 then return end
|
||||
|
||||
charger:SetSaveValue("m_iJuice", state.capacity)
|
||||
if charger:GetInternalVariable("m_flJuice") ~= nil then
|
||||
charger:SetSaveValue("m_flJuice", state.capacity)
|
||||
end
|
||||
charger:SetCycle(0)
|
||||
charger:EmitSound("items/medshot4.wav", 60, 100, 0.5)
|
||||
end)
|
||||
end
|
||||
|
||||
timer.Create("CustomCoopRechargeWallChargers", 1, 0, function()
|
||||
local now = CurTime()
|
||||
local seen = {}
|
||||
|
||||
for className, rechargeTime in pairs(chargerClasses) do
|
||||
local delay = math.max(rechargeTime:GetFloat(), 0)
|
||||
|
||||
for _, charger in ipairs(ents.FindByClass(className)) do
|
||||
seen[charger] = true
|
||||
|
||||
local juice = GetChargerJuice(charger)
|
||||
if juice == nil then continue end
|
||||
|
||||
local state = chargerStates[charger]
|
||||
if not state then
|
||||
-- A mapper may deliberately place a charger with zero charge.
|
||||
-- Only chargers observed being drained during play are refilled.
|
||||
state = {
|
||||
lastJuice = juice,
|
||||
capacity = GetChargerCapacity(charger, juice)
|
||||
}
|
||||
chargerStates[charger] = state
|
||||
elseif juice > 0 or delay == 0 then
|
||||
state.refillAt = nil
|
||||
elseif state.lastJuice > 0 and juice <= 0 then
|
||||
state.refillAt = now + delay
|
||||
elseif state.refillAt and now >= state.refillAt then
|
||||
-- Use the native Source input rather than replacing the entity,
|
||||
-- preserving its name, Hammer I/O, animation and sounds.
|
||||
RefillCharger(charger, state)
|
||||
state.refillAt = nil
|
||||
end
|
||||
|
||||
state.lastJuice = juice
|
||||
end
|
||||
end
|
||||
|
||||
for charger in pairs(chargerStates) do
|
||||
if not seen[charger] or not IsValid(charger) then
|
||||
chargerStates[charger] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
hook.Add("PostCleanupMap", "CustomCoopResetWallChargerTracking", function()
|
||||
chargerStates = {}
|
||||
end)
|
||||
+3
-2
@@ -2,8 +2,9 @@ AddCSLuaFile( "cl_init.lua" )
|
||||
AddCSLuaFile( "shared.lua" )
|
||||
AddCSLuaFile( "levels.lua" )
|
||||
include( "spawninit.lua" )
|
||||
include( "weaponsystem.lua" )
|
||||
include( "allplayersdied.lua" )
|
||||
include( "weaponsystem.lua" )
|
||||
include( "chargersystem.lua" )
|
||||
include( "allplayersdied.lua" )
|
||||
include( "deathspectate.lua" )
|
||||
include( "headcrabs.lua" )
|
||||
include( "zombies.lua" )
|
||||
|
||||
@@ -15,10 +15,23 @@ local respawnDelay = CreateConVar(
|
||||
local trackedItems = {}
|
||||
local suppressRespawns = false
|
||||
|
||||
-- These use the item_ prefix but are map machinery or containers rather than
|
||||
-- touch pickups. Ammo crates are already infinite; the others may be removed
|
||||
-- deliberately by Hammer I/O and must not be recreated as loose supplies.
|
||||
local persistentItemClasses = {
|
||||
item_ammo_crate = true,
|
||||
item_dynamic_resupply = true,
|
||||
item_healthcharger = true,
|
||||
item_item_crate = true,
|
||||
item_suitcharger = true
|
||||
}
|
||||
|
||||
local function IsRespawnable(ent)
|
||||
if not IsValid(ent) then return false end
|
||||
|
||||
local className = ent:GetClass()
|
||||
if persistentItemClasses[className] then return false end
|
||||
|
||||
return string.StartWith(className, "item_") or string.StartWith(className, "weapon_")
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user