]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/stats.qh
929c5902e8335ddd0ada8a66675edf9ab0cbd05d
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / stats.qh
1 #ifndef LIB_STATS_H
2 #define LIB_STATS_H
3
4 // TODO: rename to 'netvars'
5
6 #include "registry.qh"
7 #include "sort.qh"
8
9 .int m_id;
10
11 #define REGISTER_STAT(...) EVAL(OVERLOAD(REGISTER_STAT, __VA_ARGS__))
12 #if defined(CSQC)
13         /** Get all stats and store them as globals, access with `STAT(ID)` */
14         void stats_get() {}
15         #define STAT(...) EVAL(OVERLOAD(STAT, __VA_ARGS__))
16     #define STAT_1(id) STAT_2(id, NULL)
17         #define STAT_2(id, cl) (0, _STAT(id))
18
19         #define getstat_int(id) getstati(id, 0, 24)
20         #define getstat_bool(id) boolean(getstati(id))
21         #define getstat_float(id) getstatf(id)
22
23         #define _STAT(id) g_stat_##id
24         #define REGISTER_STAT_2(id, type) \
25                 type _STAT(id); \
26                 REGISTER(RegisterStats, STAT, Stats, id, m_id, new(stat)) \
27                 { \
28                         make_pure(this); \
29                 } \
30                 [[accumulate]] void stats_get() \
31                 { \
32                         _STAT(id) = getstat_##type(STAT_##id.m_id); \
33                 }
34         #define REGISTER_STAT_3(x, T, expr) REGISTER_STAT(x, T)
35 #elif defined(SVQC)
36         /** Add all registered stats, access with `STAT(ID, player)` or `.type stat = _STAT(ID); player.stat` */
37         void stats_add() {}
38         #define STAT(id, cl) (cl._STAT(id))
39
40         #define addstat_int(id, fld) addstat(id, AS_INT, fld)
41         #define addstat_bool(id, fld) addstat(id, AS_INT, fld)
42         #define addstat_float(id, fld) addstat(id, AS_FLOAT, fld)
43         const int AS_STRING = 1;
44         const int AS_INT = 2;
45         const int AS_FLOAT = 8;
46
47         .int __stat_null;
48         /** Prevent engine stats being sent */
49         STATIC_INIT(stats_clear)
50         {
51                 int r = 32;
52                 for (int i = 0, n = 256 - r; i < n; ++i) {
53                         addstat(r + i, AS_INT, __stat_null);
54                 }
55         }
56
57         #define _STAT(id) stat_##id
58         #define REGISTER_STAT_2(id, type) \
59                 .type _STAT(id); \
60                 REGISTER(RegisterStats, STAT, Stats, id, m_id, new(stat)) \
61                 { \
62                         make_pure(this); \
63                 } \
64                 [[accumulate]] void stats_add() \
65                 { \
66                         addstat_##type(STAT_##id.m_id, _STAT(id)); \
67                 }
68         void GlobalStats_update(entity this) {}
69     #define REGISTER_STAT_3(x, T, expr) REGISTER_STAT(x, T); [[accumulate]] void GlobalStats_update(entity this) { STAT(x, this) = (expr); }
70 #else
71         #define REGISTER_STAT_2(id, type)
72     #define REGISTER_STAT_3(x, T, expr)
73 #endif
74
75 const int STATS_ENGINE_RESERVE = 32 + (8 * 3); // Not sure how to handle vector stats yet, reserve them too
76
77 REGISTRY(Stats, 256 - STATS_ENGINE_RESERVE)
78 REGISTER_REGISTRY(RegisterStats)
79 REGISTRY_SORT(Stats, 0)
80 REGISTRY_CHECK(Stats)
81 STATIC_INIT(RegisterStats_renumber)
82 {
83         FOREACH(Stats, true, LAMBDA(it.m_id = STATS_ENGINE_RESERVE + i));
84 }
85 #ifdef SVQC
86 STATIC_INIT(stats_add) { stats_add(); }
87 #endif
88
89 #endif