X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Flib%2Freplicate.qh;h=675d743c1892826940c6a8cb6b5b5924629289ce;hb=90b21340c6f5678a7b0ea3dda116ec7f4fa4352e;hp=019194a6d55df61e608e4fe9d6c126fb73ed08ad;hpb=ac7deb97b1a0e73ceea4684be73e72912fb3f1aa;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/lib/replicate.qh b/qcsrc/lib/replicate.qh index 019194a6d..675d743c1 100644 --- a/qcsrc/lib/replicate.qh +++ b/qcsrc/lib/replicate.qh @@ -1,21 +1,62 @@ #pragma once +#ifdef SVQC +// copies a string to a tempstring (so one can strunzone it) +string strcat1(string s) = #115; // FRIK_FILE +#endif + +#if defined(CSQC) +const int REPLICATEVARS_SEND_ALL = -1; // sync all cvars with the server (init) +const int REPLICATEVARS_CHECK = 0; // check if any cvar has changed and sync it with the server +const int REPLICATEVARS_DESTROY = 1; // destroy data associated with cvars (shutdown) +#define REPLICATE_INIT(type, name) type name +#elif defined(SVQC) +#define REPLICATE_INIT(type, name) .type name +#endif + #ifdef GAMEQC /** - * Replicate a client cvar into a server field + * \def REPLICATE(fld, type, cvar) + * Replicates a client cvar into a server field * * @param fld The field to replicate into * @param type The field type - * @param cvar The cvar name + * @param cvarname + * @param fixup_func((entity this, string original_value)) optional parameter */ #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) {} + ACCUMULATE void ReplicateVars_ApplyChange(entity this, entity store, string thisname, int i) {} + /** + * \def REPLICATE_APPLYCHANGE(cvarname, ApplyChange_code) + * Allows setting code that will be executed on cvar value changes + * + * @param cvarname + * @param ApplyChange_code code meant to be run on cvar value changes + */ + #define REPLICATE_APPLYCHANGE(var, ApplyChange_code) \ + void ReplicateVars_ApplyChange(entity this, entity store, string thisname, int i) \ + { if (thisname == var) { ApplyChange_code } } #elif defined(CSQC) - ACCUMULATE void ReplicateVars(bool would_destroy) {} + noref float ReplicateVars_time; + ACCUMULATE void ReplicateVars(int mode) + { + if (!ReplicateVars_time || time < ReplicateVars_time) + return; + ReplicateVars_time = time + 0.8 + random() * 0.4; // check cvars periodically + } + void ReplicateVars_Start() + { + if (!ReplicateVars_time) // make sure it gets executed only once + { + ReplicateVars_time = time; + ReplicateVars(REPLICATEVARS_SEND_ALL); + } + } #endif #define REPLICATE_3(fld, type, var) REPLICATE_4(fld, type, var, ) @@ -27,7 +68,7 @@ { strfree(field); }, \ { \ /* also initialize to the default value of func when requesting cvars */ \ - string s = func(field); \ + string s = func(this, strcat1(field)); \ if (s != field) \ { \ strcpy(field, s); \ @@ -59,39 +100,30 @@ store.fld = field; \ } #elif defined(CSQC) - noref float ReplicateVars_time; - #define ReplicateVars_NOT_SENDING() (time > ReplicateVars_time) - #define ReplicateVars_DELAY(t) ReplicateVars_time = time + t - #define ReplicateVars_DELAY_1FRAME() ReplicateVars_time = time #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); }, ) + void ReplicateVars_Send(string cvarname) { localcmd(strcat("cl_cmd sendcvar ", cvarname, "\n")); } + #define REPLICATE_7(fld, type, var, func, check, update, destroy) \ - void ReplicateVars(bool would_destroy) \ + void ReplicateVars(int mode) \ { \ - if (would_destroy) { destroy } \ - else if (ReplicateVars_NOT_SENDING() && check) \ + if (mode == REPLICATEVARS_DESTROY) { destroy } \ + else if (mode == REPLICATEVARS_SEND_ALL || check) \ { \ - localcmd(strcat("cl_cmd sendcvar ", var, "\n")); \ - ReplicateVars_DELAY_1FRAME(); \ + ReplicateVars_Send(var); \ update \ - return; \ } \ } #define REPLICATE_SIMPLE(field, cvarname) MACRO_BEGIN \ - if (ReplicateVars_NOT_SENDING()) \ + float thecvar = cvar(cvarname); \ + if(field != thecvar) \ { \ - float thecvar = cvar(cvarname); \ - if(field != thecvar) \ - { \ - localcmd(strcat("cl_cmd sendcvar ", cvarname, "\n")); \ - ReplicateVars_DELAY_1FRAME(); \ - field = thecvar; \ - return; \ - } \ + ReplicateVars_Send(cvarname); \ + field = thecvar; \ } \ MACRO_END #endif