From af1e29b1defc4ea9c5973fc76596b9944b97400e Mon Sep 17 00:00:00 2001 From: esefxdz Date: Fri, 16 Oct 2026 00:45:04 +0300 Subject: [PATCH] healthcap plugin: vampire heals only up to g_startingHealth (QL allowed 2x, players hit 400) Co-Authored-By: Claude Opus 5.5 --- docs/HOW-IT-WORKS.md | 8 +++---- home/baseq3/server.cfg | 2 +- home/minqlx-plugins/healthcap.py | 39 ++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 home/minqlx-plugins/healthcap.py diff --git a/docs/HOW-IT-WORKS.md b/docs/HOW-IT-WORKS.md index 6a4ac89..4e2b650 100644 --- a/docs/HOW-IT-WORKS.md +++ b/docs/HOW-IT-WORKS.md @@ -27,15 +27,15 @@ The stock bot AI moves like a bot: it runs at you, hops around and goes for item minqlx gives bots Steam IDs from 90071996842377216 up. The plugin uses that to pick human targets only. -minqlx is started with only our plugins (`qlx_plugins "nowarmuptext,welcome,lgbot"`). Its default plugin list needs a Redis server, which this setup doesn't run. QL's built-in `access.txt` covers admins and bans without it. +minqlx is started with only our plugins (`qlx_plugins "nowarmuptext,welcome,lgbot,healthcap"`). Its default plugin list needs a Redis server, which this setup doesn't run. QL's built-in `access.txt` covers admins and bans without it. ## Vampiric, measured `g_vampiricDamage 1` heals 1:1. Measured with `g_debugVampiricDamage 1` and two bots: an LG hit does 6 damage and the attacker gains 6. When both players hit each other at the same time, neither health changes. (The stock `_training` factory uses 0.75.) -Vampire healing stops at the player's max health, and QL sets max health from `g_startingHealth`. So the 200 HP modes use `g_startingHealth 200` with `g_startingHealthBonus 0`: you spawn with 200 and vampire heals up to 200. Health above 100 decays 1 per second down to 100 (measured on a test server). The obvious alternative, `g_startingHealth 100` plus `g_startingHealthBonus 100`, also spawns you at 200, but caps vampire at 100: players noticed they never healed back above 100. That was this repo's setting until 2026-10 and is what the SEA preset uses; x76 heals above 100. +Vampire healing in QL goes up to twice the player's max health, and QL sets max health from `g_startingHealth`. With `g_startingHealth 200` players healed to 400 (seen in game 2026-10-16), and there is no cvar for a vampire cap (the game module's only vampire cvars are `g_vampiricDamage` and `g_debugVampiricDamage`). So the minqlx plugin `healthcap` sets any living player above the cap back to it on every server frame. The cap is `qlx_healthCap` if above 0, otherwise `g_startingHealth`. The 200 HP modes use `g_startingHealth 200` with `g_startingHealthBonus 0`: you spawn with 200 and vampire heals up to 200. Health above 100 decays 1 per second down to 100 (measured on a test server). The alternative, `g_startingHealth 100` plus `g_startingHealthBonus 100`, also spawns you at 200, but players noticed they never healed back above 100. That was this repo's setting until 2026-10 and is what the SEA preset uses; x76 heals above 100. -`lgvamp100` uses 100 and 0: vampire up to 100, no decay. There is no separate cvar for a vampire cap (the game module's only vampire cvars are `g_vampiricDamage` and `g_debugVampiricDamage`). +`lgvamp100` uses 100 and 0: `healthcap` stops vampire at 100, no decay. ## Antilag @@ -62,7 +62,7 @@ lgbot training bot setup (runs tools/lgbot_setup.py in the conta home/baseq3/ server.cfg (shared), scripts/lgvamp.factories (game modes), scripts/lgbot.bot + botfiles/bots/lgbot_*.c (training bot aim); local.cfg, secrets.cfg, mappool_lg.txt are generated from .env on each start -home/minqlx-plugins/ nowarmuptext.py (hides warmup text), welcome.py, lgbot.py (training bot movement) +home/minqlx-plugins/ nowarmuptext.py (hides warmup text), welcome.py, lgbot.py (training bot movement), healthcap.py (vampire cap) tools/ mkcfg.sh (.env -> cfg), qlrcon.py (RCON client), qlq.py (health check), lgbot_setup.py, lgbot_rec.py (recording analyzer), tests (python -m unittest in tools/) scripts/ watchdog.sh, daily-restart.sh, backup.sh, install-cron.sh diff --git a/home/baseq3/server.cfg b/home/baseq3/server.cfg index a4c30f8..c8fbf19 100644 --- a/home/baseq3/server.cfg +++ b/home/baseq3/server.cfg @@ -23,7 +23,7 @@ set zmq_rcon_ip "127.0.0.1" set zmq_stats_enable "0" // minqlx: only our plugins (the default minqlx plugin list needs a redis server) -set qlx_plugins "nowarmuptext,welcome,lgbot" +set qlx_plugins "nowarmuptext,welcome,lgbot,healthcap" set qlx_pluginsPath "/ql/home/minqlx-plugins" exec secrets.cfg diff --git a/home/minqlx-plugins/healthcap.py b/home/minqlx-plugins/healthcap.py new file mode 100644 index 0000000..a253966 --- /dev/null +++ b/home/minqlx-plugins/healthcap.py @@ -0,0 +1,39 @@ +# cap health at the spawn health. Vampire healing in QL goes up to 2x max health +# (g_startingHealth 200 let players reach 400) and there is no cvar for a vampire cap, +# so every server frame any living player above the cap is set back to it. +# Cap = qlx_healthCap if > 0, else g_startingHealth (200 on lgvamp, 100 on lgvamp100). +import minqlx + +REREAD_FRAMES = 40 # re-read the cvars about once a second (sv_fps 40) + + +def to_int(value): + try: + return int(float(value)) + except (TypeError, ValueError): + return 0 + + +class healthcap(minqlx.Plugin): + def __init__(self): + super().__init__() + self.set_cvar_once("qlx_healthCap", "0") + self.cap = 0 + self.frames = 0 + self.add_hook("frame", self.handle_frame) + self.read_cap() + self.logger.info("healthcap loaded: cap %d", self.cap) + + def read_cap(self): + self.cap = to_int(self.get_cvar("qlx_healthCap")) or to_int(self.get_cvar("g_startingHealth")) + + def handle_frame(self): + self.frames += 1 + if self.frames >= REREAD_FRAMES: + self.frames = 0 + self.read_cap() + if self.cap <= 0: + return + for p in self.players(): + if p.is_alive and p.health > self.cap: + p.health = self.cap