Net: tempentity support
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / net.qh
1 #ifndef NET_H
2 #define NET_H
3
4 #ifdef SVQC
5 .int SendFlags;
6 .bool(entity to, int sendflags) SendEntity;
7
8 void Net_LinkEntity(entity e, bool docull, float dt, bool(entity to, int sendflags) sendfunc)
9 {
10     if (!e.classname) e.classname = "net_linked";
11
12     if (!e.model || !self.modelindex) {
13         vector mi = e.mins;
14         vector ma = e.maxs;
15         _setmodel(e, "null");
16         setsize(e, mi, ma);
17     }
18
19     e.SendEntity = sendfunc;
20     e.SendFlags = 0xFFFFFF;
21
22     if (!docull) e.effects |= EF_NODEPTHTEST;
23
24     if (dt) {
25         e.nextthink = time + dt;
26         e.think = SUB_Remove;
27     }
28 }
29
30 .void() uncustomizeentityforclient;
31 .float uncustomizeentityforclient_set;
32
33 void SetCustomizer(entity e, float(void) customizer, void(void) uncustomizer)
34 {
35     e.customizeentityforclient = customizer;
36     e.uncustomizeentityforclient = uncustomizer;
37     e.uncustomizeentityforclient_set = !!uncustomizer;
38 }
39
40 void UncustomizeEntitiesRun()
41 {
42     for (entity e = NULL; (e = findfloat(e, uncustomizeentityforclient_set, 1)); ) {
43         WITH(entity, self, e, e.uncustomizeentityforclient());
44     }
45 }
46
47 #endif
48
49 #include "registry.qh"
50 #include "sort.qh"
51
52 .string netname;
53 .int m_id;
54 .void(entity this, bool isNew) m_read;
55
56 #ifdef CSQC
57     #define Net_Accept() do { if (!this)    this = spawn(); } while (0)
58     #define Net_Reject() do { if (this)     remove(this);   } while (0)
59 #else
60     #define WriteHeader(to, id) do { \
61         if (NET_##id##_istemp) WriteByte(to, SVC_TEMPENTITY); \
62         WriteByte(to, NET_##id.m_id); \
63     } while (0)
64 #endif
65
66 #ifdef CSQC
67     #define REGISTER_NET_LINKED(id, param) \
68         void Ent_Read##id(entity this, param) { this = self; } \
69         REGISTER(RegisterLinkedEntities, NET, LinkedEntities, LinkedEntities_COUNT, id, m_id, spawn()) { \
70             this.netname = #id; \
71             this.m_read = Ent_Read##id; \
72         } \
73         [[accumulate]] void Ent_Read##id(entity this, param)
74 #else
75     #define REGISTER_NET_LINKED(id, param) \
76         const bool NET_##id##_istemp = false; \
77         REGISTER(RegisterLinkedEntities, NET, LinkedEntities, LinkedEntities_COUNT, id, m_id, spawn()) { \
78             this.netname = #id; \
79         }
80 #endif
81
82 REGISTRY(LinkedEntities, 24)
83 REGISTER_REGISTRY(RegisterLinkedEntities)
84 REGISTRY_SORT(LinkedEntities, netname, 0)
85 STATIC_INIT(RegisterLinkedEntities_renumber) {
86     for (int i = 0; i < LinkedEntities_COUNT; ++i) {
87         LinkedEntities[i].m_id = 100 + i;
88     }
89 }
90
91 #ifdef CSQC
92     #define REGISTER_NET_TEMP(id, param) \
93         void Net_Read##id(entity this, param); \
94         REGISTER(RegisterTempEntities, NET, TempEntities, TempEntities_COUNT, id, m_id, spawn()) { \
95             this.netname = #id; \
96             this.m_read = Net_Read##id; \
97         } \
98         void Net_Read##id(entity this, param)
99 #else
100     #define REGISTER_NET_TEMP(id, param) \
101         const bool NET_##id##_istemp = true; \
102         REGISTER(RegisterTempEntities, NET, TempEntities, TempEntities_COUNT, id, m_id, spawn()) { \
103             this.netname = #id; \
104         }
105 #endif
106
107 REGISTRY(TempEntities, 24)
108 REGISTER_REGISTRY(RegisterTempEntities)
109 REGISTRY_SORT(TempEntities, netname, 0)
110 STATIC_INIT(RegisterTempEntities_renumber) {
111     for (int i = 0; i < TempEntities_COUNT; ++i) {
112         TempEntities[i].m_id = 115 + i;
113     }
114 }
115
116 #endif