]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/replicate.qh
Transifex autosync
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / replicate.qh
1 #pragma once
2
3 #if defined(CSQC)
4 const int REPLICATEVARS_SEND_ALL = -1; // sync all cvars with the server (init)
5 const int REPLICATEVARS_CHECK = 0; // check if any cvar has changed and sync it with the server
6 const int REPLICATEVARS_DESTROY = 1; // destroy data associated with cvars (shutdown)
7 #define REPLICATE_INIT(type, name) type name
8 #elif defined(SVQC)
9 #define REPLICATE_INIT(type, name) .type name
10 #endif
11
12 #ifdef GAMEQC
13
14     /**
15      * \def REPLICATE(fld, type, cvar)
16      * Replicates a client cvar into a server field
17      *
18      * @param fld   The field to replicate into
19      * @param type  The field type
20      * @param cvarname
21      * @param fixup_func((entity this, string original_value))  optional parameter
22      */
23         #define REPLICATE(...) EVAL_REPLICATE(OVERLOAD(REPLICATE, __VA_ARGS__))
24         #define EVAL_REPLICATE(...) __VA_ARGS__
25
26         #if defined(SVQC)
27         ACCUMULATE void ReplicateVars(entity this, entity store, string thisname, int i) {}
28         ACCUMULATE void ReplicateVars_ApplyChange(entity this, entity store, string thisname, int i) {}
29     /**
30      * \def REPLICATE_APPLYCHANGE(cvarname, ApplyChange_code)
31      * Allows setting code that will be executed on cvar value changes
32      *
33      * @param cvarname
34      * @param ApplyChange_code  code meant to be run on cvar value changes
35      */
36         #define REPLICATE_APPLYCHANGE(var, ApplyChange_code) \
37                 void ReplicateVars_ApplyChange(entity this, entity store, string thisname, int i) \
38                         { if (thisname == var) { ApplyChange_code } }
39         #elif defined(CSQC)
40         noref float ReplicateVars_time;
41         ACCUMULATE void ReplicateVars(int mode)
42         {
43                 if (!ReplicateVars_time || time < ReplicateVars_time)
44                         return;
45                 ReplicateVars_time = time + 0.8 + random() * 0.4; // check cvars periodically
46         }
47         void ReplicateVars_Start()
48         {
49                 if (!ReplicateVars_time) // make sure it gets executed only once
50                 {
51                         ReplicateVars_time = time;
52                         ReplicateVars(REPLICATEVARS_SEND_ALL);
53                 }
54         }
55         #endif
56
57         #define REPLICATE_3(fld, type, var) REPLICATE_4(fld, type, var, )
58         #define REPLICATE_4(fld, type, var, func) REPLICATE_##type(fld, var, func)
59         #if defined(SVQC)
60                 #define REPLICATE_string(fld, var, func) \
61                         REPLICATE_7(fld, string, var, , \
62                 { strcpy(field, it); }, \
63                 { strfree(field); }, \
64                 { \
65                         /* also initialize to the default value of func when requesting cvars */ \
66                         string s = func(this, strcat(field)); \
67                         if (s != field) \
68                         { \
69                                 strcpy(field, s); \
70                         } \
71                 })
72                 #define REPLICATE_vector(fld, var, func) REPLICATE_7(fld, vector, var, func, { field = stov(it); },          , )
73                 #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func,  { field = stof(it); },          , )
74                 #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func,   { field = boolean(stoi(it)); }, , )
75                 #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func,    { field = stoi(it); },          , )
76
77                 #define REPLICATE_7(fld, type, var, func, create, destroy, after) \
78                         void ReplicateVars(entity this, entity store, string thisname, int i) \
79                         { \
80                                 type field = store.fld; \
81                                 if (i < 0) { destroy } \
82                                 else \
83                                 { \
84                                         string it = func(argv(i + 1)); \
85                                         bool current = thisname == var; \
86                                         if (i > 0) \
87                                         { \
88                                                 if (current) { create } \
89                                         } \
90                                         else \
91                                         { \
92                                                 stuffcmd(this, strcat("cl_cmd sendcvar ", var, "\n")); \
93                                         } \
94                                         if (current) { after } \
95                                 } \
96                                 store.fld = field; \
97                         }
98         #elif defined(CSQC)
99                 #define REPLICATE_vector(fld, var, func) REPLICATE_7(fld, vector, var, func, (fld != stov(cvar_string(var))), { fld = stov(cvar_string(var)); }, )
100                 #define REPLICATE_string(fld, var, func) REPLICATE_7(fld, float, var, func, (fld != cvar_string(var)), { strcpy(fld, cvar_string(var)); }, { strfree(fld); })
101                 #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
102                 #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
103                 #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
104
105                 void ReplicateVars_Send(string cvarname) { localcmd(strcat("cl_cmd sendcvar ", cvarname, "\n")); }
106
107                 #define REPLICATE_7(fld, type, var, func, check, update, destroy) \
108                         void ReplicateVars(int mode) \
109                         { \
110                                 if (mode == REPLICATEVARS_DESTROY) { destroy } \
111                                 else if (mode == REPLICATEVARS_SEND_ALL || check) \
112                                 { \
113                                         ReplicateVars_Send(var); \
114                                         update \
115                                 } \
116                         }
117
118                 #define REPLICATE_SIMPLE(field, cvarname) MACRO_BEGIN \
119                         float thecvar = cvar(cvarname); \
120                         if(field != thecvar) \
121                         { \
122                                 ReplicateVars_Send(cvarname); \
123                                 field = thecvar; \
124                         } \
125                 MACRO_END
126         #endif
127
128 #endif