‪Black Ops 3 Source Code Explorer  0.1
‪An script explorer for Black Ops 3 by ZeRoY
_globallogic_ui.gsc
Go to the documentation of this file.
1 #using scripts\shared\array_shared;
2 #using scripts\shared\hud_util_shared;
3 #using scripts\shared\callbacks_shared;
4 #using scripts\shared\util_shared;
5 
6 #insert scripts\shared\shared.gsh;
7 
8 #using scripts\mp\gametypes\_globallogic;
9 #using scripts\mp\gametypes\_globallogic_player;
10 #using scripts\mp\gametypes\_loadout;
11 #using scripts\mp\gametypes\_spectating;
12 
13 #using scripts\mp\_util;
14 #using scripts\mp\bots\_bot;
15 #using scripts\mp\killstreaks\_killstreaks;
16 #using scripts\mp\teams\_teams;
17 
18 #precache( "string", "MP_HALFTIME" );
19 #precache( "string", "MP_OVERTIME" );
20 #precache( "string", "MP_ROUNDEND" );
21 #precache( "string", "MP_INTERMISSION" );
22 #precache( "string", "MP_SWITCHING_SIDES_CAPS" );
23 #precache( "string", "MP_FRIENDLY_FIRE_WILL_NOT" );
24 #precache( "string", "MP_RAMPAGE" );
25 #precache( "string", "MP_ENDED_GAME" );
26 #precache( "string", "MP_HOST_ENDED_GAME" );
27 
28 #precache( "eventstring", "medal_received" );
29 #precache( "eventstring", "killstreak_received" );
30 #precache( "eventstring", "player_callout" );
31 #precache( "eventstring", "score_event" );
32 #precache( "eventstring", "rank_up" );
33 #precache( "eventstring", "gun_level_complete" );
34 #precache( "eventstring", "challenge_complete" );
35 #precache( "eventstring", "clear_notification_queue" );
36 
37 #namespace globallogic_ui;
38 
39 function ‪init()
40 {
41 }
42 
44 {
45  level.autoassign =&‪menuAutoAssign;
46  level.spectator =&‪menuSpectator;
47  level.curClass =&‪menuClass;
48  level.teamMenu =&‪menuTeam;
49 }
50 
52 {
53  // free up some hud elems so we have enough for other things.
54 
55  // perk icons
56  if ( isdefined( self.perkicon ) )
57  {
58  for ( numSpecialties = 0; numSpecialties < level.maxSpecialties; numSpecialties++ )
59  {
60  if ( isdefined( self.perkicon[ numSpecialties ] ) )
61  {
62  self.perkicon[ numSpecialties ] ‪hud::destroyElem();
63  self.perkname[ numSpecialties ] ‪hud::destroyElem();
64  }
65  }
66  }
67 
68  if ( isdefined( self.perkHudelem ) )
69  {
70  self.perkHudelem ‪hud::destroyElem();
71  }
72 
73  // Killstreak icons
74  if ( isdefined( self.killstreakicon ) )
75  {
76  if ( isdefined( self.killstreakicon[0] ) )
77  {
78  self.killstreakicon[0] ‪hud::destroyElem();
79  }
80  if ( isdefined( self.killstreakicon[1] ) )
81  {
82  self.killstreakicon[1] ‪hud::destroyElem();
83  }
84  if ( isdefined( self.killstreakicon[2] ) )
85  {
86  self.killstreakicon[2] ‪hud::destroyElem();
87  }
88  if ( isdefined( self.killstreakicon[3] ) )
89  {
90  self.killstreakicon[3] ‪hud::destroyElem();
91  }
92  if ( isdefined( self.killstreakicon[4] ) )
93  {
94  self.killstreakicon[4] ‪hud::destroyElem();
95  }
96  }
97 
98  // lower message
99  if ( isdefined( self.lowerMessage ) )
100  self.lowerMessage ‪hud::destroyElem();
101  if ( isdefined( self.lowerTimer ) )
102  self.lowerTimer ‪hud::destroyElem();
103 
104  // progress bar
105  if ( isdefined( self.proxBar ) )
106  self.proxBar ‪hud::destroyElem();
107  if ( isdefined( self.proxBarText ) )
108  self.proxBarText ‪hud::destroyElem();
109 
110  // carry icon
111  if ( isdefined( self.carryIcon ) )
112  self.carryIcon ‪hud::destroyElem();
113 }
114 
115 function ‪teamPlayerCountsEqual( playerCounts )
116 {
117  count = undefined;
118 
119  foreach( team in level.teams )
120  {
121  if ( !isdefined( count ) )
122  {
123  count = playerCounts[team];
124  continue;
125  }
126  if ( count != playerCounts[team] )
127  return false;
128  }
129 
130  return true;
131 }
132 
133 function ‪teamWithLowestPlayerCount( playerCounts, ignore_team )
134 {
135  count = 9999;
136  lowest_team = undefined;
137 
138  foreach( team in level.teams )
139  {
140  if ( count > playerCounts[team] )
141  {
142  count = playerCounts[team];
143  lowest_team = team;
144  }
145  }
146 
147  return lowest_team;
148 }
149 
150 function ‪shouldBeSpectatorLateJoin( teamName, comingFromMenu )
151 {
152  if ( level.rankedMatch )
153  return false;
154 
155  if (teamName != "free")
156  return false;
157 
158  if ( comingFromMenu )
159  return false;
160 
161  if ( self IsHost() )
162  return false;
163 
164  if ( level.forceAutoAssign)
165  return false;
166 
167  if ( self ‪util::is_bot() )
168  return false;
169 
170  if ( self IsSplitscreen() )
171  return false;
172 
173  return true;
174 }
175 
176 function ‪menuAutoAssign( comingFromMenu )
177 {
178  teamKeys = GetArrayKeys( level.teams );
179  assignment = teamKeys[randomInt(teamKeys.size)];
180 
181  self ‪closeMenus();
182 
183  self LUINotifyEvent( &"clear_notification_queue" );
184 
185  if ( level.teamBased )
186  {
188  {
190  assert( isdefined( host ) );
191 
192  if ( !isdefined( host.team ) || host.team == "spectator" )
193  {
194  host.team = array::random( teamKeys );
195  }
196 
197  if ( !self ‪util::is_bot() )
198  {
199  assignment = host.team;
200  }
201  else
202  {
203  assignment = ‪util::getOtherTeam( host.team );
204  }
205  }
206  else
207  {
208  //get the team from the lobby system or party system
209  teamName = getAssignedTeamName( self );
210  if( isdefined( teamName ) && teamName != "free" && !comingFromMenu )
211  {
212  assignment = teamName;
213  }
214  // if we are in a custom game and the game has already started do not automatically put the player on a team
215  // make them choose their team
216  else if ( ‪shouldBeSpectatorLateJoin( teamName, comingFromMenu ) )
217  {
218  assignment = "spectator";
219  }
220  else
221  {
222  //lobby didn't have a proper team. Have the server decide.
223  playerCounts = self ‪teams::count_players();
224 
225  // if teams are equal return the team with the lowest score
226  if ( ‪teamPlayerCountsEqual( playerCounts ) )
227  {
228  // try to keep online splitscreen players together
229  if ( !level.splitscreen && self IsSplitScreen() )
230  {
231  assignment = self ‪get_splitscreen_team();
232 
233  if ( assignment == "" )
234  assignment = ‪pickTeamFromScores(teamKeys);
235  }
236  else
237  {
238  assignment = ‪pickTeamFromScores(teamKeys);
239  }
240  }
241  else
242  {
243  assignment = ‪teamWithLowestPlayerCount( playerCounts, "none" );
244  }
245  }
246  }
247 
248  if ( assignment == self.pers["team"] && (self.sessionstate == "playing" || self.sessionstate == "dead") )
249  {
250  self ‪beginClassChoice();
251  return;
252  }
253  }
254  else
255  {
256  // in ffa the team is assigned in code from the players client number
257  if ( !comingFromMenu )
258  {
259  assignment = self.sessionteam;
260  }
261  else
262  {
263  clientNum = self getEntityNumber();
264  count = 0;
265  foreach ( team in level.teams )
266  {
267  if ( team == "free" )
268  {
269  continue;
270  }
271 
272  count++;
273  if ( count == clientNum + 1 )
274  {
275  assignment = team;
276  break;
277  }
278  }
279  }
280 
281  // dont do anything.
282  if (self.sessionstate == "playing" || self.sessionstate == "dead")
283  {
284  return;
285  }
286  }
287 
288  if ( assignment == "spectator" && (!level.forceAutoAssign) )
289  {
290  self.pers["team"] = assignment;
291  self.team = assignment;
292  self.sessionteam = assignment;
293  self SetClientScriptMainMenu( game[ "menu_start_menu" ] );
294  return;
295  }
296 
297  if ( assignment != self.pers["team"] && (self.sessionstate == "playing" || self.sessionstate == "dead") )
298  {
299  self.switching_teams = true;
300  self.switchedTeamsResetGadgets = true;
301  self.joining_team = assignment;
302  self.leaving_team = self.pers["team"];
303  self ‪suicide();
304  }
305 
306  self.pers["team"] = assignment;
307  self.team = assignment;
308  self.pers["class"] = undefined;
309  self.curClass = undefined;
310  self.pers["weapon"] = undefined;
311  self.pers["savedmodel"] = undefined;
312 
313  self ‪updateObjectiveText();
314 
315  self.sessionteam = assignment;
316 
317  if ( !isAlive( self ) )
318  self.statusicon = "hud_status_dead";
319 
320  self notify("joined_team");
321  level notify( "joined_team" );
322  ‪callback::callback( #"on_joined_team" );
323  self notify("end_respawn");
324 
325  self ‪beginClassChoice();
326  self SetClientScriptMainMenu( game[ "menu_start_menu" ] );
327 
328 }
329 
331 {
332  score = undefined;
333 
334  foreach( team in level.teams )
335  {
336  if ( !isdefined( score ) )
337  {
338  score = getTeamScore(team);
339  continue;
340  }
341  if ( score != getTeamScore(team) )
342  return false;
343  }
344 
345  return true;
346 }
347 
349 {
350  score = 99999999;
351  lowest_team = undefined;
352 
353  foreach( team in level.teams )
354  {
355  if ( score > getTeamScore(team ) )
356  lowest_team = team;
357  }
358 
359  return lowest_team;
360 }
361 
362 function ‪pickTeamFromScores(teams)
363 {
364  assignment = "allies";
365 
366  if ( ‪teamScoresEqual() )
367  assignment = teams[randomInt(teams.size)];
368  else
369  assignment = ‪teamWithLowestScore();
370 
371  return assignment;
372 }
373 
375 {
376  for ( index = 0; index < level.players.size; index++ )
377  {
378  if ( !isdefined(level.players[index]) )
379  continue;
380 
381  if ( level.players[index] == self )
382  continue;
383 
384  if ( !(self IsPlayerOnSameMachine( level.players[index] )) )
385  continue;
386 
387  team = level.players[index].sessionteam;
388 
389  // going to assume first non-spectator
390  if ( team != "spectator" )
391  return team;
392  }
393 
394  return "";
395 }
396 
398 {
399  if ( (self.pers["team"] == "spectator") )
400  {
401  self SetClientCGObjectiveText( "" );
402  return;
403  }
404 
405  if( level.scorelimit > 0 || level.roundScoreLimit > 0 )
406  {
407  self SetClientCGObjectiveText( ‪util::getObjectiveScoreText( self.pers["team"] ) );
408  }
409  else
410  {
411  self SetClientCGObjectiveText( ‪util::getObjectiveText( self.pers["team"] ) );
412  }
413 }
414 
415 
416 function ‪closeMenus()
417 {
418  self closeInGameMenu();
419 }
420 
422 {
423  assert( isdefined( level.teams[self.pers["team"]] ) );
424 
425  team = self.pers["team"];
426 
427  if ( level.disableClassSelection == 1 || GetDvarint( "migration_soak" ) == 1 )
428  {
429  // skip class choice and just spawn.
430 
431  started_waiting = GetTime();
432 
433  // try to let them finish loading the level
434  while ( (!self isStreamerReady( -1, true )) && started_waiting + 90000 > GetTime() )
435  {
437  }
438 
439  self.pers["class"] = level.defaultClass;
440  self.curClass = level.defaultClass;
441 
442  if ( self.sessionstate != "playing" && game["state"] == "playing" )
443  self thread [[level.spawnClient]]();
444 
445  level thread ‪globallogic::updateTeamStatus();
447 
448  return;
449  }
450 
451  // menu_changeclass_team is the one where you choose one of the n classes to play as.
452  // menu_class_team is where you can choose to change your team, class, controls, or leave game.
453 
454  // need to wait a network frame before opening the choose-class menu, as CG_ExecuteNewServerCommands is called
455  // before the team is updated in CG_SetNextSnap_Clients.
457 
458  self openMenu( game[ "menu_changeclass_" + team ] );
459 }
460 
462 {
463  assert( isdefined( level.teams[self.pers["team"]] ) );
464 
465  team = self.pers["team"];
466 
467  // menu_changeclass_team is the one where you choose one of the n classes to play as.
468  // menu_class_team is where you can choose to change your team, class, controls, or leave game.
469 
470  self openMenu( game[ "menu_changeclass_" + team ] );
471 }
472 
473 function ‪menuTeam( team )
474 {
475  self ‪closeMenus();
476 
477  if ( !level.console && level.allow_teamchange == "0" && (isdefined(self.hasDoneCombat) && self.hasDoneCombat) )
478  {
479  return;
480  }
481 
482  if(self.pers["team"] != team)
483  {
484  // allow respawn when switching teams during grace period.
485  if ( level.inGracePeriod && (!isdefined(self.hasDoneCombat) || !self.hasDoneCombat) )
486  self.hasSpawned = false;
487 
488  if(self.sessionstate == "playing")
489  {
490  self.switching_teams = true;
491  self.switchedTeamsResetGadgets = true;
492  self.joining_team = team;
493  self.leaving_team = self.pers["team"];
494  self ‪suicide();
495  }
496 
497  self LUINotifyEvent( &"clear_notification_queue" );
498 
499  self.pers["team"] = team;
500  self.team = team;
501  self.pers["class"] = undefined;
502  self.curClass = undefined;
503  self.pers["weapon"] = undefined;
504  self.pers["savedmodel"] = undefined;
505 
506  self ‪updateObjectiveText();
507 
508  if ( !level.rankedMatch && !level.leagueMatch )
509  {
510  self.sessionstate = "spectator";
511  }
512 
513  self.sessionteam = team;
514 
515  self SetClientScriptMainMenu( game[ "menu_start_menu" ] );
516 
517  self notify("joined_team");
518  level notify( "joined_team" );
519  ‪callback::callback( #"on_joined_team" );
520  self notify("end_respawn");
521  }
522 
523  self ‪beginClassChoice();
524 }
525 
527 {
528  self ‪closeMenus();
529 
530  if(self.pers["team"] != "spectator")
531  {
532  if(isAlive(self))
533  {
534  self.switching_teams = true;
535  self.switchedTeamsResetGadgets = true;
536  self.joining_team = "spectator";
537  self.leaving_team = self.pers["team"];
538  self ‪suicide();
539  }
540 
541  self.pers["team"] = "spectator";
542  self.team = "spectator";
543  self.pers["class"] = undefined;
544  self.curClass = undefined;
545  self.pers["weapon"] = undefined;
546  self.pers["savedmodel"] = undefined;
547 
548  self ‪updateObjectiveText();
549 
550  self.sessionteam = "spectator";
551 
552  [[level.spawnSpectator]]();
553 
555 
556  self SetClientScriptMainMenu( game[ "menu_start_menu" ] );
557 
558  self notify("joined_spectators");
559  ‪callback::callback( #"on_joined_spectate" );
560  }
561 }
562 
563 function ‪menuClass( response, forcedClass )
564 {
565  self ‪closeMenus();
566 
567  // this should probably be an assert
568  if(!isdefined(self.pers["team"]) || !(isdefined( level.teams[self.pers["team"]] ) ) )
569  return;
570 
571  if ( !isdefined( forcedClass ) )
572  playerclass = self ‪loadout::getClassChoice( response );
573  else
574  playerClass = forcedClass;
575 
576  if( (isdefined( self.pers["class"] ) && self.pers["class"] == playerclass) )
577  return;
578 
579  self.pers["changed_class"] = true;
580  self notify ( "changed_class" );
581 
582  //The player selected the class they are currently using
583  if( isdefined(self.curClass) && self.curClass == playerclass )
584  {
585  self.pers["changed_class"] = false;
586  }
587 
588  self.pers["class"] = playerClass;
589  self.curClass = playerclass;
590 
591  self.pers["weapon"] = undefined;
592 
593  if ( game["state"] == "postgame" )
594  return;
595 
596  if ( self.sessionstate == "playing" )
597  {
598  supplyStationClassChange = isdefined( self.usingSupplyStation ) && self.usingSupplyStation;
599  self.usingSupplyStation = false;
600 
601  if ( ( level.inGracePeriod && !self.hasDoneCombat ) || supplyStationClassChange ) // used weapons check?
602  {
603  self ‪loadout::setClass( self.pers["class"] );
604  self.tag_stowed_back = undefined;
605  self.tag_stowed_hip = undefined;
606  self ‪loadout::giveLoadout( self.pers["team"], self.pers["class"] );
608  }
609  else if ( !( self IsSplitScreen() ) )
610  {
611  self IPrintLnBold( game["strings"]["change_class"] );
612  }
613  }
614  else
615  {
616  if ( self.sessionstate != "spectator" )
617  {
618  if ( self IsInVehicle() )
619  return;
620 
621  if ( self IsRemoteControlling() )
622  return;
623 
624  if ( self IsWeaponViewOnlyLinked() )
625  return false;
626  }
627 
628  if ( game["state"] == "playing" )
629  {
630  timePassed = undefined;
631 
632  if ( isdefined( self.respawnTimerStartTime ) )
633  {
634  timePassed = (gettime() - self.respawnTimerStartTime) / 1000;
635  }
636 
637  self thread [[level.spawnClient]](timePassed);
638 
639  self.respawnTimerStartTime = undefined;
640 
641  }
642  }
643 
644  level thread ‪globallogic::updateTeamStatus();
645 
647 }
648 
650 {
651  self endon("disconnect");
652 
653  waittillframeend; // so we don't endon the end_respawn from spawning as a spectator
654 
655  self endon("end_respawn");
656 
657  wait ‪delay;
658 
659  self ‪util::clearLowerMessage( 2.0 );
660 }
661 
‪callback
‪function callback(event, localclientnum, params)
Definition: callbacks_shared.csc:13
‪spectate_player_watcher
‪function spectate_player_watcher()
Definition: _globallogic_player.gsc:1271
‪give_owned
‪function give_owned()
Definition: _killstreaks.gsc:999
‪is_bot
‪function is_bot()
Definition: util_shared.gsc:2488
‪menuSpectator
‪function menuSpectator()
Definition: _globallogic_ui.gsc:526
‪giveLoadout
‪function giveLoadout(team, weaponclass)
Definition: _loadout.gsc:1088
‪closeMenus
‪function closeMenus()
Definition: _globallogic_ui.gsc:416
‪set_permissions_for_machine
‪function set_permissions_for_machine()
Definition: _spectating.gsc:184
‪destroyElem
‪function destroyElem()
Definition: hud_util_shared.gsc:755
‪getObjectiveScoreText
‪function getObjectiveScoreText(team)
Definition: _util.gsc:605
‪delay
‪function delay(time_or_notify, str_endon, func, arg1, arg2, arg3, arg4, arg5, arg6)
Definition: util_shared.csc:784
‪shouldBeSpectatorLateJoin
‪function shouldBeSpectatorLateJoin(teamName, comingFromMenu)
Definition: _globallogic_ui.gsc:150
‪getOtherTeam
‪function getOtherTeam(team)
Definition: _util.gsc:360
‪suicide
‪function suicide()
Definition: _vehicle.gsc:1309
‪removeSpawnMessageShortly
‪function removeSpawnMessageShortly(delay)
Definition: _globallogic_ui.gsc:649
‪updateTeamStatus
‪function updateTeamStatus()
Definition: _globallogic.gsc:2920
‪wait_network_frame
‪function wait_network_frame(n_count=1)
Definition: util_shared.gsc:64
‪menuAutoAssign
‪function menuAutoAssign(comingFromMenu)
Definition: _globallogic_ui.gsc:176
‪setClass
‪function setClass(newClass)
Definition: _loadout.gsc:1214
‪is_bot_comp_stomp
‪function is_bot_comp_stomp()
Definition: _bot.gsc:121
‪showMainMenuForTeam
‪function showMainMenuForTeam()
Definition: _globallogic_ui.gsc:461
‪SetupCallbacks
‪function SetupCallbacks()
Definition: _globallogic_ui.gsc:43
‪teamScoresEqual
‪function teamScoresEqual()
Definition: _globallogic_ui.gsc:330
‪get_splitscreen_team
‪function get_splitscreen_team()
Definition: _globallogic_ui.gsc:374
‪count_players
‪function count_players()
Definition: _teams.gsc:291
‪getClassChoice
‪function getClassChoice(response)
Definition: _loadout.gsc:466
‪menuClass
‪function menuClass(response, forcedClass)
Definition: _globallogic_ui.gsc:563
‪menuTeam
‪function menuTeam(team)
Definition: _globallogic_ui.gsc:473
‪freeGameplayHudElems
‪function freeGameplayHudElems()
Definition: _globallogic_ui.gsc:51
‪getHostPlayerForBots
‪function getHostPlayerForBots()
Definition: util_shared.gsc:2916
‪beginClassChoice
‪function beginClassChoice()
Definition: _globallogic_ui.gsc:421
‪teamWithLowestScore
‪function teamWithLowestScore()
Definition: _globallogic_ui.gsc:348
‪updateObjectiveText
‪function updateObjectiveText()
Definition: _globallogic_ui.gsc:397
‪teamWithLowestPlayerCount
‪function teamWithLowestPlayerCount(playerCounts, ignore_team)
Definition: _globallogic_ui.gsc:133
‪pickTeamFromScores
‪function pickTeamFromScores(teams)
Definition: _globallogic_ui.gsc:362
‪getObjectiveText
‪function getObjectiveText(team)
Definition: _util.gsc:600
‪teamPlayerCountsEqual
‪function teamPlayerCountsEqual(playerCounts)
Definition: _globallogic_ui.gsc:115
‪init
‪function init()
Definition: _globallogic_ui.gsc:39
‪WAIT_SERVER_FRAME
‪#define WAIT_SERVER_FRAME
Definition: shared.gsh:265
‪clearLowerMessage
‪function clearLowerMessage(fadetime)
Definition: _util.gsc:166