1 #using scripts\shared\challenges_shared;
2 #using scripts\shared\clientfield_shared;
3 #using scripts\shared\demo_shared;
4 #using scripts\shared\gameobjects_shared;
5 #using scripts\shared\hud_message_shared;
6 #using scripts\shared\hud_util_shared;
7 #using scripts\shared\math_shared;
8 #using scripts\shared\popups_shared;
9 #using scripts\shared\rank_shared;
10 #using scripts\shared\scoreevents_shared;
11 #using scripts\shared\sound_shared;
12 #using scripts\shared\system_shared;
13 #using scripts\shared\util_shared;
15 #using scripts\mp\gametypes\_globallogic;
16 #using scripts\mp\gametypes\_globallogic_audio;
17 #using scripts\mp\gametypes\_globallogic_defaults;
18 #using scripts\mp\gametypes\_globallogic_score;
19 #using scripts\mp\gametypes\_globallogic_utils;
20 #using scripts\mp\gametypes\_hud_message;
21 #using scripts\mp\gametypes\_spawning;
22 #using scripts\mp\gametypes\_spawnlogic;
24 #using scripts\mp\_challenges;
25 #using scripts\mp\_util;
26 #using scripts\mp\teams\_teams;
28 #insert scripts\shared\shared.gsh;
29 #insert scripts\shared\version.gsh;
30 #insert scripts\shared\clientfields.gsh;
32 #define CAPTURE_CONDITION_NONE 0
33 #define CAPTURE_CONDITION_AT_BASE 1
76 #define OBJECTIVE_FLAG_AT_BASE 0
77 #define OBJECTIVE_FLAG_AWAY 1
78 #define OBJECTIVE_FLAG_RETURN_SCORE_DIST 300
80 #precache( "string", "OBJECTIVES_CTF" );
81 #precache( "string", "OBJECTIVES_CTF_SCORE" );
82 #precache( "string", "OBJECTIVES_CTF_HINT" );
83 #precache( "string", "MP_CTF_OVERTIME_ROUND_1" );
84 #precache( "string", "MP_CTF_OVERTIME_ROUND_1" );
85 #precache( "string", "MP_CTF_OVERTIME_ROUND_2_WINNER" );
86 #precache( "string", "MP_CTF_OVERTIME_ROUND_2_LOSER" );
87 #precache( "string", "MP_CTF_OVERTIME_ROUND_2_TIE" );
88 #precache( "string", "MP_CTF_OVERTIME_ROUND_2_TIE" );
89 #precache( "string", "MP_FLAG_TAKEN_BY");
90 #precache( "string", "MP_ENEMY_FLAG_TAKEN");
91 #precache( "string", "MP_FRIENDLY_FLAG_TAKEN");
92 #precache( "string", "MP_FLAG_CAPTURED_BY");
93 #precache( "string", "MP_ENEMY_FLAG_CAPTURED_BY");
94 #precache( "string", "MP_FLAG_RETURNED_BY");
95 #precache( "string", "MP_FLAG_RETURNED");
96 #precache( "string", "MP_ENEMY_FLAG_RETURNED");
97 #precache( "string", "MP_FRIENDLY_FLAG_RETURNED");
98 #precache( "string", "MP_YOUR_FLAG_RETURNING_IN");
99 #precache( "string", "MP_ENEMY_FLAG_RETURNING_IN");
100 #precache( "string", "MP_FRIENDLY_FLAG_DROPPED_BY");
101 #precache( "string", "MP_FRIENDLY_FLAG_DROPPED");
102 #precache( "string", "MP_ENEMY_FLAG_DROPPED");
103 #precache( "string", "MP_SUDDEN_DEATH");
104 #precache( "string", "MP_CAP_LIMIT_REACHED");
105 #precache( "string", "MP_CTF_CANT_CAPTURE_FLAG" );
106 #precache( "triggerstring", "MP_CTF_CANT_CAPTURE_FLAG" );
107 #precache( "string", "MP_CTF_OVERTIME_WIN" );
108 #precache( "string", "MP_CTF_OVERTIME_ROUND_1" );
109 #precache( "string", "MP_CTF_OVERTIME_ROUND_2_WINNER" );
110 #precache( "string", "MP_CTF_OVERTIME_ROUND_2_LOSER" );
111 #precache( "string", "MP_CTF_OVERTIME_ROUND_2_TIE" );
112 #precache( "string", "MPUI_CTF_OVERTIME_FASTEST_CAP_TIME" );
113 #precache( "string", "MPUI_CTF_OVERTIME_DEFEAT_TIMELIMIT" );
114 #precache( "string", "MPUI_CTF_OVERTIME_DEFEAT_DID_NOT_DEFEND" );
115 #precache( "objective", "allies_base" );
116 #precache( "objective", "axis_base" );
117 #precache( "objective", "allies_flag" );
118 #precache( "objective", "axis_flag" );
119 #precache( "fx", "ui/fx_ctf_flag_base_team" );
139 level.scoreRoundWinBased = ( GetGametypeSetting(
"cumulativeRoundScores" ) == false );
140 level.flagCaptureCondition = GetGametypeSetting(
"flagCaptureCondition" );
141 level.doubleOvertime =
true;
145 if ( GetDvarString(
"scr_ctf_spawnPointFacingAngle") ==
"" )
146 SetDvar(
"scr_ctf_spawnPointFacingAngle",
"0");
148 level.teamBased =
true;
149 level.overrideTeamScore =
true;
164 if ( !isdefined( game[
"ctf_teamscore_cache"] ) )
166 game[
"ctf_teamscore_cache"][
"allies"] = 0;
167 game[
"ctf_teamscore_cache"][
"axis"] = 0;
172 level.lastDialogTime = getTime();
177 if ( !SessionModeIsSystemlink() && !SessionModeIsOnlineGame() && IsSplitScreen() )
186 game[
"flag_dropped_sound"] =
"mp_war_objective_lost";
187 game[
"flag_recovered_sound"] =
"mp_war_objective_taken";
189 game[
"strings"][
"score_limit_reached"] = &
"MP_CAP_LIMIT_REACHED";
195 if ( !isdefined( game[
"switchedsides"] ) )
196 game[
"switchedsides"] =
false;
199 setdebugsideswitch(game[
"switchedsides"]);
202 setClientNameMode(
"auto_change");
209 if ( level.splitscreen )
222 if ( isdefined( game[
"overtime_round"] ) )
225 game[
"ctf_teamscore_cache"][
"allies"] += [[level._getTeamScore]](
"allies" );
226 game[
"ctf_teamscore_cache"][
"axis"] += [[level._getTeamScore]](
"axis" );
228 [[level._setTeamScore]](
"allies", 0 );
229 [[level._setTeamScore]](
"axis", 0 );
233 if ( isdefined( game[
"ctf_overtime_time_to_beat"] ) )
238 if ( game[
"overtime_round"] == 1 )
243 else if ( isdefined( game[
"ctf_overtime_first_winner"] ) )
259 level.spawnMins = ( 0, 0, 0 );
260 level.spawnMaxs = ( 0, 0, 0 );
273 setMapCenter( level.mapCenter );
276 setDemoIntermissionPoint( spawnpoint.origin, spawnpoint.angles );
281 level.spawn_start = [];
283 foreach( team
in level.teams )
296 if ( isdefined( game[
"overtime_round"] ) )
298 if ( game[
"overtime_round"] == 1 || !level.gameEnded )
306 if ( !level.scoreRoundWinBased )
309 if ( ( game[
"teamScores"][
"allies"] == game[
"teamScores"][
"axis"] ) &&
320 if ( ( level.roundWinLimit > 0 ) && ( axisRoundsWon == level.roundWinLimit-1 ) && ( alliesRoundsWon == level.roundWinLimit-1 ) )
335 minutes = floor( milliseconds / 60000 );
336 milliseconds -= minutes * 60000;
337 seconds = floor( milliseconds / 1000 );
340 return minutes+
":0"+seconds;
344 return minutes+
":"+seconds;
350 if ( !isdefined( game[
"overtime_round"] ) )
354 else if ( isdefined( game[
"ctf_overtime_second_winner"] ) && ( game[
"ctf_overtime_second_winner"] == team ) )
358 else if ( isdefined( game[
"ctf_overtime_first_winner"] ) && ( game[
"ctf_overtime_first_winner"] == team ) )
370 if ( !isdefined( game[
"switchedsides"] ) )
371 game[
"switchedsides"] =
false;
373 level.halftimeType =
"halftime";
374 game[
"switchedsides"] = !game[
"switchedsides"];
379 if ( isdefined( game[
"overtime_round"] ) )
381 if ( game[
"overtime_round"] == 1 )
383 if ( isdefined( winningTeam ) && ( winningTeam !=
"tie" ) )
385 game[
"ctf_overtime_first_winner"] = winningTeam;
391 game[
"ctf_overtime_second_winner"] = winningTeam;
399 if ( level.scoreRoundWinBased )
401 foreach( team
in level.teams )
403 [[level._setTeamScore]]( team, game[
"roundswon"][team] );
410 if ( level.scoreRoundWinBased )
413 foreach( team
in level.teams )
415 [[level._setTeamScore]]( team, [[level._getTeamScore]]( team ) + game[
"ctf_teamscore_cache"][team] );
421 if ( isdefined( game[
"overtime_round"] ) )
423 if ( isdefined( game[
"ctf_overtime_first_winner"] ) )
425 if ( !isdefined( winningTeam ) || ( winningTeam ==
"tie" ) )
427 winningTeam = game[
"ctf_overtime_first_winner"];
430 if ( game[
"ctf_overtime_first_winner"] == winningTeam )
432 level.endVictoryReasonText = &
"MPUI_CTF_OVERTIME_FASTEST_CAP_TIME";
433 level.endDefeatReasonText = &
"MPUI_CTF_OVERTIME_DEFEAT_TIMELIMIT";
437 level.endVictoryReasonText = &
"MPUI_CTF_OVERTIME_FASTEST_CAP_TIME";
438 level.endDefeatReasonText = &
"MPUI_CTF_OVERTIME_DEFEAT_DID_NOT_DEFEND";
441 else if ( !isdefined( winningTeam ) || ( winningTeam ==
"tie" ) )
443 if ( level.scoreRoundWinBased )
455 if ( level.scoreRoundWinBased )
457 foreach( team
in level.teams )
459 score = game[
"roundswon"][team];
460 if ( team === winningTeam )
464 [[level._setTeamScore]]( team, score );
474 if ( level.scoreRoundWinBased )
490 self.isFlagCarrier =
false;
491 self.flagCarried = undefined;
499 level.flagCaptureTime = GetGametypeSetting(
"captureTime" );
500 level.flagTouchReturnTime = GetGametypeSetting(
"defuseTime" );
501 level.idleFlagReturnTime = GetGametypeSetting(
"idleFlagResetTime" );
502 level.flagRespawnTime = GetGametypeSetting(
"flagRespawnTime" );
503 level.enemyCarrierVisible = GetGametypeSetting(
"enemyCarrierVisible" );
504 level.roundLimit = GetGametypeSetting(
"roundLimit" );
505 level.cumulativeRoundScores = GetGametypeSetting(
"cumulativeRoundScores" );
507 level.teamKillPenaltyMultiplier = GetGametypeSetting(
"teamKillPenalty" );
508 level.teamKillScoreMultiplier = GetGametypeSetting(
"teamKillScore" );
510 if ( level.flagTouchReturnTime >= 0 && level.flagTouchReturnTime != 63)
512 level.touchReturn =
true;
516 level.touchReturn =
false;
522 if ( isdefined( trigger.target ) )
524 visuals[0] = getEnt( trigger.target,
"targetname" );
528 visuals[0] =
spawn(
"script_model", trigger.origin );
529 visuals[0].angles = trigger.angles;
532 entityTeam = trigger.script_team;
534 if ( game[
"switchedsides"] )
538 visuals[0] SetTeam( entityTeam );
551 if ( level.enemyCarrierVisible == 2 )
553 flag.objIDPingFriendly =
true;
555 flag.allowWeapons =
true;
561 if ( level.idleFlagReturnTime > 0 )
563 flag.autoResetTime = level.idleFlagReturnTime;
567 flag.autoResetTime = undefined;
577 entityTeam = trigger.script_team;
579 if ( game[
"switchedsides"] )
592 flag = level.teamFlags[entityTeam];
593 flag.flagBase = flagZone;
594 flagZone.flag = flag;
606 trigger =
spawn(
"trigger_radius", origin, 0, radius, height);
607 trigger setHintString( &
"MP_CTF_CANT_CAPTURE_FLAG" );
608 trigger setcursorhint(
"HINT_NOICON");
609 trigger.original_origin = origin;
619 level.teamFlags = [];
620 level.flagZones = [];
621 level.teamFlagZones = [];
623 flag_triggers = getEntArray(
"ctf_flag_pickup_trig",
"targetname" );
624 if ( !isdefined( flag_triggers ) || flag_triggers.size != 2)
626 /#print(
"Not enough ctf_flag_pickup_trig triggers found in map. Need two.");#/
630 for ( index = 0; index < flag_triggers.size; index++ )
632 trigger = flag_triggers[index];
637 level.flags[level.flags.size] = flag;
638 level.teamFlags[team] = flag;
642 flag_zones = getEntArray(
"ctf_flag_zone_trig",
"targetname" );
643 if ( !isdefined( flag_zones ) || flag_zones.size != 2)
645 /#print(
"Not enough ctf_flag_zone_trig triggers found in map. Need two.");#/
649 for ( index = 0; index < flag_zones.size; index++ )
651 trigger = flag_zones[index];
656 level.flagZones[level.flagZones.size] = flagZone;
657 level.teamFlagZones[team] = flagZone;
661 facing_angle = GetDvarint(
"scr_ctf_spawnPointFacingAngle");
664 setspawnpointsbaseweight(
util::getOtherTeamsMask(team), trigger.origin, facing_angle, level.spawnsystem.objective_facing_bonus);
679 level waittill (
"game_ended" );
687 if ( isdefined(
self.spawn_influencer_enemy_carrier ) )
691 self.spawn_influencer_enemy_carrier = undefined;
693 if ( isdefined(
self.spawn_influencer_friendly_carrier ) )
697 self.spawn_influencer_friendly_carrier = undefined;
699 if ( isdefined(
self.spawn_influencer_dropped ) )
703 self.spawn_influencer_dropped = undefined;
710 if ( isdefined( player ) )
713 origin = player.origin;
721 if ( level.touchReturn )
727 if ( isdefined( player ) )
742 if ( isdefined( player ) )
743 print( team +
" flag dropped" );
745 print( team +
" flag dropped" );
748 if ( isdefined( player ) )
750 player playLocalSound(
"mpl_flag_drop_plr");
757 if ( level.touchReturn )
776 if ( isdefined( player ) )
782 ss = level.spawnsystem;
786 if ( isdefined( player ) )
787 flag_origin = player.origin;
789 flag_origin =
self.curorigin;
792 SetInfluencerTimeOut(
self.spawn_influencer_dropped, level.idleFlagReturnTime );
799 carrierKilledBy =
self.carrierKilledBy;
800 self.carrierKilledBy = undefined;
801 if ( isdefined(
self.spawn_influencer_dropped ) )
804 self.spawn_influencer_dropped = undefined;
807 player AddPlayerStatWithGameType(
"PICKUPS", 1 );
811 if ( level.touchReturn )
824 if ( isdefined( player ) && player.pers[
"team"] == team )
826 self notify(
"picked_up");
830 if( isdefined(player.pers[
"returns"]) )
832 player.pers[
"returns"]++;
833 player.returns = player.pers[
"returns"];
835 if ( isdefined(carrierKilledBy) && carrierKilledBy == player )
845 player AddPlayerStatWithGameType(
"RETURNS", 1 );
853 player RecordGameEvent(
"return");
858 if ( isdefined( player ) )
859 print( team +
" flag returned" );
861 print( team +
" flag returned" );
868 player RecordGameEvent(
"pickup");
881 player.isFlagCarrier =
true;
882 player.flagCarried =
self;
883 player playLocalSound(
"mpl_flag_pickup_plr");
890 if ( level.enemyCarrierVisible )
910 player resetflashback();
912 /#print( team +
" flag taken" );#/
914 ss = level.spawnsystem;
925 self endon(
"disconnect" );
926 self endon(
"death" );
930 if (player.isFlagCarrier)
937 if ( isdefined(
self.carrier ) )
940 if (
self.curOrigin !=
self.trigger.baseOrigin )
959 if ( level.touchReturn )
978 team = player.pers[
"team"];
982 playerTeamsFlag = level.teamFlags[team];
989 if ( !isdefined( player.carryObject ) )
996 game[
"challenge"][team][
"capturedFlag"] =
true;
998 if( isdefined(player.pers[
"captures"]) )
1000 player.pers[
"captures"]++;
1001 player.captures = player.pers[
"captures"];
1005 player AddPlayerStatWithGameType(
"CAPTURES", 1 );
1015 /#print( enemyTeam +
" flag captured" );#/
1017 flag = player.carryObject;
1021 flag.dontAnnounceReturn =
true;
1023 flag.dontAnnounceReturn = undefined;
1031 player.isFlagCarrier =
false;
1032 player.flagCarried = undefined;
1049 player RecordGameEvent(
"capture");
1063 if ( level.touchReturn )
1079 if ( flag == level.flags[0] )
1080 return level.flags[1];
1082 return level.flags[0];
1085 function onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
1087 if ( isdefined( attacker ) && isplayer( attacker ) )
1089 for ( index = 0; index < level.flags.size; index++ )
1091 flagTeam =
"invalidTeam";
1092 inFlagRadius =
false;
1093 defendedFlag =
false;
1094 offendedFlag =
false;
1096 flagCarrier = level.flags[index].carrier;
1097 if ( isdefined( flagCarrier ) )
1099 flagOrigin = level.flags[index].carrier.origin;
1102 if ( isPlayer( attacker ) && ( attacker.pers[
"team"] !=
self.pers[
"team"] ) )
1104 if ( isdefined( level.flags[index].carrier.attackerData ) )
1106 if ( level.flags[index].carrier != attacker )
1108 if ( isdefined( level.flags[index].carrier.attackerData[
self.clientid] ) )
1118 flagOrigin = level.flags[index].curorigin;
1122 dist = Distance2dSquared(
self.origin, flagOrigin);
1123 if ( dist < level.defaultOffenseRadiusSQ )
1125 inFlagRadius =
true;
1126 if ( level.flags[index].ownerteam == attacker.pers[
"team"] )
1127 defendedFlag =
true;
1129 offendedFlag =
true;
1131 dist = Distance2dSquared(attacker.origin, flagOrigin);
1132 if ( dist < level.defaultOffenseRadiusSQ )
1134 inFlagRadius =
true;
1135 if ( level.flags[index].ownerteam == attacker.pers[
"team"] )
1136 defendedFlag =
true;
1138 offendedFlag =
true;
1142 if ( inFlagRadius && isPlayer( attacker ) && attacker.pers[
"team"] !=
self.pers[
"team"] )
1146 if ( isdefined(
self.isFlagCarrier ) &&
self.isFlagCarrier )
1149 attacker AddPlayerStat(
"kill_carrier", 1 );
1156 self RecordKillModifier(
"assaulting");
1160 if ( isCarried ==
true )
1162 if ( isdefined ( flagCarrier ) && attacker == flagCarrier )
1169 attacker addplayerstat(
"defend_carrier", 1 );
1176 self RecordKillModifier(
"defending");
1183 foreach( flag_zone
in level.flagZones )
1185 if ( isdefined( attacker.team ) && ( attacker != victim ) && isdefined( victim.team ) )
1187 dist_to_zone_origin = Distance2dSquared( attacker.origin, flag_zone.origin );
1188 victim_dist_to_zone_origin = Distance2dSquared( victim.origin, flag_zone.origin );
1189 if ( victim_dist_to_zone_origin < level.defaultOffenseRadiusSQ || dist_to_zone_origin < level.defaultOffenseRadiusSQ )
1191 if ( victim.team == flag_zone.team )
1204 if ( !isdefined(
self.isFlagCarrier ) || !
self.isFlagCarrier )
1207 if ( isdefined( attacker ) && isPlayer( attacker ) && attacker.pers[
"team"] !=
self.pers[
"team"] )
1209 if ( isdefined (
self.flagCarried ) )
1211 for ( index = 0; index < level.flags.size; index++ )
1213 currentFlag = level.flags[index];
1214 if ( currentFlag.ownerteam ==
self.team )
1216 if ( currentFlag.curOrigin == currentFlag.trigger.baseOrigin )
1218 dist = Distance2dSquared(
self.origin, currentFlag.curOrigin );
1219 if ( dist < level.defaultOffenseRadiusSQ )
1221 self.flagCarried.carrierKilledBy = attacker;
1229 attacker RecordGameEvent(
"kill_carrier");
1230 self RecordKillModifier(
"carrying");
1236 level.ReturnMessageElems = [];
1239 level.ReturnMessageElems[
"allies"][
"axis"]
hud::setPoint(
"TOPRIGHT",
"TOPRIGHT", 0, 0 );
1240 level.ReturnMessageElems[
"allies"][
"axis"].label = &
"MP_ENEMY_FLAG_RETURNING_IN";
1241 level.ReturnMessageElems[
"allies"][
"axis"].alpha = 0;
1242 level.ReturnMessageElems[
"allies"][
"axis"].archived =
false;
1244 level.ReturnMessageElems[
"allies"][
"allies"]
hud::setPoint(
"TOPRIGHT",
"TOPRIGHT", 0, 20 );
1245 level.ReturnMessageElems[
"allies"][
"allies"].label = &
"MP_YOUR_FLAG_RETURNING_IN";
1246 level.ReturnMessageElems[
"allies"][
"allies"].alpha = 0;
1247 level.ReturnMessageElems[
"allies"][
"allies"].archived =
false;
1250 level.ReturnMessageElems[
"axis"][
"allies"]
hud::setPoint(
"TOPRIGHT",
"TOPRIGHT", 0, 0 );
1251 level.ReturnMessageElems[
"axis"][
"allies"].label = &
"MP_ENEMY_FLAG_RETURNING_IN";
1252 level.ReturnMessageElems[
"axis"][
"allies"].alpha = 0;
1253 level.ReturnMessageElems[
"axis"][
"allies"].archived =
false;
1255 level.ReturnMessageElems[
"axis"][
"axis"]
hud::setPoint(
"TOPRIGHT",
"TOPRIGHT", 0, 20 );
1256 level.ReturnMessageElems[
"axis"][
"axis"].label = &
"MP_YOUR_FLAG_RETURNING_IN";
1257 level.ReturnMessageElems[
"axis"][
"axis"].alpha = 0;
1258 level.ReturnMessageElems[
"axis"][
"axis"].archived =
false;
1263 if ( level.touchReturn || level.idleFlagReturnTime == 0 )
1266 self notify(
"returnFlagAfterTimeMsg");
1267 self endon(
"returnFlagAfterTimeMsg");
1282 self endon(
"picked_up");
1283 level endon(
"game_ended");
1287 assert( !level.ReturnMessageElems[
"axis"][ownerteam].alpha );
1288 level.ReturnMessageElems[
"axis"][ownerteam].alpha = 1;
1289 level.ReturnMessageElems[
"axis"][ownerteam] setTimer( time );
1291 assert( !level.ReturnMessageElems[
"allies"][ownerteam].alpha );
1292 level.ReturnMessageElems[
"allies"][ownerteam].alpha = 1;
1293 level.ReturnMessageElems[
"allies"][ownerteam] setTimer( time );
1307 level.ReturnMessageElems[
"allies"][ownerteam].alpha = 0;
1308 level.ReturnMessageElems[
"axis"][ownerteam].alpha = 0;
1313 if ( level.hardcoreMode )
1316 self.origin =
self.original_origin;
1321 self.origin = (
self.original_origin[0],
self.original_origin[1],
self.original_origin[2] - 10000);
1326 allied_flag = level.teamFlags[
"allies"];
1327 axis_flag = level.teamFlags[
"axis"];
1329 if ( !level.touchReturn )
1334 level.flagHints[
"axis"]
turn_on();
1343 level.flagHints[
"allies"]
turn_on();
1353 self endon(
"disconnect");
1354 self ClientClaimTrigger( trigger );
1356 self waittill(
"drop_object");
1357 self ClientReleaseTrigger( trigger );
1374 if ( ( isdefined(
self.isFlagCarrier ) &&
self.isFlagCarrier ) )
1376 teamkill_penalty = teamkill_penalty * level.teamKillPenaltyMultiplier;
1379 return teamkill_penalty;
1386 if ( ( isdefined(
self.isFlagCarrier ) &&
self.isFlagCarrier ) )
1388 teamkill_score = teamkill_score * level.teamKillScoreMultiplier;
1391 return int(teamkill_score);