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