2001-07-23 20:52:47 +00:00
# include "defs.qh"
# include "messages.qh"
2001-07-17 05:58:10 +00:00
/*======================================================
TFORTMAP . QC Custom TeamFortress v3 .1
( c ) TeamFortress Software Pty Ltd 29 / 2 / 97
( c ) William Kerney 2 / 23 / 00
( c ) Craig Hauser 2 / 23 / 00
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Functions handling TeamFortress Map Entities
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
// Prototypes
// Team Functions
void ( float tno , float scoretoadd ) TeamFortress_TeamIncreaseScore ;
void ( float all ) TeamFortress_TeamShowScores ;
float ( ) TeamFortress_TeamGetWinner ;
// Functions to handle entity placement when spawned
void ( ) TF_PlaceItem ;
void ( ) TF_StartItem ;
void ( ) TF_PlaceGoal ;
void ( ) TF_StartGoal ;
// Spawn functions for all Map Entities
float ( ) CheckExistence ;
void ( ) info_tfdetect ;
void ( ) info_player_teamspawn ;
void ( ) info_tfgoal ;
void ( ) info_tfgoal_timer ;
void ( ) item_tfgoal ;
// AutoDetection Function
void ( entity AD ) ParseTFDetect ;
// Generic Functions
entity ( float ino ) Finditem ;
entity ( float gno ) Findgoal ;
entity ( float gno ) Findteamspawn ;
void ( entity Goal ) InactivateGoal ;
void ( entity Goal ) RestoreGoal ;
void ( entity Goal ) RemoveGoal ;
float ( entity Goal , entity Player , entity AP ) IsAffectedBy ;
void ( entity Goal , entity Player , entity AP , float addb ) Apply_Results ;
float ( entity Goal , entity AP ) APMeetsCriteria ;
void ( entity Goal ) SetupRespawn ;
void ( ) DoRespawn ;
void ( entity Goal , entity AP ) DoGoalWork ;
void ( entity Goal , entity AP ) DoGroupWork ;
void ( entity Item , entity AP ) DoItemGroupWork ;
void ( entity Goal , entity AP ) DoTriggerWork ;
void ( entity Goal , entity AP , float addb ) DoResults ;
void ( entity Goal , entity Player ) RemoveResults ;
//CH
void ( ) tfgoalitem_dropthink2 ;
void ( ) tfgoalitem_settouchandthink ;
//CH 3 checks for a returning goalitem
void ( ) tfgoalitem_checkoriginagain ;
void ( ) tfgoalitem_checkoriginagain2 ;
void ( ) tfgoalitem_checkoriginagain3 ;
// Goal Functions
void ( ) tfgoal_touch ;
void ( ) info_tfgoal_use ;
// Timer Goal Functions
void ( ) tfgoal_timer_tick ;
// Item Functions
void ( ) item_tfgoal_touch ;
void ( entity Item , entity AP , entity Goal ) tfgoalitem_GiveToPlayer ;
void ( float Item ) Update_team_with_flag_touch ;
void ( float Item ) Update_team_with_flag_drop ;
void ( entity Item , entity AP , float method ) tfgoalitem_RemoveFromPlayer ;
void ( ) tfgoalitem_remove ;
void ( entity Item ) tfgoalitem_drop ;
void ( entity Item ) tfgoalitem_checkgoalreturn ;
void ( ) ReturnItem ;
void ( entity Goal , entity Player , entity Item ) DisplayItemStatus ;
// CTF Support Functions
void ( ) CTF_FlagCheck ;
// Chris Support Functions
//void (float winner) RoundStop;
//=========================================================================
// ENTITY PLACEMENT HANDLING FUNCTIONS
//=========================================================================
// Copy the abbreviations into their storage areas
void ( entity Goal ) UpdateAbbreviations =
{
// The first time we enter this, copy the abbreviations
2001-07-23 20:52:47 +00:00
if ( Goal . has_disconnected = = FALSE )
2001-07-17 05:58:10 +00:00
{
// Floats
if ( Goal . g_a ! = 0 & & Goal . goal_activation = = 0 )
Goal . goal_activation = Goal . g_a ;
if ( Goal . g_e ! = 0 & & Goal . goal_effects = = 0 )
Goal . goal_effects = Goal . g_e ;
// Strings
2001-09-30 22:38:44 +00:00
if ( Goal . t_s_h )
2001-07-17 05:58:10 +00:00
Goal . team_str_home = Goal . t_s_h ;
2001-09-30 22:38:44 +00:00
if ( Goal . t_s_m )
2001-07-17 05:58:10 +00:00
Goal . team_str_moved = Goal . t_s_m ;
2001-09-30 22:38:44 +00:00
if ( Goal . t_s_c )
2001-07-17 05:58:10 +00:00
Goal . team_str_carried = Goal . t_s_c ;
2001-09-30 22:38:44 +00:00
if ( Goal . n_s_h )
2001-07-17 05:58:10 +00:00
Goal . non_team_str_home = Goal . n_s_h ;
2001-09-30 22:38:44 +00:00
if ( Goal . n_s_m )
2001-07-17 05:58:10 +00:00
Goal . non_team_str_moved = Goal . n_s_m ;
2001-09-30 22:38:44 +00:00
if ( Goal . n_s_c )
2001-07-17 05:58:10 +00:00
Goal . non_team_str_carried = Goal . n_s_c ;
2001-09-30 22:38:44 +00:00
if ( Goal . b_b )
2001-07-17 05:58:10 +00:00
Goal . broadcast = Goal . b_b ;
2001-09-30 22:38:44 +00:00
if ( Goal . b_t )
2001-07-17 05:58:10 +00:00
Goal . team_broadcast = Goal . b_t ;
2001-09-30 22:38:44 +00:00
if ( Goal . b_n )
2001-07-17 05:58:10 +00:00
Goal . non_team_broadcast = Goal . b_n ;
2001-09-30 22:38:44 +00:00
if ( Goal . b_o )
2001-07-17 05:58:10 +00:00
Goal . owners_team_broadcast = Goal . b_o ;
2001-09-30 22:38:44 +00:00
if ( Goal . n_b )
2001-07-17 05:58:10 +00:00
Goal . netname_broadcast = Goal . n_b ;
2001-09-30 22:38:44 +00:00
if ( Goal . n_t )
2001-07-17 05:58:10 +00:00
Goal . netname_team_broadcast = Goal . n_t ;
2001-09-30 22:38:44 +00:00
if ( Goal . n_n )
2001-07-17 05:58:10 +00:00
Goal . netname_non_team_broadcast = Goal . n_n ;
2001-09-30 22:38:44 +00:00
if ( Goal . n_o )
2001-07-17 05:58:10 +00:00
Goal . netname_owners_team_broadcast = Goal . n_o ;
2001-09-30 22:38:44 +00:00
if ( Goal . d_t )
2001-07-17 05:58:10 +00:00
Goal . team_drop = Goal . d_t ;
2001-09-30 22:38:44 +00:00
if ( Goal . d_n )
2001-07-17 05:58:10 +00:00
Goal . non_team_drop = Goal . d_n ;
2001-09-30 22:38:44 +00:00
if ( Goal . d_n_t )
2001-07-17 05:58:10 +00:00
Goal . netname_team_drop = Goal . d_n_t ;
2001-09-30 22:38:44 +00:00
if ( Goal . d_n_n )
2001-07-17 05:58:10 +00:00
Goal . netname_non_team_drop = Goal . d_n_n ;
2001-07-23 20:52:47 +00:00
Goal . has_disconnected = TRUE ;
2001-07-17 05:58:10 +00:00
}
} ;
// Place the Goal Item
void ( ) TF_PlaceItem =
{
local vector temp1 ;
local vector temp2 ;
2001-07-23 20:52:47 +00:00
self . flags = FL_ITEM ; // make extra wide
2001-07-17 05:58:10 +00:00
self . touch = item_tfgoal_touch ;
setorigin ( self , self . origin ) ;
2001-07-23 20:52:47 +00:00
self . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
//CH my updates
2001-07-23 20:52:47 +00:00
if ( self . goal_activation & TFGI_GOAL_TO_GROUND )
2001-07-17 05:58:10 +00:00
{
self . oldorigin = self . origin ;
2001-07-23 20:52:47 +00:00
self . movetype = MOVETYPE_TOSS ;
2001-07-17 05:58:10 +00:00
self . velocity_z = - 40 ;
self . velocity_x = 0 ; //-50 + (random() * 100);
self . velocity_y = 0 ; //-50 + (random() * 100);
self . nextthink = time + 5.0 ; // give it 5 seconds
self . think = tfgoalitem_dropthink2 ; // and then find where it ended up
}
else
{
self . velocity = ' 0 0 0 ' ;
2001-07-23 20:52:47 +00:00
self . movetype = MOVETYPE_NONE ;
2001-07-17 05:58:10 +00:00
self . oldorigin = self . origin ;
}
//CH sets goal bounding box size
2001-09-30 22:38:44 +00:00
if ( self . goal_min )
2001-07-17 05:58:10 +00:00
temp1 = self . goal_min ;
else
temp1 = ' - 16 - 16 - 24 ' ;
2001-09-30 22:38:44 +00:00
if ( self . goal_max )
2001-07-17 05:58:10 +00:00
temp2 = self . goal_max ;
else
temp2 = ' 16 16 32 ' ;
setsize ( self , temp1 , temp2 ) ; //CH sets box size from above
2001-07-23 20:52:47 +00:00
if ( self . goal_activation & TFGI_GOAL_IS_SOLID )
self . solid = SOLID_BBOX ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
self . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
//CH end my updates
//On tfgoalitem_dropthink2
// self.velocity = '0 0 0';
// self.oldorigin = self.origin; // So we can return it later
2001-07-23 20:52:47 +00:00
if ( self . goal_activation & TFGI_ITEMGLOWS )
2003-12-03 02:43:02 +00:00
self . effects = self . effects | EF_GlowColor ( self ) ;
2001-07-17 05:58:10 +00:00
// Setup the item_list mask
if ( item_list_bit = = 0 )
item_list_bit = 1 ;
self . item_list = item_list_bit ;
item_list_bit = item_list_bit * 2 ;
} ;
//=========================================================================
// Start the Goal Item
void ( ) TF_StartItem =
{
UpdateAbbreviations ( self ) ;
self . nextthink = time + 0.2 ; // items start after other solids
self . think = TF_PlaceItem ;
2001-07-23 20:52:47 +00:00
if ( self . goal_state = = TFGS_REMOVED )
2001-07-17 05:58:10 +00:00
RemoveGoal ( self ) ;
} ;
//=========================================================================
// Place the Goal
void ( ) TF_PlaceGoal =
{
if ( self . classname ! = " info_tfgoal_timer " )
{
// Only give touch functions to goals that can be activated by touch
2001-07-23 20:52:47 +00:00
if ( self . goal_activation & TFGA_TOUCH )
2001-07-17 05:58:10 +00:00
self . touch = tfgoal_touch ;
}
else
{
// Set up the next Timer Tick
self . think = tfgoal_timer_tick ;
self . nextthink = time + self . search_time ;
// So searches for this goal work later on
self . classname = " info_tfgoal " ;
}
2001-07-23 20:52:47 +00:00
self . flags = FL_ITEM ; // make extra wide
self . movetype = MOVETYPE_NONE ;
2001-07-17 05:58:10 +00:00
self . velocity = ' 0 0 0 ' ;
self . oldorigin = self . origin ; // So we can return it later
} ;
//=========================================================================
// Start the Goal
void ( ) TF_StartGoal =
{
UpdateAbbreviations ( self ) ;
self . nextthink = time + 0.2 ; // goals start after other solids
self . think = TF_PlaceGoal ;
self . use = info_tfgoal_use ;
2001-07-23 20:52:47 +00:00
if ( self . goal_state = = TFGS_REMOVED )
2001-07-17 05:58:10 +00:00
RemoveGoal ( self ) ;
} ;
//=========================================================================
// SPAWN FUNCTIONS
//=========================================================================
// Checks whether this entity should exist under the current settings
float ( ) CheckExistence =
{
UpdateAbbreviations ( self ) ;
if ( self . ex_skill_min & & ( skill < = self . ex_skill_min ) )
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
else if ( self . ex_skill_max & & ( skill > = self . ex_skill_max ) )
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
return TRUE ;
2001-07-17 05:58:10 +00:00
} ;
//=========================================================================
// Spawn a detection entity
void ( ) info_tfdetect =
{
UpdateAbbreviations ( self ) ;
// The rest of the checking is done in the ParseTFDetect() function,
// which is called the first time someone enters the map, in client.qc
} ;
//=========================================================================
// Spawn a Team Spawn Point
void ( ) info_player_teamspawn =
{
local entity te ;
2001-07-23 20:52:47 +00:00
if ( CheckExistence ( ) = = FALSE )
2001-07-17 05:58:10 +00:00
{
dremove ( self ) ;
return ;
}
// find the highest team number
if ( number_of_teams < self . team_no )
number_of_teams = self . team_no ;
// Team spawnpoints must have a team associated with them
if ( self . team_no < = 0 )
{
RPrint ( " no team_no associated with info_player_teamspawn \n " ) ;
dremove ( self ) ;
}
// Does this give out a GoalItem?
if ( self . items ! = 0 )
{
te = Finditem ( self . items ) ;
if ( ! te )
{
RPrint ( " info_player_teamspawn specifies a GoalItem that does not exist \n " ) ;
dremove ( self ) ;
}
}
if ( self . team_no = = 1 )
self . team_str_home = " ts1 " ;
else if ( self . team_no = = 2 )
self . team_str_home = " ts2 " ;
else if ( self . team_no = = 3 )
self . team_str_home = " ts3 " ;
else if ( self . team_no = = 4 )
self . team_str_home = " ts4 " ;
} ;
void ( ) i_p_t =
{
self . classname = " info_player_teamspawn " ;
info_player_teamspawn ( ) ;
} ;
//=========================================================================
// Spawn a goal entity
void ( ) info_tfgoal =
{
local vector temp1 ;
local vector temp2 ;
2001-07-23 20:52:47 +00:00
if ( CheckExistence ( ) = = FALSE )
2001-07-17 05:58:10 +00:00
{
dremove ( self ) ;
return ;
}
// Graphic
if ( self . mdl )
{
// We try both, so at least one will work
precache_model ( self . mdl ) ;
precache_model2 ( self . mdl ) ;
setmodel ( self , self . mdl ) ;
}
// Activation sound
if ( self . noise )
{
// We try both, so at least one will work
precache_sound ( self . noise ) ;
precache_sound2 ( self . noise ) ;
}
// For the powerups
precache_sound ( " items/protect.wav " ) ;
precache_sound ( " items/protect2.wav " ) ;
precache_sound ( " items/protect3.wav " ) ;
precache_sound2 ( " items/protect2.wav " ) ;
precache_sound2 ( " items/protect3.wav " ) ;
precache_sound ( " items/suit.wav " ) ;
precache_sound ( " items/suit2.wav " ) ;
precache_sound ( " items/inv1.wav " ) ;
precache_sound ( " items/inv2.wav " ) ;
precache_sound ( " items/inv3.wav " ) ;
precache_sound ( " items/damage.wav " ) ;
precache_sound ( " items/damage2.wav " ) ;
precache_sound ( " items/damage3.wav " ) ;
//CH set solid state
2001-07-23 20:52:47 +00:00
if ( self . goal_activation & TFGI_GOAL_IS_SOLID )
self . solid = SOLID_BBOX ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
self . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
if ( self . goal_state = = 0 )
2001-07-23 20:52:47 +00:00
self . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
//CH sets goal bounding box size
2001-09-30 22:38:44 +00:00
if ( self . goal_min )
2001-07-17 05:58:10 +00:00
temp1 = self . goal_min ;
else
temp1 = ' - 16 - 16 - 24 ' ;
2001-09-30 22:38:44 +00:00
if ( self . goal_max )
2001-07-17 05:58:10 +00:00
temp2 = self . goal_max ;
else
temp2 = ' 16 16 32 ' ;
setsize ( self , temp1 , temp2 ) ; //CH sets box size from above
TF_StartGoal ( ) ;
} ;
void ( ) i_t_g =
{
self . classname = " info_tfgoal " ;
info_tfgoal ( ) ;
} ;
//=========================================================================
// Spawn a Timer goal entity
void ( ) info_tfgoal_timer =
{
2001-07-23 20:52:47 +00:00
if ( CheckExistence ( ) = = FALSE )
2001-07-17 05:58:10 +00:00
{
dremove ( self ) ;
return ;
}
// Graphic
if ( self . mdl )
{
// We try both, so at least one will work
precache_model ( self . mdl ) ;
precache_model2 ( self . mdl ) ;
setmodel ( self , self . mdl ) ;
}
// Activation sound
if ( self . noise )
{
// We try both, so at least one will work
precache_sound ( self . noise ) ;
precache_sound2 ( self . noise ) ;
}
// Timer Goals must have a time specified
if ( self . search_time < = 0 )
{
RPrint ( " Timer Goal created with no specified time. \n " ) ;
dremove ( self ) ;
}
2001-07-23 20:52:47 +00:00
self . solid = SOLID_NOT ;
2001-07-17 05:58:10 +00:00
if ( self . goal_state = = 0 )
2001-07-23 20:52:47 +00:00
self . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
setsize ( self , ' - 16 - 16 - 24 ' , ' 16 16 32 ' ) ;
TF_StartGoal ( ) ;
} ;
void ( ) i_t_t =
{
self . classname = " info_tfgoal_timer " ;
info_tfgoal_timer ( ) ;
} ;
//=========================================================================
// Spawn a goalitem entity
void ( ) item_tfgoal =
{
local vector temp1 ;
local vector temp2 ;
2001-07-23 20:52:47 +00:00
if ( CheckExistence ( ) = = FALSE )
2001-07-17 05:58:10 +00:00
{
dremove ( self ) ;
return ;
}
// Graphic
if ( self . mdl )
{
// We try both, so at least one will work
precache_model ( self . mdl ) ;
precache_model2 ( self . mdl ) ;
setmodel ( self , self . mdl ) ;
}
else
{
// Default mdl for a GoalItem
self . mdl = " " ;
setmodel ( self , " " ) ;
}
// Respawn sound
precache_sound2 ( " items/itembk2.wav " ) ;
// Activation sound
if ( self . noise )
{
// We try both, so at least one will work
precache_sound ( self . noise ) ;
precache_sound2 ( self . noise ) ;
}
self . touch = item_tfgoal_touch ;
if ( self . goal_state = = 0 )
2001-07-23 20:52:47 +00:00
self . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
//CH sets how it is
2001-07-23 20:52:47 +00:00
if ( self . goal_activation & TFGI_GOAL_IS_SOLID )
self . solid = SOLID_BBOX ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
self . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
setorigin ( self , self . origin ) ;
if ( ! ( self . netname ) )
self . netname = " goalitem " ;
if ( self . pausetime < = 0 )
self . pausetime = 60 ;
// for backwards compatability
if ( self . delay ! = 0 & & self . pausetime = = 0 )
self . pausetime = self . delay ;
//CH sets goal bounding box size
2001-09-30 22:38:44 +00:00
if ( self . goal_min )
2001-07-17 05:58:10 +00:00
temp1 = self . goal_min ;
else
temp1 = ' - 16 - 16 - 24 ' ;
2001-09-30 22:38:44 +00:00
if ( self . goal_max )
2001-07-17 05:58:10 +00:00
temp2 = self . goal_max ;
else
temp2 = ' 16 16 32 ' ;
setsize ( self , temp1 , temp2 ) ; //CH sets box size from above
TF_StartItem ( ) ;
} ;
//=========================================================================
// AUTODETECTION FUNCTIONS
//=========================================================================
// Parse the Detection entities variables and set anything relevant
void ( entity AD ) ParseTFDetect =
{
// Check Version
/*
2001-09-30 22:38:44 +00:00
if ( AD . broadcast )
2001-07-17 05:58:10 +00:00
{
if ( AD . broadcast ! = " TeamFortress v2.5 " )
{
RPrint ( " This map was designed to be run on " ) ;
RPrint ( AD . broadcast ) ;
RPrint ( " \n You are using TeamFortress v2.5 \n " ) ;
RPrint ( " You can get the latest version of this patch at: " ) ;
RPrint ( " http://www.planetquake.com/teamfortress/ \n " ) ;
}
}
*/
// Set the team menu string
2001-09-30 22:38:44 +00:00
if ( AD . team_broadcast )
2001-07-17 05:58:10 +00:00
team_menu_string = AD . team_broadcast ;
// Set toggleflags (DEFUNCT)
// toggleflags = AD.impulse;
// Do localcmds
localcmd ( AD . message ) ;
// Set life limits
team1lives = AD . ammo_shells ;
team2lives = AD . ammo_nails ;
team3lives = AD . ammo_rockets ;
team4lives = AD . ammo_cells ;
// If the lives of any of the teams are 0, they want infinite lives,
// so we set their number to -1
if ( team1lives = = 0 )
team1lives = - 1 ;
if ( team2lives = = 0 )
team2lives = - 1 ;
if ( team3lives = = 0 )
team3lives = - 1 ;
if ( team4lives = = 0 )
team4lives = - 1 ;
// Prevent hook use
if ( ( AD . hook_out = = 1 ) | | no_grapple = = 1 )
2001-07-23 20:52:47 +00:00
allow_hook = FALSE ;
2001-07-17 05:58:10 +00:00
// Set player number limits for each team
team1maxplayers = AD . ammo_medikit ;
team2maxplayers = AD . ammo_detpack ;
team3maxplayers = AD . maxammo_medikit ;
team4maxplayers = AD . maxammo_detpack ;
if ( team1maxplayers = = 0 )
team1maxplayers = 100 ;
if ( team2maxplayers = = 0 )
team2maxplayers = 100 ;
if ( team3maxplayers = = 0 )
team3maxplayers = 100 ;
if ( team4maxplayers = = 0 )
team4maxplayers = 100 ;
// Set illegal playerclasses
illegalclasses = AD . playerclass ;
illegalclasses1 = AD . maxammo_shells ;
illegalclasses2 = AD . maxammo_nails ;
illegalclasses3 = AD . maxammo_rockets ;
illegalclasses4 = AD . maxammo_cells ;
civilianteams = 0 ;
// Civilian team checking
if ( illegalclasses1 = = - 1 )
{
illegalclasses1 = 0 ;
2001-07-23 20:52:47 +00:00
civilianteams = civilianteams | TEAM1_CIVILIANS ;
2001-07-17 05:58:10 +00:00
}
if ( illegalclasses2 = = - 1 )
{
illegalclasses2 = 0 ;
2001-07-23 20:52:47 +00:00
civilianteams = civilianteams | TEAM2_CIVILIANS ;
2001-07-17 05:58:10 +00:00
}
if ( illegalclasses3 = = - 1 )
{
illegalclasses3 = 0 ;
2001-07-23 20:52:47 +00:00
civilianteams = civilianteams | TEAM3_CIVILIANS ;
2001-07-17 05:58:10 +00:00
}
if ( illegalclasses4 = = - 1 )
{
illegalclasses4 = 0 ;
2001-07-23 20:52:47 +00:00
civilianteams = civilianteams | TEAM4_CIVILIANS ;
2001-07-17 05:58:10 +00:00
}
} ;
//=========================================================================
// GENERIC FUNCTIONS
//=========================================================================
// Return the item with a goal_no equal to ino
entity ( float ino ) Finditem =
{
local entity tg ;
local string st ;
// Look for the goal
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " item_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . goal_no = = ino )
return tg ;
tg = find ( tg , classname , " item_tfgoal " ) ;
}
// Goal does not exist
RPrint ( " Could not find an item with a goal_no of " ) ;
st = ftos ( ino ) ;
RPrint ( st ) ;
RPrint ( " . \n " ) ;
} ;
//=========================================================================
// Return the goal with a goal_no equal to gno
entity ( float gno ) Findgoal =
{
local entity tg ;
local string st ;
// Look for the goal
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " info_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . goal_no = = gno )
{
return tg ;
}
tg = find ( tg , classname , " info_tfgoal " ) ;
}
// Goal does not exist
RPrint ( " Could not find a goal with a goal_no of " ) ;
st = ftos ( gno ) ;
RPrint ( st ) ;
RPrint ( " . \n " ) ;
} ;
//=========================================================================
// Return the TeamSpawn with a goal_no equal to gno
entity ( float gno ) Findteamspawn =
{
local entity tg ;
local string st ;
// Look for the goal
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " info_player_teamspawn " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . goal_no = = gno )
return tg ;
tg = find ( tg , classname , " info_player_teamspawn " ) ;
}
// Goal does not exist
RPrint ( " Could not find a Teamspawn with a goal_no of " ) ;
st = ftos ( gno ) ;
RPrint ( st ) ;
RPrint ( " . \n " ) ;
} ;
//=========================================================================
// Inactivate a Timer/Goal
void ( entity Goal ) InactivateGoal =
{
# ifdef MAP_DEBUG
RPrint ( " Attempting to Inactivate " ) ;
RPrint ( Goal . netname ) ;
# endif
2001-07-23 20:52:47 +00:00
if ( Goal . goal_state = = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
{
// Not a timer goal
if ( Goal . search_time = = 0 ) {
2001-07-23 20:52:47 +00:00
if ( Goal . goal_activation & TFGI_GOAL_IS_SOLID )
Goal . solid = SOLID_BBOX ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
Goal . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
}
2001-07-23 20:52:47 +00:00
Goal . goal_state = TFGS_INACTIVE ;
2001-09-30 22:38:44 +00:00
if ( Goal . mdl )
2001-07-17 05:58:10 +00:00
setmodel ( Goal , Goal . mdl ) ;
}
# ifdef MAP_DEBUG
else
{
RPrint ( " ... failed. Goal is " ) ;
2001-07-23 20:52:47 +00:00
if ( Goal . goal_state = = TFGS_INACTIVE )
2001-07-17 05:58:10 +00:00
RPrint ( " inactive \n " ) ;
2001-07-23 20:52:47 +00:00
else if ( Goal . goal_state = = TFGS_REMOVED )
2001-07-17 05:58:10 +00:00
RPrint ( " removed \n " ) ;
2001-07-23 20:52:47 +00:00
else if ( Goal . goal_state = = TFGS_DELAYED )
2001-07-17 05:58:10 +00:00
RPrint ( " delayed \n " ) ;
}
# endif
} ;
//=========================================================================
void ( entity Goal ) RestoreGoal =
{
# ifdef MAP_DEBUG
RPrint ( " Attempting to Restore " ) ;
RPrint ( Goal . netname ) ;
# endif
if ( Goal . search_time = = 0 )
{
2001-07-23 20:52:47 +00:00
if ( Goal . goal_activation & TFGI_GOAL_IS_SOLID )
Goal . solid = SOLID_BBOX ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
Goal . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
2001-09-30 22:38:44 +00:00
if ( Goal . mdl )
2001-07-17 05:58:10 +00:00
setmodel ( Goal , Goal . mdl ) ;
2001-07-23 20:52:47 +00:00
if ( Goal . goal_state = = TFGS_REMOVED )
Goal . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
}
2001-07-23 20:52:47 +00:00
if ( Goal . goal_state = = TFGS_REMOVED )
2001-07-17 05:58:10 +00:00
{
# ifdef MAP_DEBUG
RPrint ( " ... succeeded. \n " ) ;
# endif
// Not a timer goal
if ( Goal . search_time ! = 0 )
// {
2001-07-23 20:52:47 +00:00
// if (Goal.goal_activation & TFGI_GOAL_IS_SOLID)
// Goal.solid = SOLID_BBOX;
2001-07-17 05:58:10 +00:00
// else
2001-07-23 20:52:47 +00:00
// Goal.solid = SOLID_TRIGGER;
2001-07-17 05:58:10 +00:00
// }
// else
Goal . nextthink = time + Goal . search_time ;
2001-07-23 20:52:47 +00:00
Goal . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
2001-09-30 22:38:44 +00:00
// if (Goal.mdl)
2001-07-17 05:58:10 +00:00
// setmodel(Goal, Goal.mdl);
}
# ifdef MAP_DEBUG
else
{
RPrint ( " ... failed. Goal is " ) ;
2001-07-23 20:52:47 +00:00
if ( Goal . goal_state = = TFGS_INACTIVE )
2001-07-17 05:58:10 +00:00
RPrint ( " inactive \n " ) ;
2001-07-23 20:52:47 +00:00
else if ( Goal . goal_state = = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
RPrint ( " active \n " ) ;
2001-07-23 20:52:47 +00:00
else if ( Goal . goal_state = = TFGS_DELAYED )
2001-07-17 05:58:10 +00:00
RPrint ( " delayed \n " ) ;
}
# endif
} ;
//=========================================================================
// Remove a Timer/Goal
void ( entity Goal ) RemoveGoal =
{
# ifdef MAP_DEBUG
RPrint ( " Removing " ) ;
RPrint ( Goal . netname ) ;
RPrint ( " \n " ) ;
# endif
2001-07-23 20:52:47 +00:00
Goal . solid = SOLID_NOT ;
Goal . goal_state = TFGS_REMOVED ;
2001-09-30 22:38:44 +00:00
if ( Goal . mdl )
setmodel ( Goal , " " ) ;
2001-07-17 05:58:10 +00:00
} ;
//=========================================================================
2001-07-23 20:52:47 +00:00
// Return TRUE if the player is affected by the goal
2001-07-17 05:58:10 +00:00
float ( entity Goal , entity Player , entity AP ) IsAffectedBy =
{
local float genv ;
// Don't affect anyone who isn't alive or is in Observer mode
2001-07-23 20:52:47 +00:00
if ( Player . playerclass = = PC_UNDEFINED )
return FALSE ;
2001-07-17 05:58:10 +00:00
// if (Player.health <= 0)
2001-07-23 20:52:47 +00:00
// return FALSE;
2001-07-17 05:58:10 +00:00
// Same Environment Check
2001-07-23 20:52:47 +00:00
if ( Goal . goal_effects & TFGE_SAME_ENVIRONMENT )
2001-07-17 05:58:10 +00:00
{
genv = pointcontents ( Goal . origin ) ;
if ( pointcontents ( Player . origin ) ! = genv )
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
}
if ( Goal . t_length ! = 0 )
{
// Within radius?
if ( vlen ( Goal . origin - Player . origin ) < = Goal . t_length )
{
// Obstructed by walls?
2001-07-23 20:52:47 +00:00
if ( Goal . goal_effects & TFGE_WALL )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
traceline ( Goal . origin , Player . origin , TRUE , Goal ) ;
2001-07-17 05:58:10 +00:00
if ( trace_fraction = = 1 )
2001-07-23 20:52:47 +00:00
return TRUE ;
2001-07-17 05:58:10 +00:00
}
else
2001-07-23 20:52:47 +00:00
return TRUE ;
2001-07-17 05:58:10 +00:00
}
}
if ( Goal . classname ! = " info_tfgoal_timer " )
{
2001-07-23 20:52:47 +00:00
if ( ( Goal . goal_effects & TFGE_AP ) & & ( Player = = AP ) )
return TRUE ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
if ( ( Goal . goal_effects & TFGE_AP_TEAM ) & & ( AP . team_no = = Player . team_no ) )
return TRUE ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
if ( ( Goal . goal_effects & TFGE_NOT_AP_TEAM ) & & ( AP . team_no ! = Player . team_no ) )
return TRUE ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
if ( ( Goal . goal_effects & TFGE_NOT_AP ) & & ( Player ! = AP ) )
return TRUE ;
2001-07-17 05:58:10 +00:00
}
if ( ( Goal . maxammo_shells ! = 0 ) & & ( Player . team_no = = Goal . maxammo_shells ) )
2001-07-23 20:52:47 +00:00
return TRUE ;
2001-07-17 05:58:10 +00:00
if ( ( Goal . maxammo_nails ! = 0 ) & & ( Player . team_no ! = Goal . maxammo_shells ) )
2001-07-23 20:52:47 +00:00
return TRUE ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
} ;
//=========================================================================
// Apply modifications to the Player passed in
void ( entity Goal , entity Player , entity AP , float addb ) Apply_Results =
{
local entity oldself , te , oldte ;
stuffcmd ( Player , " bf \n " ) ;
# ifdef MAP_DEBUG
RPrint ( " Applying Results from " ) ;
RPrint ( Goal . netname ) ;
RPrint ( " to " ) ;
RPrint ( AP . netname ) ;
RPrint ( " \n " ) ;
# endif
// If this is a goalitem, record the fact that this player
// has been affected by it.
if ( Goal . classname = = " item_tfgoal " )
Player . item_list = Player . item_list | Goal . item_list ;
if ( Player = = AP )
{
// Increase the team score
if ( Goal . count > 0 )
{
if ( Player . team_no > 0 )
{
TeamFortress_TeamIncreaseScore ( Player . team_no , Goal . count ) ;
// Display short team scores
TeamFortress_TeamShowScores ( 2 ) ;
}
}
}
// Apply Stats, only if told to
if ( addb )
{
# ifdef MAP_DEBUG
RPrint ( " Adding bonuses. \n " ) ;
# endif
// Some results are not applied to dead players
if ( Player . health > 0 )
{
if ( Goal . health > 0 )
T_Heal ( Player , Goal . health , 0 ) ;
if ( Goal . health < 0 )
{
if ( Goal . invincible_finished < 0 )
{
// KK allow goal to strip invinc cheats
2001-08-10 10:03:36 +00:00
Player . items = Player . items & ~ IT_INVULNERABILITY ;
2001-07-17 05:58:10 +00:00
Player . invincible_time = 0 ;
Player . invincible_finished = 0 ;
}
// Make sure we don't gib them. We don't want to gib, because
// it creates too many entities if a lot of players are affected
// by this Goal.
if ( ( 0 - Player . health ) > Goal . health )
2001-07-23 20:52:47 +00:00
TF_T_Damage ( Player , Goal , Goal , ( Player . health + 1 ) , TF_TD_IGNOREARMOUR , TF_TD_OTHER ) ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
TF_T_Damage ( Player , Goal , Goal , ( 0 - Goal . health ) , TF_TD_IGNOREARMOUR , TF_TD_OTHER ) ;
2001-07-17 05:58:10 +00:00
}
}
// The player may be dead now, so check again
if ( Player . health > 0 )
{
if ( Goal . armortype )
Player . armortype = Goal . armortype ;
Player . armorvalue = Player . armorvalue + Goal . armorvalue ;
if ( Goal . armorclass )
{ //WK Modify to | it with bought armor
//TODO: Make this a map specific option
//WK Don't give wooden armor since it doesn't exist
// any more. And we don't want gel for free, right?
2001-07-23 20:52:47 +00:00
Player . armorclass = Goal . armorclass - ( Goal . armorclass & AT_SAVEMELEE ) ;
if ( Player . tf_items & NIT_KEVLAR )
Player . armorclass = Player . armorclass | AT_SAVESHOT ;
if ( Player . tf_items & NIT_GEL )
Player . armorclass = Player . armorclass | AT_SAVEMELEE ;
if ( Player . tf_items & NIT_BLAST )
Player . armorclass = Player . armorclass | AT_SAVEEXPLOSION ;
if ( Player . tf_items & NIT_CERAMIC )
Player . armorclass = Player . armorclass | AT_SAVEELECTRICITY ;
if ( Player . tf_items & NIT_ASBESTOS )
Player . armorclass = Player . armorclass | AT_SAVEFIRE ;
2001-07-17 05:58:10 +00:00
}
Player . ammo_shells = Player . ammo_shells + Goal . ammo_shells ;
Player . ammo_nails = Player . ammo_nails + Goal . ammo_nails ;
Player . ammo_rockets = Player . ammo_rockets + Goal . ammo_rockets ;
Player . ammo_cells = Player . ammo_cells + Goal . ammo_cells ;
Player . ammo_medikit = Player . ammo_medikit + Goal . ammo_medikit ;
Player . ammo_detpack = Player . ammo_detpack + Goal . ammo_detpack ;
if ( Player . tp_grenades_1 ! = 0 ) //WK Stop Bug grenades
Player . no_grenades_1 = Player . no_grenades_1 + Goal . no_grenades_1 ;
if ( Player . tp_grenades_2 ! = 0 ) //WK Stop Bug grenades
Player . no_grenades_2 = Player . no_grenades_2 + Goal . no_grenades_2 ;
if ( Player . no_grenades_1 > GetMaxGrens ( Player , 1 ) )
Player . no_grenades_1 = GetMaxGrens ( Player , 1 ) ;
if ( Player . no_grenades_2 > GetMaxGrens ( Player , 2 ) )
Player . no_grenades_2 = GetMaxGrens ( Player , 2 ) ;
/*if (Player.no_grenades_1 > 4)
2001-07-23 20:52:47 +00:00
if ( Player . tf_items & NIT_AMMO_BANDOLIER )
2001-07-17 05:58:10 +00:00
Player . no_grenades_1 = 5 ;
else
Player . no_grenades_1 = 4 ;
if ( Player . no_grenades_2 > 4 )
2001-07-23 20:52:47 +00:00
if ( Player . tf_items & NIT_AMMO_BANDOLIER )
2001-07-17 05:58:10 +00:00
Player . no_grenades_2 = 5 ;
else
Player . no_grenades_2 = 4 ; */
if ( Player . ammo_detpack > Player . maxammo_detpack )
Player . ammo_detpack = Player . maxammo_detpack ;
// Apply any powerups
if ( Goal . invincible_finished > 0 )
{
2001-07-23 20:52:47 +00:00
Player . items = Player . items | IT_INVULNERABILITY ;
2001-07-17 05:58:10 +00:00
Player . invincible_time = 1 ;
Player . invincible_finished = time + Goal . invincible_finished ;
// if its a GoalItem, powerup is permanent, so we use TFSTATE flags
if ( Goal . classname = = " item_tfgoal " )
{
2001-07-23 20:52:47 +00:00
Player . tfstate = Player . tfstate | TFSTATE_INVINCIBLE ;
2001-07-17 05:58:10 +00:00
Player . invincible_finished = time + 666 ;
}
}
if ( Goal . invisible_finished > 0 )
{
2001-07-23 20:52:47 +00:00
Player . items = Player . items | IT_INVISIBILITY ;
2001-07-17 05:58:10 +00:00
Player . invisible_time = 1 ;
Player . invisible_finished = time + Goal . invisible_finished ;
// if its a GoalItem, powerup is permanent, so we use TFSTATE flags
if ( Goal . classname = = " item_tfgoal " )
{
2001-07-23 20:52:47 +00:00
Player . tfstate = Player . tfstate | TFSTATE_INVISIBLE ;
2001-07-17 05:58:10 +00:00
Player . invisible_finished = time + 666 ;
}
}
if ( Goal . super_damage_finished > 0 )
{
//WK Remove Inspiration when we get the real thing
2001-07-23 20:52:47 +00:00
Player . tfstate = Player . tfstate - ( Player . tfstate & TFSTATE_INSPIRED ) ;
Player . items = Player . items | IT_QUAD ;
2001-07-17 05:58:10 +00:00
Player . super_time = 1 ;
Player . super_damage_finished = time + Goal . super_damage_finished ;
// if its a GoalItem, powerup is permanent, so we use TFSTATE flags
if ( Goal . classname = = " item_tfgoal " )
{
2001-07-23 20:52:47 +00:00
Player . tfstate = Player . tfstate | TFSTATE_QUAD ;
2001-07-17 05:58:10 +00:00
Player . super_damage_finished = time + 666 ;
}
}
if ( Goal . radsuit_finished > 0 )
{
2001-07-23 20:52:47 +00:00
Player . items = Player . items | IT_SUIT ;
2001-07-17 05:58:10 +00:00
Player . rad_time = 1 ;
Player . radsuit_finished = time + Goal . radsuit_finished ;
// if its a GoalItem, powerup is permanent, so we use TFSTATE flags
if ( Goal . classname = = " item_tfgoal " )
{
2001-07-23 20:52:47 +00:00
Player . tfstate = Player . tfstate | TFSTATE_RADSUIT ;
2001-07-17 05:58:10 +00:00
Player . radsuit_finished = time + 666 ;
}
}
}
// These results are applied to dead and living players
if ( Goal . lives < 0 )
2001-07-23 20:52:47 +00:00
bprint ( PRINT_HIGH , " ERROR: GOAL GAVE OUT NEGATIVE LIVES. CUSTOMTF DOESN'T SUPPORT THAT YET \n " ) ;
2001-07-17 05:58:10 +00:00
Player . lives = Player . lives + Goal . lives ;
2003-11-30 00:12:57 +00:00
RPrint ( " Giving " + ftos ( Goal . frags ) + " frags to " + Player . netname + " from goal " + Goal . netname + " . \n " ) ;
2001-07-17 05:58:10 +00:00
Player . real_frags = Player . real_frags + Goal . frags ;
2001-07-23 20:52:47 +00:00
if ( ! ( toggleflags & TFLAG_TEAMFRAGS ) )
2001-07-17 05:58:10 +00:00
Player . frags = Player . real_frags ;
// Now apply the Playerclass limitations & Redisplay Ammo counts
oldself = self ;
self = Player ;
TeamFortress_CheckClassStats ( ) ;
//WK Fix CH's bug fix with this if statement :)
2001-07-23 20:52:47 +00:00
if ( ! ( self . current_weapon = = WEAP_ASSAULT_CANNON & & self . heat > = 0 ) )
2001-07-17 05:58:10 +00:00
W_SetCurrentAmmo ( ) ; //CH stops interrupt weapon fire bug
self = oldself ;
}
# ifdef MAP_DEBUG
else
{
RPrint ( " NOT Adding bonuses. \n " ) ;
}
# endif
2001-11-02 17:00:52 +00:00
if ( Goal . goal_result & TFGR_CAUSERESPAWN & & Player )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
if ( ( Player . playerclass = = PC_CUSTOM & & Player . done_custom & CUSTOM_FINISHED ) | | ( Player . playerclass ! = PC_UNDEFINED & & Player . playerclass ! = PC_CUSTOM ) ) //CH respawn player
2001-07-17 05:58:10 +00:00
{
//CH this needs lots of testing
//*CH
local entity temp ;
temp = self ;
self = Player ;
PutClientInServer ( ) ;
self = temp ;
}
}
// If the Goal resets Spy skin/color then do it
//CH added looking for spykit also removes thief
2001-07-23 20:52:47 +00:00
if ( Goal . goal_result & TFGR_REMOVE_DISGUISE )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
if ( Player . job & JOB_THIEF & & ( Player . job & JOB_ACTIVE | | Player . job & JOB_FULL_HIDE ) )
RevealThief ( Player , FALSE ) ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
if ( Player . playerclass = = PC_SPY | | Player . cutf_items & CUTF_SPY_KIT )
2001-07-17 05:58:10 +00:00
{
makeImmune ( self , time + 4 ) ;
//self.immune_to_check = time + 4;
Spy_RemoveDisguise ( Player ) ;
}
}
// If there's a GoalItem for this goal, give it to the player
// GoalItems use "items" for the console lights... so don't do it for items.
if ( Goal . items ! = 0 & & Goal . classname ! = " item_tfgoal " )
{
// Find the item
te = Finditem ( Goal . items ) ;
if ( te )
tfgoalitem_GiveToPlayer ( te , Player , Goal ) ;
}
// If this goal removes an item from the player, remove it
if ( Goal . axhitme ! = 0 )
{
te = Finditem ( Goal . axhitme ) ;
if ( te . owner = = Player )
{
tfgoalitem_RemoveFromPlayer ( te , Player , 1 ) ;
}
}
// if this goal removes a group of items from the player, remove them
if ( Goal . remove_item_group ! = 0 )
{
// Find all goals
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " item_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( te )
{
if ( te . group_no = = Goal . remove_item_group & & te . owner = = AP )
{
// messy, since we need the item to find the next one,
// and we also want to remove it
oldte = te ;
te = find ( te , classname , " item_tfgoal " ) ;
tfgoalitem_RemoveFromPlayer ( oldte , Player , 1 ) ;
}
else
{
te = find ( te , classname , " item_tfgoal " ) ;
}
}
}
// If this goal displays some Item statuses, then do so
if ( Goal . display_item_status1 ! = 0 )
{
te = Finditem ( Goal . display_item_status1 ) ;
if ( te )
DisplayItemStatus ( Goal , Player , te ) ;
else
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , " Item is missing. \n " ) ;
2001-07-17 05:58:10 +00:00
}
if ( Goal . display_item_status2 ! = 0 )
{
te = Finditem ( Goal . display_item_status2 ) ;
if ( te )
DisplayItemStatus ( Goal , Player , te ) ;
else
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , " Item is missing. \n " ) ;
2001-07-17 05:58:10 +00:00
}
if ( Goal . display_item_status3 ! = 0 )
{
te = Finditem ( Goal . display_item_status3 ) ;
if ( te )
DisplayItemStatus ( Goal , Player , te ) ;
else
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , " Item is missing. \n " ) ;
2001-07-17 05:58:10 +00:00
}
if ( Goal . display_item_status4 ! = 0 )
{
te = Finditem ( Goal . display_item_status4 ) ;
if ( te )
DisplayItemStatus ( Goal , Player , te ) ;
else
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , " Item is missing. \n " ) ;
2001-07-17 05:58:10 +00:00
}
} ;
//=========================================================================
// Remove any results applied to this player by the Goal
// Used when a GoalItem is dropped/removed
void ( entity Goal , entity Player ) RemoveResults =
{
local entity oldself , te ;
local float puinvin , puinvis , puquad , purad ;
// Only remove the stats if the player has been affected
// by this item. This is needed because the player may have
// died since being affected
if ( Goal . classname = = " item_tfgoal " )
{
if ( ! ( Player . item_list & Goal . item_list ) )
return ;
2001-07-23 20:52:47 +00:00
if ( Goal . goal_activation & TFGI_DONTREMOVERES )
2001-07-17 05:58:10 +00:00
return ;
// Remove the affected flag
Player . item_list = Player . item_list - ( Player . item_list & Goal . item_list ) ;
}
if ( Goal . health > 0 )
2001-07-23 20:52:47 +00:00
TF_T_Damage ( Player , Goal , Goal , Goal . health , TF_TD_IGNOREARMOUR , TF_TD_OTHER ) ;
2001-07-17 05:58:10 +00:00
if ( Goal . health < 0 )
T_Heal ( Player , ( 0 - Goal . health ) , 0 ) ;
Player . lives = Player . lives - Goal . lives ;
Player . armortype = Player . armortype - Goal . armortype ;
Player . armorvalue = Player . armorvalue - Goal . armorvalue ;
Player . armorclass = Player . armorclass - ( Player . armorclass & Goal . armorclass ) ;
Player . real_frags = Player . real_frags - Goal . frags ;
2001-07-23 20:52:47 +00:00
if ( ! ( toggleflags & TFLAG_TEAMFRAGS ) )
2001-07-17 05:58:10 +00:00
Player . frags = Player . real_frags ;
Player . ammo_shells = Player . ammo_shells - Goal . ammo_shells ;
Player . ammo_nails = Player . ammo_nails - Goal . ammo_nails ;
Player . ammo_rockets = Player . ammo_rockets - Goal . ammo_rockets ;
Player . ammo_cells = Player . ammo_cells - Goal . ammo_cells ;
Player . ammo_medikit = Player . ammo_medikit - Goal . ammo_medikit ;
Player . ammo_detpack = Player . ammo_detpack - Goal . ammo_detpack ;
Player . no_grenades_1 = Player . no_grenades_1 - Goal . no_grenades_1 ;
Player . no_grenades_2 = Player . no_grenades_2 - Goal . no_grenades_2 ;
2001-07-23 20:52:47 +00:00
puinvin = FALSE ;
puinvis = FALSE ;
puquad = FALSE ;
purad = FALSE ;
2001-07-17 05:58:10 +00:00
// Make sure we don't remove an effect another Goal is also supplying
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " item_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( te )
{
if ( ( te . owner = = Player ) & & ( te ! = Goal ) )
{
if ( te . invincible_finished > 0 )
2001-07-23 20:52:47 +00:00
puinvin = TRUE ;
2001-07-17 05:58:10 +00:00
if ( te . invisible_finished > 0 )
2001-07-23 20:52:47 +00:00
puinvis = TRUE ;
2001-07-17 05:58:10 +00:00
if ( te . super_damage_finished > 0 )
2001-07-23 20:52:47 +00:00
puquad = TRUE ;
2001-07-17 05:58:10 +00:00
if ( te . radsuit_finished > 0 )
2001-07-23 20:52:47 +00:00
purad = TRUE ;
2001-07-17 05:58:10 +00:00
}
te = find ( te , classname , " item_tfgoal " ) ;
}
// Remove all powerups
if ( ( Goal . invincible_finished > 0 ) & & ( ! puinvin ) )
{
// if its a GoalItem, powerup was permanent, so we remove TFSTATE flag
2001-07-23 20:52:47 +00:00
Player . tfstate = Player . tfstate - ( Player . tfstate & TFSTATE_INVINCIBLE ) ;
Player . items = Player . items | IT_INVULNERABILITY ;
2001-07-17 05:58:10 +00:00
Player . invincible_time = 1 ;
Player . invincible_finished = time + Goal . invincible_finished ;
}
if ( ( Goal . invisible_finished > 0 ) & & ( ! puinvis ) )
{
// if its a GoalItem, powerup was permanent, so we remove TFSTATE flag
2001-07-23 20:52:47 +00:00
Player . tfstate = Player . tfstate - ( Player . tfstate & TFSTATE_INVISIBLE ) ;
Player . items = Player . items | IT_INVISIBILITY ;
2001-07-17 05:58:10 +00:00
Player . invisible_time = 1 ;
Player . invisible_finished = time + Goal . invisible_finished ;
}
if ( ( Goal . super_damage_finished > 0 ) & & ( ! puquad ) )
{
// if its a GoalItem, powerup was permanent, so we remove TFSTATE flag
2001-07-23 20:52:47 +00:00
Player . tfstate = Player . tfstate - ( Player . tfstate & TFSTATE_QUAD ) ;
Player . items = Player . items | IT_QUAD ;
2001-07-17 05:58:10 +00:00
Player . super_time = 1 ;
Player . super_damage_finished = time + Goal . super_damage_finished ;
}
//WK Don't remove the scuba gear
2001-07-23 20:52:47 +00:00
if ( ( Goal . radsuit_finished > 0 ) & & ( ! purad ) & & ! ( Player . tf_items & NIT_SCUBA ) )
2001-07-17 05:58:10 +00:00
{
// if its a GoalItem, powerup was permanent, so we remove TFSTATE flag
2001-07-23 20:52:47 +00:00
Player . tfstate = Player . tfstate - ( Player . tfstate & TFSTATE_RADSUIT ) ;
Player . items = Player . items | IT_SUIT ;
2001-07-17 05:58:10 +00:00
Player . rad_time = 1 ;
Player . radsuit_finished = time + Goal . radsuit_finished ;
}
// Now apply the Playerclass limitations & Redisplay Ammo counts
oldself = self ;
self = Player ;
TeamFortress_CheckClassStats ( ) ;
W_SetCurrentAmmo ( ) ;
self = oldself ;
} ;
//=========================================================================
2001-07-23 20:52:47 +00:00
// Return TRUE if the player meets the AP criteria
2001-07-17 05:58:10 +00:00
float ( entity Goal , entity AP ) APMeetsCriteria =
{
local float gotone , temp ;
local entity te ;
# ifdef MAP_DEBUG
RPrint ( " ========================== \n " ) ;
# ifdef VERBOSE
RPrint ( " AP Criteria Checking \n " ) ;
RPrint ( " Goal: " ) ;
# else
RPrint ( " APCriteria: " ) ;
# endif
RPrint ( Goal . netname ) ;
# endif
2001-11-02 17:00:52 +00:00
if ( AP )
2001-07-17 05:58:10 +00:00
{
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " \n AP : " ) ;
# else
RPrint ( " by " ) ;
# endif
RPrint ( AP . netname ) ;
RPrint ( " \n " ) ;
RPrint ( " Checking team. " ) ;
# endif
// If a player of a specific team can only activate this
if ( Goal . team_no )
{
if ( Goal . team_no ! = AP . team_no )
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " passed. \n Checking class... " ) ;
# else
RPrint ( " class. " ) ;
# endif
# endif
//CH uses function in tfort.qc to return the class for evaluation
2001-07-23 20:52:47 +00:00
if ( AP . playerclass = = PC_CUSTOM & & ( Goal . playerclass ) )
2001-07-17 05:58:10 +00:00
{
temp = Return_Custom_Skins ( AP ) ;
//CH now that we have their 'class' check
if ( Goal . playerclass ! = temp )
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
}
// If a player of a specific class can only activate this
else if ( Goal . playerclass )
{
if ( Goal . playerclass ! = AP . playerclass )
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " passed. \n Checking items... " ) ;
# else
RPrint ( " items. " ) ;
# endif
# endif
// If this activation needs a GoalItem, make sure the player has it
if ( Goal . items_allowed )
{
te = Finditem ( Goal . items_allowed ) ;
if ( te . owner ! = AP )
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " passed. \n Checking goal states... " ) ;
# else
RPrint ( " goal states. " ) ;
# endif
# endif
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
2001-11-02 17:00:52 +00:00
if ( AP )
2001-07-17 05:58:10 +00:00
RPrint ( " passed. \n Checking Goal States... " ) ;
else
RPrint ( " \n Checking Goal States... " ) ;
# else
RPrint ( " Goal States. " ) ;
# endif
# endif
// Check Goal states
if ( Goal . if_goal_is_active )
{
te = Findgoal ( Goal . if_goal_is_active ) ;
2001-07-23 20:52:47 +00:00
if ( te . goal_state ! = TFGS_ACTIVE )
return FALSE ;
2001-07-17 05:58:10 +00:00
}
if ( Goal . if_goal_is_inactive )
{
te = Findgoal ( Goal . if_goal_is_inactive ) ;
2001-07-23 20:52:47 +00:00
if ( te . goal_state ! = TFGS_INACTIVE )
return FALSE ;
2001-07-17 05:58:10 +00:00
}
if ( Goal . if_goal_is_removed )
{
te = Findgoal ( Goal . if_goal_is_removed ) ;
2001-07-23 20:52:47 +00:00
if ( te . goal_state ! = TFGS_REMOVED )
return FALSE ;
2001-07-17 05:58:10 +00:00
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " passed. \n Checking group states... " ) ;
# else
RPrint ( " group states. " ) ;
# endif
# endif
if ( Goal . if_group_is_active )
{
// Find all goals in the group
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " info_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( te )
{
if ( te . group_no = = Goal . if_group_is_active )
{
2001-07-23 20:52:47 +00:00
if ( te . goal_state ! = TFGS_ACTIVE )
return FALSE ;
2001-07-17 05:58:10 +00:00
}
te = find ( te , classname , " info_tfgoal " ) ;
}
}
if ( Goal . if_group_is_inactive )
{
// Find all goals in the group
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " info_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( te )
{
if ( te . group_no = = Goal . if_group_is_inactive )
{
2001-07-23 20:52:47 +00:00
if ( te . goal_state ! = TFGS_INACTIVE )
return FALSE ;
2001-07-17 05:58:10 +00:00
}
te = find ( te , classname , " info_tfgoal " ) ;
}
}
if ( Goal . if_group_is_removed )
{
// Find all goals in the group
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " info_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( te )
{
if ( te . group_no = = Goal . if_group_is_removed )
{
2001-07-23 20:52:47 +00:00
if ( te . goal_state ! = TFGS_REMOVED )
return FALSE ;
2001-07-17 05:58:10 +00:00
}
te = find ( te , classname , " info_tfgoal " ) ;
}
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " passed. \n Checking item states... " ) ;
# else
RPrint ( " item states. " ) ;
# endif
# endif
if ( Goal . if_item_has_moved )
{
// Find the item
te = Finditem ( Goal . if_item_has_moved ) ;
if ( te )
{
2001-07-23 20:52:47 +00:00
if ( te . goal_state ! = TFGS_ACTIVE & & te . origin = = te . oldorigin )
return FALSE ;
2001-07-17 05:58:10 +00:00
}
}
if ( Goal . if_item_hasnt_moved )
{
// Find the item
te = Finditem ( Goal . if_item_hasnt_moved ) ;
if ( te )
{
2001-07-23 20:52:47 +00:00
if ( te . goal_state = = TFGS_ACTIVE | | te . origin ! = te . oldorigin )
return FALSE ;
2001-07-17 05:58:10 +00:00
}
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " passed. \n Checking item groups... " ) ;
# else
RPrint ( " item groups " ) ;
# endif
# endif
2001-11-02 17:00:52 +00:00
if ( AP )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
gotone = FALSE ;
2001-07-17 05:58:10 +00:00
if ( Goal . has_item_from_group )
{
// Find all goals
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " item_tfgoal " ) ;
while ( te & & ! gotone )
2001-07-17 05:58:10 +00:00
{
if ( te . group_no = = Goal . has_item_from_group & & te . owner = = AP )
2001-07-23 20:52:47 +00:00
gotone = TRUE ;
2001-07-17 05:58:10 +00:00
te = find ( te , classname , " item_tfgoal " ) ;
}
if ( ! gotone )
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
}
}
# ifdef MAP_DEBUG
RPrint ( " passed. \n " ) ;
# endif
2001-07-23 20:52:47 +00:00
return TRUE ;
2001-07-17 05:58:10 +00:00
} ;
//=========================================================================
// Setup the way this Timer/Goal/Item will respawn
void ( entity Goal ) SetupRespawn =
{
// Timer Goal?
if ( Goal . search_time ! = 0 )
{
InactivateGoal ( Goal ) ;
Goal . think = tfgoal_timer_tick ;
Goal . nextthink = time + Goal . search_time ;
return ;
}
// Check status of respawn for this goal
// Single Activation, do nothing
2001-07-23 20:52:47 +00:00
if ( Goal . goal_result & TFGR_SINGLE )
2001-07-17 05:58:10 +00:00
{
RemoveGoal ( Goal ) ;
return ;
}
// Respawn Activation, set up respawn
if ( Goal . wait > 0 )
{
Goal . nextthink = time + Goal . wait ;
Goal . think = DoRespawn ;
2001-09-30 22:38:44 +00:00
if ( Goal . mdl ) //CH if it has mdl, remove it so
setmodel ( Goal , " " ) ; //that people dont think it works
2001-07-17 05:58:10 +00:00
return ;
}
// Permanently active goal?
else if ( Goal . wait = = - 1 )
return ;
// Otherwise, it's a Multiple Goal
InactivateGoal ( Goal ) ;
} ;
//=========================================================================
// Respawn the goal
void ( ) DoRespawn =
{
RestoreGoal ( self ) ;
InactivateGoal ( self ) ;
} ;
//=========================================================================
// THE Function for knowing whether to activate or not
// Fuck this map code is a mess!
2001-07-23 20:52:47 +00:00
// Returns TRUE if you should activate, FALSE if not
2001-07-17 05:58:10 +00:00
float ( entity Goal , entity AP ) Activated =
{
local float APMet , RevAct , Act ;
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " \n DoIActivate: " ) ;
# else
RPrint ( " \n Goal: " ) ;
# endif
2001-09-30 22:38:44 +00:00
if ( ! Goal . netname )
2001-07-17 05:58:10 +00:00
RPrint ( Goal . classname ) ;
else
RPrint ( Goal . netname ) ;
RPrint ( " , AP: " ) ;
RPrint ( AP . netname ) ;
RPrint ( " \n " ) ;
# endif
2001-07-23 20:52:47 +00:00
if ( Goal . goal_state = = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
{
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " -- Goal already active -- \n " ) ;
# endif
# endif
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
}
2001-07-23 20:52:47 +00:00
if ( Goal . goal_state = = TFGS_REMOVED )
2001-07-17 05:58:10 +00:00
{
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " -- Goal is in Removed state -- \n " ) ;
# endif
# endif
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
}
2001-07-23 20:52:47 +00:00
if ( Goal . goal_state = = TFGS_DELAYED )
2001-07-17 05:58:10 +00:00
{
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " -- Goal is being Delayed -- \n " ) ;
# endif
# endif
2001-07-23 20:52:47 +00:00
return FALSE ;
2001-07-17 05:58:10 +00:00
}
APMet = APMeetsCriteria ( Goal , AP ) ;
if ( Goal . classname = = " item_tfgoal " )
2001-07-23 20:52:47 +00:00
RevAct = Goal . goal_activation & TFGI_REVERSE_AP ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
RevAct = Goal . goal_activation & TFGA_REVERSE_AP ;
Act = FALSE ;
2001-07-17 05:58:10 +00:00
// Does the AP match the AP Criteria?
if ( APMet )
{
# ifdef MAP_DEBUG
RPrint ( " \n " ) ;
# ifdef VERBOSE
RPrint ( " -- Criteria met -- \n " ) ;
# endif
# endif
if ( ! RevAct )
2001-07-23 20:52:47 +00:00
Act = TRUE ;
2001-07-17 05:58:10 +00:00
}
else
{
# ifdef MAP_DEBUG
RPrint ( " \n " ) ;
# ifdef VERBOSE
RPrint ( " -- Criteria not met -- \n " ) ;
# endif
# endif
if ( RevAct )
{
2001-07-23 20:52:47 +00:00
Act = TRUE ;
2001-07-17 05:58:10 +00:00
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " Reverse \n " ) ;
# endif
# endif
}
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
if ( Act )
{
RPrint ( " Activation. \n " ) ;
}
else
{
RPrint ( " NO Activation. \n " ) ;
}
# endif
# endif
return Act ;
} ;
//=========================================================================
// Attempt to activate a Goal
void ( entity Goal , entity AP , entity ActivatingGoal ) AttemptToActivate =
{
local entity te ;
if ( Activated ( Goal , AP ) )
{
// It's all cool. Do the Results.
if ( ActivatingGoal = = Goal )
2001-07-23 20:52:47 +00:00
DoResults ( Goal , AP , TRUE ) ;
2001-11-02 17:00:52 +00:00
else if ( ActivatingGoal )
2001-07-23 20:52:47 +00:00
DoResults ( Goal , AP , ( ActivatingGoal . goal_result & TFGR_ADD_BONUSES ) ) ;
2001-07-17 05:58:10 +00:00
else
DoResults ( Goal , AP , 0 ) ;
}
else
{
// If an else goal should be activated, activate it
if ( Goal . else_goal ! = 0 )
{
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " Else Goal. \n " ) ;
# endif
# endif
te = Findgoal ( Goal . else_goal ) ;
if ( te )
AttemptToActivate ( te , AP , ActivatingGoal ) ;
}
}
} ;
//=========================================================================
// Do all the activation/inactivation/etc of individual Goals
void ( entity Goal , entity AP ) DoGoalWork =
{
local entity te , RI ;
// If another goal should be activated, activate it
if ( Goal . activate_goal_no ! = 0 )
{
Update_team_with_flag_touch ( Goal . activate_goal_no ) ;
te = Findgoal ( Goal . activate_goal_no ) ;
if ( te )
AttemptToActivate ( te , AP , Goal ) ;
}
// If another goal should be inactivated, inactivate it
if ( Goal . inactivate_goal_no ! = 0 )
{
Update_team_with_flag_drop ( Goal . inactivate_goal_no ) ;
te = Findgoal ( Goal . inactivate_goal_no ) ;
if ( te )
InactivateGoal ( te ) ;
}
// If another goal should be restored, restore it
if ( Goal . restore_goal_no ! = 0 )
{
te = Findgoal ( Goal . restore_goal_no ) ;
if ( te )
RestoreGoal ( te ) ;
}
// If another goal should be removed, remove it
if ( Goal . remove_goal_no ! = 0 )
{
te = Findgoal ( Goal . remove_goal_no ) ;
if ( te )
RemoveGoal ( te ) ;
}
// If a GoalItem should be returned, return it
if ( Goal . return_item_no ! = 0 )
{
te = Finditem ( Goal . return_item_no ) ;
if ( te )
{
2001-07-23 20:52:47 +00:00
if ( te . goal_state = = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
tfgoalitem_RemoveFromPlayer ( te , te . owner , 1 ) ;
RI = spawn ( ) ;
RI . enemy = te ;
RI . think = ReturnItem ;
RI . nextthink = time + 0.1 ;
2001-07-23 20:52:47 +00:00
te . solid = SOLID_NOT ;
2001-07-17 05:58:10 +00:00
}
}
// Spawnpoint behaviour
if ( Goal . remove_spawnpoint ! = 0 )
{
te = Findteamspawn ( Goal . remove_spawnpoint ) ;
if ( te )
{
2001-07-23 20:52:47 +00:00
te . goal_state = TFGS_REMOVED ;
2001-09-30 22:38:44 +00:00
te . team_str_home = " " ;
2001-07-17 05:58:10 +00:00
}
}
if ( Goal . restore_spawnpoint ! = 0 )
{
te = Findteamspawn ( Goal . restore_spawnpoint ) ;
if ( te )
{
2001-07-23 20:52:47 +00:00
if ( te . goal_state = = TFGS_REMOVED )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
te . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
if ( te . team_no = = 1 )
te . team_str_home = " ts1 " ;
else if ( te . team_no = = 2 )
te . team_str_home = " ts2 " ;
else if ( te . team_no = = 3 )
te . team_str_home = " ts3 " ;
else if ( te . team_no = = 4 )
te . team_str_home = " ts4 " ;
}
}
}
} ;
//=========================================================================
// Do all the activation/inactivation/etc of Goal Groups
void ( entity Goal , entity AP ) DoGroupWork =
{
local string st ;
local entity tg ;
local float allset ;
// Check all goals activated flag
if ( Goal . all_active ! = 0 )
{
if ( Goal . last_impulse = = 0 )
{
// No goal specified in .lastimpulse. Print error.
RPrint ( " Goal " ) ;
st = ftos ( Goal . goal_no ) ;
RPrint ( st ) ;
RPrint ( " has a .all_active specified, but no .last_impulse \n " ) ;
}
else
{
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " All Active Group Check. \n " ) ;
# endif
# endif
allset = 1 ;
// Find all goals
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " info_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . group_no = = Goal . all_active )
{
2001-07-23 20:52:47 +00:00
if ( tg . goal_state ! = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
allset = 0 ;
}
tg = find ( tg , classname , " info_tfgoal " ) ;
}
// If all goals in this group are activated, do it
if ( allset )
{
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " All Active, Activating last_impulse. \n " ) ;
# endif
# endif
tg = Findgoal ( Goal . last_impulse ) ;
if ( tg )
2001-07-23 20:52:47 +00:00
DoResults ( tg , AP , ( Goal . goal_result & TFGR_ADD_BONUSES ) ) ;
2001-07-17 05:58:10 +00:00
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
else
{
RPrint ( " Not all Active. \n " ) ;
}
# endif
# endif
}
}
// Check Activate all in the group flag
if ( Goal . activate_group_no ! = 0 )
{
// Find all goals
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " info_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . group_no = = Goal . activate_group_no )
DoResults ( tg , AP , 0 ) ; // Don't apply bonuses
tg = find ( tg , classname , " info_tfgoal " ) ;
}
}
// Check Inactivate all in the group flag
if ( Goal . inactivate_group_no ! = 0 )
{
// Find all goals
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " info_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . group_no = = Goal . inactivate_group_no )
InactivateGoal ( tg ) ;
tg = find ( tg , classname , " info_tfgoal " ) ;
}
}
// Check Remove all in the group flag
if ( Goal . remove_group_no ! = 0 )
{
// Find all goals
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " info_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . group_no = = Goal . remove_group_no )
RemoveGoal ( tg ) ;
tg = find ( tg , classname , " info_tfgoal " ) ;
}
}
// Check Restore all in the group flag
if ( Goal . restore_group_no ! = 0 )
{
// Find all goals
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " info_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . group_no = = Goal . restore_group_no )
RestoreGoal ( tg ) ;
tg = find ( tg , classname , " info_tfgoal " ) ;
}
}
// Spawnpoint behaviour
if ( Goal . remove_spawngroup ! = 0 )
{
// Find all goals
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " info_player_teamspawn " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . group_no = = Goal . remove_spawngroup )
{
2001-07-23 20:52:47 +00:00
tg . goal_state = TFGS_REMOVED ;
2001-09-30 22:38:44 +00:00
tg . team_str_home = " " ;
2001-07-17 05:58:10 +00:00
}
tg = find ( tg , classname , " info_player_teamspawn " ) ;
}
}
if ( Goal . restore_spawngroup ! = 0 )
{
// Find all goals
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " info_player_teamspawn " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . group_no = = Goal . restore_spawngroup )
{
2001-07-23 20:52:47 +00:00
tg . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
if ( tg . team_no = = 1 )
tg . team_str_home = " ts1 " ;
else if ( tg . team_no = = 2 )
tg . team_str_home = " ts2 " ;
else if ( tg . team_no = = 3 )
tg . team_str_home = " ts3 " ;
else if ( tg . team_no = = 4 )
tg . team_str_home = " ts4 " ;
}
tg = find ( tg , classname , " info_player_teamspawn " ) ;
}
}
} ;
//=========================================================================
// Do all the checking of Item Groups
void ( entity Item , entity AP ) DoItemGroupWork =
{
local entity tg , carrier ;
local float allcarried ;
local string st ;
2001-07-23 20:52:47 +00:00
allcarried = TRUE ;
2001-07-17 05:58:10 +00:00
if ( Item . distance ! = 0 )
{
if ( Item . pain_finished = = 0 )
{
// No goal specified in .pain_finished. Print error.
RPrint ( " GoalItem " ) ;
st = ftos ( Item . goal_no ) ;
RPrint ( st ) ;
RPrint ( " has a .distance specified, but no .pain_finished \n " ) ;
}
// Find all goals
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " item_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . group_no = = Item . distance )
{
2001-07-23 20:52:47 +00:00
if ( tg . goal_state ! = TFGS_ACTIVE )
allcarried = FALSE ;
2001-07-17 05:58:10 +00:00
}
tg = find ( tg , classname , " item_tfgoal " ) ;
}
2001-07-23 20:52:47 +00:00
if ( allcarried = = TRUE )
2001-07-17 05:58:10 +00:00
{
tg = Findgoal ( Item . pain_finished ) ;
if ( tg )
2001-07-23 20:52:47 +00:00
DoResults ( tg , AP , ( Item . goal_result & TFGR_ADD_BONUSES ) ) ;
2001-07-17 05:58:10 +00:00
}
}
2001-07-23 20:52:47 +00:00
allcarried = TRUE ;
2001-07-17 05:58:10 +00:00
if ( Item . speed ! = 0 )
{
if ( Item . attack_finished = = 0 )
{
// No goal specified in .attack_finished. Print error.
RPrint ( " GoalItem " ) ;
st = ftos ( Item . goal_no ) ;
RPrint ( st ) ;
RPrint ( " has a .speed specified, but no .attack_finished \n " ) ;
}
2001-11-02 17:00:52 +00:00
carrier = NIL ;
2001-07-17 05:58:10 +00:00
// Find all goals
2001-11-02 17:00:52 +00:00
tg = find ( NIL , classname , " item_tfgoal " ) ;
2001-07-17 05:58:10 +00:00
while ( tg )
{
if ( tg . group_no = = Item . speed )
{
2001-07-23 20:52:47 +00:00
if ( tg . goal_state ! = TFGS_ACTIVE )
allcarried = FALSE ;
2001-11-02 17:00:52 +00:00
else if ( ! carrier )
2001-07-17 05:58:10 +00:00
carrier = tg . owner ;
else if ( carrier ! = tg . owner )
2001-07-23 20:52:47 +00:00
allcarried = FALSE ;
2001-07-17 05:58:10 +00:00
}
tg = find ( tg , classname , " item_tfgoal " ) ;
}
2001-07-23 20:52:47 +00:00
if ( allcarried = = TRUE )
2001-07-17 05:58:10 +00:00
{
tg = Findgoal ( Item . attack_finished ) ;
if ( tg )
2001-07-23 20:52:47 +00:00
DoResults ( tg , AP , ( Item . goal_result & TFGR_ADD_BONUSES ) ) ;
2001-07-17 05:58:10 +00:00
}
}
} ;
//=========================================================================
// Do all the activation/removal of Quake Triggers
void ( entity Goal , entity AP ) DoTriggerWork =
{
local entity otemp , stemp , t ;
# ifdef MAP_DEBUG
2001-09-30 22:38:44 +00:00
if ( Goal . killtarget )
2001-07-17 05:58:10 +00:00
{
RPrint ( " Killing Target(s): " ) ;
RPrint ( Goal . killtarget ) ;
RPrint ( " \n " ) ;
}
# endif
// remove targets
if ( Goal . killtarget )
{
2001-11-02 17:00:52 +00:00
t = NIL ;
2001-07-17 05:58:10 +00:00
do
{
t = find ( t , targetname , Goal . killtarget ) ;
2001-11-02 17:00:52 +00:00
if ( t & & t ! = Goal )
2001-07-17 05:58:10 +00:00
remove ( t ) ;
2001-11-02 17:00:52 +00:00
} while ( t ) ;
2001-07-17 05:58:10 +00:00
}
# ifdef MAP_DEBUG
2001-09-30 22:38:44 +00:00
if ( Goal . target )
2001-07-17 05:58:10 +00:00
{
RPrint ( " Activating Target(s): " ) ;
RPrint ( Goal . target ) ;
RPrint ( " \n " ) ;
}
# endif
// fire targets
if ( Goal . target )
{
2001-11-02 17:00:52 +00:00
t = NIL ;
2001-07-17 05:58:10 +00:00
activator = AP ;
do
{
t = find ( t , targetname , Goal . target ) ;
2001-11-02 17:00:52 +00:00
if ( ! t )
2001-07-17 05:58:10 +00:00
return ;
stemp = self ;
otemp = other ;
self = t ;
other = stemp ;
2001-10-17 07:48:11 +00:00
if ( self . use )
self . use ( ) ;
2001-07-17 05:58:10 +00:00
self = stemp ;
other = otemp ;
activator = AP ;
2001-11-02 17:00:52 +00:00
} while ( t ) ;
2001-07-17 05:58:10 +00:00
}
} ;
//=========================================================================
// Handles Delayed Activation of Goals
void ( ) DelayedResult =
{
2001-07-23 20:52:47 +00:00
if ( self . enemy . goal_state = = TFGS_DELAYED )
2001-07-17 05:58:10 +00:00
DoResults ( self . enemy , self . owner , self . weapon ) ;
dremove ( self ) ;
} ;
//=========================================================================
// Do the results for the Timer/Goal/Item
void ( entity Goal , entity AP , float addb ) DoResults =
{
2001-09-23 04:25:02 +00:00
local entity te ;
2001-07-17 05:58:10 +00:00
local float winners ;
// Is the goal already activated?
// This check is needed for goals which are being activated by other goals
2001-07-23 20:52:47 +00:00
if ( Goal . goal_state = = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
return ;
// Delayed Activation?
2001-07-23 20:52:47 +00:00
if ( Goal . delay_time > 0 & & Goal . goal_state ! = TFGS_DELAYED )
2001-07-17 05:58:10 +00:00
{
# ifdef MAP_DEBUG
RPrint ( " Delaying Results of " ) ;
RPrint ( Goal . netname ) ;
RPrint ( " \n " ) ;
# endif
2001-07-23 20:52:47 +00:00
Goal . goal_state = TFGS_DELAYED ;
2001-07-17 05:58:10 +00:00
te = spawn ( ) ;
te . think = DelayedResult ;
te . nextthink = time + Goal . delay_time ;
te . owner = AP ;
te . enemy = Goal ;
te . weapon = addb ;
return ;
}
UpdateAbbreviations ( Goal ) ;
2001-07-23 20:52:47 +00:00
Goal . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " -= Doing Results =- \n " ) ;
RPrint ( " Goal: " ) ;
# else
RPrint ( " DoRes: " ) ;
# endif
RPrint ( Goal . netname ) ;
# ifdef VERBOSE
RPrint ( " \n AP : " ) ;
# else
RPrint ( " by " ) ;
# endif
RPrint ( AP . netname ) ;
if ( addb )
RPrint ( " \n adding bonuses " ) ;
else
RPrint ( " \n NOT adding bonuses " ) ;
# ifdef VERBOSE
RPrint ( " \n -=================- \n " ) ;
# else
RPrint ( " \n " ) ;
# endif
# endif
//- OfN if Goal.option is 1 then no sound attenuation (ATTN_NONE)
local float attn_value ;
2001-07-23 20:52:47 +00:00
attn_value = ATTN_NORM ;
2001-07-17 05:58:10 +00:00
if ( Goal . option = = 1 )
2001-07-23 20:52:47 +00:00
attn_value = ATTN_NONE ;
2001-07-17 05:58:10 +00:00
// Make the sound
if ( Goal . noise )
2001-07-23 20:52:47 +00:00
sound ( other , CHAN_ITEM , Goal . noise , 1 , attn_value ) ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
winners = FALSE ;
2001-07-17 05:58:10 +00:00
// Increase scores
if ( Goal . increase_team1 ! = 0 )
{
TeamFortress_TeamIncreaseScore ( 1 , Goal . increase_team1 ) ;
//if (chris)
// RoundStop(1);
2001-07-23 20:52:47 +00:00
winners = TRUE ;
2001-07-17 05:58:10 +00:00
}
if ( Goal . increase_team2 ! = 0 )
{
TeamFortress_TeamIncreaseScore ( 2 , Goal . increase_team2 ) ;
//if (chris)
// RoundStop(2);
2001-07-23 20:52:47 +00:00
winners = TRUE ;
2001-07-17 05:58:10 +00:00
}
if ( Goal . increase_team3 ! = 0 )
{
TeamFortress_TeamIncreaseScore ( 3 , Goal . increase_team3 ) ;
//if (chris)
// RoundStop(3);
2001-07-23 20:52:47 +00:00
winners = TRUE ;
2001-07-17 05:58:10 +00:00
}
if ( Goal . increase_team4 ! = 0 )
{
TeamFortress_TeamIncreaseScore ( 4 , Goal . increase_team4 ) ;
//if (chris)
// RoundStop(4);
2001-07-23 20:52:47 +00:00
winners = TRUE ;
2001-07-17 05:58:10 +00:00
}
// Display short team scores only if scores changed
2001-07-23 20:52:47 +00:00
if ( winners = = TRUE )
2001-07-17 05:58:10 +00:00
TeamFortress_TeamShowScores ( 2 ) ;
// CTF Map support
2001-07-23 20:52:47 +00:00
if ( CTF_Map = = TRUE )
2001-07-17 05:58:10 +00:00
{
2001-11-02 17:00:52 +00:00
if ( AP )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
if ( Goal . goal_no = = CTF_FLAG1 )
2001-07-17 05:58:10 +00:00
{
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
while ( te )
2001-07-17 05:58:10 +00:00
{
if ( te . team_no = = 2 )
{
if ( te = = AP )
{
winners = random ( ) ;
if ( winners < 0.1 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM1 ) ;
2001-07-17 05:58:10 +00:00
else if ( winners < 0.2 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM2 ) ;
2001-07-17 05:58:10 +00:00
else if ( winners < 0.6 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM3 ) ;
2001-07-17 05:58:10 +00:00
else if ( winners < 0.7 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM4 ) ;
2001-07-17 05:58:10 +00:00
else if ( winners < 0.8 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM5_2 ) ;
2001-07-17 05:58:10 +00:00
else if ( winners < 0.95 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM6 ) ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM7 ) ;
2001-07-17 05:58:10 +00:00
}
else
CenterPrint2 ( te , " \n \n \n " , " Your team <20> <> <EFBFBD> the <20> <> <EFBFBD> <EFBFBD> <EFBFBD> flag!! " ) ;
}
else
CenterPrint2 ( te , " \n \n \n " , " Your flag has been <20> <> <EFBFBD> <EFBFBD> <EFBFBD> !! " ) ;
te = find ( te , classname , " player " ) ;
}
2001-07-23 20:52:47 +00:00
bprint ( PRINT_HIGH , AP . netname ) ;
bprint ( PRINT_HIGH , " <20> <> <EFBFBD> the <20> <> <EFBFBD> <EFBFBD> flag! \n " ) ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
AP . items = AP . items | IT_KEY1 ;
2001-07-17 05:58:10 +00:00
}
2001-07-23 20:52:47 +00:00
else if ( Goal . goal_no = = CTF_FLAG2 )
2001-07-17 05:58:10 +00:00
{
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
while ( te )
2001-07-17 05:58:10 +00:00
{
if ( te . team_no = = 1 )
{
if ( te = = AP )
{
winners = random ( ) ;
if ( winners < 0.1 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM1 ) ;
2001-07-17 05:58:10 +00:00
else if ( winners < 0.2 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM2 ) ;
2001-07-17 05:58:10 +00:00
else if ( winners < 0.6 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM3 ) ;
2001-07-17 05:58:10 +00:00
else if ( winners < 0.7 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM4 ) ;
2001-07-17 05:58:10 +00:00
else if ( winners < 0.8 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM5_1 ) ;
2001-07-17 05:58:10 +00:00
else if ( winners < 0.95 )
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM6 ) ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
CenterPrint2 ( te , " \n \n \n " , MSG_CTF_FLAG_GRAB_TEAM7 ) ;
2001-07-17 05:58:10 +00:00
}
else
CenterPrint2 ( te , " \n \n \n " , " Your team <20> <> <EFBFBD> the <20> <> <EFBFBD> <EFBFBD> <EFBFBD> flag!! " ) ;
}
else
CenterPrint2 ( te , " \n \n \n " , " Your flag has been <20> <> <EFBFBD> <EFBFBD> <EFBFBD> !! " ) ;
te = find ( te , classname , " player " ) ;
}
2001-07-23 20:52:47 +00:00
bprint ( PRINT_HIGH , AP . netname ) ;
bprint ( PRINT_HIGH , " <20> <> <EFBFBD> the <20> <> <EFBFBD> flag! \n " ) ;
AP . items = AP . items | IT_KEY2 ;
2001-07-17 05:58:10 +00:00
}
2001-07-23 20:52:47 +00:00
else if ( Goal . goal_no = = CTF_DROPOFF1 )
2001-07-17 05:58:10 +00:00
{
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
while ( te )
2001-07-17 05:58:10 +00:00
{
if ( te . team_no = = 2 )
{
if ( te = = AP )
CenterPrint2 ( te , " \n \n \n " , " You <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the flag!! " ) ;
else
CenterPrint2 ( te , " \n \n \n " , " Your flag was <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> !! " ) ;
}
else
CenterPrint2 ( te , " \n \n \n " , " Your team <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the flag!! " ) ;
te = find ( te , classname , " player " ) ;
}
2001-07-23 20:52:47 +00:00
bprint ( PRINT_HIGH , AP . netname ) ;
bprint ( PRINT_HIGH , " <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the <20> <> <EFBFBD> flag! \n " ) ;
2001-08-10 10:03:36 +00:00
AP . items = AP . items & ~ IT_KEY2 ;
2001-07-17 05:58:10 +00:00
}
2001-07-23 20:52:47 +00:00
else if ( Goal . goal_no = = CTF_DROPOFF2 )
2001-07-17 05:58:10 +00:00
{
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
while ( te )
2001-07-17 05:58:10 +00:00
{
if ( te . team_no = = 1 )
{
if ( te = = AP )
CenterPrint2 ( te , " \n \n \n " , " You <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the flag!! " ) ;
else
CenterPrint2 ( te , " \n \n \n " , " Your flag was <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> !! " ) ;
}
else
CenterPrint2 ( te , " \n \n \n " , " Your team <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the flag!! " ) ;
te = find ( te , classname , " player " ) ;
}
2001-07-23 20:52:47 +00:00
bprint ( PRINT_HIGH , AP . netname ) ;
bprint ( PRINT_HIGH , " <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the <20> <> <EFBFBD> <EFBFBD> flag! \n " ) ;
2001-08-10 10:03:36 +00:00
AP . items = AP . items & ~ IT_KEY1 ;
2001-07-17 05:58:10 +00:00
}
}
}
// Go through all the players and do any results
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
while ( te )
2001-07-17 05:58:10 +00:00
{
// Centerprinting
2001-09-30 22:38:44 +00:00
if ( Goal . broadcast & & CTF_Map = = FALSE )
2001-07-17 05:58:10 +00:00
CenterPrint2 ( te , " \n \n \n " , Goal . broadcast ) ;
2001-09-30 22:38:44 +00:00
if ( Goal . netname_broadcast & & CTF_Map = = FALSE )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
sprint ( te , PRINT_HIGH , AP . netname ) ;
sprint ( te , PRINT_HIGH , Goal . netname_broadcast ) ;
2001-07-17 05:58:10 +00:00
}
if ( AP = = te )
{
2001-09-30 22:38:44 +00:00
if ( Goal . message )
2001-07-17 05:58:10 +00:00
CenterPrint2 ( te , " \n \n \n " , Goal . message ) ;
}
else if ( AP . team_no = = te . team_no )
{
2001-09-30 22:38:44 +00:00
if ( Goal . owners_team_broadcast & & te . team_no = = Goal . owned_by )
2001-07-17 05:58:10 +00:00
CenterPrint2 ( te , " \n \n \n " , Goal . owners_team_broadcast ) ;
2001-09-30 22:38:44 +00:00
else if ( Goal . team_broadcast )
2001-07-17 05:58:10 +00:00
CenterPrint2 ( te , " \n \n \n " , Goal . team_broadcast ) ;
2001-09-30 22:38:44 +00:00
if ( Goal . netname_owners_team_broadcast & & te . team_no = = Goal . owned_by )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
sprint ( te , PRINT_HIGH , AP . netname ) ;
sprint ( te , PRINT_HIGH , Goal . netname_owners_team_broadcast ) ;
2001-07-17 05:58:10 +00:00
}
2001-09-30 22:38:44 +00:00
else if ( Goal . netname_team_broadcast )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
sprint ( te , PRINT_HIGH , AP . netname ) ;
sprint ( te , PRINT_HIGH , Goal . netname_team_broadcast ) ;
2001-07-17 05:58:10 +00:00
}
}
else
{
2001-09-30 22:38:44 +00:00
if ( Goal . owners_team_broadcast & & te . team_no = = Goal . owned_by )
2001-07-17 05:58:10 +00:00
CenterPrint2 ( te , " \n \n \n " , Goal . owners_team_broadcast ) ;
2001-09-30 22:38:44 +00:00
else if ( Goal . non_team_broadcast )
2001-07-17 05:58:10 +00:00
CenterPrint2 ( te , " \n \n \n " , Goal . non_team_broadcast ) ;
2001-09-30 22:38:44 +00:00
if ( Goal . netname_owners_team_broadcast & & te . team_no = = Goal . owned_by )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
sprint ( te , PRINT_HIGH , AP . netname ) ;
sprint ( te , PRINT_HIGH , Goal . netname_owners_team_broadcast ) ;
2001-07-17 05:58:10 +00:00
}
2001-09-30 22:38:44 +00:00
else if ( Goal . netname_non_team_broadcast )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
sprint ( te , PRINT_HIGH , AP . netname ) ;
sprint ( te , PRINT_HIGH , Goal . netname_non_team_broadcast ) ;
2001-07-17 05:58:10 +00:00
}
}
if ( IsAffectedBy ( Goal , te , AP ) )
{
// If its a Timer Goal, see if it needs to check Criteria again
2001-07-23 20:52:47 +00:00
if ( Goal . search_time ! = 0 & & Goal . goal_effects & TFGE_TIMER_CHECK_AP )
2001-07-17 05:58:10 +00:00
{
if ( APMeetsCriteria ( Goal , te ) )
Apply_Results ( Goal , te , AP , addb ) ;
}
else
{
Apply_Results ( Goal , te , AP , addb ) ;
}
}
te = find ( te , classname , " player " ) ;
}
// Goal is now active
// Items are not always set to active. They handle their modes.
if ( Goal . classname ! = " item_tfgoal " )
2001-07-23 20:52:47 +00:00
Goal . goal_state = TFGS_ACTIVE ;
2001-07-17 05:58:10 +00:00
// EndGame checking
2001-07-23 20:52:47 +00:00
if ( Goal . goal_result & TFGR_ENDGAME )
2001-07-17 05:58:10 +00:00
{
// Display Long TeamScores to everyone
TeamFortress_TeamShowScores ( 1 ) ;
winners = TeamFortress_TeamGetWinner ( ) ;
// Stop everyone
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
2001-07-17 05:58:10 +00:00
while ( te )
{
te . takedamage = 0 ;
2001-07-23 20:52:47 +00:00
te . movetype = MOVETYPE_NONE ;
2001-07-17 05:58:10 +00:00
te . velocity = ' 0 0 0 ' ;
te . avelocity = ' 0 0 0 ' ;
te = find ( te , classname , " player " ) ;
}
te = spawn ( ) ;
te . nextthink = time + 5 ; // Allow 5 secs to read the scores
te . think = execute_changelevel ;
dremove ( Goal ) ;
return ;
}
//CH spawn explosions if so needed
2001-07-23 20:52:47 +00:00
if ( Goal . goal_effects & TFGE_CAUSE_EXPLOSION )
2001-07-17 05:58:10 +00:00
{
2001-10-13 23:02:22 +00:00
WriteByte ( MSG_MULTICAST , SVC_TEMPENTITY ) ;
WriteByte ( MSG_MULTICAST , TE_EXPLOSION ) ;
WriteCoord ( MSG_MULTICAST , self . origin_x ) ;
WriteCoord ( MSG_MULTICAST , self . origin_y ) ;
WriteCoord ( MSG_MULTICAST , self . origin_z ) ;
2001-07-23 20:52:47 +00:00
multicast ( self . origin , MULTICAST_PHS ) ;
2001-07-17 05:58:10 +00:00
// BecomeExplosion();
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " Doing Groupwork... \n " ) ;
# endif
# endif
// Do Goal Group checking
DoGroupWork ( Goal , AP ) ;
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " Doing Goalwork... \n " ) ;
# endif
# endif
// Do Goal checking
DoGoalWork ( Goal , AP ) ;
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " Doing Triggerwork... \n " ) ;
# endif
# endif
// Do Quake Trigger actions
DoTriggerWork ( Goal , AP ) ;
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " Setting up Respawn... \n " ) ;
# endif
# endif
2001-09-22 22:30:33 +00:00
if ( Goal . killtarget & & Goal . killtarget = = Goal . targetname ) {
// self destructive trigger
remove ( Goal ) ;
} else {
// Setup for Respawn
// Items and Triggers do their own respawn work
if ( Goal . classname = = " info_tfgoal " )
SetupRespawn ( Goal ) ;
}
2001-07-17 05:58:10 +00:00
} ;
//=========================================================================
// GOAL FUNCTIONS
//=========================================================================
// Touch function for Goals
void ( ) tfgoal_touch =
{
local entity te ;
// If it is not activated in by the player's touch, return
2001-07-23 20:52:47 +00:00
if ( ! ( self . goal_activation & TFGA_TOUCH ) )
2001-07-17 05:58:10 +00:00
return ;
if ( other . classname ! = " player " )
return ;
// If we're in prematch mode, ignore the touch
if ( prematch > = time )
return ;
if ( other . penance_time > = time )
return ;
// If it's already active, don't bother
2001-07-23 20:52:47 +00:00
if ( self . goal_state = = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
{
# ifdef MAP_DEBUG
RPrint ( " Goal already active. aborting touch. \n " ) ;
# endif
return ;
}
// CTF Hack to make sure the key is in place.
// Temporary hack :)
2001-07-23 20:52:47 +00:00
if ( CTF_Map = = TRUE )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
if ( ( self . goal_no = = CTF_DROPOFF1 ) & & ( other . team_no = = 1 ) )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
te = Finditem ( CTF_FLAG1 ) ;
if ( ( te . goal_state = = TFGS_ACTIVE ) | | ( te . origin ! = te . oldorigin ) )
2001-07-17 05:58:10 +00:00
return ;
}
2001-07-23 20:52:47 +00:00
if ( ( self . goal_no = = CTF_DROPOFF2 ) & & ( other . team_no = = 2 ) )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
te = Finditem ( CTF_FLAG2 ) ;
if ( ( te . goal_state = = TFGS_ACTIVE ) | | ( te . origin ! = te . oldorigin ) )
2001-07-17 05:58:10 +00:00
return ;
}
}
AttemptToActivate ( self , other , self ) ;
} ;
//=========================================================================
// Use (Triggered) function for Goals
void ( ) info_tfgoal_use =
{
# ifdef MAP_DEBUG
RPrint ( " \n " ) ;
RPrint ( " TFGoal triggered by other entity. \n " ) ;
# endif
AttemptToActivate ( self , activator , self ) ;
} ;
//=========================================================================
// Timer goal tick
void ( ) tfgoal_timer_tick =
{
// Check criteria
2001-07-23 20:52:47 +00:00
if ( self . goal_state ! = TFGS_REMOVED )
2001-07-17 05:58:10 +00:00
{
# ifdef MAP_DEBUG
RPrint ( " ========================== \n " ) ;
# ifdef VERBOSE
RPrint ( " Timer Tick for: " ) ;
# else
RPrint ( " Tick: " ) ;
# endif
RPrint ( self . netname ) ;
RPrint ( " Checking criteria... " ) ;
# endif
2001-11-02 17:00:52 +00:00
if ( APMeetsCriteria ( self , NIL ) )
2001-07-17 05:58:10 +00:00
{
2001-11-02 17:00:52 +00:00
DoResults ( self , NIL , TRUE ) ;
2001-07-17 05:58:10 +00:00
}
else
{
InactivateGoal ( self ) ;
self . think = tfgoal_timer_tick ;
self . nextthink = time + self . search_time ;
}
}
} ;
//=========================================================================
// GOALITEM FUNCTIONS
//=========================================================================
// Touch function for the goalitem entity
void ( ) item_tfgoal_touch =
{
2001-11-02 17:00:52 +00:00
if ( infokey ( NIL , " ceasefire " ) = = " on " ) //OfN
2001-07-17 05:58:10 +00:00
return ;
local entity te ;
if ( other . classname ! = " player " )
return ;
if ( other . health < = 0 )
return ;
// Don't let them take goalitems in prematch
if ( prematch > = time )
return ;
// Don't let lame teamkillers take items
if ( other . penance_time > = time )
return ;
// CTF Hack to return your key.
// Temporary hack :)
2001-07-23 20:52:47 +00:00
if ( CTF_Map = = TRUE )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
if ( self . goal_no = = CTF_FLAG1 )
2001-07-17 05:58:10 +00:00
{
// Flag not at home?
if ( self . origin ! = self . oldorigin )
{
if ( other . team_no = = 1 )
{
2001-07-23 20:52:47 +00:00
bprint ( PRINT_HIGH , other . netname ) ;
bprint ( PRINT_HIGH , " <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the <20> <> <EFBFBD> <EFBFBD> flag! \n " ) ;
2001-07-17 05:58:10 +00:00
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
while ( te )
2001-07-17 05:58:10 +00:00
{
if ( te . team_no = = 1 )
CenterPrint2 ( te , " \n \n \n " , " Your flag was <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> !! " ) ;
else
CenterPrint2 ( te , " \n \n \n " , " The <20> <> <EFBFBD> <EFBFBD> <EFBFBD> flag was <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> !! " ) ;
te = find ( te , classname , " player " ) ;
}
2001-07-23 20:52:47 +00:00
self . goal_state = TFGS_INACTIVE ;
self . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
self . touch = item_tfgoal_touch ;
self . origin = self . oldorigin ;
setmodel ( self , self . mdl ) ;
setorigin ( self , self . origin ) ;
2001-07-23 20:52:47 +00:00
sound ( self , CHAN_VOICE , " items/itembk2.wav " , 1 , ATTN_NORM ) ;
2001-07-17 05:58:10 +00:00
return ;
}
}
else
{
if ( other . team_no = = 1 )
return ;
}
}
2001-07-23 20:52:47 +00:00
else if ( self . goal_no = = CTF_FLAG2 )
2001-07-17 05:58:10 +00:00
{
// Flag not at home?
if ( self . origin ! = self . oldorigin )
{
if ( other . team_no = = 2 )
{
2001-07-23 20:52:47 +00:00
bprint ( PRINT_HIGH , other . netname ) ;
bprint ( PRINT_HIGH , " <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the <20> <> <EFBFBD> flag! \n " ) ;
2001-07-17 05:58:10 +00:00
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
while ( te )
2001-07-17 05:58:10 +00:00
{
if ( te . team_no = = 2 )
CenterPrint ( te , " \n \n \n Your flag was <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> !! " ) ;
else
CenterPrint ( te , " \n \n \n The <20> <> <EFBFBD> <EFBFBD> <EFBFBD> flag was <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> !! " ) ;
te = find ( te , classname , " player " ) ;
}
2001-07-23 20:52:47 +00:00
self . goal_state = TFGS_INACTIVE ;
self . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
self . touch = item_tfgoal_touch ;
self . origin = self . oldorigin ;
setmodel ( self , self . mdl ) ;
setorigin ( self , self . origin ) ;
2001-07-23 20:52:47 +00:00
sound ( self , CHAN_VOICE , " items/itembk2.wav " , 1 , ATTN_NORM ) ;
2001-07-17 05:58:10 +00:00
return ;
}
}
else
{
if ( other . team_no = = 2 )
return ;
}
}
}
if ( Activated ( self , other ) )
{
// Give it to the player
tfgoalitem_GiveToPlayer ( self , other , self ) ;
2001-07-23 20:52:47 +00:00
self . goal_state = TFGS_ACTIVE ;
2001-07-17 05:58:10 +00:00
}
else
{
// If an else goal should be activated, activate it
if ( self . else_goal ! = 0 )
{
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " Else Goal. \n " ) ;
# endif
# endif
te = Findgoal ( self . else_goal ) ;
if ( te )
AttemptToActivate ( te , other , self ) ;
}
}
} ;
//=========================================================================
// Give the GoalItem to a Player.
void ( entity Item , entity AP , entity Goal ) tfgoalitem_GiveToPlayer =
{
# ifdef MAP_DEBUG
RPrint ( " Giving " ) ;
RPrint ( Item . netname ) ;
RPrint ( " to " ) ;
RPrint ( AP . netname ) ;
RPrint ( " \n " ) ;
# endif
Item . owner = AP ;
// Remove it from the map
2001-09-30 22:38:44 +00:00
if ( Item . mdl )
setmodel ( Item , " " ) ;
2001-07-23 20:52:47 +00:00
Item . solid = SOLID_NOT ;
2001-07-17 05:58:10 +00:00
// Do the deeds on the player
2001-07-23 20:52:47 +00:00
if ( Item . goal_activation & TFGI_GLOW )
2003-12-03 02:43:02 +00:00
AP . effects = AP . effects | EF_GlowColor ( AP ) ;
2001-07-23 20:52:47 +00:00
if ( Item . goal_activation & TFGI_SLOW )
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed ( AP ) ;
2001-07-23 20:52:47 +00:00
if ( Item . goal_activation & TFGI_ITEMGLOWS )
2003-12-03 02:43:02 +00:00
Item . effects & = ~ EF_ANYGLOW ;
2001-07-17 05:58:10 +00:00
// Light up console icons
2001-07-23 20:52:47 +00:00
if ( Item . items & IT_KEY1 )
AP . items = AP . items | IT_KEY1 ;
if ( Item . items & IT_KEY2 )
AP . items = AP . items | IT_KEY2 ;
2001-07-17 05:58:10 +00:00
// Only do the results if we're allowed to
if ( Goal ! = Item )
{
2001-07-23 20:52:47 +00:00
if ( Goal . goal_result & TFGR_NO_ITEM_RESULTS )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
Item . goal_state = TFGS_ACTIVE ;
2001-07-17 05:58:10 +00:00
return ;
}
}
# ifdef MAP_DEBUG
# ifdef VERBOSE
RPrint ( " Doing item results... \n " ) ;
# endif
# endif
// Prevent the Player from disguising themself if applicable
//CH added looking for spykit & thief
2001-07-23 20:52:47 +00:00
if ( Item . goal_result & TFGR_REMOVE_DISGUISE )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
if ( AP . job & JOB_THIEF & & ( AP . job & JOB_ACTIVE | | AP . job & JOB_FULL_HIDE ) )
RevealThief ( AP , FALSE ) ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
if ( AP . playerclass = = PC_SPY | | AP . cutf_items & CUTF_SPY_KIT )
2001-07-17 05:58:10 +00:00
{
AP . is_unabletospy = 1 ;
}
}
// Do the Results, adding the bonuses
2001-07-23 20:52:47 +00:00
DoResults ( Item , AP , TRUE ) ;
2001-07-17 05:58:10 +00:00
// Check the Item Group Stuff
DoItemGroupWork ( Item , AP ) ;
} ;
//=========================================================================
//Update which team has the flag
void ( float item ) Update_team_with_flag_touch =
{
if ( mapname ! = " steal4d " )
{
team_with_flag = 0 ;
return ;
}
if ( item = = 103 )
{
team_with_flag = 1 ;
friends1_mask = 0 ;
friends2_mask = friends3_mask = friends4_mask = 14 ;
return ;
}
if ( item = = 203 ) {
team_with_flag = 2 ;
friends2_mask = 0 ;
friends1_mask = friends3_mask = friends4_mask = 13 ;
return ;
}
if ( item = = 303 ) {
team_with_flag = 3 ;
friends3_mask = 0 ;
friends1_mask = friends2_mask = friends4_mask = 11 ;
return ;
}
if ( item = = 403 ) {
team_with_flag = 4 ;
friends4_mask = 0 ;
friends1_mask = friends2_mask = friends3_mask = 7 ;
return ;
}
} ;
//=========================================================================
//Update which team has the flag
void ( float item ) Update_team_with_flag_drop =
{
if ( mapname ! = " steal4d " ) {
team_with_flag = 0 ;
return ;
}
if ( item ! = 103 & & item ! = 203 & & item ! = 303 & & item ! = 403 )
return ;
team_with_flag = 0 ;
friends1_mask = friends2_mask = friends3_mask = friends4_mask = 0 ;
} ;
//=========================================================================
// Return the Item to its starting point
void ( ) ReturnItem =
{
2001-07-23 20:52:47 +00:00
self . enemy . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
//CH sets solid type
2001-07-23 20:52:47 +00:00
if ( self . enemy . goal_activation & TFGI_GOAL_IS_SOLID )
self . enemy . solid = SOLID_BBOX ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
self . enemy . solid = SOLID_TRIGGER ;
self . enemy . movetype = MOVETYPE_NONE ;
2001-07-17 05:58:10 +00:00
self . enemy . touch = item_tfgoal_touch ;
self . enemy . origin = self . enemy . oldorigin ;
2001-09-30 22:38:44 +00:00
if ( self . enemy . mdl )
2001-07-17 05:58:10 +00:00
setmodel ( self . enemy , self . enemy . mdl ) ;
setorigin ( self . enemy , self . enemy . origin ) ;
2001-07-23 20:52:47 +00:00
sound ( self . enemy , CHAN_VOICE , " items/itembk2.wav " , 1 , ATTN_NORM ) ;
2001-07-17 05:58:10 +00:00
// Restore a goal if needed
tfgoalitem_checkgoalreturn ( self . enemy ) ;
dremove ( self ) ;
} ;
//=========================================================================
// Remove the GoalItem from a Player.
void ( entity Item , entity AP , float method ) tfgoalitem_RemoveFromPlayer =
{
local entity te ;
2003-12-03 02:43:02 +00:00
local float slowon ;
2001-07-17 05:58:10 +00:00
local float key1on , key2on ;
local float spyoff ;
local entity DelayReturn ;
2001-11-02 17:00:52 +00:00
if ( ! Item )
2001-07-17 05:58:10 +00:00
{
2001-11-02 17:00:52 +00:00
RPrint ( " error: tfgoalitem_RemoveFromPlayer(): !Item " ) ;
2001-07-17 05:58:10 +00:00
return ;
}
# ifdef MAP_DEBUG
RPrint ( " Removing " ) ;
RPrint ( Item . netname ) ;
RPrint ( " from " ) ;
RPrint ( AP . netname ) ;
RPrint ( " \n " ) ;
# endif
2001-07-23 20:52:47 +00:00
slowon = FALSE ;
key1on = FALSE ;
key2on = FALSE ;
spyoff = FALSE ;
2001-07-17 05:58:10 +00:00
// Remove the deeds from the player
// Make sure we don't remove an effect another Goal is also supplying
2003-12-03 02:43:02 +00:00
AP . effects & = ~ EF_ANYGLOW ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
if ( Item . goal_activation & TFGI_ITEMGLOWS )
2003-12-10 03:07:19 +00:00
Item . effects = Item . effects | EF_GlowColor ( Item ) ;
2001-07-17 05:58:10 +00:00
// Remove the Spy prevention
if ( ! spyoff )
AP . is_unabletospy = 0 ;
// Remove the Light up of console icons
if ( ! key1on )
2001-08-10 10:03:36 +00:00
AP . items = AP . items & ~ IT_KEY1 ;
2001-07-17 05:58:10 +00:00
if ( ! key2on )
2001-08-10 10:03:36 +00:00
AP . items = AP . items & ~ IT_KEY2 ;
2001-07-17 05:58:10 +00:00
// Remove AP Modifications
// Go through all the players and do any results
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
while ( te )
2001-07-17 05:58:10 +00:00
{
if ( IsAffectedBy ( Item , te , AP ) )
{
RemoveResults ( Item , te ) ;
}
te = find ( te , classname , " player " ) ;
}
/*
db1 = ftos ( method ) ;
RPrint ( " returning via method : " ) ;
RPrint ( db1 ) ;
RPrint ( " \n " ) ;
*/
// Return it to the starting point if the flag is set
if ( method = = 0 ) // Dropped by a dying player
{
// Do messages
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
while ( te )
2001-07-17 05:58:10 +00:00
{
if ( te . team_no = = Item . owned_by )
{
2001-09-30 22:38:44 +00:00
if ( Item . team_drop )
2001-07-17 05:58:10 +00:00
CenterPrint2 ( te , " \n \n \n " , Item . team_drop ) ;
2001-09-30 22:38:44 +00:00
if ( Item . netname_team_drop )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
sprint ( te , PRINT_HIGH , AP . netname ) ;
sprint ( te , PRINT_HIGH , Item . netname_team_drop ) ;
2001-07-17 05:58:10 +00:00
}
}
else // (te.team_no != Item.owned_by)
{
2001-09-30 22:38:44 +00:00
if ( Item . non_team_drop )
2001-07-17 05:58:10 +00:00
CenterPrint2 ( te , " \n \n \n " , Item . non_team_drop ) ;
2001-09-30 22:38:44 +00:00
if ( Item . netname_non_team_drop )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
sprint ( te , PRINT_HIGH , AP . netname ) ;
sprint ( te , PRINT_HIGH , Item . netname_non_team_drop ) ;
2001-07-17 05:58:10 +00:00
}
}
te = find ( te , classname , " player " ) ;
}
// Drop it if the flag is set
2001-07-23 20:52:47 +00:00
if ( Item . goal_activation & TFGI_RETURN_DROP )
2001-07-17 05:58:10 +00:00
{
DelayReturn = spawn ( ) ;
DelayReturn . enemy = Item ;
DelayReturn . think = ReturnItem ;
DelayReturn . nextthink = time + 0.5 ;
/*
2001-07-23 20:52:47 +00:00
Item . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
Item . touch = item_tfgoal_touch ;
Item . origin = Item . oldorigin ;
setmodel ( Item , Item . mdl ) ;
setorigin ( Item , Item . origin ) ;
2001-07-23 20:52:47 +00:00
sound ( Item , CHAN_VOICE , " items/itembk2.wav " , 1 , ATTN_NORM ) ;
2001-07-17 05:58:10 +00:00
*/
}
2001-07-23 20:52:47 +00:00
else if ( Item . goal_activation & TFGI_DROP )
2001-07-17 05:58:10 +00:00
{
tfgoalitem_drop ( Item ) ;
}
else
{
// Remove the Item
2001-11-02 17:00:52 +00:00
Item . owner = NIL ;
2001-07-17 05:58:10 +00:00
dremove ( Item ) ;
TeamFortress_SetSpeed ( AP ) ;
2003-12-10 03:07:19 +00:00
AP . effects | = EF_GlowColor ( AP ) ;
2001-07-17 05:58:10 +00:00
return ;
}
2001-11-02 17:00:52 +00:00
Item . owner = NIL ;
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed ( AP ) ;
2003-12-10 03:07:19 +00:00
AP . effects | = EF_GlowColor ( AP ) ;
2001-07-17 05:58:10 +00:00
return ;
}
// Return it to the starting point if the flag is set
if ( method = = 1 ) // Removed by a goal activation
{
/*
bprint ( Item . netname ) ;
bprint ( " " ) ;
bprint ( Item . mdl ) ;
bprint ( " " ) ;
bprint ( vtos ( Item . origin ) ) ;
bprint ( " " ) ;
bprint ( vtos ( Item . oldorigin ) ) ;
bprint ( " \n " ) ;
*/
2001-07-23 20:52:47 +00:00
if ( Item . goal_activation & TFGI_RETURN_GOAL )
2001-07-17 05:58:10 +00:00
{
DelayReturn = spawn ( ) ;
DelayReturn . enemy = Item ;
DelayReturn . think = ReturnItem ;
DelayReturn . nextthink = time + 0.5 ;
/*
Item . origin = Item . oldorigin ;
setorigin ( Item , Item . origin ) ;
2001-07-23 20:52:47 +00:00
Item . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
Item . touch = item_tfgoal_touch ;
setmodel ( Item , Item . mdl ) ;
2001-07-23 20:52:47 +00:00
sound ( Item , CHAN_VOICE , " items/itembk2.wav " , 1 , ATTN_NORM ) ;
2001-07-17 05:58:10 +00:00
// Restore a goal if needed
tfgoalitem_checkgoalreturn ( Item ) ;
*/
2001-11-02 17:00:52 +00:00
Item . owner = NIL ;
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed ( AP ) ;
2003-12-10 03:07:19 +00:00
AP . effects | = EF_GlowColor ( AP ) ;
2001-07-17 05:58:10 +00:00
return ;
}
// Don't remove it, since it may be given away again later
2001-07-23 20:52:47 +00:00
Item . solid = SOLID_NOT ;
2001-11-02 17:00:52 +00:00
Item . owner = NIL ;
2001-07-17 05:58:10 +00:00
TeamFortress_SetSpeed ( AP ) ;
2003-12-10 03:07:19 +00:00
AP . effects | = EF_GlowColor ( AP ) ;
2001-07-17 05:58:10 +00:00
return ;
}
RPrint ( " Invalid method passed into tfgoalitem_RemoveFromPlayer \n " ) ;
} ;
//=========================================================================
// A quick check to make sure the items is not in a wall
void ( ) tfgoalitem_dropthink =
{
local float pos ;
2001-07-23 20:52:47 +00:00
# ifdef MAP_DEBUG
2001-07-17 05:58:10 +00:00
RPrint ( " DropThink for " ) ;
RPrint ( self . netname ) ;
RPrint ( " \n " ) ;
# endif
// If the flag is set, remove it after 2 minutes
2001-07-23 20:52:47 +00:00
self . movetype = MOVETYPE_TOSS ;
2001-07-17 05:58:10 +00:00
if ( self . pausetime ! = 0 )
{
pos = pointcontents ( self . origin ) ; // find the location of the Item
2001-07-31 17:08:59 +00:00
if ( pos = = CONTENTS_SLIME )
2001-07-17 05:58:10 +00:00
self . nextthink = time + ( self . pausetime / 4 ) ;
2001-07-31 17:08:59 +00:00
else if ( pos = = CONTENTS_LAVA )
2001-07-17 05:58:10 +00:00
self . nextthink = time + 5 ;
2001-07-31 17:08:59 +00:00
else if ( pos = = CONTENTS_SOLID | | pos = = CONTENTS_SKY ) // oh shit!
2001-07-17 05:58:10 +00:00
self . nextthink = time + 2 ;
else
self . nextthink = time + self . pausetime ;
self . think = tfgoalitem_remove ;
}
} ;
//CH does same as above but sets origion when done.
void ( ) tfgoalitem_dropthink2 =
{
local float pos ;
2001-07-23 20:52:47 +00:00
# ifdef MAP_DEBUG
2001-07-17 05:58:10 +00:00
RPrint ( " DropThink for " ) ;
RPrint ( self . netname ) ;
RPrint ( " \n " ) ;
# endif
// If the flag is set, remove it after 2 minutes
2001-07-23 20:52:47 +00:00
self . movetype = MOVETYPE_TOSS ;
2001-07-17 05:58:10 +00:00
/* CH leave this as it is working code. that below this is a test, which seems to work well.
// if (self.pausetime != 0)
// {
pos = pointcontents ( self . origin ) ; // find the location of the Item
2001-07-31 17:08:59 +00:00
if ( pos = = CONTENTS_SLIME )
2001-07-17 05:58:10 +00:00
self . nextthink = time + ( self . pausetime / 4 ) ;
2001-07-31 17:08:59 +00:00
else if ( pos = = CONTENTS_LAVA )
2001-07-17 05:58:10 +00:00
self . nextthink = time + 5 ;
2001-07-31 17:08:59 +00:00
else if ( pos = = CONTENTS_SOLID | | pos = = CONTENTS_SKY ) // oh shit!
2001-07-17 05:58:10 +00:00
self . nextthink = time + 2 ;
else
self . nextthink = time + self . pausetime ;
self . think = tfgoalitem_remove ;
self . velocity = ' 0 0 0 ' ;
self . oldorigin = self . origin ;
// }
*/
// if (self.pausetime != 0)
// {
pos = pointcontents ( self . origin ) ; // find the location of the Item
2001-07-31 17:08:59 +00:00
if ( pos = = CONTENTS_SLIME )
2001-07-17 05:58:10 +00:00
setorigin ( self , self . oldorigin ) ;
2001-07-31 17:08:59 +00:00
else if ( pos = = CONTENTS_LAVA )
2001-07-17 05:58:10 +00:00
setorigin ( self , self . oldorigin ) ;
2001-07-31 17:08:59 +00:00
else if ( pos = = CONTENTS_SOLID | | pos = = CONTENTS_SKY ) // oh shit!
2001-07-17 05:58:10 +00:00
setorigin ( self , self . oldorigin ) ;
else
setorigin ( self , self . origin ) ;
self . velocity = ' 0 0 0 ' ;
self . oldorigin = self . origin ;
// }
} ;
//=========================================================================
// Drop the item just like a backpack
void ( entity Item ) tfgoalitem_drop =
{
local vector temp1 ;
local vector temp2 ;
2003-12-10 03:56:01 +00:00
Item . origin = Item . owner . origin ;
2001-07-17 05:58:10 +00:00
Item . velocity_z = 400 ;
Item . velocity_x = - 50 + ( random ( ) * 100 ) ;
Item . velocity_y = - 50 + ( random ( ) * 100 ) ;
2001-07-23 20:52:47 +00:00
Item . movetype = MOVETYPE_TOSS ;
2001-07-17 05:58:10 +00:00
//CH set solid state
2003-12-10 03:56:01 +00:00
//GR this can cause players to be trapped inside their items when they dropitems, do it later
#if 0
2001-07-23 20:52:47 +00:00
if ( Item . goal_activation & TFGI_GOAL_IS_SOLID )
Item . solid = SOLID_BBOX ;
2001-07-17 05:58:10 +00:00
else
2003-12-10 03:56:01 +00:00
# endif
2001-07-23 20:52:47 +00:00
Item . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
setorigin ( Item , Item . origin ) ;
//CH sets goal bounding box size
2001-09-30 22:38:44 +00:00
if ( Item . goal_min )
2001-07-17 05:58:10 +00:00
temp1 = Item . goal_min ;
else
temp1 = ' - 16 - 16 - 24 ' ;
2001-09-30 22:38:44 +00:00
if ( Item . goal_max )
2001-07-17 05:58:10 +00:00
temp2 = Item . goal_max ;
else
temp2 = ' 16 16 32 ' ;
setsize ( Item , temp1 , temp2 ) ; //CH sets box size from above
2001-09-30 22:38:44 +00:00
if ( Item . mdl )
2001-07-17 05:58:10 +00:00
setmodel ( Item , Item . mdl ) ;
2003-12-10 03:56:01 +00:00
if ( ! Item . owner . deadflag ) //checks for dropitems
2001-07-17 05:58:10 +00:00
{
2003-12-10 03:56:01 +00:00
makevectors ( Item . owner . v_angle ) ;
Item . velocity = v_forward * 400 + v_up * 200 ;
Item . nextthink = time + 0.5 ; //CH wait a sec then make it pickupable GR half a sec
2001-07-17 05:58:10 +00:00
Item . think = tfgoalitem_settouchandthink ;
}
else
{
Item . nextthink = time + 5.0 ; // give it five seconds
Item . think = tfgoalitem_dropthink ; // and then find where it ended up
2001-07-23 20:52:47 +00:00
Item . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
Item . touch = item_tfgoal_touch ;
2003-12-10 03:56:01 +00:00
if ( Item . goal_activation & TFGI_GOAL_IS_SOLID )
{
Item . solid = SOLID_BBOX ;
setorigin ( Item , Item . origin ) ;
}
2001-07-17 05:58:10 +00:00
}
} ;
//CH brings the item online after 1 sec
void ( ) tfgoalitem_settouchandthink =
{
self . nextthink = time + 4.0 ; // give it five seconds
self . think = tfgoalitem_dropthink ; // and then find where it ended up
2001-07-23 20:52:47 +00:00
self . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
self . touch = item_tfgoal_touch ;
2003-12-10 03:56:01 +00:00
if ( self . goal_activation & TFGI_GOAL_IS_SOLID )
{
self . solid = SOLID_BBOX ;
setorigin ( self , self . origin ) ;
}
2001-07-17 05:58:10 +00:00
} ;
//=========================================================================
// Remove the item, or Return it if needed
void ( ) tfgoalitem_remove =
{
local entity te ;
2001-07-23 20:52:47 +00:00
# ifdef MAP_DEBUG
2001-07-17 05:58:10 +00:00
RPrint ( " RemoveItem for " ) ;
RPrint ( self . netname ) ;
RPrint ( " ... " ) ;
# endif
// Has someone picked it up?
2001-07-23 20:52:47 +00:00
if ( self . goal_state = = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
return ;
// Should it be returned?
2001-07-23 20:52:47 +00:00
if ( self . goal_activation & TFGI_RETURN_REMOVE )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
# ifdef MAP_DEBUG
2001-07-17 05:58:10 +00:00
RPrint ( " Returned. \n " ) ;
# endif
//CH set solid state
2001-07-23 20:52:47 +00:00
if ( self . goal_activation & TFGI_GOAL_IS_SOLID )
self . solid = SOLID_BBOX ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
self . solid = SOLID_TRIGGER ;
self . movetype = MOVETYPE_NONE ;
2001-07-17 05:58:10 +00:00
self . touch = item_tfgoal_touch ;
self . origin = self . oldorigin ;
2001-09-30 22:38:44 +00:00
if ( self . mdl )
2001-07-17 05:58:10 +00:00
setmodel ( self , self . mdl ) ;
setorigin ( self , self . origin ) ;
2001-07-23 20:52:47 +00:00
sound ( self , CHAN_VOICE , " items/itembk2.wav " , 1 , ATTN_NORM ) ;
2001-07-17 05:58:10 +00:00
// Restore a goal if needed
tfgoalitem_checkgoalreturn ( self ) ;
//CH could it check origin again?? nah...
//CH a better question would be why does it need this to work right???
self . think = tfgoalitem_checkoriginagain ;
self . nextthink = time + 1 ;
// Do we need to do any CenterPrint2ing?
2001-09-30 22:38:44 +00:00
if ( self . noise3 | | self . noise4 )
2001-07-17 05:58:10 +00:00
{
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " player " ) ;
2001-07-17 05:58:10 +00:00
while ( te )
{
if ( te . team_no = = self . owned_by )
CenterPrint2 ( te , " \n \n \n " , self . noise3 ) ;
else // (te.team_no != self.owned_by)
CenterPrint2 ( te , " \n \n \n " , self . noise4 ) ;
te = find ( te , classname , " player " ) ;
}
}
return ;
}
2001-07-23 20:52:47 +00:00
# ifdef MAP_DEBUG
2001-07-17 05:58:10 +00:00
RPrint ( " Removed. \n " ) ;
# endif
dremove ( self ) ;
} ;
//===================
//CH i wonder what this does?
//CH WHY THE HELL DOES IT NEED THIS!!!!!!!
//CH first check
void ( ) tfgoalitem_checkoriginagain =
{
// RPrint("Check #1 for return goalitem\n");
2001-07-23 20:52:47 +00:00
if ( self . origin ! = self . oldorigin & & self . goal_state ! = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
{
self . origin = self . oldorigin ;
setorigin ( self , self . origin ) ;
self . think = tfgoalitem_checkoriginagain2 ;
self . nextthink = time + 1 ;
}
} ;
//===================
//CH second check
void ( ) tfgoalitem_checkoriginagain2 =
{
// RPrint("Check #2 for return goalitem\n");
2001-07-23 20:52:47 +00:00
if ( self . origin ! = self . oldorigin & & self . goal_state ! = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
{
self . origin = self . oldorigin ;
setorigin ( self , self . origin ) ;
self . think = tfgoalitem_checkoriginagain3 ;
self . nextthink = time + 1 ;
}
} ;
//===================
//CH third and final check
void ( ) tfgoalitem_checkoriginagain3 =
{
// RPrint("Check #3 for return goalitem\n");
2001-07-23 20:52:47 +00:00
if ( self . origin ! = self . oldorigin & & self . goal_state ! = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
{
self . origin = self . oldorigin ;
setorigin ( self , self . origin ) ;
}
} ;
//=========================================================================
// Activate a goal when this item is removed, if needed
void ( entity Item ) tfgoalitem_checkgoalreturn =
{
local entity te ;
// Do we need to activate a goal somewhere?
if ( Item . impulse ! = 0 )
{
// Find the goal
te = Findgoal ( Item . impulse ) ;
if ( te )
{
te = Findgoal ( Item . impulse ) ;
if ( te )
2001-11-02 17:00:52 +00:00
AttemptToActivate ( te , NIL , Item ) ;
2001-07-17 05:58:10 +00:00
}
}
} ;
//=========================================================================
// Displays the state of a GoalItem
void ( entity Goal , entity Player , entity Item ) DisplayItemStatus =
{
2001-07-23 20:52:47 +00:00
if ( Item . goal_state = = TFGS_ACTIVE )
2001-07-17 05:58:10 +00:00
{
if ( Player . team_no = = Item . owned_by )
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , Goal . team_str_carried ) ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , Goal . non_team_str_carried ) ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , " " ) ;
2001-07-17 05:58:10 +00:00
if ( Player = = Item . owner )
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , " You " ) ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , Item . owner . netname ) ;
2001-07-17 05:58:10 +00:00
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , " . " ) ;
2001-07-17 05:58:10 +00:00
}
else if ( Item . origin ! = Item . oldorigin )
{
if ( Player . team_no = = Item . owned_by )
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , Goal . team_str_moved ) ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , Goal . non_team_str_moved ) ;
2001-07-17 05:58:10 +00:00
}
else
{
if ( Player . team_no = = Item . owned_by )
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , Goal . team_str_home ) ;
2001-07-17 05:58:10 +00:00
else
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , Goal . non_team_str_home ) ;
2001-07-17 05:58:10 +00:00
}
/*CH prints out the origin and oldorigin via flaginfo
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , " \n " ) ;
2001-07-17 05:58:10 +00:00
ac = vtos ( Item . origin ) ;
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , ac ) ;
sprint ( Player , PRINT_HIGH , " " ) ;
2001-07-17 05:58:10 +00:00
ac = vtos ( Item . oldorigin ) ;
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , ac ) ;
2001-07-17 05:58:10 +00:00
*/
2001-07-23 20:52:47 +00:00
sprint ( Player , PRINT_HIGH , " \n " ) ;
2001-07-17 05:58:10 +00:00
} ;
//=========================================================================
// CTF SUPPORT
//=========================================================================
// Spawn Functions for CTF entities.
// Team 1 spawnpoints
void ( ) info_player_team1 =
{
2001-07-23 20:52:47 +00:00
CTF_Map = TRUE ;
2001-07-17 05:58:10 +00:00
// Convert to a TeamFortress TeamSpawn point
self . classname = " info_player_teamspawn " ;
// We swap them, so that the colors match ours
self . team_no = 2 ;
// Make this point remove itself after being spawned on
2001-07-23 20:52:47 +00:00
self . goal_effects = TFSP_REMOVESELF ;
2001-07-17 05:58:10 +00:00
self . team_str_home = " ts2 " ;
} ;
// Team 2 spawnpoints
void ( ) info_player_team2 =
{
2001-07-23 20:52:47 +00:00
CTF_Map = TRUE ;
2001-07-17 05:58:10 +00:00
// Convert to a TeamFortress TeamSpawn point
self . classname = " info_player_teamspawn " ;
// We swap them, so that the colors match ours
self . team_no = 1 ;
// Make this point remove itself after being spawned on
2001-07-23 20:52:47 +00:00
self . goal_effects = TFSP_REMOVESELF ;
2001-07-17 05:58:10 +00:00
self . team_str_home = " ts1 " ;
} ;
// Team 2 flag
void ( ) item_flag_team2 =
{
local entity dp ;
2001-07-23 20:52:47 +00:00
CTF_Map = TRUE ;
2001-07-17 05:58:10 +00:00
precache_model ( " progs/w_s_key.mdl " ) ;
precache_sound ( " ogre/ogwake.wav " ) ;
precache_sound ( " boss2/pop2.wav " ) ;
// Convert the flag to a TeamFortress Goal Item
self . classname = " item_tfgoal " ;
self . netname = " Team 1 Flag " ;
self . broadcast = " <20> <> <EFBFBD> the enemy team's flag! \n " ;
self . deathtype = " You've got the enemy flag! \n " ;
self . noise = " ogre/ogwake.wav " ;
self . mdl = " progs/tf_flag.mdl " ;
self . skin = 0 ;
setmodel ( self , self . mdl ) ;
2001-07-23 20:52:47 +00:00
self . goal_no = CTF_FLAG1 ;
self . goal_activation = TFGI_GLOW | TFGI_DROP | TFGI_REMOVE | TFGI_RETURN_REMOVE | TFGI_RETURN_GOAL | TFGI_ITEMGLOWS ;
2001-07-17 05:58:10 +00:00
self . goal_effects = 1 ;
self . pausetime = 128 ;
setsize ( self , ' - 16 - 16 - 24 ' , ' 16 16 32 ' ) ;
self . touch = item_tfgoal_touch ;
2001-07-23 20:52:47 +00:00
self . goal_state = TFGS_INACTIVE ;
self . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
setorigin ( self , self . origin ) ;
self . nextthink = time + 0.2 ; // items start after other solids
self . think = TF_PlaceItem ;
// Create the dropoff point Goal
dp = spawn ( ) ;
dp . origin = self . origin ;
dp . classname = " info_tfgoal " ;
dp . goal_activation = 1 ;
dp . team_no = 1 ;
2001-07-23 20:52:47 +00:00
dp . items_allowed = CTF_FLAG2 ;
dp . goal_no = CTF_DROPOFF1 ;
2001-07-17 05:58:10 +00:00
dp . goal_effects = 3 ;
dp . broadcast = " <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the enemy flag! \n " ;
dp . message = " You <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the enemy flag! \n " ;
dp . noise = " boss2/pop2.wav " ;
2001-07-23 20:52:47 +00:00
dp . goal_result = TFGR_ADD_BONUSES ;
dp . activate_goal_no = CTF_SCORE1 ;
dp . axhitme = CTF_FLAG2 ;
2001-07-17 05:58:10 +00:00
dp . count = 10 ;
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
dp . frags = 0 ;
2001-07-23 20:52:47 +00:00
dp . solid = SOLID_TRIGGER ;
dp . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
setsize ( dp , ' - 16 - 16 - 24 ' , ' 16 16 32 ' ) ;
dp . nextthink = time + 0.2 ; // goals start after other solids
dp . think = TF_PlaceGoal ;
// Create the extra scoring goal
dp = spawn ( ) ;
dp . origin = dp . origin ;
dp . classname = " info_tfgoal " ;
dp . goal_effects = 1 ;
dp . frags = 5 ;
dp . goal_activation = 0 ;
2001-07-23 20:52:47 +00:00
dp . goal_no = CTF_SCORE1 ;
dp . solid = SOLID_NOT ;
dp . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
setsize ( dp , ' - 16 - 16 - 24 ' , ' 16 16 32 ' ) ;
dp . nextthink = time + 0.2 ; // goals start after other solids
dp . think = TF_PlaceGoal ;
} ;
// Team 1 flag
void ( ) item_flag_team1 =
{
local entity dp ;
2001-07-23 20:52:47 +00:00
CTF_Map = TRUE ;
2001-07-17 05:58:10 +00:00
precache_model ( " progs/tf_flag.mdl " ) ;
precache_sound ( " ogre/ogwake.wav " ) ;
precache_sound ( " boss2/pop2.wav " ) ;
// Convert the flag to a TeamFortress Goal Item
self . classname = " item_tfgoal " ;
self . netname = " Team 2 Flag " ;
self . broadcast = " <20> <> <EFBFBD> the enemy team's flag! \n " ;
self . deathtype = " You've got the enemy flag! \n " ;
self . noise = " ogre/ogwake.wav " ;
self . mdl = " progs/tf_flag.mdl " ;
setmodel ( self , self . mdl ) ;
self . skin = 1 ;
2001-07-23 20:52:47 +00:00
self . goal_no = CTF_FLAG2 ;
self . goal_activation = TFGI_GLOW | TFGI_DROP | TFGI_REMOVE | TFGI_RETURN_REMOVE | TFGI_RETURN_GOAL | TFGI_ITEMGLOWS ;
2001-07-17 05:58:10 +00:00
self . goal_effects = 1 ;
self . pausetime = 128 ;
setsize ( self , ' - 16 - 16 - 24 ' , ' 16 16 32 ' ) ;
self . touch = item_tfgoal_touch ;
2001-07-23 20:52:47 +00:00
self . goal_state = TFGS_INACTIVE ;
self . solid = SOLID_TRIGGER ;
2001-07-17 05:58:10 +00:00
setorigin ( self , self . origin ) ;
self . nextthink = time + 0.2 ; // items start after other solids
self . think = TF_PlaceItem ;
// Create the dropoff point Goal
dp = spawn ( ) ;
dp . origin = self . origin ;
dp . classname = " info_tfgoal " ;
dp . goal_activation = 1 ;
dp . team_no = 2 ;
2001-07-23 20:52:47 +00:00
dp . items_allowed = CTF_FLAG1 ;
dp . goal_no = CTF_DROPOFF2 ;
2001-07-17 05:58:10 +00:00
dp . goal_effects = 3 ;
dp . broadcast = " <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the enemy flag! \n " ;
dp . message = " You <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> the enemy flag! \n " ;
dp . noise = " boss2/pop2.wav " ;
2001-07-23 20:52:47 +00:00
dp . goal_result = TFGR_ADD_BONUSES ;
dp . activate_goal_no = CTF_SCORE2 ;
dp . axhitme = CTF_FLAG1 ;
2001-07-17 05:58:10 +00:00
dp . count = 10 ;
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
dp . frags = 0 ;
2001-07-23 20:52:47 +00:00
dp . solid = SOLID_TRIGGER ;
dp . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
setsize ( dp , ' - 16 - 16 - 24 ' , ' 16 16 32 ' ) ;
dp . nextthink = time + 0.2 ; // goals start after other solids
dp . think = TF_PlaceGoal ;
// Create the extra scoring goal
dp = spawn ( ) ;
dp . origin = dp . origin ;
dp . classname = " info_tfgoal " ;
dp . goal_effects = 1 ;
dp . frags = 5 ;
dp . goal_activation = 0 ;
2001-07-23 20:52:47 +00:00
dp . goal_no = CTF_SCORE2 ;
dp . solid = SOLID_NOT ;
dp . goal_state = TFGS_INACTIVE ;
2001-07-17 05:58:10 +00:00
setsize ( dp , ' - 16 - 16 - 24 ' , ' 16 16 32 ' ) ;
dp . nextthink = time + 0.2 ; // goals start after other solids
dp . think = TF_PlaceGoal ;
} ;
//=========================================================================
// Checks to make sure either flag hasn't got into bad state, and if
// it has, returns it.
void ( ) CTF_FlagCheck =
{
local entity te ;
local float flagcount , pos ;
flagcount = 0 ;
2001-11-02 17:00:52 +00:00
te = find ( NIL , classname , " item_tfgoal " ) ;
while ( te )
2001-07-17 05:58:10 +00:00
{
2001-07-23 20:52:47 +00:00
if ( te . goal_no = = CTF_FLAG1 )
2001-07-17 05:58:10 +00:00
{
pos = pointcontents ( te . origin ) ; // find the location of the Flag
2001-07-31 17:08:59 +00:00
if ( pos = = CONTENTS_SOLID | | pos = = CONTENTS_SKY )
2001-07-17 05:58:10 +00:00
{
RPrint ( " *****BUG***** \n Flag(s) outside world. \n Please report this. \n " ) ;
te . nextthink = time + 0.2 ;
te . think = tfgoalitem_remove ;
}
flagcount = flagcount + 1 ;
}
2001-07-23 20:52:47 +00:00
else if ( te . goal_no = = CTF_FLAG2 )
2001-07-17 05:58:10 +00:00
{
pos = pointcontents ( te . origin ) ; // find the location of the Flag
2001-07-31 17:08:59 +00:00
if ( pos = = CONTENTS_SOLID | | pos = = CONTENTS_SKY )
2001-07-17 05:58:10 +00:00
{
RPrint ( " *****BUG***** \n Flag(s) outside world. \n Please report this. \n " ) ;
te . nextthink = time + 0.2 ;
te . think = tfgoalitem_remove ;
}
flagcount = flagcount + 1 ;
}
te = find ( te , classname , " item_tfgoal " ) ;
}
if ( flagcount ! = 2 )
RPrint ( " *****BUG***** \n Flag(s) missing. \n Please report this. \n " ) ;
self . nextthink = time + 30 ;
} ;