prozac-qfcc/engineer.qc

1582 lines
44 KiB
C++
Raw Normal View History

#include "defs.qh"
#include "menu.qh"
2001-07-17 05:58:10 +00:00
/*======================================================
ENGINEER.QC Custom TeamFortress v3.1
(c) TeamFortress Software Pty Ltd 2/3/97
(c) William Kerney 4/14/00
(c) Craig Hauser 4/14/00
========================================================
Weapons and functions for the ENGINEER class and associated weaponry
=======================================================*/
float modelindex_tesla; //CH
// Weapon Functions
void() LaserBolt_Touch;
void() LaserBolt_Think;
void() W_FireLaser;
// EMP Grenade Functions
void() EMPExplode;
void() EMPGrenadeTouch;
void() EMPGrenadeExplode;
// Building Functions
void() TeamFortress_EngineerBuild;
void(float objtobuild) TeamFortress_Build;
void() TeamFortress_FinishedBuilding;
void() T_Dispenser;
void() Dispenser_Die;
void(entity disp) Engineer_UseDispenser;
void(entity gun) Engineer_UseSentryGun;
void(entity cam) Engineer_UseCamera;
void() CheckDistance;
float(entity obj, entity builder) CheckArea;
//WK
void() Sentry_Touch;
float(float myteam) HasFlag;
//- OfN
void(entity field) Field_Built;
//=========================================================================
// Laserbolt think function
void() LaserBolt_Think =
{
if (time > self.heat) {
dremove(self);
return;
}
self.solid = SOLID_TRIGGER;
self.movetype = MOVETYPE_FLYMISSILE;
2001-07-17 05:58:10 +00:00
self.velocity = self.oldorigin;
self.touch = LaserBolt_Touch;
setmodel(self, "progs/e_spike2.mdl");
self.nextthink = time + 1.0;
self.think = SUB_Remove;
};
//=========================================================================
// Laserbolt touch function. Just moves through the player and comes out
// the other side.
void() LaserBolt_Touch =
{
local vector org;
if (time > self.heat) {
dremove(self);
return;
}
if (other == self.owner)
return;
if (other == self.enemy && self.enemy != world)
return; // don't explode on same person twice
if (pointcontents(self.origin) == CONTENT_SKY)
2001-07-17 05:58:10 +00:00
{
dremove(self);
return;
}
//WK Sweep mines at point of impact
GuerillaMineSweep(self.origin);
org = self.origin - 8*normalize(self.velocity);
if (other.health)
{
SpawnBlood (org, 15);
deathmsg = DMSG_LASERBOLT;
TF_T_Damage (other, self, self.enemy, 25, 0, TF_TD_ELECTRICITY);
2001-07-17 05:58:10 +00:00
self.velocity = self.oldorigin;
self.owner = other;
setmodel (self, string_null);
self.touch = SUB_Null;
// self.solid = SOLID_NOT;
// self.movetype = MOVETYPE_NOCLIP;
2001-07-17 05:58:10 +00:00
self.nextthink = time + 0.1;
self.think = LaserBolt_Think;
return;
}
else
{
//WK Fly through walls!
setmodel (self, string_null);
self.touch = SUB_Null;
self.solid = SOLID_NOT;
self.movetype = MOVETYPE_NOCLIP;
2001-07-17 05:58:10 +00:00
self.nextthink = time + 0.1;
self.think = LaserBolt_Think;
return;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_SPIKE);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
2001-07-17 05:58:10 +00:00
#ifdef QUAKE_WORLD
multicast (self.origin, MULTICAST_PHS);
2001-07-17 05:58:10 +00:00
#endif
}
dremove(self);
};
//=========================================================================
// Fire a laserbolt
void() W_FireLaser =
{
local vector vec, org;
self.currentammo = self.ammo_nails = self.ammo_nails - 1;
makevectors(self.v_angle);
org = self.origin + (v_forward * 8);
vec = aim(self, 10000);
vec = normalize(vec);
newmis = spawn();
newmis.owner = self;
newmis.enemy = self; // The real owner
newmis.movetype = MOVETYPE_FLYMISSILE;
newmis.solid = SOLID_TRIGGER;
2001-07-17 05:58:10 +00:00
setmodel (newmis, "progs/e_spike1.mdl");
setsize (newmis, '0 0 0', '0 0 0');
setorigin (newmis, org + '0 0 16');
newmis.velocity = vec * 1500;
newmis.angles = vectoangles(newmis.velocity);
newmis.oldorigin = newmis.velocity;
newmis.nextthink = time + 1.5;
newmis.heat = time + 1.5;
newmis.think = SUB_Remove;
newmis.touch = LaserBolt_Touch;
};
//=========================================================================
// Ammo/Weapon exploded by the EMP grenade
void() EMPExplode =
{
local float expsize;
expsize = 10;
// Weapon?
if (self.touch == weapon_touch)
expsize = 60;
else if (self.classname == "item_shells")
expsize = 50 + self.aflag;
else if (self.classname == "item_spikes")
expsize = 40;
else if (self.classname == "item_rockets")
expsize = 100 + (self.aflag * 4);
else if (self.classname == "item_cells")
expsize = 100 + (self.aflag * 3);
else if (self.classname == "item_weapon")
expsize = 60;
else
{
RPrint("EMPExplode: Attempting to explode a ");
RPrint(self.classname);
RPrint("\n");
return;
}
deathmsg = DMSG_GREN_EMP_AMMO;
2001-07-17 05:58:10 +00:00
T_RadiusDamage (self, self.enemy, expsize, world);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
2001-07-17 05:58:10 +00:00
#ifdef QUAKE_WORLD
multicast (self.origin, MULTICAST_PHS);
2001-07-17 05:58:10 +00:00
#endif
// Respawn
Respawn_Item(self, self.enemy);
};
//=========================================================================
// Touch Function for EMP Grenade
void() EMPGrenadeTouch =
{
// If the EMP Grenade hits a player, it just bounces off
sound (self, CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
if (self.velocity == '0 0 0')
self.avelocity = '0 0 0';
};
//=========================================================================
// EMP Grenade explode function, for when the PRIMETIME runs out
void() EMPGrenadeExplode =
{
local float expsize;
local entity te, oldself;
local float total_exp;
//CH Slice gave idea of an emp gren getting rated based on blast so i added..
total_exp = 0;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_TAREXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
2001-07-17 05:58:10 +00:00
#ifdef QUAKE_WORLD
multicast (self.origin, MULTICAST_PHS);
2001-07-17 05:58:10 +00:00
#endif
// Find all ammo in the area
te = findradius(self.origin, 240);
while (te)
{
if (!CanDamage(te,self)) // OfN
SUB_Null();
else if (te.touch == ammo_touch || te.touch == weapon_touch) // Ammo/Weapon?
{
// Make sure it isn't picked up in the next second
te.solid = SOLID_NOT;
2001-07-17 05:58:10 +00:00
te.enemy = self.owner;
te.nextthink = time + 1 + (random() * 2);
te.think = EMPExplode;
}
// Detpack?
else if (te.think == TeamFortress_DetpackExplode)
{
//te.solid = SOLID_NOT;
2001-07-17 05:58:10 +00:00
te.nextthink = time + 225 * random() + 30; //WK Scramble the detpack's timer. :)
dremove(te.oldenemy); // Countdown ent
}
// Pipebomb?
else if (te.classname == "pipebomb")
{
te.nextthink = time + 0.1 + random();
}
// Mine?
else if (te.classname == "grenade" && te.netname == "land_mine")
{
te.think = GuerillaExplode;
te.nextthink = time + 0.1;
}
// Building?
else if (IsBuilding(te)) {
total_exp = total_exp + 120;
TF_T_Damage(te,self,self.owner, 120, 0, TF_TD_OTHER);
2001-07-17 05:58:10 +00:00
}
// Ammobox?
else if (te.classname == "ammobox")
{
expsize = 0;
expsize = expsize + (te.ammo_shells * 0.75);
expsize = expsize + ((te.ammo_rockets * 0.75) * 2);
expsize = expsize + ((te.ammo_cells * 0.75) * 2);
if (expsize > 0)
{
te.solid = SOLID_NOT;
2001-07-17 05:58:10 +00:00
// Damage player and explode
deathmsg = DMSG_GREN_EMP;
2001-07-17 05:58:10 +00:00
total_exp = total_exp + expsize;
if (expsize > 300) //CH so they are not too powerfull //WK was 500
expsize = 300;
T_RadiusDamage (te, self.owner, expsize, te);
te.think = SUB_Remove;
te.nextthink = time + 0.1;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, te.origin_x);
WriteCoord (MSG_BROADCAST, te.origin_y);
WriteCoord (MSG_BROADCAST, te.origin_z);
2001-07-17 05:58:10 +00:00
#ifdef QUAKE_WORLD
multicast (te.origin, MULTICAST_PHS);
2001-07-17 05:58:10 +00:00
#endif
}
}
// Backpack/Player?
else if ((te.classname == "player") || (te.classname=="monster_army") || (te.touch == BackpackTouch))
{
expsize = 0;
// calculate explosion size
expsize = expsize + (te.ammo_shells * 0.75);
expsize = expsize + ((te.ammo_rockets * 0.75) * 2);
if (!(te.weapons_carried & WEAP_SPANNER || te.touch == BackpackTouch))
2001-07-17 05:58:10 +00:00
expsize = expsize + (te.ammo_cells * 0.75);
if (expsize > 0)
{
// Damage player and explode
deathmsg = DMSG_GREN_EMP;
2001-07-17 05:58:10 +00:00
total_exp = total_exp + expsize;
//WK Make players not explode radially!
if (te.touch == BackpackTouch)
T_RadiusDamage (te, self.owner, expsize / 2, te); //WK Dampen backpack damage
if (te.touch != BackpackTouch)
{
TF_T_Damage (te, self, self.owner, expsize, 0, TF_TD_EXPLOSION);
2001-07-17 05:58:10 +00:00
// Remove ammo
te.ammo_shells = ceil(te.ammo_shells * 0.25);
te.ammo_rockets = ceil(te.ammo_rockets * 0.25);
if (!(te.cutf_items & CUTF_SENTRYGUN || te.tf_items & NIT_TESLA))
2001-07-17 05:58:10 +00:00
te.ammo_cells = ceil(te.ammo_cells * 0.25);
if (te.classname=="player")
{
// Update console
oldself = self;
self = te;
W_SetCurrentAmmo();
self = oldself;
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, te.origin_x);
WriteCoord (MSG_BROADCAST, te.origin_y);
WriteCoord (MSG_BROADCAST, te.origin_z);
2001-07-17 05:58:10 +00:00
#ifdef QUAKE_WORLD
multicast (te.origin, MULTICAST_PHS);
2001-07-17 05:58:10 +00:00
#endif
}
}
else
{
te.think = SUB_Remove;
te.nextthink = time + 0.1;
}
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, te.origin_x);
WriteCoord (MSG_BROADCAST, te.origin_y);
WriteCoord (MSG_BROADCAST, te.origin_z);
2001-07-17 05:58:10 +00:00
#ifdef QUAKE_WORLD
multicast (te.origin, MULTICAST_PHS);
2001-07-17 05:58:10 +00:00
#endif
}
}
te = te.chain;
}
sound (self, CHAN_WEAPON, "weapons/gren_emp.wav", 1, ATTN_NORM); //- OfN - cool sound! :)
2001-07-17 05:58:10 +00:00
if (total_exp > 0) {//CH Thanks Slice for the idea :)
sprint(self.owner,PRINT_HIGH, "Your EMP grenade inflicted ");
2001-07-17 05:58:10 +00:00
local string st;
st = ftos(total_exp);
sprint(self.owner,PRINT_HIGH, st);
sprint(self.owner,PRINT_HIGH, " damage\n");
2001-07-17 05:58:10 +00:00
}
#ifdef DEMO_STUFF
// Remove any camera's locks on this missile
if (self.enemy)
CamProjectileLockOff();
#endif
#ifdef QUAKE_WORLD
dremove(self);
#else
BecomeExplosion();
#endif
};
//=========================================================================
// Tests whether a team is allowed to build or not
float(float myteam) HasFlag =
{
if ( mapname != "steal4d" )
return TRUE;
2001-07-17 05:58:10 +00:00
if (myteam == team_with_flag){
return TRUE;
2001-07-17 05:58:10 +00:00
}
return FALSE;
2001-07-17 05:58:10 +00:00
};
//=========================================================================
// Function handling the Engineer's build impulse
void() TeamFortress_EngineerBuild =
{
local entity te;
// Can't build in the air
// WK Yes you can, why not? You can do it by pulling up this menu anyway
/*
if (!(self.flags & FL_ONGROUND))
2001-07-17 05:58:10 +00:00
{
CenterPrint(self, "You can't build in the air!\n\n");
return;
}
*/
if (self.is_detpacking == 1) {
CenterPrint(self, "You can't build while detpacking\n");
return;
}
if (self.is_feigning == 1) {
CenterPrint(self, "You can't build while feigning\n");
return;
}
// Pop up the menu
if (self.is_building == 0)
{
// Check to see if they've got enuf metal to build anything
if (self.ammo_cells < BUILD_COST_CAMERA && self.has_dispenser == FALSE && self.has_sentry == FALSE && self.has_tesla == FALSE && self.has_camera == FALSE && self.has_teleporter == FALSE && self.has_sensor == FALSE && self.has_fieldgen == FALSE)
2001-07-17 05:58:10 +00:00
{
CenterPrint(self, "You don't have enough metal to \nbuild anything.\n\n");
return;
}
self.current_menu = MENU_ENGINEER;
self.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
}
else if (self.is_building == 1)
{
sprint(self, PRINT_HIGH, "You stop building.\n");
2001-07-17 05:58:10 +00:00
self.is_building = 0;
self.tfstate = self.tfstate - (self.tfstate & TFSTATE_CANT_MOVE);
2001-07-17 05:58:10 +00:00
#ifdef QUAKE_WORLD
TeamFortress_SetSpeed(self);
#else
self.pausetime = time;
#endif
// Remove the timer
te = find(world, netname, "build_timer");
while (te)
{
if (te.owner == self)
{
dremove(te);
te = world;
}
else
{
te = find(te, netname, "build_timer");
}
}
self.current_weapon = self.weapon;
W_SetCurrentAmmo();
}
};
float(entity obj, entity builder) CheckArea =
{
local vector src, end;
local float pos;
// Check the origin
pos = pointcontents(obj.origin);
if (pos == CONTENT_SOLID || pos == CONTENT_SKY)
return FALSE;
2001-07-17 05:58:10 +00:00
// Check the surrounding area
src_x = obj.origin_x + obj.maxs_x + 16;
src_y = obj.origin_y + obj.maxs_y + 16;
src_z = obj.origin_z + obj.maxs_z + 16; // check upwards more
pos = pointcontents(src);
if (pos == CONTENT_SOLID || pos == CONTENT_SKY)
return FALSE;
2001-07-17 05:58:10 +00:00
end_x = obj.origin_x + obj.mins_x - 16;
end_y = obj.origin_y + obj.mins_y - 16;
end_z = obj.origin_z + obj.mins_z - 16;
traceline (src, end, TRUE, obj);
2001-07-17 05:58:10 +00:00
if (trace_fraction != 1)
return FALSE;
2001-07-17 05:58:10 +00:00
pos = pointcontents(end);
if (pos == CONTENT_SOLID || pos == CONTENT_SKY)
return FALSE;
2001-07-17 05:58:10 +00:00
// extend the size a little
src_x = obj.origin_x + obj.mins_x - 16;
src_y = obj.origin_y + obj.maxs_y + 16;
src_z = obj.origin_z + obj.maxs_z + 16;
pos = pointcontents(src);
if (pos == CONTENT_SOLID || pos == CONTENT_SKY)
return FALSE;
2001-07-17 05:58:10 +00:00
end_x = obj.origin_x + obj.maxs_x + 16;
end_y = obj.origin_y + obj.mins_y - 16;
end_z = obj.origin_z + obj.mins_z - 16; // check downwards less
traceline (src, end, TRUE, obj);
2001-07-17 05:58:10 +00:00
if (trace_fraction != 1)
return FALSE;
2001-07-17 05:58:10 +00:00
pos = pointcontents(end);
if (pos == CONTENT_SOLID || pos == CONTENT_SKY)
return FALSE;
2001-07-17 05:58:10 +00:00
// Trace a line from the player to the object too
traceline(builder.origin, obj.origin, TRUE, builder);
2001-07-17 05:58:10 +00:00
if (trace_fraction != 1)
return FALSE;
2001-07-17 05:58:10 +00:00
// may add in more checks later
return TRUE;
2001-07-17 05:58:10 +00:00
};
//////////////////////////////////////////////////////////////////////////
// rehashed version of TF_Build
void(float objtobuild) TeamFortress_Build =
{
local float btime;
local entity te;
local vector tmp1, tmp2;
newmis = spawn();
// get an origin
makevectors(self.v_angle);
v_forward_z = 0;
v_forward = normalize(v_forward) * 64;
if (objtobuild == BUILD_FIELDGEN) //- OfN - Field generators must be lined up to work
2001-07-17 05:58:10 +00:00
newmis.origin = WhereGen(self.origin + v_forward);
else
newmis.origin = self.origin + v_forward;
//WK Cheat Fix
if (self.is_feigning) {
sprint(self, PRINT_HIGH, "Try standing up first.\n");
2001-07-17 05:58:10 +00:00
return;
}
//OfN - Cheat Fix, heh
if (self.is_haxxxoring) {
sprint(self, PRINT_HIGH, "You can't build while hacking.\n");
2001-07-17 05:58:10 +00:00
return;
}
if (objtobuild == BUILD_DISPENSER)
2001-07-17 05:58:10 +00:00
{
if (self.has_dispenser)
{
sprint(self, PRINT_HIGH, "You can only have one dispenser.\nTry dismantling your old one.\n");
2001-07-17 05:58:10 +00:00
return;
}
if (!(self.cutf_items & CUTF_DISPENSER))
2001-07-17 05:58:10 +00:00
{
sprint(self, PRINT_HIGH, "You must buy the dispenser before you can build it.\n");
2001-07-17 05:58:10 +00:00
return;
}
tmp1 = '-16 -16 0';
tmp2 = '16 16 48';
#ifdef no_new_dispenser
newmis.mdl = "progs/disp.mdl";
#else
newmis.mdl = "progs/disp2.mdl";
#endif
newmis.netname = "dispenser";
btime = time + BUILD_TIME_DISPENSER;
2001-07-17 05:58:10 +00:00
}
else if (objtobuild == BUILD_SENTRYGUN)
2001-07-17 05:58:10 +00:00
{
if (self.has_sentry)
{
sprint(self, PRINT_HIGH, "You can only have one sentry gun.\nTry dismantling your old one.\n");
2001-07-17 05:58:10 +00:00
return;
}
if (!(self.cutf_items & CUTF_SENTRYGUN))
2001-07-17 05:58:10 +00:00
{
sprint(self, PRINT_HIGH, "You must buy a sentrygun before you can build one.\n");
2001-07-17 05:58:10 +00:00
return;
}
tmp1 = '-16 -16 0';
tmp2 = '16 16 48';
//newmis.mdl = "progs/turrbase.mdl";
newmis.mdl = "progs/trrbs2.mdl";
newmis.netname = "sentrygun";
btime = time + BUILD_TIME_SENTRYGUN;
2001-07-17 05:58:10 +00:00
}
else if (objtobuild == BUILD_TESLA)
2001-07-17 05:58:10 +00:00
{
if (self.has_tesla)
{
sprint(self, PRINT_HIGH, "You can only have one tesla gun.\nTry dismantling your old one.\n");
2001-07-17 05:58:10 +00:00
return;
}
if (!(self.tf_items & NIT_TESLA))
2001-07-17 05:58:10 +00:00
{
sprint(self, PRINT_HIGH, "You must buy a tesla sentry before you can build one.\n");
2001-07-17 05:58:10 +00:00
return;
}
//tmp1 = '-16 -16 0'; //- OfN commented by
tmp1 = '-16 -16 -25';
//tmp2 = '16 16 48'; //WK 62 is better, but crashes?
tmp2 = '16 16 23';
//newmis.mdl = "progs/newtesla.mdl";
newmis.mdl = "progs/coil.mdl";
newmis.netname = "tesla";
newmis.origin = newmis.origin + '0 0 25';
btime = time + BUILD_TIME_TESLA;
2001-07-17 05:58:10 +00:00
}
else if (objtobuild == BUILD_SECURITY_CAMERA)
2001-07-17 05:58:10 +00:00
{
if (self.has_camera)
{
sprint(self, PRINT_HIGH, "You can only have one security camera.\nTry dismantling your old one.\n");
2001-07-17 05:58:10 +00:00
return;
}
if (!(self.tf_items & NIT_SECURITY_CAMERA))
2001-07-17 05:58:10 +00:00
{
sprint(self, PRINT_HIGH, "You must buy a security camera before you can build one.\n");
2001-07-17 05:58:10 +00:00
return;
}
Security_Camera_Spawn();
}
else if (objtobuild == BUILD_TELEPORTER)
2001-07-17 05:58:10 +00:00
{
if (self.has_teleporter >= 2)
{
sprint(self, PRINT_HIGH, "You can only have 2 teleporters.\nTry dismantling an old one.\n");
2001-07-17 05:58:10 +00:00
return;
}
if (!(self.tf_items & NIT_TELEPORTER))
2001-07-17 05:58:10 +00:00
{
sprint(self, PRINT_HIGH, "You must buy a teleporter before you can build one.\n");
2001-07-17 05:58:10 +00:00
return;
}
tmp1 = '-16 -16 0';
tmp2 = '16 16 4';
newmis.mdl = "progs/telepad.mdl";
newmis.netname = "teleporter";
btime = time + BUILD_TIME_TELEPORTER;
2001-07-17 05:58:10 +00:00
}
else if (objtobuild == BUILD_FIELDGEN)
2001-07-17 05:58:10 +00:00
{
if (self.has_fieldgen >= 2)
{
sprint(self, PRINT_HIGH, "You already have 2 field generators.\nTry dismantling an old one.\n");
2001-07-17 05:58:10 +00:00
return;
}
if (!(self.cutf_items & CUTF_FIELDGEN))
2001-07-17 05:58:10 +00:00
{
sprint(self, PRINT_HIGH, "You must buy a field generator before you can build one.\n");
2001-07-17 05:58:10 +00:00
return;
}
tmp1 = '-6 -6 0';
tmp2 = '6 6 54';
newmis.mdl = "progs/ffgen2.mdl";
newmis.netname = "field generator";
btime = time + BUILD_TIME_FIELDGEN;
2001-07-17 05:58:10 +00:00
}
if (objtobuild != BUILD_SECURITY_CAMERA)
2001-07-17 05:58:10 +00:00
{
// before we start building it, check it out
// check for validity of point
if (CheckArea(newmis, self) == FALSE)
2001-07-17 05:58:10 +00:00
{
sprint(self, PRINT_HIGH, "Not enough room to build here\n");
2001-07-17 05:58:10 +00:00
dremove(newmis);
return;
}
self.is_building = 1;
makeImmune(self,time + 2);
//self.immune_to_check = time + 2;
self.tfstate = self.tfstate | TFSTATE_CANT_MOVE;
2001-07-17 05:58:10 +00:00
// Save the current weapon and remove it
self.weapon = self.current_weapon;
self.current_weapon = 0;
self.weaponmodel = "";
self.weaponframe = 0;
#ifdef QUAKE_WORLD
TeamFortress_SetSpeed(self);
#else
self.pausetime = btime;
#endif
newmis.owner = self;
newmis.classname = "timer";
newmis.netname = "build_timer";
newmis.nextthink = btime;
newmis.think = TeamFortress_FinishedBuilding;
newmis.colormap = self.colormap;
newmis.weapon = objtobuild;
newmis.angles_y = anglemod(self.angles_y + 180);
newmis.velocity = '0 0 8';
newmis.movetype = MOVETYPE_TOSS;
2001-07-17 05:58:10 +00:00
newmis.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
setmodel (newmis, newmis.mdl);
setsize (newmis, tmp1, tmp2);
setorigin (newmis, newmis.origin);
if (objtobuild==BUILD_TESLA)
2001-07-17 05:58:10 +00:00
{
newmis.skin = self.team_no;
if (self.team_no==3) newmis.skin=0;
else if (self.team_no==4) newmis.skin=3;
}
newmis.flags = newmis.flags - (newmis.flags & FL_ONGROUND);
2001-07-17 05:58:10 +00:00
}
};
void() DispenserThink =
{
local float iI; // is Improved?
iI=1;
if (self.num_mines & IMPROVED_ONE)
2001-07-17 05:58:10 +00:00
iI=2;
// dispenser refilling itself 5%
if (!(self.is_malfunctioning & SCREWUP_THREE)) // SB
2001-07-17 05:58:10 +00:00
{
self.ammo_shells = self.ammo_shells + rint((BUILD_DISPENSER_MAX_SHELLS*iI) / 10);
self.ammo_cells = self.ammo_cells + rint((BUILD_DISPENSER_MAX_CELLS*iI) / 10);
self.ammo_nails = self.ammo_nails + rint((BUILD_DISPENSER_MAX_NAILS*iI) / 10);
self.ammo_rockets = self.ammo_rockets + rint((BUILD_DISPENSER_MAX_ROCKETS*iI) / 10);
self.armorvalue = self.armorvalue + rint((BUILD_DISPENSER_MAX_ARMOR*iI) / 10);
if (self.ammo_shells > BUILD_DISPENSER_MAX_SHELLS*iI)
self.ammo_shells = BUILD_DISPENSER_MAX_SHELLS*iI;
if (self.ammo_nails > BUILD_DISPENSER_MAX_NAILS*iI)
self.ammo_nails = BUILD_DISPENSER_MAX_NAILS*iI;
if (self.ammo_rockets > BUILD_DISPENSER_MAX_ROCKETS*iI)
self.ammo_rockets = BUILD_DISPENSER_MAX_ROCKETS*iI;
if (self.ammo_cells > BUILD_DISPENSER_MAX_CELLS*iI)
self.ammo_cells = BUILD_DISPENSER_MAX_CELLS*iI;
if (self.armorvalue > BUILD_DISPENSER_MAX_ARMOR*iI)
self.armorvalue = BUILD_DISPENSER_MAX_ARMOR*iI;
2001-07-17 05:58:10 +00:00
}
self.nextthink = time + 10;
};
void() TeamFortress_FinishedBuilding =
{
local entity oldself;
local float current_yaw;
local vector source;
if (self.owner.is_building != 1)
return;
oldself = self;
self = self.owner;
oldself.owner = world;
oldself.real_owner = self;
self.is_building = 0;
self.tfstate = self.tfstate - (self.tfstate & TFSTATE_CANT_MOVE);
2001-07-17 05:58:10 +00:00
self.current_weapon = self.weapon;
self.StatusRefreshTime = time + 0.1;
TeamFortress_SetSpeed(self);
if (oldself.weapon == BUILD_DISPENSER)
2001-07-17 05:58:10 +00:00
{
self.has_dispenser = TRUE;
sprint (self, PRINT_HIGH, "You finish building the dispenser.\n");
2001-07-17 05:58:10 +00:00
teamprefixsprint(self.team_no,self); //- OfN
teamsprint(self.team_no, self, self.netname);
teamsprint(self.team_no, self, " has built a Dispenser.\n");
self.ammo_cells = self.ammo_cells - BUILD_COST_DISPENSER;
2001-07-17 05:58:10 +00:00
// Create the dispenser
oldself.classname = "building_dispenser";
oldself.netname = "dispenser";
oldself.blocked = T_Dispenser; // Actual touch function
oldself.touch = T_Dispenser;
oldself.max_health = BUILD_HEALTH_DISPENSER;
oldself.health = BUILD_HEALTH_DISPENSER;
2001-07-17 05:58:10 +00:00
oldself.think = DispenserThink;
oldself.nextthink = time + 5;
oldself.th_die = Dispenser_Die; // Death function
#ifdef no_new_dispenser
oldself.mdl = "progs/disp.mdl"; // Actual mdl
#else
oldself.mdl = "progs/disp2.mdl"; // Actual mdl
#endif
oldself.team_no = self.team_no;
oldself.num_mines=0; // OfN - reset HACKER improvements
oldself.real_owner = self; // The Engineer owns this item
oldself.colormap = self.colormap; // Set the Color
oldself.takedamage = DAMAGE_AIM;
2001-07-17 05:58:10 +00:00
oldself.owner = world;
oldself.movetype = MOVETYPE_TOSS;
2001-07-17 05:58:10 +00:00
oldself.velocity = '0 0 8';
oldself.flags = oldself.flags - (oldself.flags & FL_ONGROUND);
2001-07-17 05:58:10 +00:00
// Put some ammo in the Dispenser
oldself.ammo_shells = ceil(self.ammo_shells * 0.25);
oldself.ammo_nails = ceil(self.ammo_nails * 0.25);
oldself.ammo_rockets = ceil(self.ammo_rockets * 0.25);
oldself.ammo_cells = ceil(self.ammo_cells * 0.25);
oldself.armorvalue = ceil(self.armorvalue * 0.25);
// Remove ours
self.ammo_shells = ceil(self.ammo_shells * 0.75);
self.ammo_nails = ceil(self.ammo_nails * 0.75);
self.ammo_rockets = ceil(self.ammo_rockets * 0.75);
self.ammo_cells = ceil(self.ammo_cells * 0.75);
self.armorvalue = ceil(self.armorvalue * 0.75);
oldself.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
setmodel(oldself, oldself.mdl);
setsize (oldself, '-8 -8 0', '8 8 24');
setorigin(oldself, oldself.origin + '0 0 16'); //CH disp does jump
}
else if (oldself.weapon == BUILD_SENTRYGUN)
2001-07-17 05:58:10 +00:00
{
//CH special sbar for eng.
self.StatusBarScreen = 1;
self.has_sentry = TRUE;
sprint (self, PRINT_HIGH, "You finish building the sentry gun.\n");
2001-07-17 05:58:10 +00:00
teamprefixsprint(self.team_no,self); //- OfN
teamsprint(self.team_no, self, self.netname);
teamsprint(self.team_no, self, " has built a Sentry Gun.\n");
oldself.classname = "building_sentrygun_base";
oldself.netname = "sentry gun";
oldself.takedamage = 0;
oldself.th_die = Sentry_Die; // Death function
self.ammo_cells = self.ammo_cells - BUILD_COST_SENTRYGUN;
2001-07-17 05:58:10 +00:00
setsize (oldself, '-16 -16 0', '16 16 4'); // '-16 -16 0' '16 16 4'
newmis = spawn();
newmis.classname = "building_sentrygun";
newmis.health = BUILD_HEALTH_SENTRYGUN;
2001-07-17 05:58:10 +00:00
newmis.max_health = newmis.health;
newmis.tf_items = NIT_KEVLAR; //Start with kevlar armor
newmis.armorclass = AT_SAVESHOT; //kevlar armor
2001-07-17 05:58:10 +00:00
newmis.weapon = 1; // Level 1 Turret
newmis.th_die = Sentry_Die; // Death function
newmis.th_pain = Sentry_Pain;
//newmis.mdl = "progs/turrgun.mdl";
newmis.mdl = "progs/trrgn2.mdl";
sound (oldself, CHAN_ITEM, "weapons/turrset.wav", 1, ATTN_NORM);
newmis.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
setmodel(newmis, newmis.mdl);
setsize (newmis, '-16 -16 0', '16 16 48');
setorigin(newmis, oldself.origin + '0 0 8');
newmis.real_owner = oldself.real_owner; // The Engineer owns this item
newmis.trigger_field = oldself;
oldself.oldenemy = newmis;
newmis.movetype = MOVETYPE_STEP;
2001-07-17 05:58:10 +00:00
oldself.colormap = self.colormap; // Set the Base Color
newmis.colormap = self.colormap; // Set the Color
newmis.skin = self.team_no - 1;
newmis.takedamage = DAMAGE_AIM;
2001-07-17 05:58:10 +00:00
newmis.velocity = '0 0 -8';
newmis.flags = newmis.flags - (newmis.flags & FL_ONGROUND);
oldself.flags = oldself.flags - (oldself.flags & FL_ONGROUND);
2001-07-17 05:58:10 +00:00
newmis.frags = 0; //CH how many people has your sent killed?
newmis.team_no = self.team_no;
newmis.think = lvl1_sentry_stand;
newmis.nextthink = time + 0.5;
newmis.touch = Sentry_Touch;
// Rotate Details
newmis.yaw_speed = 10; //Turn rate
newmis.heat = 0; // Turn Right
newmis.angles_x = 0;
newmis.angles_y = ceil(oldself.angles_y); //CH remove decimal
newmis.angles_z = 0;
newmis.angles_y = ((ceil(newmis.angles_y / 10)) * 10); //CH set last int to 0
newmis.waitmin = anglemod(newmis.angles_y - 50);
newmis.waitmax = anglemod(newmis.angles_y + 50);
// Give the Gun some ammo
newmis.ammo_shells = 75; //WK
newmis.maxammo_shells = 100;
newmis.maxammo_rockets = 20;
newmis.num_mines=0; // OfN - reset HACKER improvements
newmis.attack_finished=time; //- controls time after loosing track of enemy to not be rotating
newmis.has_holo=0;
}
else if (oldself.weapon == BUILD_TESLA)
2001-07-17 05:58:10 +00:00
{
//CH special sbar for eng.
self.StatusBarScreen = 4;
self.has_tesla = TRUE;
sprint (self, PRINT_HIGH, "You finish building the tesla.\n");
2001-07-17 05:58:10 +00:00
teamprefixsprint(self.team_no,self); //- OfN
teamsprint(self.team_no, self, self.netname);
teamsprint(self.team_no, self, " has built a tesla.\n");
sound (oldself, CHAN_ITEM, "weapons/guerilla_set.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
oldself.classname = "building_tesla";
oldself.netname = "tesla";
oldself.takedamage = DAMAGE_AIM;
oldself.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
oldself.th_die = Tesla_Die; // Death function
oldself.th_pain = Tesla_Pain;
self.ammo_cells = self.ammo_cells - BUILD_COST_TESLA;
2001-07-17 05:58:10 +00:00
oldself.health = BUILD_HEALTH_TESLA;
oldself.movetype = MOVETYPE_TOSS;
2001-07-17 05:58:10 +00:00
oldself.colormap = self.colormap; // Set the Base Color
oldself.velocity = '0 0 -8';
oldself.avelocity = '0 0 0';
oldself.flags = oldself.flags - (oldself.flags & FL_ONGROUND);
2001-07-17 05:58:10 +00:00
oldself.team_no = self.team_no;
//- OfN -
//oldself.think = Tesla_Idle;
oldself.think = tsla_on1;
//oldself.nextthink = time + 2;
oldself.nextthink = time + 0.1;
oldself.has_holo = time + 2; // next Tesla_Idle run
oldself.job = 0; // this flag will determine which frame animation is currently on
//oldself.job_finished = time; // change for frame animation purposes, instead of increasing its nextthing during charging
oldself.no_grenades_1 = FALSE; // first think reset
2001-07-17 05:58:10 +00:00
oldself.no_grenades_2 = 0; // cloak touch delay reset
oldself.touch = Tesla_Touch;
oldself.enemy = world;
oldself.oldenemy = world; //CH for sbar
//Set all initial tesla values here
oldself.maxammo_shells = 0; //Voltage == 0
oldself.maxammo_nails = 0; //Amps == 0
oldself.maxammo_rockets = 0; //Battery == 0
oldself.max_health = 150;
oldself.ammo_cells = MAXCELLS0; //Initial ammo allocation
oldself.maxammo_cells = MAXCELLS0; //Initial maxammo
oldself.tf_items = NIT_CERAMIC; //Start with shock armor
oldself.armorclass = AT_SAVEELECTRICITY; //Shock armor
if (self.tf_items & NIT_TESLA_UPGRADE) {
2001-07-17 05:58:10 +00:00
oldself.has_sentry = 6; //Normal Upgrades
oldself.has_tesla = 2; //Misc Upgrade
}
else
{
oldself.has_sentry = 4; //Normal Upgrades
oldself.has_tesla = 1; //Misc Upgrade
}
oldself.has_teleporter = 0; //CH for frag related upgrades
if (!(self.weapons_carried & WEAP_SPANNER)) { //No spanner
2001-07-17 05:58:10 +00:00
oldself.ammo_shells = 1;
oldself.ammo_nails = 2;
oldself.ammo_rockets = 1;
oldself.has_sentry = oldself.has_sentry - 4; //Take away 3
oldself.max_health = 225;
oldself.ammo_cells = MAXCELLS1; //Initial ammo allocation
oldself.maxammo_cells = MAXCELLS1;
2001-07-17 05:58:10 +00:00
}
oldself.health = oldself.max_health;
oldself.waitmin = (oldself.ammo_shells + 2) * (oldself.ammo_nails + 2);
oldself.waitmax = FALSE; //No target yet
2001-07-17 05:58:10 +00:00
oldself.frags = 0; //CH how many people has your sent killed?
oldself.lip = 0; //WK How many tinkers have been done
modelindex_tesla = oldself.modelindex; //CH
oldself.num_mines=0; // OfN - reset HACKER improvements
oldself.is_haxxxoring=0; // isnt flying
}
else if (oldself.weapon == BUILD_TELEPORTER)
2001-07-17 05:58:10 +00:00
{
self.has_teleporter = (self.has_teleporter + 1);
sprint (self, PRINT_HIGH, "You finish building the Teleporter Pad.\n");
2001-07-17 05:58:10 +00:00
teamprefixsprint(self.team_no,self); //- OfN
teamsprint(self.team_no, self, self.netname);
teamsprint(self.team_no, self, " has built a Teleporter Pad.\n");
sound (oldself, CHAN_ITEM, "weapons/guerilla_set.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
self.ammo_cells = self.ammo_cells - BUILD_COST_TELEPORTER;
2001-07-17 05:58:10 +00:00
// Create the teleporter
oldself.classname = "building_teleporter";
oldself.netname = "teleporter";
// oldself.blocked = Teleporter_touch; // Actual touch function
oldself.touch = Teleporter_touch;
oldself.max_health = BUILD_HEALTH_TELEPORTER;
oldself.health = BUILD_HEALTH_TELEPORTER;
2001-07-17 05:58:10 +00:00
oldself.th_die = Teleporter_Die; // Death function
oldself.mdl = "progs/telepad.mdl"; // Actual mdl
oldself.team_no = self.team_no;
oldself.maxammo_cells = 200; //CH Max of 20 teleports
oldself.ammo_cells = 100; //CH start not at full
oldself.real_owner = self; // The Engineer owns this item
oldself.colormap = self.colormap; // Set the Color
oldself.takedamage = DAMAGE_AIM;
2001-07-17 05:58:10 +00:00
oldself.owner = world;
oldself.movetype = MOVETYPE_TOSS;
2001-07-17 05:58:10 +00:00
oldself.velocity = '0 0 8';
oldself.flags = oldself.flags - (oldself.flags & FL_ONGROUND);
2001-07-17 05:58:10 +00:00
oldself.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
setmodel(oldself, oldself.mdl);
setsize (oldself, '-16 -16 0', '16 16 4');
setorigin(oldself, oldself.origin + '0 0 8'); //CH does jump
oldself.heat = 4; //dont come on for 4 seconds
oldself.think = Teleporter_heat_think;
oldself.nextthink = time + 1;
oldself.spawnflags = 4; //CH cause extensive checks for height
oldself.num_mines=0; // OfN - reset HACKER improvements
}
else if (oldself.weapon == BUILD_FIELDGEN)
2001-07-17 05:58:10 +00:00
{
self.has_fieldgen = (self.has_fieldgen + 1);
sprint (self, PRINT_HIGH, "You finish building the Field Generator.\n");
2001-07-17 05:58:10 +00:00
teamprefixsprint(self.team_no,self); //- OfN
teamsprint(self.team_no, self, self.netname);
teamsprint(self.team_no, self, " has built a Field Generator.\n");
sound (oldself, CHAN_ITEM, "weapons/guerilla_set.wav", 1, ATTN_NORM);
2001-07-17 05:58:10 +00:00
self.ammo_cells = self.ammo_cells - BUILD_COST_FIELDGEN;
2001-07-17 05:58:10 +00:00
// Create the teleporter
oldself.classname = "building_fieldgen";
oldself.netname = "field generator";
// oldself.blocked = Teleporter_touch; // Actual touch function
//oldself.touch = Teleporter_touch;
oldself.max_health = BUILD_HEALTH_FIELDGEN;
oldself.health = BUILD_HEALTH_FIELDGEN;
2001-07-17 05:58:10 +00:00
oldself.th_die = FieldGen_Die; // Death function
oldself.mdl = "progs/ffgen2.mdl"; // Actual mdl
oldself.team_no = self.team_no;
oldself.maxammo_cells = 100; //CH Max of 20 field recharges
oldself.ammo_cells = 75; //CH start not at full*/
oldself.real_owner = self; // The Engineer owns this item
oldself.colormap = self.colormap; // Set the Color
oldself.takedamage = DAMAGE_AIM;
2001-07-17 05:58:10 +00:00
oldself.owner = world;
oldself.movetype = MOVETYPE_TOSS;
2001-07-17 05:58:10 +00:00
oldself.velocity = '0 0 8';
oldself.flags = oldself.flags - (oldself.flags & FL_ONGROUND);
2001-07-17 05:58:10 +00:00
oldself.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
oldself.angles = '0 0 0';
setmodel(oldself, oldself.mdl);
setsize (oldself, '-6 -6 0', '6 6 54');
setorigin(oldself, oldself.origin + '0 0 8'); //CH does jump
//oldself.heat = 4; //dont come on for 4 seconds
/*oldself.think = Teleporter_heat_think;
oldself.nextthink = time + 1;*/
oldself.spawnflags = 4; //CH cause extensive checks for height
oldself.is_malfunctioning = 0;
oldself.num_mines=0; // OfN - reset HACKER improvements
Field_Built(oldself);
}
W_SetCurrentAmmo();
};
//=========================================================================
// Dispenser Touch function. Allows players to get stuff from the Dispenser.
void() T_Dispenser =
{
local entity dist_checker;
if (other.classname != "player")
return;
if (self.is_malfunctioning & SCREWUP_ONE)
2001-07-17 05:58:10 +00:00
return;
if (self.is_malfunctioning & SCREWUP_TWO)
TF_T_Damage(self, self, self, 200, 0, TF_TD_OTHER);
2001-07-17 05:58:10 +00:00
// Ignore any engineer working on this dispenser
if (other.building == world && other.building_wait < time)
{
// Pop up the menu
other.current_menu = MENU_DISPENSER;
other.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
other.building = self;
// Start a Distance checker, which removes the menu if the player
// gets too far away from the Dispenser.
dist_checker = spawn();
dist_checker.classname = "timer";
dist_checker.owner = other;
dist_checker.enemy = self;
dist_checker.think = CheckDistance;
dist_checker.nextthink = time + 0.3;
}
};
//============================================================
// this is needed to avoid stack overflow
void() Dispenser_Explode =
{
T_RadiusDamage(self.demon_one, self.demon_one, self.has_holo, world);
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.demon_one.origin_x);
WriteCoord (MSG_BROADCAST, self.demon_one.origin_y);
WriteCoord (MSG_BROADCAST, self.demon_one.origin_z);
2001-07-17 05:58:10 +00:00
#ifdef QUAKE_WORLD
multicast (self.demon_one.origin, MULTICAST_PHS);
2001-07-17 05:58:10 +00:00
dremove(self.demon_one);
#else
BecomeExplosion ();
#endif
dremove(self); // remove explosion timer for this dispenser
};
void() Dispenser_Die =
{
local float damg;
self.real_owner.has_dispenser = FALSE;
2001-07-17 05:58:10 +00:00
damg = self.ammo_cells * 0.25;
damg = damg + self.ammo_nails * 0.1;
damg = damg + self.ammo_shells * 0.2;
damg = damg + self.ammo_rockets / 2;
//- OfN causes overflow so we need a timer for dispenser explosion
newmis = spawn();
newmis.has_holo = damg;
newmis.demon_one = self;
newmis.nextthink = time + 0.1;
newmis.think = Dispenser_Explode;
/*T_RadiusDamage(self, self, damg, world); // OfN - Fixme, stack overflow??*/
sprint(self.real_owner, PRINT_HIGH, "Your dispenser was destroyed.\n");
2001-07-17 05:58:10 +00:00
#ifdef no_new_dispenser
ThrowGib("progs/dgib1.mdl", -30);
ThrowGib("progs/dgib2.mdl", -50);
ThrowGib("progs/dgib3.mdl", -50);
#else
ThrowGib("progs/d2gib1.mdl", -30);
ThrowGib("progs/d2gib2.mdl", -50);
ThrowGib("progs/d2gib3.mdl", -50);
#endif
};
//=========================================================================
// Engineer has used a Spanner on the Dispenser
void(entity disp) Engineer_UseDispenser =
{
local entity dist_checker;
local string st;
// Print the dispenser's details
sprint (self, PRINT_HIGH, "Dispenser has ");
2001-07-17 05:58:10 +00:00
st = ftos(disp.health);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "<EFBFBD>");
2001-07-17 05:58:10 +00:00
st = ftos(disp.max_health);
sprint(self, PRINT_HIGH, st);
sprint (self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
2001-07-17 05:58:10 +00:00
st = ftos(disp.ammo_shells);
sprint (self, PRINT_HIGH, st);
sprint (self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ");
2001-07-17 05:58:10 +00:00
st = ftos(disp.ammo_nails);
sprint (self, PRINT_HIGH, st);
sprint (self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD>, ");
2001-07-17 05:58:10 +00:00
st = ftos(disp.ammo_rockets);
sprint (self, PRINT_HIGH, st);
sprint (self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
2001-07-17 05:58:10 +00:00
st = ftos(disp.ammo_cells);
sprint (self, PRINT_HIGH, st);
sprint (self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD>, and ");
2001-07-17 05:58:10 +00:00
st = ftos(disp.armorvalue);
sprint (self, PRINT_HIGH, st);
sprint (self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD>\n");
2001-07-17 05:58:10 +00:00
// Pop up the menu
self.current_menu = MENU_ENGINEER_FIX_DISPENSER;
self.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
self.building = disp;
// Start a Distance checker, which removes the menu if the player
// gets too far away from the Dispenser.
dist_checker = spawn();
dist_checker.classname = "timer";
dist_checker.owner = self;
dist_checker.enemy = disp;
dist_checker.think = CheckDistance;
dist_checker.nextthink = time + 0.3;
};
//=========================================================================
// Engineer has used a Spanner on the SentryGun
void(entity gun) Engineer_UseSentryGun =
{
local entity dist_checker;
local string st;
// Print the gun's details
sprint(self, PRINT_HIGH, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ");
2001-07-17 05:58:10 +00:00
st = Return_Colored_Num(gun.weapon);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " Sentry Gun has ");
2001-07-17 05:58:10 +00:00
st = ftos(gun.health);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "<EFBFBD>");
2001-07-17 05:58:10 +00:00
st = ftos(gun.max_health);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ");
2001-07-17 05:58:10 +00:00
st = ftos(gun.ammo_shells);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
2001-07-17 05:58:10 +00:00
if (gun.weapon == 3)
{
st = ftos(gun.ammo_rockets);
sprint(self, PRINT_HIGH, ", ");
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
2001-07-17 05:58:10 +00:00
}
sprint(self, PRINT_HIGH, "\n");
2001-07-17 05:58:10 +00:00
sprint(self, PRINT_HIGH, "Sentry Gun <20><><EFBFBD><EFBFBD><EFBFBD>: "); //CH Displays kills of sent
2001-07-17 05:58:10 +00:00
st = ftos(gun.frags);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "\n");
2001-07-17 05:58:10 +00:00
// Pop up the menu
self.current_menu = MENU_ENGINEER_FIX_SENTRYGUN;
self.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
self.building = gun;
//dodgy
if (teamplay != 0 && !Teammate(self.building.real_owner.team_no,self.team_no)) {
Menu_EngineerFix_SentryGun_Input(5);
return;
}
// Start a Distance checker, which removes the menu if the player
// gets too far away from the sentry.
dist_checker = spawn();
dist_checker.classname = "timer";
dist_checker.owner = self;
dist_checker.enemy = gun;
dist_checker.think = CheckDistance;
dist_checker.nextthink = time + 0.3;
};
////////////////////////////////////////////////
// Engineer has used a Spanner on the Tesla
void(entity gun) Engineer_UseTesla =
{
local entity dist_checker;
local string st;
// Print the gun's details
sprint(self, PRINT_HIGH, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:");
2001-07-17 05:58:10 +00:00
st = ftos(gun.health);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "<EFBFBD>");
2001-07-17 05:58:10 +00:00
st = ftos(gun.max_health);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD>:");
2001-07-17 05:58:10 +00:00
st = ftos(gun.ammo_cells);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "<EFBFBD>");
2001-07-17 05:58:10 +00:00
st = ftos(gun.maxammo_cells);
sprint(self, PRINT_HIGH, st);
2001-07-17 05:58:10 +00:00
st = ftos(gun.has_sentry);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ups Left:");
sprint(self, PRINT_HIGH, st);
2001-07-17 05:58:10 +00:00
st = ftos(gun.has_tesla);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD> Ups Left:");
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "\n");
2001-07-17 05:58:10 +00:00
sprint(self, PRINT_HIGH, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:");
2001-07-17 05:58:10 +00:00
st = ftos(gun.ammo_shells);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:");
2001-07-17 05:58:10 +00:00
st = ftos(gun.ammo_nails);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:");
2001-07-17 05:58:10 +00:00
st = ftos(gun.ammo_rockets);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "\n");
2001-07-17 05:58:10 +00:00
if (gun.tf_items) {
local float num;
num = 0;
if (gun.tf_items & NIT_TURRET) {
sprint(self, PRINT_HIGH, "TeslaTurret(tm). ");
2001-07-17 05:58:10 +00:00
num = num + 1;
}
if (gun.tf_items & NIT_SCANNER) {
sprint(self, PRINT_HIGH, "Improved Targeter. ");
2001-07-17 05:58:10 +00:00
num = num + 1;
}
if (gun.tf_items & NIT_AUTOID) {
sprint(self, PRINT_HIGH, "Spy Detector. ");
2001-07-17 05:58:10 +00:00
num = num + 1;
}
if (gun.tf_items & NIT_KEVLAR) {
sprint(self, PRINT_HIGH, "Kevlar Armor. ");
2001-07-17 05:58:10 +00:00
num = num + 1;
}
if (gun.tf_items & NIT_BLAST) {
sprint(self, PRINT_HIGH, "Blast Armor. ");
2001-07-17 05:58:10 +00:00
num = num + 1;
}
if (gun.tf_items & NIT_ASBESTOS) {
sprint(self, PRINT_HIGH, "Asbestos Armor. ");
2001-07-17 05:58:10 +00:00
num = num + 1;
}
if (gun.tf_items & NIT_TELEPORTER) {
sprint(self, PRINT_HIGH, "Upgrades from frags. ");
2001-07-17 05:58:10 +00:00
num = num + 1;
}
if (gun.tf_items & NIT_TESLA_CLOAKING) {
sprint(self, PRINT_HIGH, "Cloaking Device. ");
2001-07-17 05:58:10 +00:00
num = num + 1;
}
if (num != 0)
sprint(self, PRINT_HIGH, "\n");
2001-07-17 05:58:10 +00:00
}
sprint(self, PRINT_HIGH, "Tesla Sentry <20><><EFBFBD><EFBFBD><EFBFBD>: "); //CH Displays kills of tesla
2001-07-17 05:58:10 +00:00
st = ftos(gun.frags);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "\n");
2001-07-17 05:58:10 +00:00
// Pop up the menu
self.current_menu = MENU_ENGINEER_FIX_TESLA;
self.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
self.building = gun;
// dodgy
if (teamplay != 0 && !Teammate(self.building.real_owner.team_no, self.team_no)) {
Menu_EngineerFix_Tesla_Input(8);
return;
}
// Start a Distance checker, which removes the menu if the player
// gets too far away from the tesla.
dist_checker = spawn();
dist_checker.classname = "timer";
dist_checker.owner = self;
dist_checker.enemy = gun;
dist_checker.think = CheckDistance;
dist_checker.nextthink = time + 0.3;
};
//=================
void(entity cam) Engineer_UseSensor =
{
local entity dist_checker;
local string st;
sprint(self, PRINT_HIGH, "Motion Sensor has ");
2001-07-17 05:58:10 +00:00
st = ftos(cam.health);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "<EFBFBD>");
2001-07-17 05:58:10 +00:00
st = ftos(ceil(cam.max_health));
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
2001-07-17 05:58:10 +00:00
// Pop up the menu
self.current_menu = MENU_ENGINEER_FIX_SENSOR;
self.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
self.building = cam;
if (teamplay != 0 && !Teammate(self.building.real_owner.team_no, self.team_no)) {
Menu_EngineerFix_Sensor_Input(3);
return;
}
// Start a Distance checker, which removes the menu if the player
// gets too far away from the camera.
dist_checker = spawn();
dist_checker.classname = "timer";
dist_checker.owner = self;
dist_checker.enemy = cam;
dist_checker.think = CheckDistance;
dist_checker.nextthink = time + 0.3;
};
//=================
void(entity cam) Engineer_UseCamera =
{
local entity dist_checker;
local string st;
sprint(self, PRINT_HIGH, "Security Camera has ");
2001-07-17 05:58:10 +00:00
st = ftos(cam.health);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "<EFBFBD>");
2001-07-17 05:58:10 +00:00
st = ftos(ceil(cam.max_health));
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
2001-07-17 05:58:10 +00:00
// Pop up the menu
self.current_menu = MENU_ENGINEER_FIX_CAMERA;
self.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
self.building = cam;
if (teamplay != 0 && !Teammate(self.building.real_owner.team_no,self.team_no)) {
Menu_EngineerFix_Camera_Input(3);
return;
}
// Start a Distance checker, which removes the menu if the player
// gets too far away from the camera.
dist_checker = spawn();
dist_checker.classname = "timer";
dist_checker.owner = self;
dist_checker.enemy = cam;
dist_checker.think = CheckDistance;
dist_checker.nextthink = time + 0.3;
};
//=================
void(entity tele) Engineer_UseTeleporter =
{
local entity dist_checker;
local string st;
sprint(self, PRINT_HIGH, "Teleporter Pad has ");
2001-07-17 05:58:10 +00:00
st = ftos(tele.health);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "<EFBFBD>");
2001-07-17 05:58:10 +00:00
st = ftos(ceil(tele.max_health));
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ");
2001-07-17 05:58:10 +00:00
st = ftos(tele.ammo_cells);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "<EFBFBD>");
2001-07-17 05:58:10 +00:00
st = ftos(ceil(tele.maxammo_cells));
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, " <20><><EFBFBD><EFBFBD><EFBFBD>\n");
2001-07-17 05:58:10 +00:00
// Pop up the menu
self.current_menu = MENU_ENGINEER_FIX_TELEPORTER;
self.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
self.building = tele;
if (teamplay != 0 && !Teammate(self.building.real_owner.team_no,self.team_no)) {
Menu_EngineerFix_Teleporter_Input(4);
return;
}
// Start a Distance checker, which removes the menu if the player
// gets too far away from the teleporter.
dist_checker = spawn();
dist_checker.classname = "timer";
dist_checker.owner = self;
dist_checker.enemy = tele;
dist_checker.think = CheckDistance;
dist_checker.nextthink = time + 0.3;
};
//=========================================================================
// Think function for the timer which checks the distance between the
// Engineer and the building he's using
void() CheckDistance =
{
local vector dist;
// Check to see if the Engineer's spanner'ed a different building
// without leaving the area of this one.
if (self.owner.building != self.enemy)
{
dremove(self);
return;
}
dist = self.enemy.origin - self.owner.origin;
//WK if (vlen(dist) > 64)
if (vlen(dist) > 98)
{
CenterPrint(self.owner, "\n");
self.owner.menu_count = MENU_REFRESH_RATE;
self.owner.current_menu = MENU_DEFAULT;
2001-07-17 05:58:10 +00:00
self.owner.building = world;
dremove(self);
return;
}
self.nextthink = time + 0.3;
};