1#include "wepent.qh" 2 3#define WEPENT_SET_NORMAL(var, x) MACRO_BEGIN \ 4 var = x; \ 5MACRO_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 169