/* weapons.qc weapon and weapon hit functions Copyright (C) 1996-1997 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ // constants for the impulse command const float IMPULSE_WEAPON_FIRST = 1; const float IMPULSE_AXE = 1; const float IMPULSE_SHOTGUN = 2; const float IMPULSE_BLASTER = 60; const float IMPULSE_SNIPER = 61; const float IMPULSE_PISTOL = 62; const float IMPULSE_SABER = 63; const float IMPULSE_STUNGUN = 75; const float IMPULSE_SLUG_THROWER = 81; const float IMPULSE_SUPER_SHOTGUN = 3; const float IMPULSE_NAILGUN = 4; const float IMPULSE_SUPER_NAILGUN = 5; const float IMPULSE_GRENADE_LAUNCHER = 6; const float IMPULSE_ROCKET_LAUNCHER = 7; const float IMPULSE_LIGHTNING = 8; const float IMPULSE_WEAPON_LAST = 8; const float IMPULSE_CHEAT = 9; const float IMPULSE_WEAPONCYCLE_F = 10; const float IMPULSE_CHEAT_SERVERFLAGS = 11; const float IMPULSE_WEAPONCYCLE_R = 12; #ifdef FRIKBOT const float IMPULSE_ADDBOT = 100; const float IMPULSE_REMOVEBOT = 101; #endif void T_Damage (entity targ, entity inflictor, entity attacker, float damage); void player_run (); void T_RadiusDamage (entity bomb, entity attacker, float rad, entity ignore, string dtype); void SpawnBlood (vector org, float damage); void SuperDamageSound (); void player_blaster1 (); void SaberCheck(); void SaberMove(); void SaberOff(); void FunTaunts(); void STTaunts(); void DetpackExplode(); void DetpackTouch(); void DropDetpack(); void EmpFire(); void BlastBounce(); void BlastThink(); void ForcePush2(); void MindTrick(); void MindTrickTurn(); void FLightning(); void FLightThink(); void FJump(); void BotSetDirection(entity CheckedEntity); void FireSlug(); void StatusCheck(); void RadiusEffects(entity Concerned, entity Attacker, float Radius, string EffectType, entity Ignored, entity Ignored2); void IncendiaryThink(); void FireDart(); void RayShield(); void MakeDartShield(); void CheckDartShield(); // called by worldspawn void W_Precache () { precache_sound("grapple/grfire.wav"); precache_sound("grapple/grhit.wav"); precache_sound("grapple/grreset.wav"); precache_model("progsgrapple/null.spr"); precache_sound ("weapons/r_exp3.wav"); // new rocket explosion precache_sound ("weapons/rocket1i.wav"); // spike gun precache_sound ("weapons/sgun1.wav"); precache_sound ("weapons/guncock.wav"); // player shotgun precache_sound ("weapons/ric1.wav"); // ricochet (used in c code) precache_sound ("weapons/ric2.wav"); // ricochet (used in c code) precache_sound ("weapons/ric3.wav"); // ricochet (used in c code) precache_sound ("weapons/spike2.wav"); // super spikes precache_sound ("weapons/tink1.wav"); // spikes tink (used in c code) precache_sound ("weapons/grenade.wav"); // grenade launcher precache_sound ("weapons/bounce.wav"); // grenade bounce precache_sound ("weapons/shotgn2.wav"); // super shotgun precache_model ("progs/s_light.spr"); } float crandom () { return 2*(random() - 0.5); } /* ================ W_FireAxe ================ */ void W_FireAxe () { vector source; vector org; makevectors (self.v_angle); source = self.origin + '0 0 16'; traceline (source, source + v_forward*64, false, self); if (trace_fraction == 1.0) return; org = trace_endpos - v_forward*4; if (trace_ent.takedamage) { trace_ent.axhitme = 1; SpawnBlood (org, 20); if (deathmatch > 3) T_Damage (trace_ent, self, self, 75); else T_Damage (trace_ent, self, self, 20); } else { // hit wall sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM); WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_GUNSHOT); WriteByte (MSG_MULTICAST, 3); WriteCoord (MSG_MULTICAST, org_x); WriteCoord (MSG_MULTICAST, org_y); WriteCoord (MSG_MULTICAST, org_z); multicast (org, MULTICAST_PVS); } } //============================================================================ vector wall_velocity () { vector vel; vel = normalize (self.velocity); vel = normalize(vel + v_up*(random()- 0.5) + v_right*(random()- 0.5)); vel = vel + 2*trace_plane_normal; vel = vel * 200; return vel; } /* ================ SpawnMeatSpray ================ */ void SpawnMeatSpray (vector org, vector vel) { entity missile; missile = spawn (); missile.owner = self; missile.movetype = MOVETYPE_BOUNCE; missile.solid = SOLID_NOT; makevectors (self.angles); missile.velocity = vel; missile.velocity_z = missile.velocity_z + 250 + 50*random(); missile.avelocity = '3000 1000 2000'; // set missile duration missile.nextthink = time + 1; missile.think = SUB_Remove; setmodel (missile, "progs/zom_gib.mdl"); setsize (missile, VEC_ORIGIN, VEC_ORIGIN); setorigin (missile, org); } /* ================ SpawnBlood ================ */ void SpawnBlood (vector org, float damage) { WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_BLOOD); WriteByte (MSG_MULTICAST, 1); WriteCoord (MSG_MULTICAST, org_x); WriteCoord (MSG_MULTICAST, org_y); WriteCoord (MSG_MULTICAST, org_z); multicast (org, MULTICAST_PVS); } /* ================ spawn_touchblood ================ */ void spawn_touchblood (float damage) { vector vel; vel = wall_velocity () * 0.2; SpawnBlood (self.origin + vel*0.01, damage); } /* ============================================================================== MULTI-DAMAGE Collects multiple small damages into a single damage ============================================================================== */ entity multi_ent; float multi_damage; vector blood_org; float blood_count; vector puff_org; float puff_count; void ClearMultiDamage () { multi_ent = world; multi_damage = 0; blood_count = 0; puff_count = 0; } void ApplyMultiDamage () { if (!multi_ent) return; T_Damage (multi_ent, self, self, multi_damage); } void AddMultiDamage (entity hit, float damage) { if (!hit) return; if (hit != multi_ent) { ApplyMultiDamage (); multi_damage = damage; multi_ent = hit; } else multi_damage = multi_damage + damage; } void Multi_Finish () { if (puff_count) { WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_GUNSHOT); WriteByte (MSG_MULTICAST, puff_count); WriteCoord (MSG_MULTICAST, puff_org_x); WriteCoord (MSG_MULTICAST, puff_org_y); WriteCoord (MSG_MULTICAST, puff_org_z); multicast (puff_org, MULTICAST_PVS); } if (blood_count) { WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_BLOOD); WriteByte (MSG_MULTICAST, blood_count); WriteCoord (MSG_MULTICAST, blood_org_x); WriteCoord (MSG_MULTICAST, blood_org_y); WriteCoord (MSG_MULTICAST, blood_org_z); multicast (puff_org, MULTICAST_PVS); } } /* ============================================================================== BULLETS ============================================================================== */ /* ================ TraceAttack ================ */ void TraceAttack (float damage, vector dir) { vector vel, org; vel = normalize(dir + v_up*crandom() + v_right*crandom()); vel = vel + 2*trace_plane_normal; vel = vel * 200; org = trace_endpos - dir*4; if (trace_ent.takedamage) { blood_count = blood_count + 1; blood_org = org; AddMultiDamage (trace_ent, damage); } else { puff_count = puff_count + 1; } } /* ================ FireBullets Used by shotgun, super shotgun, and enemy soldier firing Go to the trouble of combining multiple pellets into a single damage call. ================ */ void FireBullets (float shotcount, vector dir, vector spread) { vector direction; vector src; makevectors(self.v_angle); src = self.origin + v_forward*10; src_z = self.absmin_z + self.size_z * 0.7; ClearMultiDamage (); traceline (src, src + dir*2048, false, self); puff_org = trace_endpos - dir*4; while (shotcount > 0) { direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up; traceline (src, src + direction*2048, false, self); if (trace_fraction != 1.0) TraceAttack (4, direction); shotcount = shotcount - 1; } ApplyMultiDamage (); Multi_Finish (); } // CQ void CruiseSound() { if(time >= self.MissileTime) remove(self); // if(self.voided == 0) sound(self, CHAN_AUTO, "cruise/rocktrav.wav", 1, ATTN_NORM); self.think = CruiseSound; self.nextthink = time + 0.2; } void ForceDisArm() { if(self.force <= 100) return; makevectors(self.angles); tracebox (self.origin, VEC_HULL_MIN, VEC_HULL_MAX, self.origin + (v_forward * 1000), false, self); if (trace_fraction != 1.0 && trace_ent != world && trace_ent.health) { if(trace_ent.weapon != IT_LIGHTSABER || trace_ent.HasYourSaber != "you") return; if(self.force < trace_ent.force && (random()*5) > 1) { return; // do nothing } else { self.force = self.force - 100; trace_ent.HasYourSaber = self.netname; trace_ent.impulse = IMPULSE_AXE; sound(trace_ent, CHAN_WEAPON, "lsaber/saberflyfrom.wav", 1, ATTN_NORM); // trace_ent.items = trace_ent.items - IT_LIGHTSABER; sound(self, CHAN_WEAPON, "lsaber/saberflyto.wav", 1, ATTN_NORM); if(self.HasYourSaber != "you") self.HasYourSaber = "you"; sprint(self, 1, "You got "); sprint(self, 1, trace_ent.netname); sprint(self, 1, "'s light saber\n"); sprint(trace_ent, 1, "You've been disarmed by "); sprint(trace_ent, 1, self.netname); sprint(trace_ent, 1, "\n"); sound(self, CHAN_WEAPON, "lsaber/sabergrab.wav", 1, ATTN_NORM); } } } void() Unfreeze = { self.think = self.old_think; self.nextthink = time + 0.1; self.colormap = 0; self.freezed = 0; self.attack_finished = time; if(self.classname == "player" || self.classname == "bot") self.movetype = MOVETYPE_WALK; }; void() Unfreeze_Fly = { self.think = self.old_think; self.nextthink = time + 0.1; self.colormap = 0; self.freezed = 0; self.flags = self.flags + FL_FLY; self.attack_finished = time; if(self.classname == "player" || self.classname == "bot") self.movetype = MOVETYPE_WALK; }; void() FireStun = { local vector org; if (self.ammo_cells < 10) { self.weapon = W_BestWeapon (); W_SetCurrentAmmo (); return; } // stun gun will now use jet pack energy as well if(self.JETPACK_FUEL < 5) { safe_soundtoclient(self, self, CHAN_WEAPON, "deny.wav", 1, ATTN_NORM); return; } // if (self.t_width < time) // { // sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM); // self.t_width = time + 0.6; // } // self.punchangle_x = -2; self.show_hostile = time + 0.2; self.JETPACK_FUEL = self.JETPACK_FUEL - 5; if(self.JETPACK_FUEL < 0) self.JETPACK_FUEL = 0; self.currentammo = self.ammo_cells = self.ammo_cells - 10; sound(self, CHAN_WEAPON, "stun/jawastun.wav", 1, ATTN_NORM); org = self.origin + '0 0 16'; makevectors(self.v_angle); tracebox(org, VEC_HULL_MIN, VEC_HULL_MAX, org + v_forward*1000, false, self); self.attack_finished = time + 0.3; WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); WriteByte (MSG_BROADCAST, TE_LIGHTNING1); WriteEntity (MSG_BROADCAST, self); WriteCoord (MSG_BROADCAST, org_x); WriteCoord (MSG_BROADCAST, org_y); WriteCoord (MSG_BROADCAST, org_z); WriteCoord (MSG_BROADCAST, trace_endpos_x); WriteCoord (MSG_BROADCAST, trace_endpos_y); WriteCoord (MSG_BROADCAST, trace_endpos_z); if (trace_ent.health > 0) { // 1 if (trace_ent.freezed == 0) { // 2 trace_ent.old_think = trace_ent.think; trace_ent.colormap = 1; trace_ent.nextthink = time + 5; trace_ent.freezed = 1; trace_ent.touch = SUB_Null; trace_ent.button0 = 0; trace_ent.attack_state = 0; trace_ent.velocity = '0 0 0'; if (trace_ent.flags & FL_FLY) { // 3 trace_ent.flags = trace_ent.flags - FL_FLY; trace_ent.think = Unfreeze_Fly; } // 3 else { // 3 trace_ent.think = Unfreeze; trace_ent.attack_finished = time + 5; if(trace_ent.classname == "player" || trace_ent.classname == "bot") trace_ent.movetype = MOVETYPE_NONE; } // 3 if(random() > 0.5) { sound(trace_ent, CHAN_VOICE, "stun/stun3.wav", 1, ATTN_NORM); safe_soundtoclient(self, self, CHAN_AUTO, "stun/stun1.wav", 1, ATTN_NORM); sound(trace_ent, CHAN_BODY, "stun/stun.wav", 1, ATTN_NORM); } else { sound(trace_ent, CHAN_VOICE, "stun/stun4.wav", 1, ATTN_NORM); safe_soundtoclient(self, self, CHAN_AUTO, "stun/stun2.wav", 1, ATTN_NORM); sound(trace_ent, CHAN_BODY, "stun/stun.wav", 1, ATTN_NORM); } trace_ent.FreezeTime = time + 5; } // 2 } //1 }; void ForcePush() { if(self.force <= 10) return; makevectors(self.v_angle); tracebox (self.origin, VEC_HULL_MIN, VEC_HULL_MAX, self.origin + (v_forward * 500), false, self); if (trace_fraction != 1.0 && trace_ent.health) { if(self.force < trace_ent.force && (random()*5) > 3) { if(self.force >= 200) ForcePush2(); // return; // do nothing } else { // force lightning if(trace_ent.FLightOn) { trace_ent.think = FLightStop; trace_ent.nextthink = time; } if(trace_ent.takedamage == false) trace_ent.takedamage = 2; self.force = self.force - 10; sound(self, CHAN_ITEM, "force/push.wav", 1, ATTN_NORM); trace_ent.angles_y = self.angles_y; // trace_ent.angles_y = vectoyaw(trace_ent.origin - self.origin); trace_ent.fixangle = true; BotSetDirection(trace_ent); // this is to disorient bots trace_ent.Disorient = time + (random() + 0.5); self.enemy = trace_ent; tracebox(self.enemy.origin, VEC_HULL_MIN, VEC_HULL_MAX, (self.enemy.origin + (normalize(self.enemy.origin - self.origin) * 30)), false, self.enemy); if(trace_fraction < 1.0) { if(self.enemy.classname != "grenade" || self.enemy.classname != "rocket") { self.enemy.deathtype = "forcepush"; sound(self.enemy, CHAN_VOICE, "force/pushwall.wav", 1, ATTN_NORM); if((self.force + 10) > 200) { T_Damage(self.enemy, self, self, 120); } else if((self.force + 10) > 100 && (self.force + 10) < 200) { T_Damage(self.enemy, self, self, 60); } else { T_Damage(self.enemy, self, self, 30); } } } else { if(self.enemy.classname != "grenade" || self.enemy.classname != "rocket") { self.enemy.deathtype = "forcepush"; if((self.force + 10) > 200) { T_Damage(self.enemy, self, self, 60); } else if((self.force + 10) > 100 && (self.force + 10) < 200) { T_Damage(self.enemy, self, self, 30); } else { T_Damage(self.enemy, self, self, 5); } } } if(self.enemy.classname == "rocket" || self.enemy.classname == "grenade") { local entity MyMis; MyMis = self.enemy; MyMis.owner = self; MyMis.angles = vectoangles(MyMis.origin - self.origin); MyMis.velocity = normalize(MyMis.origin - self.origin)*1000; } else { self.enemy.pusher = self; self.enemy.PushTime = time + 1.5; self.enemy.velocity = normalize(self.enemy.origin - self.origin)*20000; } } } if(self.force >= 190) ForcePush2(); } void SaberOff () { if(self.SaberOn == 0) return; self.show_hostile = time + 0.2; self.SaberOn = 0; self.takedamage = 2; self.SaberSwing = 0; if(self.HasYourSaber == "emp") { sound(self.saber, CHAN_BODY, "lsaber/saberoff.wav", 1, ATTN_NORM); } else { if(self.HasYourSaber != "you") { sound(self.saber, CHAN_BODY, "lsaber/saberflyaway.wav", 1, ATTN_NORM); } else { sound(self.saber, CHAN_BODY, "lsaber/saberoff.wav", 1, ATTN_NORM); } } remove(self.saber); } void SaberMove () { if(self.owner.deadflag > 0) SaberOff(); if(self.owner.SaberSwing == 0) { if(time >= self.owner.SaberTime) self.owner.takedamage = 2; makevectors(self.owner.angles); setorigin(self, self.owner.origin + (v_forward * 10) + (v_right * self.owner.SaberSide) + (v_up * 32)); sound(self, CHAN_BODY, "lsaber/saberhum.wav", 1, ATTN_NORM); self.think = SaberMove; self.nextthink = time + 0.1; } if(self.owner.SaberSwing == 1) { makevectors(self.owner.angles); self.owner.saberpos = self.owner.origin + (v_forward * 10) + (v_right * self.owner.SaberSide) + (v_up * 32); // set the saber velocity self.velocity = normalize(self.owner.saberpos - self.origin) * 1000; // make the saber sounds if( infokey(self.owner, "SaberWallHits") == "1" ) { traceline (self.owner.origin, self.owner.origin+ (v_forward * 64), false, self.owner); if(trace_fraction < 1.0 && trace_ent == world) { self.owner.SaberAir = 1; local entity sabertarg; sabertarg = spawn(); setmodel( sabertarg, ""); setsize( sabertarg, '0 0 0', '0 0 0'); sabertarg.owner = self.owner; setorigin( sabertarg, self.owner.origin + v_forward * 10 ); if(self.owner.SaberSide == -5) { self.owner.SoundChoice = rint(random()* 3); if(self.owner.SoundChoice == 0) { sound(self, CHAN_ITEM, "lsaber/saberhit1.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_BODY, "lsaber/saberhit1.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 1) { sound(self, CHAN_ITEM, "lsaber/saberhit1.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_BODY, "lsaber/saberhit1.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 2) { sound(self, CHAN_ITEM, "lsaber/saberhit2.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_BODY, "lsaber/saberhit2.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 3) { sound(self, CHAN_ITEM, "lsaber/saberhit3.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_BODY, "lsaber/saberhit3.wav", 1, ATTN_NORM); } } else { self.owner.SoundChoice = rint(random()* 3); if(self.owner.SoundChoice == 0) { sound(self, CHAN_VOICE, "lsaber/saberhit1.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_ITEM, "lsaber/saberhit1.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 1) { sound(self, CHAN_VOICE, "lsaber/saberhit1.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_ITEM, "lsaber/saberhit1.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 2) { sound(self, CHAN_VOICE, "lsaber/saberhit2.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_ITEM, "lsaber/saberhit2.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 3) { sound(self, CHAN_VOICE, "lsaber/saberhit3.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_ITEM, "lsaber/saberhit3.wav", 1, ATTN_NORM); } } remove (sabertarg); } } tracebox(self.owner.origin, VEC_HULL_MIN, VEC_HULL_MAX, self.owner.origin + (v_forward * 150), false, self.owner); if (trace_ent != world) { local entity sabertarg; sabertarg = spawn(); setmodel( sabertarg, ""); setsize( sabertarg, '0 0 0', '0 0 0'); sabertarg.owner = self.owner; setorigin( sabertarg, self.owner.origin + v_forward * 10 ); if(self.owner.SaberSide == -5) { self.owner.SoundChoice = rint(random()* 3); if(self.owner.SoundChoice == 0) { sound(self, CHAN_ITEM, "lsaber/saberhit1.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_BODY, "lsaber/saberhit1.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 1) { sound(self, CHAN_ITEM, "lsaber/saberhit1.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_BODY, "lsaber/saberhit1.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 2) { sound(self, CHAN_ITEM, "lsaber/saberhit2.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_BODY, "lsaber/saberhit2.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 3) { sound(self, CHAN_ITEM, "lsaber/saberhit3.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_BODY, "lsaber/saberhit3.wav", 1, ATTN_NORM); } } else { self.owner.SoundChoice = rint(random()* 3); if(self.owner.SoundChoice == 0) { sound(self, CHAN_VOICE, "lsaber/saberhit1.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_ITEM, "lsaber/saberhit1.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 1) { sound(self, CHAN_VOICE, "lsaber/saberhit1.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_ITEM, "lsaber/saberhit1.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 2) { sound(self, CHAN_VOICE, "lsaber/saberhit2.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_ITEM, "lsaber/saberhit2.wav", 1, ATTN_NORM); } if(self.owner.SoundChoice == 3) { sound(self, CHAN_VOICE, "lsaber/saberhit3.wav", 1, ATTN_NORM); sound(sabertarg, CHAN_ITEM, "lsaber/saberhit3.wav", 1, ATTN_NORM); } if(self.owner.SaberSide == -5) { self.owner.SoundChoice = rint(random()* 5); if(self.owner.SoundChoice == 1) sound(sabertarg, CHAN_WEAPON, "lsaber/saberclash1.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 2) sound(sabertarg, CHAN_WEAPON, "lsaber/saberclash2.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 3) sound(sabertarg, CHAN_WEAPON, "lsaber/saberclash3.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 4) sound(sabertarg, CHAN_WEAPON, "lsaber/saberclash4.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 5) sound(sabertarg, CHAN_WEAPON, "lsaber/saberclash5.wav", 1, ATTN_NORM); } else { self.owner.SoundChoice = rint(random()* 5); if(self.owner.SoundChoice == 1) sound(sabertarg, CHAN_VOICE, "lsaber/saberclash1.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 2) sound(sabertarg, CHAN_VOICE, "lsaber/saberclash2.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 3) sound(sabertarg, CHAN_VOICE, "lsaber/saberclash3.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 4) sound(sabertarg, CHAN_VOICE, "lsaber/saberclash4.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 5) sound(sabertarg, CHAN_VOICE, "lsaber/saberclash5.wav", 1, ATTN_NORM); } trace_ent.deathtype = "lsaber"; T_Damage (trace_ent, self.owner, self.owner, (50 + random()* 100)); } remove (sabertarg); } else { if(!self.owner.SaberAir) { if(self.owner.SaberSide == -5) { self.owner.SoundChoice = rint(random()* 6); if(self.owner.SoundChoice == 0) sound(self, CHAN_ITEM, "lsaber/saberswing7.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 1) sound(self, CHAN_ITEM, "lsaber/saberswing1.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 2) sound(self, CHAN_ITEM, "lsaber/saberswing2.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 3) sound(self, CHAN_ITEM, "lsaber/saberswing3.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 4) sound(self, CHAN_ITEM, "lsaber/saberswing4.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 5) sound(self, CHAN_ITEM, "lsaber/saberswing5.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 6) sound(self, CHAN_ITEM, "lsaber/saberswing6.wav", 1, ATTN_NORM); } else { self.owner.SoundChoice = rint(random()* 6); if(self.owner.SoundChoice == 0) sound(self, CHAN_VOICE, "lsaber/saberswing7.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 1) sound(self, CHAN_VOICE, "lsaber/saberswing1.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 2) sound(self, CHAN_VOICE, "lsaber/saberswing2.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 3) sound(self, CHAN_VOICE, "lsaber/saberswing3.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 4) sound(self, CHAN_VOICE, "lsaber/saberswing4.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 5) sound(self, CHAN_VOICE, "lsaber/saberswing5.wav", 1, ATTN_NORM); if(self.owner.SoundChoice == 6) sound(self, CHAN_VOICE, "lsaber/saberswing6.wav", 1, ATTN_NORM); } } } self.owner.SaberAir = 0; self.owner.SaberSwing = 0; self.think = SaberMove; self.nextthink = time + 0.1; } } void SaberStart () { self.SaberOn = 1; self.show_hostile = time + 0.2; vector hilt; local entity sabertip; // spawn the saber itself sabertip = spawn (); sabertip.owner = self; self.saber = sabertip; sabertip.movetype = MOVETYPE_FLY; sabertip.solid = SOLID_NOT; setmodel (sabertip, ""); setsize (sabertip, '0 0 0', '0 0 0'); if((random()* 10) >5) { self.SaberSide = 5; } else { self.SaberSide = -5; } makevectors(self.angles); self.saberpos = self.origin + (v_forward * 10) + (v_right * self.SaberSide) + (v_up * 32); setorigin (sabertip, self.saberpos); sound(sabertip, CHAN_WEAPON, "lsaber/saberon.wav", 1, ATTN_NORM); sound(sabertip, CHAN_BODY, "lsaber/saberhum.wav", 1, ATTN_NORM); sabertip.velocity = sabertip.owner.velocity; sabertip.classname = "lsaber"; sabertip.think = SaberMove; sabertip.nextthink = time; } void SaberCheck () { if(self.HasYourSaber != "you") { // sprint(self, PRINT_MEDIUM, self.HasYourSaber); // sprint(self, PRINT_MEDIUM, " has your light saber\n"); // sprint(self, PRINT_MEDIUM, "You have no light saber\n"); if(self.HasYourSaber == "emp") { self.show_hostile = time + 0.2; if(rint(random()) < 0.5) sound(self, CHAN_AUTO, "emp/empdmg.wav", 1, ATTN_NORM); else sound(self, CHAN_AUTO, "emp/empdmg2.wav", 1, ATTN_NORM); return; } safe_soundtoclient(self, self, CHAN_WEAPON, "deny.wav", 1, ATTN_NORM); return; } // See if the player is in a mind trick if(self.Tricked) return; // check to see if the saber has already been triggered // and if it has, then swing it // and if it hasn't, then trigger it if(self.SaberSwing == 1) return; if(self.SaberOn) { self.show_hostile = time + 0.2; if(self.SaberSide == -5) { self.SaberSide = 5; } else { self.SaberSide = -5; } self.SaberSwing = 1; if(self.force > 250) self.takedamage = 0; else if(self.force > 200) { if(rint(random()*2) < 2) self.takedamage = 0; } else if(self.force > 150) { if(rint(random()*2) < 1) self.takedamage = 0; } else if(self.force <= 150) { if(rint(random()*3) == 1) self.takedamage = 0; } self.SaberTime = time + 0.2; } else { SaberStart(); } } /* void SaberCheck () { if(self.classname == "player") { // check to see if the saber has already been triggered // and if it has, then swing it // and if it hasn't, then trigger it if(self.SaberOn) { self.SaberSwing = 1; // sabertip.think = SaberMove; // sabertip.nextthink = time; } else { SaberStart(); } } if(self.classname == "lsaber") { if(self.owner.impulse == 64) { self.think = SaberOff; self.nextthink = time; } self.think = SaberMove; self.nextthink = time; } } */ /* ================ FireOneBullet Used by Sniper rifle and Pistol Go to the trouble of combining multiple pellets into a single damage call. ================ */ void FireOneBullet (float shotcount, vector dir, vector spread ,float damage) { self.show_hostile = time + 0.2; vector direction; vector src; float BulletRange; BulletRange = 10000; if(self.weapon == IT_PISTOL) BulletRange = 1000; makevectors(self.v_angle); src = self.origin + v_forward*10; src_z = self.absmin_z + self.size_z * 0.7; ClearMultiDamage (); traceline (src, src + dir*BulletRange, false, self); puff_org = trace_endpos - dir*4; while (shotcount > 0) { direction = dir + crandom()*spread_x*v_right + crandom()*spread_y*v_up; traceline (src, src + direction*BulletRange, false, self); if (trace_fraction != 1.0) TraceAttack (damage, direction); shotcount = shotcount - 1; } ApplyMultiDamage (); Multi_Finish (); } /* ================ W_FireSniper ================ */ void() W_FireSniper = { local vector dir; local float damage; damage = 120 + random()*50 + random()*50 + random()*20; if( infokey(self, "Silencer") == "1" ) { sound (self, CHAN_WEAPON, "sniper/snipersilencer.wav", 1, ATTN_NORM); } else { sound (self, CHAN_WEAPON, "sniper/rifle.wav", 1, ATTN_NORM); } self.currentammo = self.ammo_shells = self.ammo_shells - 3; dir = aim (self, 100000); FireOneBullet (1, dir, '0 0 0', damage); }; /* ================ W_FirePistol ================ */ void() W_FirePistol = { local vector dir; local float damage; makevectors(self.angles); traceline(self.origin + v_forward * 10, self.origin + v_forward * 64, false, self); if(trace_fraction != 1.0) { damage = 100; } else { traceline(self.origin + v_forward * 65, self.origin + v_forward * 200, false, self); if(trace_fraction != 1.0) { damage = 50; } else { traceline(self.origin + v_forward * 201, self.origin + v_forward * 2048, false, self); if(trace_fraction != 1.0) damage = 25; } } if( infokey(self, "Silencer") == "1" ) { sound (self, CHAN_WEAPON, "pistol/silencer.wav", 1, ATTN_NORM); } else { sound (self, CHAN_WEAPON, "pistol/pistol.wav", 1, ATTN_NORM); } self.currentammo = self.ammo_shells = self.ammo_shells - 1; dir = aim (self, 100000); FireOneBullet (1, dir, '0 0 0', damage); }; // CQ /* ================ W_FireShotgun ================ */ void W_FireShotgun () { vector dir; sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM); msg_entity = self; WriteByte (MSG_ONE, SVC_SMALLKICK); if (deathmatch != 4 ) self.currentammo = self.ammo_shells = self.ammo_shells - 1; dir = aim (self, 100000); FireBullets (6, dir, '0.04 0.04 0'); } /* ================ W_FireSuperShotgun ================ */ void W_FireSuperShotgun () { vector dir; if (self.currentammo == 1) { W_FireShotgun (); return; } sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM); msg_entity = self; WriteByte (MSG_ONE, SVC_BIGKICK); if (deathmatch != 4) self.currentammo = self.ammo_shells = self.ammo_shells - 2; dir = aim (self, 100000); FireBullets (14, dir, '0.14 0.08 0'); } /* ============================================================================== ROCKETS ============================================================================== */ void BlastExplode () { float damg; // if (deathmatch == 4) // { // if ( ((other.weapon == 32) || (other.weapon == 16))) // { // if (random() < 0.1) // { // if (other != world) // { // // bprint (PRINT_HIGH, "Got here\n"); // other.deathtype = "blaze"; // T_Damage (other, self, self.owner, 1000 ); // T_RadiusDamage (self, self.owner, 1000, other); // } // } // } // } if (other == self.owner) return; // don't explode on owner if (self.voided) { return; } self.voided = 1; if (pointcontents(self.origin) == CONTENT_SKY) { remove(self); return; } damg = 80 + random()*20; if (other.health) { other.deathtype = "blast"; T_Damage (other, self, self.owner, damg ); } // don't do radius damage to the other, because all the damage // was done in the impact T_RadiusDamage (self, self.owner, damg, other, "blast"); sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); self.origin = self.origin - 8 * normalize(self.velocity); WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_EXPLOSION); WriteCoord (MSG_MULTICAST, self.origin_x); WriteCoord (MSG_MULTICAST, self.origin_y); WriteCoord (MSG_MULTICAST, self.origin_z); multicast (self.origin, MULTICAST_PHS); remove(self); } void T_MissileTouch () { float damg; // if (deathmatch == 4) // { // if ( ((other.weapon == 32) || (other.weapon == 16))) // { // if (random() < 0.1) // { // if (other != world) // { // // bprint (PRINT_HIGH, "Got here\n"); // other.deathtype = "blaze"; // T_Damage (other, self, self.owner, 1000 ); // T_RadiusDamage (self, self.owner, 1000, other); // } // } // } // } if (other == self.owner) return; // don't explode on owner if (self.voided) { return; } self.voided = 1; if (pointcontents(self.origin) == CONTENT_SKY) { remove(self); return; } damg = 100 + random()*20; if (other.health) { other.deathtype = "rocket"; T_Damage (other, self, self.owner, damg ); } // don't do radius damage to the other, because all the damage // was done in the impact T_RadiusDamage (self, self.owner, 120, other, "rocket"); // sound (self, CHAN_WEAPON, "weapons/r_exp3.wav", 1, ATTN_NORM); self.origin = self.origin - 8 * normalize(self.velocity); WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_EXPLOSION); WriteCoord (MSG_MULTICAST, self.origin_x); WriteCoord (MSG_MULTICAST, self.origin_y); WriteCoord (MSG_MULTICAST, self.origin_z); multicast (self.origin, MULTICAST_PHS); remove(self); } /* ================ W_FireRocket ================ */ void W_FireRocket () { if (deathmatch != 4) self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; self.show_hostile = time + 0.2; sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM); msg_entity = self; WriteByte (MSG_ONE, SVC_SMALLKICK); newmis = spawn (); newmis.owner = self; newmis.RocketID = self.netname; newmis.movetype = MOVETYPE_FLYMISSILE; newmis.solid = SOLID_BBOX; // set newmis speed makevectors (self.v_angle); newmis.velocity = aim(self, 1000); newmis.velocity = newmis.velocity * 1000; newmis.angles = vectoangles(newmis.velocity); newmis.touch = T_MissileTouch; newmis.voided = 0; newmis.health = 1; newmis.force = 0; // set newmis duration newmis.MissileTime = time + 5; newmis.nextthink = time + 0.1; newmis.think = CruiseSound; newmis.classname = "rocket"; setmodel (newmis, "progs/missile.mdl"); setsize (newmis, '0 0 0', '0 0 0'); setorigin (newmis, self.origin + v_forward * 8 + '0 0 16'); } /* =============================================================================== LIGHTNING =============================================================================== */ void LightningHit (entity from, float damage) { WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_LIGHTNINGBLOOD); WriteCoord (MSG_MULTICAST, trace_endpos_x); WriteCoord (MSG_MULTICAST, trace_endpos_y); WriteCoord (MSG_MULTICAST, trace_endpos_z); multicast (trace_endpos, MULTICAST_PVS); T_Damage (trace_ent, from, from, damage); } /* ================= LightningDamage ================= */ void LightningDamage (vector p1, vector p2, entity from, float damage) { entity e1, e2; vector f; f = p2 - p1; normalize (f); f_x = 0 - f_y; f_y = f_x; f_z = 0; f = f*16; e1 = e2 = world; traceline (p1, p2, false, self); if (trace_ent.takedamage) { e1 = trace_ent; LightningHit (from, damage); if (self.classname == "player") { // check DM6 platform bug-o-feature if (self.groundentity == e1) if (e1.classname == "door") e1.velocity_z = e1.velocity_z + 400; } } traceline (p1 + f, p2 + f, false, self); if (trace_ent != e1 && trace_ent.takedamage) { e2 = trace_ent; LightningHit (from, damage); } traceline (p1 - f, p2 - f, false, self); if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage) { LightningHit (from, damage); } } void W_FireLightning () { vector org; float cells; if (self.ammo_cells < 1) { self.weapon = W_BestWeapon (); W_SetCurrentAmmo (); return; } // explode if under water if (self.waterlevel > 1) { if (deathmatch > 3) { if (random() <= 0.5) { self.deathtype = "selfwater"; T_Damage (self, self, self.owner, 4000 ); } else { cells = self.ammo_cells; self.ammo_cells = 0; W_SetCurrentAmmo (); // T_RadiusDamage (self, self, 35*cells, world, ""); self.deathtype = "electricwater"; // take away several frags for stupidity self.frags = self.frags - 5; RadiusEffects(self, self, 1000, "otherelectricwater", self, self); T_Damage (self, self, self, 4000 ); return; } } else { cells = self.ammo_cells; self.ammo_cells = 0; W_SetCurrentAmmo (); // T_RadiusDamage (self, self, 35*cells, world, ""); self.deathtype = "electricwater"; // take away several frags for stupidity self.frags = self.frags - 5; RadiusEffects(self, self, 1000, "otherelectricwater", self, self); T_Damage (self, self, self, 4000 ); return; } } if (self.t_width < time) { sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM); self.t_width = time + 0.6; } msg_entity = self; WriteByte (MSG_ONE, SVC_SMALLKICK); if (deathmatch != 4) self.currentammo = self.ammo_cells = self.ammo_cells - 1; org = self.origin + '0 0 16'; traceline (org, org + v_forward*600, true, self); WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_LIGHTNING2); WriteEntity (MSG_MULTICAST, self); WriteCoord (MSG_MULTICAST, org_x); WriteCoord (MSG_MULTICAST, org_y); WriteCoord (MSG_MULTICAST, org_z); WriteCoord (MSG_MULTICAST, trace_endpos_x); WriteCoord (MSG_MULTICAST, trace_endpos_y); WriteCoord (MSG_MULTICAST, trace_endpos_z); multicast (org, MULTICAST_PHS); LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30); } //============================================================================= void GrenadeExplode () { if (self.voided) { return; } self.voided = 1; T_RadiusDamage (self, self.owner, 120, world, "grenade"); WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_EXPLOSION); WriteCoord (MSG_MULTICAST, self.origin_x); WriteCoord (MSG_MULTICAST, self.origin_y); WriteCoord (MSG_MULTICAST, self.origin_z); multicast (self.origin, MULTICAST_PHS); // Incendiary Grenade if(self.frags == 1 && self.waterlevel < 1) { local entity FireCloud; FireCloud = spawn(); setmodel(FireCloud, "progs/s_explod.spr"); setsize(FireCloud, '-120 -120 -30', '120 120 30'); FireCloud.owner = self.owner; setorigin(FireCloud, self.origin); FireCloud.force = time + 5; sound(FireCloud, CHAN_ITEM, "ambience/fire1.wav", 1, ATTN_NORM); FireCloud.think = IncendiaryThink; FireCloud.nextthink = time; } remove (self); } void TeleGrenadeExplode () { self.owner.telegrenade = 2; if (self.voided) { return; } self.voided = 1; T_RadiusDamage (self, self.owner, 60, world, "grenade"); // teleport the player to this locale self.show_hostile = time + 0.2; sound(self.owner, CHAN_BODY, "telegrenade/r_tele5.wav", 1, ATTN_NORM); WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_EXPLOSION); WriteCoord (MSG_MULTICAST, self.origin_x); WriteCoord (MSG_MULTICAST, self.origin_y); WriteCoord (MSG_MULTICAST, self.origin_z); multicast (self.origin, MULTICAST_PHS); // if(self.owner.enemy.HookID == self.owner.netname) // { // self.owner.enemy.owner.impulse = 25; // } self.owner.impulse = 25; setorigin(self.owner, (self.origin + '0 0 80')); self.owner.telegrenade = 0; droptofloor(); self.owner.flags = self.owner.flags - self.owner.flags & FL_ONGROUND; remove (self); } void GrenadeTouch () { if (other == self.owner) return; // don't explode on owner if (other.takedamage == DAMAGE_AIM) { GrenadeExplode(); return; } // CQ if(self.watertype == CONTENT_WATER) { if(random() > 0.5) sound (self, CHAN_AUTO, "player/h2ojump.wav", 1, ATTN_NORM); // bounce sound else sound (self, CHAN_AUTO, "misc/h2ohit1.wav", 1, ATTN_NORM); // bounce sound } else sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound // CQ if (self.velocity == '0 0 0') self.avelocity = '0 0 0'; } void TeleGrenadeTouch () { if(self.watertype == CONTENT_WATER) { if(random() > 0.5) sound (self, CHAN_AUTO, "player/h2ojump.wav", 1, ATTN_NORM); // bounce sound else sound (self, CHAN_AUTO, "misc/h2ohit1.wav", 1, ATTN_NORM); // bounce sound } else sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound if (self.velocity == '0 0 0') self.avelocity = '0 0 0'; } /* ================ W_FireGrenade ================ */ void W_FireGrenade () { // Incendiary Grenade if(infokey(self, "IncendiaryGrenades") == "1" && self.ammo_rockets < 20) { sprint(self, PRINT_HIGH, "Not enough ammo for Incendiary Grenade!\n"); return; } self.show_hostile = time + 0.2; vector ang; if (deathmatch != 4) self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM); msg_entity = self; WriteByte (MSG_ONE, SVC_SMALLKICK); newmis = spawn (); newmis.voided=0; newmis.owner = self; newmis.RocketID = self.netname; newmis.movetype = MOVETYPE_BOUNCE; newmis.solid = SOLID_BBOX; newmis.classname = "grenade"; // Incendiary grenade if(infokey(self, "IncendiaryGrenades") == "1") { newmis.frags = 1; self.attack_finished = time + 4; self.currentammo = self.ammo_rockets = self.ammo_rockets - 19; } else newmis.frags = 0; // set newmis speed if (self.v_angle_x) { ang = self.v_angle; // limit pitch in case the server allows pitch angles < -70, // so that grenades still go straight up and not behind if (ang_x < -70) ang_x = -70; makevectors (ang); newmis.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10; } else { // assume the player is not using the mouse. FIXME: remove? newmis.velocity = aim(self, 10000); newmis.velocity = newmis.velocity * 600; newmis.velocity_z = 200; } newmis.avelocity = '300 300 300'; newmis.angles = vectoangles(newmis.velocity); newmis.touch = GrenadeTouch; newmis.health = 1; newmis.force = 0; // set newmis duration newmis.nextthink = time + 2.5; if (deathmatch == 4) { self.attack_finished = time + 1.1; T_Damage (self, self, self.owner, 10 ); } newmis.think = GrenadeExplode; setmodel (newmis, "progs/grenade.mdl"); setsize (newmis, '0 0 0', '0 0 0'); setorigin (newmis, self.origin); } void FireTeleGrenade () { if(self.freezed) return; if(time < self.emp) { self.show_hostile = time + 0.2; if(rint(random()) < 0.5) sound(self, CHAN_AUTO, "emp/empdmg.wav", 1, ATTN_NORM); else sound(self, CHAN_AUTO, "emp/empdmg2.wav", 1, ATTN_NORM); return; } self.show_hostile = time + 0.2; vector ang; if(self.telegrenade > 0) return; // can only have one at a time // if (deathmatch != 4) // self.currentammo = self.ammo_rockets = self.ammo_rockets - 1; sound (self, CHAN_WEAPON, "telegrenade/telegrenade.wav", 1, ATTN_NORM); msg_entity = self; WriteByte (MSG_ONE, SVC_SMALLKICK); newmis = spawn (); newmis.voided=0; newmis.owner = self; newmis.RocketID = self.netname; newmis.movetype = MOVETYPE_BOUNCE; newmis.solid = SOLID_BBOX; newmis.classname = "grenade"; // set newmis speed if (self.v_angle_x) { ang = self.v_angle; // limit pitch in case the server allows pitch angles < -70, // so that grenades still go straight up and not behind if (ang_x < -70) ang_x = -70; makevectors (ang); newmis.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10; } else { // assume the player is not using the mouse. FIXME: remove? newmis.velocity = aim(self, 10000); newmis.velocity = newmis.velocity * 600; newmis.velocity_z = 200; } newmis.avelocity = '300 300 300'; newmis.angles = vectoangles(newmis.velocity); newmis.touch = TeleGrenadeTouch; // set newmis duration newmis.nextthink = time + 2.5; if (deathmatch == 4) { self.attack_finished = time + 1.1; T_Damage (self, self, self.owner, 10 ); } newmis.think = TeleGrenadeExplode; setmodel (newmis, "progs/grenade.mdl"); setsize (newmis, '0 0 0', '0 0 0'); setorigin (newmis, self.origin); self.telegrenade = 1; } //============================================================================= void spike_touch (); void superspike_touch (); /* =============== launch_spike Used for both the player and the ogre =============== */ void launch_blast (vector org, vector dir) { self.show_hostile = time + 0.2; newmis = spawn (); newmis.voided=0; newmis.owner = self; newmis.movetype = MOVETYPE_FLYMISSILE; newmis.solid = SOLID_BBOX; newmis.angles = vectoangles(dir); if(infokey(self, "BlasterBounce") != "0") { newmis.touch = BlastBounce; newmis.bounces = 0; newmis.MissileTime = time + 3; newmis.think = BlastThink; newmis.nextthink = time + 0.1; } else { newmis.touch = BlastExplode; newmis.think = SUB_Remove; newmis.nextthink = time + 3; } // newmis.touch = spike_touch; newmis.classname = "spike"; setmodel (newmis, "progsblaster/laser.mdl"); setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); setorigin (newmis, org); newmis.velocity = dir * 2000; newmis.effects = newmis.effects | EF_BRIGHTLIGHT; } void launch_spike (vector org, vector dir) { newmis = spawn (); newmis.voided=0; newmis.owner = self; newmis.movetype = MOVETYPE_FLYMISSILE; newmis.solid = SOLID_BBOX; newmis.angles = vectoangles(dir); newmis.touch = spike_touch; newmis.classname = "spike"; newmis.think = SUB_Remove; newmis.nextthink = time + 6; setmodel (newmis, "progs/spike.mdl"); setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); setorigin (newmis, org); newmis.velocity = dir * 2000; } void W_FireSuperSpikes () { vector dir; sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM); self.attack_finished = time + 0.03; if (deathmatch != 4) self.currentammo = self.ammo_nails = self.ammo_nails - 2; dir = aim (self, 1000); launch_spike (self.origin + '0 0 16', dir); newmis.touch = superspike_touch; setmodel (newmis, "progs/s_spike.mdl"); setsize (newmis, VEC_ORIGIN, VEC_ORIGIN); msg_entity = self; WriteByte (MSG_ONE, SVC_SMALLKICK); } void W_FireBlaster (float ox) { // float BlastSound; vector dir; makevectors (self.v_angle); if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN) { W_FireSuperSpikes (); return; } if (self.ammo_cells < 2) { self.weapon = W_BestWeapon (); W_SetCurrentAmmo (); return; } // BlastSound = random()* 30; // if(BlastSound < 11) // { sound (self, CHAN_WEAPON, "blaster/blaster.wav", 1, ATTN_NORM); // } // else // { // sound (self, CHAN_WEAPON, "blaster/blaster2.wav", 1, ATTN_NORM); // } self.attack_finished = time + 0.2; if (deathmatch != 4) self.currentammo = self.ammo_cells = self.ammo_cells - 2; dir = aim (self, 1000); launch_blast (self.origin + '0 0 16' + v_right*ox, dir); msg_entity = self; WriteByte (MSG_ONE, SVC_SMALLKICK); } void W_FireSpikes (float ox) { vector dir; makevectors (self.v_angle); if (self.ammo_nails >= 2 && self.weapon == IT_SUPER_NAILGUN) { W_FireSuperSpikes (); return; } if (self.ammo_nails < 1) { self.weapon = W_BestWeapon (); W_SetCurrentAmmo (); return; } sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM); self.attack_finished = time + 0.03; if (deathmatch != 4) self.currentammo = self.ammo_nails = self.ammo_nails - 1; dir = aim (self, 1000); launch_spike (self.origin + '0 0 16' + v_right*ox, dir); msg_entity = self; WriteByte (MSG_ONE, SVC_SMALLKICK); } void spike_touch () { if (other == self.owner) return; if (self.voided) { return; } self.voided = 1; if (other.solid == SOLID_TRIGGER) return; // trigger field, do nothing if (pointcontents(self.origin) == CONTENT_SKY) { remove(self); return; } // hit something that bleeds if (other.takedamage) { spawn_touchblood (9); other.deathtype = "nail"; T_Damage (other, self, self.owner, 9); } else { WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); if (self.classname == "wizspike") WriteByte (MSG_MULTICAST, TE_WIZSPIKE); else if (self.classname == "knightspike") WriteByte (MSG_MULTICAST, TE_KNIGHTSPIKE); else WriteByte (MSG_MULTICAST, TE_SPIKE); WriteCoord (MSG_MULTICAST, self.origin_x); WriteCoord (MSG_MULTICAST, self.origin_y); WriteCoord (MSG_MULTICAST, self.origin_z); multicast (self.origin, MULTICAST_PHS); } remove(self); } void superspike_touch () { if (other == self.owner) return; if (self.voided) { return; } self.voided = 1; if (other.solid == SOLID_TRIGGER) return; // trigger field, do nothing if (pointcontents(self.origin) == CONTENT_SKY) { remove(self); return; } // hit something that bleeds if (other.takedamage) { spawn_touchblood (18); other.deathtype = "supernail"; T_Damage (other, self, self.owner, 18); } else { WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_SUPERSPIKE); WriteCoord (MSG_MULTICAST, self.origin_x); WriteCoord (MSG_MULTICAST, self.origin_y); WriteCoord (MSG_MULTICAST, self.origin_z); multicast (self.origin, MULTICAST_PHS); } remove(self); } /* // only works correctly for client entities! float(entity ent) EntityNum = { float num = 0; entity e; e = world; do { e = nextent(e); num = num + 1; } while (e != ent); return num; } void() W_FireRailgun = { float entnum; vector org, pos, end; vector dir; entity ignore, old_ignore; makevectors(self.v_angle); dir = v_forward; org = self.origin + v_forward * 10 + '0 0 16'; pos = org; end = org + v_forward*2048; ignore = old_ignore = self; do { traceline (pos, end, false, ignore); pos = trace_endpos; if (trace_ent == old_ignore || trace_ent == self) { // may happen if the entities are touching. // we don't want to apply damage twice or kill ourselves, // so move forward a little bit and retry pos = pos + dir; } else { // go right through all players and monsters, // but not through explosive boxes etc which are SOLID_BBOX if (trace_ent.solid == SOLID_SLIDEBOX) { old_ignore = ignore; ignore = trace_ent; } else ignore = world; if (trace_ent.takedamage) { T_Damage (trace_ent, self, self, 100); } } } while (ignore); // sound (self, CHAN_WEAPON, "weapons/railgun.wav", 1, ATTN_NORM); sound (self, CHAN_WEAPON, "weapons/lstart.wav", 1, ATTN_NORM); float color; color = floor(stof(infokey(self, "railcolor"))); if (color < 1 || color > 7) color = 1; entnum = EntityNum(self); WriteByte (MSG_MULTICAST, SVC_TEMPENTITY); WriteByte (MSG_MULTICAST, TE_LIGHTNING1); WriteShort (MSG_MULTICAST, -512 + (entnum - 1) * 8 + color); WriteCoord (MSG_MULTICAST, org_x); WriteCoord (MSG_MULTICAST, org_y); WriteCoord (MSG_MULTICAST, org_z); WriteCoord (MSG_MULTICAST, pos_x); WriteCoord (MSG_MULTICAST, pos_y); WriteCoord (MSG_MULTICAST, pos_z); multicast (org, MULTICAST_PHS); } */ /* =============================================================================== PLAYER WEAPON USE =============================================================================== */ void W_SetCurrentAmmo () { player_run (); // get out of any weapon firing states self.items = self.items - ( self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS) ); if (self.weapon == IT_AXE) { self.currentammo = 0; self.weaponmodel = "progs/v_axe.mdl"; self.weaponframe = 0; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 1; #endif } else if (self.weapon == IT_SHOTGUN) { self.currentammo = self.ammo_shells; self.weaponmodel = "progs/v_shot.mdl"; self.weaponframe = 0; self.items = self.items | IT_SHELLS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 2; #endif } else if (self.weapon == IT_SUPER_SHOTGUN) { self.currentammo = self.ammo_shells; self.weaponmodel = "progs/v_shot2.mdl"; self.weaponframe = 0; self.items = self.items | IT_SHELLS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 3; #endif } else if (self.weapon == IT_NAILGUN) { self.currentammo = self.ammo_nails; self.weaponmodel = "progs/v_nail.mdl"; self.weaponframe = 0; self.items = self.items | IT_NAILS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 4; #endif } else if (self.weapon == IT_SUPER_NAILGUN) { self.currentammo = self.ammo_nails; self.weaponmodel = "progs/v_nail2.mdl"; self.weaponframe = 0; self.items = self.items | IT_NAILS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 5; #endif } // CQ else if (self.weapon == IT_SLUG_THROWER) { self.currentammo = self.ammo_shells; self.weaponmodel = "progspistol/pistol.mdl"; self.weaponframe = 0; self.items = self.items | IT_SHELLS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 8; #endif } else if (self.weapon == IT_STUNGUN) { self.currentammo = self.ammo_cells; self.weaponmodel = "progs/v_light.mdl"; self.weaponframe = 0; self.items = self.items | IT_CELLS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 8; #endif } else if (self.weapon == IT_LIGHTSABER) { self.currentammo = 0; // set saber color // if(infokey(self, "SaberColor") == "Purple") // { // self.weaponmodel = "progssaber/purplesaber.mdl"; // sprint(self, PRINT_MEDIUM, "Purple Saber\n"); // } if(infokey(self, "SaberColor") == "Blue") { self.weaponmodel = "progssaber/bluesaber.mdl"; // sprint(self, PRINT_MEDIUM, "Blue Saber\n"); } else if(infokey(self, "SaberColor") == "Green") { self.weaponmodel = "progssaber/greensaber.mdl"; // sprint(self, PRINT_MEDIUM, "Green Saber\n"); } else if(infokey(self, "SaberColor") == "Red") { self.weaponmodel = "progssaber/redsaber.mdl"; // sprint(self, PRINT_MEDIUM, "Red Saber\n"); } else if(infokey(self, "SaberColor") == "Standard") { self.weaponmodel = "progssaber/lsaber.mdl"; // sprint(self, PRINT_MEDIUM, "Standard Blue Saber\n"); } else self.weaponmodel = "progssaber/lsaber.mdl"; // sprint(self, PRINT_MEDIUM, infokey(self, "SaberColor")); // sprint(self, PRINT_MEDIUM, "\n"); self.weaponframe = 0; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 1; #endif } else if (self.weapon == IT_BLASTER) { self.currentammo = self.ammo_cells; self.weaponmodel = "progs/v_light.mdl"; self.weaponframe = 0; self.items = self.items | IT_CELLS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 8; #endif } else if (self.weapon == IT_SNIPER) { self.SNAP_ESR_NAME_RANGE = 10000; self.ESRRange = 10000; self.currentammo = self.ammo_shells; self.weaponmodel = "progs/v_shot.mdl"; self.weaponframe = 0; self.items = self.items | IT_SHELLS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 3; #endif } else if (self.weapon == IT_PISTOL) { self.currentammo = self.ammo_shells; self.weaponmodel = "progspistol/pistol.mdl"; self.weaponframe = 0; self.items = self.items | IT_SHELLS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 2; #endif } //CQ else if (self.weapon == IT_GRENADE_LAUNCHER) { self.currentammo = self.ammo_rockets; self.weaponmodel = "progs/v_rock.mdl"; self.weaponframe = 0; self.items = self.items | IT_ROCKETS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 6; #endif } else if (self.weapon == IT_ROCKET_LAUNCHER) { self.currentammo = self.ammo_rockets; self.weaponmodel = "progs/v_rock2.mdl"; self.weaponframe = 0; self.items = self.items | IT_ROCKETS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 7; #endif } else if (self.weapon == IT_LIGHTNING) { self.currentammo = self.ammo_cells; self.weaponmodel = "progs/v_light.mdl"; self.weaponframe = 0; self.items = self.items | IT_CELLS; #ifdef VWEP_TEST if(vw_available > 0) self.vw_index = 8; #endif } else { self.currentammo = 0; self.weaponmodel = ""; self.weaponframe = 0; } // CQ if(self.weapon != IT_SNIPER) { self.SNAP_ESR_NAME_RANGE = 500; self.ESRRange = 10000; } if(self.weapon != IT_LIGHTSABER) SaberOff(); // CQ } float W_BestWeapon () { float it; it = self.items; if(self.ammo_cells >= 2 && (it & IT_BLASTER)) return IT_BLASTER; else if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & IT_LIGHTNING) ) return IT_LIGHTNING; else if(self.ammo_nails >= 2 && (it & IT_SUPER_NAILGUN) ) return IT_SUPER_NAILGUN; else if(self.ammo_shells >= 2 && (it & IT_SUPER_SHOTGUN) ) return IT_SUPER_SHOTGUN; else if(self.ammo_nails >= 1 && (it & IT_NAILGUN) ) return IT_NAILGUN; else if(self.ammo_shells >= 1 && (it & IT_SHOTGUN) ) return IT_SHOTGUN; /* if(self.ammo_rockets >= 1 && (it & IT_ROCKET_LAUNCHER) ) return IT_ROCKET_LAUNCHER; else if(self.ammo_rockets >= 1 && (it & IT_GRENADE_LAUNCHER) ) return IT_GRENADE_LAUNCHER; */ return IT_AXE; } float W_CheckNoAmmo () { if (self.currentammo > 0) return true; if (self.weapon == IT_AXE) return true; // CQ if(self.weapon == IT_LIGHTSABER) return true; if(self.weapon == IT_SNIPER && self.currentammo >= 3) return true; // CQ self.weapon = W_BestWeapon (); W_SetCurrentAmmo (); // drop the weapon down return false; } /* ============ W_Attack An attack impulse can be triggered now ============ */ void player_axe1 (); void player_axeb1 (); void player_axec1 (); void player_axed1 (); void player_shot1 (); void player_nail1 (); void player_light1 (); void player_rocket1 (); void W_Attack () { float r; if (!W_CheckNoAmmo ()) return; makevectors (self.v_angle); // calculate forward angle for velocity self.show_hostile = time + 1; // wake monsters up if (self.weapon == IT_AXE) { self.attack_finished = time + 0.5; sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM); r = random(); if (r < 0.25) player_axe1 (); else if (r<0.5) player_axeb1 (); else if (r<0.75) player_axec1 (); else player_axed1 (); } else if (self.weapon == IT_SHOTGUN) { player_shot1 (); self.attack_finished = time + 0.5; W_FireShotgun (); } else if (self.weapon == IT_SUPER_SHOTGUN) { player_shot1 (); self.attack_finished = time + 0.7; W_FireSuperShotgun (); } else if (self.weapon == IT_NAILGUN) { player_nail1 (); } // CQ else if (self.weapon == IT_SLUG_THROWER) { if(!self.semi) { player_shot1(); FireSlug(); // self.attack_finished = time + 0.1; self.semi = 1; } } else if (self.weapon == IT_STUNGUN) { if(time < self.emp) { if(rint(random()) < 0.5) sound(self, CHAN_AUTO, "emp/empdmg.wav", 1, ATTN_NORM); else sound(self, CHAN_AUTO, "emp/empdmg2.wav", 1, ATTN_NORM); return; } FireStun(); self.attack_finished = time + 0.3; } else if(self.weapon == IT_LIGHTSABER) { if(self.freezed) return; if(self.HasYourSaber != "you") { SaberCheck(); return; } if(!self.semi) { SaberCheck(); self.semi = 1; } } else if (self.weapon == IT_SNIPER) { if(!self.semi) { player_shot1(); W_FireSniper(); self.attack_finished = time + 1; self.semi = 1; } } else if (self.weapon == IT_PISTOL) { if(!self.semi) { if(self.PistolCount > 5) { sound(self, CHAN_WEAPON, "pistol/cockgun.wav", 1, ATTN_NORM); self.semi = 1; return; } else { player_shot1(); W_FirePistol(); self.attack_finished = time + 0.2; self.semi =1; } if(self.PistolCount == 5) self.PistolTime = time + 5; self.PistolCount = self.PistolCount + 1; } } else if (self.weapon == IT_BLASTER) { if(time < self.emp) { self.show_hostile = time + 0.2; if(rint(random()) < 0.5) sound(self, CHAN_AUTO, "emp/empdmg.wav", 1, ATTN_NORM); else sound(self, CHAN_AUTO, "emp/empdmg2.wav", 1, ATTN_NORM); return; } player_blaster1 (); } // CQ else if (self.weapon == IT_SUPER_NAILGUN) { player_nail1 (); } else if (self.weapon == IT_GRENADE_LAUNCHER) { player_rocket1(); self.attack_finished = time + 0.6; W_FireGrenade(); } else if (self.weapon == IT_ROCKET_LAUNCHER) { player_rocket1(); self.attack_finished = time + 0.8; W_FireRocket(); } else if (self.weapon == IT_LIGHTNING) { if(time < self.emp) { if(rint(random()) < 0.5) sound(self, CHAN_AUTO, "emp/empdmg.wav", 1, ATTN_NORM); else sound(self, CHAN_AUTO, "emp/empdmg2.wav", 1, ATTN_NORM); return; } self.attack_finished = time + 0.1; sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM); player_light1(); /* player_shot1 (); self.attack_finished = time + 1.5; // tune this! W_FireRailgun (); */ } } /* ============ W_ChangeWeapon ============ */ void W_ChangeWeapon () { float it, am, fl; it = self.items; am = 0; if (self.impulse == IMPULSE_AXE) { fl = IT_AXE; } else if (self.impulse == IMPULSE_SHOTGUN) { fl = IT_SHOTGUN; if (self.ammo_shells < 1) am = 1; } // CQ else if (self.impulse == IMPULSE_SLUG_THROWER) { fl = IT_SLUG_THROWER; if (self.ammo_shells < 5 || self.ammo_nails < 5) am = 1; } else if (self.impulse == IMPULSE_STUNGUN) { fl = IT_STUNGUN; if (self.ammo_cells < 10) am = 1; } else if(self.impulse == IMPULSE_SABER) { if(self.freezed) return; SaberCheck(); fl = IT_LIGHTSABER; } else if (self.impulse == IMPULSE_SNIPER) { fl = IT_SNIPER; if (self.ammo_shells < 3) am = 1; } else if (self.impulse == IMPULSE_PISTOL) { fl = IT_PISTOL; if (self.ammo_shells < 1) am = 1; } else if (self.impulse == IMPULSE_BLASTER) { fl = IT_BLASTER; if (self.ammo_cells < 2) am = 1; } // CQ else if (self.impulse == IMPULSE_SUPER_SHOTGUN) { fl = IT_SUPER_SHOTGUN; if (self.ammo_shells < 2) am = 1; } else if (self.impulse == IMPULSE_NAILGUN) { fl = IT_NAILGUN; if (self.ammo_nails < 1) am = 1; } else if (self.impulse == IMPULSE_SUPER_NAILGUN) { fl = IT_SUPER_NAILGUN; if (self.ammo_nails < 2) am = 1; } else if (self.impulse == IMPULSE_GRENADE_LAUNCHER) { fl = IT_GRENADE_LAUNCHER; if(infokey(self, "IncendiaryGrenades") == "1") { if (self.ammo_rockets < 20) am = 1; } else { if (self.ammo_rockets < 1) am = 1; } } else if (self.impulse == IMPULSE_ROCKET_LAUNCHER) { fl = IT_ROCKET_LAUNCHER; if (self.ammo_rockets < 1) am = 1; } else if (self.impulse == IMPULSE_LIGHTNING) { fl = IT_LIGHTNING; if (self.ammo_cells < 1) am = 1; } self.impulse = 0; if (!(self.items & fl)) { // don't have the weapon or the ammo #ifndef AGRIP sprint (self, PRINT_HIGH, "no weapon.\n"); #else soundtoclient (self, self, CHAN_WEAPON, "deny.wav", 1, ATTN_NORM); #endif return; } if (am) { // don't have the ammo #ifndef AGRIP sprint (self, PRINT_HIGH, "not enough ammo.\n"); #else soundtoclient (self, self, CHAN_WEAPON, "ammo-out.wav", 1, ATTN_NORM); #endif return; } // // set weapon, set ammo // self.weapon = fl; W_SetCurrentAmmo (); #ifdef AGRIP snap_misc_weaponswitch(); #endif } /* ============ CheatCommand ============ */ void CheatCommand () { if (!infokey(world, "*cheats")) return; self.ammo_shells = 100; self.ammo_nails = 200; self.ammo_rockets = 100; self.ammo_cells = 100; self.items = self.items | IT_AXE | IT_LIGHTSABER | IT_BLASTER | IT_SNIPER | IT_PISTOL | IT_STUNGUN | IT_SLUG_THROWER | IT_SHOTGUN | IT_SUPER_SHOTGUN | IT_NAILGUN | IT_SUPER_NAILGUN | IT_GRENADE_LAUNCHER | IT_ROCKET_LAUNCHER | IT_LIGHTNING | IT_KEY1 | IT_KEY2; self.weapon = IT_ROCKET_LAUNCHER; self.impulse = 0; W_SetCurrentAmmo (); } /* ============ CycleWeaponCommand Go to the next weapon with ammo ============ */ void CycleWeaponCommand () { float it, am; it = self.items; self.impulse = 0; while (1) { am = 0; if (self.weapon == IT_LIGHTNING) { self.weapon = IT_BLASTER; if (self.ammo_cells < 2) am = 1; } else if (self.weapon == IT_BLASTER) { self.weapon = IT_STUNGUN; if (self.ammo_cells < 10) am = 1; } else if (self.weapon == IT_STUNGUN) { self.weapon = IT_SLUG_THROWER; if (self.ammo_shells < 5 || self.ammo_nails < 5) am = 1; else sound(self, CHAN_WEAPON, "slug/slugthrower.wav", 1, ATTN_NORM); } else if (self.weapon == IT_SLUG_THROWER) { SaberCheck(); self.weapon = IT_LIGHTSABER; if(self.HasYourSaber != "you") am = 1; } else if(self.weapon == IT_LIGHTSABER) { self.weapon = IT_AXE; } else if (self.weapon == IT_AXE) { self.weapon = IT_SHOTGUN; if (self.ammo_shells < 1) am = 1; } else if (self.weapon == IT_SHOTGUN) { self.weapon = IT_SUPER_SHOTGUN; if (self.ammo_shells < 2) am = 1; } else if (self.weapon == IT_SUPER_SHOTGUN) { self.weapon = IT_PISTOL; if (self.ammo_shells < 1) am = 1; } else if (self.weapon == IT_PISTOL) { self.weapon = IT_SNIPER; if (self.ammo_shells < 3) am = 1; } else if(self.weapon == IT_SNIPER) { self.weapon = IT_NAILGUN; if (self.ammo_nails < 1) am = 1; } else if (self.weapon == IT_NAILGUN) { self.weapon = IT_SUPER_NAILGUN; if (self.ammo_nails < 2) am = 1; } else if (self.weapon == IT_SUPER_NAILGUN) { self.weapon = IT_GRENADE_LAUNCHER; if (self.ammo_rockets < 1) am = 1; } else if (self.weapon == IT_GRENADE_LAUNCHER) { self.weapon = IT_ROCKET_LAUNCHER; if (self.ammo_rockets < 1) am = 1; } else if (self.weapon == IT_ROCKET_LAUNCHER) { self.weapon = IT_LIGHTNING; if (self.ammo_cells < 1) am = 1; } if ( (self.items & self.weapon) && am == 0) { W_SetCurrentAmmo (); #ifdef AGRIP snap_misc_weaponswitch(); #endif return; } } } /* ============ CycleWeaponReverseCommand Go to the prev weapon with ammo ============ */ void CycleWeaponReverseCommand () { float it, am; it = self.items; self.impulse = 0; while (1) { am = 0; if (self.weapon == IT_LIGHTNING) { self.weapon = IT_ROCKET_LAUNCHER; if (self.ammo_rockets < 1) am = 1; } else if (self.weapon == IT_ROCKET_LAUNCHER) { self.weapon = IT_GRENADE_LAUNCHER; if (self.ammo_rockets < 1) am = 1; } else if (self.weapon == IT_GRENADE_LAUNCHER) { self.weapon = IT_SUPER_NAILGUN; if (self.ammo_nails < 2) am = 1; } else if (self.weapon == IT_SUPER_NAILGUN) { self.weapon = IT_NAILGUN; if (self.ammo_nails < 1) am = 1; } else if (self.weapon == IT_NAILGUN) { self.weapon = IT_SNIPER; if (self.ammo_shells < 3) am = 1; } else if(self.weapon == IT_SNIPER) { self.weapon = IT_PISTOL; if (self.ammo_shells < 1) am = 1; } else if(self.weapon == IT_PISTOL) { self.weapon = IT_SUPER_SHOTGUN; if (self.ammo_shells < 2) am = 1; } else if (self.weapon == IT_SUPER_SHOTGUN) { self.weapon = IT_SHOTGUN; if (self.ammo_shells < 1) am = 1; } else if (self.weapon == IT_SHOTGUN) { self.weapon = IT_AXE; } else if (self.weapon == IT_AXE) { SaberCheck(); self.weapon = IT_LIGHTSABER; if(self.HasYourSaber != "you") am = 1; } else if(self.weapon == IT_LIGHTSABER) { self.weapon = IT_SLUG_THROWER; if (self.ammo_shells < 5 || self.ammo_nails < 5) am = 1; else sound(self, CHAN_WEAPON, "slug/slugthrower.wav", 1, ATTN_NORM); } else if (self.weapon == IT_SLUG_THROWER) { self.weapon = IT_STUNGUN; if (self.ammo_cells < 10) am = 1; } else if (self.weapon == IT_STUNGUN) { self.weapon = IT_BLASTER; if (self.ammo_cells < 2) am = 1; } else if (self.weapon == IT_BLASTER) { self.weapon = IT_LIGHTNING; if (self.ammo_cells < 1) am = 1; } if ( (it & self.weapon) && am == 0) { W_SetCurrentAmmo (); #ifdef AGRIP snap_misc_weaponswitch(); #endif return; } } } /* ============ ServerflagsCommand Just for development ============ */ void ServerflagsCommand () { if (!infokey(world, "*cheats")) return; serverflags = serverflags * 2 + 1; } /* ============ ImpulseCommands ============ */ void ImpulseCommands () { // CQ impulses if(self.impulse == 78) RayShield(); if(self.impulse == 83) FireDart(); if(self.impulse == 81) W_ChangeWeapon (); if(self.impulse == 71) FJump(); // FIX ME if(self.impulse == 69) FLightning(); if(self.impulse == 70) MindTrick(); if(self.impulse == 79) EmpFire(); if(self.impulse == 20) DropDetpack(); if(self.impulse == 68) ForceDisArm(); if(self.impulse == 75) W_ChangeWeapon (); if(self.impulse == 73) FunTaunts(); if(self.impulse == 74) STTaunts(); if(self.impulse == 67) ForcePush(); if(self.impulse == 64) SaberOff(); if(self.impulse == 56) FireTeleGrenade(); if (self.impulse == 24) FireHook (); if (self.impulse == 25) BreakHook (); if (self.impulse >= IMPULSE_WEAPON_FIRST && self.impulse <= IMPULSE_WEAPON_LAST) W_ChangeWeapon (); else if (self.impulse >= 60 && self.impulse <= 63) W_ChangeWeapon (); else if (self.impulse == IMPULSE_CHEAT) CheatCommand (); else if (self.impulse == IMPULSE_WEAPONCYCLE_F) CycleWeaponCommand (); else if (self.impulse == IMPULSE_CHEAT_SERVERFLAGS) ServerflagsCommand (); else if (self.impulse == IMPULSE_WEAPONCYCLE_R) CycleWeaponReverseCommand (); #ifdef FRIKBOT else if (self.impulse == IMPULSE_ADDBOT) Cmd_AddBot("testbot", "2"); else if (self.impulse == IMPULSE_REMOVEBOT) KickABot(); #endif #ifdef AGRIP else agh_weapons_impulsecommands(); #endif self.impulse = 0; } /* ============ W_WeaponFrame Called every frame so impulse events can be handled as well as possible ============ */ void W_WeaponFrame () { if (time < self.attack_finished) { if(!(self.freezed)) { if(self.impulse == 71) FJump(); if (self.impulse == 24) FireHook (); if (self.impulse == 25) BreakHook (); } self.impulse = 0; return; } if (self.impulse) ImpulseCommands (); if(!self.button0) self.semi = 0; // check for attack if (self.button0) { SuperDamageSound (); W_Attack (); } } /* ======== SuperDamageSound Plays sound if needed ======== */ void SuperDamageSound () { if (self.super_damage_finished > time) { if (self.super_sound < time) { self.super_sound = time + 1; sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM); } } }