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 void() CL_ExteriorWeaponentity_Think =
22 self.nextthink = time;
23 if (self.owner.exteriorweaponentity != self)
28 if (self.modelindex != self.owner.weaponentity.modelindex || self.dmg != self.owner.modelindex)
30 self.modelindex = self.owner.weaponentity.modelindex;
31 self.model = self.owner.weaponentity.model;
32 self.dmg = self.owner.modelindex;
33 setattachment(self, self.owner, "weapon");
34 // if that didn't find a tag, hide the exterior weapon model
38 self.frame = self.owner.weaponentity.frame;
39 self.effects = self.owner.weaponentity.effects;
42 // spawning weaponentity for client
43 void() CL_SpawnWeaponentity =
45 if (self.weaponentity)
50 self.weaponentity = spawn();
51 self.weaponentity.solid = SOLID_NOT;
52 self.weaponentity.owner = self;
53 self.weaponentity.weaponentity = self.weaponentity;
54 setmodel(self.weaponentity, "");
55 self.weaponentity.origin = '0 0 0';
56 self.weaponentity.angles = '0 0 0';
57 self.weaponentity.viewmodelforclient = self;
58 self.weaponentity.flags = 0;
59 self.weaponentity.think = CL_Weaponentity_Think;
60 self.weaponentity.nextthink = time;
62 self.exteriorweaponentity = spawn();
63 self.exteriorweaponentity.solid = SOLID_NOT;
64 self.exteriorweaponentity.exteriorweaponentity = self.exteriorweaponentity;
65 self.exteriorweaponentity.owner = self;
66 self.exteriorweaponentity.origin = '0 0 0';
67 self.exteriorweaponentity.angles = '0 0 0';
68 self.exteriorweaponentity.think = CL_ExteriorWeaponentity_Think;
69 self.exteriorweaponentity.nextthink = time;
72 // convertion from index (= impulse) to flag in .items
73 float(float index) weapon_translateindextoflag =
75 if (index == WEP_LASER)
77 else if (index == WEP_SHOTGUN)
79 else if (index == WEP_UZI)
81 else if (index == WEP_GRENADE_LAUNCHER)
82 return IT_GRENADE_LAUNCHER;
83 else if (index == WEP_ELECTRO)
85 else if (index == WEP_CRYLINK)
87 else if (index == WEP_NEX)
89 else if (index == WEP_HAGAR)
91 else if (index == WEP_ROCKET_LAUNCHER)
92 return IT_ROCKET_LAUNCHER;
96 float(entity cl, float wpn, float andammo) client_hasweapon =
101 weapon_hasammo = TRUE;
102 if (wpn < WEP_FIRST || wpn > WEP_LAST)
104 itemcode = weapon_translateindextoflag(wpn);
105 if (cl.items & itemcode)
111 weapon_action(wpn, WR_CHECKAMMO);
125 weapon_action(self.weapon, WR_CLEAR);
126 if (self.weapon != -1)
128 if (self.weaponentity)
130 self.weaponentity.state = WS_CLEAR;
131 setmodel(self.weaponentity, "");
132 self.weaponentity.effects = 0;
138 self.weaponentity.state = WS_READY;
139 weapon_action(self.weapon, WR_IDLE);
142 // FIXME: add qw-style client-custom weaponrating (cl_weaponrating)?
143 float(entity e) w_getbestweapon
144 {// add new weapons here
145 if (client_hasweapon(e, WEP_ROCKET_LAUNCHER, TRUE))
146 return WEP_ROCKET_LAUNCHER;
147 else if (client_hasweapon(e, WEP_NEX, TRUE))
149 else if (client_hasweapon(e, WEP_HAGAR, TRUE))
151 else if (client_hasweapon(e, WEP_GRENADE_LAUNCHER, TRUE))
152 return WEP_GRENADE_LAUNCHER;
153 else if (client_hasweapon(e, WEP_ELECTRO, TRUE))
155 else if (client_hasweapon(e, WEP_CRYLINK, TRUE))
157 else if (client_hasweapon(e, WEP_UZI, TRUE))
159 else if (client_hasweapon(e, WEP_SHOTGUN, TRUE))
163 weapon_hasammo = TRUE;
168 // Setup weapon for client (after this raise frame will be launched)
169 void(float windex, string wmodel, float hudammo) weapon_setup =
171 local string wdir, weaponmdl;
173 self.items = self.items - (self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS));
174 self.items = self.items | hudammo;
176 self.weapon = windex;
180 weaponmdl = strzone(strcat("models/weapons/", wmodel));
181 setmodel(self.weaponentity, weaponmdl);
183 // VorteX: update visible weapon
184 // CL_ViswepUpdate();
188 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
189 void(float x, float y, float z) weapon_shotdir =
191 makevectors(self.v_angle);
192 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;
193 self.shotdir = aim(self, 1000);
196 // perform weapon to attack (weaponstate and attack_finished check is here)
197 void(float() checkfunc1, float() checkfunc2, void() firefunc, float atktime) weapon_prepareattack =
199 // Change to best weapon if failed
200 if ((cvar("g_instagib") == 0) && (cvar("g_rocketarena") == 0))
205 self.switchweapon = w_getbestweapon(self);
209 // Don't do shot if previos attack not finished
210 if (time < self.attack_finished)
212 // Can't do shot if changing weapon
213 if (self.weaponentity.state != WS_READY)
216 self.attack_finished = time + atktime;
220 // perform weapon attack
221 void(float() checkfunc1, float() checkfunc2, void() firefunc) weapon_doattack
223 // Change to best weapon if failed
224 if ((cvar("g_instagib") == 0) && (cvar("g_rocketarena") == 0))
229 self.switchweapon = w_getbestweapon(self);
233 self.weaponentity.state = WS_INUSE;
235 weapon_action(self.weapon, WR_UPDATECOUNTS); // update ammo now
238 void(entity ent, float recoil) weapon_recoil =
240 ent.punchangle = (randomvec() + '-1 0 0')*recoil;
241 ent.punchangle_z = 0; // don't want roll
242 if (recoil > 3) // push back if large recoil
243 ent.velocity = ent.velocity - normalize(ent.shotdir)*recoil*25;
246 void(float fr, float t, void() func) weapon_thinkf =
249 if (self.weaponentity != world)
250 self.weaponentity.frame = fr;
251 // VorteX: haste can be added here
252 self.weapon_nextthink = time + t;
253 self.weapon_think = func;
256 void(float spd, vector org) weapon_boblayer1 =
258 // VorteX: haste can be added here
259 self.weaponentity.pos1 =org;
260 self.weaponentity.lip = spd;