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)