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