]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/net.qh
Merge branch 'master' into terencehill/menu_gametype_tooltips_2
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / net.qh
1 #ifndef NET_H
2 #define NET_H
3
4 #ifdef SVQC
5 .int Version; // deprecated, use SendFlags
6 .int SendFlags;
7 .bool(entity to, int sendflags) SendEntity;
8 .bool(entity this, entity to, int sendflags) SendEntity3;
9
10 bool SendEntity_self(entity to, int sendflags) { return self.SendEntity3(self, to, sendflags); }
11
12 void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
13 {
14     if (!e.classname) e.classname = "net_linked";
15
16     if (!e.model || !self.modelindex) {
17         vector mi = e.mins;
18         vector ma = e.maxs;
19         _setmodel(e, "null");
20         setsize(e, mi, ma);
21     }
22
23     e.SendEntity = SendEntity_self;
24     e.SendEntity3 = sendfunc;
25     e.SendFlags = 0xFFFFFF;
26
27     if (!docull) e.effects |= EF_NODEPTHTEST;
28
29     if (dt) {
30         e.nextthink = time + dt;
31         e.think = SUB_Remove;
32     }
33 }
34
35 .void() uncustomizeentityforclient;
36 .float uncustomizeentityforclient_set;
37
38 void SetCustomizer(entity e, float(void) customizer, void(void) uncustomizer)
39 {
40     e.customizeentityforclient = customizer;
41     e.uncustomizeentityforclient = uncustomizer;
42     e.uncustomizeentityforclient_set = !!uncustomizer;
43 }
44
45 void UncustomizeEntitiesRun()
46 {
47     for (entity e = NULL; (e = findfloat(e, uncustomizeentityforclient_set, 1)); ) {
48         WITH(entity, self, e, e.uncustomizeentityforclient());
49     }
50 }
51
52 #endif
53
54 #include "registry.qh"
55 #include "sort.qh"
56
57 .string netname;
58 .int m_id;
59 .void(entity this, bool isNew) m_read;
60
61 #ifdef CSQC
62     #define Net_Accept() do { if (!this)    this = spawn(); } while (0)
63     #define Net_Reject() do { if (this)     remove(this);   } while (0)
64 #else
65     #define WriteHeader(to, id) do { \
66         if (NET_##id##_istemp) WriteByte(to, SVC_TEMPENTITY); \
67         WriteByte(to, NET_##id.m_id); \
68     } while (0)
69 #endif
70
71 #ifdef CSQC
72     #define REGISTER_NET_LINKED(id, param) \
73         void Ent_Read##id(entity this, param) { this = self; } \
74         REGISTER(RegisterLinkedEntities, NET, LinkedEntities, id, m_id, spawn()) { \
75             this.netname = #id; \
76             this.m_read = Ent_Read##id; \
77         } \
78         [[accumulate]] void Ent_Read##id(entity this, param)
79 #else
80     #define REGISTER_NET_LINKED(id, param) \
81         const bool NET_##id##_istemp = false; \
82         REGISTER(RegisterLinkedEntities, NET, LinkedEntities, id, m_id, spawn()) { \
83             this.netname = #id; \
84         }
85 #endif
86
87 REGISTRY(LinkedEntities, BIT(0))
88 REGISTER_REGISTRY(RegisterLinkedEntities)
89 REGISTRY_SORT(LinkedEntities, netname, 0)
90 STATIC_INIT(RegisterLinkedEntities_renumber) {
91     for (int i = 0; i < LinkedEntities_COUNT; ++i) {
92         LinkedEntities[i].m_id = 100 + i;
93     }
94 }
95
96 #ifdef CSQC
97     #define REGISTER_NET_TEMP(id, param) \
98         void Net_Read##id(entity this, param); \
99         REGISTER(RegisterTempEntities, NET, TempEntities, id, m_id, spawn()) { \
100             this.netname = #id; \
101             this.m_read = Net_Read##id; \
102         } \
103         void Net_Read##id(entity this, param)
104 #else
105     #define REGISTER_NET_TEMP(id, param) \
106         const bool NET_##id##_istemp = true; \
107         REGISTER(RegisterTempEntities, NET, TempEntities, id, m_id, spawn()) { \
108             this.netname = #id; \
109         }
110 #endif
111
112 REGISTRY(TempEntities, BIT(0))
113 REGISTER_REGISTRY(RegisterTempEntities)
114 REGISTRY_SORT(TempEntities, netname, 0)
115 STATIC_INIT(RegisterTempEntities_renumber) {
116     for (int i = 0; i < TempEntities_COUNT; ++i) {
117         TempEntities[i].m_id = 115 + i;
118     }
119 }
120
121 #ifndef MENUQC
122 #ifdef CSQC
123 int ReadInt24_t()
124 {
125     int v = ReadShort() << 8; // note: this is signed
126     v += ReadByte(); // note: this is unsigned
127     return v;
128 }
129 vector ReadInt48_t()
130 {
131     vector v;
132     v.x = ReadInt24_t();
133     v.y = ReadInt24_t();
134     v.z = 0;
135     return v;
136 }
137 vector ReadInt72_t()
138 {
139     vector v;
140     v.x = ReadInt24_t();
141     v.y = ReadInt24_t();
142     v.z = ReadInt24_t();
143     return v;
144 }
145 #else
146 void WriteInt24_t(float dst, float val)
147 {
148     float v;
149     WriteShort(dst, (v = floor(val >> 8)));
150     WriteByte(dst, val - (v << 8)); // 0..255
151 }
152 void WriteInt48_t(float dst, vector val)
153 {
154     WriteInt24_t(dst, val.x);
155     WriteInt24_t(dst, val.y);
156 }
157 void WriteInt72_t(float dst, vector val)
158 {
159     WriteInt24_t(dst, val.x);
160     WriteInt24_t(dst, val.y);
161     WriteInt24_t(dst, val.z);
162 }
163 #endif
164 #endif
165
166 #endif