2018-06-28 18:34:52 +00:00
// DisplayName = Capture the Flag
//--- GAME RULES BEGIN ---
//Prevent enemy from capturing your flag
2022-02-18 19:34:07 +00:00
//Score one point for grabbing the enemy's flag
2018-06-28 18:34:52 +00:00
//To capture, your flag must be at its stand
//Score 100 points each time enemy flag is captured
//--- GAME RULES END ---
//exec the AI scripts
exec ( "scripts/aiCTF.cs" ) ;
2025-05-14 18:51:26 +00:00
//Time for auto overtime sudden-death mode
$ CTF : : Overtime = 5 ; //5 Minutes, 0 to disable
2018-06-28 18:34:52 +00:00
//-- tracking ---
function CTFGame : : initGameVars ( % game )
{
2022-02-18 19:34:07 +00:00
// ---------------------------------------------------
2018-06-28 18:34:52 +00:00
// z0dd - ZOD, 9/29/02. Removed T2 demo code from here
% game . SCORE_PER_SUICIDE = 0 ; // z0dd - ZOD, 8/19/02. No penalty for suicide! Was -10
% game . SCORE_PER_TEAMKILL = - 10 ;
2022-02-18 19:34:07 +00:00
% game . SCORE_PER_DEATH = 0 ;
2018-06-28 18:34:52 +00:00
% game . SCORE_PER_TK_DESTROY = - 10 ; // z0dd - ZOD, 10/03/02. Penalty for TKing equiptment.
2022-02-18 19:34:07 +00:00
% game . SCORE_PER_KILL = 10 ;
2018-06-28 18:34:52 +00:00
% game . SCORE_PER_PLYR_FLAG_CAP = 30 ;
% game . SCORE_PER_PLYR_FLAG_TOUCH = 20 ;
% game . SCORE_PER_TEAM_FLAG_CAP = 100 ;
% game . SCORE_PER_TEAM_FLAG_TOUCH = 1 ;
% game . SCORE_PER_ESCORT_ASSIST = 5 ;
% game . SCORE_PER_HEADSHOT = 1 ;
% game . SCORE_PER_REARSHOT = 1 ; // z0dd - ZOD, 8/25/02. Added Lance rear shot messages
2018-09-26 05:01:41 +00:00
% game . SCORE_PER_MIDAIR = 1 ; // Added Chocotaco. From sctf
2018-06-28 18:34:52 +00:00
% game . SCORE_PER_TURRET_KILL = 10 ; // controlled
% game . SCORE_PER_TURRET_KILL_AUTO = 5 ; // uncontrolled, z0dd - ZOD, 5/27/03. More points, was 3
2022-02-18 19:34:07 +00:00
% game . SCORE_PER_FLAG_DEFEND = 5 ;
2018-06-28 18:34:52 +00:00
% game . SCORE_PER_CARRIER_KILL = 5 ;
% game . SCORE_PER_FLAG_RETURN = 10 ;
% game . SCORE_PER_STALEMATE_RETURN = 15 ;
% game . SCORE_PER_GEN_DEFEND = 5 ;
% game . SCORE_PER_DESTROY_GEN = 10 ;
% game . SCORE_PER_DESTROY_SENSOR = 4 ;
% game . SCORE_PER_DESTROY_TURRET = 5 ;
% game . SCORE_PER_DESTROY_ISTATION = 2 ;
% game . SCORE_PER_DESTROY_VSTATION = 5 ;
% game . SCORE_PER_DESTROY_MPBTSTATION = 3 ; // z0dd - ZOD, 4/24/02. MPB Teleporter
% game . SCORE_PER_DESTROY_SOLAR = 5 ;
% game . SCORE_PER_DESTROY_SENTRY = 4 ;
% game . SCORE_PER_DESTROY_DEP_SENSOR = 1 ;
% game . SCORE_PER_DESTROY_DEP_INV = 2 ;
% game . SCORE_PER_DESTROY_DEP_TUR = 3 ;
% game . SCORE_PER_DESTROY_SHRIKE = 5 ;
% game . SCORE_PER_DESTROY_BOMBER = 8 ;
% game . SCORE_PER_DESTROY_TRANSPORT = 5 ;
% game . SCORE_PER_DESTROY_WILDCAT = 5 ;
% game . SCORE_PER_DESTROY_TANK = 8 ;
% game . SCORE_PER_DESTROY_MPB = 12 ;
% game . SCORE_PER_PASSENGER = 2 ;
% game . SCORE_PER_REPAIR_GEN = 8 ;
% game . SCORE_PER_REPAIR_SENSOR = 1 ;
% game . SCORE_PER_REPAIR_TURRET = 4 ;
% game . SCORE_PER_REPAIR_ISTATION = 2 ;
% game . SCORE_PER_REPAIR_VSTATION = 4 ;
% game . SCORE_PER_REPAIR_MPBTSTATION = 3 ; // z0dd - ZOD, 4/24/02. MPB Teleporter
% game . SCORE_PER_REPAIR_SOLAR = 4 ;
% game . SCORE_PER_REPAIR_SENTRY = 2 ;
% game . SCORE_PER_REPAIR_DEP_SEN = 1 ; // z0dd - ZOD, 4/24/02. Deployed sensors
% game . SCORE_PER_REPAIR_DEP_TUR = 3 ;
% game . SCORE_PER_REPAIR_DEP_INV = 2 ;
% game . FLAG_RETURN_DELAY = 45 * 1000 ;
% game . TIME_CONSIDERED_FLAGCARRIER_THREAT = 3 * 1000 ; //after damaging enemy flag carrier
% game . RADIUS_GEN_DEFENSE = 20 ; //meters
2022-02-18 19:34:07 +00:00
% game . RADIUS_FLAG_DEFENSE = 20 ; //meters
2018-06-28 18:34:52 +00:00
% game . TOUCH_DELAY_MS = 20000 ; //20 secs
% game . fadeTimeMS = 2000 ;
% game . notifyMineDist = 7.5 ;
% game . stalemate = false ;
% game . stalemateObjsVisible = false ;
% game . stalemateTimeMS = 60000 ;
% game . stalemateFreqMS = 15000 ;
% game . stalemateDurationMS = 6000 ;
2022-02-18 19:34:07 +00:00
// ---------------------------------------------------
2018-06-28 18:34:52 +00:00
// z0dd - ZOD, 9/29/02. Removed T2 demo code from here
}
package CTFGame
{
function ShapeBaseData : : onDestroyed ( % data , % obj , % prevstate )
{
// z0dd - ZOD, 5/27/03. Total re-write
% scorer = % obj . lastDamagedBy ;
if ( ! isObject ( % scorer ) )
return ;
if ( ( % scorer . getType ( ) & $ TypeMasks : : GameBaseObjectType ) & & % scorer . getDataBlock ( ) . catagory $ = "Vehicles" )
{
% name = % scorer . getDatablock ( ) . getName ( ) ;
if ( % name $ = "BomberFlyer" | | % name $ = "AssaultVehicle" )
% gunnerNode = 1 ;
else
% gunnerNode = 0 ;
if ( % scorer . getMountNodeObject ( % gunnerNode ) )
{
% destroyer = % scorer . getMountNodeObject ( % gunnerNode ) . client ;
% scorer = % destroyer ;
% damagingTeam = % scorer . team ;
}
}
else if ( % scorer . getClassName ( ) $ = "Turret" )
{
if ( % scorer . getControllingClient ( ) )
{
// manned turret
% destroyer = % scorer . getControllingClient ( ) ;
% scorer = % destroyer ;
% damagingTeam = % scorer . team ;
}
else
% scorer = % scorer . owner ; // unmanned turret
}
if ( ! % damagingTeam )
% damagingTeam = % scorer . team ;
if ( % damagingTeam ! = % obj . team )
{
if ( ! % obj . soiledByEnemyRepair )
Game . awardScoreStaticShapeDestroy ( % scorer , % obj ) ;
}
else
{
if ( ! % obj . getDataBlock ( ) . deployedObject )
Game . awardScoreTkDestroy ( % scorer , % obj ) ;
return ;
}
}
function ShapeBaseData : : onDisabled ( % data , % obj )
{
% obj . wasDisabled = true ;
Parent : : onDisabled ( % data , % obj ) ;
}
function RepairGunImage : : onRepair ( % this , % obj , % slot )
{
Parent : : onRepair ( % this , % obj , % slot ) ;
% target = % obj . repairing ;
if ( % target & & % target . team ! = % obj . team )
{
//error("Enemy stuff("@%obj@") is being repaired (by "@%target@")");
% target . soiledByEnemyRepair = true ;
}
}
function Flag : : objectiveInit ( % data , % flag )
{
if ( ! % flag . isTeamSkinned )
{
% pos = % flag . getTransform ( ) ;
% group = % flag . getGroup ( ) ;
}
% flag . originalPosition = % flag . getTransform ( ) ;
$ flagPos [ % flag . team ] = % flag . originalPosition ;
% flag . isHome = true ;
% flag . carrier = "" ;
% flag . grabber = "" ;
setTargetSkin ( % flag . getTarget ( ) , CTFGame : : getTeamSkin ( CTFGame , % flag . team ) ) ;
setTargetSensorGroup ( % flag . getTarget ( ) , % flag . team ) ;
setTargetAlwaysVisMask ( % flag . getTarget ( ) , 0x7 ) ;
setTargetRenderMask ( % flag . getTarget ( ) , getTargetRenderMask ( % flag . getTarget ( ) ) | 0x2 ) ;
% flag . scopeWhenSensorVisible ( true ) ;
$ flagStatus [ % flag . team ] = "<At Base>" ;
//Point the flag and stand at each other
% group = % flag . getGroup ( ) ;
% count = % group . getCount ( ) ;
% flag . stand = "" ;
for ( % i = 0 ; % i < % count ; % i + + )
{
% this = % group . getObject ( % i ) ;
//---------------------------------------------------------------------------------------------------------------------------
// z0dd - ZOD, 3/16/02. Added TSStatic, console spam fix.
if ( % this . getClassName ( ) ! $ = "InteriorInstance" & & % this . getClassName ( ) ! $ = "SimGroup" & & % this . getClassName ( ) ! $ = "TSStatic" )
{
if ( % this . getDataBlock ( ) . getName ( ) $ = "ExteriorFlagStand" )
{
% flag . stand = % this ;
% this . flag = % flag ;
}
}
}
// set the nametag on the target
setTargetName ( % flag . getTarget ( ) , CTFGame : : getTeamName ( CTFGame , % flag . team ) ) ;
// create a marker on this guy
% flag . waypoint = new MissionMarker ( ) {
position = % flag . getTransform ( ) ;
dataBlock = "FlagMarker" ;
} ;
MissionCleanup . add ( % flag . waypoint ) ;
// create a target for this (there is no MissionMarker::onAdd script call)
% target = createTarget ( % flag . waypoint , CTFGame : : getTeamName ( CTFGame , % flag . team ) , "" , "" , ' Base ' , % flag . team , 0 ) ;
setTargetAlwaysVisMask ( % target , 0xffffffff ) ;
//store the flag in an array
$ TeamFlag [ % flag . team ] = % flag ;
// --------------------------------------------------------
// z0dd - ZOD, 5/26/02. Don't let flag hover over defenders
% flag . static = true ;
// -------------------------------------------------------------------------------------------
// z0dd - ZOD, 10/03/02. Use triggers for flags that are at home, hack for flag collision bug.
% flag . trigger = new Trigger ( )
{
dataBlock = flagTrigger ;
polyhedron = "-0.6 0.6 0.1 1.2 0.0 0.0 0.0 -1.2 0.0 0.0 0.0 2.5" ;
position = % flag . position ;
rotation = % flag . rotation ;
} ;
MissionCleanup . add ( % flag . trigger ) ;
% flag . trigger . flag = % flag ;
// -------------------------------------------------------------------------------------------
}
function Flag : : onEnterLiquid ( % data , % obj , % coverage , % type )
{
if ( % type > 3 ) // 1-3 are water, 4+ is lava and quicksand(?)
{
//error("flag("@%obj@") is in liquid type" SPC %type);
2022-02-18 19:34:07 +00:00
// Changed slightly so this can be cancelled if it leaves the
2018-06-28 18:34:52 +00:00
// lava before its supposed to be returned - Ilys
% obj . lavaEnterThread = Game . schedule ( 3000 , "flagReturn" , % obj ) ;
}
}
function Flag : : onLeaveLiquid ( % data , % obj , % type )
{
// Added to stop the flag retrun if it slides out of the lava - Ilys
2022-02-18 19:34:07 +00:00
if ( isEventPending ( % obj . lavaEnterThread ) )
2018-06-28 18:34:52 +00:00
cancel ( % obj . lavaEnterThread ) ;
}
2018-09-26 05:01:41 +00:00
2018-06-28 18:34:52 +00:00
} ;
//--------------------------------------------------------------------------
// need to have this for the corporate maps which could not be fixed
function SimObject : : clearFlagWaypoints ( % this )
{
}
function WayPoint : : clearFlagWaypoints ( % this )
{
logEcho ( "Removing flag waypoint: " @ % this ) ;
if ( % this . nameTag $ = "Flag" )
% this . delete ( ) ;
}
function SimGroup : : clearFlagWaypoints ( % this )
{
for ( % i = % this . getCount ( ) - 1 ; % i > = 0 ; % i - - )
% this . getObject ( % i ) . clearFlagWaypoints ( ) ;
}
function CTFGame : : getTeamSkin ( % game , % team )
{
if ( $ host : : tournamentMode ) // z0dd - ZOD, 9/29/02. Removed T2 demo code from here
{
return $ teamSkin [ % team ] ;
}
else
{
//error("CTFGame::getTeamSkin");
if ( ! $ host : : useCustomSkins )
{
% terrain = MissionGroup . musicTrack ;
//error("Terrain type is: " SPC %terrain);
switch $ ( % terrain )
{
case "lush" :
if ( % team = = 1 )
% skin = ' beagle ' ;
else if ( % team = = 2 )
% skin = ' dsword ' ;
else % skin = ' base ' ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
case "badlands" :
if ( % team = = 1 )
% skin = ' swolf ' ;
else if ( % team = = 2 )
% skin = ' dsword ' ;
else % skin = ' base ' ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
case "ice" :
if ( % team = = 1 )
% skin = ' swolf ' ;
else if ( % team = = 2 )
% skin = ' beagle ' ;
else % skin = ' base ' ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
case "desert" :
if ( % team = = 1 )
% skin = ' cotp ' ;
else if ( % team = = 2 )
% skin = ' beagle ' ;
else % skin = ' base ' ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
case "Volcanic" :
if ( % team = = 1 )
% skin = ' dsword ' ;
else if ( % team = = 2 )
% skin = ' cotp ' ;
else % skin = ' base ' ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
default :
if ( % team = = 2 )
% skin = ' baseb ' ;
else % skin = ' base ' ;
}
}
else % skin = $ teamSkin [ % team ] ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
//error("%skin = " SPC getTaggedString(%skin));
return % skin ;
}
}
function CTFGame : : getTeamName ( % game , % team )
{
// ---------------------------------------------------
// z0dd - ZOD 3/30/02. Only display default team names
//if ( isDemo() || $host::tournamentMode)
return $ TeamName [ % team ] ;
// ---------------------------------------------------
}
//--------------------------------------------------------------------------
function CTFGame : : missionLoadDone ( % game )
{
//default version sets up teams - must be called first...
DefaultGame : : missionLoadDone ( % game ) ;
for ( % i = 1 ; % i < ( % game . numTeams + 1 ) ; % i + + )
$ teamScore [ % i ] = 0 ;
2022-02-18 19:34:07 +00:00
// remove
2018-06-28 18:34:52 +00:00
MissionGroup . clearFlagWaypoints ( ) ;
//reset some globals, just in case...
$ dontScoreTimer [ 1 ] = false ;
$ dontScoreTimer [ 2 ] = false ;
echo ( "starting camp thread..." ) ;
% game . campThread_1 = schedule ( 1000 , 0 , "checkVehicleCamping" , 1 ) ;
% game . campThread_2 = schedule ( 1000 , 0 , "checkVehicleCamping" , 2 ) ;
}
function CTFGame : : playerTouchFlag ( % game , % player , % flag )
{
% client = % player . client ;
if ( ( % flag . carrier $ = "" ) & & ( % player . getState ( ) ! $ = "Dead" ) )
{
// z0dd - ZOD, 5/07/04. Cancel the lava return.
2025-05-14 18:51:26 +00:00
if ( isEventPending ( % flag . lavaEnterThread ) )
cancel ( % flag . lavaEnterThread ) ;
2018-06-28 18:34:52 +00:00
//flag isn't held and has been touched by a live player
if ( % client . team = = % flag . team )
% game . playerTouchOwnFlag ( % player , % flag ) ;
else
% game . playerTouchEnemyFlag ( % player , % flag ) ;
}
// toggle visibility of the flag
setTargetRenderMask ( % flag . waypoint . getTarget ( ) , % flag . isHome ? 0 : 1 ) ;
}
function CTFGame : : playerTouchOwnFlag ( % game , % player , % flag )
2022-02-18 19:34:07 +00:00
{
2018-06-28 18:34:52 +00:00
if ( % flag . isHome )
{
if ( % player . holdingFlag ! $ = "" )
% game . flagCap ( % player ) ;
}
else
% game . flagReturn ( % flag , % player ) ;
//call the AI function
2022-02-18 19:34:07 +00:00
% game . AIplayerTouchOwnFlag ( % player , % flag ) ;
2018-06-28 18:34:52 +00:00
}
function CTFGame : : playerTouchEnemyFlag ( % game , % player , % flag )
{
// ---------------------------------------------------------------
// z0dd, ZOD - 9/27/02. Player must wait to grab after throwing it
if ( ( % player . flagTossWait ! $ = "" ) & & % player . flagTossWait )
return false ;
// ---------------------------------------------------------------
cancel ( % flag . searchSchedule ) ; // z0dd - ZOD, 9/28/02. Hack for flag collision bug. SquirrelOfDeath, 10/02/02: Moved from PlayerTouchFlag
cancel ( % game . updateFlagThread [ % flag ] ) ; // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater
% game . flagHeldTime [ % flag ] = getSimTime ( ) ; // z0dd - ZOD, 8/15/02. Store time player grabbed flag.
% client = % player . client ;
% player . holdingFlag = % flag ; //%player has this flag
% flag . carrier = % player ; //this %flag is carried by %player
2022-02-18 19:34:07 +00:00
2020-03-23 20:23:42 +00:00
// attach the camera to the flag.carrier
2021-03-16 17:01:21 +00:00
if ( $ Observers )
2020-03-23 20:23:42 +00:00
{
2021-03-16 17:01:21 +00:00
for ( % i = 0 ; % i < ClientGroup . getCount ( ) ; % i + + )
{
% cl = ClientGroup . getObject ( % i ) ;
if ( % cl . team < = 0 & & % cl . observingFlag & & % cl . flagObsTeam = = % flag . team )
observeFlag ( % cl , % player . client , 2 , % flag . team ) ;
}
2020-03-23 20:23:42 +00:00
}
2022-02-18 19:34:07 +00:00
2020-03-23 20:23:42 +00:00
% player . mountImage ( FlagImage , $ FlagSlot , true , % game . getTeamSkin ( % flag . team ) ) ;
% game . playerGotFlagTarget ( % player ) ;
2022-02-18 19:34:07 +00:00
2020-03-23 20:23:42 +00:00
//only cancel the return timer if the player is in bounds...
if ( ! % client . outOfBounds )
{
cancel ( $ FlagReturnTimer [ % flag ] ) ;
$ FlagReturnTimer [ % flag ] = "" ;
}
2018-06-28 18:34:52 +00:00
% player . mountImage ( FlagImage , $ FlagSlot , true , % game . getTeamSkin ( % flag . team ) ) ;
% game . playerGotFlagTarget ( % player ) ;
//only cancel the return timer if the player is in bounds...
if ( ! % client . outOfBounds )
{
cancel ( $ FlagReturnTimer [ % flag ] ) ;
$ FlagReturnTimer [ % flag ] = "" ;
}
//if this flag was "at home", see if both flags have now been taken
if ( % flag . isHome )
{
// tiebreaker score
% game . awardScoreFlagTouch ( % client , % flag ) ;
% startStalemate = false ;
if ( $ TeamFlag [ 1 ] = = % flag )
% startStalemate = ! $ TeamFlag [ 2 ] . isHome ;
else
% startStalemate = ! $ TeamFlag [ 1 ] . isHome ;
if ( % startStalemate )
% game . stalemateSchedule = % game . schedule ( % game . stalemateTimeMS , beginStalemate ) ;
2020-03-23 20:23:42 +00:00
}
2018-06-28 18:34:52 +00:00
% flag . hide ( true ) ;
2022-02-18 19:34:07 +00:00
% flag . startFade ( 0 , 0 , false ) ;
2018-06-28 18:34:52 +00:00
% flag . isHome = false ;
2022-07-15 20:28:01 +00:00
% flag . setVelocity ( "0 0 0" ) ;
2018-06-28 18:34:52 +00:00
if ( % flag . stand )
% flag . stand . getDataBlock ( ) . onFlagTaken ( % flag . stand ) ; //animate, if exterior stand
$ flagStatus [ % flag . team ] = % client . nameBase ;
% teamName = % game . getTeamName ( % flag . team ) ;
2022-02-18 19:34:07 +00:00
2020-03-25 03:13:46 +00:00
if ( % grabspeed )
{
2022-02-18 18:30:44 +00:00
messageTeamExcept ( % client , ' MsgCTFFlagTaken ' , ' \ c2Teammate % 1 took the % 2 flag . ( Speed : % 5 Kph ) ~ wfx / misc / flag_snatch . wav ' , % client . name , % teamName , % flag . team , % client . nameBase , % grabspeed ) ;
messageTeam ( % flag . team , ' MsgCTFFlagTaken ' , ' \ c2Your flag has been taken by % 1 ! ( Speed : % 5 Kph ) ~ wfx / misc / flag_taken . wav ' , % client . name , 0 , % flag . team , % client . nameBase , % grabspeed ) ;
messageTeam ( 0 , ' MsgCTFFlagTaken ' , ' \ c2 % 1 took the % 2 flag . ( Speed : % 5 Kph ) ~ wfx / misc / flag_snatch . wav ' , % client . name , % teamName , % flag . team , % client . nameBase , % grabspeed ) ;
messageClient ( % client , ' MsgCTFFlagTaken ' , ' \ c2You took the % 2 flag . ( Speed : % 5 Kph ) ~ wfx / misc / flag_snatch . wav ' , % client . name , % teamName , % flag . team , % client . nameBase , % grabspeed ) ;
2020-03-26 03:26:13 +00:00
if ( % grabspeed > 300 )
messageAll ( ' ' , "~wfx/Bonuses/high-level4-blazing.wav" ) ;
2020-03-25 03:13:46 +00:00
}
else
{
messageTeamExcept ( % client , ' MsgCTFFlagTaken ' , ' \ c2Teammate % 1 took the % 2 flag . ~ wfx / misc / flag_snatch . wav ' , % client . name , % teamName , % flag . team , % client . nameBase ) ;
messageTeam ( % flag . team , ' MsgCTFFlagTaken ' , ' \ c2Your flag has been taken by % 1 ! ~ wfx / misc / flag_taken . wav ' , % client . name , 0 , % flag . team , % client . nameBase ) ;
messageTeam ( 0 , ' MsgCTFFlagTaken ' , ' \ c2 % 1 took the % 2 flag . ~ wfx / misc / flag_snatch . wav ' , % client . name , % teamName , % flag . team , % client . nameBase ) ;
messageClient ( % client , ' MsgCTFFlagTaken ' , ' \ c2You took the % 2 flag . ~ wfx / misc / flag_snatch . wav ' , % client . name , % teamName , % flag . team , % client . nameBase ) ;
}
2020-03-25 03:19:23 +00:00
logEcho ( % client . nameBase @" (pl " @ % player @"/cl " @ % client @") took team " @ % flag . team @" flag (" @ % grabspeed @")" ) ; // MP: 6/15/2011 added grabspeed.
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
//call the AI function
% game . AIplayerTouchEnemyFlag ( % player , % flag ) ;
//if the player is out of bounds, then in 3 seconds, it should be thrown back towards the in bounds area...
if ( % client . outOfBounds )
% game . schedule ( 3000 , "boundaryLoseFlag" , % player ) ;
}
function CTFGame : : playerGotFlagTarget ( % game , % player )
{
% player . scopeWhenSensorVisible ( true ) ;
% target = % player . getTarget ( ) ;
setTargetRenderMask ( % target , getTargetRenderMask ( % target ) | 0x2 ) ;
if ( % game . stalemateObjsVisible )
setTargetAlwaysVisMask ( % target , 0x7 ) ;
}
function CTFGame : : playerLostFlagTarget ( % game , % player )
{
% player . scopeWhenSensorVisible ( false ) ;
% target = % player . getTarget ( ) ;
setTargetRenderMask ( % target , getTargetRenderMask ( % target ) & ~ 0x2 ) ;
// clear his always vis target mask
setTargetAlwaysVisMask ( % target , ( 1 < < getTargetSensorGroup ( % target ) ) ) ;
}
//----------------------------------------------------------------------------------------
// z0dd - ZOD, 8/4/02: KineticPoet's flag updater code
function CTFGame : : updateFlagTransform ( % game , % flag )
{
% flag . setTransform ( % flag . getTransform ( ) ) ;
2025-01-22 01:00:28 +00:00
% game . updateFlagThread [ % flag ] = % game . schedule ( 100 , "updateFlagTransform" , % flag ) ;
2018-06-28 18:34:52 +00:00
}
//----------------------------------------------------------------------------------------
function CTFGame : : playerDroppedFlag ( % game , % player )
{
% client = % player . client ;
% flag = % player . holdingFlag ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
% game . updateFlagTransform ( % flag ) ; // z0dd - ZOD, 8/4/02, Call to KineticPoet's flag updater
% held = % game . formatTime ( getSimTime ( ) - % game . flagHeldTime [ % flag ] , false ) ; // z0dd - ZOD, 8/15/02. How long did player hold flag?
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
% game . playerLostFlagTarget ( % player ) ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
% player . holdingFlag = "" ; //player isn't holding a flag anymore
2022-02-18 19:34:07 +00:00
% flag . carrier = "" ; //flag isn't held anymore
2018-06-28 18:34:52 +00:00
$ flagStatus [ % flag . team ] = "<In the Field>" ;
2022-02-18 19:34:07 +00:00
2021-02-26 20:40:53 +00:00
// attach the camera to the flag
2021-03-16 17:01:21 +00:00
if ( $ Observers )
2020-03-23 20:23:42 +00:00
{
2021-03-16 17:01:21 +00:00
for ( % i = 0 ; % i < ClientGroup . getCount ( ) ; % i + + )
{
% cl = ClientGroup . getObject ( % i ) ;
if ( % cl . team < = 0 & & % cl . observingFlag & & % cl . flagObsTeam = = % flag . team )
observeFlag ( % cl , $ TeamFlag [ % flag . team ] , 1 , % flag . team ) ;
}
2020-03-23 20:23:42 +00:00
}
2022-02-18 19:34:07 +00:00
% player . unMountImage ( $ FlagSlot ) ;
% flag . hide ( false ) ; //Does the throwItem function handle this?
2018-06-28 18:34:52 +00:00
% teamName = % game . getTeamName ( % flag . team ) ;
messageTeamExcept ( % client , ' MsgCTFFlagDropped ' , ' \ c2Teammate % 1 dropped the % 2 flag . ( Held : % 4 ) ~ wfx / misc / flag_drop . wav ' , % client . name , % teamName , % flag . team , % held ) ; // z0dd - ZOD, 8/15/02. How long flag was held
messageTeam ( % flag . team , ' MsgCTFFlagDropped ' , ' \ c2Your flag has been dropped by % 1 ! ( Held : % 4 ) ~ wfx / misc / flag_drop . wav ' , % client . name , 0 , % flag . team , % held ) ; // z0dd - ZOD, 8/15/02. How long flag was held
messageTeam ( 0 , ' MsgCTFFlagDropped ' , ' \ c2 % 1 dropped the % 2 flag . ( Held : % 4 ) ~ wfx / misc / flag_drop . wav ' , % client . name , % teamName , % flag . team , % held ) ; // z0dd - ZOD, 8/15/02. How long flag was held
if ( ! % player . client . outOfBounds )
messageClient ( % client , ' MsgCTFFlagDropped ' , ' \ c2You dropped the % 2 flag . ( Held : % 4 ) ~ wfx / misc / flag_drop . wav ' , % client . name , % teamName , % flag . team , % held ) ; // z0dd - ZOD, 8/15/02. How long flag was held
// Yogi, 8/18/02. 3rd param changed 0 -> %client.name
logEcho ( % client . nameBase @" (pl " @ % player @"/cl " @ % client @") dropped team " @ % flag . team @" flag" @" (Held: " @ % held @")" ) ;
//don't duplicate the schedule if there's already one in progress...
if ( $ FlagReturnTimer [ % flag ] < = 0 )
$ FlagReturnTimer [ % flag ] = % game . schedule ( % game . FLAG_RETURN_DELAY - % game . fadeTimeMS , "flagReturnFade" , % flag ) ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
//call the AI function
% game . AIplayerDroppedFlag ( % player , % flag ) ;
}
function CTFGame : : flagCap ( % game , % player )
{
% client = % player . client ;
% flag = % player . holdingFlag ;
% flag . carrier = "" ;
2022-02-18 19:34:07 +00:00
2021-02-26 20:40:53 +00:00
// when a player cap the flag, attach to flag again
2021-03-16 17:01:21 +00:00
if ( $ Observers )
2020-03-29 05:38:04 +00:00
{
2021-03-16 17:01:21 +00:00
for ( % i = 0 ; % i < ClientGroup . getCount ( ) ; % i + + )
{
% cl = ClientGroup . getObject ( % i ) ;
if ( % cl . team < = 0 & & % cl . observingFlag & & % cl . flagObsTeam = = % flag . team )
observeFlag ( % cl , $ TeamFlag [ % flag . team ] , 1 , % flag . team ) ;
}
2020-03-29 05:38:04 +00:00
}
2018-06-28 18:34:52 +00:00
2022-02-18 18:30:44 +00:00
% held = % game . formatTime ( getSimTime ( ) - % game . flagHeldTime [ % flag ] , true ) ; // z0dd - ZOD, 8/15/02. How long did player hold flag?
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
% game . playerLostFlagTarget ( % player ) ;
2020-03-23 20:23:42 +00:00
2018-06-28 18:34:52 +00:00
//award points to player and team
% teamName = % game . getTeamName ( % flag . team ) ;
messageTeamExcept ( % client , ' MsgCTFFlagCapped ' , ' \ c2 % 1 captured the % 2 flag ! ( Held : % 5 ) ~ wfx / misc / flag_capture . wav ' , % client . name , % teamName , % flag . team , % client . team , % held ) ;
2022-02-18 19:34:07 +00:00
messageTeam ( % flag . team , ' MsgCTFFlagCapped ' , ' \ c2Your flag was captured by % 1. ( Held : % 5 ) ~ wfx / misc / flag_lost . wav ' , % client . name , 0 , % flag . team , % client . team , % held ) ;
messageTeam ( 0 , ' MsgCTFFlagCapped ' , ' \ c2 % 1 captured the % 2 flag ! ( Held : % 5 ) ~ wfx / misc / flag_capture . wav ' , % client . name , % teamName , % flag . team , % client . team , % held ) ;
2018-06-28 18:34:52 +00:00
messageClient ( % client , ' MsgCTFFlagCapped ' , ' \ c2You captured the % 2 flag ! ( Held : % 5 ) ~ wfx / misc / flag_capture . wav ' , % client . name , % teamName , % flag . team , % client . team , % held ) ; // Yogi, 8/18/02. 3rd param changed 0 -> %client.name
2020-03-23 20:23:42 +00:00
logEcho ( % client . nameBase @" (pl " @ % player @"/cl " @ % client @") capped team " @ % client . team @" flag" @" (Held: " @ % held @")" ) ; // MP: 6/14/2011 The team is wrong, but the stats program auto-corrects it, so just leave as is
2018-06-28 18:34:52 +00:00
% player . holdingFlag = "" ; //no longer holding it.
% player . unMountImage ( $ FlagSlot ) ;
2022-02-18 19:34:07 +00:00
% game . awardScoreFlagCap ( % client , % flag ) ;
2018-06-28 18:34:52 +00:00
% game . flagReset ( % flag ) ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
//call the AI function
% game . AIflagCap ( % player , % flag ) ;
2020-03-23 20:23:42 +00:00
//Determine score status
% caplimit = MissionGroup . CTF_scoreLimit ;
2022-02-18 19:34:07 +00:00
% otherteam = ( % client . team = = 1 ) ? 2 : 1 ;
2020-03-23 20:23:42 +00:00
//Find out caps from score
% clientteamcaps = mFloor ( $ TeamScore [ % client . team ] / % game . SCORE_PER_TEAM_FLAG_CAP ) ;
% otherteamcaps = mFloor ( $ TeamScore [ % otherteam ] / % game . SCORE_PER_TEAM_FLAG_CAP ) ;
2022-02-18 19:34:07 +00:00
2020-03-23 20:23:42 +00:00
//Determine Gamepoint
if ( % clientteamcaps > = ( % caplimit - 1 ) )
{
if ( % clientteamcaps = = % otherteamcaps )
% scorestatus = "tied" ;
else
% scorestatus = "gamepoint" ;
}
else
% scorestatus = "normal" ;
2018-06-28 18:34:52 +00:00
//if this cap didn't end the game, play the announcer...
2020-03-23 20:23:42 +00:00
if ( $ missionRunning )
2018-10-10 03:38:21 +00:00
{
2020-03-23 20:23:42 +00:00
switch $ ( % scorestatus )
{
case normal :
//classic uses only storm/inferno
if ( % game . getTeamName ( % client . team ) $ = ' Inferno ' )
messageAll ( "" , ' ~ wvoice / announcer / ann . infscores . wav ' ) ;
else if ( % game . getTeamName ( % client . team ) $ = ' Storm ' )
messageAll ( "" , ' ~ wvoice / announcer / ann . stoscores . wav ' ) ;
case tied :
//Announce tied message
messageAll ( "" , ' ~ wvoice / announcer / ann . closegame_03 . wav ' ) ;
case gamepoint :
//Announce gamepoint
messageAll ( "" , ' ~ wvoice / announcer / ann . gamepoint_imminent . wav ' ) ;
}
2018-10-10 03:38:21 +00:00
}
2018-06-28 18:34:52 +00:00
}
function CTFGame : : flagReturnFade ( % game , % flag )
{
$ FlagReturnTimer [ % flag ] = % game . schedule ( % game . fadeTimeMS , "flagReturn" , % flag ) ;
% flag . startFade ( % game . fadeTimeMS , 0 , true ) ;
}
function CTFGame : : flagReturn ( % game , % flag , % player )
{
// Kill the lava scedule - Ilys
if ( isEventPending ( % flag . lavaEnterThread ) )
cancel ( % flag . lavaEnterThread ) ;
cancel ( $ FlagReturnTimer [ % flag ] ) ;
$ FlagReturnTimer [ % flag ] = "" ;
if ( % flag . team = = 1 )
% otherTeam = 2 ;
else
% otherTeam = 1 ;
% teamName = % game . getTeamName ( % flag . team ) ;
2022-02-18 19:34:07 +00:00
2021-02-26 20:40:53 +00:00
// when the flag return, attach to flag again
2021-03-16 17:01:21 +00:00
if ( $ Observers )
2020-03-23 20:23:42 +00:00
{
2021-03-16 17:01:21 +00:00
for ( % i = 0 ; % i < ClientGroup . getCount ( ) ; % i + + )
{
% cl = ClientGroup . getObject ( % i ) ;
if ( % cl . team < = 0 & & % cl . observingFlag & & % cl . flagObsTeam = = % flag . team )
observeFlag ( % cl , $ TeamFlag [ % flag . team ] , 1 , % flag . team ) ;
}
2020-03-23 20:23:42 +00:00
}
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
if ( % player ! $ = "" )
{
//a player returned it
% client = % player . client ;
messageTeamExcept ( % client , ' MsgCTFFlagReturned ' , ' \ c2Teammate % 1 returned your flag to base . ~ wfx / misc / flag_return . wav ' , % client . name , 0 , % flag . team ) ;
messageTeam ( % otherTeam , ' MsgCTFFlagReturned ' , ' \ c2Enemy % 1 returned the % 2 flag . ~ wfx / misc / flag_return . wav ' , % client . name , % teamName , % flag . team ) ;
messageTeam ( 0 , ' MsgCTFFlagReturned ' , ' \ c2 % 1 returned the % 2 flag . ~ wfx / misc / flag_return . wav ' , % client . name , % teamName , % flag . team ) ;
messageClient ( % client , ' MsgCTFFlagReturned ' , ' \ c2You returned your flag . ~ wfx / misc / flag_return . wav ' , % client . name , % teamName , % flag . team ) ; // Yogi, 8/18/02. 3rd param changed 0 -> %client.name
logEcho ( % client . nameBase @" (pl " @ % player @"/cl " @ % client @") returned team " @ % flag . team @" flag" ) ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
// find out what type of return it is
// stalemate return?
// ---------------------------------------------------
// z0dd - ZOD, 9/29/02. Removed T2 demo code from here
if ( % game . stalemate )
{
//error("Stalemate return!!!");
% game . awardScoreStalemateReturn ( % player . client ) ;
}
// regular return
else
{
% enemyFlagDist = vectorDist ( $ flagPos [ % flag . team ] , $ flagPos [ % otherTeam ] ) ;
% dist = vectorDist ( % flag . position , % flag . originalPosition ) ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
% rawRatio = % dist / % enemyFlagDist ;
% ratio = % rawRatio < 1 ? % rawRatio : 1 ;
% percentage = mFloor ( ( % ratio ) * 10 ) * 10 ;
2022-02-18 19:34:07 +00:00
% game . awardScoreFlagReturn ( % player . client , % percentage ) ;
2018-06-28 18:34:52 +00:00
}
// ---------------------------------------------------
2022-02-18 19:34:07 +00:00
}
2018-06-28 18:34:52 +00:00
else
{
//returned due to timer
messageTeam ( % otherTeam , ' MsgCTFFlagReturned ' , ' \ c2The % 2 flag was returned to base . ~ wfx / misc / flag_return . wav ' , 0 , % teamName , % flag . team ) ; //because it was dropped for too long
messageTeam ( % flag . team , ' MsgCTFFlagReturned ' , ' \ c2Your flag was returned . ~ wfx / misc / flag_return . wav ' , 0 , 0 , % flag . team ) ;
messageTeam ( 0 , ' MsgCTFFlagReturned ' , ' \ c2The % 2 flag was returned to base . ~ wfx / misc / flag_return . wav ' , 0 , % teamName , % flag . team ) ;
logEcho ( "team " @ % flag . team @" flag returned (timeout)" ) ;
}
% game . flagReset ( % flag ) ;
}
function CTFGame : : showStalemateTargets ( % game )
{
cancel ( % game . stalemateSchedule ) ;
//show the targets
for ( % i = 1 ; % i < = 2 ; % i + + )
{
% flag = $ TeamFlag [ % i ] ;
//find the object to scope/waypoint....
//render the target hud icon for slot 1 (a centermass flag)
//if we just set him as always sensor vis, it'll work fine.
if ( isObject ( % flag . carrier ) )
setTargetAlwaysVisMask ( % flag . carrier . getTarget ( ) , 0x7 ) ;
}
//schedule the targets to hide
% game . stalemateObjsVisible = true ;
% game . stalemateSchedule = % game . schedule ( % game . stalemateDurationMS , hideStalemateTargets ) ;
}
function CTFGame : : hideStalemateTargets ( % game )
{
cancel ( % game . stalemateSchedule ) ;
//hide the targets
for ( % i = 1 ; % i < = 2 ; % i + + )
{
% flag = $ TeamFlag [ % i ] ;
if ( isObject ( % flag . carrier ) )
{
% target = % flag . carrier . getTarget ( ) ;
setTargetAlwaysVisMask ( % target , ( 1 < < getTargetSensorGroup ( % target ) ) ) ;
}
}
//schedule the targets to show again
% game . stalemateObjsVisible = false ;
% game . stalemateSchedule = % game . schedule ( % game . stalemateFreqMS , showStalemateTargets ) ;
}
function CTFGame : : beginStalemate ( % game )
{
% game . stalemate = true ;
% game . showStalemateTargets ( ) ;
// z0dd - ZOD, 5/27/03. Added anti-turtling, return flags after x minutes
if ( ! $ Host : : TournamentMode )
{
2020-03-23 20:23:42 +00:00
messageAll ( ' MsgStalemate ' , "\c3Anti turtle initialized. Flags will be returned to bases in " @ $ Host : : ClassicAntiTurtleTime @ " minutes." ) ;
% game . turtleSchedule = % game . schedule ( $ Host : : ClassicAntiTurtleTime * 60000 , "antiTurtle" ) ;
2025-01-11 21:50:56 +00:00
error ( formatTimeString ( "HH:nn:ss" ) SPC "Anti-Turtle thread beginning now - ID:" SPC % game . turtleSchedule ) ;
2018-06-28 18:34:52 +00:00
}
}
function CTFGame : : endStalemate ( % game )
{
% game . stalemate = false ;
% game . hideStalemateTargets ( ) ;
cancel ( % game . stalemateSchedule ) ;
2020-03-23 20:23:42 +00:00
cancel ( % game . turtleSchedule ) ;
2018-06-28 18:34:52 +00:00
}
function CTFGame : : antiTurtle ( % game )
{
if ( isEventPending ( % game . turtleSchedule ) )
2020-03-23 20:23:42 +00:00
cancel ( % game . turtleSchedule ) ;
2018-06-28 18:34:52 +00:00
2020-03-23 20:23:42 +00:00
if ( % game . turtleSchedule > 0 )
% game . turtleSchedule = 0 ;
if ( isEventPending ( % game . stalemateSchedule ) )
cancel ( % game . stalemateSchedule ) ;
if ( % game . stalemateSchedule > 0 )
% game . stalemateSchedule = 0 ;
2022-02-18 19:34:07 +00:00
2020-03-23 20:23:42 +00:00
for ( % i = 1 ; % i < = Game . numTeams ; % i + + )
2018-06-28 18:34:52 +00:00
Game . flagReturn ( $ TeamFlag [ % i ] ) ;
2022-02-18 19:34:07 +00:00
2020-03-23 20:23:42 +00:00
messageAll ( "" , "\c3Both flags returned to bases to break stalemate.~wfx/misc/flag_return.wav" ) ;
error ( formatTimeString ( "HH:nn:ss" ) SPC "Anti-Turtle thread ended" ) ;
2018-06-28 18:34:52 +00:00
}
function CTFGame : : flagReset ( % game , % flag )
{
cancel ( % game . updateFlagThread [ % flag ] ) ; // z0dd - ZOD, 8/4/02. Cancel this flag's thread to KineticPoet's flag updater
//any time a flag is reset, kill the stalemate schedule
2020-03-23 20:23:42 +00:00
% game . endStalemate ( % game ) ;
2018-06-28 18:34:52 +00:00
//make sure if there's a player carrying it (probably one out of bounds...), it is stripped first
if ( isObject ( % flag . carrier ) )
{
//hide the target hud icon for slot 2 (a centermass flag - visible only as part of a teams sensor network)
% game . playerLostFlagTarget ( % flag . carrier ) ;
% flag . carrier . holdingFlag = "" ; //no longer holding it.
% flag . carrier . unMountImage ( $ FlagSlot ) ;
}
//fades, restore default position, home, velocity, general status, etc.
% flag . setVelocity ( "0 0 0" ) ;
% flag . setTransform ( % flag . originalPosition ) ;
% flag . isHome = true ;
% flag . carrier = "" ;
% flag . grabber = "" ;
$ flagStatus [ % flag . team ] = "<At Base>" ;
% flag . hide ( false ) ;
if ( % flag . stand )
% flag . stand . getDataBlock ( ) . onFlagReturn ( % flag . stand ) ; //animate, if exterior stand
//fade the flag in...
2022-02-18 19:34:07 +00:00
% flag . startFade ( % game . fadeTimeMS , 0 , false ) ;
2018-06-28 18:34:52 +00:00
// dont render base target
setTargetRenderMask ( % flag . waypoint . getTarget ( ) , 0 ) ;
//call the AI function
% game . AIflagReset ( % flag ) ;
// --------------------------------------------------------
// z0dd - ZOD, 5/26/02. Don't let flag hover over defenders
% flag . static = true ;
// --------------------------------------------------------------------------
// z0dd - ZOD, 9/28/02. Hack for flag collision bug.
if ( % flag . searchSchedule ! $ = "" )
{
cancel ( % flag . searchSchedule ) ;
}
2022-02-18 19:34:07 +00:00
// --------------------------------------------------------------------------
2018-06-28 18:34:52 +00:00
}
function CTFGame : : timeLimitReached ( % game )
{
2018-08-07 06:50:49 +00:00
logEcho ( "game over (timelimit)" ) ;
% game . gameOver ( ) ;
cycleMissions ( ) ;
2018-06-28 18:34:52 +00:00
}
function CTFGame : : scoreLimitReached ( % game )
{
logEcho ( "game over (scorelimit)" ) ;
% game . gameOver ( ) ;
cycleMissions ( ) ;
}
function CTFGame : : notifyMineDeployed ( % game , % mine )
{
//see if the mine is within 5 meters of the flag stand...
% mineTeam = % mine . sourceObject . team ;
% homeFlag = $ TeamFlag [ % mineTeam ] ;
if ( isObject ( % homeFlag ) )
{
% dist = VectorDist ( % homeFlag . originalPosition , % mine . position ) ;
if ( % dist < = % game . notifyMineDist )
{
messageTeam ( % mineTeam , ' MsgCTFFlagMined ' , "The flag has been mined.~wvoice/announcer/flag_minedFem.wav" ) ;
}
}
}
function CTFGame : : gameOver ( % game )
{
// z0dd - ZOD, 5/27/03. Kill the anti-turtle schedule
if ( % game . turtleSchedule ! $ = "" )
{
cancel ( % game . turtleSchedule ) ;
% game . turtleSchedule = "" ;
}
// z0dd - ZOD, 9/28/02. Hack for flag collision bug.
for ( % f = 1 ; % f < = % game . numTeams ; % f + + )
{
cancel ( $ TeamFlag [ % f ] . searchSchedule ) ;
cancel ( $ TeamFlag [ % f ] . lavaEnterThread ) ; // Kill Ilys lava schedule - ZOD
}
// -------------------------------------------
// z0dd - ZOD, 9/28/02. Cancel camp schedules.
if ( Game . campThread_1 ! $ = "" )
cancel ( Game . campThread_1 ) ;
if ( Game . campThread_2 ! $ = "" )
cancel ( Game . campThread_2 ) ;
// -------------------------------------------
//call the default
DefaultGame : : gameOver ( % game ) ;
//send the winner message
% winner = "" ;
if ( $ teamScore [ 1 ] > $ teamScore [ 2 ] )
% winner = % game . getTeamName ( 1 ) ;
else if ( $ teamScore [ 2 ] > $ teamScore [ 1 ] )
% winner = % game . getTeamName ( 2 ) ;
2020-11-17 14:30:42 +00:00
switch $ ( % winner )
{
case ' Storm ' :
messageAll ( ' MsgGameOver ' , "Match has ended.~wvoice/announcer/ann.stowins.wav" ) ;
case ' Inferno ' :
messageAll ( ' MsgGameOver ' , "Match has ended.~wvoice/announcer/ann.infwins.wav" ) ;
case ' Starwolf ' :
messageAll ( ' MsgGameOver ' , "Match has ended.~wvoice/announcer/ann.swwin.wav" ) ;
case ' Blood Eagle ' :
messageAll ( ' MsgGameOver ' , "Match has ended.~wvoice/announcer/ann.bewin.wav" ) ;
case ' Diamond Sword ' :
messageAll ( ' MsgGameOver ' , "Match has ended.~wvoice/announcer/ann.dswin.wav" ) ;
case ' Phoenix ' :
messageAll ( ' MsgGameOver ' , "Match has ended.~wvoice/announcer/ann.pxwin.wav" ) ;
default :
messageAll ( ' MsgGameOver ' , "Match has ended.~wvoice/announcer/ann.gameover.wav" ) ;
}
2018-06-28 18:34:52 +00:00
messageAll ( ' MsgClearObjHud ' , "" ) ;
2022-02-18 19:34:07 +00:00
for ( % i = 0 ; % i < ClientGroup . getCount ( ) ; % i + + )
2018-06-28 18:34:52 +00:00
{
% client = ClientGroup . getObject ( % i ) ;
% game . resetScore ( % client ) ;
}
for ( % j = 1 ; % j < = % game . numTeams ; % j + + )
$ TeamScore [ % j ] = 0 ;
}
function CTFGame : : onClientDamaged ( % game , % clVictim , % clAttacker , % damageType , % implement , % damageLoc )
2022-02-18 19:34:07 +00:00
{
2018-06-28 18:34:52 +00:00
if ( % clVictim . headshot & & % damageType = = $ DamageType : : Laser & & % clVictim . team ! = % clAttacker . team )
{
% clAttacker . scoreHeadshot + + ;
if ( % game . SCORE_PER_HEADSHOT ! = 0 )
{
messageClient ( % clAttacker , ' msgHeadshot ' , ' \ c0You received a % 1 point bonus for a successful headshot . ' , % game . SCORE_PER_HEADSHOT ) ;
messageTeamExcept ( % clAttacker , ' msgHeadshot ' , ' \ c5 % 1 hit a sniper rifle headshot . ' , % clAttacker . name ) ; // z0dd - ZOD, 8/15/02. Tell team
}
% game . recalcScore ( % clAttacker ) ;
}
// -----------------------------------------------
// z0dd - ZOD, 8/25/02. Rear Lance hits
if ( % clVictim . rearshot & & % damageType = = $ DamageType : : ShockLance & & % clVictim . team ! = % clAttacker . team )
{
% clAttacker . scoreRearshot + + ;
if ( % game . SCORE_PER_REARSHOT ! = 0 )
{
messageClient ( % clAttacker , ' msgRearshot ' , ' \ c0You received a % 1 point bonus for a successful rearshot . ' , % game . SCORE_PER_REARSHOT ) ;
messageTeamExcept ( % clAttacker , ' msgRearshot ' , ' \ c5 % 1 hit a shocklance rearshot . ' , % clAttacker . name ) ;
}
% game . recalcScore ( % clAttacker ) ;
}
// -----------------------------------------------
//the DefaultGame will set some vars
DefaultGame : : onClientDamaged ( % game , % clVictim , % clAttacker , % damageType , % implement , % damageLoc ) ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
//if victim is carrying a flag and is not on the attackers team, mark the attacker as a threat for x seconds(for scoring purposes)
if ( ( % clVictim . holdingFlag ! $ = "" ) & & ( % clVictim . team ! = % clAttacker . team ) )
{
% clAttacker . dmgdFlagCarrier = true ;
2022-02-18 19:34:07 +00:00
cancel ( % clAttacker . threatTimer ) ; //restart timer
2018-06-28 18:34:52 +00:00
% clAttacker . threatTimer = schedule ( % game . TIME_CONSIDERED_FLAGCARRIER_THREAT , % clAttacker . dmgdFlagCarrier = false ) ;
}
}
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
////////////////////////////////////////////////////////////////////////////////////////
function CTFGame : : clientMissionDropReady ( % game , % client )
{
messageClient ( % client , ' MsgClientReady ' , "" , % game . class ) ;
% game . resetScore ( % client ) ;
for ( % i = 1 ; % i < = % game . numTeams ; % i + + )
{
$ Teams [ % i ] . score = 0 ;
messageClient ( % client , ' MsgCTFAddTeam ' , "" , % i , % game . getTeamName ( % i ) , $ flagStatus [ % i ] , $ TeamScore [ % i ] ) ;
}
//%game.populateTeamRankArray(%client);
//messageClient(%client, 'MsgYourRankIs', "", -1);
2022-02-18 19:34:07 +00:00
messageClient ( % client , ' MsgMissionDropInfo ' , ' \ c0You are in mission % 1 ( % 2 ) . ' , $ MissionDisplayName , $ MissionTypeDisplayName , $ ServerName ) ;
2018-06-28 18:34:52 +00:00
DefaultGame : : clientMissionDropReady ( % game , % client ) ;
}
function CTFGame : : assignClientTeam ( % game , % client , % respawn )
{
DefaultGame : : assignClientTeam ( % game , % client , % respawn ) ;
// if player's team is not on top of objective hud, switch lines
messageClient ( % client , ' MsgCheckTeamLines ' , "" , % client . team ) ;
}
function CTFGame : : recalcScore ( % game , % cl )
{
% killValue = % cl . kills * % game . SCORE_PER_KILL ;
% deathValue = % cl . deaths * % game . SCORE_PER_DEATH ;
if ( % killValue - % deathValue = = 0 )
% killPoints = 0 ;
else
% killPoints = ( % killValue * % killValue ) / ( % killValue - % deathValue ) ;
// ---------------------------------------------------
// z0dd - ZOD, 9/29/02. Removed T2 demo code from here
% cl . offenseScore = % killPoints +
2022-02-18 19:34:07 +00:00
% cl . suicides * % game . SCORE_PER_SUICIDE +
2018-06-28 18:34:52 +00:00
% cl . escortAssists * % game . SCORE_PER_ESCORT_ASSIST +
2022-02-18 19:34:07 +00:00
% cl . teamKills * % game . SCORE_PER_TEAMKILL +
2018-06-28 18:34:52 +00:00
% cl . tkDestroys * % game . SCORE_PER_TK_DESTROY + // z0dd - ZOD, 10/03/02. Penalty for tking equiptment.
2022-02-18 19:34:07 +00:00
% cl . scoreHeadshot * % game . SCORE_PER_HEADSHOT +
2018-06-28 18:34:52 +00:00
% cl . scoreRearshot * % game . SCORE_PER_REARSHOT + // z0dd - ZOD, 8/25/02. Added Lance rear shot messages
2022-02-18 19:34:07 +00:00
% cl . scoreMidAir * % game . SCORE_PER_MIDAIR +
% cl . flagCaps * % game . SCORE_PER_PLYR_FLAG_CAP +
% cl . flagGrabs * % game . SCORE_PER_PLYR_FLAG_TOUCH +
% cl . genDestroys * % game . SCORE_PER_DESTROY_GEN +
% cl . sensorDestroys * % game . SCORE_PER_DESTROY_SENSOR +
% cl . turretDestroys * % game . SCORE_PER_DESTROY_TURRET +
% cl . iStationDestroys * % game . SCORE_PER_DESTROY_ISTATION +
% cl . vstationDestroys * % game . SCORE_PER_DESTROY_VSTATION +
2018-06-28 18:34:52 +00:00
% cl . mpbtstationDestroys * % game . SCORE_PER_DESTROY_MPBTSTATION + // z0dd - ZOD 3/30/02. MPB Teleporter
2022-02-18 19:34:07 +00:00
% cl . solarDestroys * % game . SCORE_PER_DESTROY_SOLAR +
% cl . sentryDestroys * % game . SCORE_PER_DESTROY_SENTRY +
% cl . depSensorDestroys * % game . SCORE_PER_DESTROY_DEP_SENSOR +
% cl . depTurretDestroys * % game . SCORE_PER_DESTROY_DEP_TUR +
2018-06-28 18:34:52 +00:00
% cl . depStationDestroys * % game . SCORE_PER_DESTROY_DEP_INV +
2022-02-18 19:34:07 +00:00
% cl . vehicleScore + % cl . vehicleBonus ;
2018-06-28 18:34:52 +00:00
2022-02-18 19:34:07 +00:00
% cl . defenseScore = % cl . genDefends * % game . SCORE_PER_GEN_DEFEND +
2018-06-28 18:34:52 +00:00
% cl . flagDefends * % game . SCORE_PER_FLAG_DEFEND +
2022-02-18 19:34:07 +00:00
% cl . carrierKills * % game . SCORE_PER_CARRIER_KILL +
% cl . escortAssists * % game . SCORE_PER_ESCORT_ASSIST +
% cl . turretKills * % game . SCORE_PER_TURRET_KILL_AUTO +
% cl . mannedturretKills * % game . SCORE_PER_TURRET_KILL +
2018-06-28 18:34:52 +00:00
% cl . genRepairs * % game . SCORE_PER_REPAIR_GEN +
% cl . SensorRepairs * % game . SCORE_PER_REPAIR_SENSOR +
% cl . TurretRepairs * % game . SCORE_PER_REPAIR_TURRET +
% cl . StationRepairs * % game . SCORE_PER_REPAIR_ISTATION +
% cl . VStationRepairs * % game . SCORE_PER_REPAIR_VSTATION +
% cl . mpbtstationRepairs * % game . SCORE_PER_REPAIR_MPBTSTATION + // z0dd - ZOD 4/10/04. MPB Teleporter
% cl . depSensorRepairs * % game . SCORE_PER_REPAIR_DEP_SEN + // z0dd - ZOD 5/27/03. Deployed sensors %cl.mpbtstationRepairs * %game.SCORE_PER_REPAIR_MPBTSTATION + // z0dd - ZOD 3/30/02. MPB Teleporter
% cl . solarRepairs * % game . SCORE_PER_REPAIR_SOLAR +
% cl . sentryRepairs * % game . SCORE_PER_REPAIR_SENTRY +
% cl . depInvRepairs * % game . SCORE_PER_REPAIR_DEP_INV +
% cl . depTurretRepairs * % game . SCORE_PER_REPAIR_DEP_TUR +
2022-02-18 19:34:07 +00:00
% cl . returnPts ;
2018-06-28 18:34:52 +00:00
// ---------------------------------------------------
// z0dd - ZOD, 9/29/02. Removed T2 demo code from here
% cl . score = mFloor ( % cl . offenseScore + % cl . defenseScore ) ;
% game . recalcTeamRanks ( % cl ) ;
}
function CTFGame : : updateKillScores ( % game , % clVictim , % clKiller , % damageType , % implement )
{
// is this a vehicle kill rather than a player kill
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
// console error message suppression
if ( isObject ( % implement ) )
{
if ( % implement . getDataBlock ( ) . getName ( ) $ = "AssaultPlasmaTurret" | | % implement . getDataBlock ( ) . getName ( ) $ = "BomberTurret" ) // gunner
% clKiller = % implement . vehicleMounted . getMountNodeObject ( 1 ) . client ;
else if ( % implement . getDataBlock ( ) . catagory $ = "Vehicles" ) // pilot
2022-02-18 19:34:07 +00:00
% clKiller = % implement . getMountNodeObject ( 0 ) . client ;
2018-06-28 18:34:52 +00:00
}
if ( % game . testTurretKill ( % implement ) ) //check for turretkill before awarded a non client points for a kill
% game . awardScoreTurretKill ( % clVictim , % implement ) ;
else if ( % game . testKill ( % clVictim , % clKiller ) ) //verify victim was an enemy
{
% value = % game . awardScoreKill ( % clKiller ) ;
% game . shareScore ( % clKiller , % value ) ;
% game . awardScoreDeath ( % clVictim ) ;
if ( % game . testGenDefend ( % clVictim , % clKiller ) )
% game . awardScoreGenDefend ( % clKiller ) ;
2022-02-18 19:34:07 +00:00
if ( % game . testCarrierKill ( % clVictim , % clKiller ) )
2018-06-28 18:34:52 +00:00
% game . awardScoreCarrierKill ( % clKiller ) ;
else
{
if ( % game . testFlagDefend ( % clVictim , % clKiller ) )
% game . awardScoreFlagDefend ( % clKiller ) ;
}
if ( % game . testEscortAssist ( % clVictim , % clKiller ) )
2022-02-18 19:34:07 +00:00
% game . awardScoreEscortAssist ( % clKiller ) ;
}
2018-06-28 18:34:52 +00:00
else
2022-02-18 19:34:07 +00:00
{
2018-06-28 18:34:52 +00:00
if ( % game . testSuicide ( % clVictim , % clKiller , % damageType ) ) //otherwise test for suicide
{
2022-02-18 19:34:07 +00:00
% game . awardScoreSuicide ( % clVictim ) ;
2018-06-28 18:34:52 +00:00
}
else
{
2021-09-30 20:22:55 +00:00
if ( % game . testTeamKill ( % clVictim , % clKiller , % damageType ) ) //otherwise test for a teamkill
2018-06-28 18:34:52 +00:00
% game . awardScoreTeamKill ( % clVictim , % clKiller ) ;
}
2022-02-18 19:34:07 +00:00
}
2018-06-28 18:34:52 +00:00
}
function CTFGame : : testFlagDefend ( % game , % victimID , % killerID )
{
InitContainerRadiusSearch ( % victimID . plyrPointOfDeath , % game . RADIUS_FLAG_DEFENSE , $ TypeMasks : : ItemObjectType ) ;
2022-02-18 19:34:07 +00:00
% objID = containerSearchNext ( ) ;
while ( % objID ! = 0 )
2018-06-28 18:34:52 +00:00
{
% objType = % objID . getDataBlock ( ) . getName ( ) ;
2022-02-18 19:34:07 +00:00
if ( ( % objType $ = "Flag" ) & & ( % objID . team = = % killerID . team ) )
2018-06-28 18:34:52 +00:00
return true ; //found the(a) killer's flag near the victim's point of death
else
2022-02-18 19:34:07 +00:00
% objID = containerSearchNext ( ) ;
2018-06-28 18:34:52 +00:00
}
2022-02-18 19:34:07 +00:00
return false ; //didn't find a qualifying flag within required radius of victims point of death
2018-06-28 18:34:52 +00:00
}
function CTFGame : : testGenDefend ( % game , % victimID , % killerID )
{
InitContainerRadiusSearch ( % victimID . plyrPointOfDeath , % game . RADIUS_GEN_DEFENSE , $ TypeMasks : : StaticShapeObjectType ) ;
% objID = containerSearchNext ( ) ;
while ( % objID ! = 0 )
{
% objType = % objID . getDataBlock ( ) . ClassName ;
2022-02-18 19:34:07 +00:00
if ( ( % objType $ = "generator" ) & & ( % objID . team = = % killerID . team ) )
2018-06-28 18:34:52 +00:00
return true ; //found a killer's generator within required radius of victim's death
else
% objID = containerSearchNext ( ) ;
}
2022-02-18 19:34:07 +00:00
return false ; //didn't find a qualifying gen within required radius of victim's point of death
2018-06-28 18:34:52 +00:00
}
function CTFGame : : testCarrierKill ( % game , % victimID , % killerID )
{
% flag = % victimID . plyrDiedHoldingFlag ;
2022-02-18 19:34:07 +00:00
return ( ( % flag ! $ = "" ) & & ( % flag . team = = % killerID . team ) ) ;
2018-06-28 18:34:52 +00:00
}
function CTFGame : : testEscortAssist ( % game , % victimID , % killerID )
{
2022-02-18 19:34:07 +00:00
return ( % victimID . dmgdFlagCarrier ) ;
2018-06-28 18:34:52 +00:00
}
function CTFGame : : awardScoreFlagCap ( % game , % cl , % flag )
{
% cl . flagCaps + + ;
$ TeamScore [ % cl . team ] + = % game . SCORE_PER_TEAM_FLAG_CAP ;
messageAll ( ' MsgTeamScoreIs ' , "" , % cl . team , $ TeamScore [ % cl . team ] ) ;
2019-03-11 20:36:44 +00:00
//%flag.grabber.flagGrabs++; //moved to awardScoreFlagTouch
2018-06-28 18:34:52 +00:00
if ( % game . SCORE_PER_TEAM_FLAG_CAP > 0 )
{
% plural = ( % game . SCORE_PER_PLYR_FLAG_CAP ! = 1 ? 's' : "" ) ;
% plural2 = ( % game . SCORE_PER_PLYR_FLAG_TOUCH ! = 1 ? 's' : "" ) ;
// z0dd - ZOD, 9/29/02. Removed T2 demo code from here
// z0dd - ZOD, 9/29/02. Removed T2 demo code from here
if ( % cl = = % flag . grabber )
{
messageClient ( % cl , ' msgCTFFriendCap ' , ' \ c0You receive % 1 point % 2 for stealing and capturing the enemy flag ! ' , % game . SCORE_PER_PLYR_FLAG_CAP + % game . SCORE_PER_PLYR_FLAG_TOUCH , % plural ) ;
messageTeam ( % flag . team , ' msgCTFEnemyCap ' , ' \ c0Enemy % 1 received % 2 point % 3 for capturing your flag ! ' , % cl . name , % game . SCORE_PER_PLYR_FLAG_CAP + % game . SCORE_PER_PLYR_FLAG_TOUCH , % plural ) ;
//messageTeamExcept(%cl, 'msgCTFFriendCap', '\c0Teammate %1 receives %2 point%3 for capturing the enemy flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP+%game.SCORE_PER_PLYR_FLAG_TOUCH, %plural); // z0dd - ZOD, 8/15/02. Message is pointless
}
else
{
if ( isObject ( % flag . grabber ) ) // is the grabber still here?
{
messageClient ( % cl , ' msgCTFFriendCap ' , ' \ c0You receive % 1 point % 2 for capturing the enemy flag ! % 3 gets % 4 point % 5 for the steal assist . ' , % game . SCORE_PER_PLYR_FLAG_CAP , % plural , % flag . grabber . name , % game . SCORE_PER_PLYR_FLAG_TOUCH , % plural2 ) ;
messageClient ( % flag . grabber , ' msgCTFFriendCap ' , ' \ c0You receive % 1 point % 2 for stealing a flag that was subsequently capped by % 3. ' , % game . SCORE_PER_PLYR_FLAG_TOUCH , % plural2 , % cl . name ) ;
}
else
messageClient ( % cl , ' msgCTFFriendCap ' , ' \ c0You receive % 1 point % 2 for capturing the enemy flag ! ' , % game . SCORE_PER_PLYR_FLAG_CAP , % plural ) ;
//messageTeamExcept(%cl, 'msgCTFFriendCap', '\c0Teammate %1 receives %2 point%3 for capturing the enemy flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP, %plural); // z0dd - ZOD, 8/15/02. Message is pointless
//messageTeam(%flag.team, 'msgCTFEnemyCap', '\c0Enemy %1 received %2 point%3 for capturing your flag!', %cl.name, %game.SCORE_PER_PLYR_FLAG_CAP, %plural); // z0dd - ZOD, 8/15/02. Message is pointless
}
// ---------------------------------------------------
}
% game . recalcScore ( % cl ) ;
if ( isObject ( % flag . grabber ) )
% game . recalcScore ( % flag . grabber ) ;
% game . checkScoreLimit ( % cl . team ) ;
}
function CTFGame : : awardScoreFlagTouch ( % game , % cl , % flag )
{
% flag . grabber = % cl ;
2019-03-11 20:36:44 +00:00
% flag . grabber . flagGrabs + + ; //moved from awardScoreFlagCap to correctly count flaggrabs
2018-06-28 18:34:52 +00:00
% team = % cl . team ;
if ( $ DontScoreTimer [ % team ] )
return ;
$ dontScoreTimer [ % team ] = true ;
//tinman - needed to remove all game calls to "eval" for the PURE server...
% game . schedule ( % game . TOUCH_DELAY_MS , resetDontScoreTimer , % team ) ;
//schedule(%game.TOUCH_DELAY_MS, 0, eval, "$dontScoreTimer["@%team@"] = false;");
$ TeamScore [ % team ] + = % game . SCORE_PER_TEAM_FLAG_TOUCH ;
messageAll ( ' MsgTeamScoreIs ' , "" , % team , $ TeamScore [ % team ] ) ;
if ( % game . SCORE_PER_TEAM_FLAG_TOUCH > 0 )
{
% plural = ( % game . SCORE_PER_TEAM_FLAG_TOUCH ! = 1 ? 's' : "" ) ;
messageTeam ( % team , ' msgCTFFriendFlagTouch ' , ' \ c0Your team receives % 1 point % 2 for grabbing the enemy flag ! ' , % game . SCORE_PER_TEAM_FLAG_TOUCH , % plural ) ;
messageTeam ( % flag . team , ' msgCTFEnemyFlagTouch ' , ' \ c0Enemy % 1 receives % 2 point % 3 for grabbing your flag ! ' , % cl . name , % game . SCORE_PER_TEAM_FLAG_TOUCH , % plural ) ;
}
% game . recalcScore ( % cl ) ;
% game . checkScoreLimit ( % team ) ;
}
function CTFGame : : resetDontScoreTimer ( % game , % team )
{
$ dontScoreTimer [ % team ] = false ;
}
2025-05-14 18:51:26 +00:00
function CTFGame : : checkTimeLimit ( % game , % forced )
{
// Don't add extra checks:
if ( % forced )
cancel ( % game . timeCheck ) ;
// if there is no time limit, check back in a minute to see if it's been set
if ( ( $ Host : : TimeLimit $ = "" ) | | $ Host : : TimeLimit = = 0 )
{
% game . timeCheck = % game . schedule ( 20000 , "checkTimeLimit" ) ;
return ;
}
% curTimeLeftMS = ( $ Host : : TimeLimit * 60 * 1000 ) + $ missionStartTime - getSimTime ( ) ;
if ( % curTimeLeftMS < = 0 )
{
% teamOneCaps = mFloor ( $ TeamScore [ 1 ] / % game . SCORE_PER_TEAM_FLAG_CAP ) ;
% teamTwoCaps = mFloor ( $ TeamScore [ 2 ] / % game . SCORE_PER_TEAM_FLAG_CAP ) ;
2025-06-23 19:38:00 +00:00
if ( % teamOneCaps = = % teamTwoCaps & & $ CTF : : Overtime & & ( ( $ TeamRank [ 1 , count ] + $ TeamRank [ 2 , count ] ) > 6 ) ) {
if ( ! % game . overtime )
{
2025-05-14 18:51:26 +00:00
% game . overtime = 1 ;
if ( $ CTF : : Overtime > 1 ) { % s = "s" ; }
messageAll ( ' MsgOvertime ' , ' \ c2Sudden - Death Overtime Initiated : % 1 Minute % 2 Remaining ~ wfx / powered / turret_heavy_activate . wav ' , $ CTF : : Overtime , % s ) ;
echo ( "Sudden-Death Overtime Initiated" ) ;
UpdateClientTimes ( $ CTF : : Overtime * 60 * 1000 ) ;
EndCountdown ( $ CTF : : Overtime * 60 * 1000 ) ;
% game . timeCheck = % game . schedule ( $ CTF : : Overtime * 60 * 1000 , "timeLimitReached" ) ;
}
}
2025-06-23 19:38:00 +00:00
else
{
if ( % game . scheduleVote ! $ = "" & & ! % game . voteOT )
{
messageAll ( ' MsgOvertime ' , ' \ c2Vote Overtime Initiated . ~ wfx / powered / turret_heavy_activate . wav ' ) ;
% game . voteOT = 1 ;
2025-05-14 18:51:26 +00:00
}
2025-06-23 19:38:00 +00:00
else
{
2025-05-14 18:51:26 +00:00
% game . timeLimitReached ( ) ;
}
}
}
else
{
if ( % curTimeLeftMS > = 20000 )
% game . timeCheck = % game . schedule ( 20000 , "checkTimeLimit" ) ;
else
% game . timeCheck = % game . schedule ( % curTimeLeftMS + 1 , "checkTimeLimit" ) ;
//now synchronize everyone's clock
messageAll ( ' MsgSystemClock ' , "" , $ Host : : TimeLimit , % curTimeLeftMS ) ;
}
}
2018-06-28 18:34:52 +00:00
function CTFGame : : checkScoreLimit ( % game , % team )
{
% scoreLimit = MissionGroup . CTF_scoreLimit * % game . SCORE_PER_TEAM_FLAG_CAP ;
// default of 5 if scoreLimit not defined
if ( % scoreLimit $ = "" )
% scoreLimit = 5 * % game . SCORE_PER_TEAM_FLAG_CAP ;
2025-05-14 18:51:26 +00:00
if ( % game . overtime ) {
% teamOneCaps = mFloor ( $ TeamScore [ 1 ] / % game . SCORE_PER_TEAM_FLAG_CAP ) ;
% teamTwoCaps = mFloor ( $ TeamScore [ 2 ] / % game . SCORE_PER_TEAM_FLAG_CAP ) ;
if ( % teamOneCaps ! = % teamTwoCaps ) {
% game . scoreLimitReached ( ) ;
}
}
else {
if ( $ TeamScore [ % team ] > = % scoreLimit )
% game . scoreLimitReached ( ) ;
}
2018-06-28 18:34:52 +00:00
}
function CTFGame : : awardScoreFlagReturn ( % game , % cl , % perc )
{
2019-03-12 07:15:42 +00:00
% cl . flagReturns + + ; //give flagreturn stat
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
// ---------------------------------------------------
// z0dd - ZOD, 9/29/02. Removed T2 demo code from here
if ( % game . SCORE_PER_FLAG_RETURN ! = 0 )
{
% pts = mfloor ( % game . SCORE_PER_FLAG_RETURN * ( % perc / 100 ) ) ;
if ( % perc = = 100 )
messageClient ( % cl , ' scoreFlaRetMsg ' , ' Flag return - exceeded capping distance - % 1 point bonus . ' , % pts , % perc ) ;
else if ( % perc = = 0 )
messageClient ( % cl , ' scoreFlaRetMsg ' , ' You gently place the flag back on the stand . ' , % pts , % perc ) ;
2022-02-18 19:34:07 +00:00
else
2018-06-28 18:34:52 +00:00
messageClient ( % cl , ' scoreFlaRetMsg ' , ' \ c0Flag return from % 2 % % of capping distance - % 1 point bonus . ' , % pts , % perc ) ;
% cl . returnPts + = % pts ;
}
% game . recalcScore ( % cl ) ;
return % game . SCORE_PER_FLAG_RETURN ;
// ---------------------------------------------------
}
function CTFGame : : awardScoreStalemateReturn ( % game , % cl )
{
if ( % game . SCORE_PER_STALEMATE_RETURN ! = 0 )
{
messageClient ( % cl , ' scoreStaleRetMsg ' , ' \ c0You received a % 1 point bonus for a stalemate - breaking , flag return . ' , % game . SCORE_PER_STALEMATE_RETURN ) ;
% cl . returnPts + = % game . SCORE_PER_STALEMATE_RETURN ;
}
% game . recalcScore ( % cl ) ;
return % game . SCORE_PER_STALEMATE_RETURN ;
}
function CTFGame : : awardScoreGenDefend ( % game , % killerID )
{
% killerID . genDefends + + ;
if ( % game . SCORE_PER_GEN_DEFEND ! = 0 )
{
messageClient ( % killerID , ' msgGenDef ' , ' \ c0You received a % 1 point bonus for defending a generator . ' , % game . SCORE_PER_GEN_DEFEND ) ;
messageTeamExcept ( % killerID , ' msgGenDef ' , ' \ c2 % 1 defended our generator from an attack . ' , % killerID . name ) ; // z0dd - ZOD, 8/15/02. Tell team
//messageTeamExcept(%killerID, 'msgGenDef', '\c0Teammate %1 received a %2 point bonus for defending a generator.', %killerID.name, %game.SCORE_PER_GEN_DEFEND);
}
% game . recalcScore ( % cl ) ;
return % game . SCORE_PER_GEN_DEFEND ;
}
function CTFGame : : awardScoreCarrierKill ( % game , % killerID )
{
% killerID . carrierKills + + ;
if ( % game . SCORE_PER_CARRIER_KILL ! = 0 )
{
messageClient ( % killerID , ' msgCarKill ' , ' \ c0You received a % 1 point bonus for stopping the enemy flag carrier ! ' , % game . SCORE_PER_CARRIER_KILL ) ;
messageTeamExcept ( % killerID , ' msgCarKill ' , ' \ c2 % 1 stopped the enemy flag carrier . ' , % killerID . name ) ; // z0dd - ZOD, 8/15/02. Tell team
//messageTeamExcept(%killerID, 'msgCarKill', '\c0Teammate %1 received a %2 point bonus for stopping the enemy flag carrier!', %killerID.name, %game.SCORE_PER_CARRIER_KILL);
}
2022-02-18 19:34:07 +00:00
% game . recalcScore ( % killerID ) ;
2018-06-28 18:34:52 +00:00
return % game . SCORE_PER_CARRIER_KILL ;
}
function CTFGame : : awardScoreFlagDefend ( % game , % killerID )
{
% killerID . flagDefends + + ;
if ( % game . SCORE_PER_FLAG_DEFEND ! = 0 )
{
messageClient ( % killerID , ' msgFlagDef ' , ' \ c0You received a % 1 point bonus for defending your flag ! ' , % game . SCORE_PER_FLAG_DEFEND ) ;
messageTeamExcept ( % killerID , ' msgFlagDef ' , ' \ c2 % 1 defended our flag . ' , % killerID . name ) ; // z0dd - ZOD, 8/15/02. Tell team
//messageTeamExcept(%killerID, 'msgFlagDef', '\c0Teammate %1 received a %2 point bonus for defending your flag!', %killerID.name, %game.SCORE_PER_FLAG_DEFEND);
2022-02-18 19:34:07 +00:00
}
2018-06-28 18:34:52 +00:00
% game . recalcScore ( % killerID ) ;
return % game . SCORE_PER_FLAG_DEFEND ;
}
function CTFGame : : awardScoreEscortAssist ( % game , % killerID )
{
% killerID . escortAssists + + ;
if ( % game . SCORE_PER_ESCORT_ASSIST ! = 0 )
{
messageClient ( % killerID , ' msgEscAsst ' , ' \ c0You received a % 1 point bonus for protecting the flag carrier ! ' , % game . SCORE_PER_ESCORT_ASSIST ) ;
messageTeamExcept ( % killerID , ' msgEscAsst ' , ' \ c2 % 1 protected our flag carrier . ' , % killerID . name ) ; // z0dd - ZOD, 8/15/02. Tell team
//messageTeamExcept(%killerID, 'msgEscAsst', '\c0Teammate %1 received a %2 point bonus for protecting the flag carrier!', %killerID.name, %game.SCORE_PER_ESCORT_ASSIST);
}
% game . recalcScore ( % killerID ) ;
return % game . SCORE_PER_ESCORT_ASSIST ;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Asset Destruction scoring ////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// z0dd - ZOD, 10/03/02. Penalty for TKing equiptment.
function CTFGame : : awardScoreTkDestroy ( % game , % cl , % obj )
{
% cl . tkDestroys + + ;
messageTeamExcept ( % cl , ' msgTkDes ' , ' \ c5Teammate % 1 destroyed your team \ ' s % 3 objective ! ' , % cl . name , % game . cleanWord ( % obj . getDataBlock ( ) . targetTypeTag ) ) ;
messageClient ( % cl , ' msgTkDes ' , ' \ c0You have been penalized % 1 points for destroying your teams equiptment . ' , % game . SCORE_PER_TK_DESTROY ) ;
% game . recalcScore ( % cl ) ;
% game . shareScore ( % cl , % game . SCORE_PER_TK_DESTROY ) ;
}
function CTFGame : : awardScoreStaticShapeDestroy ( % game , % cl , % obj )
{
% dataName = % obj . getDataBlock ( ) . getName ( ) ;
switch $ ( % dataName )
{
case "GeneratorLarge" :
% cl . genDestroys + + ;
% value = % game . SCORE_PER_DESTROY_GEN ;
% msgType = ' msgGenDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy % 2 Generator ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy generator . ' ;
case "SolarPanel" :
% cl . solarDestroys + + ;
% value = % game . SCORE_PER_DESTROY_SOLAR ;
% msgType = ' msgSolarDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy % 2 Solar Panel ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy solar panel . ' ;
case "SensorLargePulse" or "SensorMediumPulse" :
% cl . sensorDestroys + + ;
% value = % game . SCORE_PER_DESTROY_SENSOR ;
% msgType = ' msgSensorDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy % 2 Sensor ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy pulse sensor . ' ;
case "TurretBaseLarge" :
% cl . turretDestroys + + ;
% value = % game . SCORE_PER_DESTROY_TURRET ;
% msgType = ' msgTurretDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy % 2 Turret ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy base turret . ' ;
case "StationInventory" :
% cl . IStationDestroys + + ;
% value = % game . SCORE_PER_DESTROY_ISTATION ;
% msgType = ' msgInvDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy % 2 Inventory Station ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy inventory station . ' ;
case "StationAmmo" :
% cl . aStationDestroys + + ;
% value = % game . SCORE_PER_DESTROY_ASTATION ;
% msgType = ' msgAmmoDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy % 2 Ammo Station ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy ammo station . ' ;
case "StationVehicle" :
% cl . VStationDestroys + + ;
% value = % game . SCORE_PER_DESTROY_VSTATION ;
% msgType = ' msgVSDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy Vehicle Station ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy vehicle station . ' ;
case "SentryTurret" :
% cl . sentryDestroys + + ;
% value = % game . SCORE_PER_DESTROY_SENTRY ;
% msgType = ' msgSentryDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy % 2 Sentry Turret ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy sentry turret . ' ;
case "DeployedMotionSensor" or "DeployedPulseSensor" :
% cl . depSensorDestroys + + ;
% value = % game . SCORE_PER_DESTROY_DEP_SENSOR ;
% msgType = ' msgDepSensorDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy Deployed Sensor ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy deployed sensor . ' ;
case "TurretDeployedWallIndoor" or "TurretDeployedFloorIndoor" or "TurretDeployedCeilingIndoor" :
% cl . depTurretDestroys + + ;
% value = % game . SCORE_PER_DESTROY_DEP_TUR ;
% msgType = ' msgDepTurDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy Deployed Spider Clamp Turret ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy deployed spider clamp turret . ' ;
case "TurretDeployedOutdoor" :
% cl . depTurretDestroys + + ;
% value = % game . SCORE_PER_DESTROY_DEP_TUR ;
% msgType = ' msgDepTurDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy Deployed Landspike Turret ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy deployed landspike turret . ' ;
case "DeployedStationInventory" :
% cl . depStationDestroys + + ;
% value = % game . SCORE_PER_DESTROY_DEP_INV ;
% msgType = ' msgDepInvDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy Deployed Station ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy deployed station . ' ;
case "MPBTeleporter" :
% cl . mpbtstationDestroys + + ;
% value = % game . SCORE_PER_DESTROY_MPBTSTATION ;
% msgType = ' msgMPBTeleDes ' ;
% tMsg = ' \ c5 % 1 destroyed an enemy MPB Teleport Station ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for destroying an enemy MPB teleport station . ' ;
default :
return ;
}
2020-03-26 16:52:12 +00:00
if ( isObject ( % cl ) )
{
teamDestroyMessage ( % cl , ' MsgDestroyed ' , % tMsg , % cl . name , % obj . nameTag ) ;
messageClient ( % cl , % msgType , % clMsg , % value , % dataName ) ;
% game . recalcScore ( % cl ) ;
% game . shareScore ( % scorer , % value ) ;
}
else //when the asset attacker is unknown
teamDestroyMessage ( % cl , ' MsgDestroyed ' , % tMsg , "A teammate" , % obj . nameTag ) ;
2018-06-28 18:34:52 +00:00
}
/////////////////////////////////////////////////////////////////////////////////////////
// Repair Scoring Functions /////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
function CTFGame : : testValidRepair ( % game , % obj )
{
if ( ! % obj . wasDisabled )
return false ;
else if ( % obj . lastDamagedByTeam = = % obj . team )
return false ;
else if ( % obj . team ! = % obj . repairedBy . team )
return false ;
2022-02-18 19:34:07 +00:00
else
2018-06-28 18:34:52 +00:00
{
if ( % obj . soiledByEnemyRepair )
% obj . soiledByEnemyRepair = false ;
return true ;
}
}
function CTFGame : : objectRepaired ( % game , % obj , % objName )
{
% game . staticShapeOnRepaired ( % obj , % objName ) ;
% obj . wasDisabled = false ;
}
function CTFGame : : staticShapeOnRepaired ( % game , % obj , % objName )
{
if ( % game . testValidRepair ( % obj ) )
{
% repairman = % obj . repairedBy ;
% dataName = % obj . getDataBlock ( ) . getName ( ) ;
switch $ ( % dataName )
{
case "GeneratorLarge" :
% repairman . genRepairs + + ;
% score = % game . SCORE_PER_REPAIR_GEN ;
% tMsgType = ' msgGenRepaired ' ;
% msgType = ' msgGenRep ' ;
% tMsg = ' \ c0 % 1 repaired the % 2 Generator ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a generator . ' ;
case "SolarPanel" :
% repairman . solarRepairs + + ;
% score = % game . SCORE_PER_REPAIR_SOLAR ;
% tMsgType = ' msgsolarRepaired ' ;
% msgType = ' msgsolarRep ' ;
% tMsg = ' \ c0 % 1 repaired the % 2 Solar Panel ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a solar panel . ' ;
case "SensorLargePulse" or "SensorMediumPulse" :
% repairman . sensorRepairs + + ;
% score = % game . SCORE_PER_REPAIR_SENSOR ;
% tMsgType = ' msgSensorRepaired ' ;
% msgType = ' msgSensorRep ' ;
% tMsg = ' \ c0 % 1 repaired the % 2 Pulse Sensor ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a pulse sensor . ' ;
case "StationInventory" or "StationAmmo" :
% repairman . stationRepairs + + ;
% score = % game . SCORE_PER_REPAIR_ISTATION ;
% tMsgType = ' msgStationRepaired ' ;
% msgType = ' msgIStationRep ' ;
% tMsg = ' \ c0 % 1 repaired the % 2 Station ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a station . ' ;
case "StationVehicle" :
% repairman . VStationRepairs + + ;
% score = % game . SCORE_PER_REPAIR_VSTATION ;
% tMsgType = ' msgvstationRepaired ' ;
% msgType = ' msgVStationRep ' ;
% tMsg = ' \ c0 % 1 repaired the Vehicle Station ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a vehicle station . ' ;
case "TurretBaseLarge" :
% repairman . TurretRepairs + + ;
% score = % game . SCORE_PER_REPAIR_TURRET ;
% tMsgType = ' msgTurretRepaired ' ;
% msgType = ' msgTurretRep ' ;
% tMsg = ' \ c0 % 1 repaired the % 2 Turret ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a base turret . ' ;
case "SentryTurret" :
% repairman . sentryRepairs + + ;
% score = % game . SCORE_PER_REPAIR_SENTRY ;
% tMsgType = ' msgsentryTurretRepaired ' ;
% msgType = ' msgSentryRep ' ;
% tMsg = ' \ c0 % 1 repaired the % 2 Sentry Turret ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a sentry turret . ' ;
case "DeployedMotionSensor" or "DeployedPulseSensor" :
% repairman . depSensorRepairs + + ;
% tMsgType = ' msgDepSensorRepaired ' ;
% msgType = ' msgDepSensorRep ' ;
% score = % game . SCORE_PER_REPAIR_DEP_SENSOR ;
% tMsg = ' \ c0 % 1 repaired a Deployed Sensor ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a deployed sensor . ' ;
case "TurretDeployedWallIndoor" or "TurretDeployedFloorIndoor" or "TurretDeployedCeilingIndoor" :
% repairman . depTurretRepairs + + ;
% score = % game . SCORE_PER_REPAIR_DEP_TUR ;
% tMsgType = ' msgDepTurretRepaired ' ;
% msgType = ' msgDepTurretRep ' ;
% tMsg = ' \ c0 % 1 repaired a Spider Clamp Turret ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a deployable spider clamp turret . ' ;
case "TurretDeployedOutdoor" :
% repairman . depTurretRepairs + + ;
% score = % game . SCORE_PER_REPAIR_DEP_TUR ;
% tMsgType = ' msgDepTurretRepaired ' ;
% msgType = ' msgDepTurretRep ' ;
% tMsg = ' \ c0 % 1 repaired a Landspike Turret ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a deployable landspike turret . ' ;
case "DeployedStationInventory" :
% repairman . depInvRepairs + + ;
% score = % game . SCORE_PER_REPAIR_DEP_INV ;
% tMsgType = ' msgDepInvRepaired ' ;
% msgType = ' msgDepInvRep ' ;
% tMsg = ' \ c0 % 1 repaired a Deployable Station ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a deployed station . ' ;
case "MPBTeleporter" :
% repairman . mpbtstationRepairs + + ;
% score = % game . SCORE_PER_REPAIR_MPBTSTATION ;
% tMsgType = ' msgMPBTeleRepaired ' ;
% msgType = ' msgMPBTeleRep ' ;
% tMsg = ' \ c0 % 1 repaired the MPB Teleporter Station ! ' ;
% clMsg = ' \ c0You received a % 1 point bonus for repairing a mpb teleporter station . ' ;
default :
return ;
}
teamRepairMessage ( % repairman , % tMsgType , % tMsg , % repairman . name , % obj . nameTag ) ;
messageClient ( % repairman , % msgType , % clMsg , % score , % dataName ) ;
% game . recalcScore ( % repairman ) ;
}
}
// ---------------------------------------------------------
function CTFGame : : resetScore ( % game , % client )
{
% client . offenseScore = 0 ;
% client . kills = 0 ;
2018-09-26 05:01:41 +00:00
% client . scoreMidAir = 0 ;
2018-06-28 18:34:52 +00:00
% client . deaths = 0 ;
% client . suicides = 0 ;
% client . escortAssists = 0 ;
% client . teamKills = 0 ;
% client . tkDestroys = 0 ; // z0dd - ZOD, 10/03/02. Penalty for tking equiptment.
% client . flagCaps = 0 ;
% client . flagGrabs = 0 ;
% client . genDestroys = 0 ;
% client . sensorDestroys = 0 ;
% client . turretDestroys = 0 ;
% client . iStationDestroys = 0 ;
% client . vstationDestroys = 0 ;
% client . mpbtstationDestroys = 0 ; // z0dd - ZOD 3/30/02. MPB Teleporter
% client . solarDestroys = 0 ;
% client . sentryDestroys = 0 ;
% client . depSensorDestroys = 0 ;
% client . depTurretDestroys = 0 ;
% client . depStationDestroys = 0 ;
2022-02-18 19:34:07 +00:00
% client . vehicleScore = 0 ;
% client . vehicleBonus = 0 ;
2018-06-28 18:34:52 +00:00
% client . flagDefends = 0 ;
% client . defenseScore = 0 ;
% client . genDefends = 0 ;
% client . carrierKills = 0 ;
% client . escortAssists = 0 ;
% client . turretKills = 0 ;
% client . mannedTurretKills = 0 ;
% client . flagReturns = 0 ;
% client . genRepairs = 0 ;
% client . SensorRepairs = 0 ;
% client . TurretRepairs = 0 ;
% client . StationRepairs = 0 ;
% client . VStationRepairs = 0 ;
% client . mpbtstationRepairs = 0 ; // z0dd - ZOD 3/30/02. MPB Teleporter
% client . solarRepairs = 0 ;
% client . sentryRepairs = 0 ;
% client . depSensorRepairs = 0 ; // z0dd - ZOD 5/27/03. Deployed sensors
% client . depInvRepairs = 0 ;
% client . depTurretRepairs = 0 ;
% client . returnPts = 0 ;
% client . score = 0 ;
}
function CTFGame : : enterMissionArea ( % game , % playerData , % player )
{
if ( % player . getState ( ) $ = "Dead" )
return ;
2022-02-18 19:34:07 +00:00
% player . client . outOfBounds = false ;
2018-06-28 18:34:52 +00:00
messageClient ( % player . client , ' EnterMissionArea ' , ' \ c1You are back in the mission area . ' ) ;
logEcho ( % player . client . nameBase @" (pl " @ % player @"/cl " @ % player . client @") entered mission area" ) ;
//the instant a player leaves the mission boundary, the flag is dropped, and the return is scheduled...
if ( % player . holdingFlag > 0 )
{
cancel ( $ FlagReturnTimer [ % player . holdingFlag ] ) ;
$ FlagReturnTimer [ % player . holdingFlag ] = "" ;
}
}
function CTFGame : : leaveMissionArea ( % game , % playerData , % player )
{
if ( % player . getState ( ) $ = "Dead" )
return ;
// maybe we'll do this just in case
% player . client . outOfBounds = true ;
// if the player is holding a flag, strip it and throw it back into the mission area
// otherwise, just print a message
if ( % player . holdingFlag > 0 )
% game . boundaryLoseFlag ( % player ) ;
else
messageClient ( % player . client , ' MsgLeaveMissionArea ' , ' \ c1You have left the mission area . ~ wfx / misc / warning_beep . wav ' ) ;
logEcho ( % player . client . nameBase @" (pl " @ % player @"/cl " @ % player . client @") left mission area" ) ;
}
function CTFGame : : boundaryLoseFlag ( % game , % player )
{
// this is called when a player goes out of the mission area while holding
// the enemy flag. - make sure the player is still out of bounds
if ( ! % player . client . outOfBounds | | ! isObject ( % player . holdingFlag ) )
return ;
// ------------------------------------------------------------------------------
// z0dd - ZOD - SquirrelOfDeath, 9/27/02. Delay on grabbing flag after tossing it
% player . flagTossWait = true ;
% player . schedule ( 1000 , resetFlagTossWait ) ;
// ------------------------------------------------------------------------------
% client = % player . client ;
% flag = % player . holdingFlag ;
% flag . setVelocity ( "0 0 0" ) ;
% flag . setTransform ( % player . getWorldBoxCenter ( ) ) ;
% flag . setCollisionTimeout ( % player ) ;
% held = % game . formatTime ( getSimTime ( ) - % game . flagHeldTime [ % flag ] , false ) ; // z0dd - ZOD, 8/15/02. How long did player hold flag?
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
% game . playerDroppedFlag ( % player ) ;
// now for the tricky part -- throwing the flag back into the mission area
// let's try throwing it back towards its "home"
% home = % flag . originalPosition ;
% vecx = firstWord ( % home ) - firstWord ( % player . getWorldBoxCenter ( ) ) ;
% vecy = getWord ( % home , 1 ) - getWord ( % player . getWorldBoxCenter ( ) , 1 ) ;
% vecz = getWord ( % home , 2 ) - getWord ( % player . getWorldBoxCenter ( ) , 2 ) ;
% vec = % vecx SPC % vecy SPC % vecz ;
// normalize the vector, scale it, and add an extra "upwards" component
% vecNorm = VectorNormalize ( % vec ) ;
% vec = VectorScale ( % vecNorm , 1500 ) ;
% vec = vectorAdd ( % vec , "0 0 500" ) ;
// z0dd - ZOD, 6/09/02. Remove anti-hover so flag can be thrown properly
% flag . static = false ;
// z0dd - ZOD, 10/02/02. Hack for flag collision bug.
% flag . searchSchedule = % game . schedule ( 10 , "startFlagCollisionSearch" , % flag ) ;
// apply the impulse to the flag object
% flag . applyImpulse ( % player . getWorldBoxCenter ( ) , % vec ) ;
//don't forget to send the message
//messageClient(%player.client, 'MsgCTFFlagDropped', '\c1You have left the mission area and lost the flag.~wfx/misc/flag_drop.wav', 0, 0, %player.holdingFlag.team);
// z0dd - ZOD 3/30/02. Above message was sending the wrong varible to objective hud.
messageClient ( % player . client , ' MsgCTFFlagDropped ' , ' \ c1You have left the mission area and lost the flag . ( Held : % 4 ) ~ wfx / misc / flag_drop . wav ' , % client . name , 0 , % flag . team , % held ) ; // Yogi, 8/18/02. 3rd param changed 0 -> %client.name
logEcho ( % player . client . nameBase @" (pl " @ % player @"/cl " @ % player . client @") lost flag (out of bounds)" @" (Held: " @ % held @")" ) ;
}
function CTFGame : : dropFlag ( % game , % player )
{
if ( % player . holdingFlag > 0 )
{
if ( ! % player . client . outOfBounds )
% player . throwObject ( % player . holdingFlag ) ;
else
% game . boundaryLoseFlag ( % player ) ;
}
2018-08-07 06:50:49 +00:00
2018-06-28 18:34:52 +00:00
}
function CTFGame : : applyConcussion ( % game , % player )
{
% game . dropFlag ( % player ) ;
}
function CTFGame : : vehicleDestroyed ( % game , % vehicle , % destroyer )
{
//vehicle name
% data = % vehicle . getDataBlock ( ) ;
//%vehicleType = getTaggedString(%data.targetNameTag) SPC getTaggedString(%data.targetTypeTag);
% vehicleType = getTaggedString ( % data . targetTypeTag ) ;
if ( % vehicleType ! $ = "MPB" )
% vehicleType = strlwr ( % vehicleType ) ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
% enemyTeam = ( % destroyer . team = = 1 ) ? 2 : 1 ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
% scorer = 0 ;
% multiplier = 1 ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
% passengers = 0 ;
for ( % i = 0 ; % i < % data . numMountPoints ; % i + + )
if ( % vehicle . getMountNodeObject ( % i ) )
% passengers + + ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
//what destroyed this vehicle
if ( % destroyer . client )
{
//it was a player, or his mine, satchel, whatever...
% destroyer = % destroyer . client ;
% scorer = % destroyer ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
// determine if the object used was a mine
if ( % vehicle . lastDamageType = = $ DamageType : : Mine )
% multiplier = 2 ;
2022-02-18 19:34:07 +00:00
}
2018-06-28 18:34:52 +00:00
else if ( % destroyer . getClassName ( ) $ = "Turret" )
{
if ( % destroyer . getControllingClient ( ) )
{
//manned turret
% destroyer = % destroyer . getControllingClient ( ) ;
% scorer = % destroyer ;
}
2022-02-18 19:34:07 +00:00
else
2018-06-28 18:34:52 +00:00
{
% destroyerName = "A turret" ;
% multiplier = 0 ;
}
2022-02-18 19:34:07 +00:00
}
2018-06-28 18:34:52 +00:00
else if ( % destroyer . getDataBlock ( ) . catagory $ = "Vehicles" )
{
// Vehicle vs vehicle kill!
if ( % name $ = "BomberFlyer" | | % name $ = "AssaultVehicle" )
% gunnerNode = 1 ;
else
% gunnerNode = 0 ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
if ( % destroyer . getMountNodeObject ( % gunnerNode ) )
{
% destroyer = % destroyer . getMountNodeObject ( % gunnerNode ) . client ;
% scorer = % destroyer ;
}
% multiplier = 3 ;
}
else // Is there anything else we care about?
return ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
if ( % destroyerName $ = "" )
% destroyerName = % destroyer . name ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
if ( % vehicle . team = = % destroyer . team ) // team kill
{
% pref = ( % vehicleType $ = "Assault Tank" ) ? "an" : "a" ;
messageAll ( ' msgVehicleTeamDestroy ' , ' \ c0 % 1 TEAMKILLED % 3 % 2 ! ' , % destroyerName , % vehicleType , % pref ) ;
}
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
else // legit kill
{
//messageTeamExcept(%destroyer, 'msgVehicleDestroy', '\c0%1 destroyed an enemy %2.', %destroyerName, %vehicleType); // z0dd - ZOD, 8/20/02. not needed with new messenger on line below
teamDestroyMessage ( % destroyer , ' msgVehDestroyed ' , ' \ c5 % 1 destroyed an enemy % 2 ! ' , % destroyerName , % vehicleType ) ; // z0dd - ZOD, 8/20/02. Send teammates a destroy message
messageTeam ( % enemyTeam , ' msgVehicleDestroy ' , ' \ c0 % 1 destroyed your team \ ' s % 2. ' , % destroyerName , % vehicleType ) ;
//messageClient(%destroyer, 'msgVehicleDestroy', '\c0You destroyed an enemy %1.', %vehicleType);
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
if ( % scorer )
{
% value = % game . awardScoreVehicleDestroyed ( % scorer , % vehicleType , % multiplier , % passengers ) ;
% game . shareScore ( % value ) ;
}
}
}
function CTFGame : : awardScoreVehicleDestroyed ( % game , % client , % vehicleType , % mult , % passengers )
{
// z0dd - ZOD, 9/29/02. Removed T2 demo code from here
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
if ( % vehicleType $ = "Grav Cycle" )
% base = % game . SCORE_PER_DESTROY_WILDCAT ;
else if ( % vehicleType $ = "Assault Tank" )
% base = % game . SCORE_PER_DESTROY_TANK ;
else if ( % vehicleType $ = "MPB" )
% base = % game . SCORE_PER_DESTROY_MPB ;
else if ( % vehicleType $ = "Turbograv" )
% base = % game . SCORE_PER_DESTROY_SHRIKE ;
else if ( % vehicleType $ = "Bomber" )
% base = % game . SCORE_PER_DESTROY_BOMBER ;
else if ( % vehicleType $ = "Heavy Transport" )
% base = % game . SCORE_PER_DESTROY_TRANSPORT ;
2022-02-18 19:34:07 +00:00
% total = ( % base * % mult ) + ( % passengers * % game . SCORE_PER_PASSENGER ) ;
2018-06-28 18:34:52 +00:00
% client . vehicleScore + = % total ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
messageClient ( % client , ' msgVehicleScore ' , ' \ c0You received a % 1 point bonus for destroying an enemy % 2. ' , % total , % vehicleType ) ;
% game . recalcScore ( % client ) ;
return % total ;
}
function CTFGame : : shareScore ( % game , % client , % amount )
{
2022-02-18 19:34:07 +00:00
// z0dd - ZOD, 9/29/02. Removed T2 demo code from here
//error("share score of"SPC %amount SPC "from client:" SPC %client);
2018-06-28 18:34:52 +00:00
// all of the player in the bomber and tank share the points
// gained from any of the others
% vehicle = % client . vehicleMounted ;
if ( ! % vehicle )
return 0 ;
% vehicleType = getTaggedString ( % vehicle . getDataBlock ( ) . targetTypeTag ) ;
if ( % vehicleType $ = "Bomber" | | % vehicleType $ = "Assault Tank" )
{
for ( % i = 0 ; % i < % vehicle . getDataBlock ( ) . numMountPoints ; % i + + )
{
% occupant = % vehicle . getMountNodeObject ( % i ) ;
if ( % occupant )
{
% occCl = % occupant . client ;
if ( % occCl ! = % client & & % occCl . team = = % client . team )
{
// the vehicle has a valid teammate at this node
// share the score with them
% occCl . vehicleBonus + = % amount ;
% game . recalcScore ( % occCl ) ;
}
2022-02-18 19:34:07 +00:00
}
2018-06-28 18:34:52 +00:00
}
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
}
}
function CTFGame : : awardScoreTurretKill ( % game , % victimID , % implement )
{
if ( ( % killer = % implement . getControllingClient ( ) ) ! = 0 ) //award whoever might be controlling the turret
{
if ( % killer = = % victimID )
% game . awardScoreSuicide ( % victimID ) ;
2022-02-18 19:34:07 +00:00
else if ( % killer . team = = % victimID . team ) //player controlling a turret killed a teammate
2018-06-28 18:34:52 +00:00
{
% killer . teamKills + + ;
% game . awardScoreTurretTeamKill ( % victimID , % killer ) ;
% game . awardScoreDeath ( % victimID ) ;
}
else
{
% killer . mannedturretKills + + ;
% game . recalcScore ( % killer ) ;
% game . awardScoreDeath ( % victimID ) ;
2022-02-18 19:34:07 +00:00
}
}
2018-06-28 18:34:52 +00:00
else if ( ( % killer = % implement . owner ) ! = 0 ) //if it isn't controlled, award score to whoever deployed it
{
2022-02-18 19:34:07 +00:00
if ( % killer . team = = % victimID . team )
2018-06-28 18:34:52 +00:00
{
% game . awardScoreDeath ( % victimID ) ;
}
2022-02-18 19:34:07 +00:00
else
2018-06-28 18:34:52 +00:00
{
% killer . turretKills + + ;
% game . recalcScore ( % killer ) ;
% game . awardScoreDeath ( % victimID ) ;
}
2022-02-18 19:34:07 +00:00
}
//default is, no one was controlling it, no one owned it. No score given.
2018-06-28 18:34:52 +00:00
}
function CTFGame : : testKill ( % game , % victimID , % killerID )
{
return ( ( % killerID ! = 0 ) & & ( % victimID . team ! = % killerID . team ) ) ;
}
function CTFGame : : awardScoreKill ( % game , % killerID )
{
2022-02-18 19:34:07 +00:00
% killerID . kills + + ;
% game . recalcScore ( % killerID ) ;
2018-06-28 18:34:52 +00:00
return % game . SCORE_PER_KILL ;
}
function checkVehicleCamping ( % team )
{
% position = $ flagPos [ % team ] ;
2020-08-31 21:47:40 +00:00
% radius = 15 ;
2018-06-28 18:34:52 +00:00
InitContainerRadiusSearch ( % position , % radius , $ TypeMasks : : VehicleObjectType ) ;
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
while ( ( % vehicle = containerSearchNext ( ) ) ! = 0 )
{
% dist = containerSearchCurrRadDamageDist ( ) ;
if ( % dist > % radius )
continue ;
else
2022-02-18 19:34:07 +00:00
{
2018-06-28 18:34:52 +00:00
//if( %vehicle.team == %team )
applyVehicleCampDamage ( % vehicle ) ;
}
}
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
if ( % team = = 1 )
Game . campThread_1 = schedule ( 1000 , 0 , "checkVehicleCamping" , 1 ) ;
else
Game . campThread_2 = schedule ( 1000 , 0 , "checkVehicleCamping" , 2 ) ;
}
function applyVehicleCampDamage ( % vehicle )
{
if ( ! isObject ( % vehicle ) )
return ;
if ( % vehicle . getDamageState ( ) $ = "Destroyed" )
return ;
% client = % vehicle . getMountNodeObject ( 0 ) . client ; // grab the pilot
2022-02-18 19:34:07 +00:00
2018-06-28 18:34:52 +00:00
messageClient ( % client , ' serverMessage ' , "Can't park vehicles in flag zones!" ) ;
2022-02-18 19:34:07 +00:00
% vehicle . getDataBlock ( ) . damageObject ( % vehicle , 0 , "0 0 0" , 0.5 , 0 ) ;
2018-06-28 18:34:52 +00:00
}
// z0dd - ZOD, 10/02/02. Hack for flag collision bug.
function CTFGame : : startFlagCollisionSearch ( % game , % flag )
{
% flag . searchSchedule = % game . schedule ( 10 , "startFlagCollisionSearch" , % flag ) ; // SquirrelOfDeath, 10/02/02. Moved from after the while loop
% pos = % flag . getWorldBoxCenter ( ) ;
InitContainerRadiusSearch ( % pos , 1.0 , $ TypeMasks : : VehicleObjectType | $ TypeMasks : : CorpseObjectType | $ TypeMasks : : PlayerObjectType ) ;
while ( ( % found = containerSearchNext ( ) ) ! = 0 )
{
% flag . getDataBlock ( ) . onCollision ( % flag , % found ) ;
// SquirrelOfDeath, 10/02/02. Removed break to catch all players possibly intersecting with flag
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// VOTING ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
2022-06-12 14:38:43 +00:00
// function CTFGame::sendGameVoteMenu(%game, %client, %key)
// {
// DefaultGame::sendGameVoteMenu(%game, %client, %key);
// if ( %game.scheduleVote $= "" )
// {
// if(%client.isAdmin)
// messageClient( %client, 'MsgVoteItem', "", %key, 'VoteAntiTurtleTime', 'change the anti turtle time to', 'Change Anti-Turtle time' );
// else
// messageClient( %client, 'MsgVoteItem', "", %key, 'VoteAntiTurtleTime', 'change the anti turtle time to', 'Vote Anti-Turtle time' );
// }
// }
// function CTFGame::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4)
// {
// DefaultGame::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4);
// switch$ (%typeName)
// {
// case "voteAntiTurtleTime":
// %game.voteAntiTurtleTime(%admin, %arg1, %arg2, %arg3, %arg4);
// }
// }
// function CTFGame::sendAntiTurtleTimeList( %game, %client, %key )
// {
// messageClient( %client, 'MsgVoteItem', "", %key, 6, "", '6 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 8, "", '8 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 10, "", '10 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 12, "", '12 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 14, "", '14 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 16, "", '16 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 18, "", '18 minutes' );
// messageClient( %client, 'MsgVoteItem', "", %key, 200, "", 'Disable Anti Turtle' );
// }
2018-06-28 18:34:52 +00:00
function CTFGame : : voteAntiTurtleTime ( % game , % admin , % newLimit )
{
if ( % newLimit = = 200 )
% display = "disabled" ;
else
% display = % newLimit ;
% cause = "" ;
if ( % admin )
{
messageAll ( ' MsgAdminForce ' , ' \ c3 % 1 \ c2 set the anti - turtle time to % 2. ~ wfx / misc / diagnostic_on . wav ' , $ AdminCl . name , % display ) ;
$ Host : : ClassicAntiTurtleTime = % newLimit ;
% cause = "(admin)" ;
}
else
{
% totalVotes = % game . totalVotesFor + % game . totalVotesAgainst ;
2022-02-18 19:34:07 +00:00
if ( % totalVotes > 0 & & ( % game . totalVotesFor / ( ClientGroup . getCount ( ) - $ HostGameBotCount ) ) > ( $ Host : : VotePasspercent / 100 ) )
2018-06-28 18:34:52 +00:00
{
2022-02-18 19:34:07 +00:00
messageAll ( ' MsgVotePassed ' , ' \ c2The anti - turtle time is set to % 1. ' , % display ) ;
2018-06-28 18:34:52 +00:00
$ Host : : ClassicAntiTurtleTime = % newLimit ;
% cause = "(vote)" ;
}
2022-02-18 19:34:07 +00:00
else
messageAll ( ' MsgVoteFailed ' , ' \ c2The vote to change the anti - turtle time did not pass : % 1 percent . ' , mFloor ( % game . totalVotesFor / ( ClientGroup . getCount ( ) - $ HostGameBotCount ) * 100 ) ) ;
2018-06-28 18:34:52 +00:00
}
if ( % cause ! $ = "" )
logEcho ( $ AdminCl . name @ ": anti-turtle time set to " @ % display SPC % cause , 1 ) ;
}