4 // copies a string to a tempstring (so one can strunzone it)
5 string strcat1(string s) = #115; // FRIK_FILE
9 const int REPLICATEVARS_SEND_ALL = -1; // sync all cvars with the server (init)
10 const int REPLICATEVARS_CHECK = 0; // check if any cvar has changed and sync it with the server
11 const int REPLICATEVARS_DESTROY = 1; // destroy data associated with cvars (shutdown)
12 #define REPLICATE_INIT(type, name) type name
14 #define REPLICATE_INIT(type, name) .type name
20 * \def REPLICATE(fld, type, cvar)
21 * Replicates a client cvar into a server field
23 * @param fld The field to replicate into
24 * @param type The field type
26 * @param fixup_func((entity this, string original_value)) optional parameter
28 #define REPLICATE(...) EVAL_REPLICATE(OVERLOAD(REPLICATE, __VA_ARGS__))
29 #define EVAL_REPLICATE(...) __VA_ARGS__
32 ACCUMULATE void ReplicateVars(entity this, entity store, string thisname, int i) {}
33 ACCUMULATE void ReplicateVars_ApplyChange(entity this, entity store, string thisname, int i) {}
35 * \def REPLICATE_APPLYCHANGE(cvarname, ApplyChange_code)
36 * Allows setting code that will be executed on cvar value changes
39 * @param ApplyChange_code code meant to be run on cvar value changes
41 #define REPLICATE_APPLYCHANGE(var, ApplyChange_code) \
42 void ReplicateVars_ApplyChange(entity this, entity store, string thisname, int i) \
43 { if (thisname == var) { ApplyChange_code } }
45 noref float ReplicateVars_time;
46 ACCUMULATE void ReplicateVars(int mode)
48 if (!ReplicateVars_time || time < ReplicateVars_time)
50 ReplicateVars_time = time + 0.8 + random() * 0.4; // check cvars periodically
52 void ReplicateVars_Start()
54 if (!ReplicateVars_time) // make sure it gets executed only once
56 ReplicateVars_time = time;
57 ReplicateVars(REPLICATEVARS_SEND_ALL);
62 #define REPLICATE_3(fld, type, var) REPLICATE_4(fld, type, var, )
63 #define REPLICATE_4(fld, type, var, func) REPLICATE_##type(fld, var, func)
65 #define REPLICATE_string(fld, var, func) \
66 REPLICATE_7(fld, string, var, , \
67 { strcpy(field, it); }, \
68 { strfree(field); }, \
70 /* also initialize to the default value of func when requesting cvars */ \
71 string s = func(this, strcat1(field)); \
77 #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func, { field = stof(it); }, , )
78 #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func, { field = boolean(stoi(it)); }, , )
79 #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func, { field = stoi(it); }, , )
81 #define REPLICATE_7(fld, type, var, func, create, destroy, after) \
82 void ReplicateVars(entity this, entity store, string thisname, int i) \
84 type field = store.fld; \
85 if (i < 0) { destroy } \
88 string it = func(argv(i + 1)); \
89 bool current = thisname == var; \
92 if (current) { create } \
96 stuffcmd(this, strcat("cl_cmd sendcvar ", var, "\n")); \
98 if (current) { after } \
103 #define REPLICATE_string(fld, var, func) REPLICATE_7(fld, float, var, func, (fld != cvar_string(var)), { strcpy(fld, cvar_string(var)); }, { strfree(fld); })
104 #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
105 #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
106 #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
108 void ReplicateVars_Send(string cvarname) { localcmd(strcat("cl_cmd sendcvar ", cvarname, "\n")); }
110 #define REPLICATE_7(fld, type, var, func, check, update, destroy) \
111 void ReplicateVars(int mode) \
113 if (mode == REPLICATEVARS_DESTROY) { destroy } \
114 else if (mode == REPLICATEVARS_SEND_ALL || check) \
116 ReplicateVars_Send(var); \
121 #define REPLICATE_SIMPLE(field, cvarname) MACRO_BEGIN \
122 float thecvar = cvar(cvarname); \
123 if(field != thecvar) \
125 ReplicateVars_Send(cvarname); \