2 ===========================================================================
4 CLIENT WEAPONSYSTEM CODE
5 Bring back W_Weaponframe
7 ===========================================================================
10 void() CL_Weaponentity_Think =
12 self.nextthink = time;
13 if (self.owner.weaponentity != self)
20 // spawning weaponentity for client
21 void() CL_SpawnWeaponentity =
23 if (self.weaponentity)
28 self.weaponentity = spawn();
29 self.weaponentity.solid = SOLID_NOT;
30 self.weaponentity.owner = self;
31 self.weaponentity.weaponentity = self.weaponentity;
32 setmodel(self.weaponentity, "");
33 self.weaponentity.origin = '0 0 0';
34 self.weaponentity.angles = '0 0 0';
35 self.weaponentity.viewmodelforclient = self;
36 self.weaponentity.flags = 0;
37 self.weaponentity.think = CL_Weaponentity_Think;
38 self.weaponentity.nextthink = time;
41 // convertion from index (= impulse) to flag in .items
42 float(float index) weapon_translateindextoflag =
44 if (index == WEP_LASER)
46 else if (index == WEP_SHOTGUN)
48 else if (index == WEP_UZI)
50 else if (index == WEP_GRENADE_LAUNCHER)
51 return IT_GRENADE_LAUNCHER;
52 else if (index == WEP_ELECTRO)
54 else if (index == WEP_CRYLINK)
56 else if (index == WEP_NEX)
58 else if (index == WEP_HAGAR)
60 else if (index == WEP_ROCKET_LAUNCHER)
61 return IT_ROCKET_LAUNCHER;
65 float(entity cl, float wpn, float andammo) client_hasweapon =
70 weapon_hasammo = TRUE;
71 if (wpn < WEP_FIRST || wpn > WEP_LAST)
73 itemcode = weapon_translateindextoflag(wpn);
74 if (cl.items & itemcode)
80 weapon_action(wpn, WR_CHECKAMMO);
94 weapon_action(self.weapon, WR_CLEAR);
95 if (self.weapon != -1)
97 if (self.weaponentity)
99 self.weaponentity.state = WS_CLEAR;
100 setmodel(self.weaponentity, "");
101 self.weaponentity.effects = 0;
107 self.weaponentity.state = WS_READY;
108 weapon_action(self.weapon, WR_IDLE);
111 // FIXME: add qw-style client-custom weaponrating (cl_weaponrating)?
112 float(entity e) w_getbestweapon
113 {// add new weapons here
114 if (client_hasweapon(e, WEP_ROCKET_LAUNCHER, TRUE))
115 return WEP_ROCKET_LAUNCHER;
116 else if (client_hasweapon(e, WEP_NEX, TRUE))
118 else if (client_hasweapon(e, WEP_HAGAR, TRUE))
120 else if (client_hasweapon(e, WEP_GRENADE_LAUNCHER, TRUE))
121 return WEP_GRENADE_LAUNCHER;
122 else if (client_hasweapon(e, WEP_ELECTRO, TRUE))
124 else if (client_hasweapon(e, WEP_CRYLINK, TRUE))
126 else if (client_hasweapon(e, WEP_UZI, TRUE))
128 else if (client_hasweapon(e, WEP_SHOTGUN, TRUE))
132 weapon_hasammo = TRUE;
137 // Setup weapon for client (after this raise frame will be launched)
138 void(float windex, string wmodel, float hudammo) weapon_setup =
140 local string wdir, weaponmdl;
142 self.items = self.items - (self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS));
143 self.items = self.items | hudammo;
145 self.weapon = windex;
149 weaponmdl = strzone(strcat("models/weapons/", wmodel));
150 setmodel(self.weaponentity, weaponmdl);
152 // VorteX: update visible weapon
153 // CL_ViswepUpdate();
157 float WEAPON_MAXRELX = 14; // if more, shot can be spawned after wall surface (in empty worldspace) or inside other entity if client stands close to it
158 void(float x, float y, float z) weapon_shotdir =
160 makevectors(self.v_angle);
161 self.shotorg = self.origin + self.view_ofs + v_forward*bound(0, x, WEAPON_MAXRELX) + v_right*(y + self.weaponentity.view_ofs_y) + v_up*z;
162 self.shotdir = aim(self, 1000);
165 // perform weapon to attack (weaponstate and attack_finished check is here)
166 void(float() checkfunc1, float() checkfunc2, void() firefunc, float atktime) weapon_prepareattack =
168 // Change to best weapon if failed
169 if (!(game & GAME_INSTAGIB) && !(game & GAME_ROCKET_ARENA))
174 self.switchweapon = w_getbestweapon(self);
178 // Don't do shot if previos attack not finished
179 if (!(game & GAME_INSANE))
180 if (time < self.attack_finished)
182 // Can't do shot if changing weapon
183 if (!(game & GAME_INSANE))
184 if (self.weaponentity.state != WS_READY)
187 self.attack_finished = time + atktime;
191 // perform weapon attack
192 void(float() checkfunc1, float() checkfunc2, void() firefunc) weapon_doattack
194 // Change to best weapon if failed
195 if (!(game & GAME_INSTAGIB) && !(game & GAME_ROCKET_ARENA))
200 self.switchweapon = w_getbestweapon(self);
204 self.weaponentity.state = WS_INUSE;
206 weapon_action(self.weapon, WR_UPDATECOUNTS); // update ammo now
209 void(entity ent, float recoil) weapon_recoil =
211 ent.punchangle = (randomvec() + '-1 0 0')*recoil;
212 ent.punchangle_z = 0; // don't want roll
213 if (recoil > 3) // push back if large recoil
214 ent.velocity = ent.velocity - normalize(ent.shotdir)*recoil*25;
217 void(float fr, float t, void() func) weapon_thinkf =
220 if (self.weaponentity != world)
221 self.weaponentity.frame = fr;
222 // VorteX: haste can be added here
223 self.weapon_nextthink = time + t;
224 self.weapon_think = func;
227 void(float spd, vector org) weapon_boblayer1 =
229 // VorteX: haste can be added here
230 self.weaponentity.pos1 =org;
231 self.weaponentity.lip = spd;