prozac-qfcc/field.qc

1168 lines
32 KiB
C++
Raw Normal View History

#include "defs.qh"
#include "menu.qh"
2001-07-17 05:58:10 +00:00
/*=======================================================//
// field.QC - CustomTF 3.2.OfN - 30/1/2001 - //
2001-07-17 05:58:10 +00:00
// by Sergio Fuma<6D>a Grunwaldt - OfteN aka superCOCK2000 //
=========================================================//
Field generator stuff - Written all by myself! :)
I took the model and some sounds from deadlode mod
One sound is from megaTF
=========================================================*/
// field generator flags, DO NOT MODIFY
#define FIELDGEN_ISOFF 0 // no field, not linked, and its not trying to link (several possible reasons)
#define FIELDGEN_ISIDLE 1 // no field, not linked, trying to link with other generator
2001-07-17 05:58:10 +00:00
#define FIELDGEN_ISDISABLED 2 // no field, linked, its disabled temporary (teammate passing thru field)
#define FIELDGEN_ISENABLED 3 // field, linked, and cells enough, waiting for shock, only hum sound
#define FIELDGEN_ISWORKING 4 // field, linked, glowing and all the field visual/sound effects are on
2001-07-17 05:58:10 +00:00
// field generator settings
#define FIELDGEN_SHOCKTIME 3 // seconds the generators remains glowing and doing lightning after a shock
#define FIELDGEN_LINKTIME 3.5 // seconds between tries to link with other generator
#define FIELDGEN_TIMEDISABLED 1.5 // was 3 // then 2
#define FIELDGEN_CELLSCOST 2 // cells cost for each "FIELDGEN_ISWORKING" pass
#define FIELDGEN_DMG 80 // normal damag when touching
#define FIELDGEN_DMGINSIDE 120 // damage when trapped inside field
#define FIELDGEN_MAXZ 10
2001-07-17 05:58:10 +00:00
/*===============================================================================================
EXPLANATION OF HOW THE ENTITY FIELDS ARE USED ( thnx? np.. =) )
---------------------------------------------
For field generator entity:
---------------------------
.fieldgen_status - Holds current status of every field generator, FIELDGEN_XXXX determines
.fieldgen_hasfield - Boolean value, determines if field generator is currently supporting a force field
2012-07-06 02:29:18 +00:00
.fieldgen_field - This points to the force field, if none its always 'nil'
.no_grenades_1 - Controls delay between tries to link (only affects sound currently, it tries to link every frame)
.no_grenades_1 - Controls delay for field to go up again after beeing disabled
.tp_grenades_1 - Controls delay of the WORKING status
2001-07-17 05:58:10 +00:00
.has_teleporter - Used to flash generators when field is activated
.has_camera - Controls delay between cells take
.has_tesla - Boolean, forced status.
2001-07-17 05:58:10 +00:00
For force field entity:
-----------------------
.demon_one - Points to the first field generator
.demon_two - Points to the 2nd generator
.fieldgen_status - Hum sound running, boolean
.fieldgen_hasfield - Shield sound running, boolean
.has_tesla - Controls delay between hums
.has_sentry - Controls delay between shield sounds
.dmg - Next damage the field will do
.has_camera - Used to control the rate at which the field touch sound/visual effects are done (4hz)
.forcefield_offset - Offset to one of the gens from origin, used for lightning effects
2001-07-17 05:58:10 +00:00
================================================================================================*/
void() CheckDistance;
entity(entity fieldgen) Find_OtherGen;
float(entity fieldgen1, entity fieldgen2) FieldGens_CanLink;
float(entity fieldgen) FieldGen_CanIdle;
float(entity field) IsValidFieldGen;
float (vector targ, vector check) vis2orig;
float(entity field) IsValidField;
void(entity tfield, entity gen1) Field_UpdateSounds;
void(entity tfield) Field_MakeVisual;
float(entity tfield) FieldIsImproved;
float(entity tfield) FieldIsMalfunctioning;
void() Field_touch;
void() Field_touch_SUB;
float(entity e1, entity e2) EntsTouching2;
void(entity tfield, vector where, entity thing) FieldExplosion;
float(entity tfield, entity who) Field_ItCanPass;
float(entity tfield, entity who) Field_ShouldDamage;
#ifdef FIELD_FORCEMODE
entity(entity myself) GetMyFieldGen;
float(entity tfield) Field_GetForcedStatus;
void(float value) SetFieldForcedStatus; // player function (self = player) cuts disabled time also
float() GetFieldForcedStatus; // player
#endif
//=========================================================================================
// field generator model and sounds
void() Field_Precache =
{
precache_sound ("misc/null.wav");
precache_sound2("misc/ffhum.wav");
precache_sound2("misc/ffbeep.wav");
precache_sound2("misc/ffield.wav");
precache_sound2("misc/ffact.wav");
precache_sound2("misc/fffail.wav");
precache_model2("progs/ffgen2.mdl");
2001-07-17 05:58:10 +00:00
};
//================================================================================================
// checks for field generators and removes itself if needed, checks for stuck entities on field
void() Field_think =
{
if (self.classname != "force_field")
{
RPrint("BUG: Not a force field entity was in 'FieldThink()'!\n");
return;
}
self.has_camera = FALSE;
// checks for removal...
if (!IsValidFieldGen(self.demon_one) || !IsValidFieldGen(self.demon_two))
{
if (IsValidFieldGen(self.demon_one))
{
self.demon_one.fieldgen_hasfield = FALSE;
2012-07-06 02:29:18 +00:00
self.demon_one.fieldgen_field = nil;
}
if (IsValidFieldGen(self.demon_two))
{
self.demon_two.fieldgen_hasfield = FALSE;
2012-07-06 02:29:18 +00:00
self.demon_two.fieldgen_field = nil;
}
2012-07-06 02:29:18 +00:00
self.demon_one = nil;
self.demon_two = nil;
dremove(self);
RPrint("Debug: Field entity removed in Field_think()\n"); //shouldnt happen
}
else
self.nextthink = time + 0.25; // 4hz check
if (IsValidFieldGen(self.demon_one))
if (self.demon_one.fieldgen_status == FIELDGEN_ISWORKING)
Field_MakeVisual(self);
// checks for anything stuck in field :)
local entity te;
local float frange;
2001-07-17 05:58:10 +00:00
frange = FIELDGEN_RANGE;
2001-07-17 05:58:10 +00:00
if (FieldIsImproved(self) & IMPROVED_FOUR)
frange = FIELDGEN_HACKEDRANGE;
2001-07-17 05:58:10 +00:00
te = findradius(self.origin,frange);
while (te)
2001-07-17 05:58:10 +00:00
{
if (te != self)
if (te != self.demon_one)
if (te != self.demon_two)
if (te.velocity == '0 0 0')
// if (!IsBuilding(te)) // no screwing with the buildings :)
if (te.classname != "force_field")
if (EntsTouching2(te,self))
{
other = te;
deathmsg = DMSG_STUCK_FORCEFIELD;
self.dmg = FIELDGEN_DMGINSIDE; // this gonna hurt
Field_touch_SUB();
2001-07-17 05:58:10 +00:00
}
te = te.chain;
}
};
//=============================================================================================
// is one entity actually inside the other one? (this avoids using a stupid trigger)
float(entity e1, entity e2) EntsTouching2 =
{
if (hullpointcontents (e2, e1.mins, e1.maxs, e1.origin) != CONTENTS_SOLID)
return FALSE;
return TRUE;
2001-07-17 05:58:10 +00:00
};
//=================================================================================
// these 2 functions return the current hacks that should apply to the field
float(entity tfield) FieldIsImproved =
{
if (IsValidFieldGen(tfield.demon_one) && IsValidFieldGen(tfield.demon_two))
return tfield.demon_one.num_mines | tfield.demon_two.num_mines;
2001-07-17 05:58:10 +00:00
if (IsValidFieldGen(tfield.demon_one))
return tfield.demon_one.num_mines;
2001-07-17 05:58:10 +00:00
if (IsValidFieldGen(tfield.demon_two))
return tfield.demon_two.num_mines;
2001-07-17 05:58:10 +00:00
return 0;
2001-07-17 05:58:10 +00:00
};
float(entity tfield) FieldIsMalfunctioning =
{
if (IsValidFieldGen(tfield.demon_one) && IsValidFieldGen(tfield.demon_two))
return tfield.demon_one.is_malfunctioning | tfield.demon_two.is_malfunctioning;
2001-07-17 05:58:10 +00:00
if (IsValidFieldGen(tfield.demon_one))
return tfield.demon_one.is_malfunctioning;
2001-07-17 05:58:10 +00:00
if (IsValidFieldGen(tfield.demon_two))
return tfield.demon_two.is_malfunctioning;
2001-07-17 05:58:10 +00:00
return 0;
2001-07-17 05:58:10 +00:00
};
//=================================================================
// self is the field, disables it
void() DisableField =
{
if (IsValidFieldGen(self.demon_one))
{
self.demon_one.fieldgen_status = FIELDGEN_ISDISABLED;
self.demon_one.no_grenades_2 = time + FIELDGEN_TIMEDISABLED;
}
if (IsValidFieldGen(self.demon_two))
{
self.demon_two.fieldgen_status = FIELDGEN_ISDISABLED;
self.demon_two.no_grenades_2 = time + FIELDGEN_TIMEDISABLED;
}
sound (self, CHAN_VOICE, "misc/ffbeep.wav", 0.4, ATTN_IDLE);
2001-07-17 05:58:10 +00:00
};
//=========================================================================================
// applies damage and makes the sound and visual effect for the forcefield shock
void() Field_touch_SUB =
{
local float doFX;
local float shoulddamage;
doFX = TRUE;
if (FieldIsMalfunctioning(self) & SCREWUP_THREE) // reduce output
self.dmg = 1;
if (other.classname == "player") // PLAYERS
{
2001-07-28 17:48:57 +00:00
//dprint (vtos (other.origin) + "\n");
if (other.playerclass == PC_UNDEFINED) // Observers
return;
if (Field_ItCanPass(self, other))
{
DisableField();
return;
}
else
{
self.velocity = self.velocity - (self.velocity*4) + '0 0 1';
shoulddamage = Field_ShouldDamage(self,other);
if (shoulddamage == 1)
TF_T_Damage (other, self, self.real_owner, self.dmg, TF_TD_NOTTEAM, TF_TD_ELECTRICITY);
else if (shoulddamage == 2) // hacked to hurt teammates
{
if (deathmsg == DMSG_FORCEFIELD)
deathmsg = DMSG_FF_HACKED;
else /* if (deathmsg == DMSG_FORCEFIELD_STUCK) */
deathmsg = DMSG_FF_STUCK_HACKED;
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
TF_T_Damage (other, self, self.martyr_enemy, self.dmg, TF_TD_NOTTEAM, TF_TD_ELECTRICITY);
}
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
if (shoulddamage)
self.demon_one.has_camera = self.demon_two.has_camera = 0;
}
}
else if (other.classname != "force_field") // non player entities
{
if (IsMonster(other))
{
if (Field_ItCanPass(self, other))
{
DisableField();
return;
}
else
{
shoulddamage = Field_ShouldDamage(self,other);
if (shoulddamage == 1)
TF_T_Damage (other, self, self.real_owner, self.dmg, TF_TD_NOTTEAM, TF_TD_ELECTRICITY);
else if (shoulddamage == 2) // hacked to hurt teammates
{
if (deathmsg == DMSG_FORCEFIELD)
deathmsg = DMSG_FF_HACKED;
else /* if (deathmsg == DMSG_FORCEFIELD_STUCK) */
deathmsg = DMSG_FF_STUCK_HACKED;
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
TF_T_Damage (other, self, self.martyr_enemy, self.dmg, TF_TD_NOTTEAM, TF_TD_ELECTRICITY);
}
}
}
2001-07-17 05:58:10 +00:00
}
2001-07-17 05:58:10 +00:00
if(other.movetype != MOVETYPE_NONE && other.movetype != MOVETYPE_PUSH && other.movetype != MOVETYPE_BOUNCE && other.movetype != MOVETYPE_BOUNCEMISSILE)
{
checkmove(other.origin, other.mins, other.maxs, other.origin + '0 0 1', MOVE_NORMAL, other);
if (trace_fraction == 1)
{
local vector forward = crossproduct(normalize(self.demon_one.origin - self.demon_two.origin), '0 0 1');
if (crossproduct (normalize(self.origin - other.origin), normalize(self.demon_one.origin -self.demon_two.origin))
* '0 0 1' > 0)
other.velocity = -300 * forward;
else
other.velocity = 300 * forward;
2012-07-06 02:29:18 +00:00
other.velocity.z += 50;
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
setorigin(other, other.origin + '0 0 1');
}
else if (IsBuilding(other))
{
sprint(other.real_owner, PRINT_HIGH, "The forcefield short-circuits your structure\n");
2012-07-06 02:29:18 +00:00
TF_T_Damage(other, nil, nil, 9999, TF_TD_IGNOREARMOUR, 0);
}
}
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
FieldExplosion(self,other.origin,other);
PutFieldWork(self);
2001-07-17 05:58:10 +00:00
};
#ifdef FIELD_FORCEMODE
//==========================================================================
// gets one of our field generators
entity(entity myself) GetMyFieldGen =
{
local entity te;
local float foundit;
2012-07-06 02:29:18 +00:00
te = nil;
foundit = FALSE;
2012-07-06 02:29:18 +00:00
te = find(nil, classname, "building_fieldgen");
while (te && foundit == FALSE)
{
if (te.real_owner == myself) // is it ours?
foundit = TRUE; // yeah, found it
if (foundit == FALSE) // our search must continue...
te = find(te, classname, "building_fieldgen");
}
return te;
2001-07-17 05:58:10 +00:00
};
//=========================================================================
// these functions retrieve and set the current 'forced status' on a field
float(entity tfield) Field_GetForcedStatus =
{
if (IsValidFieldGen(tfield.demon_one) && IsValidFieldGen(tfield.demon_two))
{
if (tfield.demon_two.has_tesla || tfield.demon_one.has_tesla)
return TRUE;
}
else if (IsValidFieldGen(tfield.demon_one))
{
if (tfield.demon_one.has_tesla)
return TRUE;
}
else if (IsValidFieldGen(tfield.demon_two))
{
if (tfield.demon_two.has_tesla)
return TRUE;
}
return FALSE;
2001-07-17 05:58:10 +00:00
};
//==============================================================================
// player functions called on menu.qc to disable/enable forced status on field
void(float value) SetFieldForcedStatus =
{
local entity gen1, gen2;
gen1 = GetMyFieldGen(self);
gen2 = Find_OtherGen(gen1);
if (IsValidFieldGen(gen1))
{
gen1.has_tesla = value;
if (value)
gen1.no_grenades_2 = time;
}
if (IsValidFieldGen(gen2))
{
gen2.has_tesla = value;
if (value)
gen2.no_grenades_2 = time;
}
2001-07-17 05:58:10 +00:00
};
float() GetFieldForcedStatus =
{
local entity gen1, gen2;
gen1 = GetMyFieldGen(self);
gen2 = Find_OtherGen(gen1);
if (IsValidFieldGen(gen1) && IsValidFieldGen(gen2))
{
if (gen1.has_tesla || gen2.has_tesla)
return TRUE;
}
else if (IsValidFieldGen(gen1))
return gen1.has_tesla;
else if (IsValidFieldGen(gen2))
return gen2.has_tesla;
return FALSE;
2001-07-17 05:58:10 +00:00
};
#endif
//=========================================================================
// returns TRUE if 'who' entity should be able to pass thru the field
float(entity tfield, entity who) Field_ItCanPass =
{
if (FieldIsMalfunctioning(tfield) & SCREWUP_ONE)
return FALSE;
2001-07-17 05:58:10 +00:00
/*
if (who == tfield.real_owner) // field owner - always pass
return TRUE;
*/
if (Field_GetForcedStatus(tfield))
return FALSE;
if (who.classname == "player") // PLAYERS
{
if (Teammate(who.team_no, tfield.real_owner.team_no)) // teammate
return TRUE;
if (Teammate(who.undercover_team, tfield.real_owner.team_no)) // spies disguised as our team
return TRUE;
}
else if (IsMonster(who)) // MONSTERS/ARMY
{
if (Teammate(who.real_owner.team_no, tfield.real_owner.team_no)) // team monster
return TRUE;
}
return FALSE;
2001-07-17 05:58:10 +00:00
};
//=========================================================================
// returns 1 or 2 if 'who' entity should be damaged by the field
// 1 if it's an enemy, 2 if a friendly and has been hacked
2001-07-17 05:58:10 +00:00
float(entity tfield, entity who) Field_ShouldDamage =
{
local float fr;
if (FieldIsMalfunctioning(tfield) & SCREWUP_ONE)
fr = 2;
else
fr = 0;
2001-07-17 05:58:10 +00:00
if (who.classname == "player") // PLAYERS
{
if (who == tfield.real_owner) // field owner
return fr;
2001-07-17 05:58:10 +00:00
if (Teammate(who.team_no, tfield.real_owner.team_no)) // teammate
return fr;
2001-07-17 05:58:10 +00:00
if (Teammate(who.undercover_team, tfield.real_owner.team_no)) // spies disguised as our team
return fr;
}
else if (IsMonster(who)) // MONSTERS/ARMY
{
if (Teammate(who.real_owner.team_no, tfield.real_owner.team_no)) // team monster
return fr;
}
2001-07-17 05:58:10 +00:00
return 1;
2001-07-17 05:58:10 +00:00
};
//=============================================================================
// applies the particle effect and electric sound (at max 4hz rate)
void(entity tfield, vector where, entity thing) FieldExplosion =
{
if (!tfield.has_camera)
{
if (!thing || thing.is_removed) return;
2001-07-17 05:58:10 +00:00
local vector whereFX;
whereFX = where;
2012-07-06 02:29:18 +00:00
whereFX.z = tfield.origin.z;
2001-07-17 05:58:10 +00:00
spawnFOG(whereFX);
sound(tfield,CHAN_BODY,"effects/crunch.wav",0.5,ATTN_NORM);
2001-07-17 05:58:10 +00:00
tfield.has_camera = TRUE; // cya soon
}
2001-07-17 05:58:10 +00:00
};
void(entity field) PutFieldWork =
{
if (IsValidFieldGen(field.demon_one))
field.demon_one.tp_grenades_1 = time + FIELDGEN_SHOCKTIME;
if (IsValidFieldGen(field.demon_two))
field.demon_two.tp_grenades_1 = time + FIELDGEN_SHOCKTIME;
2001-07-17 05:58:10 +00:00
};
void() Field_touch =
{
if (other.classname == "force_field") return; //avoid weird loops with other fields
2001-07-17 05:58:10 +00:00
deathmsg = DMSG_FORCEFIELD;
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
if (self.dmg == FIELDGEN_DMGINSIDE)
deathmsg = DMSG_STUCK_FORCEFIELD;
else
self.dmg = FIELDGEN_DMG;
Field_touch_SUB();
2001-07-17 05:58:10 +00:00
};
//===================================================================================
// creates the force field between the 2 generators (only if none currently on)
void(entity gen1, entity gen2) Create_Field =
{
2001-07-28 17:48:57 +00:00
//local string foo;
if (gen1.fieldgen_hasfield || gen2.fieldgen_hasfield)
return;
2001-07-17 05:58:10 +00:00
2001-07-28 17:48:57 +00:00
//foo = "gen1: " + vtos (gen1.origin) + " " + vtos (gen1.absmin) + " " + vtos (gen1.absmax);
//dprint(foo + "\n");
//foo = "gen2: " + vtos (gen2.origin) + " " + vtos (gen2.absmin) + " " + vtos (gen2.absmax);
//dprint(foo + "\n");
/* dprint("gen1:\n");
eprint(gen1.fieldgen_field);
dprint("gen2:\n");
eprint(gen2.fieldgen_field);
dprint("done\n"); */
if (gen1.fieldgen_field || gen2.fieldgen_field) // CHECK
return;
2001-07-17 05:58:10 +00:00
// already checked b4 on CanLink -> CanIdle
/*if (!IsValidFieldGen(gen1) || !IsValidFieldGen(gen2))
return;*/
gen1.fieldgen_status = FIELDGEN_ISENABLED;
gen2.fieldgen_status = FIELDGEN_ISENABLED;
2001-07-17 05:58:10 +00:00
gen1.fieldgen_hasfield = TRUE;
gen2.fieldgen_hasfield = TRUE;
2001-07-17 05:58:10 +00:00
local entity tfield;
2001-07-17 05:58:10 +00:00
// generate field
tfield = spawn();
tfield.classname = "force_field";
2012-07-06 02:29:18 +00:00
tfield.owner = nil;
tfield.real_owner = gen1.real_owner; // --> player
2001-07-17 05:58:10 +00:00
tfield.think = Field_think;
tfield.touch = Field_touch;
tfield.nextthink = time + 0.25;
2001-07-17 05:58:10 +00:00
// set pos and size
2012-07-06 02:29:18 +00:00
tfield.size.x = vlen (gen1.origin - gen2.origin) - 10;
tfield.size.y = 4;
tfield.size.z = 48; // was 64, but 48 is more realistic
tfield.maxs = tfield.size * 0.5; // FIXME: / 2 is broken
tfield.mins = -tfield.maxs;
2001-07-28 17:48:57 +00:00
tfield.origin = AVG (gen1.origin, gen2.origin);
2012-07-06 02:29:18 +00:00
tfield.origin.z = AVG (gen1.absmax.z, gen2.absmax.z) - tfield.maxs.z - 1;
tfield.forcefield_offset = (gen2.origin - gen1.origin);
local vector right, forward, up;
up = '0 0 1';
right = normalize (gen2.origin - gen1.origin);
forward = crossproduct (up, right);
// local string foo;
2001-07-28 17:48:57 +00:00
// foo = "right: " + vtos (right) + "\nforward: " + vtos (forward)
// + "\nup: " + vtos (up) + "\nmins: " + vtos (tfield.mins)
// + " maxs: " + vtos (tfield.maxs) + "\norigin: " + vtos (tfield.origin) + "\n";
// dprint (foo);
tfield.rotated_bbox = getboxhull();
rotate_bbox (tfield.rotated_bbox, right, forward, up, tfield.mins,
tfield.maxs);
local vector mins, maxs;
mins = getboxbounds (tfield.rotated_bbox, 0);
maxs = getboxbounds (tfield.rotated_bbox, 1);
// apply stuff
tfield.movetype = MOVETYPE_NONE;
tfield.solid = SOLID_BBOX;
setsize(tfield, mins, maxs);
setorigin(tfield, tfield.origin);
// foo = "min: " + vtos (mins) + "\n" +
// "max: " + vtos (maxs) + "\n" +
// "absmin: " + vtos (tfield.absmin) + "\n" +
// "absmax: " + vtos (tfield.absmax) + "\n";
// dprint (foo + "\n");
// assign the pointers on the field generators
gen1.fieldgen_field = tfield;
gen2.fieldgen_field = tfield;
// assign the pointers to generators on ourselves
tfield.demon_one = gen1;
tfield.demon_two = gen2;
//make activating sound
sound (tfield, CHAN_VOICE, "misc/ffact.wav", 0.2, ATTN_NORM);
// flash generators
gen1.effects = EF_DIMLIGHT;
gen1.has_teleporter = TRUE;
gen1.skin = 2;
gen2.effects = EF_DIMLIGHT;
gen2.has_teleporter = TRUE;
gen2.skin = 2;
if (gen1.martyr_enemy)
tfield.martyr_enemy = gen1.martyr_enemy;
else if (gen1.martyr_enemy)
tfield.martyr_enemy = gen2.martyr_enemy;
else
2012-07-06 02:29:18 +00:00
tfield.martyr_enemy = nil;
/* // make sure the field goes off instantly if there's somebody in it
local entity oldself;
oldself = self;
self = tfield;
self.think ();
self = oldself; */
2001-07-17 05:58:10 +00:00
};
//=================================================================0
// removes the force field (if any)
void(entity gen1, entity gen2) Remove_Field =
{
if (IsValidFieldGen(gen1))
{
if (IsValidField(gen1.fieldgen_field))
{
freeboxhull (gen1.fieldgen_field.rotated_bbox);
dremove(gen1.fieldgen_field);
}
gen1.fieldgen_hasfield = FALSE;
2012-07-06 02:29:18 +00:00
gen1.fieldgen_field = nil;
if (IsValidFieldGen(gen2))
{
gen2.fieldgen_hasfield = FALSE;
2012-07-06 02:29:18 +00:00
gen2.fieldgen_field = nil;
}
}
else if (IsValidFieldGen(gen2))
{
if (IsValidField(gen2.fieldgen_field))
{
freeboxhull (gen2.fieldgen_field.rotated_bbox);
dremove(gen2.fieldgen_field);
}
gen2.fieldgen_hasfield = FALSE;
2012-07-06 02:29:18 +00:00
gen2.fieldgen_field = nil;
}
2001-07-17 05:58:10 +00:00
};
float(entity field) IsValidField =
{
if (!field)
return FALSE;
if (field.classname != "force_field")
return FALSE;
2001-07-17 05:58:10 +00:00
return TRUE;
2001-07-17 05:58:10 +00:00
};
float(entity field) IsValidFieldGen =
{
if (!field)
return FALSE;
if (field.classname != "building_fieldgen")
return FALSE;
2001-07-17 05:58:10 +00:00
return TRUE;
2001-07-17 05:58:10 +00:00
};
//========================================================
// starts or removes sounds on the field
void(entity tfield, entity gen1) Field_UpdateSounds =
{
//fieldgen_status : hum
//fieldgen_hasfield : shield
if (IsValidField(tfield)) // only if there is a field currently
{
local float playhum, playshield;
playhum = FALSE; playshield = FALSE;
/*if (gen1.fieldgen_status == FIELDGEN_ISOFF) // for some reason we r not working
{
playhum = FALSE;
playshield = FALSE;
}
else if (gen1.fieldgen_status == FIELDGEN_ISIDLE) // awaiting for link
{
playhum = FALSE;
playshield = FALSE;
}
else if (gen1.fieldgen_status == FIELDGEN_ISDISABLED) // teammate passing thru the field?
{
playhum = FALSE;
playshield = FALSE;
}
else*/
if (gen1.fieldgen_status == FIELDGEN_ISENABLED)
{
playhum = TRUE;
playshield = FALSE;
}
else if (gen1.fieldgen_status == FIELDGEN_ISWORKING)
{
playhum = TRUE;
playshield = TRUE;
}
// MAKE THE SHIT SOUND !
if (!playhum)
{
if (tfield.fieldgen_status)
{
sound(tfield,CHAN_MISC,"misc/null.wav",0.5,ATTN_NORM);
tfield.fieldgen_status = FALSE;
}
}
else
{
if (!tfield.fieldgen_status || tfield.has_tesla < time)
{
sound(tfield,CHAN_MISC,"misc/ffhum.wav",0.3,ATTN_NORM);
tfield.has_tesla = time + 1;
tfield.fieldgen_status = TRUE;
}
}
if(!playshield)
{
if (tfield.fieldgen_hasfield)
{
sound(tfield,CHAN_ITEM,"misc/null.wav",0.2,ATTN_NORM);
tfield.fieldgen_hasfield = FALSE;
}
}
else
{
if (!tfield.fieldgen_hasfield || tfield.has_sentry < time)
{
//TODO?: lower volume as (FIELDGEN_SHOCKTIME - time) decreases
sound(tfield,CHAN_ITEM,"misc/ffield.wav",0.4,ATTN_NORM);
tfield.has_sentry = time + 1;
tfield.fieldgen_hasfield = TRUE;
}
}
}
2001-07-17 05:58:10 +00:00
};
//====================================================================
// do the lightning stuff while field is FIELDGEN_ISWORKING
void(entity tfield) Field_MakeVisual =
{
if (IsValidField(tfield))
{
local vector f;
f = tfield.origin + (tfield.forcefield_offset * 0.5 * (random() * 2 - 1));
2001-07-17 05:58:10 +00:00
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
if (random() > 0.5)
WriteByte (MSG_MULTICAST, TE_LIGHTNING2);
else
WriteByte (MSG_MULTICAST, TE_LIGHTNING1);
WriteEntity (MSG_MULTICAST, tfield);
2012-07-06 02:29:18 +00:00
WriteCoord (MSG_MULTICAST, f.x);
WriteCoord (MSG_MULTICAST, f.y);
WriteCoord (MSG_MULTICAST, tfield.origin.z + tfield.mins.z);
WriteCoord (MSG_MULTICAST, f.x);
WriteCoord (MSG_MULTICAST, f.y);
WriteCoord (MSG_MULTICAST, tfield.origin.z + tfield.maxs.z);
}
2001-07-17 05:58:10 +00:00
};
//==================================================
// called every frame by the field generators
void() FieldGen_think =
{
local entity othergen;
othergen = Find_OtherGen(self); // get our brother
if (FieldGens_CanLink(self,othergen))
Create_Field(self,othergen); // checks redundancy itself
else
Remove_Field(self,othergen); // checks redundancy itself
// field main loop (ai? heh.. my cat is smarter than these force fields)
if (self.fieldgen_status == FIELDGEN_ISOFF) // for some reason we r not working
{
self.effects = 0;
self.skin = 0;
if (FieldGen_CanIdle(self)) // can we go idle?
self.fieldgen_status = FIELDGEN_ISIDLE;
}
else if (self.fieldgen_status == FIELDGEN_ISIDLE) // awaiting for link
{
self.effects = 0;
self.skin = 0;
if (self.no_grenades_1 < time) // trying to link sound/flash time
{
sound (self, CHAN_WEAPON, "misc/fffail.wav", 0.5, ATTN_IDLE);
self.skin = 1;
self.effects = EF_DIMLIGHT;
self.no_grenades_1 = time + FIELDGEN_LINKTIME;
}
}
else if (self.fieldgen_status == FIELDGEN_ISDISABLED) // teammate passing thru the field?
{
self.effects = 0;
self.skin = 0;
// time check
if (self.no_grenades_2 < time) // can we go idle?
{
self.fieldgen_status = FIELDGEN_ISIDLE;
self.tp_grenades_1 = 0;
}
}
else if (self.fieldgen_status == FIELDGEN_ISENABLED)
{
if (!self.has_teleporter)
{
self.effects = 0;
self.skin = 1;
}
if (self.fieldgen_hasfield == FALSE)
self.fieldgen_status = FIELDGEN_ISIDLE;
if (self.tp_grenades_1 >= time)
self.fieldgen_status = FIELDGEN_ISWORKING;
}
else if (self.fieldgen_status == FIELDGEN_ISWORKING)
{
self.effects = EF_DIMLIGHT;
self.skin = 2;
if (self.has_camera <= time)
{
self.ammo_cells = self.ammo_cells - FIELDGEN_CELLSCOST;
self.has_camera = time + 1;
}
if (self.fieldgen_hasfield == FALSE)
self.fieldgen_status = FIELDGEN_ISIDLE;
else if (self.tp_grenades_1 <= time)
self.fieldgen_status = FIELDGEN_ISENABLED;
}
Field_UpdateSounds(self.fieldgen_field, self); // update force field sounds
if (!FieldGen_CanIdle(self)) // turn us off if needed
self.fieldgen_status = FIELDGEN_ISOFF;
2001-07-17 05:58:10 +00:00
self.has_teleporter = FALSE; // resets 'flash' status bypass
self.nextthink = time + 0.1;
2001-07-17 05:58:10 +00:00
};
//=======================================================================
// returns TRUE if the generator could currently go to idle status
float(entity fieldgen) FieldGen_CanIdle =
{
if (!(IsValidFieldGen(fieldgen)))
return FALSE;
2001-07-17 05:58:10 +00:00
if (fieldgen.ammo_cells >= FIELDGEN_CELLSCOST &&
!(fieldgen.is_malfunctioning & SCREWUP_FOUR)
&& fieldgen.health > 0)
return TRUE;
2001-07-17 05:58:10 +00:00
return FALSE;
2001-07-17 05:58:10 +00:00
};
//=======================================================================
// returns TRUE if both generators could currently generate the field
float(entity fieldgen1, entity fieldgen2) FieldGens_CanLink =
{
if (!(IsValidFieldGen(fieldgen1)) || !(IsValidFieldGen(fieldgen2)))
return FALSE;
2001-07-17 05:58:10 +00:00
if (!visible2(fieldgen1,fieldgen2))
return FALSE;
local float r;
r = vlen(fieldgen1.origin - fieldgen2.origin); // get distance between generators
2001-07-17 05:58:10 +00:00
// if ((fieldgen1.num_mines & IMPROVED_FOUR && fieldgen2.num_mines & IMPROVED_FOUR) && r > FIELDGEN_HACKEDRANGE2)
// return FALSE;
2001-07-17 05:58:10 +00:00
/*if (fieldgen1.num_mines & IMPROVED_FOUR || fieldgen2.num_mines & IMPROVED_FOUR)
{
if ((fieldgen1.num_mines & IMPROVED_FOUR && fieldgen2.num_mines & IMPROVED_FOUR) && r > FIELDGEN_HACKEDRANGE2)
return FALSE;
else
if ((fieldgen1.num_mines & IMPROVED_FOUR || fieldgen2.num_mines & IMPROVED_FOUR) && r > FIELDGEN_HACKEDRANGE)
return FALSE;
}*/
if ((fieldgen1.num_mines & IMPROVED_FOUR || fieldgen2.num_mines & IMPROVED_FOUR) && r > FIELDGEN_HACKEDRANGE)
return FALSE;
if (r > FIELDGEN_RANGE && !(fieldgen1.num_mines & IMPROVED_FOUR || fieldgen2.num_mines & IMPROVED_FOUR))
return FALSE;
2012-07-06 02:29:18 +00:00
if (fabs(fieldgen1.origin.z - fieldgen2.origin.z) > FIELDGEN_MAXZ)
return FALSE;
if (fieldgen1.fieldgen_status == FIELDGEN_ISDISABLED || fieldgen2.fieldgen_status == FIELDGEN_ISDISABLED)
return FALSE;
if (fieldgen1.fieldgen_status == FIELDGEN_ISOFF || fieldgen2.fieldgen_status == FIELDGEN_ISOFF)
return FALSE;
if (FieldGen_CanIdle(fieldgen1) && FieldGen_CanIdle(fieldgen2))
return TRUE;
return FALSE;
2001-07-17 05:58:10 +00:00
};
//=============================================================================================
// initialize field generator stuff just after beeing built, called on engineer.qc
void(entity field) Field_Built =
{
2012-07-06 02:29:18 +00:00
field.touch = nil;
field.think = FieldGen_think;
field.nextthink = time + 0.1;
field.fieldgen_status = FIELDGEN_ISIDLE; // we start on IDLE status (searching for other gen to link)
field.fieldgen_hasfield = FALSE;
field.no_grenades_1 = time + 3;
2012-07-06 02:29:18 +00:00
field.fieldgen_field = nil;
field.martyr_enemy = nil;
2001-07-17 05:58:10 +00:00
};
//==============================================================
// returns our other generator (if any)
entity(entity fieldgen) Find_OtherGen =
{
local entity te;
local float foundit;
2012-07-06 02:29:18 +00:00
te = nil;
foundit = FALSE;
2012-07-06 02:29:18 +00:00
te = find(nil, classname, "building_fieldgen");
while (te && foundit == FALSE)
{
if (te.real_owner == fieldgen.real_owner) // is it ours?
if (te != fieldgen) // and not the same generator..
foundit = TRUE; // yeah, found it
if (foundit == FALSE) // our search must continue...
te = find(te, classname, "building_fieldgen");
}
return te;
2001-07-17 05:58:10 +00:00
};
//=========================================================================================
// returns the place where field gen could be built related to player current pos and yaw
// called on engineer.qc, place is the origin passed where other kind of buildings are built
// FIXME: changed to allow placing anywhere. comments need updating
2001-07-17 05:58:10 +00:00
void (vector place) WhereGen =
2001-07-17 05:58:10 +00:00
{
// if we have no field generator currently, it can be placed anywhere
if (self.has_fieldgen == 0)
return;
local float r, foundit;
2012-07-06 02:29:18 +00:00
local entity te = nil;
foundit = FALSE;
// find the other generator
do {
te = find (te, classname, "building_fieldgen");
if (te.real_owner == self)
foundit = TRUE;
} while (te && foundit == FALSE);
/*
2012-07-06 02:29:18 +00:00
te = find (nil, classname, "building_fieldgen");
while (te && foundit == FALSE)
{
if (te.real_owner == self) // is it ours?
foundit = TRUE; // yeah, found it
if (foundit == FALSE) // our search must continue...
te = find (te, classname, "building_fieldgen");
}*/
// check for error getting the other gen
if (!te || te.classname != "building_fieldgen" || foundit == FALSE)
{
RPrint("BUG: Error on field generator placement routine. 'WhereGen()'\n");
return;
}
// print message if they wont link
if (!vis2orig (te.origin,place))
sprint (self, PRINT_HIGH,
"Your field generators won't link, there are obstacles between them!\n");
r = vlen(te.origin - place); // get distance between generators
if (r > FIELDGEN_HACKEDRANGE && te.num_mines & IMPROVED_FOUR)
sprint (self, PRINT_HIGH,
"Your field generators are too far away to link, even hacked\n");
if (r > FIELDGEN_RANGE && !(te.num_mines & IMPROVED_FOUR))
sprint (self, PRINT_HIGH,
"Your field generators are too far away to link\n");
2012-07-06 02:29:18 +00:00
if (fabs (place.z - te.origin.z) > FIELDGEN_MAXZ)
sprint (self, PRINT_HIGH,
"Your field generators are at different heights, they won't link\n");
// return the final building place
return;
2001-07-17 05:58:10 +00:00
};
//======================================================================
// damn! our field generator was destroyed. Force field must go down..
void() FieldGen_Die =
{
self.real_owner.has_fieldgen = self.real_owner.has_fieldgen - 1;
if (self.real_owner.has_fieldgen < 0) self.real_owner.has_fieldgen = 0;
2001-07-17 05:58:10 +00:00
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_EXPLOSION);
2012-07-06 02:29:18 +00:00
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
// check if field should be removed..
local entity othergen;
othergen = Find_OtherGen(self);
if (IsValidFieldGen(othergen))
{
Remove_Field(self, othergen);
}
else
{
2012-07-06 02:29:18 +00:00
Remove_Field(self, nil); // extra removal, not needed i think...
}
2001-07-17 05:58:10 +00:00
sprint(self.real_owner, PRINT_HIGH, "Your field generator was destroyed.\n");
2001-07-17 05:58:10 +00:00
//TODO: gibs, one of the tesla, one custom
2001-07-17 05:58:10 +00:00
dremove(self);
2001-07-17 05:58:10 +00:00
};
//=========================================================================
// Engineer has used a Spanner on the field generator
void(entity field) Engineer_UseFieldGen =
{
self.building = field;
if (Teammate(self.building.real_owner.team_no,self.team_no) && self.building.is_malfunctioning & SCREWUP_THREE)
{
//if (self.building.is_malfunctioning & SCREWUP_FOUR)
//{
sprint(self,PRINT_HIGH,"Trapped field generator, have a nice day!\n");
deathmsg = DMSG_FGTRAP;
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
//used to do radius damage
TF_T_Damage(self, self.building, self.building.martyr_enemy, FGTRAP_DMG, 0, TF_TD_ELECTRICITY);
return;
//}
}
local entity dist_checker;
2001-07-17 05:58:10 +00:00
local string st;
sprint(self, PRINT_HIGH, "Field Generator has ");
2001-07-17 05:58:10 +00:00
st = ftos(field.health);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "<EFBFBD>");
2001-07-17 05:58:10 +00:00
st = ftos(field.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(field.ammo_cells);
sprint(self, PRINT_HIGH, st);
sprint(self, PRINT_HIGH, "<EFBFBD>");
2001-07-17 05:58:10 +00:00
st = ftos(field.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_FIELDGEN;
self.menu_count = MENU_REFRESH_RATE;
2001-07-17 05:58:10 +00:00
//dodgy
if (teamplay != 0 && !Teammate(self.building.real_owner.team_no,self.team_no)) {
Menu_EngineerFix_FieldGen_Input(4);
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 = field;
dist_checker.think = CheckDistance;
dist_checker.nextthink = time + 0.3;
};