#pragma once
+#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)
+ 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, )
#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(this, strcat(field)); \
+ if (s != field) \
+ { \
+ strcpy(field, s); \
+ } \
+ })
+ #define REPLICATE_vector(fld, var, func) REPLICATE_7(fld, vector, var, func, { field = stov(it); }, , )
+ #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) \
{ \
} \
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_vector(fld, var, func) REPLICATE_7(fld, vector, var, func, (fld != stov(cvar_string(var))), { fld = stov(cvar_string(var)); }, )
+ #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(int mode) \
+ { \
+ if (mode == REPLICATEVARS_DESTROY) { destroy } \
+ else if (mode == REPLICATEVARS_SEND_ALL || check) \
+ { \
+ ReplicateVars_Send(var); \
+ update \
+ } \
+ }
+
+ #define REPLICATE_SIMPLE(field, cvarname) MACRO_BEGIN \
+ float thecvar = cvar(cvarname); \
+ if(field != thecvar) \
+ { \
+ ReplicateVars_Send(cvarname); \
+ field = thecvar; \
+ } \
+ MACRO_END
#endif
#endif