#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); }