]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/wepent.qc
Merge branch 'master' into Lyberta/StandaloneOverkillWeapons
[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, okvortex_charge, WEPENT_SET_NORMAL, \
30         { WriteByte(chan, this.okvortex_charge * 16); }, \
31         { (viewmodels[this.m_wepent_slot]).okvortex_charge = ReadByte() / 16; }) \
32     \
33     PROP(false, m_gunalign, WEPENT_SET_NORMAL, \
34         { WriteByte(chan, this.m_gunalign); }, \
35         { (viewmodels[this.m_wepent_slot]).m_gunalign = ReadByte(); }) \
36     \
37     PROP(false, porto_v_angle_held, WEPENT_SET_NORMAL, \
38         { WriteByte(chan, this.porto_v_angle_held); if(this.porto_v_angle_held) { \
39                  WriteAngle(chan, this.porto_v_angle.x); WriteAngle(chan, this.porto_v_angle.y); \
40                 } }, \
41         { (viewmodels[this.m_wepent_slot]).angles_held_status = ReadByte(); if((viewmodels[this.m_wepent_slot]).angles_held_status) { \
42                 (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; } \
43                 else { (viewmodels[this.m_wepent_slot]).angles_held = '0 0 0'; } }) \
44     \
45     PROP(false, tuba_instrument, WEPENT_SET_NORMAL, \
46         { WriteByte(chan, this.tuba_instrument); }, \
47         { (viewmodels[this.m_wepent_slot]).tuba_instrument = ReadByte(); }) \
48     \
49         /**/
50
51 #ifdef SVQC
52
53         int WEPENT_PUBLICMASK = 0;
54         STATIC_INIT(WEPENT_PUBLICMASK)
55         {
56                 int i = 0;
57                 #define X(public, fld, set, sv, cl) { \
58                         if (public) { \
59                                 WEPENT_PUBLICMASK |= BIT(i); \
60                         } \
61                         i += 1; \
62                 }
63                 WEPENT_NETPROPS(X);
64         #undef X
65                 if (i >= BITS(16 - 1)) LOG_FATAL("Exceeded WEPENT_NETPROPS limit");
66         }
67
68         bool _wepent_send(entity this, entity to, int sf, int chan)
69         {
70                 sf |= this.m_forceupdate;
71                 this.m_forceupdate = 0;
72                 if (chan == MSG_ENTITY)
73                         WriteHeader(chan, ENT_CLIENT_WEPENT);
74                 else
75                         WriteHeader(chan, CLIENT_WEPENT);
76                 .entity weaponentity = this.owner.weaponentity_fld;
77                 WriteByte(chan, weaponslot(weaponentity));
78                 WriteShort(chan, sf);
79                 int i = 0;
80                 #define X(public, fld, set, sv, cl) { \
81                         if (sf & BIT(i)) { \
82                                 sv; \
83                         } \
84                         i += 1; \
85                 }
86                 WEPENT_NETPROPS(X);
87         #undef X
88                 return true;
89         }
90
91         bool wepent_send(entity this, entity to, int sf)
92         {
93                 return _wepent_send(this, to, sf, MSG_ENTITY);
94         }
95
96         void wepent_think(entity this)
97         {
98                 if(wasfreed(this.owner) || !this.owner)
99                 {
100                         delete(this);
101                         return;
102                 }
103
104                 this.nextthink = time;
105
106                 entity o = this.owner;
107
108                 int i = 0;
109                 #define X(public, fld, set, sv, cl) { \
110                         if (this.fld != o.fld) { \
111                                 set(this.fld, o.fld); \
112                                 this.SendFlags |= BIT(i); \
113                         } \
114                         i += 1; \
115                 }
116                 WEPENT_NETPROPS(X);
117         #undef X
118         }
119
120         bool wepent_customize(entity this, entity client)
121         {
122                 //entity e = WaypointSprite_getviewentity(client);
123                 .entity weaponentity = this.owner.weaponentity_fld;
124                 return client.(weaponentity) == this.owner;
125         }
126
127         void wepent_link(entity wep)
128         {
129                 entity e = new(wepent_sender);
130                 e.owner = wep;
131                 setthink(e, wepent_think);
132                 e.nextthink = time;
133                 //e.drawonlytoclient = wep.owner;
134                 setcefc(e, wepent_customize);
135                 Net_LinkEntity(e, false, 0, wepent_send);
136         }
137
138 #endif
139
140 #ifdef CSQC
141
142         bool ReadWepent(entity this)
143         {
144                 int slot = ReadByte();
145                 this.m_wepent_slot = slot;
146                 viewmodels[slot].m_wepent_slot = slot;
147                 int sf = ReadShort();
148                 int i = 0;
149                 #define X(public, fld, set, sv, cl) { \
150                         if (sf & BIT(i)) { \
151                                 cl; \
152                         } \
153                         i += 1; \
154                 }
155                 WEPENT_NETPROPS(X);
156         #undef X
157                 return true;
158         }
159
160         NET_HANDLE(ENT_CLIENT_WEPENT, bool isnew)
161         {
162                 if (isnew)
163                         this.classname = "wepent_receiver";
164                 return ReadWepent(this);
165         }
166
167         NET_HANDLE(CLIENT_WEPENT, bool isnew)
168         {
169                 return ReadWepent(NULL);
170         }
171
172 #endif