]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/wepent.qc
Merge branch 'master' into Mario/wepent_experimental
[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 /** the engine player name strings are mutable! */
8 #define WEPENT_SET_MUTABLE_STRING(var, x) MACRO_BEGIN \
9         if (var) strunzone(var); \
10         var = strzone(x); \
11 MACRO_END
12
13 #ifdef SVQC
14         .int w_sv_entnum;
15         .Weapon w_m_switchweapon;
16         .Weapon w_m_switchingweapon;
17         .Weapon w_m_weapon;
18         //.float w_weapon_nextthink;
19         .float w_m_alpha;
20         .float w_vortex_charge;
21         .int w_m_gunalign;
22         .bool w_porto_v_angle_held;
23         .int w_tuba_instrument;
24 #endif
25
26 // #define PROP(public, fld, set, sv, cl)
27 #define WEPENT_NETPROPS(PROP) PROP(false, sv_entnum, WEPENT_SET_NORMAL, {}, {}) /* sentinel */ \
28         PROP(false, m_switchweapon, WEPENT_SET_NORMAL, \
29         { WriteByte(chan, this.m_switchweapon.m_id); }, \
30         { (viewmodels[this.m_wepent_slot]).switchweapon = Weapons_from(ReadByte()); }) \
31     \
32     PROP(false, m_switchingweapon, WEPENT_SET_NORMAL, \
33         { WriteByte(chan, this.m_switchingweapon.m_id); }, \
34         { (viewmodels[this.m_wepent_slot]).switchingweapon = Weapons_from(ReadByte()); }) \
35     \
36     PROP(false, m_weapon, WEPENT_SET_NORMAL, \
37         { WriteByte(chan, this.m_weapon.m_id); }, \
38         { (viewmodels[this.m_wepent_slot]).activeweapon = Weapons_from(ReadByte()); }) \
39     \
40     PROP(false, m_alpha, WEPENT_SET_NORMAL, \
41         { WriteByte(chan, this.m_alpha * 16); }, \
42         { (viewmodels[this.m_wepent_slot]).alpha = ReadByte() / 16; }) \
43     \
44     PROP(false, vortex_charge, WEPENT_SET_NORMAL, \
45         { WriteByte(chan, this.vortex_charge * 16); }, \
46         { (viewmodels[this.m_wepent_slot]).vortex_charge = ReadByte() / 16; }) \
47     \
48     PROP(false, m_gunalign, WEPENT_SET_NORMAL, \
49         { WriteByte(chan, this.m_gunalign); }, \
50         { (viewmodels[this.m_wepent_slot]).m_gunalign = ReadByte(); }) \
51     \
52     PROP(false, porto_v_angle_held, WEPENT_SET_NORMAL, \
53         { WriteByte(chan, this.porto_v_angle_held); if(this.porto_v_angle_held) { \
54                  WriteAngle(chan, this.porto_v_angle.x); WriteAngle(chan, this.porto_v_angle.y); \
55                 } }, \
56         { (viewmodels[this.m_wepent_slot]).angles_held_status = ReadByte(); if((viewmodels[this.m_wepent_slot]).angles_held_status) { \
57                 (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; } \
58                 else { (viewmodels[this.m_wepent_slot]).angles_held = '0 0 0'; } }) \
59     \
60     PROP(false, tuba_instrument, WEPENT_SET_NORMAL, \
61         { WriteByte(chan, this.tuba_instrument); }, \
62         { (viewmodels[this.m_wepent_slot]).tuba_instrument = ReadByte(); }) \
63     \
64         /**/
65
66 #ifdef SVQC
67
68         int WEPENT_PUBLICMASK = 0;
69         STATIC_INIT(WEPENT_PUBLICMASK)
70         {
71                 int i = 0;
72                 #define X(public, fld, set, sv, cl) { \
73                         if (public) { \
74                                 WEPENT_PUBLICMASK |= BIT(i); \
75                         } \
76                         i += 1; \
77                 }
78                 WEPENT_NETPROPS(X);
79         #undef X
80                 if (i >= BITS(16 - 1)) LOG_FATAL("Exceeded WEPENT_NETPROPS limit");
81         }
82
83         bool _wepent_send(entity this, entity to, int sf, int chan)
84         {
85                 sf |= this.m_forceupdate;
86                 this.m_forceupdate = 0;
87                 if (chan == MSG_ENTITY)
88                         WriteHeader(chan, ENT_CLIENT_WEPENT);
89                 else
90                         WriteHeader(chan, CLIENT_WEPENT);
91                 .entity weaponentity = this.weaponentity_fld;
92                 WriteByte(chan, weaponslot(weaponentity));
93                 WriteShort(chan, sf);
94                 int i = 0;
95                 #define X(public, fld, set, sv, cl) { \
96                         if (sf & BIT(i)) { \
97                                 sv; \
98                         } \
99                         i += 1; \
100                 }
101                 WEPENT_NETPROPS(X);
102         #undef X
103                 return true;
104         }
105
106         bool wepent_send(entity this, entity to, int sf)
107         {
108                 return _wepent_send(this, to, sf, MSG_ENTITY);
109         }
110
111         void wepent_update(entity this)
112         {
113                 int i = 0;
114                 #define X(public, fld, set, sv, cl) { \
115                         if (this.w_##fld != this.fld) { \
116                                 set(this.w_##fld, this.fld); \
117                                 this.SendFlags |= BIT(i); \
118                         } \
119                         i += 1; \
120                 }
121                 WEPENT_NETPROPS(X);
122         #undef X
123         }
124
125         void wepent_link(entity wep)
126         {
127                 Net_LinkEntity(wep, false, 0, wepent_send);
128         }
129
130 #endif
131
132 #ifdef CSQC
133
134         bool ReadWepent(entity this)
135         {
136                 this.m_wepent_slot = ReadByte();
137                 int sf = ReadShort();
138                 int i = 0;
139                 #define X(public, fld, set, sv, cl) { \
140                         if (sf & BIT(i)) { \
141                                 cl; \
142                         } \
143                         i += 1; \
144                 }
145                 WEPENT_NETPROPS(X);
146         #undef X
147                 return true;
148         }
149
150         NET_HANDLE(ENT_CLIENT_WEPENT, bool isnew)
151         {
152                 if (isnew)
153                         this.classname = "wepent_receiver";
154                 return ReadWepent(this);
155         }
156
157         NET_HANDLE(CLIENT_WEPENT, bool isnew)
158         {
159                 return ReadWepent(NULL);
160         }
161
162 #endif