Advertisement
Chibibowa

HP Rebalance for ETLegacy [Final]

Feb 16th, 2025 (edited)
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.28 KB | None | 0 0
  1. ------------------------------------------------------------
  2. -- FixHPforClass 1.2
  3. -- Per-class max HP, no "reviving" from 0 HP.
  4. ------------------------------------------------------------
  5.  
  6. modname = "FixHPforClass"
  7. version = "1.2"
  8.  
  9. ------------------------------------------------------------
  10. -- Class IDs in Wolf:ET (typical ordering)
  11. ------------------------------------------------------------
  12. local CLASS_SOLDIER   = 0
  13. local CLASS_MEDIC     = 1
  14. local CLASS_ENGINEER  = 2
  15. local CLASS_FIELDOPS  = 3
  16. local CLASS_COVERTOPS = 4
  17.  
  18. ------------------------------------------------------------
  19. -- Configuration: Max HP per class
  20. ------------------------------------------------------------
  21. local classMaxHP = {
  22.     [CLASS_SOLDIER]   = 190,
  23.     [CLASS_MEDIC]     = 175,
  24.     [CLASS_ENGINEER]  = 190,
  25.     [CLASS_FIELDOPS]  = 190,
  26.     [CLASS_COVERTOPS] = 190
  27. }
  28.  
  29. ------------------------------------------------------------
  30. -- Regeneration rate for NON-Medics (HP/sec)
  31. ------------------------------------------------------------
  32. local REGEN_RATE = 2.15
  33.  
  34. ------------------------------------------------------------
  35. -- We'll track last time we regenerated (once per second)
  36. -- and fractional leftover for sub-integer increments.
  37. ------------------------------------------------------------
  38. local lastRegenTime    = {}
  39. local regenAccumulator = {}
  40.  
  41. ------------------------------------------------------------
  42. -- et_InitGame: Called at map/server start
  43. ------------------------------------------------------------
  44. function et_InitGame(levelTime, randomSeed, restart)
  45.     et.RegisterModname(modname .. " " .. version)
  46. end
  47.  
  48. ------------------------------------------------------------
  49. -- et_ClientSpawn: Called when a player spawns (or is revived)
  50. -- => Give them full HP, reset regeneration tracking
  51. ------------------------------------------------------------
  52. function et_ClientSpawn(clientNum, revived)
  53.     local class = et.gentity_get(clientNum, "sess.playerType")
  54.     local maxHP = getMaxHPForClass(class)
  55.  
  56.     -- Set Max HP and current health
  57.     et.gentity_set(clientNum, "ps.stats", 3, maxHP)  -- STAT_MAX_HEALTH = 3
  58.     et.gentity_set(clientNum, "health", maxHP)
  59.  
  60.     -- Reset regeneration tracking
  61.     lastRegenTime[clientNum]    = et.trap_Milliseconds()
  62.     regenAccumulator[clientNum] = 0.0
  63. end
  64.  
  65. ------------------------------------------------------------
  66. -- et_RunFrame: Called ~100 times per second
  67. -- 1) Keep custom max HP enforced
  68. -- 2) Regenerate HP for non-Medics (only if HP >= 1)
  69. ------------------------------------------------------------
  70. function et_RunFrame(levelTime)
  71.     local maxClients = tonumber(et.trap_Cvar_Get("sv_maxclients"))
  72.     for clientNum = 0, maxClients - 1 do
  73.         if isActivePlayer(clientNum) then
  74.             fixMaxHP(clientNum)
  75.             regenHPIfNeeded(clientNum, levelTime)
  76.         else
  77.             -- Clear if not active or dead
  78.             lastRegenTime[clientNum]    = nil
  79.             regenAccumulator[clientNum] = nil
  80.         end
  81.     end
  82. end
  83.  
  84. ------------------------------------------------------------
  85. -- Helper: check if a client is connected & alive (hp > 0)
  86. ------------------------------------------------------------
  87. function isActivePlayer(clientNum)
  88.     local connected = et.gentity_get(clientNum, "pers.connected")
  89.     if connected ~= 2 then  -- 2 = CON_CONNECTED
  90.         return false
  91.     end
  92.     local hp = et.gentity_get(clientNum, "health")
  93.     return (hp > 0)  -- Must be above 0 to be "alive"
  94. end
  95.  
  96. ------------------------------------------------------------
  97. -- Helper: retrieve the max HP for a given class
  98. ------------------------------------------------------------
  99. function getMaxHPForClass(classID)
  100.     -- Default/fallback if unexpected class ID
  101.     return classMaxHP[classID] or 100
  102. end
  103.  
  104. ------------------------------------------------------------
  105. -- 1) Enforce max HP for that player's class
  106. -- 2) Clamp current HP if it exceeds the max
  107. ------------------------------------------------------------
  108. function fixMaxHP(clientNum)
  109.     local class = et.gentity_get(clientNum, "sess.playerType")
  110.     local maxHP = getMaxHPForClass(class)
  111.  
  112.     -- Force STAT_MAX_HEALTH to be correct
  113.     et.gentity_set(clientNum, "ps.stats", 3, maxHP)
  114.  
  115.     local curHP = et.gentity_get(clientNum, "health")
  116.     if curHP > maxHP then
  117.         et.gentity_set(clientNum, "health", maxHP)
  118.     end
  119. end
  120.  
  121. ------------------------------------------------------------
  122. -- Regenerate HP at REGEN_RATE HP/s for NON-Medics ONLY.
  123. -- We do partial increments once per second to keep it smooth.
  124. -- Skips if current HP < 1, so players at 0 HP can't be "rescued."
  125. ------------------------------------------------------------
  126. function regenHPIfNeeded(clientNum, levelTime)
  127.     local class = et.gentity_get(clientNum, "sess.playerType")
  128.  
  129.     -- Skip regeneration for Medics
  130.     if class == CLASS_MEDIC then
  131.         return
  132.     end
  133.  
  134.     -- Current HP (already guaranteed > 0 from isActivePlayer, but let's be explicit)
  135.     local curHP = et.gentity_get(clientNum, "health")
  136.     if curHP < 1 then
  137.         -- This ensures if for some reason HP is 0, we do NOT regen
  138.         return
  139.     end
  140.  
  141.     -- If we have no record, initialize
  142.     if not lastRegenTime[clientNum] then
  143.         lastRegenTime[clientNum]    = levelTime
  144.         regenAccumulator[clientNum] = 0.0
  145.         return
  146.     end
  147.  
  148.     -- Only apply regen every full 1000 ms
  149.     local elapsed = levelTime - lastRegenTime[clientNum]
  150.     if elapsed >= 1000 then
  151.         -- Advance lastRegenTime by exactly 1000 ms
  152.         lastRegenTime[clientNum] = lastRegenTime[clientNum] + 1000
  153.  
  154.         -- Get this player's max HP
  155.         local maxHP = getMaxHPForClass(class)
  156.  
  157.         -- Skip if already at or above max
  158.         if curHP >= maxHP then
  159.             return
  160.         end
  161.  
  162.         -- Add REGEN_RATE to the accumulator
  163.         regenAccumulator[clientNum] = regenAccumulator[clientNum] + REGEN_RATE
  164.  
  165.         -- Take the integer part
  166.         local plus = math.floor(regenAccumulator[clientNum])
  167.         if plus > 0 then
  168.             regenAccumulator[clientNum] = regenAccumulator[clientNum] - plus
  169.             local newHP = curHP + plus
  170.             if newHP > maxHP then
  171.                 newHP = maxHP
  172.             end
  173.             et.gentity_set(clientNum, "health", newHP)
  174.         end
  175.     end
  176. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement