#pragma once #ifdef GAMEQC /** * Replicate a client cvar into a server field * * @param fld The field to replicate into * @param type The field type * @param cvar The cvar name */ #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) #if defined(SVQC) #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) \ { \ 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); }, , ) #define REPLICATE_7(fld, type, var, func, create, destroy, after) \ void ReplicateVars(entity this, entity store, string thisname, int i) \ { \ type field = store.fld; \ if (i < 0) { destroy } \ else \ { \ string it = func(argv(i + 1)); \ bool current = thisname == var; \ if (i > 0) \ { \ if (current) { create } \ } \ else \ { \ stuffcmd(this, strcat("cl_cmd sendcvar ", var, "\n")); \ } \ if (current) { after } \ } \ store.fld = field; \ } #elif defined(CSQC) 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); }, ) #define REPLICATE_7(fld, type, var, func, check, update, destroy) \ void ReplicateVars(bool would_destroy) \ { \ if (would_destroy) { destroy } \ else if (ReplicateVars_NOT_SENDING() && check) \ { \ localcmd(strcat("cl_cmd sendcvar ", var, "\n")); \ ReplicateVars_DELAY_1FRAME(); \ update \ return; \ } \ } #define REPLICATE_SIMPLE(field, cvarname) MACRO_BEGIN \ if (ReplicateVars_NOT_SENDING() && field != cvar(cvarname)) \ { \ localcmd(strcat("cl_cmd sendcvar ", cvarname, "\n")); \ ReplicateVars_DELAY_1FRAME(); \ field = cvar(cvarname); \ return; \ } \ MACRO_END #endif #endif