prozac-qfcc/weapons.qc

4578 lines
126 KiB
C++
Raw Normal View History

<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
2001-07-17 05:58:10 +00:00
/*======================================================
WEAPONS.QC Custom TeamFortress v3.1
(c) TeamFortress Software Pty Ltd 29/2/97
(c) William Kerney 5/21/00
========================================================
All the functions for firing all the weapons, holds
all new precache() functions, finding best weapons,
choosing next weapon, and all impulse commands.
======================================================*/
#include "defs.qh"
#include "menu.qh"
2001-07-17 05:58:10 +00:00
void() SniperSight_Update2; //CH for RL
void() I_DID_CHEAT_ONE; //CH for speed.qc
void() I_DID_CHEAT_TWO;
void() I_DID_CHEAT_THREE;
void(string gibname, float dm) ThrowGib;
void (entity targ, entity inflictor, entity attacker, float damage) T_Damage;
void (entity targ, entity inflictor, entity attacker, float damage, float T_flags, float T_AttackType) TF_T_Damage;
void () player_run;
void(entity bomb, entity attacker, float rad, entity ignore) T_RadiusDamage;
void() TeamFortress_DisplayDetectionItems;
vector(vector veca, vector vecb) crossproduct;
2001-07-17 05:58:10 +00:00
void(vector org, float damage) SpawnBlood;
void(entity rhook) Reset_Grapple;
void() SuperDamageSound;
float() W_BestWeapon;
void() ConcussionGrenadeTimer;
void() W_PrintWeaponMessage;
void() button_touch;
void() button_fire;
void() MauserRecoilThink;
float() ReturnWeaponVelocity;
vector() Grunty_LeadShot;
// TeamFortress Impulse Commands
void() TeamFortress_ChangeClass;
void() TeamFortress_DisplayLegalClasses;
void() TeamFortress_Inventory;
void() TeamFortress_SaveMe;
void(float inAuto) TeamFortress_ID;
void() TeamFortress_ShowTF;
void() TeamFortress_SniperWeapon;
void() TeamFortress_AssaultWeapon;
void() TeamFortress_IncendiaryCannon;
void() TeamFortress_FlameThrower;
void() TeamFortress_PrimeGrenade;
void() TeamFortress_ThrowGrenade;
void() TeamFortress_Discard;
void(entity p) TeamFortress_SetSpeed;
void() TeamFortress_DetonatePipebombs;
void() PipebombTouch;
void(float foo) TeamFortress_DetpackStop;
void(float type) SniperSight_Create;
void(float zoom_level) TF_zoom;
void() TeamFortress_ReloadCurrentWeapon;
void() TeamFortress_AutoZoomToggle;
void() TeamFortress_StatusQuery;
void() TeamFortress_SpyGoUndercover;
void(float type) TeamFortress_SpyFeignDeath;
void() TeamFortress_EngineerBuild;
void() DropKey;
void() UseSpecialSkill;
void() UseJobSkill; //WK Function for handling professions
void (entity targ, float pain) RevealThief;
void(vector startpos) GuerillaMineSweep;
void(entity foo,float bar) makeImmune;
float() CheckForReload;
void() SBBuildSensor;
void() SBFireInterface;
//void() SBInitiateInterface;
void() W_FireMauser;
void() W_FireDaedalus;
// TeamFortress Pre-Impulse Commands
void(float scanrange,float inAuto) TeamFortress_Scan;
void(float timer) TeamFortress_SetDetpack;
// Team Functions
float(float tno) TeamFortress_TeamSet;
void(float tno) TeamFortress_TeamShowScores;
void(entity Player) TeamFortress_TeamShowMemberClasses;
#ifdef DEMO_STUFF
// Camera Functions
void() CamLock;
void() CamDistLock;
void() CamVecLock;
void() CamAngleLock;
void() CamRevAngleLock;
void() CamProjectileLock;
void() CamProjectileZoom;
void() CamProjectileLockOn;
void() CamProjectileLockOff;
void() CamOffset;
void() CamDrop;
void() fadetoblack;
void() fadefromblack;
void() fadetowhite;
void() fadefromwhite;
#endif
// Engineer Functions
void(entity disp) Engineer_UseDispenser;
void(entity cam) Engineer_UseSensor;
void(entity gun) Engineer_UseSentryGun;
void(entity gun) Engineer_UseTesla;
void(entity cam) Engineer_UseCamera;
void(entity tele) Engineer_UseTeleporter;
void(entity field) Engineer_UseFieldGen;
void() Engineer_AutoUse;
2001-07-17 05:58:10 +00:00
void(entity spy) Spy_RemoveDisguise;
// Help functions
void() TeamFortress_MOTD;
void() TeamFortress_HelpMap;
void(float res) StatusRes;
// BioInfection functions
void() BioInfection_Decay;
void() BioInfection_MonsterDecay;
// Attacking functions
void() W_FireFlame;
void() W_FireIncendiaryCannon;
void() W_FireTranq;
void() W_FireLaser;
// Timer Functions
void() HallucinationTimer;
void() TranquiliserTimer;
// CTF Support functions
void() TeamFortress_CTF_FlagInfo;
// PC_UNDEFINED viewing functions
2001-07-17 05:58:10 +00:00
void() TF_MovePlayer;
//WK CustomTF Functions
void() custom_demon_precache;
void() custom_lay;
//void() CameraSwitchView;
//CH dropitems
void() TeamFortress_DropItems;
//- OfN -
void(entity player) ActivateHolo;
void(vector org, vector dir) grunty_spike;
void () UpdateInfos;
void() launch_horn;
void() player_laser1;
void(entity field) PutFieldWork;
void(entity tfield, vector where, entity thing) FieldExplosion;
// called by worldspawn
void() W_Precache =
{
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_sound ("wizard/wattack.wav"); // sniper rifle
precache_sound ("items/r_item1.wav"); // Medikit
precache_sound ("items/r_item2.wav"); // Medikit
precache_model ("progs/flame2.mdl"); // Flamethrower
precache_sound ("ambience/fire1.wav");
precache_sound2("blob/land1.wav"); // Hook
precache_model2("progs/v_spike.mdl"); // Hook
precache_sound ("hknight/hit.wav"); // Hook
// NEW FILES
precache_sound ("weapons/turrset.wav"); // Sentry Gun Setup
precache_sound ("weapons/turrspot.wav"); // Sentry Gun Spot
precache_sound ("weapons/turridle.wav"); // Sentry Gun Idle
precache_sound ("weapons/sniper.wav"); // sniper rifle
precache_sound ("weapons/flmfire2.wav"); // flamethrower
precache_sound ("weapons/flmgrexp.wav"); // flamethrower
2001-07-17 05:58:10 +00:00
precache_sound ("misc/vapeur2.wav"); // flamethrower
precache_sound ("weapons/asscan1.wav"); // Assault Cannon Powerup
precache_sound ("weapons/asscan2.wav"); // Assault Cannon Churning
precache_sound ("weapons/asscan3.wav"); // Assault Cannon Powerdown
precache_sound ("weapons/railgun.wav"); // Railgun
precache_sound ("weapons/dartgun.wav"); // Spy's dart gun
precache_sound ("ambience/thunder1.wav"); // Connect sound
2001-07-17 05:58:10 +00:00
//WK
// precache_model ("progs/v_merc.mdl"); //Carbine Model
// precache_sound ("weapons/carbfire.wav"); // Carbine shooting
// precache_sound ("weapons/carbreld.wav"); // Carbine shooting
// precache_sound ("weapons/carbrock.wav"); // Carbine shooting
// precache_sound ("weapons/nishi.wav"); // Nishi shooting
2001-07-17 05:58:10 +00:00
precache_model ("progs/telepad.mdl"); //Teleporter pad
precache_model ("progs/camera.mdl"); // Security Camera
precache_sound ("ambience/orff.wav"); // Chaplan sound
precache_sound ("weapons/guerilla_blip.wav"); // Landmine beep
precache_sound ("weapons/guerilla_set.wav"); // Landmine set
precache_sound ("weapons/camera_beep.wav"); // CH camera beep
precache_sound ("misc/enemy.wav"); // sensor alert
precache_sound ("weapons/fith.wav"); // WK Fire in the hole
// precache_model2("progs/guerilla_mine.mdl"); // The Landmine
// precache_model ("progs/tesla.mdl"); // The Tesla (by --Warrior--)
2001-07-17 05:58:10 +00:00
precache_model ("progs/minimissile.mdl"); // Swarm missile (BLOG)
// precache_model ("progs/newtesla.mdl"); // The Tesla (by --Warrior-- & BLOG)
precache_model ("progs/coil.mdl"); // The Tesla (by --Warrior-- & BLOG)
// precache_model ("progs/tscloak.mdl");
2001-07-17 05:58:10 +00:00
precache_model ("progs/tesgib1.mdl"); // Tesla Gib
precache_model ("progs/tesgib2.mdl"); // Tesla Gib
precache_model ("progs/tesgib3.mdl"); // Tesla Gib
precache_sound ("doors/medtry.wav"); //CH Dropping detpack sound
precache_sound ("doors/baseuse.wav"); //CH Detpack warning sound
precache_sound ("enforcer/sight1.wav"); // WK Taunt
precache_sound ("enforcer/sight2.wav"); // WK Taunt
precache_sound ("enforcer/sight3.wav"); // WK Taunt
precache_sound ("enforcer/sight4.wav"); // WK Taunt
custom_demon_precache();
};
float() crandom =
{
return 2*(random() - 0.5);
};
//======================================================================
// Calculate the attack_finished time
void(float att_delay) Attack_Finished =
{
if (self.tfstate & TFSTATE_TRANQUILISED)
2001-07-17 05:58:10 +00:00
self.attack_finished = time + (att_delay * 1.5);
else if (self.aura == AURA_HASTE)
2001-07-17 05:58:10 +00:00
self.attack_finished = time + (att_delay * 0.75);
else
self.attack_finished = time + att_delay;
};
/*
================
W_FireAxe
================
*/
void() W_FireAxe =
{
local vector source;
local vector org, def;
local vector dir = NIL; //XXX false +ve on uninit
2001-07-17 05:58:10 +00:00
if (self.classname == "player")
makevectors(self.v_angle);
else
dir = normalize (self.enemy.origin - self.origin);
source = self.origin + '0 0 16';
if (self.classname == "player") {
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
traceline (source, source + v_forward*64, FALSE, self);
2001-07-17 05:58:10 +00:00
else
traceline (source, source + v_forward*96, FALSE, self);
2001-07-17 05:58:10 +00:00
}
else
traceline (source, source + dir*64, FALSE, self);
2001-07-17 05:58:10 +00:00
if (trace_fraction == 1.0)
return;
org = trace_endpos - v_forward*4;
if (trace_ent.classname == "force_field") {
2001-07-17 05:58:10 +00:00
FieldExplosion(trace_ent,trace_endpos,trace_ent);
PutFieldWork(trace_ent);
return;
}
if (trace_ent.takedamage) {
2001-07-17 05:58:10 +00:00
trace_ent.axhitme = 1;
SpawnBlood (org, 20);
if (!(self.cutf_items & CUTF_KNIFE) || trace_ent.classname != "player") {
deathmsg = DMSG_AXE;
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
TF_T_Damage (trace_ent, self, self, 30, TF_TD_NOTTEAM, TF_TD_OTHER);
2001-07-17 05:58:10 +00:00
else
TF_T_Damage (trace_ent, self, self, 60, TF_TD_NOTTEAM, TF_TD_OTHER);
} else { // spy can try for the backstab!
2001-07-17 05:58:10 +00:00
//WK Only give blood if you hit an enemy when being a warlock
if ((!Teammate(trace_ent.team_no, self.team_no) || !(self.job & JOB_WARLOCK)) && prematch < time) {
self.job = self.job | JOB_BLOODY_KNIFE;
2001-07-17 05:58:10 +00:00
self.weaponmode = 1; // Put blood on the knife
self.weaponmodel = "progs/v_knife2.mdl";
} else if (self.job & JOB_WARLOCK) {
sprint(self,PRINT_HIGH,"You may only draw blood from enemies\n");
2001-07-17 05:58:10 +00:00
}
// Check direction of Attack
makevectors(trace_ent.v_angle);
def = v_right;
if (self.classname == "player")
makevectors(self.v_angle);
else
makevectors(self.angles);
// Backstab
if ((crossproduct(def,v_forward) * '0 0 1') > 0) {
deathmsg = DMSG_BACKSTAB;
2001-07-17 05:58:10 +00:00
ThrowGib("progs/gib1.mdl", -50);
ThrowGib("progs/gib2.mdl", 10);
ThrowGib("progs/gib3.mdl", 50);
ThrowGib ("progs/gib2.mdl", 25); //-added
//WK 120 & no IGNOREARMOR
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
TF_T_Damage (trace_ent, self, self, 100, TF_TD_IGNOREARMOUR | TF_TD_NOTTEAM, TF_TD_OTHER);
2001-07-17 05:58:10 +00:00
else
TF_T_Damage (trace_ent, self, self, 200, TF_TD_IGNOREARMOUR | TF_TD_NOTTEAM, TF_TD_OTHER);
} else {
deathmsg = DMSG_AXE;
2001-07-17 05:58:10 +00:00
//WK 40
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
TF_T_Damage (trace_ent, self, self, 50, TF_TD_NOTTEAM, TF_TD_OTHER);
2001-07-17 05:58:10 +00:00
else
TF_T_Damage (trace_ent, self, self, 100, TF_TD_NOTTEAM, TF_TD_OTHER);
2001-07-17 05:58:10 +00:00
}
}
} 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);
2001-07-17 05:58:10 +00:00
}
};
/*
================
W_FireSpanner
================
*/
void() W_FireSpanner =
{
local vector source;
local vector org;
2001-07-17 05:58:10 +00:00
local float healam;
local entity te;
makevectors(self.v_angle);
source = self.origin + '0 0 16';
if (self.cutf_items & CUTF_CLOSECOMBAT)
traceline (source, source + v_forward*96, FALSE, self);
2001-07-17 05:58:10 +00:00
else
traceline (source, source + v_forward*64, FALSE, self);
2001-07-17 05:58:10 +00:00
if (trace_fraction == 1.0)
return;
org = trace_endpos - v_forward*4;
if (trace_ent.classname == "force_field") {
2001-07-17 05:58:10 +00:00
FieldExplosion(trace_ent,trace_endpos,trace_ent);
PutFieldWork(trace_ent);
deathmsg = DMSG_SPANNERFIELD;
TF_T_Damage(self, self, self, self.health + 50, TF_TD_IGNOREARMOUR, TF_TD_OTHER);
sound (self, CHAN_MISC, "effects/crunch.wav", 1, ATTN_NONE);
2001-07-17 05:58:10 +00:00
return;
}
// It may be a trigger that can be activated by the engineer's spanner
if (trace_ent.goal_activation & TFGA_SPANNER) {
2001-07-17 05:58:10 +00:00
// Does the AP match the AP Criteria?
if (Activated(trace_ent,self)) {
DoResults(trace_ent, self, TRUE);
2001-07-17 05:58:10 +00:00
if (trace_ent.classname == "func_button") {
2001-07-17 05:58:10 +00:00
trace_ent.enemy = self;
other = self;
self = trace_ent;
self.dont_do_triggerwork = TRUE; // Already done in DoResults
2001-07-17 05:58:10 +00:00
button_fire();
self = other;
}
} else {
2001-07-17 05:58:10 +00:00
// If an else goal should be activated, activate it
if (trace_ent.else_goal != 0) {
2001-07-17 05:58:10 +00:00
te = Findgoal(trace_ent.else_goal);
if (te)
DoResults(te, self, (trace_ent.goal_result & TFGR_ADD_BONUSES));
} else {
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);
2001-07-17 05:58:10 +00:00
}
}
return;
}
if (trace_ent.takedamage) {
// auto-repair/dismantle if hit twice
if (trace_ent == self.building) {
Engineer_AutoUse();
return;
} else if (trace_ent.classname == "building_dispenser") {
2001-07-17 05:58:10 +00:00
Engineer_UseDispenser(trace_ent);
return;
} else if (trace_ent.classname == "building_sentrygun") {
2001-07-17 05:58:10 +00:00
Engineer_UseSentryGun(trace_ent);
return;
} else if (trace_ent.classname == "building_sentrygun_base") {
2001-07-17 05:58:10 +00:00
if (trace_ent.oldenemy)
Engineer_UseSentryGun(trace_ent.oldenemy);
return;
} else if (trace_ent.classname == "building_tesla") {
2001-07-17 05:58:10 +00:00
Engineer_UseTesla(trace_ent);
return;
} else if (trace_ent.classname == "building_camera") {
2001-07-17 05:58:10 +00:00
Engineer_UseCamera(trace_ent);
return;
} else if (trace_ent.classname == "building_sensor") {
2001-07-17 05:58:10 +00:00
Engineer_UseSensor(trace_ent);
return;
} else if (trace_ent.classname == "building_teleporter") {
2001-07-17 05:58:10 +00:00
Engineer_UseTeleporter(trace_ent);
return;
} else if (trace_ent.classname == "building_fieldgen") {
2001-07-17 05:58:10 +00:00
Engineer_UseFieldGen(trace_ent);
return;
} else {
if (trace_ent.classname == "player") {
if (Teammate(trace_ent.team_no, self.team_no) && (teamplay) || (coop)) {
healam = WEAP_SPANNER_REPAIR;
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < healam)
healam = self.ammo_cells;
// Only fix armor if they've got some
if (trace_ent.armor_allowed == 0) //WK
return;
if (trace_ent.armorvalue <= 0) // SB
return;
if (trace_ent.maxarmor - trace_ent.armorvalue < (healam * 4))
healam = ceil((trace_ent.maxarmor - trace_ent.armorvalue) / 4);
if (healam > 0) {
2001-07-17 05:58:10 +00:00
trace_ent.armorvalue = trace_ent.armorvalue + (healam * 4);
if (trace_ent.armorvalue > trace_ent.maxarmor)
trace_ent.armorvalue = trace_ent.maxarmor;
//WK Give them full armor color
trace_ent.armortype = trace_ent.armor_allowed;
self.ammo_cells = self.ammo_cells - healam;
sound(trace_ent, CHAN_WEAPON, "items/r_item1.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);
2001-07-17 05:58:10 +00:00
W_SetCurrentAmmo ();
}
return;
}
}
trace_ent.axhitme = 1;
SpawnBlood (org, 20);
deathmsg = DMSG_SPANNER;
2001-07-17 05:58:10 +00:00
//WK 20
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
TF_T_Damage (trace_ent, self, self, 20, TF_TD_NOTTEAM, TF_TD_OTHER);
2001-07-17 05:58:10 +00:00
else
TF_T_Damage (trace_ent, self, self, 40, TF_TD_NOTTEAM, TF_TD_OTHER);
2001-07-17 05:58:10 +00:00
}
} 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);
2001-07-17 05:58:10 +00:00
}
};
/*
================
W_FireMedikit
================
*/
void(entity ignore, entity ignore2, string st, string st2, string st3, string st4, string st5, string st6) teamsprintbi;
void(float tno, entity ignore, entity ignore2) teamprefixsprintbi;
void(float inAuto) W_FireMedikit =
{
local vector source;
local vector org;
local float healam;
local entity te, BioInfection;
source = self.origin + '0 0 16';
if (self.cutf_items & CUTF_CLOSECOMBAT)
traceline (source, source + v_forward*96, FALSE, self);
2001-07-17 05:58:10 +00:00
else
traceline (source, source + v_forward*64, FALSE, self);
2001-07-17 05:58:10 +00:00
if (trace_fraction == 1.0)
return;
org = trace_endpos - v_forward*4;
if (trace_ent.takedamage) {
if (trace_ent.classname == "player") {
if (Teammate(trace_ent.team_no, self.team_no) || (coop)) {
healam = WEAP_MEDIKIT_HEAL;
2001-07-17 05:58:10 +00:00
// remove concussion from player
// Try to find a concusstimer entity for this player
te = find(NIL, classname, "timer");
while (((te.owner != trace_ent) || (te.think != ConcussionGrenadeTimer)) && (te)) {
2001-07-17 05:58:10 +00:00
te = find(te, classname, "timer");
}
if (te) {
2001-07-17 05:58:10 +00:00
stuffcmd(trace_ent ,"v_idlescale 0\n");
SpawnBlood(org, 20);
sprint(trace_ent, PRINT_HIGH, "you have been healed of your concussion\n");
2001-07-17 05:58:10 +00:00
// Give the medic a frag for doing it, only if it was caused by an enemy
if (!Teammate(self.team_no,te.team_no)) {
2001-07-17 05:58:10 +00:00
self.real_frags = self.real_frags + 1;
if (!(toggleflags & TFLAG_TEAMFRAGS))
2001-07-17 05:58:10 +00:00
self.frags = self.real_frags;
}
dremove(te);
}
// remove hallucination from player
// Try to find a hallucination timer entity for this player
if (trace_ent.tfstate & TFSTATE_HALLUCINATING) {
te = find(NIL, classname, "timer");
while (((te.owner != trace_ent)
|| (te.think != HallucinationTimer)) && (te)) {
2001-07-17 05:58:10 +00:00
te = find(te, classname, "timer");
}
if (te) {
trace_ent.tfstate = trace_ent.tfstate - (trace_ent.tfstate & TFSTATE_HALLUCINATING);
2001-07-17 05:58:10 +00:00
SpawnBlood(org, 20);
sprint(trace_ent, PRINT_HIGH, "you have been healed of your hallucinations\n");
2001-07-17 05:58:10 +00:00
// Give the medic a frag for doing it, only if it was caused by an enemy
if (!Teammate(self.team_no,te.team_no)) {
2001-07-17 05:58:10 +00:00
self.real_frags = self.real_frags + 1;
if (!(toggleflags & TFLAG_TEAMFRAGS))
2001-07-17 05:58:10 +00:00
self.frags = self.real_frags;
}
dremove(te);
} else {
2001-07-17 05:58:10 +00:00
RPrint("Warning: Error in Hallucination Timer logic.\n");
}
}
// remove tranquilisation from player
// Try to find a tranquilisation timer entity for this player
if (trace_ent.tfstate & TFSTATE_TRANQUILISED) {
te = find(NIL, classname, "timer");
while (((te.owner != trace_ent) || (te.think != TranquiliserTimer)) && (te)) {
2001-07-17 05:58:10 +00:00
te = find(te, classname, "timer");
}
if (te) {
trace_ent.tfstate = trace_ent.tfstate - (trace_ent.tfstate & TFSTATE_TRANQUILISED);
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed(trace_ent);
SpawnBlood(org, 20);
sprint(trace_ent, PRINT_HIGH, "you have been healed of your tranquilisation\n");
2001-07-17 05:58:10 +00:00
// Give the medic a frag for doing it, only if it was caused by an enemy
if (!Teammate(self.team_no,te.team_no)) {
2001-07-17 05:58:10 +00:00
self.real_frags = self.real_frags + 1;
if (!(toggleflags & TFLAG_TEAMFRAGS))
2001-07-17 05:58:10 +00:00
self.frags = self.real_frags;
}
dremove(te);
} else {
2001-07-17 05:58:10 +00:00
RPrint("Warning: Error in Tranquilisation Timer logic.\n");
}
}
// check if the healed player is blinded
if (trace_ent.FlashTime > 0) {
te = find(NIL, netname, "flashtimer");
while ((te.owner != trace_ent || te.classname != "timer") && (te))
2001-07-17 05:58:10 +00:00
te = find(te, netname, "flashtimer");
if (te) {
2001-07-17 05:58:10 +00:00
trace_ent.FlashTime = 0;
SpawnBlood(org, 20);
// Give the medic a frag for doing it, only if it was caused by an enemy
stuffcmd(trace_ent, "v_cshift 0\n"); //WK -- /CH te -> trace_ent
stuffcmd(trace_ent, "r_norefresh 0;wait;echo;wait;echo;wait;echo;wait;echo\n"); //WK -- /CH te -> trace_ent
if (!Teammate(self.team_no,te.team_no)) {
2001-07-17 05:58:10 +00:00
self.real_frags = self.real_frags + 1;
if (!(toggleflags & TFLAG_TEAMFRAGS))
2001-07-17 05:58:10 +00:00
self.frags = self.real_frags;
}
dremove(te);
} else {
2001-07-17 05:58:10 +00:00
RPrint("Warning: Error in Flash Timer logic.\n");
trace_ent.FlashTime = 0;
}
}
// check if the healed player is infected
if (trace_ent.tfstate & TFSTATE_INFECTED) {
2001-07-17 05:58:10 +00:00
healam = rint(trace_ent.health / 2);
// remove the infection
trace_ent.tfstate = trace_ent.tfstate - (trace_ent.tfstate & TFSTATE_INFECTED);
2001-07-17 05:58:10 +00:00
// some damage is caused (because of the use of leeches!)
// remove half their remaining health
deathmsg = DMSG_MEDIKIT;
2001-07-17 05:58:10 +00:00
T_Damage(trace_ent, self, self, healam);
SpawnBlood(org, 30);
sprint(trace_ent, PRINT_HIGH,self.netname);
sprint(trace_ent, PRINT_HIGH, " cures your infection!\n");
2001-07-17 05:58:10 +00:00
if (self.classname == "player") {
sprint(self, PRINT_HIGH, "You have healed ");
sprint(self, PRINT_HIGH, trace_ent.netname);
sprint(self, PRINT_HIGH, " of the infection.\n");
2001-07-17 05:58:10 +00:00
teamprefixsprintbi(self.team_no, self, trace_ent);
teamsprintbi(self, trace_ent, trace_ent.netname,
" infection has been cured by ",
self.netname, "\n", "", "");
2001-07-17 05:58:10 +00:00
// Give the medic a frag for doing it, only if it was caused by an enemy
if (!Teammate(trace_ent.infection_team_no, self.team_no)) {
2001-07-17 05:58:10 +00:00
self.real_frags = self.real_frags + 1;
if (!(toggleflags & TFLAG_TEAMFRAGS))
2001-07-17 05:58:10 +00:00
self.frags = self.real_frags;
}
}
return;
}
// put out the fire if they are burning
if (trace_ent.numflames > 0) {
sound(trace_ent, CHAN_WEAPON, "items/r_item1.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
trace_ent.numflames = 0;
sprint(trace_ent, PRINT_HIGH, "The flames have been doused!\n");
2001-07-17 05:58:10 +00:00
if (self.classname == "player") {
sprint(self, PRINT_MEDIUM, "You have put out ");
sprint(self, PRINT_MEDIUM, trace_ent.netname);
sprint(self, PRINT_MEDIUM, "'s fire.\n");
2001-07-17 05:58:10 +00:00
}
return;
}
if (healam > 0 && trace_ent.health < trace_ent.max_health) {
sound(trace_ent, CHAN_WEAPON, "items/r_item1.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
trace_ent.axhitme = 1;
SpawnBlood (org, 20);
T_Heal(trace_ent, healam, 0);
} else if (trace_ent.health >= trace_ent.max_health && trace_ent.health < (trace_ent.max_health + WEAP_MEDIKIT_OVERHEAL)) {
2001-07-17 05:58:10 +00:00
healam = 10;
if (healam > (self.ammo_medikit * 10))
healam = (self.ammo_medikit * 10);
if (healam > 0) {
sound(trace_ent, CHAN_ITEM, "items/r_item2.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
T_Heal(trace_ent, healam, 1);
self.ammo_medikit = self.ammo_medikit - rint(healam / 10);
if (!(trace_ent.items & IT_SUPERHEALTH)) {
trace_ent.items = trace_ent.items | IT_SUPERHEALTH;
2001-07-17 05:58:10 +00:00
newmis = spawn();
newmis.classname = "medikit_rot";
newmis.nextthink = time + 20;
newmis.think = item_megahealth_rot;
newmis.owner = trace_ent;
}
}
}
}
#ifdef MEDIKIT_IS_BIOWEAPON
//WK Don't infect if they're invincible or observing
else if (!(trace_ent.invincible_finished) && !(trace_ent.playerclass == PC_UNDEFINED)) {
2001-07-17 05:58:10 +00:00
if (inAuto)
return;
trace_ent.axhitme = 1;
SpawnBlood (org, 20);
deathmsg = DMSG_BIOWEAPON_ATT;
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
2001-07-17 05:58:10 +00:00
T_Damage (trace_ent, self, self, 10);
else
T_Damage (trace_ent, self, self, 20);
if (trace_ent.weapons_carried & WEAP_MEDIKIT) //WK
2001-07-17 05:58:10 +00:00
return;
//Melee armor stops infection 75% of the time
if (trace_ent.tf_items & NIT_GEL && random() < 0.75)
2001-07-17 05:58:10 +00:00
return;
trace_ent.tfstate = trace_ent.tfstate | TFSTATE_INFECTED;
2001-07-17 05:58:10 +00:00
BioInfection = spawn ();
BioInfection.classname = "timer";
BioInfection.netname = "biotimer";
BioInfection.owner = trace_ent;
BioInfection.nextthink = time + 2;
BioInfection.think = BioInfection_Decay;
BioInfection.enemy = self;
trace_ent.infection_team_no = self.team_no;
}
#endif
} else if (IsMonster(trace_ent)) { //- OfN - //|| trace_ent.classname == "monster_fish")
if (Teammate(trace_ent.real_owner.team_no, self.team_no)) {
if (trace_ent.health < trace_ent.max_health) {
2001-07-17 05:58:10 +00:00
if (trace_ent.max_health - trace_ent.health < 50)
healam = trace_ent.max_health - trace_ent.health;
else
healam = 50;
if (healam > self.ammo_medikit)
healam = self.ammo_medikit;
if (healam == 0)
return;
sound(trace_ent, CHAN_WEAPON, "items/r_item1.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
trace_ent.axhitme = 1;
SpawnBlood (org, 20);
T_Heal(trace_ent, healam, 0);
self.ammo_medikit = self.ammo_medikit - healam;
if (trace_ent.health > trace_ent.max_health)
trace_ent.health = trace_ent.max_health;
}
}
2001-10-13 01:33:54 +00:00
} else {
trace_ent.axhitme = 1;
SpawnBlood (org, 30);
T_Damage (trace_ent, self, self, 10);
}
} else {
2001-07-17 05:58:10 +00:00
if (inAuto) return; //Don't click for automedic
// 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);
2001-07-17 05:58:10 +00:00
}
};
/*
================
W_FireBioweapon
================
*/
void() W_FireBioweapon =
{
local vector source;
local vector org;
local entity BioInfection;
source = self.origin + '0 0 16';
traceline (source, source + v_forward*64, FALSE, self);
2001-07-17 05:58:10 +00:00
if (trace_fraction == 1.0)
return;
org = trace_endpos - v_forward*4;
if (trace_ent.takedamage) {
if (trace_ent.classname == "player") {
if ((!Teammate(trace_ent.team_no, self.team_no) && teamplay) || teamplay == 0) {
2001-07-17 05:58:10 +00:00
trace_ent.axhitme = 1;
SpawnBlood (org, 20);
deathmsg = DMSG_BIOWEAPON_ATT;
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
2001-07-17 05:58:10 +00:00
T_Damage (trace_ent, self, self, 10);
else
T_Damage (trace_ent, self, self, 20);
if (trace_ent.weapons_carried & WEAP_MEDIKIT) //WK
2001-07-17 05:58:10 +00:00
return;
trace_ent.tfstate = trace_ent.tfstate | TFSTATE_INFECTED;
2001-07-17 05:58:10 +00:00
BioInfection = spawn ();
BioInfection.classname = "timer";
BioInfection.netname = "biotimer";
BioInfection.owner = trace_ent;
BioInfection.nextthink = time + 2;
BioInfection.think = BioInfection_Decay;
BioInfection.enemy = self;
trace_ent.infection_team_no = self.team_no;
}
} else if (trace_ent.flags & FL_MONSTER) {
if (trace_ent.classname == "monster_zombie") {
2001-07-17 05:58:10 +00:00
// zombie slayer!
T_Damage (trace_ent, self, self, 200);
}
trace_ent.axhitme = 1;
SpawnBlood(org, 20);
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
2001-07-17 05:58:10 +00:00
T_Damage (trace_ent, self, self, 10);
else
T_Damage (trace_ent, self, self, 20);
BioInfection = spawn ();
BioInfection.classname = "timer";
BioInfection.classname = "biotimer";
BioInfection.nextthink = time + 2;
BioInfection.think = BioInfection_MonsterDecay;
BioInfection.owner = self;
BioInfection.enemy = trace_ent;
} else { // must be a switch
2001-07-17 05:58:10 +00:00
trace_ent.axhitme = 1;
SpawnBlood (org, 30);
T_Damage(trace_ent, self, self, 40);
}
} 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);
2001-07-17 05:58:10 +00:00
}
};
//============================================================================
vector() wall_velocity =
{
local 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(vector org, vector vel) SpawnMeatSpray =
{
local entity missile;
missile = spawn ();
missile.owner = self;
missile.movetype = MOVETYPE_BOUNCE;
missile.solid = SOLID_NOT;
2001-07-17 05:58:10 +00:00
makevectors (self.angles);
missile.velocity = vel;
missile.velocity_z = missile.velocity_z + 250 + 50*random();
missile.avelocity = '3000 1000 2000';
// set missile duration
2001-07-17 05:58:10 +00:00
missile.nextthink = time + 1;
missile.think = SUB_Remove;
setmodel (missile, "progs/zom_gib.mdl");
setsize (missile, '0 0 0', '0 0 0');
setorigin (missile, org);
};
/*
================
SpawnBlood
================
*/
void(vector org, float damage) SpawnBlood =
{
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);
2001-07-17 05:58:10 +00:00
};
/*
================
spawn_touchblood
================
*/
void(float damage) spawn_touchblood =
{
local vector vel;
vel = wall_velocity () * 0.2;
SpawnBlood (self.origin + vel*0.01, damage);
};
/*
================
SpawnChunk
================
*/
void(vector org, vector vel) SpawnChunk =
{
particle (org, vel*0.02, 0, 10);
};
/*
==============================================================================
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 = NIL;
2001-07-17 05:58:10 +00:00
multi_damage = 0;
blood_count = 0;
puff_count = 0;
};
void() ApplyMultiDamage =
{
if (!multi_ent)
return;
// don't set deathmsg here, since it'll be set by the weapon that fired
if (self.current_weapon & WEAP_LIGHT_ASSAULT)
TF_T_Damage (multi_ent, self, self, multi_damage, TF_TD_NOTTEAM, TF_TD_NAIL);
2001-07-17 05:58:10 +00:00
else
TF_T_Damage (multi_ent, self, self, multi_damage, TF_TD_NOTTEAM, TF_TD_SHOT);
2001-07-17 05:58:10 +00:00
};
void(entity hit, float damage) AddMultiDamage =
{
if (!hit)
return;
if (hit != multi_ent) {
2001-07-17 05:58:10 +00:00
ApplyMultiDamage ();
multi_damage = damage;
multi_ent = hit;
} else
2001-07-17 05:58:10 +00:00
multi_damage = multi_damage + damage;
};
void (integer big) Multi_Finish =
2001-07-17 05:58:10 +00:00
{
if (puff_count) {
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_GUNSHOT);
WriteByte (MSG_MULTICAST, big ? puff_count * 2 : 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);
2001-07-17 05:58:10 +00:00
}
if (blood_count) {
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_BLOOD);
WriteByte (MSG_MULTICAST, big ? blood_count * 2 : puff_count);
WriteCoord (MSG_MULTICAST, blood_org_x);
WriteCoord (MSG_MULTICAST, blood_org_y);
WriteCoord (MSG_MULTICAST, blood_org_z);
multicast (puff_org, MULTICAST_PVS);
2001-07-17 05:58:10 +00:00
}
};
/*
==============================================================================
BULLETS
==============================================================================
*/
/*
================
TraceAttack
================
*/
void (float damage, vector dir) TraceAttack =
2001-07-17 05:58:10 +00:00
{
local vector vel, org;
2001-07-17 05:58:10 +00:00
vel = normalize (dir + v_up * crandom() + v_right * crandom());
vel = vel + 2 * trace_plane_normal;
2001-07-17 05:58:10 +00:00
vel = vel * 200;
org = trace_endpos - v_forward * 4;
2001-07-17 05:58:10 +00:00
//WK Sweep mines at the end of the attack
GuerillaMineSweep (trace_endpos);
2001-07-17 05:58:10 +00:00
if (damage && trace_ent.takedamage) {
blood_org = org;
blood_count++;
2001-07-17 05:58:10 +00:00
AddMultiDamage (trace_ent, damage);
} else {
puff_org = org;
puff_count++;
if (trace_ent.classname == "force_field") { //- OfN - Makes field explosion b4 removing it
FieldExplosion(trace_ent,trace_endpos,trace_ent);
PutFieldWork(trace_ent);
}
2001-07-17 05:58:10 +00:00
}
};
/*
================
FireBullets
Used by shotgun, super shotgun, assault cannon, and enemy soldier firing
Go to the trouble of combining multiple pellets into a single damage call.
================
*/
void(float shotcount, vector dir, vector spread) FireBullets =
{
local vector direction;
local vector src;
makevectors (self.v_angle);
2001-07-17 05:58:10 +00:00
src = self.origin + v_forward * 10;
2001-07-17 05:58:10 +00:00
src_z = self.absmin_z + self.size_z * 0.7;
ClearMultiDamage ();
while (shotcount > 0) {
direction = dir + crandom() * spread_x * v_right + crandom() * spread_y * v_up;
if (self.current_weapon & WEAP_ASSAULT_CANNON)
traceline (src, src + direction * 2048, FALSE, self);
else
traceline (src, src + direction * 1024, FALSE, self);
if (trace_fraction == 1.0)
TraceAttack (0, direction);
else if (self.current_weapon & WEAP_ASSAULT_CANNON) //WK Sinth's bugfix
TraceAttack (8, direction); //WK(12) (6) Reversed from 2.5
else if (self.current_weapon & WEAP_LIGHT_ASSAULT)
TraceAttack (3, direction);
else
TraceAttack (6, direction); //WK 4
2001-07-17 05:58:10 +00:00
shotcount--;
2001-07-17 05:58:10 +00:00
}
ApplyMultiDamage ();
Multi_Finish (TRUE);
2001-07-17 05:58:10 +00:00
};
/*
================
W_FireShotgun
================
*/
void() W_FireShotgun =
{
local vector dir;
sound (self, CHAN_WEAPON, "weapons/guncock.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
if (self.classname == "player")
KickPlayer(-2, self);
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
if (self.classname == "player")
dir = aim (self, 100000);
else {
2001-07-17 05:58:10 +00:00
dir = self.enemy.origin - self.enemy.velocity * (0.08 / self.has_sensor);
dir = normalize (dir - self.origin);
}
deathmsg = DMSG_SHOTGUN;
FireBullets (6, dir, '0.03 0.03 0');
2001-07-17 05:58:10 +00:00
};
/*
================
W_FireSuperShotgun
================
*/
void() W_FireSuperShotgun =
{
local vector dir;
if (self.currentammo == 1) {
2001-07-17 05:58:10 +00:00
W_FireShotgun ();
return;
}
sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
if (self.classname == "player")
KickPlayer(-4, self);
self.currentammo = self.ammo_shells = self.ammo_shells - 2;
if (self.classname == "player")
dir = aim (self, 100000);
else {
2001-07-17 05:58:10 +00:00
dir = self.enemy.origin - self.enemy.velocity * (0.08 / self.has_sensor);
dir = normalize (dir - self.origin);
}
deathmsg = DMSG_SSHOTGUN;
FireBullets (6, dir, '0.11 0.06 0'); //WK 14, 0.14, 0.08
FireBullets (6, dir, '0.11 0.06 0');
2001-07-17 05:58:10 +00:00
};
/*
================
FireSniperBullet
Used by sniper rifle firing (W_FireSniperRifle)
================
*/
void(vector direction, float damage) FireSniperBullet =
{
local vector src;
makevectors (self.v_angle);
2001-07-17 05:58:10 +00:00
src = self.origin + v_forward * 10;
2001-07-17 05:58:10 +00:00
src_z = self.absmin_z + self.size_z * 0.7;
ClearMultiDamage ();
traceline (src, src + direction * 4096, FALSE, self);
2001-07-17 05:58:10 +00:00
if (trace_fraction == 1.0)
TraceAttack (0, direction);
else
2001-07-17 05:58:10 +00:00
TraceAttack (damage, direction);
ApplyMultiDamage ();
Multi_Finish (FALSE);
2001-07-17 05:58:10 +00:00
};
/*
=================================
TeamFortress : W_FireSniperRifle
=================================
*/
void() W_FireSniperRifle =
{
local vector dir, src;
local float dam_mult, zdif, use_this, ign_mult = 0;
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
local vector angle;
2001-07-17 05:58:10 +00:00
sound (self ,CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
KickPlayer(-2, self);
// self.currentammo = self.ammo_shells = self.ammo_shells - 1; // ofn moved!
2001-07-17 05:58:10 +00:00
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
angle = self.v_angle;
if (self.heat < vlen(self.velocity) * 0.1)
self.heat = vlen(self.velocity) * 0.1;
if (!(self.flags & FL_ONGROUND) && self.heat < 100)
self.heat = 100;
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
if (self.heat > 0) {
angle_x += (random() * 0.08 * self.heat) - (0.04 * self.heat);
angle_y += (random() * 0.08 * self.heat) - (0.04 * self.heat);
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
}
makevectors(angle);
2001-07-17 05:58:10 +00:00
src = self.origin + v_forward * 10;
src_z = self.absmin_z + self.size_z * 0.7;
dir = v_forward; //XXX is this correct?
use_this = FALSE;
traceline (src, src + dir*8092, FALSE, self);
if (trace_fraction != 1.0) {
if (trace_ent) {
if (trace_ent.classname == "player") {
use_this = TRUE;
2001-07-17 05:58:10 +00:00
}
}
}
KickPlayer(-4, self);
if (!use_this) {
2001-07-17 05:58:10 +00:00
// aim, 'cause no entity in sights
dir = aim (self, 10000); // this corrects the aiming slightly, for bad players
traceline (src, src + dir*3072, FALSE, self);
2001-07-17 05:58:10 +00:00
}
deathmsg = DMSG_SNIPERRIFLE;
dam_mult = 0;
local string st = infokey (NIL, "sniper_dmg");
if (st)
dam_mult = stof (st);
if (!dam_mult)
dam_mult = SNIPER_DMG;
2001-07-17 05:58:10 +00:00
if (self.cutf_items & CUTF_OTR)
{
ign_mult=dam_mult*OTR_IGNFACTOR;
dam_mult=dam_mult*OTR_DMGFACTOR;
}
2001-07-17 05:58:10 +00:00
self.ammo_shells -= 5;
W_SetCurrentAmmo();
2001-07-17 05:58:10 +00:00
if (trace_ent) {
if (trace_ent.classname == "player") {
2001-07-17 05:58:10 +00:00
local float x;
local vector f, g, h;
f = trace_endpos - src;
g_x = trace_endpos_x;
g_y = trace_endpos_y;
g_z = 0;
h_x = trace_ent.origin_x;
h_y = trace_ent.origin_y;
h_z = 0;
x = vlen(g - h);
f = (normalize(f) * x) + trace_endpos;
zdif = f_z - trace_ent.origin_z;
deathmsg = DMSG_SNIPERRIFLE;
2001-07-17 05:58:10 +00:00
trace_ent.head_shot_vector = '0 0 0';
if (zdif < 0) {
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
// leg shot doesn't hurt very much
dam_mult *= 0.40;
ign_mult *= 0.40;
if ((dam_mult + ign_mult) > SNIPER_MAXLEG)
{
dam_mult *= (dam_mult + ign_mult) / SNIPER_MAXLEG;
ign_mult *= (dam_mult + ign_mult) / SNIPER_MAXLEG;
}
2001-07-17 05:58:10 +00:00
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
if (trace_ent.armorvalue < 0.8)
trace_ent.leg_damage++;
2001-07-17 05:58:10 +00:00
//- OfN - OTR bullets do twice damage ----------//
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
if (self.cutf_items & CUTF_OTR) {
trace_ent.leg_damage++;
}
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed(trace_ent);
deathmsg = DMSG_SNIPERLEGSHOT;
2001-07-17 05:58:10 +00:00
//WK Kevlar ignored for snipers again.
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
//GR red armor has leg protection
2001-07-17 05:58:10 +00:00
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
if (trace_ent.armortype >= 0.7 && trace_ent.armorvalue > 0) {
TF_T_Damage (trace_ent, self, self, ign_mult, TF_TD_IGNOREARMOUR, TF_TD_SHOT);
TF_T_Damage (trace_ent, self, self, dam_mult, 0, TF_TD_SHOT);
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
} else {
TF_T_Damage (trace_ent, self, self, dam_mult + ign_mult, TF_TD_IGNOREARMOUR,0);
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
}
2001-07-17 05:58:10 +00:00
if (trace_ent.health > 0) {
if (self.cutf_items & CUTF_OTR) {
sprint(trace_ent, PRINT_MEDIUM, "Leg injury! That was OTR stuff!\n");
sprint(self, PRINT_MEDIUM, "OTR Leg shot - that'll slow him down!\n");
} else { //- not OTR..
sprint(trace_ent, PRINT_MEDIUM, "Leg injury!\n");
sprint(self, PRINT_MEDIUM, "Leg shot - that'll slow him down!\n");
}
2001-07-17 05:58:10 +00:00
}
return;
} else if (zdif > 20) {
2001-07-17 05:58:10 +00:00
// head shot
dam_mult *= 2;
ign_mult *= 2;
2001-07-17 05:58:10 +00:00
stuffcmd(trace_ent, "bf\n");
trace_ent.head_shot_vector = trace_ent.origin - self.origin;
deathmsg = DMSG_SNIPERHEADSHOT;
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
if (trace_ent.armortype > 0.5 && trace_ent.armorvalue > 0)
{
TF_T_Damage (trace_ent, self, self, ign_mult, TF_TD_IGNOREARMOUR, TF_TD_SHOT);
TF_T_Damage (trace_ent, self, self, dam_mult, 0, TF_TD_SHOT);
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
} else {
TF_T_Damage (trace_ent, self, self, dam_mult + ign_mult, TF_TD_IGNOREARMOUR, 0);
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
}
2001-07-17 05:58:10 +00:00
if (trace_ent.health > 0) {
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
if (self.cutf_items & CUTF_OTR) {
sprint(trace_ent, PRINT_MEDIUM, "Head injury! That was OTR stuff!\n");
sprint(self, PRINT_MEDIUM, "OTR Head shot - that's gotta hurt!\n");
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
} else {
sprint(trace_ent, PRINT_MEDIUM, "Head injury!\n");
sprint(self, PRINT_MEDIUM, "Head shot - that's gotta hurt!\n");
}
}
2001-07-17 05:58:10 +00:00
return;
} else
deathmsg = DMSG_SNIPERRIFLE;
TF_T_Damage (trace_ent, self, self, ign_mult, TF_TD_IGNOREARMOUR, TF_TD_SHOT);
2001-07-17 05:58:10 +00:00
}
}
ClearMultiDamage ();
if (trace_fraction == 1.0)
TraceAttack (0, dir);
else // if it hit something
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
TraceAttack (SNIPER_DMG * dam_mult, dir);
2001-07-17 05:58:10 +00:00
ApplyMultiDamage ();
Multi_Finish (FALSE);
2001-07-17 05:58:10 +00:00
};
#ifndef NO_AUTORIFLE
2001-07-17 05:58:10 +00:00
/*
===================================
TeamFortress : W_FireAutoRifle
===================================
*/
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
// same as sniper rifle
2001-07-17 05:58:10 +00:00
void() W_FireAutoRifle =
{
local vector dir;
2001-07-17 05:58:10 +00:00
sound (self ,CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
KickPlayer(-1, self);
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
makevectors(self.v_angle);
dir = v_forward;
deathmsg = DMSG_AUTORIFLE;
FireSniperBullet (dir, 8);
2001-07-17 05:58:10 +00:00
};
#endif
2001-07-17 05:58:10 +00:00
/*
================
TeamFortress : W_FireAssaultCannon
================
*/
void() W_FireAssaultCannon =
{
local vector dir;
KickPlayer(-4, self);
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
2001-07-17 05:58:10 +00:00
dir = aim (self, 100000);
deathmsg = DMSG_ASSAULTCANNON;
FireBullets (5, dir, '0.15 0.10 0');
2001-07-17 05:58:10 +00:00
};
/*
=========================================
Custom TeamFortress : W_FireLightAssault
=========================================
*/
void() W_FireLightAssault =
{
local vector dir;
if (self.ammo_nails < 1) {
2001-07-17 05:58:10 +00:00
self.current_weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
W_PrintWeaponMessage();
return;
}
sound (self, CHAN_WEAPON, "weapons/guncock.wav", 0.6, ATTN_NORM);
2001-07-17 05:58:10 +00:00
KickPlayer(-4, self);
makevectors(self.v_angle);
dir = v_forward;
deathmsg = DMSG_LIGHT_ASSAULT;
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
self.reload_light_assault = self.reload_light_assault + 1;
if (CheckForReload() == TRUE)
return;
FireBullets (5, dir, '0.05 0.05 0');
2001-07-17 05:58:10 +00:00
Attack_Finished(0.2);
};
/*
==============================================================================
ROCKETS
==============================================================================
*/
void() s_explode1 = [0, s_explode2] {};
void() s_explode2 = [1, s_explode3] {};
void() s_explode3 = [2, s_explode4] {};
void() s_explode4 = [3, s_explode5] {};
void() s_explode5 = [4, s_explode6] {};
void() s_explode6 = [5, SUB_Remove] {};
void() BecomeExplosion =
{
dremove(self);
};
void() T_MissileTouch =
{
local float damg;
local float bonus;
if (other.classname == "player" && other.playerclass == PC_UNDEFINED)
return;
if (pointcontents(self.origin) == CONTENTS_SKY) {
2001-07-17 05:58:10 +00:00
dremove(self);
return;
}
// Lowered from 120
damg = 100;
2001-07-17 05:58:10 +00:00
if (self.owner.classname == "trap_shooter" || self.owner.classname == "trap_spikeshooter" || self.owner.classname == "trap_tf_spikeshooter" || self.owner.classname == "trap_tf_shooter")
if (self.owner.dmg != 0)
damg = self.owner.dmg;
2001-07-17 05:58:10 +00:00
if (self.has_tesla) //Cluster rockets do less
damg = damg - 25;
deathmsg = self.weapon;
if (other.health) {
2001-07-17 05:58:10 +00:00
bonus = 10 + random()*20;
if (self.has_tesla)
bonus = 0;
TF_T_Damage (other, self, self.owner, damg+bonus, 0, TF_TD_EXPLOSION);
2001-07-17 05:58:10 +00:00
}
// don't do radius damage to the other, because all the damage
// was done in the impact
// Lowered from 120
T_RadiusDamage (self, self.owner, damg, other);
self.origin = self.origin - 8*normalize(self.velocity);
#ifdef DEMO_STUFF
// Remove any camera's locks on this missile
if (self.enemy)
CamProjectileLockOff();
#endif
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);
2001-07-17 05:58:10 +00:00
if (other.classname == "force_field") //- OfN - Makes field explosion b4 removing it
FieldExplosion(other,self.origin,self);
2001-07-17 05:58:10 +00:00
dremove(self);
};
//CH rocket tracker (taken from shalrath.qc)
void() Rocket_Track_Dot =
{
if (time > self.has_sentry) {
self.think = SUB_Remove;
} else {
2001-07-17 05:58:10 +00:00
local vector dir, vtemp;
local entity tg, sight;
sight = NIL;
tg = find (NIL, classname, "timer");
while (tg) {
2001-07-17 05:58:10 +00:00
if (tg.owner == self.owner && tg.think == SniperSight_Update2)
sight = tg;
tg = find(tg, classname, "timer");
}
if (sight) { //Found a sight
2001-07-17 05:58:10 +00:00
vtemp = sight.origin;
dir = normalize(vtemp - self.origin);
// if (self.owner.cluster_mode && !(self.has_tesla)) //Slow down main rocket
// self.velocity = dir * 500;
// else
2001-07-17 05:58:10 +00:00
if (self.owner.cluster_mode)
self.velocity = dir * 600;
else
self.velocity = dir * 900;
self.angles = vectoangles(self.velocity);
self.think = Rocket_Track_Dot;
//WK Add in cluster munitions support
if (self.has_tesla) { //We're a cluster, so act crazy
makevectors(self.angles);
self.v_angle = sight.origin; //Save last direction for losing sight
self.velocity = self.velocity + 300 * v_right * (random() - 0.5);
self.velocity = self.velocity + 300 * v_up * (random() - 0.5);
}
} else { //Lost sight of sight
2001-07-17 05:58:10 +00:00
if (self.has_tesla && self.v_angle != '0 0 0') {
vtemp = self.v_angle;
dir = normalize(vtemp - self.origin);
if (self.owner.cluster_mode && !(self.has_tesla)) //Slow down main rocket
self.velocity = dir * 900;
else
self.velocity = dir * 1000;
self.angles = vectoangles(self.velocity);
self.think = Rocket_Track_Dot;
makevectors(self.angles);
self.velocity = self.velocity + 300 * v_right * (random() - 0.5);
self.velocity = self.velocity + 300 * v_up * (random() - 0.5);
}
// self.velocity = 1000 * normalize(self.v_angle);
}
}
self.nextthink = time + 0.25;
};
/*
================
W_FireRocket
================
*/
void() W_FireRocket =
{
local float loops;
local vector olorigin, dir = NIL; //XXX false +ve for dir
2001-07-17 05:58:10 +00:00
loops = 0;
if (self.tf_items & NIT_CLUSTER_ROCKETS && self.cluster_mode == TRUE)
2001-07-17 05:58:10 +00:00
loops = 5;
while (loops >= 0) {
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
if (self.ammo_rockets < 0) {
self.currentammo = self.ammo_rockets = 0;
return;
}
if (loops == 0) {
sound (self, CHAN_WEAPON, "weapons/sgun1.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
if (self.classname == "player")
KickPlayer(-2, self);
}
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
newmis.classname = "rocket"; //- OfN - Checked on airfist
// set newmis speed
if (self.classname == "player") {
2001-07-17 05:58:10 +00:00
makevectors (self.v_angle);
dir = v_forward;
} else if (self.classname == "monster_army")
2001-07-17 05:58:10 +00:00
dir = Grunty_LeadShot();
2001-07-17 05:58:10 +00:00
newmis.velocity = dir;
if (!loops) { //WK Not a cluster Rocket
if (self.tf_items & NIT_CLUSTER_ROCKETS && self.cluster_mode == TRUE)
2001-07-17 05:58:10 +00:00
{ //Make lead rocket start slower too
if (self.tf_items & NIT_RL_LASER_SIGHT) //Cluster and sight to start
2001-07-17 05:58:10 +00:00
newmis.velocity = newmis.velocity * 400;
else
newmis.velocity = newmis.velocity * 600; //Cluster and no sight
} else
2001-07-17 05:58:10 +00:00
newmis.velocity = newmis.velocity * 900;
} else if (self.tf_items & NIT_RL_LASER_SIGHT) //Cluster and sight to start
2001-07-17 05:58:10 +00:00
newmis.velocity = newmis.velocity * 400;
else
newmis.velocity = newmis.velocity * 600; //Cluster and no sight
newmis.angles = vectoangles(newmis.velocity);
newmis.touch = T_MissileTouch;
// set newmis duration
if (self.tf_items & NIT_RL_LASER_SIGHT) {
2001-07-17 05:58:10 +00:00
newmis.nextthink = time + 0.1; //Because tracks a sight
if (loops)
newmis.nextthink = time + 0.5; //Delay one second to spread out
newmis.think = Rocket_Track_Dot;
newmis.has_sentry = time + 6;
} else {
newmis.nextthink = time + 4;
newmis.think = SUB_Remove;
}
newmis.weapon = DMSG_ROCKETL;
2001-07-17 05:58:10 +00:00
if (!loops)
setmodel (newmis, "progs/missile.mdl");
else
setmodel (newmis, "progs/minimissile.mdl"); //Diff model for swarm rockets
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, self.origin + dir*8 + '0 0 16');
if (loops) { //WK Vary the starting point of the cluster
traceline (self.origin, self.origin + v_forward*9192, FALSE, self); //Make this TRUE
2001-07-17 05:58:10 +00:00
newmis.v_angle = trace_endpos;
newmis.has_tesla = loops; //Tell the rocket it is a cluster
newmis.weapon = DMSG_CLUSTER_ROCKET;
2001-07-17 05:58:10 +00:00
olorigin = newmis.origin;
newmis.origin = newmis.origin + v_right * (random() * 120 - 60);
newmis.origin = newmis.origin + v_forward * (random() * 40);
newmis.origin = newmis.origin + v_up * (random() * 50 - 20);
olorigin = olorigin - newmis.origin; //Get vector to new point
olorigin = 200 * normalize(olorigin);
if (self.tf_items & NIT_RL_LASER_SIGHT) //Dont spread without sight
2001-07-17 05:58:10 +00:00
newmis.velocity = newmis.velocity + olorigin;
}
loops = loops - 1;
} //End while loops
#ifdef DEMO_STUFF
// Have we got a live camera in projectile mode?
if (live_camera)
CamProjectileLockOn();
#endif
};
/*
===============================================================================
LIGHTNING
===============================================================================
*/
void(entity from, float damage) LightningHit =
{
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);
TF_T_Damage (trace_ent, from, from, damage, TF_TD_NOTTEAM, TF_TD_ELECTRICITY);
2001-07-17 05:58:10 +00:00
};
/*
=================
LightningDamage
=================
*/
void(vector p1, vector p2, entity from, float damage) LightningDamage =
{
local entity e1, e2;
local vector f;
f = p2 - p1;
normalize (f);
f_x = 0 - f_y;
f_y = f_x;
f_z = 0;
f = f*16;
e1 = e2 = NIL;
2001-07-17 05:58:10 +00:00
traceline (p1, p2, FALSE, self);
2001-07-17 05:58:10 +00:00
//WK Sweep mines at point of impact
GuerillaMineSweep(trace_endpos);
deathmsg = DMSG_LIGHTNING;
2001-07-17 05:58:10 +00:00
if (trace_ent.takedamage)
LightningHit (from, damage);
2001-07-17 05:58:10 +00:00
e1 = trace_ent;
traceline (p1 + f, p2 + f, FALSE, self);
2001-07-17 05:58:10 +00:00
if (trace_ent != e1 && trace_ent.takedamage)
LightningHit (from, damage);
e2 = trace_ent;
traceline (p1 - f, p2 - f, FALSE, self);
2001-07-17 05:58:10 +00:00
if (trace_ent != e1 && trace_ent != e2 && trace_ent.takedamage)
LightningHit (from, damage);
};
void() W_FireLightning =
{
local vector org;
local float cells, damage;
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 1) {
2001-07-17 05:58:10 +00:00
self.current_weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
W_PrintWeaponMessage();
return;
}
// explode if under water
if (self.waterlevel > 1) {
2001-07-17 05:58:10 +00:00
cells = self.ammo_cells;
if (cells > 10)
cells = 10; //WK Don't allow detpacks on the fly!
2001-07-17 05:58:10 +00:00
self.ammo_cells = self.ammo_cells - cells;
W_SetCurrentAmmo ();
deathmsg = DMSG_LIGHTNING;
//WK T_RadiusDamage (self, self, 35*cells, NIL);
T_RadiusDamage (self, self, 20*cells, NIL);
2001-07-17 05:58:10 +00:00
Attack_Finished(5);
return;
}
if (self.t_width < time) {
sound (self, CHAN_WEAPON, "weapons/lhit.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
self.t_width = time + 0.6;
}
KickPlayer(-2, self);
if (self.ammo_cells > 300) {
damage = 25;
self.ammo_cells -= 15;
} else if (self.ammo_cells > 200) {
damage = 20;
self.ammo_cells -= 10;
} else if (self.ammo_cells > 100) {
damage = 17;
self.ammo_cells -= 4;
} else {
damage = 12;
self.ammo_cells -= 1.2;
2001-07-17 05:58:10 +00:00
}
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_cells;
org = self.origin + '0 0 16';
// OfN - Check for force field
traceline (org, org + v_forward*600, FALSE, self);
2001-07-17 05:58:10 +00:00
if (trace_ent.classname == "force_field") {
FieldExplosion(trace_ent,trace_endpos,trace_ent);
PutFieldWork(trace_ent);
2001-07-17 05:58:10 +00:00
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);
return;
}
//_------------------------------------_//
2001-07-17 05:58:10 +00:00
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);
2001-07-17 05:58:10 +00:00
LightningDamage (self.origin, trace_endpos + v_forward*4, self, damage);
2001-07-17 05:58:10 +00:00
};
//=============================================================================
float (float tno) num_team_pipebombs =
{
if (tno == 1)
return num_team_pipebombs_1;
if (tno == 2)
2001-07-17 05:58:10 +00:00
return num_team_pipebombs_2;
if (tno == 3)
2001-07-17 05:58:10 +00:00
return num_team_pipebombs_3;
if (tno == 4)
2001-07-17 05:58:10 +00:00
return num_team_pipebombs_4;
return 0;
};
void(float tno) ExplodeOldPipebomb =
{
local entity old;
local float index;
if (tno != 0) {
2001-07-17 05:58:10 +00:00
index = num_team_pipebombs(tno);
index = index - (MAX_WORLD_PIPEBOMBS / number_of_teams);
} else {
index = num_world_pipebombs - MAX_WORLD_PIPEBOMBS;
2001-07-17 05:58:10 +00:00
}
old = find(NIL, classname, "pipebomb");
while (index > 0) {
if (!old) {
2001-07-17 05:58:10 +00:00
RPrint("*** ERROR: ExplodeOldPipebomb. ***\n");
RPrint("*** Please report this. ***\n");
num_world_pipebombs = 0;
num_team_pipebombs_1 = 0;
num_team_pipebombs_2 = 0;
num_team_pipebombs_3 = 0;
num_team_pipebombs_4 = 0;
return;
}
if (old.owner.team_no == tno || tno == 0) {
2001-07-17 05:58:10 +00:00
old.nextthink = time + 0.5;
index = index - 1;
}
old = find(old, classname, "pipebomb");
}
};
void(float tno) increment_team_pipebombs =
{
if (tno == 1)
num_team_pipebombs_1 = num_team_pipebombs_1 + 1;
else if (tno == 2)
num_team_pipebombs_2 = num_team_pipebombs_2 + 1;
else if (tno == 3)
num_team_pipebombs_3 = num_team_pipebombs_3 + 1;
else if (tno == 4)
num_team_pipebombs_4 = num_team_pipebombs_4 + 1;
};
void(float tno) decrement_team_pipebombs =
{
if (tno == 1)
num_team_pipebombs_1 = num_team_pipebombs_1 - 1;
else if (tno == 2)
num_team_pipebombs_2 = num_team_pipebombs_2 - 1;
else if (tno == 3)
num_team_pipebombs_3 = num_team_pipebombs_3 - 1;
else if (tno == 4)
num_team_pipebombs_4 = num_team_pipebombs_4 - 1;
};
//=============================================================================
void() GrenadeExplode =
{
if (self.classname == "pipebomb") {
2001-07-17 05:58:10 +00:00
num_world_pipebombs = num_world_pipebombs - 1;
decrement_team_pipebombs(self.owner.team_no);
}
deathmsg = self.weapon;
T_RadiusDamage (self, self.owner, 120, NIL);
2001-07-17 05:58:10 +00:00
#ifdef DEMO_STUFF
// Remove any camera's locks on this missile
if (self.enemy)
CamProjectileLockOff();
#endif
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);
2001-07-17 05:58:10 +00:00
dremove(self);
};
void() GrenadeTouch =
{
if (other == self.owner)
return; // don't explode on owner
if (other.takedamage == DAMAGE_AIM) {
2001-07-17 05:58:10 +00:00
GrenadeExplode();
return;
}
sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); // bounce sound
2001-07-17 05:58:10 +00:00
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};
/*
================
W_FireGrenade
================
*/
void() W_FireGrenade =
{
self.currentammo = self.ammo_rockets = self.ammo_rockets - 1;
sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
KickPlayer(-2, self);
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_BOUNCE;
newmis.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
// Set grenade type based on firing mode
if (self.weaponmode == GL_NORMAL) {
newmis.weapon = DMSG_GRENADEL;
2001-07-17 05:58:10 +00:00
newmis.classname = "grenade";
newmis.skin = 1;
newmis.touch = GrenadeTouch;
newmis.nextthink = time + 2.5;
} else { // if (self.weaponmode == GL_PIPEBOMB)
if (self.team_no != 0) {
2001-07-17 05:58:10 +00:00
increment_team_pipebombs(self.team_no);
if (num_team_pipebombs(self.team_no) > (MAX_WORLD_PIPEBOMBS / number_of_teams))
2001-07-17 05:58:10 +00:00
ExplodeOldPipebomb(self.team_no);
} else {
2001-07-17 05:58:10 +00:00
num_world_pipebombs = num_world_pipebombs + 1;
if (num_world_pipebombs > MAX_WORLD_PIPEBOMBS)
2001-07-17 05:58:10 +00:00
ExplodeOldPipebomb(0);
}
newmis.classname = "pipebomb";
newmis.skin = 2;
newmis.touch = PipebombTouch;
newmis.nextthink = time + 120; // Remove pipebombs older than 2 minutes
newmis.weapon = DMSG_GREN_PIPE;
2001-07-17 05:58:10 +00:00
}
// set newmis speed
makevectors (self.v_angle);
if (self.v_angle_x)
newmis.velocity = v_forward*600 + v_up * 200 + crandom()*v_right*10 + crandom()*v_up*10;
else {
2001-07-17 05:58:10 +00:00
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.think = GrenadeExplode;
setmodel (newmis, "progs/grenade2.mdl");
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, self.origin);
#ifdef DEMO_STUFF
// Have we got a live camera in projectile mode?
if (live_camera)
CamProjectileLockOn();
#endif
};
//=============================================================================
void() spike_touch;
/*
===============
launch_spike
Used for both the player and the ogre
===============
*/
void(vector org, vector dir) launch_spike =
{
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
newmis.angles = vectoangles(dir);
newmis.touch = spike_touch;
newmis.weapon = DMSG_NAILGUN;
2001-07-17 05:58:10 +00:00
newmis.classname = "spike";
newmis.think = SUB_Remove;
newmis.nextthink = time + 6;
setmodel (newmis, "progs/spike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
2001-07-17 05:58:10 +00:00
setorigin (newmis, org);
newmis.velocity = dir * 1600; // was 1000
#ifdef DEMO_STUFF
// Have we got a live camera in projectile mode?
if (live_camera)
CamProjectileLockOn();
#endif
};
void() superspike_touch =
{
local float ndmg;
if (other == self.owner)
return;
if (other.solid == SOLID_TRIGGER)
2001-07-17 05:58:10 +00:00
return; // trigger field, do nothing
if (pointcontents(self.origin) == CONTENTS_SKY)
2001-07-17 05:58:10 +00:00
{
dremove(self);
return;
}
// hit something that bleeds
if (other.takedamage) {
2001-07-17 05:58:10 +00:00
spawn_touchblood (18);
deathmsg = self.weapon;
/*
// In QW, nail grens only launch 1 nail, and it does more damage.
if (deathmsg == DMSG_GREN_NAIL)
2001-07-17 05:58:10 +00:00
ndmg = 40;
else
*/
ndmg = 13;
if (self.owner.classname == "grenade")
TF_T_Damage (other, self, self.owner.owner, ndmg, TF_TD_NOTTEAM, TF_TD_NAIL);
2001-07-17 05:58:10 +00:00
else
TF_T_Damage (other, self, self.owner, ndmg, TF_TD_NOTTEAM, TF_TD_NAIL);
} else {
if (other.classname == "force_field") //- OfN - Makes field explosion b4 removing it
FieldExplosion(other,self.origin,self);
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);
}
2001-07-17 05:58:10 +00:00
}
dremove(self);
};
void() W_FireSuperSpikes =
{
local vector dir;
sound (self, CHAN_WEAPON, "weapons/spike2.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
Attack_Finished(0.2);
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;
newmis.weapon = DMSG_SNG;
2001-07-17 05:58:10 +00:00
setmodel (newmis, "progs/s_spike.mdl");
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
2001-07-17 05:58:10 +00:00
KickPlayer(-2, self);
};
void(float ox) W_FireSpikes =
{
if (self.ammo_nails >= 2 && self.current_weapon == WEAP_SNG) {
2001-07-17 05:58:10 +00:00
W_FireSuperSpikes ();
return;
}
local vector dir;
2001-07-17 05:58:10 +00:00
if (self.classname == "player")
makevectors (self.v_angle);
else
makevectors (self.angles);
if (self.ammo_nails < 1)
if (self.classname == "player") {
2001-07-17 05:58:10 +00:00
self.current_weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
W_PrintWeaponMessage();
return;
}
sound (self, CHAN_WEAPON, "weapons/rocket1i.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
Attack_Finished(0.2);
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
if (self.classname == "player") {
2001-07-17 05:58:10 +00:00
dir = aim (self, 1000);
launch_spike (self.origin + '0 0 16' + v_right*ox, dir);
KickPlayer(-2, self);
} else if (self.classname == "monster_army") { //- OfN -
2001-07-17 05:58:10 +00:00
dir = Grunty_LeadShot();
grunty_spike(self.origin + '0 0 16' + v_right*ox, dir);
}
};
//.float hit_z;
void() spike_touch =
{
if (other.solid == SOLID_TRIGGER)
2001-07-17 05:58:10 +00:00
return; // trigger field, do nothing
if (pointcontents(self.origin) == CONTENTS_SKY) {
2001-07-17 05:58:10 +00:00
dremove(self);
return;
}
//WK Sweep mines at point of impact
GuerillaMineSweep(self.origin);
// hit something that bleeds
if (other.takedamage) {
2001-07-17 05:58:10 +00:00
spawn_touchblood (9);
deathmsg = self.weapon;
//- OfN - Wizard projectiles do SCRAG_DMG damage
if (self.classname == "wizspike") {
2001-07-17 05:58:10 +00:00
local float wizdmg;
wizdmg = SCRAG_DMG;
2001-07-17 05:58:10 +00:00
if (other.classname == "player") {
if (other.cutf_items & CUTF_DEMONLORE) // if we have demon lore, it does less damage to us
2001-07-17 05:58:10 +00:00
wizdmg = wizdmg * 0.8;
}
TF_T_Damage (other, self, self.owner, wizdmg, TF_TD_NOTTEAM, 0);
sound (self, CHAN_MISC, "effects/crunch.wav", 0.4, ATTN_NORM); // any better sound?
} else if (self.owner.classname == "grenade") // - OfN -
TF_T_Damage (other, self, self.owner.owner, 12, TF_TD_NOTTEAM, TF_TD_NAIL);
else
TF_T_Damage (other, self, self.owner, 12, TF_TD_NOTTEAM, TF_TD_NAIL);
} else {
2001-07-17 05:58:10 +00:00
if (other.classname == "force_field") //- OfN - Makes field explosion b4 removing it
FieldExplosion(other,self.origin,self);
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);
}
2001-07-17 05:58:10 +00:00
}
#ifdef DEMO_STUFF
// Remove any camera's locks on this missile
if (self.enemy)
CamProjectileLockOff();
#endif
dremove(self);
};
/*
===============================================================================
PLAYER WEAPON USE
===============================================================================
*/
void() W_SetCurrentAmmo =
{
if (self.health <= 0 || self.current_weapon == 0)
return; // get out of any weapon firing states
player_run();
self.items = self.items & ~(IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS);
2001-07-17 05:58:10 +00:00
self.weapon = 0;
//WK Set armor here... update armor picture
self.items = self.items & ~(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3);
2001-07-17 05:58:10 +00:00
if (self.armortype >= 0.8)
self.items = self.items | IT_ARMOR3;
2001-07-17 05:58:10 +00:00
else if (self.armortype >= 0.6)
self.items = self.items | IT_ARMOR2;
2001-07-17 05:58:10 +00:00
else if (self.armortype >= 0.3)
self.items = self.items | IT_ARMOR1;
2001-07-17 05:58:10 +00:00
//WK Show nothing for custom playerclass while building
if ( self.playerclass == PC_CUSTOM
&& (self.done_custom & CUSTOM_BUILDING)) {
//We are building a class
2001-07-17 05:58:10 +00:00
self.currentammo = 0;
self.weaponmodel = "";
return;
}
if (self.current_weapon == WEAP_AXE) {
2001-07-17 05:58:10 +00:00
self.currentammo = 0;
if (self.cutf_items & CUTF_KNIFE) { //WK
if (self.job & JOB_BLOODY_KNIFE)
2001-07-17 05:58:10 +00:00
self.weaponmode = 1;
else
self.weaponmode = 0; //CH maybe fix bug that knife is bloody when not?
if (self.weaponmode == 0)
self.weaponmodel = "progs/v_knife.mdl"; //Nonbloody
else
self.weaponmodel = "progs/v_knife2.mdl"; //Bloody
} else
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_axe.mdl";
self.weaponframe = 0;
} else if (self.current_weapon == WEAP_HOOK) {
2001-07-17 05:58:10 +00:00
self.currentammo = 0;
self.weaponmodel = "progs/v_grap.mdl";
self.weaponframe = 0;
} else if (self.current_weapon == WEAP_SPANNER) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_cells;
self.weaponmodel = "progs/v_span.mdl";
self.weaponframe = 0;
} else if (self.current_weapon == WEAP_SHOTGUN) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_shells;
self.items = self.items | IT_CELLS;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_shot.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_SHELLS;
self.weapon = IT_SHOTGUN;
} else if (self.current_weapon == WEAP_SUPER_SHOTGUN) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_shells;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_shot2.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_SHELLS;
self.weapon = IT_SUPER_SHOTGUN;
} else if (self.current_weapon == WEAP_NAILGUN) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_nails;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_nail.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_NAILS;
self.weapon = IT_NAILGUN;
} else if (self.current_weapon == WEAP_LIGHT_ASSAULT) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_nails;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_nail2.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_NAILS;
self.weapon = IT_LIGHT_ASSAULT;
} else if (self.current_weapon == WEAP_GRENADE_LAUNCHER) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_rockets;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_rock.mdl";
self.weaponframe = 0;
}
self.weapon = IT_GRENADE_LAUNCHER;
self.items = self.items | IT_ROCKETS;
} else if (self.current_weapon == WEAP_ROCKET_LAUNCHER) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_rockets;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_rock2.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_ROCKETS;
self.weapon = IT_ROCKET_LAUNCHER;
} else if (self.current_weapon == WEAP_LIGHTNING) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_cells;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_light.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_CELLS;
self.weapon = IT_LIGHTNING;
} else if (self.current_weapon == WEAP_SNIPER_RIFLE) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_shells;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_srifle.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_SHELLS;
self.weapon = IT_SHOTGUN;
#ifndef NO_AUTORIFLE
} else if (self.current_weapon == WEAP_AUTO_RIFLE) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_shells;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_srifle.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_SHELLS;
self.weapon = IT_SUPER_SHOTGUN;
#endif
} else if (self.current_weapon == WEAP_ASSAULT_CANNON) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_shells;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_asscan.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_SHELLS;
self.weapon = IT_ROCKET_LAUNCHER;
} else if (self.current_weapon == WEAP_FLAMETHROWER) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_cells;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_rock.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_CELLS;
self.weapon = IT_GRENADE_LAUNCHER;
} else if (self.current_weapon == WEAP_INCENDIARY) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_rockets;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_rock2.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_ROCKETS;
self.weapon = IT_ROCKET_LAUNCHER;
} else if (self.current_weapon == WEAP_MEDIKIT) {
2001-07-17 05:58:10 +00:00
self.currentammo = 0;
self.weaponmodel = "progs/v_medi.mdl";
self.weaponframe = 0;
} else if (self.current_weapon == WEAP_TRANQ) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_nails;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_shot.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_NAILS;
self.weapon = IT_SHOTGUN;
} else if (self.current_weapon == WEAP_LASER) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_nails;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_rail.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_NAILS;
self.weapon = IT_SHOTGUN;
} else if (self.current_weapon == WEAP_DAEDALUS) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_cells;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_rock.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_CELLS;
self.weapon = IT_LIGHTNING;
} else if (self.current_weapon == WEAP_MAUSER) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_nails;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_rail.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_NAILS;
self.weapon = IT_LIGHT_ASSAULT;
} else if (self.current_weapon == WEAP_AIRF) {
2001-07-17 05:58:10 +00:00
self.currentammo = 0;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_airgun.mdl";
self.weaponframe = 0;
}
} else if (self.current_weapon == WEAP_SNG) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_nails;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_nail2.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_NAILS;
self.weapon = IT_LIGHT_ASSAULT;//IT_SUPER_NAILGUN;
} else if (self.current_weapon == WEAP_LASERCANNON) {
2001-07-17 05:58:10 +00:00
self.currentammo = self.ammo_cells;
if (!(self.tfstate & TFSTATE_RELOADING)) {
2001-07-17 05:58:10 +00:00
self.weaponmodel = "progs/v_laserg.mdl";
self.weaponframe = 0;
}
self.items = self.items | IT_CELLS;
self.weapon = WEAP_LASERCANNON;
} else {
2001-07-17 05:58:10 +00:00
self.currentammo = 0;
self.weaponmodel = "";
self.weaponframe = 0;
}
};
float() W_BestWeapon =
{
local float it;
it = self.weapons_carried;
if (self.ammo_cells >= 1 && (it & WEAP_LIGHTNING) && self.waterlevel <= 1)
return WEAP_LIGHTNING;
if(self.ammo_shells >= 1 && (it & WEAP_SNIPER_RIFLE) )
return WEAP_SNIPER_RIFLE;
if(self.ammo_rockets >= 1 && (it & WEAP_ROCKET_LAUNCHER) )
return WEAP_ROCKET_LAUNCHER;
if (self.ammo_cells >= 5 && (it & WEAP_DAEDALUS) )
return WEAP_DAEDALUS;
if (self.ammo_cells >= 6 && (self.ammo_shells >= 1) && (it & WEAP_ASSAULT_CANNON))
return WEAP_ASSAULT_CANNON;
if(self.ammo_nails >= 10 && (it & WEAP_LIGHT_ASSAULT) )
return WEAP_LIGHT_ASSAULT;
if(self.ammo_rockets >= 3 && (it & WEAP_INCENDIARY) )
return WEAP_INCENDIARY;
if(self.ammo_rockets >= 1 && (it & WEAP_GRENADE_LAUNCHER) )
return WEAP_GRENADE_LAUNCHER;
if (self.ammo_cells >= 1 && (it & WEAP_LASERCANNON))
return WEAP_LASERCANNON;
if(self.ammo_nails >= 2 && (it & WEAP_SNG))
return WEAP_SNG;
if (self.ammo_cells >= 1 && (it & WEAP_FLAMETHROWER))
return WEAP_FLAMETHROWER;
if(self.ammo_shells >= 2 && (it & WEAP_SUPER_SHOTGUN) )
return WEAP_SUPER_SHOTGUN;
if (self.ammo_nails >= 1 && (it & WEAP_LASER) )
return WEAP_LASER;
if(self.ammo_nails >= 1 && (it & WEAP_NAILGUN) )
return WEAP_NAILGUN;
if(self.ammo_shells >= 1 && (it & WEAP_SHOTGUN) )
return WEAP_SHOTGUN;
if (self.ammo_nails >= 1 && (it & WEAP_MAUSER) )
return WEAP_MAUSER;
if (self.ammo_nails >= 1 && (it & WEAP_TRANQ) )
return WEAP_TRANQ;
if (it & WEAP_MEDIKIT)
return WEAP_MEDIKIT;
if (it & WEAP_AIRF)
return WEAP_AIRF;
if (it & WEAP_SPANNER)
return WEAP_SPANNER;
if (it & WEAP_AXE)
return WEAP_AXE;
2001-07-17 05:58:10 +00:00
return 0;
};
float() W_CheckNoAmmo =
{
if (self.current_weapon == WEAP_MEDIKIT)
return TRUE;
if (self.current_weapon == WEAP_AIRF)
return TRUE;
if (self.current_weapon == WEAP_AXE || self.current_weapon == WEAP_HOOK || self.current_weapon == WEAP_SPANNER)
return TRUE;
if (self.current_weapon == WEAP_INCENDIARY) {
2001-07-17 05:58:10 +00:00
if (self.currentammo >= 3)
return TRUE;
} else if (self.current_weapon == WEAP_DAEDALUS) {
2001-07-17 05:58:10 +00:00
if (self.currentammo >= 5)
return TRUE;
} else if (self.current_weapon == WEAP_SNIPER_RIFLE) {
if (self.currentammo >= 5)
return TRUE;
} else if (self.currentammo > 0)
return TRUE;
2001-07-17 05:58:10 +00:00
self.current_weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
W_PrintWeaponMessage();
// drop the weapon down
return FALSE;
2001-07-17 05:58:10 +00:00
};
/*====================
W_Reload
Is called when weapon has finished reloading
====================*/
void() W_Reload_shotgun =
{
self.owner.tfstate = self.owner.tfstate - (self.owner.tfstate & TFSTATE_RELOADING);
self.owner.weaponmodel = "progs/v_shot.mdl";
sprint(self.owner, PRINT_LOW, "finished reloading\n");
self.owner.StatusRefreshTime = time + 0.1;
2001-07-17 05:58:10 +00:00
dremove(self);
2001-07-17 05:58:10 +00:00
};
void() W_Reload_light_assault =
{
self.owner.tfstate = self.owner.tfstate - (self.owner.tfstate & TFSTATE_RELOADING);
self.owner.weaponmodel = "progs/v_nail2.mdl";
sprint(self.owner, PRINT_LOW, "finished reloading\n");
self.owner.StatusRefreshTime = time + 0.1;
2001-07-17 05:58:10 +00:00
dremove(self);
2001-07-17 05:58:10 +00:00
};
void() W_Reload_super_shotgun =
{
self.owner.tfstate = self.owner.tfstate - (self.owner.tfstate & TFSTATE_RELOADING);
self.owner.weaponmodel = "progs/v_shot2.mdl";
sprint(self.owner, PRINT_LOW, "finished reloading\n");
self.owner.StatusRefreshTime = time + 0.1;
2001-07-17 05:58:10 +00:00
dremove(self);
2001-07-17 05:58:10 +00:00
};
void() W_Reload_grenade_launcher =
{
self.owner.tfstate = self.owner.tfstate - (self.owner.tfstate & TFSTATE_RELOADING);
self.owner.weaponmodel = "progs/v_rock.mdl";
sprint(self.owner, PRINT_LOW, "finished reloading\n");
self.owner.StatusRefreshTime = time + 0.1;
2001-07-17 05:58:10 +00:00
dremove(self);
2001-07-17 05:58:10 +00:00
};
void() W_Reload_rocket_launcher =
{
self.owner.tfstate = self.owner.tfstate - (self.owner.tfstate & TFSTATE_RELOADING);
self.owner.weaponmodel = "progs/v_rock2.mdl";
sprint(self.owner, PRINT_LOW, "finished reloading\n");
self.owner.StatusRefreshTime = time + 0.1;
2001-07-17 05:58:10 +00:00
dremove(self);
2001-07-17 05:58:10 +00:00
};
void() W_Reload_laser_cannon =
{
self.owner.tfstate = self.owner.tfstate - (self.owner.tfstate & TFSTATE_RELOADING);
self.owner.weaponmodel = "progs/v_laserg.mdl";
sprint(self.owner, PRINT_LOW, "Laser Cannon charged\n");
self.owner.StatusRefreshTime = time + 0.1;
2001-07-17 05:58:10 +00:00
dremove(self);
2001-07-17 05:58:10 +00:00
};
float() CheckForReload =
{
local entity tWeapon;
if (self.current_weapon == WEAP_SHOTGUN) {
if (self.reload_shotgun >= RE_SHOTGUN && self.ammo_shells > 0) {
2001-07-17 05:58:10 +00:00
self.reload_shotgun = 0;
if (self.ammo_shells < RE_SHOTGUN)
self.reload_shotgun = RE_SHOTGUN - self.ammo_shells;
2001-07-17 05:58:10 +00:00
sprint (self, PRINT_HIGH, "reloading...\n");
self.tfstate = (self.tfstate | TFSTATE_RELOADING);
2001-07-17 05:58:10 +00:00
tWeapon = spawn();
tWeapon.owner = self;
tWeapon.classname = "timer";
tWeapon.nextthink = time + RE_SHOTGUN_TIME;
2001-07-17 05:58:10 +00:00
tWeapon.think = W_Reload_shotgun;
self.weaponmodel = "";
self.weaponframe = 0;
return TRUE;
2001-07-17 05:58:10 +00:00
}
} else if (self.current_weapon == WEAP_SUPER_SHOTGUN) {
if (self.reload_super_shotgun > RE_SUPER_SHOTGUN)
self.reload_super_shotgun = RE_SUPER_SHOTGUN;
if ( self.reload_super_shotgun >= RE_SUPER_SHOTGUN
&& self.ammo_shells > 0) {
self.reload_super_shotgun = 0;
if (self.ammo_shells < RE_SUPER_SHOTGUN)
self.reload_super_shotgun =
RE_SUPER_SHOTGUN - self.ammo_shells;
2001-07-17 05:58:10 +00:00
sprint (self, PRINT_HIGH, "reloading...\n");
self.tfstate = (self.tfstate | TFSTATE_RELOADING);
tWeapon = spawn();
tWeapon.owner = self;
tWeapon.classname = "timer";
tWeapon.nextthink = time + RE_SUPER_SHOTGUN_TIME;
tWeapon.think = W_Reload_super_shotgun;
2001-07-17 05:58:10 +00:00
self.weaponmodel = "";
self.weaponframe = 0;
return TRUE;
2001-07-17 05:58:10 +00:00
}
} else if (self.current_weapon == WEAP_LIGHT_ASSAULT) {
if ( self.reload_light_assault >= RE_LIGHT_ASSAULT
&& self.ammo_nails > 0) {
2001-07-17 05:58:10 +00:00
self.reload_light_assault = 0;
if (self.ammo_nails < RE_LIGHT_ASSAULT)
self.reload_light_assault = RE_LIGHT_ASSAULT - self.ammo_nails;
2001-07-17 05:58:10 +00:00
sprint (self, PRINT_HIGH, "reloading...\n");
self.tfstate = (self.tfstate | TFSTATE_RELOADING);
2001-07-17 05:58:10 +00:00
tWeapon = spawn();
tWeapon.owner = self;
tWeapon.classname = "timer";
tWeapon.nextthink = time + RE_LIGHT_ASSAULT_TIME;
2001-07-17 05:58:10 +00:00
tWeapon.think = W_Reload_light_assault;
self.weaponmodel = "";
self.weaponframe = 0;
return TRUE;
2001-07-17 05:58:10 +00:00
}
} else if (self.current_weapon == WEAP_LASERCANNON) {
if ( self.reload_laser_cannon >= RE_LASER_CANNON
&& self.ammo_cells > 0) {
2001-07-17 05:58:10 +00:00
self.reload_laser_cannon = 0;
if (self.ammo_cells < RE_LASER_CANNON)
self.reload_laser_cannon = RE_LASER_CANNON - self.ammo_cells;
2001-07-17 05:58:10 +00:00
sprint (self, PRINT_HIGH, "Charging cannon...\n");
self.tfstate = (self.tfstate | TFSTATE_RELOADING);
2001-07-17 05:58:10 +00:00
tWeapon = spawn();
tWeapon.owner = self;
tWeapon.classname = "timer";
tWeapon.nextthink = time + RE_LASER_CANNON_TIME;
2001-07-17 05:58:10 +00:00
tWeapon.think = W_Reload_laser_cannon;
self.weaponmodel = "";
self.weaponframe = 0;
return TRUE;
}
} else if (self.current_weapon == WEAP_GRENADE_LAUNCHER) {
if ( self.reload_grenade_launcher >= RE_GRENADE_LAUNCHER
&& self.ammo_rockets > 0) {
self.reload_grenade_launcher = 0;
if (self.ammo_rockets < RE_GRENADE_LAUNCHER)
self.reload_grenade_launcher =
RE_GRENADE_LAUNCHER - self.ammo_rockets;
2001-07-17 05:58:10 +00:00
sprint (self, PRINT_HIGH, "reloading...\n");
self.tfstate = (self.tfstate | TFSTATE_RELOADING);
tWeapon = spawn();
tWeapon.owner = self;
tWeapon.classname = "timer";
tWeapon.nextthink = time + RE_GRENADE_LAUNCHER_TIME;
tWeapon.think = W_Reload_grenade_launcher;
2001-07-17 05:58:10 +00:00
self.weaponmodel = "";
self.weaponframe = 0;
2001-07-17 05:58:10 +00:00
return TRUE;
}
} else if (self.current_weapon == WEAP_ROCKET_LAUNCHER) {
if ( self.reload_rocket_launcher >= RE_ROCKET_LAUNCHER
&& self.ammo_rockets > 0) {
self.reload_rocket_launcher = 0;
if (self.ammo_rockets < RE_ROCKET_LAUNCHER)
self.reload_rocket_launcher = RE_ROCKET_LAUNCHER
- self.ammo_rockets;
2001-07-17 05:58:10 +00:00
sprint (self, PRINT_HIGH, "reloading...\n");
self.tfstate = (self.tfstate | TFSTATE_RELOADING);
tWeapon = spawn();
tWeapon.owner = self;
tWeapon.classname = "timer";
if (self.tf_items & NIT_CLUSTER_ROCKETS)
tWeapon.nextthink = time + RE_ROCKET_LAUNCHER_TIME - 1;
else
tWeapon.nextthink = time + RE_ROCKET_LAUNCHER_TIME;
tWeapon.think = W_Reload_rocket_launcher;
self.weaponmodel = "";
self.weaponframe = 0;
2001-07-17 05:58:10 +00:00
return TRUE;
}
2001-07-17 05:58:10 +00:00
}
return FALSE;
2001-07-17 05:58:10 +00:00
};
/*
============
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_snail1; // ofn SNG
void() player_light1;
void() player_light_assault1;
void() player_rocket1;
#ifndef NO_AUTORIFLE
2001-07-17 05:58:10 +00:00
void() player_autorifle1;
#endif
2001-07-17 05:58:10 +00:00
void() player_assaultcannon1;
void() player_assaultcannonup1;
void() player_assaultcannondown1;
void() player_medikit1;
void() player_medikitb1;
void() player_medikitc1;
void() player_medikitd1;
void() player_bioweapon1;
void() player_bioweaponb1;
void() player_bioweaponc1;
void() player_bioweapond1;
void() player_chain1;
void() player_chain2;
void() player_chain3;
void() player_chain4;
void() player_chain5;
void() W_Attack =
{
local float r;
2001-07-17 05:58:10 +00:00
if (!W_CheckNoAmmo ())
return;
if (self.playerclass == PC_CUSTOM && (self.done_custom & CUSTOM_BUILDING))
2001-07-17 05:58:10 +00:00
return;
if (self.tfstate & TFSTATE_RELOADING)
2001-07-17 05:58:10 +00:00
return;
if (self.penance_time > time)
return;
//WK Tranq does not remove disguise
1) Attempted to give players positive frags whenever possible. You now should get frags for blowing people up with others' dispensers/mines/expbody, airfisting rockets, etc. 2) Redid Give_Frags_Out 3) Changed many uses of pointcontents and ugly hacks to use hullpointcontents and checkmove, now a lot cleaner and less buggy 4) You can grapple builds again. This caused really odd bugs. 5) You can now damage your own buildings again (gasp). Any time a tesla or sentry is damaged it turns on its attacker, friendly or otherwise. This is both a counter-TK and counter-spy mechanism. 6) Teslas are now entirely inside their bounding box 7) Now check every frame for players startsolid and for outside of the map cube. 8) #define WALL_HURT to make it hurt when you hit a wall 9) Used some cool ideas (aka laws of physics) to make the airfist a little less annoying 10) You now only get 1 mirv per slot without bandolier. Demoman and hwguy gain bandolier. demoman loses his extra mirv but gains an extra grenade and pair of detpacks. Hwguy gets extra grenade. 11) New and improved EMP grenade now does damage based on range. no longer blows up shells. Doesn't directly damage sentries anymore, but does significant damage to dispensers. EMP someone who's setting a det and it blows up in their face. 12) Players now do radius damage from getting EMPed (again) 13) EMPs now go through walls (again) 14) EMP number lowered by one (3 without, 4 with bandolier) and cost raised by $100 15) You can only have 2 frag grens, 3 with bandolier now. 16) Hover boots will now eat cells if they get low on charge. In addition, the silly bug where their charge wasn't restored when you die is fixed now. 17) EMPing a detpack now sets its timer to anywhere between 1 and 121 seconds from current time, with a logarithmic probability of it being lower. (random() * random() * 120 + 1). Also, probably more time the closer it is to the EMP. 18) Judo can now be blocked by people with close combat, knife or judo. Blocked judo means that the attacker loses 3 seconds of attack. 19) Judo missing now makes them unable to fire. 20) Shortened judo range (back to normal if w/ close combat) 21) Attempted to rework the railgun. Seems to be okay now. Probably still a lot of bugs in here, but since this is the devel version I thought I would commit all my changes so people could start testing it. I'll commit fixes as soon as I find the bugs.
2003-11-26 08:53:44 +00:00
//GR Spy can fire and keep their skin if not color-disguised.
if (self.is_undercover && (self.current_weapon != WEAP_TRANQ && self.current_weapon != WEAP_MAUSER)
&& (self.undercover_team != self.team_no))
2001-07-17 05:58:10 +00:00
Spy_RemoveDisguise(self);
if (self.job & JOB_THIEF && (self.job & JOB_ACTIVE || self.job & JOB_FULL_HIDE))
RevealThief(self,FALSE);
2001-07-17 05:58:10 +00:00
//WK When conced you randomly don't fire
if (self.tfstate & TFSTATE_CONCUSSIONED)
2001-07-17 05:58:10 +00:00
if (random() <= 0.3)
return;
makevectors (self.v_angle); // calculate forward angle for velocity
self.show_hostile = time + 1; // wake monsters up
if (self.current_weapon == WEAP_AXE) {
//if (self.cutf_items & CUTF_KNIFE) //WK Go berserk with the knife
2001-07-17 05:58:10 +00:00
// Attack_Finished(0.5); // no, don't (0.35)
//else
Attack_Finished(0.5);
sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
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.current_weapon == WEAP_SPANNER) {
2001-07-17 05:58:10 +00:00
Attack_Finished(0.35); //WK Berserk with spanner
sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
player_axe1 ();
} else if (self.current_weapon == WEAP_HOOK) {
2001-07-17 05:58:10 +00:00
if (!self.hook_out)
player_chain1 ();
Attack_Finished(1); //WK
} else if (self.current_weapon == WEAP_SHOTGUN) {
if (CheckForReload() == TRUE)
2001-07-17 05:58:10 +00:00
return;
player_shot1 ();
W_FireShotgun ();
self.reload_shotgun = self.reload_shotgun + 1;
self.StatusRefreshTime = time + 0.1;
CheckForReload();
Attack_Finished(0.5);
} else if (self.current_weapon == WEAP_SUPER_SHOTGUN) {
if (CheckForReload() == TRUE)
2001-07-17 05:58:10 +00:00
return;
player_shot1 ();
W_FireSuperShotgun ();
self.reload_super_shotgun = self.reload_super_shotgun + 2;
self.StatusRefreshTime = time + 0.1;
CheckForReload();
Attack_Finished(0.7);
} else if (self.current_weapon == WEAP_SNG) {
2001-07-17 05:58:10 +00:00
player_snail1 ();
} else if (self.current_weapon == WEAP_NAILGUN) {
2001-07-17 05:58:10 +00:00
player_nail1 ();
} else if (self.current_weapon == WEAP_LIGHT_ASSAULT) {
if (CheckForReload() == TRUE)
2001-07-17 05:58:10 +00:00
return;
player_light_assault1();
CheckForReload();
} else if (self.current_weapon == WEAP_GRENADE_LAUNCHER) {
if (CheckForReload() == TRUE)
2001-07-17 05:58:10 +00:00
return;
player_rocket1();
W_FireGrenade();
self.reload_grenade_launcher = self.reload_grenade_launcher + 1;
2001-07-17 05:58:10 +00:00
self.StatusRefreshTime = time + 0.1;
CheckForReload();
Attack_Finished(0.6);
} else if (self.current_weapon == WEAP_ROCKET_LAUNCHER) {
if (CheckForReload() == TRUE)
2001-07-17 05:58:10 +00:00
return;
player_rocket1();
W_FireRocket();
if (self.tf_items & NIT_CLUSTER_ROCKETS && self.cluster_mode == TRUE) //WK Clusters are multiple shots
2001-07-17 05:58:10 +00:00
self.reload_rocket_launcher = self.reload_rocket_launcher + 8;
else
self.reload_rocket_launcher = self.reload_rocket_launcher + 1;
self.StatusRefreshTime = time + 0.1;
CheckForReload();
//CH so that the dot can be removed quicker (reset after dot gone)
if (self.tf_items & NIT_RL_LASER_SIGHT)
2001-07-17 05:58:10 +00:00
Attack_Finished(0.1);
else
Attack_Finished(0.8);
} else if (self.current_weapon == WEAP_LIGHTNING) {
2001-07-17 05:58:10 +00:00
player_light1();
Attack_Finished(0.1);
sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
} else if (self.current_weapon == WEAP_DAEDALUS) { //CHANGEME
2001-07-17 05:58:10 +00:00
player_rocket1();
W_FireDaedalus();
Attack_Finished(0.8);
sound (self, CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM);
} else if (self.current_weapon == WEAP_SNIPER_RIFLE) {
2001-07-17 05:58:10 +00:00
// Can't fire while jumping
// WK You can if you are a scuba commando!
if ( (self.flags & FL_ONGROUND) || (self.hook_out)
|| ((self.tf_items & NIT_SCUBA) && self.waterlevel) ) {
player_shot1();
W_FireSniperRifle();
Attack_Finished(SNIPER_RIFLE_RELOAD_TIME);
2001-07-17 05:58:10 +00:00
}
#ifndef NO_AUTORIFLE
} else if (self.current_weapon == WEAP_AUTO_RIFLE) {
player_autorifle1();
2001-07-17 05:58:10 +00:00
W_FireAutoRifle();
Attack_Finished(0.1);
#endif
} else if (self.current_weapon == WEAP_ASSAULT_CANNON) {
2001-07-17 05:58:10 +00:00
// Need 4 cells to power up the Assault Cannon
if (self.ammo_cells < 4) {
sprint (self, PRINT_MEDIUM, "Insufficient cells to power up the Assault Cannon.\n");
stuffcmd (self, "-attack;\n"); // to avoid flooding
} else {
2001-07-17 05:58:10 +00:00
self.ammo_cells = self.ammo_cells - 4;
// Can't move while firing the Assault Cannon :)
self.heat = 1;
makeImmune(self,time+2);
// self.immune_to_check = time + 2;
self.tfstate = self.tfstate | TFSTATE_ASSAULTCANNON;
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed(self);
player_assaultcannonup1();
2001-07-17 05:58:10 +00:00
}
} else if (self.current_weapon == WEAP_FLAMETHROWER) {
player_shot1();
W_FireFlame();
if (self.waterlevel > 2)
Attack_Finished(1);
2001-07-17 05:58:10 +00:00
else
Attack_Finished(0.15);
} else if (self.current_weapon == WEAP_INCENDIARY) {
2001-07-17 05:58:10 +00:00
player_rocket1();
W_FireIncendiaryCannon();
Attack_Finished(1.2);
} else if (self.current_weapon == WEAP_MEDIKIT) {
sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
r = random();
if (r < 0.25)
player_medikit1 ();
else if (r < 0.5)
2001-07-17 05:58:10 +00:00
player_medikitb1 ();
else if (r < 0.75)
2001-07-17 05:58:10 +00:00
player_medikitc1 ();
else
player_medikitd1 ();
Attack_Finished(0.5);
} else if (self.current_weapon == WEAP_TRANQ) {
sound (self, CHAN_WEAPON, "weapons/dartgun.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
player_shot1 ();
W_FireTranq ();
Attack_Finished(1.5);
} else if (self.current_weapon == WEAP_LASER) {
sound (self, CHAN_WEAPON, "weapons/railgun.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
player_shot1();
W_FireLaser();
Attack_Finished(0.4);
} else if (self.current_weapon == WEAP_MAUSER) {
sound (self, CHAN_WEAPON, "weapons/dartgun.wav", 1, ATTN_NORM);
// player_shot1();
2001-07-17 05:58:10 +00:00
W_FireMauser();
Attack_Finished(2.0);
} else if (self.current_weapon == WEAP_AIRF) {
2001-07-17 05:58:10 +00:00
launch_horn();
}
if (self.current_weapon == WEAP_LASERCANNON) {
if (CheckForReload() == TRUE)
2001-07-17 05:58:10 +00:00
return;
player_laser1();
CheckForReload();
}
2001-07-17 05:58:10 +00:00
};
/*=========================
W_PrintWeaponMessage
Prints a message indicating
the current selected weapon,
if needed.
=========================*/
void() W_PrintWeaponMessage =
{
//WK Custom class friendly
if (self.current_weapon == WEAP_AXE) { // && (self.weapons_carried & WEAP_HOOK))
if (!(self.cutf_items & CUTF_KNIFE))
sprint(self, PRINT_MEDIUM, "Axe selected\n");
else {
if (self.weaponmode == 0)
sprint(self, PRINT_MEDIUM, "Knife selected\n"); //Nonbloody
else
sprint(self, PRINT_MEDIUM, "Bloody Knife selected\n"); //Bloody
2001-07-17 05:58:10 +00:00
}
} else if (self.current_weapon == WEAP_HOOK)
sprint(self, PRINT_MEDIUM, "Grappling Hook selected\n");
2001-07-17 05:58:10 +00:00
//CH because they use the same mdl, say what they are.
else if (self.current_weapon == WEAP_FLAMETHROWER)
sprint(self, PRINT_MEDIUM, "Flamethrower selected\n");
else if (self.current_weapon == WEAP_ROCKET_LAUNCHER) {
sprint(self, PRINT_MEDIUM, "Rocket Launcher selected");
if (self.cluster_mode == TRUE && self.tf_items & NIT_CLUSTER_ROCKETS) //set to fire cluster rockets
sprint(self, PRINT_MEDIUM, " Cluster Mode");
else if (self.tf_items & NIT_CLUSTER_ROCKETS)
sprint(self, PRINT_MEDIUM, " Normal Mode");
sprint(self, PRINT_MEDIUM, "\n");
} else if (self.current_weapon == WEAP_INCENDIARY)
sprint(self, PRINT_MEDIUM, "Incendiary cannon selected\n");
else if (self.current_weapon == WEAP_LIGHTNING)
sprint(self, PRINT_MEDIUM, "Lightning Gun selected\n");
else if (self.current_weapon == WEAP_SPANNER)
sprint(self, PRINT_MEDIUM, "Spanner readied\n");
else if (self.current_weapon == WEAP_GRENADE_LAUNCHER) {
if (self.weaponmode == GL_NORMAL)
sprint(self, PRINT_MEDIUM, "Normal grenade mode\n");
else if (self.weaponmode == GL_PIPEBOMB)
sprint(self, PRINT_MEDIUM, "Pipebomb mode\n");
} else if (self.current_weapon == WEAP_SNIPER_RIFLE)
sprint(self, PRINT_MEDIUM, "Sniper Rifle ready\n");
#ifndef NO_AUTORIFLE
else if (self.current_weapon == WEAP_AUTO_RIFLE)
sprint(self, PRINT_MEDIUM, "Rifle on fully auto\n");
#endif
else if (self.current_weapon == WEAP_TRANQ)
sprint(self, PRINT_MEDIUM, "Tranquiliser gun selected\n");
else if (self.current_weapon == WEAP_MEDIKIT)
sprint(self, PRINT_MEDIUM, "Medikit/Bioweapon readied\n");
else if (self.current_weapon == WEAP_MAUSER)
sprint(self, PRINT_MEDIUM, "Mauser WK-77 Assassin's Gun readied\n");
else if (self.current_weapon == WEAP_DAEDALUS)
sprint(self, PRINT_MEDIUM, "Daedalus Impulse Rifle readied\n");
else if (self.current_weapon == WEAP_LIGHTNING)
sprint(self, PRINT_MEDIUM, "Lighting gun selected\n");
else if (self.current_weapon == WEAP_AIRF)
sprint(self, PRINT_MEDIUM, "Airfist prepared\n");
else if (self.current_weapon == WEAP_LASERCANNON)
sprint(self, PRINT_MEDIUM, "Laser Cannon selected\n");
else if (self.current_weapon == WEAP_SNG)
sprint(self, PRINT_MEDIUM, "Super Nailgun selected\n");
else if (self.current_weapon == WEAP_NAILGUN)
sprint(self, PRINT_MEDIUM, "Nailgun selected\n");
else if (self.current_weapon == WEAP_LIGHT_ASSAULT)
sprint(self, PRINT_MEDIUM, "Light Assualt cannon selected\n");
2001-07-17 05:58:10 +00:00
};
/*
============
W_ChangeWeapon
============
*/
void() W_ChangeWeapon =
{
local float it, am, fl, loopck;
local float have_weapon, usable;
if (self.tfstate & TFSTATE_RELOADING)
2001-07-17 05:58:10 +00:00
return;
if (self.tfstate & TFSTATE_CANT_MOVE)
2001-07-17 05:58:10 +00:00
return;
it = self.weapons_carried;
fl = self.current_weapon;
am = 0;
usable = 0;
have_weapon = TRUE;
2001-07-17 05:58:10 +00:00
if (self.impulse == 1) {
if (!(it & (WEAP_HOOK | WEAP_MEDIKIT | WEAP_AXE | WEAP_SPANNER)))
have_weapon = FALSE;
2001-07-17 05:58:10 +00:00
while (!usable && have_weapon) {
if (fl == WEAP_SPANNER) {
fl = WEAP_MEDIKIT;
2001-07-17 05:58:10 +00:00
if (it & WEAP_MEDIKIT)
2001-07-17 05:58:10 +00:00
usable = 1;
} else if (fl == WEAP_MEDIKIT) {
fl = WEAP_HOOK;
2001-07-17 05:58:10 +00:00
if ((self.weapons_carried & WEAP_HOOK) && (fl & WEAP_HOOK))
2001-07-17 05:58:10 +00:00
usable = 1;
if (self.hook_out)
Reset_Grapple(self.hook);
} else if (fl == WEAP_HOOK) {
fl = WEAP_AXE;
2001-07-17 05:58:10 +00:00
if (it & WEAP_AXE)
2001-07-17 05:58:10 +00:00
usable = 1;
} else {
fl = WEAP_SPANNER;
2001-07-17 05:58:10 +00:00
if (it & WEAP_SPANNER)
2001-07-17 05:58:10 +00:00
usable = 1;
}
}
} else if ((self.weapons_carried & WEAP_HOOK) && (self.impulse == HOOK_IMP1 || self.impulse == HOOK_IMP2)) {
fl = WEAP_HOOK;
} else if (self.impulse == AXE_IMP) {
if (!(it & (WEAP_MEDIKIT | WEAP_AXE | WEAP_SPANNER)))
have_weapon = FALSE;
2001-07-17 05:58:10 +00:00
while (!usable && have_weapon) {
if (fl == WEAP_SPANNER) {
fl = WEAP_MEDIKIT;
2001-07-17 05:58:10 +00:00
if (it & WEAP_MEDIKIT)
2001-07-17 05:58:10 +00:00
usable = 1;
} else if (fl == WEAP_MEDIKIT) {
fl = WEAP_AXE;
2001-07-17 05:58:10 +00:00
if (it & WEAP_AXE)
2001-07-17 05:58:10 +00:00
usable = 1;
} else {
fl = WEAP_SPANNER;
2001-07-17 05:58:10 +00:00
if (it & WEAP_SPANNER)
2001-07-17 05:58:10 +00:00
usable = 1;
}
}
} else if (self.impulse == 2) {
if (!(((it & WEAP_SNIPER_RIFLE || it & WEAP_SHOTGUN || it & WEAP_TRANQ) && self.ammo_shells > 0) || (it & WEAP_LASER && self.ammo_nails > 0)|| (it & WEAP_DAEDALUS && self.ammo_cells > 0)))
have_weapon = FALSE;
2001-07-17 05:58:10 +00:00
loopck = 0;
while (!usable && have_weapon) {
2001-07-17 05:58:10 +00:00
loopck = (loopck + 1);
if (loopck >= 10)
have_weapon = FALSE;
if (fl == WEAP_SNIPER_RIFLE) {
fl = WEAP_SHOTGUN;
if (it & WEAP_SHOTGUN && self.ammo_shells > 0)
2001-07-17 05:58:10 +00:00
usable = 1;
} else if (fl == WEAP_SHOTGUN) {
fl = WEAP_TRANQ;
if (it & WEAP_TRANQ && self.ammo_nails > 0)
2001-07-17 05:58:10 +00:00
usable = 1;
} else if (fl == WEAP_TRANQ) {
fl = WEAP_LASER;
if (it & WEAP_LASER && self.ammo_nails > 0)
2001-07-17 05:58:10 +00:00
usable = 1;
} else {
fl = WEAP_SNIPER_RIFLE;
if (it & WEAP_SNIPER_RIFLE && self.ammo_shells > 0)
2001-07-17 05:58:10 +00:00
usable = 1;
}
}
if (fl == WEAP_LASER) {
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 1)
am = 1;
} else {
2001-07-17 05:58:10 +00:00
if (self.ammo_shells < 1)
am = 1;
}
} else if (self.impulse == 3) {
if (!(
#ifndef NO_AUTORIFLE
(it & WEAP_AUTO_RIFLE && self.ammo_shells > 0) ||
#endif
(it & WEAP_SUPER_SHOTGUN && self.ammo_shells >1)))
have_weapon = FALSE;
2001-07-17 05:58:10 +00:00
loopck = 0;
while (!usable && have_weapon) {
2001-07-17 05:58:10 +00:00
loopck = (loopck + 1);
if (loopck >= 10)
have_weapon = FALSE;
#ifndef NO_AUTORIFLE
if (fl == WEAP_AUTO_RIFLE) {
fl = WEAP_SUPER_SHOTGUN;
if (it & WEAP_SUPER_SHOTGUN && self.ammo_shells > 1)
2001-07-17 05:58:10 +00:00
usable = 1;
} else {
fl = WEAP_AUTO_RIFLE;
if (it & WEAP_AUTO_RIFLE && self.ammo_shells > 0)
2001-07-17 05:58:10 +00:00
usable = 1;
}
#else
fl = WEAP_SUPER_SHOTGUN;
if (it & WEAP_SUPER_SHOTGUN && self.ammo_cells > 1)
usable = 1;
else
have_weapon = FALSE;
#endif
2001-07-17 05:58:10 +00:00
}
if (fl == WEAP_SUPER_SHOTGUN) {
2001-07-17 05:58:10 +00:00
if (self.ammo_shells < 2)
am = 1;
} else {
2001-07-17 05:58:10 +00:00
if (self.ammo_shells < 1)
am = 1;
}
} else if (self.impulse == 4) {
/*
fl = WEAP_NAILGUN;
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 1)
am = 1;
*/
2001-07-17 05:58:10 +00:00
if (!(it & WEAP_LASERCANNON || it & WEAP_NAILGUN))
have_weapon = FALSE;
2001-07-17 05:58:10 +00:00
loopck = 0;
while (!usable && have_weapon) {
2001-07-17 05:58:10 +00:00
loopck = (loopck + 1);
if (loopck >= 10)
have_weapon = FALSE;
if (fl == WEAP_LASERCANNON) {
fl = WEAP_NAILGUN;
if (it & WEAP_NAILGUN)
2001-07-17 05:58:10 +00:00
usable = 1;
} else {
fl = WEAP_LASERCANNON;
if (it & WEAP_LASERCANNON)
2001-07-17 05:58:10 +00:00
usable = 1;
}
}
if (fl == WEAP_NAILGUN) {
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 1)
am = 1;
} else if (fl == WEAP_LASERCANNON) {
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 1)
am = 1;
}
} else if (self.impulse == 5) {
if (!(it & WEAP_LIGHT_ASSAULT || it & WEAP_MAUSER || it & WEAP_SNG))
have_weapon = FALSE;
2001-07-17 05:58:10 +00:00
loopck = 0;
while (!usable && have_weapon) {
2001-07-17 05:58:10 +00:00
loopck = (loopck + 1);
if (loopck >= 10)
have_weapon = FALSE;
if (fl == WEAP_LIGHT_ASSAULT) {
fl = WEAP_MAUSER;
if (it & WEAP_MAUSER)
2001-07-17 05:58:10 +00:00
usable = 1;
//-
} else if (fl == WEAP_MAUSER) {
fl = WEAP_SNG;
if (it & WEAP_SNG)
2001-07-17 05:58:10 +00:00
usable = 1;
//-
} else {
fl = WEAP_LIGHT_ASSAULT;
if (it & WEAP_LIGHT_ASSAULT)
2001-07-17 05:58:10 +00:00
usable = 1;
}
}
if (fl == WEAP_MAUSER) {
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 1)
am = 1;
} else if (fl == WEAP_LIGHT_ASSAULT) {
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 1)
am = 1;
} else if (fl == WEAP_SNG) {
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 2)
am = 1;
}
} else if (self.impulse == 6) {
if (!((it & WEAP_FLAMETHROWER && self.ammo_cells > 0) || (it & WEAP_GRENADE_LAUNCHER && self.ammo_rockets > 0)))
have_weapon = FALSE;
2001-07-17 05:58:10 +00:00
loopck = 0;
while (!usable && have_weapon) {
2001-07-17 05:58:10 +00:00
loopck = (loopck + 1);
if (loopck >= 10)
have_weapon = FALSE;
if (fl == WEAP_FLAMETHROWER) {
fl = WEAP_GRENADE_LAUNCHER;
self.weaponmode = GL_NORMAL;
if (it & WEAP_GRENADE_LAUNCHER && self.ammo_rockets > 0)
2001-07-17 05:58:10 +00:00
usable = 1;
} else {
fl = WEAP_FLAMETHROWER;
if (it & WEAP_FLAMETHROWER && self.ammo_cells > 0)
2001-07-17 05:58:10 +00:00
usable = 1;
}
}
if (fl == WEAP_FLAMETHROWER) {
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 1)
am = 1;
} else {
2001-07-17 05:58:10 +00:00
if (self.ammo_rockets < 1)
am = 1;
}
} else if (self.impulse == 7) {
if (!((it & WEAP_INCENDIARY && self.ammo_rockets > 2) || ((it & WEAP_ROCKET_LAUNCHER || it & WEAP_GRENADE_LAUNCHER) && self.ammo_rockets > 0) || (it & WEAP_ASSAULT_CANNON && self.ammo_shells > 0 && self.ammo_cells > 3)))
have_weapon = FALSE;
2001-07-17 05:58:10 +00:00
loopck = 0;
while (!usable && have_weapon) {
2001-07-17 05:58:10 +00:00
loopck = (loopck + 1);
if (loopck >= 10)
have_weapon = FALSE;
if (fl == WEAP_INCENDIARY) {
fl = WEAP_ROCKET_LAUNCHER;
if (it & WEAP_ROCKET_LAUNCHER && self.ammo_rockets > 0)
2001-07-17 05:58:10 +00:00
usable = 1;
} else if (fl == WEAP_ROCKET_LAUNCHER) {
if (self.tf_items & NIT_CLUSTER_ROCKETS) {
if (self.cluster_mode == TRUE) {
// bprint(PRINT_HIGH, "cluster mode FALSE\n");
self.cluster_mode = FALSE;
fl = WEAP_ASSAULT_CANNON;
if ( it & WEAP_ASSAULT_CANNON && self.ammo_shells > 0
&& self.ammo_cells > 3)
2001-07-17 05:58:10 +00:00
usable = 1;
} else {
// bprint(PRINT_HIGH, "cluster mode TRUE\n");
self.cluster_mode = TRUE;
fl = WEAP_ROCKET_LAUNCHER;
if (it & WEAP_ROCKET_LAUNCHER && self.ammo_rockets > 0)
2001-07-17 05:58:10 +00:00
usable = 1;
}
} else {
fl = WEAP_ASSAULT_CANNON;
if ( it & WEAP_ASSAULT_CANNON && self.ammo_shells > 0
&& self.ammo_cells > 3)
2001-07-17 05:58:10 +00:00
usable = 1;
}
} else if (fl == WEAP_ASSAULT_CANNON) {
fl = WEAP_GRENADE_LAUNCHER;
self.weaponmode = GL_PIPEBOMB;
if (it & WEAP_GRENADE_LAUNCHER && self.ammo_rockets > 0)
2001-07-17 05:58:10 +00:00
usable = 1;
} else {
fl = WEAP_INCENDIARY;
if (it & WEAP_INCENDIARY && self.ammo_rockets > 2)
2001-07-17 05:58:10 +00:00
usable = 1;
}
}
if (fl == WEAP_ASSAULT_CANNON) {
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 4 || self.ammo_shells < 1)
am = 1;
} else if (fl == WEAP_INCENDIARY) {
2001-07-17 05:58:10 +00:00
if (self.ammo_rockets < 3)
am = 1;
} else {
2001-07-17 05:58:10 +00:00
if (self.ammo_rockets < 1)
am = 1;
}
} else if (self.impulse == 8) {
if (!(it & WEAP_LIGHTNING || it & WEAP_DAEDALUS || it & WEAP_AIRF))
have_weapon = FALSE;
2001-07-17 05:58:10 +00:00
loopck = 0;
while (!usable && have_weapon) {
2001-07-17 05:58:10 +00:00
loopck = (loopck + 1);
if (loopck >= 10)
have_weapon = FALSE;
if (fl == WEAP_DAEDALUS) {
fl = WEAP_LIGHTNING;
if (it & WEAP_LIGHTNING) //WEAP_DAEDALUS
2001-07-17 05:58:10 +00:00
usable = 1;
} else if (fl == WEAP_LIGHTNING) {
fl = WEAP_AIRF;
if (it & WEAP_AIRF) //WEAP_DAEDALUS
2001-07-17 05:58:10 +00:00
usable = 1;
} else {
fl = WEAP_DAEDALUS;
if (it & WEAP_DAEDALUS)
2001-07-17 05:58:10 +00:00
usable = 1;
}
} if (fl == WEAP_DAEDALUS) {
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 5)
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
{
if (it & WEAP_LIGHTNING)
fl = WEAP_LIGHTNING;
else am = 1;
}
} if (fl == WEAP_LIGHTNING) {
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 1)
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
am = 1;
} if (it & WEAP_AIRF && am) {
fl = WEAP_AIRF;
am = 0;
}
} else if (self.impulse == TF_MEDIKIT) {
fl = WEAP_MEDIKIT;
2001-07-17 05:58:10 +00:00
if (it & WEAP_MEDIKIT)
2001-07-17 05:58:10 +00:00
usable = 1;
}
self.impulse = 0;
// don't have the weapon
if (!have_weapon || (!(it & fl))) {
sprint (self, PRINT_HIGH, "no weapon.\n");
2001-07-17 05:58:10 +00:00
return;
}
// don't have the ammo
if (am == 1) {
sprint(self, PRINT_HIGH, "not enough ammo.\n");
2001-07-17 05:58:10 +00:00
return;
}
// don't have the cells for the cannon
if (am == 2) {
sprint(self, PRINT_HIGH, "not enough cells to power assault cannon.\n");
2001-07-17 05:58:10 +00:00
return;
}
// set weapon, set ammo
self.current_weapon = fl;
W_SetCurrentAmmo ();
W_PrintWeaponMessage();
self.StatusRefreshTime = time + 0.1;
};
/*
============
CycleWeaponCommand
Go to the next weapon with ammo
============
*/
void() CycleWeaponCommand =
{
//CH reorder so that they please me
local float it, am, cont, loopcount;
// Some safety code
if (!self.weaponmodel || self.current_weapon == 0)
2001-07-17 05:58:10 +00:00
return;
if (self.tfstate & TFSTATE_RELOADING)
return;
2001-07-17 05:58:10 +00:00
if (self.tfstate & TFSTATE_CANT_MOVE)
2001-07-17 05:58:10 +00:00
return;
it = self.weapons_carried;
self.impulse = 0;
loopcount = 0;
while (1) {
2001-07-17 05:58:10 +00:00
am = 0;
cont = FALSE;
2001-07-17 05:58:10 +00:00
if (self.current_weapon == WEAP_AXE) {
self.current_weapon = WEAP_SPANNER;
} else if (self.current_weapon == WEAP_SPANNER) {
self.current_weapon = WEAP_SHOTGUN;
2001-07-17 05:58:10 +00:00
if (self.ammo_shells < 1)
am = 1;
} else if (self.current_weapon == WEAP_SHOTGUN) {
self.current_weapon = WEAP_LASER;
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 1)
am = 1;
} else if (self.current_weapon == WEAP_LASER) {
self.current_weapon = WEAP_TRANQ;
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 1)
am = 1;
} else if (self.current_weapon == WEAP_TRANQ) {
self.current_weapon = WEAP_SNIPER_RIFLE;
if (self.ammo_shells < 5)
2001-07-17 05:58:10 +00:00
am = 1;
} else if (self.current_weapon == WEAP_SNIPER_RIFLE) {
#ifndef NO_AUTORIFLE
self.current_weapon = WEAP_AUTO_RIFLE;
2001-07-17 05:58:10 +00:00
if (self.ammo_shells < 1)
am = 1;
} else if (self.current_weapon == WEAP_AUTO_RIFLE) {
#endif
self.current_weapon = WEAP_MAUSER;
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 1)
am = 1;
} else if (self.current_weapon == WEAP_MAUSER) {
self.current_weapon = WEAP_SUPER_SHOTGUN;
2001-07-17 05:58:10 +00:00
if (self.ammo_shells < 2)
am = 1;
} else if (self.current_weapon == WEAP_SUPER_SHOTGUN) {
self.current_weapon = WEAP_NAILGUN;
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 1)
am = 1;
//-
} else if (self.current_weapon == WEAP_NAILGUN) {
self.current_weapon = WEAP_SNG;
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 2)
am = 1;
//-
} else if (self.current_weapon == WEAP_SNG) {
self.current_weapon = WEAP_LASERCANNON;
if (self.ammo_cells < 1)
2001-07-17 05:58:10 +00:00
am = 1;
//-
} else if (self.current_weapon == WEAP_LASERCANNON) { // was WEAP_NAILGUN
self.current_weapon = WEAP_LIGHT_ASSAULT;
2001-07-17 05:58:10 +00:00
if (self.ammo_nails < 2)
am = 1;
} else if (self.current_weapon == WEAP_LIGHT_ASSAULT) {
self.current_weapon = WEAP_FLAMETHROWER;
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 1)
am = 1;
} else if (self.current_weapon == WEAP_FLAMETHROWER) {
self.current_weapon = WEAP_GRENADE_LAUNCHER;
self.weaponmode = GL_NORMAL;
2001-07-17 05:58:10 +00:00
if (self.ammo_rockets < 1)
am = 1;
} else if (self.current_weapon == WEAP_GRENADE_LAUNCHER && self.weaponmode == GL_NORMAL) {
self.current_weapon = WEAP_GRENADE_LAUNCHER;
self.weaponmode = GL_PIPEBOMB;
2001-07-17 05:58:10 +00:00
if (self.ammo_rockets < 1)
am = 1;
} else if (self.current_weapon == WEAP_GRENADE_LAUNCHER && self.weaponmode == GL_PIPEBOMB) {
self.current_weapon = WEAP_INCENDIARY;
2001-07-17 05:58:10 +00:00
if (self.ammo_rockets < 3)
am = 1;
} else if (self.current_weapon == WEAP_INCENDIARY) {
self.current_weapon = WEAP_DAEDALUS;
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 1)
am = 1;
} else if (self.current_weapon == WEAP_DAEDALUS) {
self.current_weapon = WEAP_ROCKET_LAUNCHER;
2001-07-17 05:58:10 +00:00
if (self.ammo_rockets < 1)
am = 1;
} else if (self.current_weapon == WEAP_ROCKET_LAUNCHER) {
if (self.tf_items & NIT_CLUSTER_ROCKETS) {
if (self.cluster_mode == TRUE) {
// bprint(PRINT_HIGH, "cluster mode FALSE\n");
self.cluster_mode = FALSE;
self.current_weapon = WEAP_ASSAULT_CANNON;
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 4)
am = 1;
if (self.ammo_shells < 1)
am = 1;
} else {
// bprint(PRINT_HIGH, "cluster mode TRUE\n");
self.cluster_mode = TRUE;
self.current_weapon = WEAP_ROCKET_LAUNCHER;
2001-07-17 05:58:10 +00:00
if (self.ammo_rockets < 1)
am = 1;
}
} else {
self.current_weapon = WEAP_ASSAULT_CANNON;
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 4)
am = 1;
if (self.ammo_shells < 1)
am = 1;
}
} else if (self.current_weapon == WEAP_ASSAULT_CANNON) {
self.current_weapon = WEAP_LIGHTNING;
2001-07-17 05:58:10 +00:00
if (self.ammo_cells < 1)
am = 1;
} else if (self.current_weapon == WEAP_LIGHTNING) {
self.current_weapon = WEAP_AIRF;
2001-07-17 05:58:10 +00:00
if (!(self.weapons_carried & WEAP_AIRF))
2001-07-17 05:58:10 +00:00
am = 1;
} else if (self.current_weapon == WEAP_AIRF) {
self.current_weapon = WEAP_HOOK;
2001-07-17 05:58:10 +00:00
if (!(self.weapons_carried & WEAP_HOOK))
2001-07-17 05:58:10 +00:00
am = 1;
} else if (self.current_weapon == WEAP_HOOK) {
self.current_weapon = WEAP_MEDIKIT;
} else if (self.current_weapon == WEAP_MEDIKIT) {
self.current_weapon = WEAP_AXE;
2001-07-17 05:58:10 +00:00
}
// Safety precaution
if (loopcount > 30)
return;
loopcount = loopcount + 1;
// check if player actually has the weapon
// if not, loop again
if ((self.weapons_carried & self.current_weapon) && (am == 0)) {
if (self.current_weapon != WEAP_GRENADE_LAUNCHER)
self.weaponmode = GL_NORMAL; // reset the pipebombs
2001-07-17 05:58:10 +00:00
W_SetCurrentAmmo ();
W_PrintWeaponMessage();
self.StatusRefreshTime = time + 0.1;
return;
}
}
};
/*
============
ImpulseCommands
============
*/
void() DeadImpulses;
float(float inp) BuildingImpulses =
{
if (inp < 10) return TRUE;
if (inp > TF_CHANGEPC && inp <= TF_CHANGEPC + PC_LASTCLASS) return TRUE;
if (inp == TF_CHANGECLASS) return TRUE;
if (inp == TF_HELP_MAP) return TRUE;
if (inp == TF_SHOWTF) return TRUE;
if (inp == TF_TEAM_CLASSES) return TRUE;
if (inp == TF_TEAM_SCORES) return TRUE;
if (inp == TF_TEAM_LIST) return TRUE;
if (inp == TF_TEAM_ENUM) return TRUE;
if (inp == TF_ID) return TRUE;
if (inp == TF_SELL) return TRUE;
if (inp == I_CHEAT_ONE) return TRUE;
if (inp == I_CHEAT_TWO) return TRUE;
if (inp == I_CHEAT_THREE) return TRUE;
return FALSE;
2001-07-17 05:58:10 +00:00
};
void() Alias_BitImpulse;
2001-07-17 05:58:10 +00:00
void() ImpulseCommands =
{
if (self.impulse >= TF_BITSTART && self.impulse <= TF_BITNONE) {
Alias_BitImpulse ();
self.impulse = 0;
return;
}
if (self.impulse == TF_ALIASNEXT) {
self.impulse = 0;
self.got_aliases_time = time;
return;
}
if ((self.impulse== TF_CHANGEPC + PC_CUSTOM || self.impulse==TF_SELL) && custom_mode==2) {
2001-07-17 05:58:10 +00:00
self.impulse=0;
sprint(self,PRINT_MEDIUM,"Custom player classes are disabled\n");
2001-07-17 05:58:10 +00:00
return;
}
if (self.impulse <= TF_CHANGEPC + PC_RANDOM && self.impulse >= TF_CHANGEPC + PC_SCOUT && stock_mode==2) {
2001-07-17 05:58:10 +00:00
self.impulse=0;
sprint(self,PRINT_MEDIUM,"Stock player classes are disabled\n");
2001-07-17 05:58:10 +00:00
return;
}
// local entity te; //- OfN - Unused!
2001-07-17 05:58:10 +00:00
//WK Don't allow any commands except menu ones when building a class
if ( self.playerclass == PC_CUSTOM
&& (self.done_custom & CUSTOM_BUILDING)) {
if (!BuildingImpulses(self.impulse)) {
2001-07-17 05:58:10 +00:00
self.impulse = 0;
return;
}
}
//WK Don't allow bastards to do any commands
if (self.penance_time > time)
return;
if (prematch >= time)
if (self.impulse > 10 || self.impulse < 1) {
2001-07-17 05:58:10 +00:00
self.impulse = 0;
return;
}
/*=====================
These Impulse commands rely on the use of self.last_impulse. Since they use
self.impulse for their own purposes, they _must_ be placed before the other
self.impulse tests, and they _must_ set self.impulse = 0 when they're done.
=====================*/
// TeamFortress Detpack
if (self.last_impulse == TF_DETPACK && self.impulse)
2001-07-17 05:58:10 +00:00
TeamFortress_SetDetpack(self.impulse);
// TeamFortress Scan
else if (self.last_impulse == TF_SCAN && self.impulse)
TeamFortress_Scan(self.impulse,FALSE);
2001-07-17 05:58:10 +00:00
/*=====================
The rest of these Impulse Commands don't use self.last_impulse. They _must_
be placed _after_ the Impulse Commands that do require self.last_impulse
=====================*/
// Catch the 8 key to reprint the classhelp.
// Remove this when we return the lightning gun
//CH was on impulse 8, but thats lgun
if (self.impulse == 9 && self.current_menu != MENU_CLASSHELP && (self.playerclass > 0 && self.playerclass < 11)) {
self.current_menu = MENU_CLASSHELP;
self.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
self.menu_displaytime = 0;
}
// uses the special skill of the player's class
if (self.impulse == TF_SPECIAL_SKILL)
2001-07-17 05:58:10 +00:00
UseSpecialSkill();
// uses the special skill of the player's class
if (self.impulse == TF_SKILL)
2001-07-17 05:58:10 +00:00
UseJobSkill();
// No weapon related impulses can be done when setting detpacks or building WK or chaplaning
if (!self.is_building && !self.is_detpacking && !self.is_feigning && !(self.job & JOB_CHAPLAN && self.job & JOB_ACTIVE)) {
if ((self.impulse >= 1 && self.impulse < 9) || (self.impulse == TF_MEDIKIT))
2001-07-17 05:58:10 +00:00
W_ChangeWeapon ();
// Grappling Hook
else if ((self.weapons_carried & WEAP_HOOK) && (self.impulse == HOOK_IMP1 || self.impulse == HOOK_IMP2))
2001-07-17 05:58:10 +00:00
W_ChangeWeapon ();
// Axe
else if (self.impulse == AXE_IMP)
2001-07-17 05:58:10 +00:00
W_ChangeWeapon ();
// cycle weapon reverse and cycle weapon do the same thing
// TBD: make CycleWeaponReverseCommand()
else if (self.impulse == 10 || self.impulse == 12)
CycleWeaponCommand ();
// TeamFortress Reload current weapon
else if (self.impulse == TF_RELOAD)
2001-07-17 05:58:10 +00:00
TeamFortress_ReloadCurrentWeapon();
// Scanning impulses
else if (self.impulse == TF_SCAN_10)
TeamFortress_Scan(10,FALSE);
else if (self.impulse == TF_SCAN_30)
TeamFortress_Scan(30,FALSE);
else if (self.impulse == TF_SCAN_100)
TeamFortress_Scan(100,FALSE);
else if (self.impulse == TF_SCAN_ENEMY) //CH
TeamFortress_Scan(TF_SCAN_ENEMY,FALSE);
else if (self.impulse == TF_SCAN_FRIENDLY)
TeamFortress_Scan(TF_SCAN_FRIENDLY,FALSE);
2001-07-17 05:58:10 +00:00
// TeamFortress Set Detpack Impulses
else if (self.impulse == TF_DETPACK_5)
2001-07-17 05:58:10 +00:00
TeamFortress_SetDetpack(5);
else if (self.impulse == TF_DETPACK_20)
2001-07-17 05:58:10 +00:00
TeamFortress_SetDetpack(20);
else if (self.impulse == TF_DETPACK_50)
2001-07-17 05:58:10 +00:00
TeamFortress_SetDetpack(50);
else if (self.impulse == TF_DROP_AMMO) {
self.current_menu = MENU_DROP;
self.menu_count = MENU_REFRESH_RATE - 5;
} else if (self.impulse == TF_DISCARD)
2001-07-17 05:58:10 +00:00
TeamFortress_Discard();
//CH
else if (self.impulse == TF_DROPITEMS)
2001-07-17 05:58:10 +00:00
TeamFortress_DropItems();
#ifdef COOP_MODE
else if (self.impulse == TF_DROPKEY && coop)
2001-07-17 05:58:10 +00:00
DropKey();
#endif
}
//WK We can toss grens while chaplaining. Readme says so. :p
if (!self.is_building && !self.is_detpacking && !self.is_feigning) {
2001-07-17 05:58:10 +00:00
// TeamFortress Prime Grenade Type 1
if (self.impulse == TF_GRENADE_1)
2001-07-17 05:58:10 +00:00
TeamFortress_PrimeGrenade();
// TeamFortress Prime Grenade Type 2
else if (self.impulse == TF_GRENADE_2)
2001-07-17 05:58:10 +00:00
TeamFortress_PrimeGrenade();
}
// TeamFortress Inventory
if (self.impulse == TF_INVENTORY)
2001-07-17 05:58:10 +00:00
TeamFortress_Inventory();
else if (self.impulse == TF_MEDIC_HELPME)
2001-07-17 05:58:10 +00:00
TeamFortress_SaveMe();
else if (self.impulse == TF_TAUNT) {
2001-07-17 05:58:10 +00:00
if (self.last_saveme_sound < time) {
sound(self, CHAN_WEAPON, "enforcer/sight1.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
self.last_saveme_sound = time + 4;
}
} else if (self.impulse == TF_TAUNT2) {
2001-07-17 05:58:10 +00:00
if (self.last_saveme_sound < time) {
sound(self, CHAN_WEAPON, "enforcer/sight2.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
self.last_saveme_sound = time + 4;
}
} else if (self.impulse == TF_TAUNT3) {
2001-07-17 05:58:10 +00:00
if (self.last_saveme_sound < time) {
sound(self, CHAN_WEAPON, "enforcer/sight3.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
self.last_saveme_sound = time + 4;
}
} else if (self.impulse == TF_TAUNT4) {
2001-07-17 05:58:10 +00:00
if (self.last_saveme_sound < time) {
sound(self, CHAN_WEAPON, "enforcer/sight4.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
self.last_saveme_sound = time + 4;
}
} else if (self.impulse == TF_TAUNT5) {
2001-07-17 05:58:10 +00:00
if (self.last_saveme_sound < time) {
sound(self, CHAN_WEAPON, "weapons/fith.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
self.last_saveme_sound = time + 4;
}
}
// TeamFortress Throw Grenade
else if (self.impulse == TF_GRENADE_T)
2001-07-17 05:58:10 +00:00
TeamFortress_ThrowGrenade();
//else if (self.impulse == BUILD_SENSOR && self.cutf_items & CUTF_SENSOR) // SB build sensor (not enough room on menu...)
2001-07-17 05:58:10 +00:00
// SBBuildSensor();
else if (self.impulse == THROW_DETPACK)
2001-07-17 05:58:10 +00:00
PrimeC4Det();
/*else if (self.impulse == IMPULSE_INTERFACE)
SBInitiateInterface();*/
else if (self.impulse == IMPULSE_HOLO)
2001-07-17 05:58:10 +00:00
ActivateHolo(self);
else if (self.impulse == TF_ID)
TeamFortress_ID(FALSE);
2001-07-17 05:58:10 +00:00
// TeamFortress Detonate Pipebombs (yep, can be done while setting a detpack :)
else if (self.impulse == TF_PB_DETONATE)
2001-07-17 05:58:10 +00:00
TeamFortress_DetonatePipebombs();
// TeamFortress Stop Setting Detpack
else if (self.impulse == TF_DETPACK_STOP)
TeamFortress_DetpackStop(FALSE);
2001-07-17 05:58:10 +00:00
// TeamFortress Class Impulses
//WK - Custom class friendly
else if (self.impulse == TF_SPY_SPY && (self.cutf_items & CUTF_SPY_KIT))
2001-07-17 05:58:10 +00:00
TeamFortress_SpyGoUndercover();
else if (self.impulse == TF_SPY_DIE && (self.cutf_items & CUTF_SPY_KIT))
2001-07-17 05:58:10 +00:00
TeamFortress_SpyFeignDeath(1); //CH normal feign
else if (self.impulse == TF_SPY_DIE2 && (self.cutf_items & CUTF_SPY_KIT))
2001-07-17 05:58:10 +00:00
TeamFortress_SpyFeignDeath(2); //CH special sfeign
else if (self.impulse == TF_ENGINEER_BUILD &&
((self.cutf_items & CUTF_SENSOR) || (self.cutf_items & CUTF_SENTRYGUN) || self.tf_items & NIT_TESLA || self.tf_items & NIT_SECURITY_CAMERA || self.tf_items & NIT_TELEPORTER || self.cutf_items & CUTF_FIELDGEN || self.cutf_items & CUTF_DISPENSER))
2001-07-17 05:58:10 +00:00
TeamFortress_EngineerBuild();
// CTF Support Impulses
else if (self.impulse == FLAG_INFO) {
if (CTF_Map == TRUE)
2001-07-17 05:58:10 +00:00
TeamFortress_CTF_FlagInfo();
else
TeamFortress_DisplayDetectionItems();
}
2001-07-17 05:58:10 +00:00
#ifdef DEMO_STUFF
// Camera Impulses
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_TARGET)
2001-07-17 05:58:10 +00:00
CamLock();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_ZOOM)
2001-07-17 05:58:10 +00:00
CamDistLock();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_VEC)
2001-07-17 05:58:10 +00:00
CamVecLock();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_ANGLE)
2001-07-17 05:58:10 +00:00
CamAngleLock();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_REVANGLE)
2001-07-17 05:58:10 +00:00
CamRevAngleLock();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_PROJECTILE)
2001-07-17 05:58:10 +00:00
CamProjectileLock();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_PROJECTILE_Z)
2001-07-17 05:58:10 +00:00
CamProjectileZoom();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_OFFSET)
2001-07-17 05:58:10 +00:00
CamOffset();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_DROP)
2001-07-17 05:58:10 +00:00
CamDrop();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_FADETOBLACK)
2001-07-17 05:58:10 +00:00
fadetoblack();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_FADEFROMBLACK)
2001-07-17 05:58:10 +00:00
fadefromblack();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_FADETOWHITE)
2001-07-17 05:58:10 +00:00
fadetowhite();
else if (self.playerclass == PC_UNDEFINED && self.impulse == TF_CAM_FADEFROMWHITE)
2001-07-17 05:58:10 +00:00
fadefromwhite();
#endif
else
DeadImpulses();
/*=====================
TeamFortress Pre-Impulse Commands
=====================*/
if (self.impulse == TF_DETPACK)
2001-07-17 05:58:10 +00:00
self.last_impulse = self.impulse;
if (self.impulse == TF_SCAN)
2001-07-17 05:58:10 +00:00
self.last_impulse = self.impulse;
self.impulse = 0;
};
/*====================
DeadImpulses
Impulse commands that
are allowable if the
player is dead
====================*/
void() DeadImpulses =
{
if ((self.impulse== TF_CHANGEPC + PC_CUSTOM || self.impulse==TF_SELL) && custom_mode==2) {
2001-07-17 05:58:10 +00:00
self.impulse=0;
sprint(self,PRINT_MEDIUM,"Custom player classes are disabled\n");
2001-07-17 05:58:10 +00:00
return;
}
if (self.impulse <= TF_CHANGEPC + PC_RANDOM && self.impulse >= TF_CHANGEPC + PC_SCOUT && stock_mode==2) {
2001-07-17 05:58:10 +00:00
self.impulse=0;
sprint(self,PRINT_MEDIUM,"Stock player classes are disabled\n");
2001-07-17 05:58:10 +00:00
return;
}
#ifdef DEBUG
if (self.impulse == 69 && infokey(NIL, "allow_debug") == "yes")
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
{
self.demon_blood = MAX_KNIFE_BLOOD;
self.job = self.job | JOB_BLOODY_KNIFE;
self.impulse=0;
return;
}
if (self.impulse == 18 && infokey(NIL, "allow_debug") == "yes")
1) Attempted to give players positive frags whenever possible. You now should get frags for blowing people up with others' dispensers/mines/expbody, airfisting rockets, etc. 2) Redid Give_Frags_Out 3) Changed many uses of pointcontents and ugly hacks to use hullpointcontents and checkmove, now a lot cleaner and less buggy 4) You can grapple builds again. This caused really odd bugs. 5) You can now damage your own buildings again (gasp). Any time a tesla or sentry is damaged it turns on its attacker, friendly or otherwise. This is both a counter-TK and counter-spy mechanism. 6) Teslas are now entirely inside their bounding box 7) Now check every frame for players startsolid and for outside of the map cube. 8) #define WALL_HURT to make it hurt when you hit a wall 9) Used some cool ideas (aka laws of physics) to make the airfist a little less annoying 10) You now only get 1 mirv per slot without bandolier. Demoman and hwguy gain bandolier. demoman loses his extra mirv but gains an extra grenade and pair of detpacks. Hwguy gets extra grenade. 11) New and improved EMP grenade now does damage based on range. no longer blows up shells. Doesn't directly damage sentries anymore, but does significant damage to dispensers. EMP someone who's setting a det and it blows up in their face. 12) Players now do radius damage from getting EMPed (again) 13) EMPs now go through walls (again) 14) EMP number lowered by one (3 without, 4 with bandolier) and cost raised by $100 15) You can only have 2 frag grens, 3 with bandolier now. 16) Hover boots will now eat cells if they get low on charge. In addition, the silly bug where their charge wasn't restored when you die is fixed now. 17) EMPing a detpack now sets its timer to anywhere between 1 and 121 seconds from current time, with a logarithmic probability of it being lower. (random() * random() * 120 + 1). Also, probably more time the closer it is to the EMP. 18) Judo can now be blocked by people with close combat, knife or judo. Blocked judo means that the attacker loses 3 seconds of attack. 19) Judo missing now makes them unable to fire. 20) Shortened judo range (back to normal if w/ close combat) 21) Attempted to rework the railgun. Seems to be okay now. Probably still a lot of bugs in here, but since this is the devel version I thought I would commit all my changes so people could start testing it. I'll commit fixes as soon as I find the bugs.
2003-11-26 08:53:44 +00:00
{
sprint(self, PRINT_HIGH, "Your origin is: '", ftos(self.origin_x), " ", ftos(self.origin_y));
sprint(self, PRINT_HIGH, " ", ftos(self.origin_z), "'\n");
self.impulse=0;
return;
}
if (self.impulse == 195 && !debug_target && infokey(NIL, "allow_debug") == "yes")
debug_target = self;
#endif
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
2001-07-17 05:58:10 +00:00
//<CH>
if (self.impulse == I_CHEAT_ONE) {
2001-07-17 05:58:10 +00:00
I_DID_CHEAT_ONE();
}
if (self.impulse == I_CHEAT_TWO) {
2001-07-17 05:58:10 +00:00
I_DID_CHEAT_TWO();
}
if (self.impulse == I_CHEAT_THREE) {
2001-07-17 05:58:10 +00:00
I_DID_CHEAT_THREE();
}
//</CH>
//WK - Add in TF2.6 support for changeclass
if (self.impulse == TF_CHANGECLASS) {
self.current_menu = MENU_CLASS;
2001-07-17 05:58:10 +00:00
Menu_Class();
}
//WK Have a normal "custom" command reset the "sell" flag
//Have to do this here, since "upgrade" corrupts self.impulse
if (self.impulse == TF_CHANGEPC + PC_CUSTOM) //
self.done_custom = self.done_custom - (self.done_custom & CUSTOM_SELLING);
2001-07-17 05:58:10 +00:00
//WK - CustomTF1.6 ability to sell frags
//Sets a flag saying that we wish to sell
//And then issues a command to rebuild our class.
if (self.impulse == TF_SELL) {
if (bounty) {
self.done_custom = self.done_custom | CUSTOM_SELLING;
self.impulse = TF_CHANGEPC + PC_CUSTOM;
} else {
sprint (self, PRINT_HIGH, "Sorry, the admin has bounty disabled\n");
2001-07-17 05:58:10 +00:00
self.impulse = 0;
return;
}
}
// TeamFortress Show Toggleflag State
if (self.impulse == TF_SHOWTF)
2001-07-17 05:58:10 +00:00
TeamFortress_ShowTF();
// TeamFortress Show Legal PlayerClasses
// Toggle autozoom on/off
else if (self.impulse == TF_AUTOZOOM)
2001-07-17 05:58:10 +00:00
TeamFortress_AutoZoomToggle();
else if (self.impulse == TF_SHOWLEGALCLASSES)
2001-07-17 05:58:10 +00:00
TeamFortress_DisplayLegalClasses();
// TeamFortress Change PlayerClass
else if (self.impulse > TF_CHANGEPC && self.impulse <= (TF_CHANGEPC + PC_CUSTOM) ) {
2001-07-17 05:58:10 +00:00
//WK Hackish bug-fix for "Custom Custom" teleporting
if (self.impulse == TF_CHANGEPC + PC_CUSTOM) {
if ((self.done_custom & (CUSTOM_FINISHED | CUSTOM_BUILDING) && !(self.done_custom & CUSTOM_ON_SPAWN)) || self.playerclass != PC_CUSTOM)
2001-07-17 05:58:10 +00:00
TeamFortress_ChangeClass();
} else
2001-07-17 05:58:10 +00:00
TeamFortress_ChangeClass();
} else if (self.impulse == TF_UNCUSTOM && self.done_custom & CUSTOM_ON_SPAWN) {
self.done_custom = self.done_custom - (self.done_custom & CUSTOM_ON_SPAWN);
sprint(self, PRINT_HIGH, "You will no longer spawn as a new playerclass.\n");
2001-07-17 05:58:10 +00:00
}
// TeamFortress Help Impulses
else if (self.impulse == TF_LAY)
2001-07-17 05:58:10 +00:00
custom_lay();
else if (self.impulse == TF_HELP_MAP)
2001-07-17 05:58:10 +00:00
TeamFortress_HelpMap();
else if (self.impulse == TF_STATUS_QUERY)
2001-07-17 05:58:10 +00:00
TeamFortress_StatusQuery();
// TeamFortress Team Impulse
else if (self.impulse == TF_TEAM_1)
2001-07-17 05:58:10 +00:00
TeamFortress_TeamSet(1);
else if (self.impulse == TF_TEAM_2)
2001-07-17 05:58:10 +00:00
TeamFortress_TeamSet(2);
else if (self.impulse == TF_TEAM_3)
2001-07-17 05:58:10 +00:00
TeamFortress_TeamSet(3);
else if (self.impulse == TF_TEAM_4)
2001-07-17 05:58:10 +00:00
TeamFortress_TeamSet(4);
else if (self.impulse == TF_TEAM_SCORES)
2001-07-17 05:58:10 +00:00
TeamFortress_TeamShowScores(0);
else if (self.impulse == TF_TEAM_CLASSES)
2001-07-17 05:58:10 +00:00
TeamFortress_TeamShowMemberClasses(self);
else if (self.impulse == TF_STATUSBAR_ON) {
2001-07-17 05:58:10 +00:00
self.StatusRefreshTime = time + 0.2;
self.StatusBarSize = self.StatusBarSize + 1;
if (self.StatusBarSize > 2)
self.StatusBarSize = 1;
} else if (self.impulse == TF_STATUSBAR_OFF) {
2001-07-17 05:58:10 +00:00
self.StatusRefreshTime = time + 60;
self.StatusBarSize = 0;
} else if (self.impulse >= TF_STATUSBAR_RES_START && self.impulse <= TF_STATUSBAR_RES_END) {
2001-07-17 05:58:10 +00:00
StatusRes(self.impulse - 71);
}
// TeamFortress Alias checking
else if (self.impulse == TF_ALIAS_CHECK) {
sprint (self, PRINT_HIGH, "Aliases checked.\n");
self.got_aliases = TRUE;
2001-07-17 05:58:10 +00:00
self.impulse = 0;
}
};
/*
============
W_WeaponFrame
Called every frame so impulse events can be handled as well as possible
============
*/
void() W_WeaponFrame =
{
local vector tv;
if (!(self.tfstate & TFSTATE_AIMING)) {
if (self.height > 29 && self.height < 90) {
self.height = self.height + 80 * frametime;
2001-07-17 05:58:10 +00:00
if (self.height > 90)
self.height = 90;
TF_zoom(self.height);
}
}
if (self.current_menu > 0) {
2001-07-17 05:58:10 +00:00
Player_Menu();
if (self.impulse > 0 && self.impulse < 11) {
2001-07-17 05:58:10 +00:00
Menu_Input(self.impulse);
if (self.impulse != 0) {
if (self.team_no == 0 && teamplay && (self.lives != 0)) {
2001-07-17 05:58:10 +00:00
Menu_Team_Input(self.impulse);
}
/* WK Disable picking normal class menu
else if (self.playerclass == PC_UNDEFINED && (self.lives != 0))
2001-07-17 05:58:10 +00:00
{
Menu_Class_Input(self.impulse);
}
*/
2001-07-17 05:58:10 +00:00
}
}
}
if (time < self.attack_finished)
return;
// Stop calling this function so much
if (self.impulse != 0)
ImpulseCommands ();
// Can't fire while setting a detpack or building something
if ((self.is_building != 0) || (self.is_detpacking != 0) || (self.is_feigning != 0) || (self.is_haxxxoring != 0) || (self.is_toffingadet != 0))
return;
//WK ...or Chaplaning
if (self.job & JOB_CHAPLAN && self.job & JOB_ACTIVE)
2001-07-17 05:58:10 +00:00
return;
// Check for release
if (!self.button0 && self.fire_held_down && self.current_weapon == WEAP_ASSAULT_CANNON) {
self.fire_held_down = FALSE;
2001-07-17 05:58:10 +00:00
// Let him/her walk again
2002-09-08 01:44:11 +00:00
self.tfstate &= ~TFSTATE_ASSAULTCANNON;
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed(self);
player_run ();
}
2001-07-17 05:58:10 +00:00
// check for attack
if (self.button0 && !(self.fire_held_down)) {
if ((self.current_menu == MENU_CLASSHELP) || (self.current_menu == MENU_CLASSHELP2)) {
self.current_menu = MENU_REPEATHELP;
self.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
Attack_Finished(0.2);
} else if (self.current_weapon == WEAP_SNIPER_RIFLE) {
if (self.tfstate & TFSTATE_AIMING) {
if (!W_CheckNoAmmo())
self.tfstate &= ~TFSTATE_AIMING;
else if (self.height > 30) {
2001-07-17 05:58:10 +00:00
self.height = self.height - 5;
TF_zoom(self.height);
}
} else {
2001-07-17 05:58:10 +00:00
tv = self.velocity;
tv_z = 0;
if (vlen(tv) <= WEAP_SNIPER_RIFLE_MAX_MOVE && W_CheckNoAmmo()) {
2001-07-17 05:58:10 +00:00
// create the laser sight
SniperSight_Create(0);
self.heat = 30; // damage done
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
2003-11-12 04:58:19 +00:00
// GR no, charging sniper rifle makes no sense, idiot
2001-07-17 05:58:10 +00:00
#ifdef WEINER_SNIPER
self.heat = 80;
#endif
self.height = 90;
self.tfstate = self.tfstate | TFSTATE_AIMING;
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed(self);
}
}
} else if (self.current_weapon == WEAP_ROCKET_LAUNCHER && self.tf_items & NIT_RL_LASER_SIGHT) {
if (!(self.tfstate & TFSTATE_RL_LASER)) {
2001-07-17 05:58:10 +00:00
// create the laser sight
SniperSight_Create(1);
self.tfstate = self.tfstate | TFSTATE_RL_LASER;
2001-07-17 05:58:10 +00:00
SuperDamageSound ();
W_Attack ();
TeamFortress_SetSpeed(self);
}
} else if (self.current_weapon == WEAP_ASSAULT_CANNON) {
2001-07-17 05:58:10 +00:00
// Only fire the Assault Cannon if the player is on the ground
// WK Or if you are a Scuba Commando Underwater!
if (self.flags & FL_ONGROUND || ((self.tf_items & NIT_SCUBA) && self.waterlevel)) {
2001-07-17 05:58:10 +00:00
SuperDamageSound ();
W_Attack ();
} else {
sprint(self, PRINT_MEDIUM, "You cannot fire the assault cannon without\nyour feet on the ground...\n");
stuffcmd (self, "-attack;\n"); // so that they don't get flooded
2001-07-17 05:58:10 +00:00
}
} else {
2001-07-17 05:58:10 +00:00
SuperDamageSound ();
W_Attack ();
}
} else if (self.playerclass == PC_UNDEFINED) {
2001-07-17 05:58:10 +00:00
self.weaponmode = 0;
} else if (self.tfstate & TFSTATE_AIMING) {
2001-07-17 05:58:10 +00:00
W_Attack();
self.tfstate = self.tfstate - TFSTATE_AIMING;
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed(self);
self.heat = 0;
} else if (self.tfstate & TFSTATE_RL_LASER) {
2001-07-17 05:58:10 +00:00
//CH the dot should remove itself
Attack_Finished(0.5); //Finish it up
self.tfstate = self.tfstate - TFSTATE_RL_LASER;
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed(self);
player_run ();
}
};
/*
================
T_DaedalusTouch
Combination conc, krac and RL
================
*/
#define BOUNCE 120
void() T_DaedalusTouch =
{
local float points = 0; //XXX false +ve
2001-07-17 05:58:10 +00:00
local vector org;
local entity head;
head = findradius(self.origin, BOUNCE);
2001-07-17 05:58:10 +00:00
while (head) {
//Conc
if (head.takedamage && !IsBuilding(head)) {
2001-07-17 05:58:10 +00:00
org = head.origin + (head.mins + head.maxs)*0.5;
points = 0.5*vlen (org - self.origin);
if (points < 0) points = 0;
points = BOUNCE - points;
if (points > 0) {
2001-07-17 05:58:10 +00:00
head.velocity = org - self.origin;
head.velocity = head.velocity * (points / 20);
if (head.cutf_items & CUTF_GYMNAST)
2001-07-17 05:58:10 +00:00
head.velocity = head.velocity * (points / 20);
if (head.classname != "player" && head.flags & FL_ONGROUND)
head.flags = head.flags - FL_ONGROUND;
2001-07-17 05:58:10 +00:00
}
}
if (head.takedamage) {
2001-07-17 05:58:10 +00:00
//Krac
if (IsBuilding(head))
TF_T_Damage (head, self, self.owner, 100, TF_TD_NOTTEAM, TF_TD_FIRE);
2001-07-17 05:58:10 +00:00
//Rocket Launcher (w/ armor stripping)
else {
2001-07-17 05:58:10 +00:00
if (head.armorvalue > 35) head.armorvalue = head.armorvalue - 35;
else head.armorvalue = 0;
deathmsg = DMSG_DAEDALUS;
TF_T_Damage (head, self, self.owner, points / 8, TF_TD_NOTTEAM, TF_TD_FIRE);
2001-07-17 05:58:10 +00:00
}
}
head = head.chain;
}
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);
2001-07-17 05:58:10 +00:00
if (other.classname == "force_field") //- OfN - Makes field explosion b4 removing it
FieldExplosion(other,self.origin,self);
dremove(self);
};
/*
================
W_FireDaedalus (WK)
================
*/
void() W_FireDaedalus =
{
sound (self, CHAN_WEAPON, "weapons/grenade.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
KickPlayer(-2, self);
self.currentammo = self.ammo_cells = self.ammo_cells - 5;
if (self.ammo_cells < 0) {
self.ammo_cells = 0;
return;
}
SuperDamageSound();
newmis = spawn ();
newmis.owner = self;
newmis.movetype = MOVETYPE_FLYMISSILE;
2001-07-17 05:58:10 +00:00
newmis.classname = "rocket"; // OfN - for airfist pushing
newmis.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
makevectors (self.v_angle);
newmis.velocity = v_forward;
newmis.velocity = newmis.velocity * 500;
newmis.avelocity = '600 600 0';
newmis.angles = vectoangles(newmis.velocity);
newmis.skin = 1;
//CHANGEME Replace this with s_explode sprite. :)
setmodel (newmis, "progs/flare.mdl");
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, self.origin + v_forward*8 + '0 0 16');
newmis.touch = T_DaedalusTouch;
newmis.nextthink = time + 4;
newmis.think = SUB_Remove;
};
/* Sponsored by SB-1 Tech
**
** W_FireMauser!
** Fires the mauser spy thing which is likely to have a name change
** so nyeh
*/
void() W_FireMauser =
{
local vector org;
local vector source;
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
if (self.ammo_nails < 0) {
2001-07-17 05:58:10 +00:00
self.ammo_nails = 0;
return;
}
KickPlayer(-2, self);
makevectors(self.v_angle);
source = self.origin + '0 0 16';
traceline (source, source + v_forward*100, FALSE, self);
2001-07-17 05:58:10 +00:00
if (trace_fraction == 1.0)
return;
org = trace_endpos - v_forward*4;
if (trace_ent.takedamage) {
2001-07-17 05:58:10 +00:00
trace_ent.axhitme = 1;
SpawnBlood (org, 20);
deathmsg = DMSG_MAUSER;
2001-07-17 05:58:10 +00:00
SuperDamageSound();
TF_T_Damage(trace_ent, self, self, 20, TF_TD_NOTTEAM, TF_TD_SHOT);
2001-07-17 05:58:10 +00:00
if (trace_ent.classname == "player")
{
TF_T_Damage(trace_ent, self, self, 50+200*random(), TF_TD_NOTTEAM + TF_TD_IGNOREARMOUR, TF_TD_OTHER);
sprint(trace_ent, PRINT_HIGH, "Your nerves scream as poison floods your veins...\n");
2001-07-17 05:58:10 +00:00
}
} else {
if (trace_ent.classname == "force_field") { //- OfN - Makes field explosion
2001-07-17 05:58:10 +00:00
FieldExplosion(trace_ent,trace_endpos,trace_ent);
PutFieldWork(trace_ent);
}
}
newmis = spawn();
newmis.owner = self;
newmis.heat = 0;
newmis.think = MauserRecoilThink;
newmis.nextthink = time + 0.1;
};
void () MauserRecoilThink =
{
self.owner.weaponframe = self.heat = self.heat + 1;
if (self.heat >= 6) {
2001-07-17 05:58:10 +00:00
self.owner.weaponframe = 0;
dremove(self);
return;
}
self.nextthink = time + 0.1;
};
/*
========
SuperDamageSound
Plays sound if needed
========
*/
void() SuperDamageSound =
{
if (self.super_damage_finished > time) {
if (self.super_sound < time) {
2001-07-17 05:58:10 +00:00
self.super_sound = time + 1;
sound (self, CHAN_BODY, "items/damage3.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
}
} else if (self.aura == AURA_POWER) {
2001-07-17 05:58:10 +00:00
if (self.super_sound < time)
{
self.super_sound = time + 1;
sound (self, CHAN_BODY, "auras/aura2.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
}
} else if (self.aura == AURA_HASTE) {
if (self.super_sound < time) {
2001-07-17 05:58:10 +00:00
self.super_sound = time + 1;
sound (self, CHAN_BODY, "auras/aura4.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
}
}
return;
};
/*===========================================================
// laser cannon stuff (from hipnotic)
//==========================================================
*/
void() HIP_LaserTouch =
{
local vector org;
local vector spot1,spot2;
local vector oldvel;
// local float r;
self.owner = NIL;
self.cnt = self.cnt + 1;
if (pointcontents(self.origin) == CONTENTS_SKY) {
remove(self);
return;
}
oldvel = normalize(self.neworigin);
spot1 = self.origin - (16*oldvel);
spot2 = self.origin + (16*oldvel);
traceline (spot1, spot2, FALSE, self); // see through other monsters
self.origin = trace_endpos;
org = self.origin;
2001-07-17 05:58:10 +00:00
if (other.health) {
// other.deathtype = "hiplaser";
if (self.owner == other)
self.dmg = self.dmg / 2;
2001-07-17 05:58:10 +00:00
spawn_touchblood (self.dmg);
2001-07-17 05:58:10 +00:00
//- OfN laser hurts monsters a lot
if (IsMonsterNonArmy(other))
self.dmg = self.dmg * 2;
//- scrags get rapped by the laser
if (other.classname == "monster_wizard")
self.dmg = self.dmg * 2; // this is *4
deathmsg = DMSG_LASERCANNON;
TF_T_Damage (other, self, self.demon_one, self.dmg, TF_TD_NOTTEAM, TF_TD_ELECTRICITY);
} else if ((self.cnt >= 3) || (random() < 0.15)) {
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_PHS);
} else {
// self.dmg = 0.66 * self.dmg;
self.dmg = 0.9 * self.dmg;
// self.speed = 0.95 * self.speed;
self.velocity = oldvel+(2*trace_plane_normal);
self.velocity = normalize(self.velocity);
self.velocity = self.speed * self.velocity;
self.neworigin = self.velocity;
if (self.flags & FL_ONGROUND)
self.flags = self.flags - FL_ONGROUND;
// r = random();
// self.attack_finished = time + 7; //ofn - restart its life of 7 seconds
if (other.classname == "force_field") //- OfN - Makes field explosion
FieldExplosion(other,self.origin,self);
sound (self, CHAN_WEAPON, "weapons/laserric.wav", 1, ATTN_STATIC);
return;
}
2001-07-17 05:58:10 +00:00
if (other.classname == "force_field") //- OfN - Makes field explosion b4 removing it
FieldExplosion(other,self.origin,self);
sound (self, CHAN_WEAPON, "enforcer/enfstop.wav", 1, ATTN_STATIC);
dremove(self);
2001-07-17 05:58:10 +00:00
};
void() HIP_LaserThink =
{
// local float delta; //unused?
2001-07-17 05:58:10 +00:00
if (time>self.attack_finished) {
remove(self);
return;
}
if (self.flags & FL_ONGROUND)
self.flags = self.flags - FL_ONGROUND;
self.velocity = self.neworigin;
self.angles = vectoangles(self.velocity);
self.nextthink = time+0.15;
};
2001-07-17 05:58:10 +00:00
void(vector org, vector vec, float light) HIP_LaunchLaser =
{
// sound (self ,CHAN_WEAPON, "weapons/shotgn2.wav", 1, ATTN_NORM);
sound (self ,CHAN_WEAPON, "weapons/laserg.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
vec = normalize(vec);
2001-07-17 05:58:10 +00:00
newmis = spawn();
newmis.owner = self;
newmis.classname = "hiplaser";
newmis.demon_one = self; // was "lastvictim" field of hipnotic // OfN needed because .owner is removed later
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_BBOX;
// if (light)
// newmis.effects = EF_DIMLIGHT;
setmodel (newmis, "progs/lasrspik.mdl");
2001-07-17 05:58:10 +00:00
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, org);
newmis.speed = 1000;
newmis.dmg = LASER_CANNON_DMG;
newmis.velocity = vec * newmis.speed;
newmis.neworigin = newmis.velocity; // was last_velocity field on hypnotic source code
newmis.angles = vectoangles(newmis.velocity);
newmis.avelocity = '0 0 400';
2001-07-17 05:58:10 +00:00
newmis.nextthink = time;
newmis.attack_finished = time + 3.5; //was 3.5//OfN- they last for 7 seconds now
newmis.think = HIP_LaserThink;
newmis.touch = HIP_LaserTouch;
newmis.count = 0;
2001-07-17 05:58:10 +00:00
};
/*
=================
HIP_FireLaser
=================
*/
void(float stat) HIP_FireLaser =
{
2001-07-17 05:58:10 +00:00
local vector org;
local vector dir;
local vector out;
local float ofs;
local float aofs;
if (!self.button0) {
player_run ();
return;
}
if (self.ammo_cells < 1) {
2001-07-17 05:58:10 +00:00
self.weapon = W_BestWeapon ();
W_SetCurrentAmmo ();
return;
}
SuperDamageSound();
muzzleflash();
makevectors (self.v_angle);
ofs = 6;
out = v_forward;
out_z = 0;
out = normalize(out);
org = self.origin + ((12-ofs) * v_up) + (12*out);
// org = self.origin + (1*v_forward);
dir = aim (self, 1000);
aofs = ofs * 0.707;
if (stat == 0) {
self.currentammo = self.ammo_cells = self.ammo_cells - 1;
// org = org + (aofs*v_right);
org = org - (aofs*v_up);
HIP_LaunchLaser(org, dir, 0);
// org = org - (2*aofs*v_right);
// HIP_LaunchLaser(org, dir, 0);
} else if (stat == 1) {
self.currentammo = self.ammo_cells = self.ammo_cells - 1;
org = org + (ofs*v_up);
// if (random()<0.1) {
// HIP_LaunchLaser(org, dir, 1);
// newmis.dmg = 25;
// } else
HIP_LaunchLaser(org, dir, 0);
2001-07-17 05:58:10 +00:00
}
msg_entity = self;
WriteByte (MSG_ONE, SVC_SMALLKICK);
2001-07-17 05:58:10 +00:00
self.reload_laser_cannon = self.reload_laser_cannon + 1;
2001-07-17 05:58:10 +00:00
if (CheckForReload() == TRUE)
return;
2001-07-17 05:58:10 +00:00
};