2023-04-13 17:30:38 +02:00

1398 lines
50 KiB
Plaintext

#using scripts\shared\challenges_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\demo_shared;
#using scripts\shared\gameobjects_shared;
#using scripts\shared\hud_message_shared;
#using scripts\shared\hud_util_shared;
#using scripts\shared\math_shared;
#using scripts\shared\popups_shared;
#using scripts\shared\rank_shared;
#using scripts\shared\scoreevents_shared;
#using scripts\shared\sound_shared;
#using scripts\shared\system_shared;
#using scripts\shared\util_shared;
#using scripts\mp\gametypes\_globallogic;
#using scripts\mp\gametypes\_globallogic_audio;
#using scripts\mp\gametypes\_globallogic_defaults;
#using scripts\mp\gametypes\_globallogic_score;
#using scripts\mp\gametypes\_globallogic_utils;
#using scripts\mp\gametypes\_hud_message;
#using scripts\mp\gametypes\_spawning;
#using scripts\mp\gametypes\_spawnlogic;
#using scripts\mp\_challenges;
#using scripts\mp\_util;
#using scripts\mp\teams\_teams;
/*
CTF
Level requirements
------------------
Allied Spawnpoints:
classname mp_sd_spawn_attacker
Allied players spawn from these. Place at least 16 of these relatively close together.
Axis Spawnpoints:
classname mp_sd_spawn_defender
Axis players spawn from these. Place at least 16 of these relatively close together.
Spectator Spawnpoints:
classname mp_global_intermission
Spectators spawn from these and intermission is viewed from these positions.
Atleast one is required, any more and they are randomly chosen between.
Flag:
classname trigger_multiple
targetname flagtrigger
script_gameobjectname ctf
script_label Set to name of flag. This sets the letter shown on the compass in original mode.
script_team Set to allies or axis. This is used to set which team a flag is used by.
This should be a 16x16 unit trigger with an origin brush placed so that it's center lies on the bottom plane of the trigger.
Must be in the level somewhere. This is the trigger that is used to represent a flag.
It gets moved to the position of the planted bomb model.
*/
/*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions.*/
/*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
/*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
#precache( "string", "OBJECTIVES_CTF" );
#precache( "string", "OBJECTIVES_CTF_SCORE" );
#precache( "string", "OBJECTIVES_CTF_HINT" );
#precache( "string", "MP_CTF_OVERTIME_ROUND_1" );
#precache( "string", "MP_CTF_OVERTIME_ROUND_1" );
#precache( "string", "MP_CTF_OVERTIME_ROUND_2_WINNER" );
#precache( "string", "MP_CTF_OVERTIME_ROUND_2_LOSER" );
#precache( "string", "MP_CTF_OVERTIME_ROUND_2_TIE" );
#precache( "string", "MP_CTF_OVERTIME_ROUND_2_TIE" );
#precache( "string", "MP_FLAG_TAKEN_BY");
#precache( "string", "MP_ENEMY_FLAG_TAKEN");
#precache( "string", "MP_FRIENDLY_FLAG_TAKEN");
#precache( "string", "MP_FLAG_CAPTURED_BY");
#precache( "string", "MP_ENEMY_FLAG_CAPTURED_BY");
#precache( "string", "MP_FLAG_RETURNED_BY");
#precache( "string", "MP_FLAG_RETURNED");
#precache( "string", "MP_ENEMY_FLAG_RETURNED");
#precache( "string", "MP_FRIENDLY_FLAG_RETURNED");
#precache( "string", "MP_YOUR_FLAG_RETURNING_IN");
#precache( "string", "MP_ENEMY_FLAG_RETURNING_IN");
#precache( "string", "MP_FRIENDLY_FLAG_DROPPED_BY");
#precache( "string", "MP_FRIENDLY_FLAG_DROPPED");
#precache( "string", "MP_ENEMY_FLAG_DROPPED");
#precache( "string", "MP_SUDDEN_DEATH");
#precache( "string", "MP_CAP_LIMIT_REACHED");
#precache( "string", "MP_CTF_CANT_CAPTURE_FLAG" );
#precache( "triggerstring", "MP_CTF_CANT_CAPTURE_FLAG" );
#precache( "string", "MP_CTF_OVERTIME_WIN" );
#precache( "string", "MP_CTF_OVERTIME_ROUND_1" );
#precache( "string", "MP_CTF_OVERTIME_ROUND_2_WINNER" );
#precache( "string", "MP_CTF_OVERTIME_ROUND_2_LOSER" );
#precache( "string", "MP_CTF_OVERTIME_ROUND_2_TIE" );
#precache( "string", "MPUI_CTF_OVERTIME_FASTEST_CAP_TIME" );
#precache( "string", "MPUI_CTF_OVERTIME_DEFEAT_TIMELIMIT" );
#precache( "string", "MPUI_CTF_OVERTIME_DEFEAT_DID_NOT_DEFEND" );
#precache( "objective", "allies_base" );
#precache( "objective", "axis_base" );
#precache( "objective", "allies_flag" );
#precache( "objective", "axis_flag" );
#precache( "fx", "ui/fx_ctf_flag_base_team" );
function autoexec __init__sytem__() { system::register("ctf",&__init__,undefined,undefined); }
function __init__()
{
clientfield::register( "scriptmover", "ctf_flag_away", 1, 1, "int" );
}
function main()
{
globallogic::init();
util::registerTimeLimit( 0, 1440 );
util::registerRoundLimit( 0, 10 );
util::registerRoundWinLimit( 0, 10 );
util::registerRoundSwitch( 0, 9 );
util::registerNumLives( 0, 100 );
util::registerScoreLimit( 0, 5000 );
level.scoreRoundWinBased = ( GetGametypeSetting( "cumulativeRoundScores" ) == false );
level.flagCaptureCondition = GetGametypeSetting( "flagCaptureCondition" );
level.doubleOvertime = true;
globallogic::registerFriendlyFireDelay( level.gameType, 15, 0, 1440 );
if ( GetDvarString( "scr_ctf_spawnPointFacingAngle") == "" )
SetDvar("scr_ctf_spawnPointFacingAngle", "0");
level.teamBased = true;
level.overrideTeamScore = true;
level.onStartGameType =&onStartGameType;
level.onSpawnPlayer =&onSpawnPlayer;
level.onPrecacheGameType =&onPrecacheGameType;
level.onPlayerKilled =&onPlayerKilled;
level.onRoundSwitch =&onRoundSwitch;
level.onEndGame =&onEndGame;
level.onRoundEndGame =&onRoundEndGame;
level.getTeamKillPenalty =&ctf_getTeamKillPenalty;
level.getTeamKillScore =&ctf_getTeamKillScore;
level.setMatchScoreHUDElemForTeam =&setMatchScoreHUDElemForTeam;
level.shouldPlayOvertimeRound =&shouldPlayOvertimeRound;
gameobjects::register_allowed_gameobject( level.gameType );
if ( !isdefined( game["ctf_teamscore_cache"] ) )
{
game["ctf_teamscore_cache"]["allies"] = 0; // ctf team score cacge is the total flags earned before the score is reset for OT, used by cumulative-round win rule
game["ctf_teamscore_cache"]["axis"] = 0;
}
globallogic_audio::set_leader_gametype_dialog ( "startCtf", "hcStartCtf", "objCapture", "objCapture" );
level.lastDialogTime = getTime();
level thread ctf_icon_hide();
// Sets the scoreboard columns and determines with data is sent across the network
if ( !SessionModeIsSystemlink() && !SessionModeIsOnlineGame() && IsSplitScreen() )
// local matches only show the first three columns
globallogic::setvisiblescoreboardcolumns( "score", "kills", "captures", "returns", "deaths" );
else
globallogic::setvisiblescoreboardcolumns( "score", "kills", "deaths", "captures", "returns" );
}
function onPrecacheGameType()
{
game["flag_dropped_sound"] = "mp_war_objective_lost";
game["flag_recovered_sound"] = "mp_war_objective_taken";
game["strings"]["score_limit_reached"] = &"MP_CAP_LIMIT_REACHED";
}
function onStartGameType()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
/#
setdebugsideswitch(game["switchedsides"]);
#/
setClientNameMode("auto_change");
globallogic_score::resetTeamScores();
util::setObjectiveText( "allies", &"OBJECTIVES_CTF" );
util::setObjectiveText( "axis", &"OBJECTIVES_CTF" );
if ( level.splitscreen )
{
util::setObjectiveScoreText( "allies", &"OBJECTIVES_CTF" );
util::setObjectiveScoreText( "axis", &"OBJECTIVES_CTF" );
}
else
{
util::setObjectiveScoreText( "allies", &"OBJECTIVES_CTF_SCORE" );
util::setObjectiveScoreText( "axis", &"OBJECTIVES_CTF_SCORE" );
}
util::setObjectiveHintText( "allies", &"OBJECTIVES_CTF_HINT" );
util::setObjectiveHintText( "axis", &"OBJECTIVES_CTF_HINT" );
if ( isdefined( game["overtime_round"] ) )
{
// This is only necessary when cumulativeRoundScores is on so that the game doesn't immediately end due to scorelimit being set to 1 in OT
game["ctf_teamscore_cache"]["allies"] += [[level._getTeamScore]]( "allies" );
game["ctf_teamscore_cache"]["axis"] += [[level._getTeamScore]]( "axis" );
[[level._setTeamScore]]( "allies", 0 );
[[level._setTeamScore]]( "axis", 0 );
// One flag wins the round
util::registerScoreLimit( 1, 1 );
if ( isdefined( game["ctf_overtime_time_to_beat"] ) )
{
util::registerTimeLimit( game["ctf_overtime_time_to_beat"] / 60000, game["ctf_overtime_time_to_beat"] / 60000 );
}
if ( game["overtime_round"] == 1 )
{
util::setObjectiveHintText( "allies", &"MP_CTF_OVERTIME_ROUND_1" );
util::setObjectiveHintText( "axis", &"MP_CTF_OVERTIME_ROUND_1" );
}
else if ( isdefined( game["ctf_overtime_first_winner"] ) )
{
util::setObjectiveHintText( game["ctf_overtime_first_winner"], &"MP_CTF_OVERTIME_ROUND_2_WINNER" );
util::setObjectiveHintText( util::getOtherTeam( game["ctf_overtime_first_winner"] ), &"MP_CTF_OVERTIME_ROUND_2_LOSER" );
}
else
{
util::setObjectiveHintText( "allies", &"MP_CTF_OVERTIME_ROUND_2_TIE" );
util::setObjectiveHintText( "axis", &"MP_CTF_OVERTIME_ROUND_2_TIE" );
}
}
// now that the game objects have been deleted place the influencers
spawning::create_map_placed_influencers();
level.spawnMins = ( 0, 0, 0 );
level.spawnMaxs = ( 0, 0, 0 );
spawnlogic::place_spawn_points( "mp_ctf_spawn_allies_start" );
spawnlogic::place_spawn_points( "mp_ctf_spawn_axis_start" );
spawnlogic::add_spawn_points( "allies", "mp_ctf_spawn_allies" );
spawnlogic::add_spawn_points( "axis", "mp_ctf_spawn_axis" );
spawning::add_fallback_spawnpoints( "allies", "mp_tdm_spawn" );
spawning::add_fallback_spawnpoints( "axis", "mp_tdm_spawn" );
spawning::updateAllSpawnPoints();
spawning::update_fallback_spawnpoints();
level.mapCenter = math::find_box_center( level.spawnMins, level.spawnMaxs );
setMapCenter( level.mapCenter );
spawnpoint = spawnlogic::get_random_intermission_point();
setDemoIntermissionPoint( spawnpoint.origin, spawnpoint.angles );
level.spawn_axis = spawnlogic::get_spawnpoint_array( "mp_ctf_spawn_axis" );
level.spawn_allies = spawnlogic::get_spawnpoint_array( "mp_ctf_spawn_allies" );
level.spawn_start = [];
foreach( team in level.teams )
{
level.spawn_start[ team ] = spawnlogic::get_spawnpoint_array("mp_ctf_spawn_" + team + "_start");
}
thread updateGametypeDvars();
thread ctf();
}
function shouldPlayOvertimeRound()
{
// Play 2 rounds of overtime
if ( isdefined( game["overtime_round"] ) )
{
if ( game["overtime_round"] == 1 || !level.gameEnded ) // If we've only played 1 round or we're in the middle of the 2nd keep going
{
return true;
}
return false;
}
if ( !level.scoreRoundWinBased )
{
// Only go to overtime if both teams are tied and it's either the last round or both teams are one away from winning
if ( ( game["teamScores"]["allies"] == game["teamScores"]["axis"] ) &&
( util::hitRoundLimit() || ( game["teamScores"]["allies"] == level.scoreLimit-1 ) ) )
{
return true;
}
}
else
{
// Only go to overtime if both teams are one round away from winning
alliesRoundsWon = util::getRoundsWon( "allies" );
axisRoundsWon = util::getRoundsWon( "axis" );
if ( ( level.roundWinLimit > 0 ) && ( axisRoundsWon == level.roundWinLimit-1 ) && ( alliesRoundsWon == level.roundWinLimit-1 ) )
{
return true;
}
if ( util::hitRoundLimit() && ( alliesRoundsWon == axisRoundsWon ) )
{
return true;
}
}
return false;
}
function minutesAndSecondsString( milliseconds )
{
minutes = floor( milliseconds / 60000 );
milliseconds -= minutes * 60000;
seconds = floor( milliseconds / 1000 );
if ( seconds < 10 )
{
return minutes+":0"+seconds;
}
else
{
return minutes+":"+seconds;
}
}
function setMatchScoreHUDElemForTeam( team )
{
if ( !isdefined( game["overtime_round"] ) )
{
self hud_message::setMatchScoreHUDElemForTeam( team );
}
else if ( isdefined( game["ctf_overtime_second_winner"] ) && ( game["ctf_overtime_second_winner"] == team ) )
{
self setText( minutesAndSecondsString( game["ctf_overtime_best_time"] ) );
}
else if ( isdefined( game["ctf_overtime_first_winner"] ) && ( game["ctf_overtime_first_winner"] == team ) )
{
self setText( minutesAndSecondsString( game["ctf_overtime_time_to_beat"] ) );
}
else
{
self setText( &"" );
}
}
function onRoundSwitch()
{
if ( !isdefined( game["switchedsides"] ) )
game["switchedsides"] = false;
level.halftimeType = "halftime";
game["switchedsides"] = !game["switchedsides"];
}
function onEndGame( winningTeam )
{
if ( isdefined( game["overtime_round"] ) )
{
if ( game["overtime_round"] == 1 )
{
if ( isdefined( winningTeam ) && ( winningTeam != "tie" ) )
{
game["ctf_overtime_first_winner"] = winningTeam;
game["ctf_overtime_time_to_beat"] = globallogic_utils::getTimePassed();
}
}
else
{
game["ctf_overtime_second_winner"] = winningTeam;
game["ctf_overtime_best_time"] = globallogic_utils::getTimePassed();
}
}
}
function updateTeamScoreByRoundsWon()
{
if ( level.scoreRoundWinBased )
{
foreach( team in level.teams )
{
[[level._setTeamScore]]( team, game["roundswon"][team] );
}
}
}
function updateTeamScoreByFlagsCaptured()
{
if ( level.scoreRoundWinBased )
return;
foreach( team in level.teams )
{
[[level._setTeamScore]]( team, [[level._getTeamScore]]( team ) + game["ctf_teamscore_cache"][team] );
}
}
function onRoundEndGame( winningTeam )
{
if ( isdefined( game["overtime_round"] ) )
{
if ( isdefined( game["ctf_overtime_first_winner"] ) )
{
if ( !isdefined( winningTeam ) || ( winningTeam == "tie" ) )
{
winningTeam = game["ctf_overtime_first_winner"];
}
if ( game["ctf_overtime_first_winner"] == winningTeam )
{
level.endVictoryReasonText = &"MPUI_CTF_OVERTIME_FASTEST_CAP_TIME";
level.endDefeatReasonText = &"MPUI_CTF_OVERTIME_DEFEAT_TIMELIMIT";
}
else
{
level.endVictoryReasonText = &"MPUI_CTF_OVERTIME_FASTEST_CAP_TIME";
level.endDefeatReasonText = &"MPUI_CTF_OVERTIME_DEFEAT_DID_NOT_DEFEND";
}
}
else if ( !isdefined( winningTeam ) || ( winningTeam == "tie" ) )
{
if ( level.scoreRoundWinBased )
{
updateTeamScoreByRoundsWon();
}
else
{
updateTeamScoreByFlagsCaptured();
}
return "tie";
}
if ( level.scoreRoundWinBased )
{
foreach( team in level.teams )
{
score = game["roundswon"][team];
if ( team === winningTeam )
{
score++;
}
[[level._setTeamScore]]( team, score );
}
}
else
{
updateTeamScoreByFlagsCaptured();
}
return winningTeam;
}
if ( level.scoreRoundWinBased )
{
updateTeamScoreByRoundsWon();
winner = globallogic::determineTeamWinnerByGameStat( "roundswon" );
}
else
{
winner = globallogic::determineTeamWinnerByTeamScore();
}
return winner;
}
function onSpawnPlayer(predictedSpawn)
{
self.isFlagCarrier = false;
self.flagCarried = undefined;
self clientfield::set( "ctf_flag_carrier", 0 );
spawning::onSpawnPlayer(predictedSpawn);
}
function updateGametypeDvars()
{
level.flagCaptureTime = GetGametypeSetting( "captureTime" );
level.flagTouchReturnTime = GetGametypeSetting( "defuseTime" ); // using defuseTime for touch return
level.idleFlagReturnTime = GetGametypeSetting( "idleFlagResetTime" );
level.flagRespawnTime = GetGametypeSetting( "flagRespawnTime" );
level.enemyCarrierVisible = GetGametypeSetting( "enemyCarrierVisible" );
level.roundLimit = GetGametypeSetting( "roundLimit" );
level.cumulativeRoundScores = GetGametypeSetting( "cumulativeRoundScores" );
level.teamKillPenaltyMultiplier = GetGametypeSetting( "teamKillPenalty" );
level.teamKillScoreMultiplier = GetGametypeSetting( "teamKillScore" );
if ( level.flagTouchReturnTime >= 0 && level.flagTouchReturnTime != 63)
{
level.touchReturn = true;
}
else
{
level.touchReturn = false;
}
}
function createFlag( trigger )
{
if ( isdefined( trigger.target ) )
{
visuals[0] = getEnt( trigger.target, "targetname" );
}
else
{
visuals[0] = spawn( "script_model", trigger.origin );
visuals[0].angles = trigger.angles;
}
entityTeam = trigger.script_team;
// TODO MTEAM - switched sides
if ( game["switchedsides"] )
entityTeam = util::getOtherTeam( entityTeam );
visuals[0] setModel( teams::get_flag_model( entityTeam ) );
visuals[0] SetTeam( entityTeam );
flag = gameobjects::create_carry_object( entityTeam, trigger, visuals, (0,0,100), istring(entityTeam+"_flag") );
flag gameobjects::set_team_use_time( "friendly", level.flagTouchReturnTime );
flag gameobjects::set_team_use_time( "enemy", level.flagCaptureTime );
flag gameobjects::allow_carry( "enemy" );
flag gameobjects::set_visible_team( "any" );
flag gameobjects::set_visible_carrier_model( teams::get_flag_carry_model( entityTeam ) );
flag gameobjects::set_2d_icon( "friendly", level.iconDefend2D );
flag gameobjects::set_3d_icon( "friendly", level.iconDefend3D );
flag gameobjects::set_2d_icon( "enemy", level.iconCapture2D );
flag gameobjects::set_3d_icon( "enemy", level.iconCapture3D );
if ( level.enemyCarrierVisible == 2 )
{
flag.objIDPingFriendly = true;
}
flag.allowWeapons = true;
flag.onPickup =&onPickup;
flag.onPickupFailed =&onPickup;
flag.onDrop =&onDrop;
flag.onReset =&onReset;
if ( level.idleFlagReturnTime > 0 )
{
flag.autoResetTime = level.idleFlagReturnTime;
}
else
{
flag.autoResetTime = undefined;
}
return flag;
}
function createFlagZone( trigger )
{
visuals = [];
entityTeam = trigger.script_team;
// TODO MTEAM - switched sides
if ( game["switchedsides"] )
entityTeam = util::getOtherTeam( entityTeam );
flagZone = gameobjects::create_use_object( entityTeam, trigger, visuals, (0,0,0), istring(entityTeam+"_base") );
flagZone gameobjects::allow_use( "friendly" );
flagZone gameobjects::set_use_time( 0 );
flagZone gameobjects::set_use_text( &"MP_CAPTURING_FLAG" );
flagZone gameobjects::set_visible_team( "friendly" );
enemyTeam = util::getOtherTeam( entityTeam );
flagZone gameobjects::set_key_object( level.teamFlags[enemyTeam] );
flagZone.onUse =&onCapture;
flag = level.teamFlags[entityTeam];
flag.flagBase = flagZone;
flagZone.flag = flag;
flagZone createFlagSpawnInfluencer( entityTeam );
return flagZone;
}
function createFlagHint( team, origin )
{
radius = 128;
height = 64;
trigger = spawn("trigger_radius", origin, 0, radius, height);
trigger setHintString( &"MP_CTF_CANT_CAPTURE_FLAG" );
trigger setcursorhint("HINT_NOICON");
trigger.original_origin = origin;
trigger turn_off();
return trigger;
}
function ctf()
{
level.flags = [];
level.teamFlags = [];
level.flagZones = [];
level.teamFlagZones = [];
flag_triggers = getEntArray( "ctf_flag_pickup_trig", "targetname" );
if ( !isdefined( flag_triggers ) || flag_triggers.size != 2)
{
/#util::error("Not enough ctf_flag_pickup_trig triggers found in map. Need two.");#/
return;
}
for ( index = 0; index < flag_triggers.size; index++ )
{
trigger = flag_triggers[index];
flag = createFlag( trigger );
team = flag gameobjects::get_owner_team();
level.flags[level.flags.size] = flag;
level.teamFlags[team] = flag;
}
flag_zones = getEntArray( "ctf_flag_zone_trig", "targetname" );
if ( !isdefined( flag_zones ) || flag_zones.size != 2)
{
/#util::error("Not enough ctf_flag_zone_trig triggers found in map. Need two.");#/
return;
}
for ( index = 0; index < flag_zones.size; index++ )
{
trigger = flag_zones[index];
flagZone = createFlagZone( trigger );
team = flagZone gameobjects::get_owner_team();
level.flagZones[level.flagZones.size] = flagZone;
level.teamFlagZones[team] = flagZone;
level.flagHints[team] = createFlagHint( team, trigger.origin );
facing_angle = GetDvarint( "scr_ctf_spawnPointFacingAngle");
// the opposite team will want to face this point
setspawnpointsbaseweight( util::getOtherTeamsMask(team), trigger.origin, facing_angle, level.spawnsystem.objective_facing_bonus);
}
// once all the flags have been registered with the game,
// give each spawn point a baseline score for each objective flag,
// based on whether or not player will be looking in the direction of that flag upon spawning
//generate_baseline_spawn_point_scores();
createReturnMessageElems();
}
//Runs each round, as function as restarted at the start of every round.
//Hides the flag status icons and the 2D and 3D icons from the player's view
function ctf_icon_hide()
{
level waittill ( "game_ended" );
level.teamFlags["allies"] gameobjects::set_visible_team( "none" );
level.teamFlags["axis"] gameobjects::set_visible_team( "none" );
}
function removeInfluencers()
{
if ( isdefined( self.spawn_influencer_enemy_carrier ) )
{
// self == player
self spawning::remove_influencer( self.spawn_influencer_enemy_carrier );
self.spawn_influencer_enemy_carrier = undefined;
}
if ( isdefined( self.spawn_influencer_friendly_carrier ) )
{
// self == player
self spawning::remove_influencer( self.spawn_influencer_friendly_carrier );
self.spawn_influencer_friendly_carrier = undefined;
}
if ( isdefined( self.spawn_influencer_dropped ) )
{
// self == flag
self.trigger spawning::remove_influencer( self.spawn_influencer_dropped );
self.spawn_influencer_dropped = undefined;
}
}
function onDrop( player )
{
origin = (0,0,0);
if ( isdefined( player ) )
{
player clientfield::set( "ctf_flag_carrier", 0 );
origin = player.origin;
}
team = self gameobjects::get_owner_team();
otherTeam = util::getOtherTeam( team );
bbPrint( "mpobjective", "gametime %d objtype %s team %s playerx %d playery %d playerz %d", gettime(), "ctf_flagdropped", team, origin );
self.visuals[0] clientfield::set( "ctf_flag_away", 1 );
if ( level.touchReturn )
{
self gameobjects::allow_carry( "any" );
level.flagHints[otherTeam] turn_off();
}
if ( isdefined( player ) )
{
util::printAndSoundOnEveryone( team, undefined, &"", undefined, "mp_war_objective_lost" );
level thread popups::DisplayTeamMessageToTeam( &"MP_FRIENDLY_FLAG_DROPPED", player, team );
level thread popups::DisplayTeamMessageToTeam( &"MP_ENEMY_FLAG_DROPPED", player, otherTeam );
}
else
{
util::printAndSoundOnEveryone( team, undefined, &"", undefined, "mp_war_objective_lost" );
}
globallogic_audio::leader_dialog( "ctfFriendlyFlagDropped", team, undefined, "ctf_flag" );
globallogic_audio::leader_dialog( "ctfEnemyFlagDropped", otherTeam, undefined, "ctf_flag_enemy" );
/#
if ( isdefined( player ) )
print( team + " flag dropped" );
else
print( team + " flag dropped" );
#/
if ( isdefined( player ) )
{
player playLocalSound("mpl_flag_drop_plr");
}
globallogic_audio::play_2d_on_team( "mpl_flagdrop_sting_friend", otherTeam );
globallogic_audio::play_2d_on_team( "mpl_flagdrop_sting_enemy", team );
if ( level.touchReturn )
{
self gameobjects::set_3d_icon( "friendly", level.iconReturn3D );
self gameobjects::set_2d_icon( "friendly", level.iconReturn2D );
}
else
{
self gameobjects::set_3d_icon( "friendly", level.iconDropped3D );
self gameobjects::set_2d_icon( "friendly", level.iconDropped2D );
}
self gameobjects::set_visible_team( "any" );
self gameobjects::set_3d_icon( "enemy", level.iconCapture3D );
self gameobjects::set_2d_icon( "enemy", level.iconCapture2D );
thread sound::play_on_players( game["flag_dropped_sound"], game["attackers"] );
self thread returnFlagAfterTimeMsg( level.idleFlagReturnTime );
// remove carrier influencers
if ( isdefined( player ) )
{
player removeInfluencers();
}
// create new influencers on the flag
ss = level.spawnsystem;
player_team_mask = util::getTeamMask( otherTeam ); // this is the player that has the flag's team
enemy_team_mask = util::getTeamMask( team ); // and his enemies
if ( isdefined( player ) )
flag_origin = player.origin;
else
flag_origin = self.curorigin;
self.spawn_influencer_dropped = self.trigger spawning::create_entity_influencer( "ctf_flag_dropped", player_team_mask|enemy_team_mask );
SetInfluencerTimeOut( self.spawn_influencer_dropped, level.idleFlagReturnTime );
}
function onPickup( player )
{
carrierKilledBy = self.carrierKilledBy;
self.carrierKilledBy = undefined;
if ( isdefined( self.spawn_influencer_dropped ) )
{
self.trigger spawning::remove_influencer( self.spawn_influencer_dropped );
self.spawn_influencer_dropped = undefined;
}
player AddPlayerStatWithGameType( "PICKUPS", 1 );
//scoreevents::processScoreEvent( "flag_grab", player );
if ( level.touchReturn )
{
self gameobjects::allow_carry( "enemy" );
}
// always clear influencers. we'll create new ones if it's been picked up by an enemy.
self removeInfluencers();
team = self gameobjects::get_owner_team();
otherTeam = util::getOtherTeam( team );
self clearReturnFlagHudElems();
if ( isdefined( player ) && player.pers["team"] == team )
{
self notify("picked_up");
util::printAndSoundOnEveryone( team, undefined, &"", undefined, "mp_obj_returned" );
if( isdefined(player.pers["returns"]) )
{
player.pers["returns"]++;
player.returns = player.pers["returns"];
}
if ( isdefined(carrierKilledBy) && carrierKilledBy == player )
{
scoreevents::processScoreEvent( "flag_carrier_kill_return_close", player );
}
else if (distancesquared(self.trigger.baseOrigin, player.origin) > 300*300)
{
scoreevents::processScoreEvent( "flag_return", player );
}
demo::bookmark( "event", gettime(), player );
player AddPlayerStatWithGameType( "RETURNS", 1 );
level thread popups::DisplayTeamMessageToTeam( &"MP_FRIENDLY_FLAG_RETURNED", player, team );
level thread popups::DisplayTeamMessageToTeam( &"MP_ENEMY_FLAG_RETURNED", player, otherTeam );
self.visuals[0] clientfield::set( "ctf_flag_away", 0 );
self gameobjects::set_flags( 0 );
bbPrint( "mpobjective", "gametime %d objtype %s team %s playerx %d playery %d playerz %d", gettime(), "ctf_flagreturn", team, player.origin );
player RecordGameEvent("return");
// want to return the flag here
self returnFlag();
/#
if ( isdefined( player ) )
print( team + " flag returned" );
else
print( team + " flag returned" );
#/
return;
}
else
{
bbPrint( "mpobjective", "gametime %d objtype %s team %s playerx %d playery %d playerz %d", gettime(), "ctf_flagpickup", team, player.origin );
player RecordGameEvent("pickup");
scoreevents::processScoreEvent( "flag_grab", player );
demo::bookmark( "event", gettime(), player );
util::printAndSoundOnEveryone( otherteam, undefined, &"", undefined, "mp_obj_taken", "mp_enemy_obj_taken" );
level thread popups::DisplayTeamMessageToTeam( &"MP_FRIENDLY_FLAG_TAKEN", player, team );
level thread popups::DisplayTeamMessageToTeam( &"MP_ENEMY_FLAG_TAKEN", player, otherTeam );
globallogic_audio::leader_dialog( "ctfFriendlyFlagTaken", team, undefined, "ctf_flag" );
globallogic_audio::leader_dialog( "ctfEnemyFlagTaken", otherTeam, undefined, "ctf_flag_enemy" );
player.isFlagCarrier = true;
player.flagCarried = self;
player playLocalSound("mpl_flag_pickup_plr");
player clientfield::set( "ctf_flag_carrier", 1 );
self gameobjects::set_flags( 1 );
globallogic_audio::play_2d_on_team( "mpl_flagget_sting_friend", otherTeam );
globallogic_audio::play_2d_on_team( "mpl_flagget_sting_enemy", team );
if ( level.enemyCarrierVisible )
{
self gameobjects::set_visible_team( "any" );
}
else
{
self gameobjects::set_visible_team( "enemy" );
}
self gameobjects::set_2d_icon( "friendly", level.iconKill2D );
self gameobjects::set_3d_icon( "friendly", level.iconKill3D );
self gameobjects::set_2d_icon( "enemy", level.iconEscort2D );
self gameobjects::set_3d_icon( "enemy", level.iconEscort3D );
player thread claim_trigger( level.flagHints[otherTeam] );
update_hints();
//Reset flashback here
player resetflashback();
/#print( team + " flag taken" );#/
ss = level.spawnsystem;
player_team_mask = util::getTeamMask( otherTeam ); // this is the player that has the flag's team
enemy_team_mask = util::getTeamMask( team ); // and his enemies
player.spawn_influencer_friendly_carrier = player spawning::create_entity_masked_friendly_influencer( "ctf_carrier_friendly", player_team_mask );
player.spawn_influencer_enemy_carrier = player spawning::create_entity_masked_enemy_influencer( "ctf_carrier_enemy", enemy_team_mask );
}
}
function OnPickupMusicState ( player )
{
self endon( "disconnect" );
self endon( "death" );
// wait 6 seconds and see if the player still has the flag.
wait (6);
if (player.isFlagCarrier)
{
//Was the SUSPENSE state changes to ACTION - removed state CDC - 6/19/12
}
}
function isHome()
{
if ( isdefined( self.carrier ) )
return false;
if ( self.curOrigin != self.trigger.baseOrigin )
return false;
return true;
}
function returnFlag()
{
team = self gameobjects::get_owner_team();
otherTeam = util::getOtherTeam(team);
globallogic_audio::play_2d_on_team( "mpl_flagreturn_sting", team );
globallogic_audio::play_2d_on_team( "mpl_flagreturn_sting", otherTeam );
level.teamFlagZones[otherTeam] gameobjects::allow_use( "friendly" );
level.teamFlagZones[otherTeam] gameobjects::set_visible_team( "friendly" );
update_hints();
if ( level.touchReturn )
{
self gameobjects::allow_carry( "enemy" );
}
self gameobjects::return_home();
self gameobjects::set_visible_team( "any" );
//TODO: Add 2D Icons
self gameobjects::set_3d_icon( "friendly", level.iconDefend3D );
self gameobjects::set_2d_icon( "friendly", level.iconDefend2D );
self gameobjects::set_3d_icon( "enemy", level.iconCapture3D );
self gameobjects::set_2d_icon( "enemy", level.iconCapture2D );
globallogic_audio::leader_dialog( "ctfFriendlyFlagReturned", team, undefined, "ctf_flag" );
globallogic_audio::leader_dialog( "ctfEnemyFlagReturned", otherTeam, undefined, "ctf_flag_enemy" );
}
function onCapture( player )
{
team = player.pers["team"];
enemyTeam = util::getOtherTeam( team );
time = gettime();
playerTeamsFlag = level.teamFlags[team];
if ( (level.flagCaptureCondition == 1) && playerTeamsFlag gameobjects::is_object_away_from_home() )
{
return;
}
if ( !isdefined( player.carryObject ) )
{
return; // the carryObject can be undefined if the player dies a frame before (and possibly other edges cases)
}
util::printAndSoundOnEveryone( team, undefined, &"", undefined, "mp_obj_captured", "mp_enemy_obj_captured" );
bbPrint( "mpobjective", "gametime %d objtype %s team %s playerx %d playery %d playerz %d", time, "ctf_flagcapture", enemyTeam, player.origin ); // flag BELONGS to enemyTeam
game["challenge"][team]["capturedFlag"] = true;
if( isdefined(player.pers["captures"]) )
{
player.pers["captures"]++;
player.captures = player.pers["captures"];
}
demo::bookmark( "event", gettime(), player );
player AddPlayerStatWithGameType( "CAPTURES", 1 );
level thread popups::DisplayTeamMessageToTeam( &"MP_ENEMY_FLAG_CAPTURED", player, team );
level thread popups::DisplayTeamMessageToTeam( &"MP_FRIENDLY_FLAG_CAPTURED", player, enemyTeam );
globallogic_audio::play_2d_on_team( "mpl_flagcapture_sting_enemy", enemyTeam );
globallogic_audio::play_2d_on_team( "mpl_flagcapture_sting_friend", team );
player giveFlagCaptureXP( player );
/#print( enemyTeam + " flag captured" );#/
flag = player.carryObject;
player challenges::capturedObjective( time, flag.trigger );
flag.dontAnnounceReturn = true;
flag gameobjects::return_home();
flag.dontAnnounceReturn = undefined;
otherTeam = util::getOtherTeam(team);
level.teamFlags[otherTeam] gameobjects::allow_carry( "enemy" );
level.teamFlags[otherTeam] gameobjects::set_visible_team( "any" );
level.teamFlags[otherTeam] gameobjects::return_home();
level.teamFlagZones[otherTeam] gameobjects::allow_use( "friendly" );
player.isFlagCarrier = false;
player.flagCarried = undefined;
player clientfield::set( "ctf_flag_carrier", 0 );
// execution will stop on this line on last flag cap of a level
globallogic_score::giveTeamScoreForObjective( team, 1 );
// NOTE: team is the team of the capturing player, unlike in other flag events
globallogic_audio::leader_dialog( "ctfEnemyFlagCaptured", team, undefined, "ctf_flag_enemy" );
globallogic_audio::leader_dialog( "ctfFriendlyFlagCaptured", enemyTeam, undefined, "ctf_flag" );
flag removeInfluencers();
player removeInfluencers();
}
function giveFlagCaptureXP( player )
{
scoreevents::processScoreEvent( "flag_capture", player );
player RecordGameEvent("capture");
}
function onReset()
{
update_hints();
team = self gameobjects::get_owner_team();
self gameobjects::set_3d_icon( "friendly", level.iconDefend3D );
self gameobjects::set_2d_icon( "friendly", level.iconDefend2D );
self gameobjects::set_3d_icon( "enemy", level.iconCapture3D );
self gameobjects::set_2d_icon( "enemy", level.iconCapture2D );
if ( level.touchReturn )
{
self gameobjects::allow_carry( "enemy" );
}
level.teamFlagZones[team] gameobjects::set_visible_team( "friendly" );
level.teamFlagZones[team] gameobjects::allow_use( "friendly" );
self.visuals[0] clientfield::set( "ctf_flag_away", 0 );
self gameobjects::set_flags( 0 );
self clearReturnFlagHudElems();
self removeInfluencers();
}
function getOtherFlag( flag )
{
if ( flag == level.flags[0] )
return level.flags[1];
return level.flags[0];
}
function onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
{
if ( isdefined( attacker ) && isplayer( attacker ) )
{
for ( index = 0; index < level.flags.size; index++ )
{
flagTeam = "invalidTeam";
inFlagRadius = false;
defendedFlag = false;
offendedFlag = false;
flagCarrier = level.flags[index].carrier;
if ( isdefined( flagCarrier ) )
{
flagOrigin = level.flags[index].carrier.origin;
isCarried = true;
if ( isPlayer( attacker ) && ( attacker.pers["team"] != self.pers["team"] ) )
{
if ( isdefined( level.flags[index].carrier.attackerData ) )
{
if ( level.flags[index].carrier != attacker )
{
if ( isdefined( level.flags[index].carrier.attackerData[self.clientid] ) )
{
scoreevents::processScoreEvent( "rescue_flag_carrier", attacker, undefined, weapon );
}
}
}
}
}
else
{
flagOrigin = level.flags[index].curorigin;
isCarried = false;
}
dist = Distance2dSquared(self.origin, flagOrigin);
if ( dist < level.defaultOffenseRadiusSQ )
{
inFlagRadius = true;
if ( level.flags[index].ownerteam == attacker.pers["team"] )
defendedFlag = true;
else
offendedFlag = true;
}
dist = Distance2dSquared(attacker.origin, flagOrigin);
if ( dist < level.defaultOffenseRadiusSQ )
{
inFlagRadius = true;
if ( level.flags[index].ownerteam == attacker.pers["team"] )
defendedFlag = true;
else
offendedFlag = true;
}
if ( inFlagRadius && isPlayer( attacker ) && attacker.pers["team"] != self.pers["team"] )
{
if ( defendedFlag )
{
if ( isdefined( self.isFlagCarrier ) && self.isFlagCarrier )
{
scoreevents::processScoreEvent( "kill_flag_carrier", attacker, undefined, weapon );
attacker AddPlayerStat( "kill_carrier", 1 );
}
else
{
scoreevents::processScoreEvent( "killed_attacker", attacker, undefined, weapon );
}
self RecordKillModifier("assaulting");
}
if ( offendedFlag )
{
if ( isCarried == true )
{
if ( isdefined ( flagCarrier ) && attacker == flagCarrier )
{
scoreevents::processScoreEvent( "killed_enemy_while_carrying_flag", attacker, undefined, weapon );
}
else
{
scoreevents::processScoreEvent( "defend_flag_carrier", attacker, undefined, weapon );
attacker addplayerstat( "defend_carrier", 1 );
}
}
else
{
scoreevents::processScoreEvent( "killed_defender", attacker, undefined, weapon );
}
self RecordKillModifier("defending");
}
}
}
victim = self;
foreach( flag_zone in level.flagZones )
{
if ( isdefined( attacker.team ) && ( attacker != victim ) && isdefined( victim.team ) )
{
dist_to_zone_origin = Distance2dSquared( attacker.origin, flag_zone.origin );
victim_dist_to_zone_origin = Distance2dSquared( victim.origin, flag_zone.origin );
if ( victim_dist_to_zone_origin < level.defaultOffenseRadiusSQ || dist_to_zone_origin < level.defaultOffenseRadiusSQ )
{
if ( victim.team == flag_zone.team )
{
attacker thread challenges::killedBaseDefender( flag_zone.trigger );
}
else
{
attacker thread challenges::killedBaseOffender( flag_zone.trigger, weapon );
}
}
}
}
}
if ( !isdefined( self.isFlagCarrier ) || !self.isFlagCarrier )
return;
if ( isdefined( attacker ) && isPlayer( attacker ) && attacker.pers["team"] != self.pers["team"] )
{
if ( isdefined ( self.flagCarried ) )
{
for ( index = 0; index < level.flags.size; index++ )
{
currentFlag = level.flags[index];
if ( currentFlag.ownerteam == self.team )
{
if ( currentFlag.curOrigin == currentFlag.trigger.baseOrigin )
{
dist = Distance2dSquared(self.origin, currentFlag.curOrigin );
if ( dist < level.defaultOffenseRadiusSQ )
{
self.flagCarried.carrierKilledBy = attacker;
break;
}
}
}
}
}
attacker RecordGameEvent("kill_carrier");
self RecordKillModifier("carrying");
}
}
function createReturnMessageElems()
{
level.ReturnMessageElems = [];
level.ReturnMessageElems["allies"]["axis"] = hud::createServerTimer( "objective", 1.4, "allies" );
level.ReturnMessageElems["allies"]["axis"] hud::setPoint( "TOPRIGHT", "TOPRIGHT", 0, 0 );
level.ReturnMessageElems["allies"]["axis"].label = &"MP_ENEMY_FLAG_RETURNING_IN";
level.ReturnMessageElems["allies"]["axis"].alpha = 0;
level.ReturnMessageElems["allies"]["axis"].archived = false;
level.ReturnMessageElems["allies"]["allies"] = hud::createServerTimer( "objective", 1.4, "allies" );
level.ReturnMessageElems["allies"]["allies"] hud::setPoint( "TOPRIGHT", "TOPRIGHT", 0, 20 );
level.ReturnMessageElems["allies"]["allies"].label = &"MP_YOUR_FLAG_RETURNING_IN";
level.ReturnMessageElems["allies"]["allies"].alpha = 0;
level.ReturnMessageElems["allies"]["allies"].archived = false;
level.ReturnMessageElems["axis"]["allies"] = hud::createServerTimer( "objective", 1.4, "axis" );
level.ReturnMessageElems["axis"]["allies"] hud::setPoint( "TOPRIGHT", "TOPRIGHT", 0, 0 );
level.ReturnMessageElems["axis"]["allies"].label = &"MP_ENEMY_FLAG_RETURNING_IN";
level.ReturnMessageElems["axis"]["allies"].alpha = 0;
level.ReturnMessageElems["axis"]["allies"].archived = false;
level.ReturnMessageElems["axis"]["axis"] = hud::createServerTimer( "objective", 1.4, "axis" );
level.ReturnMessageElems["axis"]["axis"] hud::setPoint( "TOPRIGHT", "TOPRIGHT", 0, 20 );
level.ReturnMessageElems["axis"]["axis"].label = &"MP_YOUR_FLAG_RETURNING_IN";
level.ReturnMessageElems["axis"]["axis"].alpha = 0;
level.ReturnMessageElems["axis"]["axis"].archived = false;
}
function returnFlagAfterTimeMsg( time )
{
if ( level.touchReturn || level.idleFlagReturnTime == 0 )
return;
self notify("returnFlagAfterTimeMsg");
self endon("returnFlagAfterTimeMsg");
result = returnFlagHudElems( time );
self removeInfluencers();
self clearReturnFlagHudElems();
if ( !isdefined( result ) ) // returnFlagHudElems hit an endon
return;
// self returnFlag();
}
function returnFlagHudElems( time )
{
self endon("picked_up");
level endon("game_ended");
ownerteam = self gameobjects::get_owner_team();
assert( !level.ReturnMessageElems["axis"][ownerteam].alpha );
level.ReturnMessageElems["axis"][ownerteam].alpha = 1;
level.ReturnMessageElems["axis"][ownerteam] setTimer( time );
assert( !level.ReturnMessageElems["allies"][ownerteam].alpha );
level.ReturnMessageElems["allies"][ownerteam].alpha = 1;
level.ReturnMessageElems["allies"][ownerteam] setTimer( time );
if( time <= 0 )
return false;
else
wait time;
return true;
}
function clearReturnFlagHudElems()
{
ownerteam = self gameobjects::get_owner_team();
level.ReturnMessageElems["allies"][ownerteam].alpha = 0;
level.ReturnMessageElems["axis"][ownerteam].alpha = 0;
}
function turn_on()
{
if ( level.hardcoreMode )
return;
self.origin = self.original_origin;
}
function turn_off()
{
self.origin = ( self.original_origin[0], self.original_origin[1], self.original_origin[2] - 10000);
}
function update_hints()
{
allied_flag = level.teamFlags["allies"];
axis_flag = level.teamFlags["axis"];
if ( !level.touchReturn )
return;
if ( isdefined(allied_flag.carrier) && axis_flag gameobjects::is_object_away_from_home() )
{
level.flagHints["axis"] turn_on();
}
else
{
level.flagHints["axis"] turn_off();
}
if ( isdefined(axis_flag.carrier) && allied_flag gameobjects::is_object_away_from_home() )
{
level.flagHints["allies"] turn_on();
}
else
{
level.flagHints["allies"] turn_off();
}
}
function claim_trigger( trigger )
{
self endon("disconnect");
self ClientClaimTrigger( trigger );
self waittill("drop_object");
self ClientReleaseTrigger( trigger );
}
function createFlagSpawnInfluencer( entityTeam )
{
otherteam = util::getOtherTeam(entityTeam);
team_mask = util::getTeamMask( entityTeam );
other_team_mask = util::getTeamMask( otherteam );
self.spawn_influencer_friendly = self spawning::create_influencer( "ctf_base_friendly", self.trigger.origin, team_mask );
self.spawn_influencer_enemy = self spawning::create_influencer( "ctf_base_friendly", self.trigger.origin, other_team_mask );
}
function ctf_getTeamKillPenalty( eInflictor, attacker, sMeansOfDeath, weapon )
{
teamkill_penalty = globallogic_defaults::default_getTeamKillPenalty( eInflictor, attacker, sMeansOfDeath, weapon );
if ( ( isdefined( self.isFlagCarrier ) && self.isFlagCarrier ) )
{
teamkill_penalty = teamkill_penalty * level.teamKillPenaltyMultiplier;
}
return teamkill_penalty;
}
function ctf_getTeamKillScore( eInflictor, attacker, sMeansOfDeath, weapon )
{
teamkill_score = rank::getScoreInfoValue( "kill" );
if ( ( isdefined( self.isFlagCarrier ) && self.isFlagCarrier ) )
{
teamkill_score = teamkill_score * level.teamKillScoreMultiplier;
}
return int(teamkill_score);
}