‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
ctf.gsc
Go to the documentation of this file.
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;
14 
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;
23 
24 #using scripts\mp\_challenges;
25 #using scripts\mp\_util;
26 #using scripts\mp\teams\_teams;
27 
28 #insert scripts\shared\shared.gsh;
29 #insert scripts\shared\version.gsh;
30 #insert scripts\shared\clientfields.gsh;
31 
32 #define CAPTURE_CONDITION_NONE 0
33 #define CAPTURE_CONDITION_AT_BASE 1
34 
35 /*
36  CTF
37 
38  Level requirements
39  ------------------
40  Allied Spawnpoints:
41  classname mp_sd_spawn_attacker
42  Allied players spawn from these. Place at least 16 of these relatively close together.
43 
44  Axis Spawnpoints:
45  classname mp_sd_spawn_defender
46  Axis players spawn from these. Place at least 16 of these relatively close together.
47 
48  Spectator Spawnpoints:
49  classname mp_global_intermission
50  Spectators spawn from these and intermission is viewed from these positions.
51  Atleast one is required, any more and they are randomly chosen between.
52 
53  Flag:
54  classname trigger_multiple
55  targetname flagtrigger
56  script_gameobjectname ctf
57  script_label Set to name of flag. This sets the letter shown on the compass in original mode.
58  script_team Set to allies or axis. This is used to set which team a flag is used by.
59  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.
60  Must be in the level somewhere. This is the trigger that is used to represent a flag.
61  It gets moved to the position of the planted bomb model.
62 */
63 
64 /*QUAKED mp_ctf_spawn_axis (0.75 0.0 0.5) (-16 -16 0) (16 16 72)
65 Axis players spawn away from enemies and near their team at one of these positions.*/
66 
67 /*QUAKED mp_ctf_spawn_allies (0.0 0.75 0.5) (-16 -16 0) (16 16 72)
68 Allied players spawn away from enemies and near their team at one of these positions.*/
69 
70 /*QUAKED mp_ctf_spawn_axis_start (1.0 0.0 0.5) (-16 -16 0) (16 16 72)
71 Axis players spawn away from enemies and near their team at one of these positions at the start of a round.*/
72 
73 /*QUAKED mp_ctf_spawn_allies_start (0.0 1.0 0.5) (-16 -16 0) (16 16 72)
74 Allied players spawn away from enemies and near their team at one of these positions at the start of a round.*/
75 
76 #define OBJECTIVE_FLAG_AT_BASE 0
77 #define OBJECTIVE_FLAG_AWAY 1
78 #define OBJECTIVE_FLAG_RETURN_SCORE_DIST 300
79 
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" );
120 
121 ‪REGISTER_SYSTEM( "ctf", &‪__init__, undefined )
122 
123 function ‪__init__()
124 {
125  ‪clientfield::register( "scriptmover", "ctf_flag_away", ‪VERSION_SHIP, 1, "int" );
126 }
127 
128 function ‪main()
129 {
131 
132  ‪util::registerTimeLimit( 0, 1440 );
136  ‪util::registerNumLives( 0, 100 );
137  ‪util::registerScoreLimit( 0, 5000 );
138 
139  level.scoreRoundWinBased = ( GetGametypeSetting( "cumulativeRoundScores" ) == false );
140  level.flagCaptureCondition = GetGametypeSetting( "flagCaptureCondition" );
141  level.doubleOvertime = true;
142 
143  ‪globallogic::registerFriendlyFireDelay( level.gameType, 15, 0, 1440 );
144 
145  if ( GetDvarString( "scr_ctf_spawnPointFacingAngle") == "" )
146  SetDvar("scr_ctf_spawnPointFacingAngle", "0");
147 
148  level.teamBased = true;
149  level.overrideTeamScore = true;
150  level.onStartGameType =&‪onStartGameType;
151  level.onSpawnPlayer =&‪onSpawnPlayer;
152  level.onPrecacheGameType =&‪onPrecacheGameType;
153  level.onPlayerKilled =&‪onPlayerKilled;
154  level.onRoundSwitch =&‪onRoundSwitch;
155  level.onEndGame =&‪onEndGame;
156  level.onRoundEndGame =&‪onRoundEndGame;
157  level.getTeamKillPenalty =&‪ctf_getTeamKillPenalty;
158  level.getTeamKillScore =&‪ctf_getTeamKillScore;
159  level.setMatchScoreHUDElemForTeam =&‪setMatchScoreHUDElemForTeam;
160  level.shouldPlayOvertimeRound =&‪shouldPlayOvertimeRound;
161 
163 
164  if ( !isdefined( game["ctf_teamscore_cache"] ) )
165  {
166  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
167  game["ctf_teamscore_cache"]["axis"] = 0;
168  }
169 
170  ‪globallogic_audio::set_leader_gametype_dialog ( "startCtf", "hcStartCtf", "objCapture", "objCapture" );
171 
172  level.lastDialogTime = getTime();
173 
174  level thread ‪ctf_icon_hide();
175 
176  // Sets the scoreboard columns and determines with data is sent across the network
177  if ( !SessionModeIsSystemlink() && !SessionModeIsOnlineGame() && IsSplitScreen() )
178  // local matches only show the first three columns
179  ‪globallogic::setvisiblescoreboardcolumns( "score", "kills", "captures", "returns", "deaths" );
180  else
181  ‪globallogic::setvisiblescoreboardcolumns( "score", "kills", "deaths", "captures", "returns" );
182 }
183 
185 {
186  game["flag_dropped_sound"] = "mp_war_objective_lost";
187  game["flag_recovered_sound"] = "mp_war_objective_taken";
188 
189  game["strings"]["score_limit_reached"] = &"MP_CAP_LIMIT_REACHED";
190 
191 }
192 
194 {
195  if ( !isdefined( game["switchedsides"] ) )
196  game["switchedsides"] = false;
197 
198  /#
199  setdebugsideswitch(game["switchedsides"]);
200  #/
201 
202  setClientNameMode("auto_change");
203 
205 
206  ‪util::setObjectiveText( "allies", &"OBJECTIVES_CTF" );
207  ‪util::setObjectiveText( "axis", &"OBJECTIVES_CTF" );
208 
209  if ( level.splitscreen )
210  {
211  ‪util::setObjectiveScoreText( "allies", &"OBJECTIVES_CTF" );
212  ‪util::setObjectiveScoreText( "axis", &"OBJECTIVES_CTF" );
213  }
214  else
215  {
216  ‪util::setObjectiveScoreText( "allies", &"OBJECTIVES_CTF_SCORE" );
217  ‪util::setObjectiveScoreText( "axis", &"OBJECTIVES_CTF_SCORE" );
218  }
219  ‪util::setObjectiveHintText( "allies", &"OBJECTIVES_CTF_HINT" );
220  ‪util::setObjectiveHintText( "axis", &"OBJECTIVES_CTF_HINT" );
221 
222  if ( isdefined( game["overtime_round"] ) )
223  {
224  // 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
225  game["ctf_teamscore_cache"]["allies"] += [[level._getTeamScore]]( "allies" );
226  game["ctf_teamscore_cache"]["axis"] += [[level._getTeamScore]]( "axis" );
227 
228  [[level._setTeamScore]]( "allies", 0 );
229  [[level._setTeamScore]]( "axis", 0 );
230 
231  // One flag wins the round
233  if ( isdefined( game["ctf_overtime_time_to_beat"] ) )
234  {
235  ‪util::registerTimeLimit( game["ctf_overtime_time_to_beat"] / 60000, game["ctf_overtime_time_to_beat"] / 60000 );
236  }
237 
238  if ( game["overtime_round"] == 1 )
239  {
240  ‪util::setObjectiveHintText( "allies", &"MP_CTF_OVERTIME_ROUND_1" );
241  ‪util::setObjectiveHintText( "axis", &"MP_CTF_OVERTIME_ROUND_1" );
242  }
243  else if ( isdefined( game["ctf_overtime_first_winner"] ) )
244  {
245  ‪util::setObjectiveHintText( game["ctf_overtime_first_winner"], &"MP_CTF_OVERTIME_ROUND_2_WINNER" );
246  ‪util::setObjectiveHintText( ‪util::getOtherTeam( game["ctf_overtime_first_winner"] ), &"MP_CTF_OVERTIME_ROUND_2_LOSER" );
247  }
248  else
249  {
250  ‪util::setObjectiveHintText( "allies", &"MP_CTF_OVERTIME_ROUND_2_TIE" );
251  ‪util::setObjectiveHintText( "axis", &"MP_CTF_OVERTIME_ROUND_2_TIE" );
252  }
253  }
254 
255 
256  // now that the game objects have been deleted place the influencers
258 
259  level.spawnMins = ( 0, 0, 0 );
260  level.spawnMaxs = ( 0, 0, 0 );
261  ‪spawnlogic::place_spawn_points( "mp_ctf_spawn_allies_start" );
262  ‪spawnlogic::place_spawn_points( "mp_ctf_spawn_axis_start" );
263  ‪spawnlogic::add_spawn_points( "allies", "mp_ctf_spawn_allies" );
264  ‪spawnlogic::add_spawn_points( "axis", "mp_ctf_spawn_axis" );
265 
266  ‪spawning::add_fallback_spawnpoints( "allies", "mp_tdm_spawn" );
267  ‪spawning::add_fallback_spawnpoints( "axis", "mp_tdm_spawn" );
268 
271 
272  level.mapCenter = ‪math::find_box_center( level.spawnMins, level.spawnMaxs );
273  setMapCenter( level.mapCenter );
274 
276  setDemoIntermissionPoint( spawnpoint.origin, spawnpoint.angles );
277 
278  level.spawn_axis = ‪spawnlogic::get_spawnpoint_array( "mp_ctf_spawn_axis" );
279  level.spawn_allies = ‪spawnlogic::get_spawnpoint_array( "mp_ctf_spawn_allies" );
280 
281  level.spawn_start = [];
282 
283  foreach( team in level.teams )
284  {
285  level.spawn_start[ team ] = ‪spawnlogic::get_spawnpoint_array("mp_ctf_spawn_" + team + "_start");
286  }
287 
288  thread ‪updateGametypeDvars();
289 
290  thread ‪ctf();
291 }
292 
294 {
295  // Play 2 rounds of overtime
296  if ( isdefined( game["overtime_round"] ) )
297  {
298  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
299  {
300  return true;
301  }
302 
303  return false;
304  }
305 
306  if ( !level.scoreRoundWinBased )
307  {
308  // Only go to overtime if both teams are tied and it's either the last round or both teams are one away from winning
309  if ( ( game["teamScores"]["allies"] == game["teamScores"]["axis"] ) &&
310  ( ‪util::hitRoundLimit() || ( game["teamScores"]["allies"] == level.scoreLimit-1 ) ) )
311  {
312  return true;
313  }
314  }
315  else
316  {
317  // Only go to overtime if both teams are one round away from winning
318  alliesRoundsWon = ‪util::getRoundsWon( "allies" );
319  axisRoundsWon = ‪util::getRoundsWon( "axis" );
320  if ( ( level.roundWinLimit > 0 ) && ( axisRoundsWon == level.roundWinLimit-1 ) && ( alliesRoundsWon == level.roundWinLimit-1 ) )
321  {
322  return true;
323  }
324  if ( ‪util::hitRoundLimit() && ( alliesRoundsWon == axisRoundsWon ) )
325  {
326  return true;
327  }
328  }
329 
330  return false;
331 }
332 
333 function ‪minutesAndSecondsString( milliseconds )
334 {
335  minutes = floor( milliseconds / 60000 );
336  milliseconds -= minutes * 60000;
337  seconds = floor( milliseconds / 1000 );
338  if ( seconds < 10 )
339  {
340  return minutes+":0"+seconds;
341  }
342  else
343  {
344  return minutes+":"+seconds;
345  }
346 }
347 
349 {
350  if ( !isdefined( game["overtime_round"] ) )
351  {
353  }
354  else if ( isdefined( game["ctf_overtime_second_winner"] ) && ( game["ctf_overtime_second_winner"] == team ) )
355  {
356  self setText( ‪minutesAndSecondsString( game["ctf_overtime_best_time"] ) );
357  }
358  else if ( isdefined( game["ctf_overtime_first_winner"] ) && ( game["ctf_overtime_first_winner"] == team ) )
359  {
360  self setText( ‪minutesAndSecondsString( game["ctf_overtime_time_to_beat"] ) );
361  }
362  else
363  {
364  self setText( &"" );
365  }
366 }
367 
369 {
370  if ( !isdefined( game["switchedsides"] ) )
371  game["switchedsides"] = false;
372 
373  level.halftimeType = "halftime";
374  game["switchedsides"] = !game["switchedsides"];
375 }
376 
377 function ‪onEndGame( winningTeam )
378 {
379  if ( isdefined( game["overtime_round"] ) )
380  {
381  if ( game["overtime_round"] == 1 )
382  {
383  if ( isdefined( winningTeam ) && ( winningTeam != "tie" ) )
384  {
385  game["ctf_overtime_first_winner"] = winningTeam;
386  game["ctf_overtime_time_to_beat"] = ‪globallogic_utils::getTimePassed();
387  }
388  }
389  else
390  {
391  game["ctf_overtime_second_winner"] = winningTeam;
392  game["ctf_overtime_best_time"] = ‪globallogic_utils::getTimePassed();
393  }
394  }
395 }
396 
398 {
399  if ( level.scoreRoundWinBased )
400  {
401  foreach( team in level.teams )
402  {
403  [[level._setTeamScore]]( team, game["roundswon"][team] );
404  }
405  }
406 }
407 
409 {
410  if ( level.scoreRoundWinBased )
411  return;
412 
413  foreach( team in level.teams )
414  {
415  [[level._setTeamScore]]( team, [[level._getTeamScore]]( team ) + game["ctf_teamscore_cache"][team] );
416  }
417 }
418 
419 function ‪onRoundEndGame( winningTeam )
420 {
421  if ( isdefined( game["overtime_round"] ) )
422  {
423  if ( isdefined( game["ctf_overtime_first_winner"] ) )
424  {
425  if ( !isdefined( winningTeam ) || ( winningTeam == "tie" ) )
426  {
427  winningTeam = game["ctf_overtime_first_winner"];
428  }
429 
430  if ( game["ctf_overtime_first_winner"] == winningTeam )
431  {
432  level.endVictoryReasonText = &"MPUI_CTF_OVERTIME_FASTEST_CAP_TIME";
433  level.endDefeatReasonText = &"MPUI_CTF_OVERTIME_DEFEAT_TIMELIMIT";
434  }
435  else
436  {
437  level.endVictoryReasonText = &"MPUI_CTF_OVERTIME_FASTEST_CAP_TIME";
438  level.endDefeatReasonText = &"MPUI_CTF_OVERTIME_DEFEAT_DID_NOT_DEFEND";
439  }
440  }
441  else if ( !isdefined( winningTeam ) || ( winningTeam == "tie" ) )
442  {
443  if ( level.scoreRoundWinBased )
444  {
446  }
447  else
448  {
450  }
451 
452  return "tie";
453  }
454 
455  if ( level.scoreRoundWinBased )
456  {
457  foreach( team in level.teams )
458  {
459  score = game["roundswon"][team];
460  if ( team === winningTeam )
461  {
462  score++;
463  }
464  [[level._setTeamScore]]( team, score );
465  }
466  }
467  else
468  {
470  }
471  return winningTeam;
472  }
473 
474  if ( level.scoreRoundWinBased )
475  {
477 
478  winner = ‪globallogic::determineTeamWinnerByGameStat( "roundswon" );
479  }
480  else
481  {
483  }
484 
485  return winner;
486 }
487 
488 function ‪onSpawnPlayer(predictedSpawn)
489 {
490  self.isFlagCarrier = false;
491  self.flagCarried = undefined;
493 
494  ‪spawning::onSpawnPlayer(predictedSpawn);
495 }
496 
498 {
499  level.flagCaptureTime = GetGametypeSetting( "captureTime" );
500  level.flagTouchReturnTime = GetGametypeSetting( "defuseTime" ); // using defuseTime for touch return
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" );
506 
507  level.teamKillPenaltyMultiplier = GetGametypeSetting( "teamKillPenalty" );
508  level.teamKillScoreMultiplier = GetGametypeSetting( "teamKillScore" );
509 
510  if ( level.flagTouchReturnTime >= 0 && level.flagTouchReturnTime != 63)
511  {
512  level.touchReturn = true;
513  }
514  else
515  {
516  level.touchReturn = false;
517  }
518 }
519 
520 function ‪createFlag( trigger )
521 {
522  if ( isdefined( trigger.target ) )
523  {
524  visuals[0] = getEnt( trigger.target, "targetname" );
525  }
526  else
527  {
528  visuals[0] = ‪spawn( "script_model", trigger.origin );
529  visuals[0].angles = trigger.angles;
530  }
531 
532  entityTeam = trigger.script_team;
533  // TODO MTEAM - switched sides
534  if ( game["switchedsides"] )
535  entityTeam = ‪util::getOtherTeam( entityTeam );
536 
537  visuals[0] setModel( ‪teams::get_flag_model( entityTeam ) );
538  visuals[0] SetTeam( entityTeam );
539 
540  flag = ‪gameobjects::create_carry_object( entityTeam, trigger, visuals, (0,0,100), istring(entityTeam+"_flag") );
541  flag ‪gameobjects::set_team_use_time( "friendly", level.flagTouchReturnTime );
542  flag ‪gameobjects::set_team_use_time( "enemy", level.flagCaptureTime );
543  flag ‪gameobjects::allow_carry( "enemy" );
544  flag ‪gameobjects::set_visible_team( "any" );
546  flag ‪gameobjects::set_2d_icon( "friendly", level.iconDefend2D );
547  flag ‪gameobjects::set_3d_icon( "friendly", level.iconDefend3D );
548  flag ‪gameobjects::set_2d_icon( "enemy", level.iconCapture2D );
549  flag ‪gameobjects::set_3d_icon( "enemy", level.iconCapture3D );
550 
551  if ( level.enemyCarrierVisible == 2 )
552  {
553  flag.objIDPingFriendly = true;
554  }
555  flag.allowWeapons = true;
556  flag.onPickup =&‪onPickup;
557  flag.onPickupFailed =&‪onPickup;
558  flag.onDrop =&‪onDrop;
559  flag.onReset =&‪onReset;
560 
561  if ( level.idleFlagReturnTime > 0 )
562  {
563  flag.autoResetTime = level.idleFlagReturnTime;
564  }
565  else
566  {
567  flag.autoResetTime = undefined;
568  }
569 
570  return flag;
571 }
572 
573 function ‪createFlagZone( trigger )
574 {
575  visuals = [];
576 
577  entityTeam = trigger.script_team;
578  // TODO MTEAM - switched sides
579  if ( game["switchedsides"] )
580  entityTeam = ‪util::getOtherTeam( entityTeam );
581 
582  flagZone = ‪gameobjects::create_use_object( entityTeam, trigger, visuals, (0,0,0), istring(entityTeam+"_base") );
583  flagZone ‪gameobjects::allow_use( "friendly" );
584  flagZone ‪gameobjects::set_use_time( 0 );
585  flagZone ‪gameobjects::set_use_text( &"MP_CAPTURING_FLAG" );
586  flagZone ‪gameobjects::set_visible_team( "friendly" );
587 
588  enemyTeam = ‪util::getOtherTeam( entityTeam );
589  flagZone ‪gameobjects::set_key_object( level.teamFlags[enemyTeam] );
590  flagZone.onUse =&‪onCapture;
591 
592  flag = level.teamFlags[entityTeam];
593  flag.flagBase = flagZone;
594  flagZone.flag = flag;
595 
596  flagZone ‪createFlagSpawnInfluencer( entityTeam );
597 
598  return flagZone;
599 }
600 
601 function ‪createFlagHint( team, origin )
602 {
603  radius = 128;
604  height = 64;
605 
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;
610 
611  trigger ‪turn_off();
612 
613  return trigger;
614 }
615 
616 function ‪ctf()
617 {
618  level.flags = [];
619  level.teamFlags = [];
620  level.flagZones = [];
621  level.teamFlagZones = [];
622 
623  flag_triggers = getEntArray( "ctf_flag_pickup_trig", "targetname" );
624  if ( !isdefined( flag_triggers ) || flag_triggers.size != 2)
625  {
626  /#print("Not enough ctf_flag_pickup_trig triggers found in map. Need two.");#/
627  return;
628  }
629 
630  for ( index = 0; index < flag_triggers.size; index++ )
631  {
632  trigger = flag_triggers[index];
633 
634  flag = ‪createFlag( trigger );
635 
636  team = flag ‪gameobjects::get_owner_team();
637  level.flags[level.flags.size] = flag;
638  level.teamFlags[team] = flag;
639 
640  }
641 
642  flag_zones = getEntArray( "ctf_flag_zone_trig", "targetname" );
643  if ( !isdefined( flag_zones ) || flag_zones.size != 2)
644  {
645  /#print("Not enough ctf_flag_zone_trig triggers found in map. Need two.");#/
646  return;
647  }
648 
649  for ( index = 0; index < flag_zones.size; index++ )
650  {
651  trigger = flag_zones[index];
652 
653  flagZone = ‪createFlagZone( trigger );
654 
655  team = flagZone ‪gameobjects::get_owner_team();
656  level.flagZones[level.flagZones.size] = flagZone;
657  level.teamFlagZones[team] = flagZone;
658 
659  level.flagHints[team] = ‪createFlagHint( team, trigger.origin );
660 
661  facing_angle = GetDvarint( "scr_ctf_spawnPointFacingAngle");
662 
663  // the opposite team will want to face this point
664  setspawnpointsbaseweight( ‪util::getOtherTeamsMask(team), trigger.origin, facing_angle, level.spawnsystem.objective_facing_bonus);
665  }
666 
667  // once all the flags have been registered with the game,
668  // give each spawn point a baseline score for each objective flag,
669  // based on whether or not player will be looking in the direction of that flag upon spawning
670  //generate_baseline_spawn_point_scores();
671 
673 }
674 
675 //Runs each round, as function as restarted at the start of every round.
676 //Hides the flag status icons and the 2D and 3D icons from the player's view
678 {
679  level waittill ( "game_ended" );
680 
681  level.teamFlags["allies"] ‪gameobjects::set_visible_team( "none" );
682  level.teamFlags["axis"] ‪gameobjects::set_visible_team( "none" );
683 }
684 
686 {
687  if ( isdefined( self.spawn_influencer_enemy_carrier ) )
688  {
689  // self == player
690  self ‪spawning::remove_influencer( self.spawn_influencer_enemy_carrier );
691  self.spawn_influencer_enemy_carrier = undefined;
692  }
693  if ( isdefined( self.spawn_influencer_friendly_carrier ) )
694  {
695  // self == player
696  self ‪spawning::remove_influencer( self.spawn_influencer_friendly_carrier );
697  self.spawn_influencer_friendly_carrier = undefined;
698  }
699  if ( isdefined( self.spawn_influencer_dropped ) )
700  {
701  // self == flag
702  self.trigger ‪spawning::remove_influencer( self.spawn_influencer_dropped );
703  self.spawn_influencer_dropped = undefined;
704  }
705 }
706 
707 function ‪onDrop( player )
708 {
709  origin = (0,0,0);
710  if ( isdefined( player ) )
711  {
713  origin = player.origin;
714  }
715 
716  team = self ‪gameobjects::get_owner_team();
717  otherTeam = ‪util::getOtherTeam( team );
718 
719  self.visuals[0] ‪clientfield::set( "ctf_flag_away", 1 );
720 
721  if ( level.touchReturn )
722  {
723  self ‪gameobjects::allow_carry( "any" );
724  level.flagHints[otherTeam] ‪turn_off();
725  }
726 
727  if ( isdefined( player ) )
728  {
729  ‪util::printAndSoundOnEveryone( team, undefined, &"", undefined, "mp_war_objective_lost" );
730 
731  level thread ‪popups::DisplayTeamMessageToTeam( &"MP_FRIENDLY_FLAG_DROPPED", player, team );
732  level thread ‪popups::DisplayTeamMessageToTeam( &"MP_ENEMY_FLAG_DROPPED", player, otherTeam );
733  }
734  else
735  {
736  ‪util::printAndSoundOnEveryone( team, undefined, &"", undefined, "mp_war_objective_lost" );
737  }
738 
739  ‪globallogic_audio::leader_dialog( "ctfFriendlyFlagDropped", team, undefined, "ctf_flag" );
740  ‪globallogic_audio::leader_dialog( "ctfEnemyFlagDropped", otherTeam, undefined, "ctf_flag_enemy" );
741  /#
742  if ( isdefined( player ) )
743  print( team + " flag dropped" );
744  else
745  print( team + " flag dropped" );
746  #/
747 
748  if ( isdefined( player ) )
749  {
750  player playLocalSound("mpl_flag_drop_plr");
751  }
752 
753 
754  ‪globallogic_audio::play_2d_on_team( "mpl_flagdrop_sting_friend", otherTeam );
755  ‪globallogic_audio::play_2d_on_team( "mpl_flagdrop_sting_enemy", team );
756 
757  if ( level.touchReturn )
758  {
759  self ‪gameobjects::set_3d_icon( "friendly", level.iconReturn3D );
760  self ‪gameobjects::set_2d_icon( "friendly", level.iconReturn2D );
761  }
762  else
763  {
764  self ‪gameobjects::set_3d_icon( "friendly", level.iconDropped3D );
765  self ‪gameobjects::set_2d_icon( "friendly", level.iconDropped2D );
766  }
767  self ‪gameobjects::set_visible_team( "any" );
768  self ‪gameobjects::set_3d_icon( "enemy", level.iconCapture3D );
769  self ‪gameobjects::set_2d_icon( "enemy", level.iconCapture2D );
770 
771  thread ‪sound::play_on_players( game["flag_dropped_sound"], game["attackers"] );
772 
773  self thread ‪returnFlagAfterTimeMsg( level.idleFlagReturnTime );
774 
775  // remove carrier influencers
776  if ( isdefined( player ) )
777  {
778  player ‪removeInfluencers();
779  }
780 
781  // create new influencers on the flag
782  ss = level.spawnsystem;
783  player_team_mask = ‪util::getTeamMask( otherTeam ); // this is the player that has the flag's team
784  enemy_team_mask = ‪util::getTeamMask( team ); // and his enemies
785 
786  if ( isdefined( player ) )
787  flag_origin = player.origin;
788  else
789  flag_origin = self.curorigin;
790 
791  self.spawn_influencer_dropped = self.trigger ‪spawning::create_entity_influencer( "ctf_flag_dropped", player_team_mask|enemy_team_mask );
792  SetInfluencerTimeOut( self.spawn_influencer_dropped, level.idleFlagReturnTime );
793 
794 }
795 
796 
797 function ‪onPickup( player )
798 {
799  carrierKilledBy = self.carrierKilledBy;
800  self.carrierKilledBy = undefined;
801  if ( isdefined( self.spawn_influencer_dropped ) )
802  {
803  self.trigger ‪spawning::remove_influencer( self.spawn_influencer_dropped );
804  self.spawn_influencer_dropped = undefined;
805  }
806 
807  player AddPlayerStatWithGameType( "PICKUPS", 1 );
808 
809  //scoreevents::processScoreEvent( "flag_grab", player );
810 
811  if ( level.touchReturn )
812  {
813  self ‪gameobjects::allow_carry( "enemy" );
814  }
815 
816  // always clear influencers. we'll create new ones if it's been picked up by an enemy.
817  self ‪removeInfluencers();
818 
819  team = self ‪gameobjects::get_owner_team();
820  otherTeam = ‪util::getOtherTeam( team );
821 
823 
824  if ( isdefined( player ) && player.pers["team"] == team )
825  {
826  self notify("picked_up");
827 
828  ‪util::printAndSoundOnEveryone( team, undefined, &"", undefined, "mp_obj_returned" );
829 
830  if( isdefined(player.pers["returns"]) )
831  {
832  player.pers["returns"]++;
833  player.returns = player.pers["returns"];
834  }
835  if ( isdefined(carrierKilledBy) && carrierKilledBy == player )
836  {
837  ‪scoreevents::processScoreEvent( "flag_carrier_kill_return_close", player );
838  }
839  else if (distancesquared(self.trigger.baseOrigin, player.origin) > ‪OBJECTIVE_FLAG_RETURN_SCORE_DIST*‪OBJECTIVE_FLAG_RETURN_SCORE_DIST)
840  {
841  ‪scoreevents::processScoreEvent( "flag_return", player );
842  }
843  ‪demo::bookmark( "event", gettime(), player );
844 
845  player AddPlayerStatWithGameType( "RETURNS", 1 );
846 
847  level thread ‪popups::DisplayTeamMessageToTeam( &"MP_FRIENDLY_FLAG_RETURNED", player, team );
848  level thread ‪popups::DisplayTeamMessageToTeam( &"MP_ENEMY_FLAG_RETURNED", player, otherTeam );
849 
850  self.visuals[0] ‪clientfield::set( "ctf_flag_away", 0 );
852 
853  player RecordGameEvent("return");
854 
855  // want to return the flag here
856  self ‪returnFlag();
857  /#
858  if ( isdefined( player ) )
859  print( team + " flag returned" );
860  else
861  print( team + " flag returned" );
862  #/
863 
864  return;
865  }
866  else
867  {
868  player RecordGameEvent("pickup");
869 
870  ‪scoreevents::processScoreEvent( "flag_grab", player );
871  ‪demo::bookmark( "event", gettime(), player );
872 
873  ‪util::printAndSoundOnEveryone( otherteam, undefined, &"", undefined, "mp_obj_taken", "mp_enemy_obj_taken" );
874 
875  level thread ‪popups::DisplayTeamMessageToTeam( &"MP_FRIENDLY_FLAG_TAKEN", player, team );
876  level thread ‪popups::DisplayTeamMessageToTeam( &"MP_ENEMY_FLAG_TAKEN", player, otherTeam );
877 
878  ‪globallogic_audio::leader_dialog( "ctfFriendlyFlagTaken", team, undefined, "ctf_flag" );
879  ‪globallogic_audio::leader_dialog( "ctfEnemyFlagTaken", otherTeam, undefined, "ctf_flag_enemy" );
880 
881  player.isFlagCarrier = true;
882  player.flagCarried = self;
883  player playLocalSound("mpl_flag_pickup_plr");
886 
887  ‪globallogic_audio::play_2d_on_team( "mpl_flagget_sting_friend", otherTeam );
888  ‪globallogic_audio::play_2d_on_team( "mpl_flagget_sting_enemy", team );
889 
890  if ( level.enemyCarrierVisible )
891  {
892  self ‪gameobjects::set_visible_team( "any" );
893  }
894  else
895  {
896  self ‪gameobjects::set_visible_team( "enemy" );
897  }
898 
899  self ‪gameobjects::set_2d_icon( "friendly", level.iconKill2D );
900  self ‪gameobjects::set_3d_icon( "friendly", level.iconKill3D );
901  self ‪gameobjects::set_2d_icon( "enemy", level.iconEscort2D );
902  self ‪gameobjects::set_3d_icon( "enemy", level.iconEscort3D );
903 
904  player thread ‪claim_trigger( level.flagHints[otherTeam] );
905 
906  ‪update_hints();
907 
908 
909  //Reset flashback here
910  player resetflashback();
911 
912  /#print( team + " flag taken" );#/
913 
914  ss = level.spawnsystem;
915  player_team_mask = ‪util::getTeamMask( otherTeam ); // this is the player that has the flag's team
916  enemy_team_mask = ‪util::getTeamMask( team ); // and his enemies
917 
918  player.spawn_influencer_friendly_carrier = player ‪spawning::create_entity_masked_friendly_influencer( "ctf_carrier_friendly", player_team_mask );
919  player.spawn_influencer_enemy_carrier = player ‪spawning::create_entity_masked_enemy_influencer( "ctf_carrier_enemy", enemy_team_mask );
920  }
921 
922 }
923 function ‪OnPickupMusicState ( player )
924 {
925  self endon( "disconnect" );
926  self endon( "death" );
927 
928  // wait 6 seconds and see if the player still has the flag.
929  wait (6);
930  if (player.isFlagCarrier)
931  {
932  //Was the SUSPENSE state changes to ACTION - removed state CDC - 6/19/12
933  }
934 }
935 function ‪isHome()
936 {
937  if ( isdefined( self.carrier ) )
938  return false;
939 
940  if ( self.curOrigin != self.trigger.baseOrigin )
941  return false;
942 
943  return true;
944 }
945 
946 function ‪returnFlag()
947 {
948  team = self ‪gameobjects::get_owner_team();
949  otherTeam = ‪util::getOtherTeam(team);
950 
951  ‪globallogic_audio::play_2d_on_team( "mpl_flagreturn_sting", team );
952  ‪globallogic_audio::play_2d_on_team( "mpl_flagreturn_sting", otherTeam );
953 
954  level.teamFlagZones[otherTeam] ‪gameobjects::allow_use( "friendly" );
955  level.teamFlagZones[otherTeam] ‪gameobjects::set_visible_team( "friendly" );
956 
957  ‪update_hints();
958 
959  if ( level.touchReturn )
960  {
961  self ‪gameobjects::allow_carry( "enemy" );
962  }
964  self ‪gameobjects::set_visible_team( "any" );
965  //TODO: Add 2D Icons
966  self ‪gameobjects::set_3d_icon( "friendly", level.iconDefend3D );
967  self ‪gameobjects::set_2d_icon( "friendly", level.iconDefend2D );
968  self ‪gameobjects::set_3d_icon( "enemy", level.iconCapture3D );
969  self ‪gameobjects::set_2d_icon( "enemy", level.iconCapture2D );
970 
971  ‪globallogic_audio::leader_dialog( "ctfFriendlyFlagReturned", team, undefined, "ctf_flag" );
972  ‪globallogic_audio::leader_dialog( "ctfEnemyFlagReturned", otherTeam, undefined, "ctf_flag_enemy" );
973 }
974 
975 
976 function ‪onCapture( player )
977 {
978  team = player.pers["team"];
979  enemyTeam = ‪util::getOtherTeam( team );
980  time = gettime();
981 
982  playerTeamsFlag = level.teamFlags[team];
983 
984  if ( (level.flagCaptureCondition == ‪CAPTURE_CONDITION_AT_BASE) && playerTeamsFlag ‪gameobjects::is_object_away_from_home() )
985  {
986  return;
987  }
988 
989  if ( !isdefined( player.carryObject ) )
990  {
991  return; // the carryObject can be undefined if the player dies a frame before (and possibly other edges cases)
992  }
993 
994  ‪util::printAndSoundOnEveryone( team, undefined, &"", undefined, "mp_obj_captured", "mp_enemy_obj_captured" );
995 
996  game["challenge"][team]["capturedFlag"] = true;
997 
998  if( isdefined(player.pers["captures"]) )
999  {
1000  player.pers["captures"]++;
1001  player.captures = player.pers["captures"];
1002  }
1003 
1004  ‪demo::bookmark( "event", gettime(), player );
1005  player AddPlayerStatWithGameType( "CAPTURES", 1 );
1006 
1007  level thread ‪popups::DisplayTeamMessageToTeam( &"MP_ENEMY_FLAG_CAPTURED", player, team );
1008  level thread ‪popups::DisplayTeamMessageToTeam( &"MP_FRIENDLY_FLAG_CAPTURED", player, enemyTeam );
1009 
1010  ‪globallogic_audio::play_2d_on_team( "mpl_flagcapture_sting_enemy", enemyTeam );
1011  ‪globallogic_audio::play_2d_on_team( "mpl_flagcapture_sting_friend", team );
1012 
1013  player ‪giveFlagCaptureXP( player );
1014 
1015  /#print( enemyTeam + " flag captured" );#/
1016 
1017  flag = player.carryObject;
1018 
1019  player ‪challenges::capturedObjective( time, flag.trigger );
1020 
1021  flag.dontAnnounceReturn = true;
1023  flag.dontAnnounceReturn = undefined;
1024 
1025  otherTeam = ‪util::getOtherTeam(team);
1026  level.teamFlags[otherTeam] ‪gameobjects::allow_carry( "enemy" );
1027  level.teamFlags[otherTeam] ‪gameobjects::set_visible_team( "any" );
1028  level.teamFlags[otherTeam] ‪gameobjects::return_home();
1029  level.teamFlagZones[otherTeam] ‪gameobjects::allow_use( "friendly" );
1030 
1031  player.isFlagCarrier = false;
1032  player.flagCarried = undefined;
1034 
1035  // execution will stop on this line on last flag cap of a level
1037 
1038  // NOTE: team is the team of the capturing player, unlike in other flag events
1039  ‪globallogic_audio::leader_dialog( "ctfEnemyFlagCaptured", team, undefined, "ctf_flag_enemy" );
1040  ‪globallogic_audio::leader_dialog( "ctfFriendlyFlagCaptured", enemyTeam, undefined, "ctf_flag" );
1041 
1042  flag ‪removeInfluencers();
1043  player ‪removeInfluencers();
1044 }
1045 
1046 function ‪giveFlagCaptureXP( player )
1047 {
1048  ‪scoreevents::processScoreEvent( "flag_capture", player );
1049  player RecordGameEvent("capture");
1050 }
1051 
1052 function ‪onReset()
1053 {
1054  ‪update_hints();
1055 
1056  team = self ‪gameobjects::get_owner_team();
1057 
1058  self ‪gameobjects::set_3d_icon( "friendly", level.iconDefend3D );
1059  self ‪gameobjects::set_2d_icon( "friendly", level.iconDefend2D );
1060  self ‪gameobjects::set_3d_icon( "enemy", level.iconCapture3D );
1061  self ‪gameobjects::set_2d_icon( "enemy", level.iconCapture2D );
1062 
1063  if ( level.touchReturn )
1064  {
1065  self ‪gameobjects::allow_carry( "enemy" );
1066  }
1067 
1068  level.teamFlagZones[team] ‪gameobjects::set_visible_team( "friendly" );
1069  level.teamFlagZones[team] ‪gameobjects::allow_use( "friendly" );
1070 
1071  self.visuals[0] ‪clientfield::set( "ctf_flag_away", 0 );
1074  self ‪removeInfluencers();
1075 }
1076 
1077 function ‪getOtherFlag( flag )
1078 {
1079  if ( flag == level.flags[0] )
1080  return level.flags[1];
1081 
1082  return level.flags[0];
1083 }
1084 
1085 function ‪onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
1086 {
1087  if ( isdefined( attacker ) && isplayer( attacker ) )
1088  {
1089  for ( index = 0; index < level.flags.size; index++ )
1090  {
1091  flagTeam = "invalidTeam";
1092  inFlagRadius = false;
1093  defendedFlag = false;
1094  offendedFlag = false;
1095 
1096  flagCarrier = level.flags[index].carrier;
1097  if ( isdefined( flagCarrier ) )
1098  {
1099  flagOrigin = level.flags[index].carrier.origin;
1100  isCarried = true;
1101 
1102  if ( isPlayer( attacker ) && ( attacker.pers["team"] != self.pers["team"] ) )
1103  {
1104  if ( isdefined( level.flags[index].carrier.attackerData ) )
1105  {
1106  if ( level.flags[index].carrier != attacker )
1107  {
1108  if ( isdefined( level.flags[index].carrier.attackerData[self.clientid] ) )
1109  {
1110  ‪scoreevents::processScoreEvent( "rescue_flag_carrier", attacker, undefined, weapon );
1111  }
1112  }
1113  }
1114  }
1115  }
1116  else
1117  {
1118  flagOrigin = level.flags[index].curorigin;
1119  isCarried = false;
1120  }
1121 
1122  dist = Distance2dSquared(self.origin, flagOrigin);
1123  if ( dist < level.defaultOffenseRadiusSQ )
1124  {
1125  inFlagRadius = true;
1126  if ( level.flags[index].ownerteam == attacker.pers["team"] )
1127  defendedFlag = true;
1128  else
1129  offendedFlag = true;
1130  }
1131  dist = Distance2dSquared(attacker.origin, flagOrigin);
1132  if ( dist < level.defaultOffenseRadiusSQ )
1133  {
1134  inFlagRadius = true;
1135  if ( level.flags[index].ownerteam == attacker.pers["team"] )
1136  defendedFlag = true;
1137  else
1138  offendedFlag = true;
1139  }
1140 
1141 
1142  if ( inFlagRadius && isPlayer( attacker ) && attacker.pers["team"] != self.pers["team"] )
1143  {
1144  if ( defendedFlag )
1145  {
1146  if ( isdefined( self.isFlagCarrier ) && self.isFlagCarrier )
1147  {
1148  ‪scoreevents::processScoreEvent( "kill_flag_carrier", attacker, undefined, weapon );
1149  attacker AddPlayerStat( "kill_carrier", 1 );
1150  }
1151  else
1152  {
1153  ‪scoreevents::processScoreEvent( "killed_attacker", attacker, undefined, weapon );
1154  }
1155 
1156  self RecordKillModifier("assaulting");
1157  }
1158  if ( offendedFlag )
1159  {
1160  if ( isCarried == true )
1161  {
1162  if ( isdefined ( flagCarrier ) && attacker == flagCarrier )
1163  {
1164  ‪scoreevents::processScoreEvent( "killed_enemy_while_carrying_flag", attacker, undefined, weapon );
1165  }
1166  else
1167  {
1168  ‪scoreevents::processScoreEvent( "defend_flag_carrier", attacker, undefined, weapon );
1169  attacker addplayerstat( "defend_carrier", 1 );
1170  }
1171  }
1172  else
1173  {
1174  ‪scoreevents::processScoreEvent( "killed_defender", attacker, undefined, weapon );
1175  }
1176  self RecordKillModifier("defending");
1177  }
1178  }
1179  }
1180 
1181  victim = self;
1182 
1183  foreach( flag_zone in level.flagZones )
1184  {
1185  if ( isdefined( attacker.team ) && ( attacker != victim ) && isdefined( victim.team ) )
1186  {
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 )
1190  {
1191  if ( victim.team == flag_zone.team )
1192  {
1193  attacker thread ‪challenges::killedBaseDefender( flag_zone.trigger );
1194  }
1195  else
1196  {
1197  attacker thread ‪challenges::killedBaseOffender( flag_zone.trigger, weapon );
1198  }
1199  }
1200  }
1201  }
1202  }
1203 
1204  if ( !isdefined( self.isFlagCarrier ) || !self.isFlagCarrier )
1205  return;
1206 
1207  if ( isdefined( attacker ) && isPlayer( attacker ) && attacker.pers["team"] != self.pers["team"] )
1208  {
1209  if ( isdefined ( self.flagCarried ) )
1210  {
1211  for ( index = 0; index < level.flags.size; index++ )
1212  {
1213  currentFlag = level.flags[index];
1214  if ( currentFlag.ownerteam == self.team )
1215  {
1216  if ( currentFlag.curOrigin == currentFlag.trigger.baseOrigin )
1217  {
1218  dist = Distance2dSquared(self.origin, currentFlag.curOrigin );
1219  if ( dist < level.defaultOffenseRadiusSQ )
1220  {
1221  self.flagCarried.carrierKilledBy = attacker;
1222  break;
1223  }
1224  }
1225  }
1226  }
1227  }
1228 
1229  attacker RecordGameEvent("kill_carrier");
1230  self RecordKillModifier("carrying");
1231  }
1232 }
1233 
1235 {
1236  level.ReturnMessageElems = [];
1237 
1238  level.ReturnMessageElems["allies"]["axis"] = ‪hud::createServerTimer( "objective", 1.4, "allies" );
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;
1243  level.ReturnMessageElems["allies"]["allies"] = ‪hud::createServerTimer( "objective", 1.4, "allies" );
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;
1248 
1249  level.ReturnMessageElems["axis"]["allies"] = ‪hud::createServerTimer( "objective", 1.4, "axis" );
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;
1254  level.ReturnMessageElems["axis"]["axis"] = ‪hud::createServerTimer( "objective", 1.4, "axis" );
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;
1259 }
1260 
1262 {
1263  if ( level.touchReturn || level.idleFlagReturnTime == 0 )
1264  return;
1265 
1266  self notify("returnFlagAfterTimeMsg");
1267  self endon("returnFlagAfterTimeMsg");
1268 
1269  ‪result = ‪returnFlagHudElems( time );
1270 
1271  self ‪removeInfluencers();
1273 
1274  if ( !isdefined( ‪result ) ) // returnFlagHudElems hit an endon
1275  return;
1276 
1277 // self returnFlag();
1278 }
1279 
1280 function ‪returnFlagHudElems( time )
1281 {
1282  self endon("picked_up");
1283  level endon("game_ended");
1284 
1285  ownerteam = self ‪gameobjects::get_owner_team();
1286 
1287  assert( !level.ReturnMessageElems["axis"][ownerteam].alpha );
1288  level.ReturnMessageElems["axis"][ownerteam].alpha = 1;
1289  level.ReturnMessageElems["axis"][ownerteam] setTimer( time );
1290 
1291  assert( !level.ReturnMessageElems["allies"][ownerteam].alpha );
1292  level.ReturnMessageElems["allies"][ownerteam].alpha = 1;
1293  level.ReturnMessageElems["allies"][ownerteam] setTimer( time );
1294 
1295  if( time <= 0 )
1296  return false;
1297  else
1298  wait time;
1299 
1300  return true;
1301 }
1302 
1304 {
1305  ownerteam = self ‪gameobjects::get_owner_team();
1306 
1307  level.ReturnMessageElems["allies"][ownerteam].alpha = 0;
1308  level.ReturnMessageElems["axis"][ownerteam].alpha = 0;
1309 }
1310 
1311 function ‪turn_on()
1312 {
1313  if ( level.hardcoreMode )
1314  return;
1315 
1316  self.origin = self.original_origin;
1317 }
1318 
1319 function ‪turn_off()
1320 {
1321  self.origin = ( self.original_origin[0], self.original_origin[1], self.original_origin[2] - 10000);
1322 }
1323 
1325 {
1326  allied_flag = level.teamFlags["allies"];
1327  axis_flag = level.teamFlags["axis"];
1328 
1329  if ( !level.touchReturn )
1330  return;
1331 
1332  if ( isdefined(allied_flag.carrier) && axis_flag ‪gameobjects::is_object_away_from_home() )
1333  {
1334  level.flagHints["axis"] ‪turn_on();
1335  }
1336  else
1337  {
1338  level.flagHints["axis"] ‪turn_off();
1339  }
1340 
1341  if ( isdefined(axis_flag.carrier) && allied_flag ‪gameobjects::is_object_away_from_home() )
1342  {
1343  level.flagHints["allies"] ‪turn_on();
1344  }
1345  else
1346  {
1347  level.flagHints["allies"] ‪turn_off();
1348  }
1349 }
1350 
1351 function ‪claim_trigger( trigger )
1352 {
1353  self endon("disconnect");
1354  self ClientClaimTrigger( trigger );
1355 
1356  self waittill("drop_object");
1357  self ClientReleaseTrigger( trigger );
1358 }
1359 
1360 function ‪createFlagSpawnInfluencer( entityTeam )
1361 {
1362  otherteam = ‪util::getOtherTeam(entityTeam);
1363  team_mask = ‪util::getTeamMask( entityTeam );
1364  other_team_mask = ‪util::getTeamMask( otherteam );
1365 
1366  self.spawn_influencer_friendly = self ‪spawning::create_influencer( "ctf_base_friendly", self.trigger.origin, team_mask );
1367  self.spawn_influencer_enemy = self ‪spawning::create_influencer( "ctf_base_friendly", self.trigger.origin, other_team_mask );
1368 }
1369 
1370 function ‪ctf_getTeamKillPenalty( eInflictor, attacker, sMeansOfDeath, weapon )
1371 {
1372  teamkill_penalty = ‪globallogic_defaults::default_getTeamKillPenalty( eInflictor, attacker, sMeansOfDeath, weapon );
1373 
1374  if ( ( isdefined( self.isFlagCarrier ) && self.isFlagCarrier ) )
1375  {
1376  teamkill_penalty = teamkill_penalty * level.teamKillPenaltyMultiplier;
1377  }
1378 
1379  return teamkill_penalty;
1380 }
1381 
1382 function ‪ctf_getTeamKillScore( eInflictor, attacker, sMeansOfDeath, weapon )
1383 {
1384  teamkill_score = ‪rank::getScoreInfoValue( "kill" );
1385 
1386  if ( ( isdefined( self.isFlagCarrier ) && self.isFlagCarrier ) )
1387  {
1388  teamkill_score = teamkill_score * level.teamKillScoreMultiplier;
1389  }
1390 
1391  return int(teamkill_score);
1392 }
‪create_use_object
‪function create_use_object(ownerTeam, trigger, visuals, offset, objectiveName, allowInitialHoldDelay=false, allowWeaponCyclingDuringHold=false)
Definition: gameobjects_shared.gsc:1491
‪processScoreEvent
‪function processScoreEvent(event, player, victim, weapon)
Definition: scoreevents_shared.gsc:19
‪ctf_getTeamKillPenalty
‪function ctf_getTeamKillPenalty(eInflictor, attacker, sMeansOfDeath, weapon)
Definition: ctf.gsc:1370
‪setObjectiveText
‪function setObjectiveText(team, text)
Definition: _util.gsc:585
‪updateGametypeDvars
‪function updateGametypeDvars()
Definition: ctf.gsc:497
‪allow_use
‪function allow_use(relativeTeam)
Definition: gameobjects_shared.gsc:3485
‪setvisiblescoreboardcolumns
‪function setvisiblescoreboardcolumns(col1, col2, col3, col4, col5)
Definition: _globallogic.gsc:545
‪killedBaseDefender
‪function killedBaseDefender(objective)
Definition: _challenges.gsc:1647
‪getTeamMask
‪function getTeamMask(team)
Definition: _util.gsc:373
‪createFlagZone
‪function createFlagZone(trigger)
Definition: ctf.gsc:573
‪turn_off
‪function turn_off()
Definition: ctf.gsc:1319
‪updateAllSpawnPoints
‪function updateAllSpawnPoints()
Definition: _spawning.gsc:551
‪registerRoundWinLimit
‪function registerRoundWinLimit(minValue, maxValue)
Definition: _util.gsc:630
‪set_use_time
‪function set_use_time(time)
Definition: gameobjects_shared.gsc:3455
‪ctf_icon_hide
‪function ctf_icon_hide()
Definition: ctf.gsc:677
‪register_allowed_gameobject
‪function register_allowed_gameobject(gameobject)
Definition: gameobjects_shared.gsc:67
‪getRoundsWon
‪function getRoundsWon(team)
Definition: util_shared.gsc:3718
‪set_visible_carrier_model
‪function set_visible_carrier_model(visibleModel)
Definition: gameobjects_shared.gsc:3862
‪onPickup
‪function onPickup(player)
Definition: ctf.gsc:797
‪onReset
‪function onReset()
Definition: ctf.gsc:1052
‪giveFlagCaptureXP
‪function giveFlagCaptureXP(player)
Definition: ctf.gsc:1046
‪minutesAndSecondsString
‪function minutesAndSecondsString(milliseconds)
Definition: ctf.gsc:333
‪OnPickupMusicState
‪function OnPickupMusicState(player)
Definition: ctf.gsc:923
‪killedBaseOffender
‪function killedBaseOffender(objective, weapon)
Definition: _challenges.gsc:1566
‪isHome
‪function isHome()
Definition: ctf.gsc:935
‪is_object_away_from_home
‪function is_object_away_from_home()
Definition: gameobjects_shared.gsc:1004
‪find_box_center
‪function find_box_center(mins, maxs)
Definition: math_shared.gsc:86
‪set_2d_icon
‪function set_2d_icon(relativeTeam, shader)
Definition: gameobjects_shared.gsc:3564
‪clearReturnFlagHudElems
‪function clearReturnFlagHudElems()
Definition: ctf.gsc:1303
‪ctf_getTeamKillScore
‪function ctf_getTeamKillScore(eInflictor, attacker, sMeansOfDeath, weapon)
Definition: ctf.gsc:1382
‪onPlayerKilled
‪function onPlayerKilled(eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration)
Definition: ctf.gsc:1085
‪resetTeamScores
‪function resetTeamScores()
Definition: _globallogic_score.gsc:808
‪set_3d_icon
‪function set_3d_icon(relativeTeam, shader)
Definition: gameobjects_shared.gsc:3570
‪VERSION_SHIP
‪#define VERSION_SHIP
Definition: version.gsh:36
‪__init__
‪function __init__()
Definition: ctf.gsc:123
‪onPrecacheGameType
‪function onPrecacheGameType()
Definition: ctf.gsc:184
‪setPoint
‪function setPoint(point, relativePoint, xOffset, yOffset, moveTime)
Definition: hud_util_shared.gsc:53
‪createFlagHint
‪function createFlagHint(team, origin)
Definition: ctf.gsc:601
‪CAPTURE_CONDITION_AT_BASE
‪#define CAPTURE_CONDITION_AT_BASE
Definition: ctf.gsc:33
‪play_on_players
‪function play_on_players(sound, team)
Definition: sound_shared.gsc:257
‪registerFriendlyFireDelay
‪function registerFriendlyFireDelay(dvarString, defaultValue, minValue, maxValue)
Definition: _globallogic.gsc:3917
‪create_influencer
‪function create_influencer(name, origin, team_mask)
Definition: _spawning.gsc:267
‪spawn
‪function spawn(v_origin=(0, 0, 0), v_angles=(0, 0, 0))
Definition: struct.csc:23
‪removeInfluencers
‪function removeInfluencers()
Definition: ctf.gsc:685
‪allow_carry
‪function allow_carry(relativeTeam)
Definition: gameobjects_shared.gsc:3480
‪capturedObjective
‪function capturedObjective(captureTime, objective)
Definition: challenges_shared.gsc:882
‪set_flags
‪function set_flags(flags)
Definition: gameobjects_shared.gsc:4234
‪registerNumLives
‪function registerNumLives(minValue, maxValue, teamLivesMinValue, teamLivesMaxValue)
Definition: _util.gsc:664
‪onStartGameType
‪function onStartGameType()
Definition: ctf.gsc:193
‪registerScoreLimit
‪function registerScoreLimit(minValue, maxValue)
Definition: _util.gsc:638
‪CLIENT_FIELD_CTF_CARRIER
‪#define CLIENT_FIELD_CTF_CARRIER
Definition: clientfields.gsh:4
‪add_spawn_points
‪function add_spawn_points(team, spawnPointName)
Definition: _spawnlogic.gsc:20
‪getScoreInfoValue
‪function getScoreInfoValue(type)
Definition: rank_shared.gsc:248
‪ctf
‪function ctf()
Definition: ctf.gsc:616
‪create_map_placed_influencers
‪function create_map_placed_influencers()
Definition: _spawning.gsc:522
‪set_key_object
‪function set_key_object(object)
Definition: gameobjects_shared.gsc:1674
‪set_team_use_time
‪function set_team_use_time(relativeTeam, time)
Definition: gameobjects_shared.gsc:3465
‪get_flag_model
‪function get_flag_model(teamRef)
Definition: _teams.gsc:357
‪getOtherTeam
‪function getOtherTeam(team)
Definition: _util.gsc:360
‪setMatchScoreHUDElemForTeam
‪function setMatchScoreHUDElemForTeam(team)
Definition: ctf.gsc:348
‪updateTeamScoreByRoundsWon
‪function updateTeamScoreByRoundsWon()
Definition: ctf.gsc:397
‪onCapture
‪function onCapture(player)
Definition: ctf.gsc:976
‪add_fallback_spawnpoints
‪function add_fallback_spawnpoints(team, point_class)
Definition: _spawning.gsc:608
‪default_getTeamKillPenalty
‪function default_getTeamKillPenalty(eInflictor, attacker, sMeansOfDeath, weapon)
Definition: _globallogic_defaults.gsc:337
‪get_owner_team
‪function get_owner_team()
Definition: gameobjects_shared.gsc:3445
‪get_flag_carry_model
‪function get_flag_carry_model(teamRef)
Definition: _teams.gsc:364
‪OBJECTIVE_FLAG_RETURN_SCORE_DIST
‪#define OBJECTIVE_FLAG_RETURN_SCORE_DIST
Definition: ctf.gsc:78
‪return_home
‪function return_home()
Definition: gameobjects_shared.gsc:971
‪getTimePassed
‪function getTimePassed()
Definition: _globallogic_utils.gsc:274
‪OBJECTIVE_FLAG_AWAY
‪#define OBJECTIVE_FLAG_AWAY
Definition: ctf.gsc:77
‪printAndSoundOnEveryone
‪function printAndSoundOnEveryone(team, enemyteam, printFriendly, printEnemy, soundFriendly, soundEnemy, printarg)
Definition: _util.gsc:252
‪set_visible_team
‪function set_visible_team(relativeTeam)
Definition: gameobjects_shared.gsc:3491
‪set_leader_gametype_dialog
‪function set_leader_gametype_dialog(startGameDialogKey, startHcGameDialogKey, offenseOrderDialogKey, defenseOrderDialogKey)
Definition: _globallogic_audio.gsc:92
‪determineTeamWinnerByTeamScore
‪function determineTeamWinnerByTeamScore()
Definition: _globallogic.gsc:624
‪place_spawn_points
‪function place_spawn_points(spawnPointName)
Definition: _spawnlogic.gsc:22
‪get_spawnpoint_array
‪function get_spawnpoint_array(classname)
Definition: _spawnlogic.gsc:27
‪determineTeamWinnerByGameStat
‪function determineTeamWinnerByGameStat(gameStat)
Definition: _globallogic.gsc:578
‪setObjectiveHintText
‪function setObjectiveHintText(team, text)
Definition: _util.gsc:595
‪onEndGame
‪function onEndGame(winningTeam)
Definition: ctf.gsc:377
‪create_entity_masked_enemy_influencer
‪function create_entity_masked_enemy_influencer(name, team_mask)
Definition: _spawning.gsc:324
‪getOtherFlag
‪function getOtherFlag(flag)
Definition: ctf.gsc:1077
‪REGISTER_SYSTEM
‪#define REGISTER_SYSTEM(__sys, __func_init_preload, __reqs)
Definition: shared.gsh:204
‪bookmark
‪function bookmark(type, time, mainClientEnt, otherClientEnt, eventPriority, inflictorEnt, overrideEntityCamera, actorEnt)
Definition: demo_shared.gsc:25
‪update_hints
‪function update_hints()
Definition: ctf.gsc:1324
‪createFlag
‪function createFlag(trigger)
Definition: ctf.gsc:520
‪registerRoundSwitch
‪function registerRoundSwitch(minValue, maxValue)
Definition: _util.gsc:615
‪create_carry_object
‪function create_carry_object(ownerTeam, trigger, visuals, offset, objectiveName, hitSound)
Definition: gameobjects_shared.gsc:266
‪registerRoundLimit
‪function registerRoundLimit(minValue, maxValue)
Definition: _util.gsc:622
‪create_entity_masked_friendly_influencer
‪function create_entity_masked_friendly_influencer(name, team_mask)
Definition: _spawning.gsc:317
‪returnFlag
‪function returnFlag()
Definition: ctf.gsc:946
‪init
‪function init()
Definition: struct.csc:1
‪getOtherTeamsMask
‪function getOtherTeamsMask(skip_team)
Definition: _util.gsc:382
‪onDrop
‪function onDrop(player)
Definition: ctf.gsc:707
‪hitRoundLimit
‪function hitRoundLimit()
Definition: util_shared.gsc:3547
‪main
‪function main()
Definition: ctf.gsc:128
‪turn_on
‪function turn_on()
Definition: ctf.gsc:1311
‪giveTeamScoreForObjective
‪function giveTeamScoreForObjective(team, score)
Definition: _globallogic_score.gsc:773
‪set
‪function set(str_field_name, n_value)
Definition: clientfield_shared.gsc:34
‪setObjectiveScoreText
‪function setObjectiveScoreText(team, text)
Definition: _util.gsc:590
‪createServerTimer
‪function createServerTimer(font, fontScale, team)
Definition: hud_util_shared.gsc:376
‪leader_dialog
‪function leader_dialog(dialogKey, team, excludeList, objectiveKey, killstreakId, dialogBufferKey)
Definition: _globallogic_audio.gsc:435
‪shouldPlayOvertimeRound
‪function shouldPlayOvertimeRound()
Definition: ctf.gsc:293
‪onSpawnPlayer
‪function onSpawnPlayer(predictedSpawn)
Definition: ctf.gsc:488
‪DisplayTeamMessageToTeam
‪function DisplayTeamMessageToTeam(message, player, team)
Definition: popups_shared.gsc:147
‪remove_influencer
‪function remove_influencer(to_be_removed)
Definition: _spawning.gsc:383
‪register
‪function register()
Definition: _ai_tank.gsc:126
‪returnFlagAfterTimeMsg
‪function returnFlagAfterTimeMsg(time)
Definition: ctf.gsc:1261
‪set_use_text
‪function set_use_text(text)
Definition: gameobjects_shared.gsc:3460
‪result
‪function result(death, attacker, mod, weapon)
Definition: _zm_aat_blast_furnace.gsc:46
‪registerTimeLimit
‪function registerTimeLimit(minValue, maxValue)
Definition: _util.gsc:655
‪get_random_intermission_point
‪function get_random_intermission_point()
Definition: _spawnlogic.gsc:54
‪updateTeamScoreByFlagsCaptured
‪function updateTeamScoreByFlagsCaptured()
Definition: ctf.gsc:408
‪create_entity_influencer
‪function create_entity_influencer(name, team_mask)
Definition: _spawning.gsc:294
‪update_fallback_spawnpoints
‪function update_fallback_spawnpoints()
Definition: _spawning.gsc:585
‪claim_trigger
‪function claim_trigger(trigger)
Definition: ctf.gsc:1351
‪onRoundSwitch
‪function onRoundSwitch()
Definition: ctf.gsc:368
‪play_2d_on_team
‪function play_2d_on_team(alias, team)
Definition: _globallogic_audio.gsc:845
‪createFlagSpawnInfluencer
‪function createFlagSpawnInfluencer(entityTeam)
Definition: ctf.gsc:1360
‪returnFlagHudElems
‪function returnFlagHudElems(time)
Definition: ctf.gsc:1280
‪createReturnMessageElems
‪function createReturnMessageElems()
Definition: ctf.gsc:1234
‪onRoundEndGame
‪function onRoundEndGame(winningTeam)
Definition: ctf.gsc:419
‪OBJECTIVE_FLAG_AT_BASE
‪#define OBJECTIVE_FLAG_AT_BASE
Definition: ctf.gsc:76