Properly support team field on trigger_multiple
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / wepent.qc
1 #include "wepent.qh"
2
3 #define WEPENT_SET_NORMAL(var, x) MACRO_BEGIN \
4         var = x; \
5 MACRO_END
6
7 // #define PROP(public, fld, set, sv, cl)
8 #define WEPENT_NETPROPS(PROP) PROP(false, sv_entnum, WEPENT_SET_NORMAL, {}, {}) /* sentinel */ \
9         PROP(false, m_switchweapon, WEPENT_SET_NORMAL, \
10         { WriteByte(chan, this.m_switchweapon.m_id); }, \
11         { (viewmodels[this.m_wepent_slot]).switchweapon = Weapons_from(ReadByte()); }) \
12     \
13     PROP(false, m_switchingweapon, WEPENT_SET_NORMAL, \
14         { WriteByte(chan, this.m_switchingweapon.m_id); }, \
15         { (viewmodels[this.m_wepent_slot]).switchingweapon = Weapons_from(ReadByte()); }) \
16     \
17     PROP(false, m_weapon, WEPENT_SET_NORMAL, \
18         { WriteByte(chan, this.m_weapon.m_id); }, \
19         { (viewmodels[this.m_wepent_slot]).activeweapon = Weapons_from(ReadByte()); }) \
20     \
21     PROP(false, m_alpha, WEPENT_SET_NORMAL, \
22         { WriteByte(chan, rint(bound(-1, 254 * this.m_alpha, 254) - -1)); }, \
23         { (viewmodels[this.m_wepent_slot]).alpha = (ReadByte() + -1) / 254; }) \
24     \
25     PROP(false, vortex_charge, WEPENT_SET_NORMAL, \
26         { WriteByte(chan, this.vortex_charge * 16); }, \
27         { (viewmodels[this.m_wepent_slot]).vortex_charge = ReadByte() / 16; }) \
28     \
29     PROP(false, m_gunalign, WEPENT_SET_NORMAL, \
30         { WriteByte(chan, this.m_gunalign); }, \
31         { (viewmodels[this.m_wepent_slot]).m_gunalign = ReadByte(); }) \
32     \
33     PROP(false, porto_v_angle_held, WEPENT_SET_NORMAL, \
34         { WriteByte(chan, this.porto_v_angle_held); if(this.porto_v_angle_held) { \
35                  WriteAngle(chan, this.porto_v_angle.x); WriteAngle(chan, this.porto_v_angle.y); \
36                 } }, \
37         { (viewmodels[this.m_wepent_slot]).angles_held_status = ReadByte(); if((viewmodels[this.m_wepent_slot]).angles_held_status) { \
38                 (viewmodels[this.m_wepent_slot]).angles_held_x = ReadAngle(); (viewmodels[this.m_wepent_slot]).angles_held_y = ReadAngle(); (viewmodels[this.m_wepent_slot]).angles_held_z = 0; } \
39                 else { (viewmodels[this.m_wepent_slot]).angles_held = '0 0 0'; } }) \
40     \
41     PROP(false, tuba_instrument, WEPENT_SET_NORMAL, \
42         { WriteByte(chan, this.tuba_instrument); }, \
43         { (viewmodels[this.m_wepent_slot]).tuba_instrument = ReadByte(); }) \
44     \
45         /**/
46
47 #ifdef SVQC
48
49         int WEPENT_PUBLICMASK = 0;
50         STATIC_INIT(WEPENT_PUBLICMASK)
51         {
52                 int i = 0;
53                 #define X(public, fld, set, sv, cl) { \
54                         if (public) { \
55                                 WEPENT_PUBLICMASK |= BIT(i); \
56                         } \
57                         i += 1; \
58                 }
59                 WEPENT_NETPROPS(X);
60         #undef X
61                 if (i >= BITS(16 - 1)) LOG_FATAL("Exceeded WEPENT_NETPROPS limit");
62         }
63
64         bool _wepent_send(entity this, entity to, int sf, int chan)
65         {
66                 sf |= this.m_forceupdate;
67                 this.m_forceupdate = 0;
68                 if (chan == MSG_ENTITY)
69                         WriteHeader(chan, ENT_CLIENT_WEPENT);
70                 else
71                         WriteHeader(chan, CLIENT_WEPENT);
72                 .entity weaponentity = this.owner.weaponentity_fld;
73                 WriteByte(chan, weaponslot(weaponentity));
74                 WriteShort(chan, sf);
75                 int i = 0;
76                 #define X(public, fld, set, sv, cl) { \
77                         if (sf & BIT(i)) { \
78                                 sv; \
79                         } \
80                         i += 1; \
81                 }
82                 WEPENT_NETPROPS(X);
83         #undef X
84                 return true;
85         }
86
87         bool wepent_send(entity this, entity to, int sf)
88         {
89                 return _wepent_send(this, to, sf, MSG_ENTITY);
90         }
91
92         void wepent_think(entity this)
93         {
94                 if(wasfreed(this.owner) || !this.owner)
95                 {
96                         delete(this);
97                         return;
98                 }
99
100                 this.nextthink = time;
101
102                 entity o = this.owner;
103
104                 int i = 0;
105                 #define X(public, fld, set, sv, cl) { \
106                         if (this.fld != o.fld) { \
107                                 set(this.fld, o.fld); \
108                                 this.SendFlags |= BIT(i); \
109                         } \
110                         i += 1; \
111                 }
112                 WEPENT_NETPROPS(X);
113         #undef X
114         }
115
116         bool wepent_customize(entity this, entity client)
117         {
118                 //entity e = WaypointSprite_getviewentity(client);
119                 .entity weaponentity = this.owner.weaponentity_fld;
120                 return client.(weaponentity) == this.owner;
121         }
122
123         void wepent_link(entity wep)
124         {
125                 entity e = new(wepent_sender);
126                 e.owner = wep;
127                 setthink(e, wepent_think);
128                 e.nextthink = time;
129                 //e.drawonlytoclient = wep.owner;
130                 setcefc(e, wepent_customize);
131                 Net_LinkEntity(e, false, 0, wepent_send);
132         }
133
134 #endif
135
136 #ifdef CSQC
137
138         bool ReadWepent(entity this)
139         {
140                 int slot = ReadByte();
141                 this.m_wepent_slot = slot;
142                 viewmodels[slot].m_wepent_slot = slot;
143                 int sf = ReadShort();
144                 int i = 0;
145                 #define X(public, fld, set, sv, cl) { \
146                         if (sf & BIT(i)) { \
147                                 cl; \
148                         } \
149                         i += 1; \
150                 }
151                 WEPENT_NETPROPS(X);
152         #undef X
153                 return true;
154         }
155
156         NET_HANDLE(ENT_CLIENT_WEPENT, bool isnew)
157         {
158                 if (isnew)
159                         this.classname = "wepent_receiver";
160                 return ReadWepent(this);
161         }
162
163         NET_HANDLE(CLIENT_WEPENT, bool isnew)
164         {
165                 return ReadWepent(NULL);
166         }
167
168 #endif