]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/replicate.qh
44a185d495d8235e99b9c8962fc6bd651cbd2752
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / replicate.qh
1 #pragma once
2
3
4 #if defined(CSQC)
5 #define REPLICATE_FIELD(type, name) type name
6 #elif defined(SVQC)
7 #define REPLICATE_FIELD(type, name) .type name
8 #endif
9
10 #ifdef GAMEQC
11
12     /**
13      * Replicate a client cvar into a server field
14      *
15      * @param fld   The field to replicate into
16      * @param type  The field type
17      * @param cvar  The cvar name
18      */
19         #define REPLICATE(...) EVAL_REPLICATE(OVERLOAD(REPLICATE, __VA_ARGS__))
20         #define EVAL_REPLICATE(...) __VA_ARGS__
21
22         #if defined(SVQC)
23         ACCUMULATE void ReplicateVars(entity this, entity store, string thisname, int i) {}
24         #elif defined(CSQC)
25         ACCUMULATE void ReplicateVars(int mode) {}
26         #endif
27
28         #define REPLICATE_3(fld, type, var) REPLICATE_4(fld, type, var, )
29         #define REPLICATE_4(fld, type, var, func) REPLICATE_##type(fld, var, func)
30         #if defined(SVQC)
31                 #define REPLICATE_string(fld, var, func) \
32                         REPLICATE_7(fld, string, var, , \
33                 { strcpy(field, it); }, \
34                 { strfree(field); }, \
35                 { \
36                         /* also initialize to the default value of func when requesting cvars */ \
37                         string s = func(field); \
38                         if (s != field) \
39                         { \
40                                 strcpy(field, s); \
41                         } \
42                 })
43                 #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func,  { field = stof(it); },          , )
44                 #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func,   { field = boolean(stoi(it)); }, , )
45                 #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func,    { field = stoi(it); },          , )
46
47                 #define REPLICATE_7(fld, type, var, func, create, destroy, after) \
48                         void ReplicateVars(entity this, entity store, string thisname, int i) \
49                         { \
50                                 type field = store.fld; \
51                                 if (i < 0) { destroy } \
52                                 else \
53                                 { \
54                                         string it = func(argv(i + 1)); \
55                                         bool current = thisname == var; \
56                                         if (i > 0) \
57                                         { \
58                                                 if (current) { create } \
59                                         } \
60                                         else \
61                                         { \
62                                                 stuffcmd(this, strcat("cl_cmd sendcvar ", var, "\n")); \
63                                         } \
64                                         if (current) { after } \
65                                 } \
66                                 store.fld = field; \
67                         }
68         #elif defined(CSQC)
69                 noref float ReplicateVars_time;
70                 #define ReplicateVars_NOT_SENDING() (time > ReplicateVars_time)
71                 #define ReplicateVars_DELAY(t) ReplicateVars_time = time + t
72                 #define ReplicateVars_DELAY_1FRAME() ReplicateVars_time = time
73                 #define REPLICATE_string(fld, var, func) REPLICATE_7(fld, float, var, func, (fld != cvar_string(var)), { strcpy(fld, cvar_string(var)); }, { strfree(fld); })
74                 #define REPLICATE_float(fld, var, func) REPLICATE_7(fld, float, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
75                 #define REPLICATE_bool(fld, var, func) REPLICATE_7(fld, bool, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
76                 #define REPLICATE_int(fld, var, func) REPLICATE_7(fld, int, var, func, (fld != cvar(var)), { fld = cvar(var); }, )
77
78                 void ReplicateVars_Destroy() { ReplicateVars(1); }
79                 void ReplicateVars_Send_All() { ReplicateVars(-1); }
80                 void ReplicateVars_Check()
81                 {
82                         // if a cvar has changed send it and check cvars again next frame
83                         ReplicateVars(0);
84                         if (ReplicateVars_NOT_SENDING()) // if no cvar has changed
85                                 ReplicateVars_DELAY(0.8 + random() * 0.4); // check cvars after a while
86                 }
87                 void ReplicateVars_Send(string cvarname) { localcmd(strcat("cl_cmd sendcvar ", cvarname, "\n")); }
88
89                 #define REPLICATE_7(fld, type, var, func, check, update, destroy) \
90                         void ReplicateVars(int mode) \
91                         { \
92                                 if (mode == 1) { destroy } \
93                                 else if (mode == -1) { ReplicateVars_Send(var); update } \
94                                 else if (ReplicateVars_NOT_SENDING() && check) \
95                                 { \
96                                         ReplicateVars_Send(var); \
97                                         ReplicateVars_DELAY_1FRAME(); \
98                                         update \
99                                         return; \
100                                 } \
101                         }
102
103                 #define REPLICATE_SIMPLE(field, cvarname) MACRO_BEGIN \
104                         if (ReplicateVars_NOT_SENDING()) \
105                         { \
106                                 float thecvar = cvar(cvarname); \
107                                 if(field != thecvar) \
108                                 { \
109                                         ReplicateVars_Send(cvarname); \
110                                         ReplicateVars_DELAY_1FRAME(); \
111                                         field = thecvar; \
112                                         return; \
113                                 } \
114                         } \
115                 MACRO_END
116         #endif
117
118 #endif