From 596322f78ac249a88835a5f3c976e03ae232d97c Mon Sep 17 00:00:00 2001 From: terencehill Date: Sun, 18 Aug 2019 18:18:58 +0200 Subject: [PATCH] Automatically send cvar values (when changed) to the server for settings that need a sendcvar call so that they can be applied instantly, e.g. cl_casings --- qcsrc/client/defs.qh | 72 +++++++++++++++++++ qcsrc/client/main.qc | 2 + qcsrc/client/view.qc | 12 ++++ qcsrc/common/effects/qc/casings.qc | 7 +- .../common/mutators/mutator/buffs/cl_buffs.qh | 3 + .../common/mutators/mutator/dodging/_mod.inc | 3 + qcsrc/common/mutators/mutator/dodging/_mod.qh | 3 + .../mutators/mutator/dodging/cl_dodging.qc | 1 + .../mutators/mutator/dodging/cl_dodging.qh | 4 ++ .../mutators/mutator/dodging/sv_dodging.qc | 4 +- .../mutators/mutator/multijump/multijump.qc | 5 +- qcsrc/common/mutators/mutator/nades/nades.qc | 6 +- qcsrc/common/mutators/mutator/nades/nades.qh | 2 + .../mutator/spawn_near_teammate/_mod.inc | 3 + .../mutator/spawn_near_teammate/_mod.qh | 3 + .../cl_spawn_near_teammate.qc | 1 + .../cl_spawn_near_teammate.qh | 4 ++ qcsrc/common/stats.qh | 2 +- qcsrc/common/weapons/all.qh | 7 ++ qcsrc/lib/replicate.qh | 61 +++++++++++----- 20 files changed, 177 insertions(+), 28 deletions(-) create mode 100644 qcsrc/common/mutators/mutator/dodging/cl_dodging.qc create mode 100644 qcsrc/common/mutators/mutator/dodging/cl_dodging.qh create mode 100644 qcsrc/common/mutators/mutator/spawn_near_teammate/cl_spawn_near_teammate.qc create mode 100644 qcsrc/common/mutators/mutator/spawn_near_teammate/cl_spawn_near_teammate.qh diff --git a/qcsrc/client/defs.qh b/qcsrc/client/defs.qh index 1fa2fd42be..23760d74e1 100644 --- a/qcsrc/client/defs.qh +++ b/qcsrc/client/defs.qh @@ -109,6 +109,78 @@ int w_deathtype; float w_issilent, w_random; vector w_org, w_backoff; +float autoswitch; +bool cvar_cl_allow_uid2name; +float cvar_cl_autoscreenshot; +float cvar_cl_autotaunt; +float cvar_cl_clippedspectating; +float cvar_cl_handicap; +float cvar_cl_jetpack_jump; +float cvar_cl_movement_track_canjump; +float cvar_cl_noantilag; +string cvar_cl_physics; +float cvar_cl_voice_directional; +float cvar_cl_voice_directional_taunt_attenuation; +float cvar_cl_weaponimpulsemode; +string cvar_g_xonoticversion; +float cvar_cl_cts_noautoswitch; +bool cvar_cl_weapon_switch_reload; +bool cvar_cl_weapon_switch_fallback_to_impulse; + +REPLICATE(autoswitch, bool, "cl_autoswitch"); +REPLICATE(cvar_cl_allow_uid2name, bool, "cl_allow_uid2name"); +REPLICATE(cvar_cl_autoscreenshot, int, "cl_autoscreenshot"); +REPLICATE(cvar_cl_autotaunt, float, "cl_autotaunt"); +REPLICATE(cvar_cl_clippedspectating, bool, "cl_clippedspectating"); +REPLICATE(cvar_cl_handicap, float, "cl_handicap"); +REPLICATE(cvar_cl_jetpack_jump, bool, "cl_jetpack_jump"); +REPLICATE(cvar_cl_movement_track_canjump, bool, "cl_movement_track_canjump"); +REPLICATE(cvar_cl_noantilag, bool, "cl_noantilag"); +REPLICATE(cvar_cl_physics, string, "cl_physics"); +REPLICATE(cvar_cl_voice_directional, int, "cl_voice_directional"); +REPLICATE(cvar_cl_voice_directional_taunt_attenuation, float, "cl_voice_directional_taunt_attenuation"); +REPLICATE(cvar_cl_weaponimpulsemode, int, "cl_weaponimpulsemode"); +REPLICATE(cvar_g_xonoticversion, string, "g_xonoticversion"); +REPLICATE(cvar_cl_cts_noautoswitch, bool, "cl_cts_noautoswitch"); +REPLICATE(cvar_cl_weapon_switch_reload, bool, "cl_weapon_switch_reload"); +REPLICATE(cvar_cl_weapon_switch_fallback_to_impulse, bool, "cl_weapon_switch_fallback_to_impulse"); +/* +// this is also a STAT +// pointless sending this cvars since server can't change gun alignment during the match +int cvar_cl_gunalign; +REPLICATE(cvar_cl_gunalign, int, "cl_gunalign"); + +// cvar cl_newusekeysupported doesn't exist +float cvar_cl_newusekeysupported; +REPLICATE(cvar_cl_newusekeysupported, bool, "cl_newusekeysupported"); +*/ +string cvar_cl_allow_uidtracking; +REPLICATE(cvar_cl_allow_uidtracking, string, "cl_allow_uidtracking"); + +string cvar_cl_weaponpriority; +REPLICATE(cvar_cl_weaponpriority, string, "cl_weaponpriority"); + +string cvar_cl_weaponpriorities[10]; +REPLICATE(cvar_cl_weaponpriorities[0], string, "cl_weaponpriority0"); +REPLICATE(cvar_cl_weaponpriorities[1], string, "cl_weaponpriority1"); +REPLICATE(cvar_cl_weaponpriorities[2], string, "cl_weaponpriority2"); +REPLICATE(cvar_cl_weaponpriorities[3], string, "cl_weaponpriority3"); +REPLICATE(cvar_cl_weaponpriorities[4], string, "cl_weaponpriority4"); +REPLICATE(cvar_cl_weaponpriorities[5], string, "cl_weaponpriority5"); +REPLICATE(cvar_cl_weaponpriorities[6], string, "cl_weaponpriority6"); +REPLICATE(cvar_cl_weaponpriorities[7], string, "cl_weaponpriority7"); +REPLICATE(cvar_cl_weaponpriorities[8], string, "cl_weaponpriority8"); +REPLICATE(cvar_cl_weaponpriorities[9], string, "cl_weaponpriority9"); + +.int cvar_value; +void ReplicateVars(bool would_destroy) +{ + FOREACH(Notifications, it.nent_type == MSG_CHOICE, { + string cvarname = sprintf("notification_%s", Get_Notif_CvarName(it)); + REPLICATE_SIMPLE(it.cvar_value, cvarname); + }); +} + float bgmtime; string weaponorder_byimpulse; diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index 04cafebbd3..c8274fe626 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -230,6 +230,8 @@ void Shutdown() deactivate_minigame(); HUD_MinigameMenu_Close(NULL, NULL, NULL); + + ReplicateVars(true); // destroy } .float has_team; diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 7c3c1068b1..a7449494f6 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -1541,6 +1541,7 @@ float oldr_useinfinitefarclip; float prev_myteam; int lasthud; float vh_notice_time; +float ReplicateVars_time; void CSQC_UpdateView(entity this, float w, float h) { TC(int, w); TC(int, h); @@ -1562,6 +1563,17 @@ void CSQC_UpdateView(entity this, float w, float h) lasthud = hud; + // TODO maybe don't send cvar values until the menu is open + // TODO remove CheckSendCvars from menu code (it seems broken anyway) + // TODO remove references to sendcvar from cvar descriptions + // TODO stop server from requesting cvar values to the client on connection as it's no longer necessary + + if (time > ReplicateVars_time) // prevents network spam + { + ReplicateVars(false); + ReplicateVars_time = time + 0.8 + random() * 0.4; + } + HUD_Scale_Disable(); if(autocvar__hud_showbinds_reload) // menu can set this one diff --git a/qcsrc/common/effects/qc/casings.qc b/qcsrc/common/effects/qc/casings.qc index 304552961c..589e343c8d 100644 --- a/qcsrc/common/effects/qc/casings.qc +++ b/qcsrc/common/effects/qc/casings.qc @@ -9,11 +9,14 @@ REGISTER_NET_TEMP(casings) -#ifdef SVQC - +#if defined(SVQC) .bool cvar_cl_casings; +#elif defined(CSQC) +bool cvar_cl_casings; +#endif REPLICATE(cvar_cl_casings, bool, "cl_casings"); +#ifdef SVQC void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner, .entity weaponentity) { if (!(CS(casingowner).cvar_cl_casings)) diff --git a/qcsrc/common/mutators/mutator/buffs/cl_buffs.qh b/qcsrc/common/mutators/mutator/buffs/cl_buffs.qh index c93902291d..c9dbe5add1 100644 --- a/qcsrc/common/mutators/mutator/buffs/cl_buffs.qh +++ b/qcsrc/common/mutators/mutator/buffs/cl_buffs.qh @@ -1,3 +1,6 @@ #pragma once #include "buffs.qh" + +float cvar_cl_buffs_autoreplace; +REPLICATE(cvar_cl_buffs_autoreplace, bool, "cl_buffs_autoreplace"); diff --git a/qcsrc/common/mutators/mutator/dodging/_mod.inc b/qcsrc/common/mutators/mutator/dodging/_mod.inc index 80a7828a70..99b822d42a 100644 --- a/qcsrc/common/mutators/mutator/dodging/_mod.inc +++ b/qcsrc/common/mutators/mutator/dodging/_mod.inc @@ -1,4 +1,7 @@ // generated file; do not modify +#ifdef CSQC + #include +#endif #ifdef SVQC #include #endif diff --git a/qcsrc/common/mutators/mutator/dodging/_mod.qh b/qcsrc/common/mutators/mutator/dodging/_mod.qh index fef7b8e6e4..d2c0d05c7a 100644 --- a/qcsrc/common/mutators/mutator/dodging/_mod.qh +++ b/qcsrc/common/mutators/mutator/dodging/_mod.qh @@ -1,4 +1,7 @@ // generated file; do not modify +#ifdef CSQC + #include +#endif #ifdef SVQC #include #endif diff --git a/qcsrc/common/mutators/mutator/dodging/cl_dodging.qc b/qcsrc/common/mutators/mutator/dodging/cl_dodging.qc new file mode 100644 index 0000000000..a9d10efa70 --- /dev/null +++ b/qcsrc/common/mutators/mutator/dodging/cl_dodging.qc @@ -0,0 +1 @@ +#include "cl_dodging.qh" diff --git a/qcsrc/common/mutators/mutator/dodging/cl_dodging.qh b/qcsrc/common/mutators/mutator/dodging/cl_dodging.qh new file mode 100644 index 0000000000..84f77314ed --- /dev/null +++ b/qcsrc/common/mutators/mutator/dodging/cl_dodging.qh @@ -0,0 +1,4 @@ +#pragma once + +float cvar_cl_dodging_timeout; +REPLICATE(cvar_cl_dodging_timeout, float, "cl_dodging_timeout"); diff --git a/qcsrc/common/mutators/mutator/dodging/sv_dodging.qc b/qcsrc/common/mutators/mutator/dodging/sv_dodging.qc index 6640cb8bf2..c97308d58a 100644 --- a/qcsrc/common/mutators/mutator/dodging/sv_dodging.qc +++ b/qcsrc/common/mutators/mutator/dodging/sv_dodging.qc @@ -40,10 +40,12 @@ #endif #ifdef CSQC + float cvar_cl_dodging_timeout; #define PHYS_DODGING_FRAMETIME (1 / (frametime <= 0 ? 60 : frametime)) #define PHYS_DODGING_TIMEOUT(s) STAT(DODGING_TIMEOUT) #define PHYS_DODGING_PRESSED_KEYS(s) (s).pressedkeys #elif defined(SVQC) + .float cvar_cl_dodging_timeout; #define PHYS_DODGING_FRAMETIME sys_frametime #define PHYS_DODGING_TIMEOUT(s) CS(s).cvar_cl_dodging_timeout #define PHYS_DODGING_PRESSED_KEYS(s) CS(s).pressedkeys @@ -56,8 +58,6 @@ bool autocvar_sv_dodging_sound; #include #include -.float cvar_cl_dodging_timeout; - REGISTER_MUTATOR(dodging, cvar("g_dodging")) { // this just turns on the cvar. diff --git a/qcsrc/common/mutators/mutator/multijump/multijump.qc b/qcsrc/common/mutators/mutator/multijump/multijump.qc index 081a1fdb6f..0efd85635c 100644 --- a/qcsrc/common/mutators/mutator/multijump/multijump.qc +++ b/qcsrc/common/mutators/mutator/multijump/multijump.qc @@ -24,6 +24,7 @@ REGISTER_MUTATOR(multijump, true); .bool multijump_ready; #ifdef CSQC +bool cvar_cl_multijump; bool autocvar_cl_multijump = true; #define PHYS_MULTIJUMP_CLIENT(s) autocvar_cl_multijump @@ -114,10 +115,10 @@ MUTATOR_HOOKFUNCTION(multijump, PlayerJump) } } -#ifdef SVQC - REPLICATE(cvar_cl_multijump, bool, "cl_multijump"); +#ifdef SVQC + MUTATOR_HOOKFUNCTION(multijump, BuildMutatorsString) { M_ARGV(0, string) = strcat(M_ARGV(0, string), ":multijump"); diff --git a/qcsrc/common/mutators/mutator/nades/nades.qc b/qcsrc/common/mutators/mutator/nades/nades.qc index 8dc82dbcf9..d48319a421 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qc +++ b/qcsrc/common/mutators/mutator/nades/nades.qc @@ -10,6 +10,9 @@ float autocvar_g_nades_spread = 0.04; REGISTER_STAT(NADES_SMALL, int, autocvar_g_nades_nade_small) #ifdef GAMEQC +REPLICATE(cvar_cl_nade_type, int, "cl_nade_type"); +REPLICATE(cvar_cl_pokenade_type, string, "cl_pokenade_type"); + entity Nade_TrailEffect(int proj, int nade_team) { switch (proj) @@ -1546,9 +1549,6 @@ MUTATOR_HOOKFUNCTION(nades, SpectateCopy) STAT(VEIL_ORB_ALPHA, client) = STAT(VEIL_ORB_ALPHA, spectatee); } -REPLICATE(cvar_cl_nade_type, int, "cl_nade_type"); -REPLICATE(cvar_cl_pokenade_type, string, "cl_pokenade_type"); - MUTATOR_HOOKFUNCTION(nades, BuildMutatorsString) { M_ARGV(0, string) = strcat(M_ARGV(0, string), ":Nades"); diff --git a/qcsrc/common/mutators/mutator/nades/nades.qh b/qcsrc/common/mutators/mutator/nades/nades.qh index 2729316a88..d76eb94145 100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qh +++ b/qcsrc/common/mutators/mutator/nades/nades.qh @@ -101,6 +101,8 @@ MUTATOR_HOOKABLE(Nade_Damage, EV_Nade_Damage); #endif #ifdef CSQC +float cvar_cl_nade_type; +string cvar_cl_pokenade_type; bool Projectile_isnade(int proj); // TODO: remove void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expand_time); // TODO: mutator diff --git a/qcsrc/common/mutators/mutator/spawn_near_teammate/_mod.inc b/qcsrc/common/mutators/mutator/spawn_near_teammate/_mod.inc index fe3a6ebc5d..46496895af 100644 --- a/qcsrc/common/mutators/mutator/spawn_near_teammate/_mod.inc +++ b/qcsrc/common/mutators/mutator/spawn_near_teammate/_mod.inc @@ -1,4 +1,7 @@ // generated file; do not modify +#ifdef CSQC + #include +#endif #ifdef SVQC #include #endif diff --git a/qcsrc/common/mutators/mutator/spawn_near_teammate/_mod.qh b/qcsrc/common/mutators/mutator/spawn_near_teammate/_mod.qh index b34f8f8f16..c4cfe5ada9 100644 --- a/qcsrc/common/mutators/mutator/spawn_near_teammate/_mod.qh +++ b/qcsrc/common/mutators/mutator/spawn_near_teammate/_mod.qh @@ -1,4 +1,7 @@ // generated file; do not modify +#ifdef CSQC + #include +#endif #ifdef SVQC #include #endif diff --git a/qcsrc/common/mutators/mutator/spawn_near_teammate/cl_spawn_near_teammate.qc b/qcsrc/common/mutators/mutator/spawn_near_teammate/cl_spawn_near_teammate.qc new file mode 100644 index 0000000000..11774cae3a --- /dev/null +++ b/qcsrc/common/mutators/mutator/spawn_near_teammate/cl_spawn_near_teammate.qc @@ -0,0 +1 @@ +#include "cl_spawn_near_teammate.qh" diff --git a/qcsrc/common/mutators/mutator/spawn_near_teammate/cl_spawn_near_teammate.qh b/qcsrc/common/mutators/mutator/spawn_near_teammate/cl_spawn_near_teammate.qh new file mode 100644 index 0000000000..640a7255f1 --- /dev/null +++ b/qcsrc/common/mutators/mutator/spawn_near_teammate/cl_spawn_near_teammate.qh @@ -0,0 +1,4 @@ +#pragma once + +float cvar_cl_spawn_near_teammate; +REPLICATE(cvar_cl_spawn_near_teammate, bool, "cl_spawn_near_teammate"); diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index cf51ea66b3..e35115d3e5 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -376,8 +376,8 @@ noref int autocvar_cl_gunalign; #endif #ifdef SVQC .int cvar_cl_gunalign; -REPLICATE(cvar_cl_gunalign, int, "cl_gunalign"); #endif + REGISTER_STAT(GUNALIGN, int) #ifdef SVQC SPECTATE_COPYFIELD(_STAT(GUNALIGN)) diff --git a/qcsrc/common/weapons/all.qh b/qcsrc/common/weapons/all.qh index 43398e6a5d..0be413f0fb 100644 --- a/qcsrc/common/weapons/all.qh +++ b/qcsrc/common/weapons/all.qh @@ -384,6 +384,13 @@ ENUMCLASS_END(WFRAME) vector shotorg_adjust_values(vector vecs, bool y_is_right, bool visual, int algn); void CL_WeaponEntity_SetModel(entity this, string name, bool _anim); +#ifdef CSQC +bool cvar_cl_accuracy_data_share; +REPLICATE(cvar_cl_accuracy_data_share, bool, "cl_accuracy_data_share"); +bool cvar_cl_accuracy_data_receive; +REPLICATE(cvar_cl_accuracy_data_receive, bool, "cl_accuracy_data_receive"); +#endif + #ifdef SVQC void wframe_send(entity actor, entity weaponentity, vector a, bool restartanim); #endif diff --git a/qcsrc/lib/replicate.qh b/qcsrc/lib/replicate.qh index 6569897826..6b1dc20ff2 100644 --- a/qcsrc/lib/replicate.qh +++ b/qcsrc/lib/replicate.qh @@ -12,27 +12,31 @@ #define REPLICATE(...) EVAL_REPLICATE(OVERLOAD(REPLICATE, __VA_ARGS__)) #define EVAL_REPLICATE(...) __VA_ARGS__ + #if defined(SVQC) ACCUMULATE void ReplicateVars(entity this, entity store, string thisname, int i) {} + #elif defined(CSQC) + ACCUMULATE void ReplicateVars(bool would_destroy) {} + #endif #define REPLICATE_3(fld, type, var) REPLICATE_4(fld, type, var, ) #define REPLICATE_4(fld, type, var, func) REPLICATE_##type(fld, var, func) - #define REPLICATE_string(fld, var, func) \ - REPLICATE_7(fld, string, var, , \ - { strcpy(field, it); }, \ - { strfree(field); }, \ - { \ - /* also initialize to the default value of func when requesting cvars */ \ - string s = func(field); \ - if (s != field) \ + #if defined(SVQC) + #define REPLICATE_string(fld, var, func) \ + REPLICATE_7(fld, string, var, , \ + { strcpy(field, it); }, \ + { strfree(field); }, \ { \ - strcpy(field, s); \ - } \ - }) - #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func, { field = stof(it); }, , ) - #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func, { field = boolean(stoi(it)); }, , ) - #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func, { field = stoi(it); }, , ) + /* also initialize to the default value of func when requesting cvars */ \ + string s = func(field); \ + if (s != field) \ + { \ + strcpy(field, s); \ + } \ + }) + #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func, { field = stof(it); }, , ) + #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func, { field = boolean(stoi(it)); }, , ) + #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func, { field = stoi(it); }, , ) - #if defined(SVQC) #define REPLICATE_7(fld, type, var, func, create, destroy, after) \ void ReplicateVars(entity this, entity store, string thisname, int i) \ { \ @@ -48,15 +52,36 @@ } \ else \ { \ - stuffcmd(this, "cl_cmd sendcvar " var "\n"); \ + stuffcmd(this, strcat("cl_cmd sendcvar ", var, "\n")); \ } \ if (current) { after } \ } \ store.fld = field; \ } #elif defined(CSQC) - // TODO - #define REPLICATE_7(fld, type, var, func, create, destroy, after) + #define REPLICATE_string(fld, var, func) REPLICATE_7(fld, float, var, func, (fld != cvar_string(var)), { strcpy(fld, cvar_string(var)); }, { strfree(fld); }) + #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func, (fld != cvar(var)), { fld = cvar(var); }, ) + #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func, (fld != cvar(var)), { fld = cvar(var); }, ) + #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func, (fld != cvar(var)), { fld = cvar(var); }, ) + + #define REPLICATE_7(fld, type, var, func, check, update, destroy) \ + void ReplicateVars(bool would_destroy) \ + { \ + if (would_destroy > 0) { destroy } \ + else if (check) \ + { \ + localcmd(strcat("cl_cmd sendcvar ", var, "\n")); \ + update \ + } \ + } + + #define REPLICATE_SIMPLE(field, cvarname) MACRO_BEGIN \ + if (field != cvar(cvarname)) \ + { \ + localcmd(strcat("cl_cmd sendcvar ", cvarname, "\n")); \ + field = cvar(cvarname); \ + } \ + MACRO_END #endif #endif -- 2.39.2