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