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;
171 float(entity cl, float wpn, float andammo) client_hasweapon =
173 local float itemcode;
174 local entity oldself;
176 weapon_hasammo = TRUE;
177 if (wpn < WEP_FIRST || wpn > WEP_LAST)
179 itemcode = weapon_translateindextoflag(wpn);
180 if (cl.items & itemcode)
186 weapon_action(wpn, WR_CHECKAMMO);
200 weapon_action(self.weapon, WR_CLEAR);
201 if (self.weapon != -1)
203 if (self.weaponentity)
205 self.weaponentity.state = WS_CLEAR;
206 setmodel(self.weaponentity, "");
207 self.weaponentity.effects = 0;
213 self.weaponentity.state = WS_READY;
214 weapon_action(self.weapon, WR_IDLE);
217 // FIXME: add qw-style client-custom weaponrating (cl_weaponrating)?
218 float(entity e) w_getbestweapon
219 {// add new weapons here
220 if (client_hasweapon(e, WEP_ROCKET_LAUNCHER, TRUE))
221 return WEP_ROCKET_LAUNCHER;
222 else if (client_hasweapon(e, WEP_NEX, TRUE))
224 else if (client_hasweapon(e, WEP_HAGAR, TRUE))
226 else if (client_hasweapon(e, WEP_GRENADE_LAUNCHER, TRUE))
227 return WEP_GRENADE_LAUNCHER;
228 else if (client_hasweapon(e, WEP_ELECTRO, TRUE))
230 else if (client_hasweapon(e, WEP_CRYLINK, TRUE))
232 else if (client_hasweapon(e, WEP_UZI, TRUE))
234 else if (client_hasweapon(e, WEP_SHOTGUN, TRUE))
238 weapon_hasammo = TRUE;
243 // Setup weapon for client (after this raise frame will be launched)
244 void(float windex, string wmodel, float hudammo) weapon_setup =
246 local string weaponmdl;
248 self.items = self.items - (self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS));
249 self.items = self.items | hudammo;
251 self.weapon = windex;
255 weaponmdl = strzone(strcat("models/weapons/", wmodel));
256 setmodel(self.weaponentity, weaponmdl);
258 // VorteX: update visible weapon
259 // CL_ViswepUpdate();
263 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
264 void(float x, float y, float z) weapon_shotdir =
266 makevectors(self.v_angle);
267 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;
268 self.shotdir = aim(self, 1000);
271 // perform weapon to attack (weaponstate and attack_finished check is here)
272 void(float() checkfunc1, float() checkfunc2, void() firefunc, float atktime) weapon_prepareattack =
277 self.switchweapon = w_getbestweapon(self);
280 // Don't do shot if previos attack not finished
281 if (time < self.attack_finished)
283 // Can't do shot if changing weapon
284 if (self.weaponentity.state != WS_READY)
287 self.attack_finished = time + atktime;
291 // perform weapon attack
292 void(float() checkfunc1, float() checkfunc2, void() firefunc) weapon_doattack
297 self.switchweapon = w_getbestweapon(self);
300 self.weaponentity.state = WS_INUSE;
302 weapon_action(self.weapon, WR_UPDATECOUNTS); // update ammo now
305 void(entity ent, float recoil) weapon_recoil =
307 ent.punchangle = (randomvec() + '-1 0 0')*recoil;
308 ent.punchangle_z = 0; // don't want roll
309 if (recoil > 3) // push back if large recoil
310 ent.velocity = ent.velocity - normalize(ent.shotdir)*recoil*25;
313 void(float fr, float t, void() func) weapon_thinkf =
317 if (self.weaponentity != world)
318 self.weaponentity.frame = fr;
321 if(cvar("g_runematch"))
323 if(self.runes & RUNE_SPEED)
325 if(self.runes & CURSE_SLOW)
326 t = t * cvar("g_balance_rune_speed_combo_atkrate");
328 t = t * cvar("g_balance_rune_speed_atkrate");
330 else if(self.runes & CURSE_SLOW)
332 t = t * cvar("g_balance_curse_slow_atkrate");
336 // VorteX: haste can be added here
337 self.weapon_nextthink = time + t;
338 self.weapon_think = func;
341 void(float spd, vector org) weapon_boblayer1 =
343 // VorteX: haste can be added here
344 self.weaponentity.pos1 =org;
345 self.weaponentity.lip = spd;