2 ===========================================================================
4 CLIENT WEAPONSYSTEM CODE
5 Bring back W_Weaponframe
7 ===========================================================================
10 void LaserTarget_Think()
17 // list of weapons that will use the laser, and the options that enable it
18 if(self.owner.laser_on && self.owner.weapon == WEP_ROCKET_LAUNCHER && cvar("g_homing_missile"))
21 //if(self.owner.weapon == WEP_ELECTRO && cvar("g_homing_electro"))
26 // if a laser-enabled weapon isn't selected, delete any existing laser and quit
29 // rocket launcher isn't selected, so no laser target.
30 if(self.lasertarget != world)
32 remove(self.lasertarget);
33 self.lasertarget = world;
40 // we don't have a lasertarget entity, so spawn one
41 //bprint("create laser target\n");
42 e = self.lasertarget = spawn();
43 e.owner = self.owner; // Its owner is my owner
44 e.classname = "laser_target";
45 e.movetype = MOVETYPE_NOCLIP; // don't touch things
46 setmodel(e, "models/laser_dot.mdl"); // what it looks like
47 e.scale = 1.25; // make it larger
48 e.alpha = 0.25; // transparency
49 e.colormod = '255 0 0' * (1/255) * 8; // change colors
50 e.effects = EF_FULLBRIGHT;
51 // make it dynamically glow
52 // you should avoid over-using this, as it can slow down the player's computer.
53 e.glow_color = 251; // red color
59 // move the laser dot to where the player is looking
61 makevectors(self.owner.v_angle); // set v_forward etc to the direction the player is looking
62 offset = '0 0 26' + v_right*3;
63 traceline(self.owner.origin + offset, self.owner.origin + offset + v_forward * 2048, FALSE, self); // trace forward until you hit something, like a player or wall
64 setorigin(e, trace_endpos + v_forward*8); // move me to where the traceline ended
65 if(trace_plane_normal != '0 0 0')
66 e.angles = vectoangles(trace_plane_normal);
68 e.angles = vectoangles(v_forward);
71 void() CL_Weaponentity_Think =
73 self.nextthink = time;
74 if (self.owner.weaponentity != self)
79 self.effects = self.owner.effects;
80 self.alpha = self.owner.alpha;
82 // create or update the lasertarget entity
86 void() CL_ExteriorWeaponentity_Think =
88 self.nextthink = time;
89 if (self.owner.exteriorweaponentity != self)
94 if (self.cnt != self.owner.weaponentity.modelindex || self.dmg != self.owner.modelindex || self.deadflag != self.owner.deadflag)
96 self.cnt = self.owner.weaponentity.modelindex;
97 self.dmg = self.owner.modelindex;
98 self.deadflag = self.owner.deadflag;
99 if (self.owner.deadflag) self.model = "";
100 else if (self.owner.weapon == WEP_LASER) setmodel(self, "models/weapons/v_laser.md3");
101 else if (self.owner.weapon == WEP_SHOTGUN) setmodel(self, "models/weapons/v_shotgun.md3");
102 else if (self.owner.weapon == WEP_UZI) setmodel(self, "models/weapons/v_uzi.md3");
103 else if (self.owner.weapon == WEP_GRENADE_LAUNCHER) setmodel(self, "models/weapons/v_gl.md3");
104 else if (self.owner.weapon == WEP_ELECTRO) setmodel(self, "models/weapons/v_electro.md3");
105 else if (self.owner.weapon == WEP_CRYLINK) setmodel(self, "models/weapons/v_crylink.md3");
106 else if (self.owner.weapon == WEP_NEX) setmodel(self, "models/weapons/v_nex.md3");
107 else if (self.owner.weapon == WEP_HAGAR) setmodel(self, "models/weapons/v_hagar.md3");
108 else if (self.owner.weapon == WEP_ROCKET_LAUNCHER) setmodel(self, "models/weapons/v_rl.md3");
109 setattachment(self, self.owner, "bip01 r hand");
110 // if that didn't find a tag, hide the exterior weapon model
114 self.effects = self.owner.weaponentity.effects;
117 // spawning weaponentity for client
118 void() CL_SpawnWeaponentity =
120 if (self.weaponentity)
125 self.weaponentity = spawn();
126 self.weaponentity.solid = SOLID_NOT;
127 self.weaponentity.owner = self;
128 self.weaponentity.weaponentity = self.weaponentity;
129 setmodel(self.weaponentity, "");
130 self.weaponentity.origin = '0 0 0';
131 self.weaponentity.angles = '0 0 0';
132 self.weaponentity.viewmodelforclient = self;
133 self.weaponentity.flags = 0;
134 self.weaponentity.think = CL_Weaponentity_Think;
135 self.weaponentity.nextthink = time;
137 self.exteriorweaponentity = spawn();
138 self.exteriorweaponentity.solid = SOLID_NOT;
139 self.exteriorweaponentity.exteriorweaponentity = self.exteriorweaponentity;
140 self.exteriorweaponentity.owner = self;
141 self.exteriorweaponentity.origin = '0 0 0';
142 self.exteriorweaponentity.angles = '0 0 0';
143 self.exteriorweaponentity.think = CL_ExteriorWeaponentity_Think;
144 self.exteriorweaponentity.nextthink = time;
147 // convertion from index (= impulse) to flag in .items
148 float(float index) weapon_translateindextoflag =
150 if (index == WEP_LASER)
152 else if (index == WEP_SHOTGUN)
154 else if (index == WEP_UZI)
156 else if (index == WEP_GRENADE_LAUNCHER)
157 return IT_GRENADE_LAUNCHER;
158 else if (index == WEP_ELECTRO)
160 else if (index == WEP_CRYLINK)
162 else if (index == WEP_NEX)
164 else if (index == WEP_HAGAR)
166 else if (index == WEP_ROCKET_LAUNCHER)
167 return IT_ROCKET_LAUNCHER;
168 else if (index == WEP_LASER)
174 float(entity cl, float wpn, float andammo) client_hasweapon =
176 local float itemcode;
177 local entity oldself;
179 weapon_hasammo = TRUE;
180 if (wpn < WEP_FIRST || wpn > WEP_LAST)
182 itemcode = weapon_translateindextoflag(wpn);
183 if (cl.items & itemcode)
189 weapon_action(wpn, WR_CHECKAMMO);
203 weapon_action(self.weapon, WR_CLEAR);
204 if (self.weapon != -1)
206 if (self.weaponentity)
208 self.weaponentity.state = WS_CLEAR;
209 setmodel(self.weaponentity, "");
210 self.weaponentity.effects = 0;
216 self.weaponentity.state = WS_READY;
217 weapon_action(self.weapon, WR_IDLE);
220 // FIXME: add qw-style client-custom weaponrating (cl_weaponrating)?
221 float(entity e) w_getbestweapon
222 {// add new weapons here
223 if (client_hasweapon(e, WEP_ROCKET_LAUNCHER, TRUE))
224 return WEP_ROCKET_LAUNCHER;
225 else if (client_hasweapon(e, WEP_NEX, TRUE))
227 else if (client_hasweapon(e, WEP_HAGAR, TRUE))
229 else if (client_hasweapon(e, WEP_GRENADE_LAUNCHER, TRUE))
230 return WEP_GRENADE_LAUNCHER;
231 else if (client_hasweapon(e, WEP_ELECTRO, TRUE))
233 else if (client_hasweapon(e, WEP_CRYLINK, TRUE))
235 else if (client_hasweapon(e, WEP_UZI, TRUE))
237 else if (client_hasweapon(e, WEP_SHOTGUN, TRUE))
239 else if (client_hasweapon(e, WEP_LASER, FALSE))
245 // Setup weapon for client (after this raise frame will be launched)
246 void(float windex, string wmodel, float hudammo) weapon_setup =
248 local string weaponmdl;
250 self.items = self.items - (self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS));
251 self.items = self.items | hudammo;
253 self.weapon = windex;
257 weaponmdl = strzone(strcat("models/weapons/", wmodel));
258 setmodel(self.weaponentity, weaponmdl);
260 // VorteX: update visible weapon
261 // CL_ViswepUpdate();
265 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
266 void(float x, float y, float z) weapon_shotdir =
268 makevectors(self.v_angle);
269 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;
270 self.shotdir = aim(self, 1000);
273 // perform weapon to attack (weaponstate and attack_finished check is here)
274 void(float() checkfunc1, float() checkfunc2, void() firefunc, float atktime) weapon_prepareattack =
279 self.switchweapon = w_getbestweapon(self);
282 // Don't do shot if previos attack not finished
283 if (time < self.attack_finished)
285 // Can't do shot if changing weapon
286 if (self.weaponentity.state != WS_READY)
289 self.attack_finished = time + atktime;
293 // perform weapon attack
294 void(float() checkfunc1, float() checkfunc2, void() firefunc) weapon_doattack
299 self.switchweapon = w_getbestweapon(self);
302 self.weaponentity.state = WS_INUSE;
304 weapon_action(self.weapon, WR_UPDATECOUNTS); // update ammo now
307 void(entity ent, float recoil) weapon_recoil =
309 ent.punchangle = (randomvec() + '-1 0 0')*recoil;
310 ent.punchangle_z = 0; // don't want roll
311 if (recoil > 3) // push back if large recoil
312 ent.velocity = ent.velocity - normalize(ent.shotdir)*recoil*25;
315 void(float fr, float t, void() func) weapon_thinkf =
319 if (self.weaponentity != world)
320 self.weaponentity.frame = fr;
323 if(cvar("g_runematch"))
325 if(self.runes & RUNE_SPEED)
327 if(self.runes & CURSE_SLOW)
328 t = t * cvar("g_balance_rune_speed_combo_atkrate");
330 t = t * cvar("g_balance_rune_speed_atkrate");
332 else if(self.runes & CURSE_SLOW)
334 t = t * cvar("g_balance_curse_slow_atkrate");
338 // VorteX: haste can be added here
339 self.weapon_nextthink = time + t;
340 self.weapon_think = func;
343 void(float spd, vector org) weapon_boblayer1 =
345 // VorteX: haste can be added here
346 self.weaponentity.pos1 =org;
347 self.weaponentity.lip = spd;