From 353c0b9567d17df5f6c3c94f618fecfdff513fa7 Mon Sep 17 00:00:00 2001 From: TimePath Date: Sat, 2 Sep 2017 11:30:30 +1000 Subject: [PATCH] Make some mutators accept cvar expressions for being enabled --- .../mutator/bloodloss/sv_bloodloss.qc | 3 +- .../mutator/campcheck/sv_campcheck.qc | 3 +- .../mutators/mutator/cloaked/sv_cloaked.qc | 3 +- qcsrc/common/mutators/mutator/hook/sv_hook.qc | 2 +- .../mutators/mutator/instagib/sv_instagib.qc | 7 +- .../invincibleproj/sv_invincibleproj.qc | 3 +- .../mutator/melee_only/sv_melee_only.qc | 3 +- .../mutators/mutator/midair/sv_midair.qc | 3 +- .../mutators/mutator/multijump/multijump.qc | 2 +- qcsrc/common/mutators/mutator/nades/nades.qc | 4 +- .../mutators/mutator/new_toys/sv_new_toys.qc | 4 +- qcsrc/common/mutators/mutator/nix/sv_nix.qc | 3 +- .../mutators/mutator/overkill/sv_overkill.qc | 4 +- .../physical_items/sv_physical_items.qc | 2 +- .../mutators/mutator/pinata/sv_pinata.qc | 3 +- .../mutator/rocketflying/sv_rocketflying.qc | 3 +- .../mutators/mutator/sandbox/sv_sandbox.qc | 3 +- .../sv_spawn_near_teammate.qc | 3 +- .../mutator/superspec/sv_superspec.qc | 3 +- .../mutator/touchexplode/sv_touchexplode.qc | 3 +- .../mutators/mutator/vampire/sv_vampire.qc | 3 +- .../mutator/vampirehook/sv_vampirehook.qc | 3 +- .../mutators/mutator/walljump/walljump.qc | 2 +- qcsrc/server/autocvars.qh | 8 +- qcsrc/server/resources.qc | 3 +- qcsrc/server/resources.qh | 3 +- qcsrc/server/sv_main.qc | 132 ++++++++++-------- qcsrc/server/sv_main.qh | 2 + 28 files changed, 126 insertions(+), 94 deletions(-) diff --git a/qcsrc/common/mutators/mutator/bloodloss/sv_bloodloss.qc b/qcsrc/common/mutators/mutator/bloodloss/sv_bloodloss.qc index d1b265816..1164e0ade 100644 --- a/qcsrc/common/mutators/mutator/bloodloss/sv_bloodloss.qc +++ b/qcsrc/common/mutators/mutator/bloodloss/sv_bloodloss.qc @@ -1,6 +1,7 @@ #include "sv_bloodloss.qh" -REGISTER_MUTATOR(bloodloss, cvar("g_bloodloss")); +float autocvar_g_bloodloss; +REGISTER_MUTATOR(bloodloss, autocvar_g_bloodloss); .float bloodloss_timer; diff --git a/qcsrc/common/mutators/mutator/campcheck/sv_campcheck.qc b/qcsrc/common/mutators/mutator/campcheck/sv_campcheck.qc index a64f9d080..987645aaa 100644 --- a/qcsrc/common/mutators/mutator/campcheck/sv_campcheck.qc +++ b/qcsrc/common/mutators/mutator/campcheck/sv_campcheck.qc @@ -1,10 +1,11 @@ #include "sv_campcheck.qh" +string autocvar_g_campcheck; float autocvar_g_campcheck_damage; float autocvar_g_campcheck_distance; float autocvar_g_campcheck_interval; -REGISTER_MUTATOR(campcheck, cvar("g_campcheck")); +REGISTER_MUTATOR(campcheck, expr_evaluate(autocvar_g_campcheck)); .float campcheck_nextcheck; .float campcheck_traveled_distance; diff --git a/qcsrc/common/mutators/mutator/cloaked/sv_cloaked.qc b/qcsrc/common/mutators/mutator/cloaked/sv_cloaked.qc index eb45d4baf..a1fe27a87 100644 --- a/qcsrc/common/mutators/mutator/cloaked/sv_cloaked.qc +++ b/qcsrc/common/mutators/mutator/cloaked/sv_cloaked.qc @@ -1,6 +1,7 @@ #include "sv_cloaked.qh" -REGISTER_MUTATOR(cloaked, cvar("g_cloaked")); +string autocvar_g_cloaked; +REGISTER_MUTATOR(cloaked, expr_evaluate(autocvar_g_cloaked)); float autocvar_g_balance_cloaked_alpha; diff --git a/qcsrc/common/mutators/mutator/hook/sv_hook.qc b/qcsrc/common/mutators/mutator/hook/sv_hook.qc index 5dfdf4386..c39678119 100644 --- a/qcsrc/common/mutators/mutator/hook/sv_hook.qc +++ b/qcsrc/common/mutators/mutator/hook/sv_hook.qc @@ -5,7 +5,7 @@ #ifdef SVQC AUTOCVAR(g_grappling_hook_useammo, bool, false, "Use ammunition with the off-hand grappling hook"); -REGISTER_MUTATOR(hook, cvar("g_grappling_hook")) { +REGISTER_MUTATOR(hook, expr_evaluate(cvar_string("g_grappling_hook"))) { MUTATOR_ONADD { g_grappling_hook = true; if(!autocvar_g_grappling_hook_useammo) diff --git a/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc b/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc index 3de831198..1561dc10d 100644 --- a/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc +++ b/qcsrc/common/mutators/mutator/instagib/sv_instagib.qc @@ -1,5 +1,10 @@ #include "sv_instagib.qh" +bool autocvar_g_instagib_damagedbycontents = true; +bool autocvar_g_instagib_blaster_keepdamage = false; +bool autocvar_g_instagib_blaster_keepforce = false; +bool autocvar_g_instagib_mirrordamage; +bool autocvar_g_instagib_friendlypush = true; //int autocvar_g_instagib_ammo_drop; bool autocvar_g_instagib_ammo_convert_cells; bool autocvar_g_instagib_ammo_convert_rockets; @@ -12,7 +17,7 @@ float autocvar_g_instagib_speed_highspeed; #include -REGISTER_MUTATOR(mutator_instagib, cvar("g_instagib") && !g_nexball); +REGISTER_MUTATOR(mutator_instagib, autocvar_g_instagib && !g_nexball); spawnfunc(item_minst_cells) { diff --git a/qcsrc/common/mutators/mutator/invincibleproj/sv_invincibleproj.qc b/qcsrc/common/mutators/mutator/invincibleproj/sv_invincibleproj.qc index 23e0d0d85..e68c687bd 100644 --- a/qcsrc/common/mutators/mutator/invincibleproj/sv_invincibleproj.qc +++ b/qcsrc/common/mutators/mutator/invincibleproj/sv_invincibleproj.qc @@ -1,6 +1,7 @@ #include "sv_invincibleproj.qh" -REGISTER_MUTATOR(invincibleprojectiles, cvar("g_invincible_projectiles")); +string autocvar_g_invincible_projectiles; +REGISTER_MUTATOR(invincibleprojectiles, expr_evaluate(autocvar_g_invincible_projectiles)); MUTATOR_HOOKFUNCTION(invincibleprojectiles, EditProjectile) { diff --git a/qcsrc/common/mutators/mutator/melee_only/sv_melee_only.qc b/qcsrc/common/mutators/mutator/melee_only/sv_melee_only.qc index a54292122..ac06a8f77 100644 --- a/qcsrc/common/mutators/mutator/melee_only/sv_melee_only.qc +++ b/qcsrc/common/mutators/mutator/melee_only/sv_melee_only.qc @@ -1,6 +1,7 @@ #include "sv_melee_only.qh" -REGISTER_MUTATOR(melee_only, cvar("g_melee_only") && !cvar("g_instagib") && !cvar("g_overkill") && !g_nexball); +string autocvar_g_melee_only; +REGISTER_MUTATOR(melee_only, expr_evaluate(autocvar_g_melee_only) && !cvar("g_instagib") && !cvar("g_overkill") && !g_nexball); MUTATOR_HOOKFUNCTION(melee_only, SetStartItems, CBC_ORDER_LAST) { diff --git a/qcsrc/common/mutators/mutator/midair/sv_midair.qc b/qcsrc/common/mutators/mutator/midair/sv_midair.qc index 92bbacc00..54b3673c6 100644 --- a/qcsrc/common/mutators/mutator/midair/sv_midair.qc +++ b/qcsrc/common/mutators/mutator/midair/sv_midair.qc @@ -1,8 +1,9 @@ #include "sv_midair.qh" +string autocvar_g_midair; float autocvar_g_midair_shieldtime; -REGISTER_MUTATOR(midair, cvar("g_midair")); +REGISTER_MUTATOR(midair, expr_evaluate(autocvar_g_midair)); .float midair_shieldtime; diff --git a/qcsrc/common/mutators/mutator/multijump/multijump.qc b/qcsrc/common/mutators/mutator/multijump/multijump.qc index 47dcfd4af..081a1fdb6 100644 --- a/qcsrc/common/mutators/mutator/multijump/multijump.qc +++ b/qcsrc/common/mutators/mutator/multijump/multijump.qc @@ -9,7 +9,7 @@ #if defined(SVQC) -REGISTER_MUTATOR(multijump, cvar("g_multijump")); +REGISTER_MUTATOR(multijump, autocvar_g_multijump); #elif defined(CSQC) REGISTER_MUTATOR(multijump, true); #endif diff --git a/qcsrc/common/mutators/mutator/nades/nades.qc b/qcsrc/common/mutators/mutator/nades/nades.qc index ab8e175e7..92e16b48d 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qc +++ b/qcsrc/common/mutators/mutator/nades/nades.qc @@ -150,7 +150,7 @@ void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expan #include #include -REGISTER_MUTATOR(nades, cvar("g_nades")); +REGISTER_MUTATOR(nades, autocvar_g_nades); .float nade_time_primed; .float nade_lifetime; @@ -872,7 +872,7 @@ void nade_damage(entity this, entity inflictor, entity attacker, float damage, i hp -= damage; SetResourceAmount(this, RESOURCE_HEALTH, hp); - + if ( this.nade_type != NADE_TYPE_HEAL.m_id || IS_PLAYER(attacker) ) this.realowner = attacker; diff --git a/qcsrc/common/mutators/mutator/new_toys/sv_new_toys.qc b/qcsrc/common/mutators/mutator/new_toys/sv_new_toys.qc index 288c2d5c8..af364995a 100644 --- a/qcsrc/common/mutators/mutator/new_toys/sv_new_toys.qc +++ b/qcsrc/common/mutators/mutator/new_toys/sv_new_toys.qc @@ -68,9 +68,11 @@ roflsound "New toys, new toys!" sound. */ +string autocvar_g_new_toys; + bool nt_IsNewToy(int w); -REGISTER_MUTATOR(nt, cvar("g_new_toys") && !cvar("g_instagib") && !cvar("g_overkill")) +REGISTER_MUTATOR(nt, expr_evaluate(autocvar_g_new_toys) && !cvar("g_instagib") && !cvar("g_overkill")) { MUTATOR_ONADD { diff --git a/qcsrc/common/mutators/mutator/nix/sv_nix.qc b/qcsrc/common/mutators/mutator/nix/sv_nix.qc index 33536fb0a..4de24a589 100644 --- a/qcsrc/common/mutators/mutator/nix/sv_nix.qc +++ b/qcsrc/common/mutators/mutator/nix/sv_nix.qc @@ -1,5 +1,6 @@ #include "sv_nix.qh" +string autocvar_g_nix; int autocvar_g_balance_nix_ammo_cells; int autocvar_g_balance_nix_ammo_plasma; int autocvar_g_balance_nix_ammo_fuel; @@ -35,7 +36,7 @@ float nix_nextweapon; bool NIX_CanChooseWeapon(int wpn); -REGISTER_MUTATOR(nix, cvar("g_nix") && !cvar("g_instagib") && !cvar("g_overkill")) +REGISTER_MUTATOR(nix, expr_evaluate(autocvar_g_nix) && !cvar("g_instagib") && !cvar("g_overkill")) { MUTATOR_ONADD { diff --git a/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc b/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc index d2a7308de..b47e58751 100644 --- a/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc +++ b/qcsrc/common/mutators/mutator/overkill/sv_overkill.qc @@ -3,6 +3,8 @@ #include "hmg.qh" #include "rpc.qh" +string autocvar_g_overkill; + bool autocvar_g_overkill_powerups_replace; bool autocvar_g_overkill_itemwaypoints = true; @@ -18,7 +20,7 @@ bool autocvar_g_overkill_filter_armormega; void ok_Initialize(); -REGISTER_MUTATOR(ok, cvar("g_overkill") && !cvar("g_instagib") && !g_nexball && cvar_string("g_mod_balance") == "Overkill") +REGISTER_MUTATOR(ok, expr_evaluate(autocvar_g_overkill) && !cvar("g_instagib") && !g_nexball && cvar_string("g_mod_balance") == "Overkill") { MUTATOR_ONADD { diff --git a/qcsrc/common/mutators/mutator/physical_items/sv_physical_items.qc b/qcsrc/common/mutators/mutator/physical_items/sv_physical_items.qc index 62781c920..38cd7474b 100644 --- a/qcsrc/common/mutators/mutator/physical_items/sv_physical_items.qc +++ b/qcsrc/common/mutators/mutator/physical_items/sv_physical_items.qc @@ -4,7 +4,7 @@ int autocvar_g_physical_items; float autocvar_g_physical_items_damageforcescale; float autocvar_g_physical_items_reset; -REGISTER_MUTATOR(physical_items, cvar("g_physical_items")) +REGISTER_MUTATOR(physical_items, autocvar_g_physical_items) { // check if we have a physics engine MUTATOR_ONADD diff --git a/qcsrc/common/mutators/mutator/pinata/sv_pinata.qc b/qcsrc/common/mutators/mutator/pinata/sv_pinata.qc index 53e4f49e6..1084ff778 100644 --- a/qcsrc/common/mutators/mutator/pinata/sv_pinata.qc +++ b/qcsrc/common/mutators/mutator/pinata/sv_pinata.qc @@ -1,6 +1,7 @@ #include "sv_pinata.qh" -REGISTER_MUTATOR(pinata, cvar("g_pinata") && !cvar("g_instagib") && !cvar("g_overkill")); +string autocvar_g_pinata; +REGISTER_MUTATOR(pinata, expr_evaluate(autocvar_g_pinata) && !cvar("g_instagib") && !cvar("g_overkill")); MUTATOR_HOOKFUNCTION(pinata, PlayerDies) { diff --git a/qcsrc/common/mutators/mutator/rocketflying/sv_rocketflying.qc b/qcsrc/common/mutators/mutator/rocketflying/sv_rocketflying.qc index 9f0d8fbf0..d3c1922b9 100644 --- a/qcsrc/common/mutators/mutator/rocketflying/sv_rocketflying.qc +++ b/qcsrc/common/mutators/mutator/rocketflying/sv_rocketflying.qc @@ -1,6 +1,7 @@ #include "sv_rocketflying.qh" -REGISTER_MUTATOR(rocketflying, cvar("g_rocket_flying")); +string autocvar_g_rocket_flying; +REGISTER_MUTATOR(rocketflying, expr_evaluate(autocvar_g_rocket_flying)); MUTATOR_HOOKFUNCTION(rocketflying, EditProjectile) { diff --git a/qcsrc/common/mutators/mutator/sandbox/sv_sandbox.qc b/qcsrc/common/mutators/mutator/sandbox/sv_sandbox.qc index 93dc602f0..d121cf109 100644 --- a/qcsrc/common/mutators/mutator/sandbox/sv_sandbox.qc +++ b/qcsrc/common/mutators/mutator/sandbox/sv_sandbox.qc @@ -1,5 +1,6 @@ #include "sv_sandbox.qh" +string autocvar_g_sandbox; int autocvar_g_sandbox_info; bool autocvar_g_sandbox_readonly; string autocvar_g_sandbox_storage_name; @@ -18,7 +19,7 @@ float autocvar_g_sandbox_object_material_velocity_factor; float autosave_time; void sandbox_Database_Load(); -REGISTER_MUTATOR(sandbox, cvar("g_sandbox")) +REGISTER_MUTATOR(sandbox, expr_evaluate(autocvar_g_sandbox)) { MUTATOR_ONADD { diff --git a/qcsrc/common/mutators/mutator/spawn_near_teammate/sv_spawn_near_teammate.qc b/qcsrc/common/mutators/mutator/spawn_near_teammate/sv_spawn_near_teammate.qc index 9ff364474..ad40f978d 100644 --- a/qcsrc/common/mutators/mutator/spawn_near_teammate/sv_spawn_near_teammate.qc +++ b/qcsrc/common/mutators/mutator/spawn_near_teammate/sv_spawn_near_teammate.qc @@ -2,6 +2,7 @@ #include +string autocvar_g_spawn_near_teammate; float autocvar_g_spawn_near_teammate_distance; int autocvar_g_spawn_near_teammate_ignore_spawnpoint; int autocvar_g_spawn_near_teammate_ignore_spawnpoint_max; @@ -10,7 +11,7 @@ float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death; bool autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health; bool autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath; -REGISTER_MUTATOR(spawn_near_teammate, cvar("g_spawn_near_teammate")); +REGISTER_MUTATOR(spawn_near_teammate, expr_evaluate(autocvar_g_spawn_near_teammate)); .entity msnt_lookat; diff --git a/qcsrc/common/mutators/mutator/superspec/sv_superspec.qc b/qcsrc/common/mutators/mutator/superspec/sv_superspec.qc index 4c99095b7..eb2008235 100644 --- a/qcsrc/common/mutators/mutator/superspec/sv_superspec.qc +++ b/qcsrc/common/mutators/mutator/superspec/sv_superspec.qc @@ -1,6 +1,7 @@ #include "sv_superspec.qh" -REGISTER_MUTATOR(superspec, cvar("g_superspectate")); +string autocvar_g_superspectate; +REGISTER_MUTATOR(superspec, expr_evaluate(autocvar_g_superspectate)); #define _SSMAGIX "SUPERSPEC_OPTIONSFILE_V1" #define _ISLOCAL(ent) ((edict_num(1) == (ent)) ? true : false) diff --git a/qcsrc/common/mutators/mutator/touchexplode/sv_touchexplode.qc b/qcsrc/common/mutators/mutator/touchexplode/sv_touchexplode.qc index 3e6edb04b..a1b38fb6e 100644 --- a/qcsrc/common/mutators/mutator/touchexplode/sv_touchexplode.qc +++ b/qcsrc/common/mutators/mutator/touchexplode/sv_touchexplode.qc @@ -1,11 +1,12 @@ #include "sv_touchexplode.qh" +string autocvar_g_touchexplode; float autocvar_g_touchexplode_radius; float autocvar_g_touchexplode_damage; float autocvar_g_touchexplode_edgedamage; float autocvar_g_touchexplode_force; -REGISTER_MUTATOR(touchexplode, cvar("g_touchexplode")); +REGISTER_MUTATOR(touchexplode, expr_evaluate(autocvar_g_touchexplode)); .float touchexplode_time; diff --git a/qcsrc/common/mutators/mutator/vampire/sv_vampire.qc b/qcsrc/common/mutators/mutator/vampire/sv_vampire.qc index 1b07ecd66..199b4e202 100644 --- a/qcsrc/common/mutators/mutator/vampire/sv_vampire.qc +++ b/qcsrc/common/mutators/mutator/vampire/sv_vampire.qc @@ -1,6 +1,7 @@ #include "sv_vampire.qh" -REGISTER_MUTATOR(vampire, cvar("g_vampire") && !cvar("g_instagib")); +string autocvar_g_vampire; +REGISTER_MUTATOR(vampire, expr_evaluate(autocvar_g_vampire) && !cvar("g_instagib")); MUTATOR_HOOKFUNCTION(vampire, PlayerDamage_SplitHealthArmor) { diff --git a/qcsrc/common/mutators/mutator/vampirehook/sv_vampirehook.qc b/qcsrc/common/mutators/mutator/vampirehook/sv_vampirehook.qc index e2b0f57d7..ce9e27065 100644 --- a/qcsrc/common/mutators/mutator/vampirehook/sv_vampirehook.qc +++ b/qcsrc/common/mutators/mutator/vampirehook/sv_vampirehook.qc @@ -1,6 +1,7 @@ #include "sv_vampirehook.qh" -REGISTER_MUTATOR(vh, cvar("g_vampirehook")); +string autocvar_g_vampirehook; +REGISTER_MUTATOR(vh, expr_evaluate(autocvar_g_vampirehook)); bool autocvar_g_vampirehook_teamheal; float autocvar_g_vampirehook_damage; diff --git a/qcsrc/common/mutators/mutator/walljump/walljump.qc b/qcsrc/common/mutators/mutator/walljump/walljump.qc index b0d95ea29..c462a7e2b 100644 --- a/qcsrc/common/mutators/mutator/walljump/walljump.qc +++ b/qcsrc/common/mutators/mutator/walljump/walljump.qc @@ -4,7 +4,7 @@ #ifdef CSQC REGISTER_MUTATOR(walljump, true); #elif defined(SVQC) -REGISTER_MUTATOR(walljump, cvar("g_walljump")); +REGISTER_MUTATOR(walljump, autocvar_g_walljump); #endif #define PHYS_WALLJUMP(s) STAT(WALLJUMP, s) diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh index f585a9a2c..fa8cee717 100644 --- a/qcsrc/server/autocvars.qh +++ b/qcsrc/server/autocvars.qh @@ -165,12 +165,7 @@ int autocvar_g_maxplayers; float autocvar_g_maxplayers_spectator_blocktime; float autocvar_g_maxpushtime; float autocvar_g_maxspeed; -#define autocvar_g_instagib cvar("g_instagib") -bool autocvar_g_instagib_damagedbycontents = true; -bool autocvar_g_instagib_blaster_keepdamage = false; -bool autocvar_g_instagib_blaster_keepforce = false; -bool autocvar_g_instagib_mirrordamage; -bool autocvar_g_instagib_friendlypush = true; +bool autocvar_g_instagib; #define autocvar_g_mirrordamage cvar("g_mirrordamage") #define autocvar_g_mirrordamage_virtual cvar("g_mirrordamage_virtual") bool autocvar_g_mirrordamage_onlyweapons; @@ -416,7 +411,6 @@ float autocvar_g_monsters_armor_blockpercent; float autocvar_g_monsters_healthbars; bool autocvar_g_monsters_lineofsight = true; //bool autocvar_g_monsters_ignoretraces = true; -#define autocvar_g_bloodloss cvar("g_bloodloss") bool autocvar_g_nades; bool autocvar_g_nades_override_dropweapon = true; vector autocvar_g_nades_throw_offset; diff --git a/qcsrc/server/resources.qc b/qcsrc/server/resources.qc index 7677c6c2c..edf4ff162 100644 --- a/qcsrc/server/resources.qc +++ b/qcsrc/server/resources.qc @@ -1,10 +1,9 @@ +#include "resources.qh" /// \file /// \brief Source file that contains implementation of the resource system. /// \author Lyberta /// \copyright GNU GPLv2 or any later version. -#include "resources.qh" - #include "autocvars.qh" #include "miscfunctions.qh" diff --git a/qcsrc/server/resources.qh b/qcsrc/server/resources.qh index 3189fde95..ce8e1e8e5 100644 --- a/qcsrc/server/resources.qh +++ b/qcsrc/server/resources.qh @@ -1,10 +1,9 @@ +#pragma once /// \file /// \brief Header file that describes the resource system. /// \author Lyberta /// \copyright GNU GPLv2 or any later version. -#pragma once - /// \brief Unconditional maximum amount of resources the entity can have. const int RESOURCE_AMOUNT_HARD_LIMIT = 999; diff --git a/qcsrc/server/sv_main.qc b/qcsrc/server/sv_main.qc index 87430a93e..68e7b375b 100644 --- a/qcsrc/server/sv_main.qc +++ b/qcsrc/server/sv_main.qc @@ -247,6 +247,77 @@ void StartFrame() .string gametypefilter; .string cvarfilter; bool DoesQ3ARemoveThisEntity(entity this); + +/** + * Evaluate an expression of the form: [+ | -]? [var[op]val | [op]var | val | var] ... + * +: all must match. this is the default + * -: one must NOT match + * + * var>x + * var=x + * var<=x + * var==x + * var!=x + * var===x + * var!==x + */ +bool expr_evaluate(string s) +{ + bool ret = false; + if (str2chr(s, 0) == '+') { + s = substring(s, 1, -1); + } else if (str2chr(s, 0) == '-') { + ret = true; + s = substring(s, 1, -1); + } + bool expr_fail = false; + for (int i = 0, n = tokenize_console(s); i < n; ++i) { + int o; + string k, v; + s = argv(i); + #define X(expr) \ + if (expr) { \ + continue; \ + } else { \ + expr_fail = true; \ + break; \ + } + #define BINOP(op, len, expr) \ + if ((o = strstrofs(s, op, 0)) >= 0) { \ + k = substring(s, 0, o); \ + v = substring(s, o + len, -1); \ + X(expr); \ + } + BINOP(">=", 2, cvar(k) >= stof(v)); + BINOP("<=", 2, cvar(k) <= stof(v)); + BINOP(">", 1, cvar(k) > stof(v)); + BINOP("<", 1, cvar(k) < stof(v)); + BINOP("==", 2, cvar(k) == stof(v)); + BINOP("!=", 2, cvar(k) != stof(v)); + BINOP("===", 3, cvar_string(k) == v); + BINOP("!==", 3, cvar_string(k) != v); + { + k = s; + bool b = true; + if (str2chr(k, 0) == '!') { + k = substring(s, 1, -1); + b = false; + } + float f = stof(k); + bool isnum = ftos(f) == k; + X(boolean(isnum ? f : cvar(k)) == b); + } + #undef BINOP + #undef X + } + if (!expr_fail) { + ret = !ret; + } + // now ret is true if we want to keep the item, and false if we want to get rid of it + return ret; +} + void SV_OnEntityPreSpawnFunction(entity this) { __spawnfunc_expecting = true; @@ -257,65 +328,8 @@ void SV_OnEntityPreSpawnFunction(entity this) { goto cleanup; } - if (this.cvarfilter != "") { - bool inv = false; - - string s = this.cvarfilter; - if (str2chr(s, 0) == '+') { - s = substring(s, 1, -1); - } else if(str2chr(s, 0) == '-') { - inv = true; - s = substring(s, 1, -1); - } - - bool cvar_fail = false; - for (int i = 0, n = tokenize_console(s); i < n; ++i) { - int o; - string k, v; - s = argv(i); - // syntax: - // var>x - // var=x - // var<=x - // var==x - // var!=x - // var===x - // var!==x - #define X(expr) \ - if (expr) { \ - continue; \ - } else { \ - cvar_fail = true; \ - break; \ - } - #define BINOP(op, len, expr) \ - if ((o = strstrofs(s, op, 0)) >= 0) { \ - k = substring(s, 0, o); \ - v = substring(s, o + len, -1); \ - X(expr); \ - } - BINOP(">=", 2, cvar(k) >= stof(v)); - BINOP("<=", 2, cvar(k) <= stof(v)); - BINOP(">", 1, cvar(k) > stof(v)); - BINOP("<", 1, cvar(k) < stof(v)); - BINOP("==", 2, cvar(k) == stof(v)); - BINOP("!=", 2, cvar(k) != stof(v)); - // fixme: did these two ever work? - BINOP("===", 2, cvar_string(k) == v); - BINOP("!==", 2, cvar_string(k) != v); - if (str2chr(s, 0) == '!') { k = substring(s, 1, -1); X(!cvar(k)); } - { k = s; X(cvar(k)); } - #undef BINOP - #undef X - } - if (!cvar_fail) { - inv = !inv; - } - // now inv is true if we want to keep the item, and false if we want to get rid of it - if (!inv) { - goto cleanup; - } + if (this.cvarfilter != "" && !expr_evaluate(this.cvarfilter)) { + goto cleanup; } if (DoesQ3ARemoveThisEntity(this)) { diff --git a/qcsrc/server/sv_main.qh b/qcsrc/server/sv_main.qh index 6f70f09be..7f86d19c0 100644 --- a/qcsrc/server/sv_main.qh +++ b/qcsrc/server/sv_main.qh @@ -1 +1,3 @@ #pragma once + +bool expr_evaluate(string s); -- 2.39.2