├── Apex Modding Auto Injector.zip ├── README.md ├── lobby_panel_play.nut └── sh_character_select_new.gnut /Apex Modding Auto Injector.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/outl4wz/apex-squirrelscripts-linux/ad16ad8bc3aa885a876dd7597577d176defdb45e/Apex Modding Auto Injector.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # apex-squirrelscripts-linux 2 | Updated Squirrel scripts for linux only! 3 | 4 | (Base -> https://www.unknowncheats.me/forum/apex-legends/569820-modify-squirrel-script-linux.html) 5 | 6 | 7 | [Features] 8 | 9 | (original -> https://www.unknowncheats.me/forum/apex-legends/505139-apex-squirrel-scripts.html) 10 | fullmap radar 11 | minimap radar 12 | TriggerBot (Usage: On/Off = F4, Activation = Mouse 4) 13 | item icon ESP (Usage: Press F3 For On/Off) 14 | seer health ESP 15 | autoloot (Usage: Press F2 For On/Off) 16 | 17 | tutorial and orientation matches bypass (works by default) 18 | 19 | basic glow with outline 20 | 21 | 22 | [Usage] 23 | Download "Titanfall_VPKTool3.4_Portable.zip" from https://noskill.gitbook.io/titanfall2/intro/duction/tools 24 | 25 | Open "englishclient_frontend.bsp.pak000_dir.vpk" in "...../Steam/steamapps/common/Apex Legends/vpk/" with the downloaded "Titalfall VPK Tool", extract all (delete the log file) 26 | 27 | Replace "sh_character_select_new.gnut" using the file in this repository 28 | 29 | Repack with Tools -> Repack 30 | 31 | Rename the generated vpk file to "client_frontend.bsp.pak000_000.vpk" and the _dir.vpk file to "englishclient_frontend.bsp.pak000_dir.vpk" 32 | 33 | Move the two generated files back to "...../Steam/steamapps/common/Apex Legends/vpk/" 34 | 35 | 36 | [Video] 37 | https://vimeo.com/795981518 38 | (From https://www.unknowncheats.me/forum/apex-legends/569820-modify-squirrel-script-linux.html) 39 | -------------------------------------------------------------------------------- /lobby_panel_play.nut: -------------------------------------------------------------------------------- 1 | global function InitPlayPanel 2 | global function PlayPanel_LevelInit 3 | global function PlayPanel_LevelShutdown 4 | 5 | global function IsPlayPanelCurrentlyTopLevel 6 | global function PlayPanelUpdate 7 | global function ClientToUI_PartyMemberJoinedOrLeft 8 | global function GetModeSelectButton 9 | global function GetLobbyChatBox 10 | 11 | global function Lobby_GetPlaylists 12 | global function Lobby_GetPlaylistMods 13 | global function Lobby_GetSelectedPlaylist 14 | global function Lobby_GetLastSelectedPlaylist 15 | global function Lobby_IsPlaylistAvailable 16 | global function Lobby_SetSelectedPlaylist 17 | global function Lobby_ClearSelectedPlaylist 18 | global function Lobby_SetSelectedPlaylistMods 19 | global function Lobby_GetSelectedPlaylistExpectedSquadSize 20 | global function Lobby_OnGamemodeSelectClose 21 | global function Lobby_UpdateLoadscreenFromPlaylist 22 | global function Lobby_ShowDialoguePopupFromData 23 | 24 | global function Lobby_GetPlaylistState 25 | global function Lobby_GetPlaylistStateString 26 | global function Lobby_ResetAreLobbyButtonsUpdating 27 | 28 | global function Lobby_UpdatePlayPanelPlaylists 29 | 30 | global function CanInvite 31 | 32 | global function UpdateMiniPromoPinning 33 | global function UpdateLootBoxButton 34 | 35 | global function ShouldShowMatchmakingDelayDialog 36 | global function ShowMatchmakingDelayDialog 37 | global function ShouldShowLastGameRankedAbandonForgivenessDialog 38 | global function ShowLastGameRankedAbandonForgivenessDialog 39 | global function PulseModeButton 40 | 41 | global function ReadyShortcut_OnActivate 42 | 43 | global function HasLocalPlayerCompletedTraining 44 | global function IsLocalPlayerExemptFromTraining 45 | 46 | global function HasLocalPlayerCompletedNewPlayerOrientation 47 | global function IsLocalPlayerExemptFromNewPlayerOrientation 48 | global function DoNonlocalPlayerPartyMembersNeedToCompleteNewPlayerOrientation 49 | 50 | 51 | global function DialogFlow_DidCausePotentiallyInterruptingPopup 52 | 53 | global function Lobby_ShowCallToActionPopup 54 | 55 | global function OpenGameModeSelectDialog 56 | 57 | global function JoinMatchAsPartySpectatorFailedAddedToWaitlistDialog 58 | 59 | global function JoinMatchAsWaitlistedPartySpectatorDialog 60 | 61 | #if DEV 62 | global function DEV_PrintPartyInfo 63 | global function DEV_PrintUserInfo 64 | global function Lobby_MovePopupMessage 65 | global function Lobby_ShowBattlePassPopup 66 | global function Lobby_ShowHeirloomShopPopup 67 | global function Lobby_ShowLegendsTokenPopup 68 | global function Lobby_ShowQuestPopup 69 | global function Lobby_ShowStoryEventChallengesPopup 70 | global function Lobby_ShowStoryEventAutoplayDialoguePopup 71 | #endif 72 | 73 | global function DoesPlaylistRequireTraining 74 | 75 | global function DoesPlaylistRequireNewPlayerOrientation 76 | 77 | 78 | 79 | global function Lobby_OpenBattlePassMilestoneDialog 80 | 81 | 82 | const string SOUND_BP_POPUP = "UI_Menu_BattlePass_PopUp" 83 | 84 | const string SOUND_START_MATCHMAKING_1P = "UI_Menu_ReadyUp_1P" 85 | const string SOUND_STOP_MATCHMAKING_1P = "UI_Menu_ReadyUp_Cancel_1P" 86 | const string SOUND_START_MATCHMAKING_3P = "UI_Menu_ReadyUp_3P" 87 | const string SOUND_STOP_MATCHMAKING_3P = "UI_Menu_ReadyUp_Cancel_3P" 88 | 89 | const float INVITE_LAST_TIMEOUT = 15.0 90 | const float INVITE_LAST_PANEL_EXPIRATION = 1 * MINUTES_PER_HOUR * SECONDS_PER_MINUTE 91 | global enum ePlaylistState 92 | { 93 | AVAILABLE, 94 | NO_PLAYLIST, 95 | TRAINING_REQUIRED, 96 | COMPLETED_TRAINING_REQUIRED, 97 | 98 | COMPLETED_ORIENTATION_REQUIRED, 99 | 100 | PARTY_SIZE_OVER, 101 | LOCKED, 102 | RANKED_LEVEL_REQUIRED, 103 | RANKED_LARGE_RANK_DIFFERENCE, 104 | RANKED_NOT_INITIALIZED, 105 | RANKED_MATCH_ABANDON_DELAY, 106 | ACCOUNT_LEVEL_REQUIRED, 107 | ROTATION_GROUP_MISMATCH, 108 | DEV_PLAYTEST, 109 | _COUNT 110 | } 111 | 112 | 113 | const table< int, string > playlistStateMap = { 114 | [ ePlaylistState.NO_PLAYLIST ] = "#PLAYLIST_STATE_NO_PLAYLIST", 115 | [ ePlaylistState.TRAINING_REQUIRED ] = "#PLAYLIST_STATE_TRAINING_REQUIRED", 116 | [ ePlaylistState.COMPLETED_TRAINING_REQUIRED ] = "#PLAYLIST_STATE_COMLETED_TRAINING_REQUIRED", 117 | 118 | [ ePlaylistState.COMPLETED_ORIENTATION_REQUIRED ] = "#PLAYLIST_STATE_COMPLETED_ORIENTATION_REQUIRED", 119 | 120 | [ ePlaylistState.AVAILABLE ] = "#PLAYLIST_STATE_AVAILABLE", 121 | [ ePlaylistState.PARTY_SIZE_OVER ] = "#PLAYLIST_STATE_PARTY_SIZE_OVER", 122 | [ ePlaylistState.LOCKED ] = "#PLAYLIST_STATE_LOCKED", 123 | [ ePlaylistState.RANKED_LEVEL_REQUIRED ] = "#PLAYLIST_STATE_RANKED_LEVEL_REQUIRED", 124 | [ ePlaylistState.RANKED_LARGE_RANK_DIFFERENCE ] = "#PLAYLIST_STATE_RANKED_LARGE_RANK_DIFFERENCE", 125 | [ ePlaylistState.RANKED_NOT_INITIALIZED ] = "#PLAYLIST_STATE_RANKED_NOT_INITIALIZED", 126 | [ ePlaylistState.RANKED_MATCH_ABANDON_DELAY ] = "#RANKED_ABANDON_PENALTY_PLAYLIST_STATE", 127 | [ ePlaylistState.ROTATION_GROUP_MISMATCH ] = "#PLAYLIST_UNAVAILABLE", 128 | [ ePlaylistState.ACCOUNT_LEVEL_REQUIRED ] = "#PLAYLIST_STATE_RANKED_LEVEL_REQUIRED", 129 | [ ePlaylistState.DEV_PLAYTEST ] = "#PLAYLIST_STATE_PLAYTEST", 130 | } 131 | 132 | struct BattlePassInfo 133 | { 134 | ItemFlavor ornull battlePassOrNull 135 | int bpExpirationTimestamp 136 | } 137 | 138 | const int TRAINING_REQUIRED_BELOW_LEVEL_0_BASE = 14 139 | enum eTrainingExemptionState 140 | { 141 | UNINITIALIZED, 142 | FALSE, 143 | TRUE, 144 | } 145 | 146 | struct 147 | { 148 | var panel 149 | var chatBox 150 | var chatroomMenu 151 | var chatroomMenu_chatroomWidget 152 | 153 | var fillButton 154 | var modeButton 155 | var gamemodeSelectButton 156 | var readyButton 157 | var trainingButton 158 | var inviteFriendsButton0 159 | var inviteFriendsButton1 160 | var inviteLastPlayedHeader 161 | var inviteLastPlayedUnitFrame0 162 | var inviteLastPlayedUnitFrame1 163 | var friendButton0 164 | var friendButton1 165 | var selfButton 166 | var allChallengesButton 167 | var eventPrizeTrackButton 168 | var storyPrizeTrackButton 169 | var miniPromoButton 170 | 171 | bool newModesAcknowledged = false 172 | 173 | var hdTextureProgress 174 | 175 | int lastExpireTime 176 | 177 | string lastVisiblePlaylistValue 178 | int lastPartySize = 0 179 | bool lastCuiIsValid = false 180 | 181 | array playlists 182 | array playlistMods 183 | string selectedPlaylist 184 | string selectedPlaylistMods 185 | 186 | bool personInLeftSpot = false 187 | bool personInRightSlot = false 188 | 189 | Friend& friendInLeftSpot 190 | Friend& friendInRightSpot 191 | 192 | string unspoofedHardwareForLeftSlot 193 | string unspoofedHardwareForRightSlot 194 | 195 | string lastPlayedPlayerPlatformUid0 = "" 196 | string lastPlayedPlayerNucleusID0 = "" 197 | int lastPlayedPlayerHardwareID0 = -1 198 | string lastPlayedPlayerPlatformUid1 = "" 199 | string lastPlayedPlayerNucleusID1 = "" 200 | int lastPlayedPlayerHardwareID1 = -1 201 | int lastPlayedPlayerPersistenceIndex0 = -1 202 | int lastPlayedPlayerPersistenceIndex1 = -1 203 | float lastPlayedPlayerInviteSentTimestamp0 = -1 204 | float lastPlayedPlayerInviteSentTimestamp1 = -1 205 | 206 | 207 | bool leftWasReady = false 208 | bool rightWasReady = false 209 | 210 | bool fullInstallNotification = false 211 | bool skipDialogCheckForActivateReadyButton = false 212 | 213 | bool wasReady = false 214 | 215 | bool haveShownSelfMatchmakingDelay = false 216 | bool haveShownPartyMemberMatchmakingDelay = false 217 | bool haveShownLastGameRankedAbandonForgivenessDialog = false 218 | int lobbyRankTier = -1 219 | bool rankedInitialized = false 220 | float currentMaxMatchmakingDelayEndTime = -1 221 | var rankedRUIToUpdate = null 222 | 223 | 224 | 225 | 226 | void functionref() onCallToActionFunc 227 | 228 | string lastPlaylistDisplayed 229 | 230 | 231 | 232 | 233 | 234 | 235 | table s_cachedAccountXPFrac 236 | 237 | bool dialogFlowDidCausePotentiallyInterruptingPopup = false 238 | 239 | var challengeCategorySelection 240 | bool challengeInputCallbacksRegistered = false 241 | int challengeLastStickState = eStickState.NEUTRAL 242 | 243 | float nextAllowFriendsUpdateTime 244 | 245 | 246 | bool fillButtonWasFullSquad = false 247 | bool fillButtonWasHidden = false 248 | bool fillButtonState = true 249 | 250 | bool isShowing = false 251 | 252 | BattlePassInfo currentBPInfo 253 | 254 | bool areLobbyButtonsUpdating 255 | int isLocalPlayerExemptFromTraining = eTrainingExemptionState.UNINITIALIZED 256 | 257 | 258 | var partyMemberNotice 259 | 260 | } file 261 | 262 | void function InitPlayPanel( var panel ) 263 | { 264 | file.panel = panel 265 | SetPanelTabTitle( panel, "#PLAY" ) 266 | AddPanelEventHandler( panel, eUIEvent.PANEL_SHOW, PlayPanel_OnShow ) 267 | AddPanelEventHandler( panel, eUIEvent.PANEL_HIDE, PlayPanel_OnHide ) 268 | AddPanelEventHandler( panel, eUIEvent.PANEL_NAVBACK, PlayPanel_OnNavBack ) 269 | 270 | SetPanelInputHandler( panel, BUTTON_Y, ReadyShortcut_OnActivate ) 271 | 272 | file.fillButton = Hud_GetChild( panel, "FillButton" ) 273 | Hud_AddEventHandler( file.fillButton, UIE_CLICK, FillButton_OnActivate ) 274 | 275 | file.modeButton = Hud_GetChild( panel, "ModeButton" ) 276 | Hud_AddEventHandler( file.modeButton, UIE_CLICK, ModeButton_OnActivate ) 277 | 278 | file.gamemodeSelectButton = Hud_GetChild( panel, "gamemodeSelectButton" ) 279 | Hud_AddEventHandler( file.gamemodeSelectButton, UIE_CLICK, GamemodeSelectButton_OnActivate ) 280 | Hud_AddEventHandler( file.gamemodeSelectButton, UIE_GET_FOCUS, GamemodeSelectButton_OnGetFocus ) 281 | Hud_AddEventHandler( file.gamemodeSelectButton, UIE_LOSE_FOCUS, GamemodeSelectButton_OnLoseFocus ) 282 | Hud_SetVisible( file.gamemodeSelectButton, false ) 283 | 284 | file.readyButton = Hud_GetChild( panel, "ReadyButton" ) 285 | Hud_AddEventHandler( file.readyButton, UIE_CLICK, ReadyButton_OnActivate ) 286 | 287 | file.inviteFriendsButton0 = Hud_GetChild( panel, "InviteFriendsButton0" ) 288 | Hud_AddEventHandler( file.inviteFriendsButton0, UIE_CLICK, InviteFriendsButton_OnActivate ) 289 | 290 | file.inviteFriendsButton1 = Hud_GetChild( panel, "InviteFriendsButton1" ) 291 | Hud_AddEventHandler( file.inviteFriendsButton1, UIE_CLICK, InviteFriendsButton_OnActivate ) 292 | 293 | file.inviteLastPlayedHeader = Hud_GetChild( panel, "InviteLastSquadHeader" ) 294 | Hud_Hide( file.inviteLastPlayedHeader ) 295 | 296 | file.inviteLastPlayedUnitFrame0 = Hud_GetChild( panel, "InviteLastPlayedUnitframe0" ) 297 | Hud_AddEventHandler( file.inviteLastPlayedUnitFrame0, UIE_CLICK, InviteLastPlayedButton_OnActivate ) 298 | 299 | Hud_AddKeyPressHandler( file.inviteLastPlayedUnitFrame0, InviteLastPlayedButton_OnKeyPress ) 300 | Hud_AddEventHandler( file.inviteLastPlayedUnitFrame0, UIE_CLICKRIGHT, InviteLastPlayedButton_OnRightClick ) 301 | Hud_Hide( file.inviteLastPlayedUnitFrame0 ) 302 | 303 | file.inviteLastPlayedUnitFrame1 = Hud_GetChild( panel, "InviteLastPlayedUnitframe1" ) 304 | Hud_AddEventHandler( file.inviteLastPlayedUnitFrame1, UIE_CLICK, InviteLastPlayedButton_OnActivate ) 305 | 306 | Hud_AddKeyPressHandler( file.inviteLastPlayedUnitFrame1, InviteLastPlayedButton_OnKeyPress ) 307 | Hud_AddEventHandler( file.inviteLastPlayedUnitFrame1, UIE_CLICKRIGHT, InviteLastPlayedButton_OnRightClick ) 308 | Hud_Hide( file.inviteLastPlayedUnitFrame1 ) 309 | 310 | file.selfButton = Hud_GetChild( panel, "SelfButton" ) 311 | Hud_AddEventHandler( file.selfButton, UIE_CLICK, FriendButton_OnActivate ) 312 | 313 | #if NX_PROG || PC_PROG_NX_UI 314 | RuiSetFloat( Hud_GetRui( file.selfButton ), "lobbyNXOffset", 1.0 ) 315 | #endif 316 | 317 | file.friendButton0 = Hud_GetChild( panel, "FriendButton0" ) 318 | Hud_AddKeyPressHandler(file.friendButton0, FriendButton_OnKeyPress) 319 | 320 | file.friendButton1 = Hud_GetChild( panel, "FriendButton1" ) 321 | Hud_AddKeyPressHandler(file.friendButton1, FriendButton_OnKeyPress) 322 | 323 | file.allChallengesButton = Hud_GetChild( panel, "AllChallengesButton" ) 324 | Hud_SetVisible( file.allChallengesButton, true ) 325 | Hud_SetEnabled( file.allChallengesButton, true ) 326 | 327 | var nextBPRewardButton = Hud_GetChild( panel, "ChallengesNextBPReward" ) 328 | Hud_AddEventHandler( nextBPRewardButton, UIE_CLICK, ChallengeInspectNextReward ) 329 | 330 | HudElem_SetRuiArg( file.allChallengesButton, "buttonText", Localize( "#CHALLENGES_LOBBY_BUTTON_SHORT" ) ) 331 | Hud_AddEventHandler( file.allChallengesButton, UIE_CLICK, AllChallengesButton_OnActivate ) 332 | 333 | file.eventPrizeTrackButton = Hud_GetChild( panel, "EventPrizeTrackButton" ) 334 | Hud_SetVisible( file.eventPrizeTrackButton, true ) 335 | Hud_SetEnabled( file.eventPrizeTrackButton, true ) 336 | 337 | file.storyPrizeTrackButton = Hud_GetChild( panel, "StoryPrizeTrackButton" ) 338 | Hud_SetVisible( file.storyPrizeTrackButton, true ) 339 | Hud_SetEnabled( file.storyPrizeTrackButton, true ) 340 | 341 | Hud_AddEventHandler( Hud_GetChild( file.panel, "PopupMessage" ), UIE_CLICK, OnClickCallToActionPopup ) 342 | 343 | file.challengeCategorySelection = Hud_GetChild( file.panel, "ChallengeCatergorySelection" ) 344 | Hud_AddEventHandler( Hud_GetChild( file.panel, "ChallengeCatergoryLeftButton" ), UIE_CLICK, IsRTL() ? ChallengeSwitchRight_OnClick : ChallengeSwitchLeft_OnClick ) 345 | Hud_AddEventHandler( Hud_GetChild( file.panel, "ChallengeCatergoryRightButton" ), UIE_CLICK, IsRTL() ? ChallengeSwitchLeft_OnClick : ChallengeSwitchRight_OnClick ) 346 | 347 | AddMenuVarChangeHandler( "isMatchmaking", UpdateLobbyButtons ) 348 | 349 | file.chatBox = Hud_GetChild( panel, "ChatRoomTextChat" ) 350 | file.hdTextureProgress = Hud_GetChild( panel, "HDTextureProgress" ) 351 | 352 | file.partyMemberNotice = Hud_GetChild( panel, "PartyMemberNotice" ) 353 | 354 | 355 | 356 | 357 | var chatTextEntry = Hud_GetChild( Hud_GetChild( file.chatBox, "ChatInputLine" ), "ChatInputTextEntry" ) 358 | Hud_SetNavUp( chatTextEntry, chatTextEntry ) 359 | 360 | file.miniPromoButton = ( Hud_GetChild( panel, "MiniPromo" ) ) 361 | InitMiniPromo( file.miniPromoButton ) 362 | 363 | RegisterSignal( "UpdateFriendButtons" ) 364 | RegisterSignal( "CallToActionPopupThink" ) 365 | RegisterSignal( "Lobby_ShowCallToActionPopup" ) 366 | 367 | RegisterSignal( "CallToActionPopupAudioThink" ) 368 | RegisterSignal( "CallToActionPopupAudioCancel" ) 369 | 370 | var aboutButton = Hud_GetChild( file.panel, "AboutButton" ) 371 | Hud_AddEventHandler( aboutButton, UIE_CLICK, Lobby_OnClickPlaylistAboutButton ) 372 | 373 | var rankedBadge = Hud_GetChild( file.panel, "RankedBadge" ) 374 | Hud_AddEventHandler( rankedBadge, UIE_CLICK, OpenRankedInfoPage ) 375 | 376 | 377 | 378 | 379 | 380 | 381 | AddUICallback_OnLevelInit( SharedRanked_OnLevelInit ) 382 | AddCallback_OnPartyMemberAdded( TryShowMatchmakingDelayDialog ) 383 | AddCallback_OnPartyMemberRemoved( UpdateCurrentMaxMatchmakingDelayEndTime ) 384 | AddCallback_PartySpectateSlotUnavailableWaitlisted( OnPartySpectateSlotUnavailableWaitlisted ) 385 | AddCallback_PartySpectateSlotAvailable( OnPartySpectateSlotAvailable ) 386 | 387 | #if DEV 388 | AddMenuThinkFunc( Hud_GetParent( file.panel ), LobbyAutomationThink ) 389 | #endif 390 | } 391 | 392 | void function Lobby_OnClickPlaylistAboutButton( var button ) 393 | { 394 | string modeRules = GetPlaylist_UIRules() 395 | if( FeatureHasTutorialTabs( modeRules ) ) 396 | OpenFeatureTutorialDialog( button, modeRules ) 397 | else 398 | OpenAboutGameModePage( button ) 399 | } 400 | 401 | void function PlayPanel_LevelInit() 402 | { 403 | if ( IsLobby() == false ) 404 | return 405 | 406 | file.currentBPInfo.battlePassOrNull = GetActiveBattlePass() 407 | if ( file.currentBPInfo.battlePassOrNull != null ) 408 | file.currentBPInfo.bpExpirationTimestamp = CalEvent_GetFinishUnixTime( expect ItemFlavor( GetActiveSeason( GetUnixTimestamp() ) ) ) 409 | 410 | ResetFillButton() 411 | } 412 | 413 | void function PlayPanel_LevelShutdown() 414 | { 415 | if ( file.isShowing ) 416 | PlayPanel_OnHide( file.panel ) 417 | } 418 | 419 | 420 | bool function IsPlayPanelCurrentlyTopLevel() 421 | { 422 | return GetActiveMenu() == GetMenu( "LobbyMenu" ) && IsPanelActive( file.panel ) 423 | } 424 | 425 | 426 | void function UpdateLastPlayedPlayerInfo() 427 | { 428 | string oldUid0 = file.lastPlayedPlayerPlatformUid0 429 | string oldUid1 = file.lastPlayedPlayerPlatformUid1 430 | 431 | array curPartyMemberUids 432 | file.lastPlayedPlayerPlatformUid0 = "" 433 | file.lastPlayedPlayerNucleusID0 = "" 434 | file.lastPlayedPlayerHardwareID0 = -1 435 | file.lastPlayedPlayerPersistenceIndex0 = -1 436 | 437 | file.lastPlayedPlayerPlatformUid1 = "" 438 | file.lastPlayedPlayerNucleusID1 = "" 439 | file.lastPlayedPlayerHardwareID1 = -1 440 | file.lastPlayedPlayerPersistenceIndex1 = -1 441 | 442 | if ( !IsPersistenceAvailable() || !InviteLastPlayedPanelShouldBeVisible() ) 443 | { 444 | return 445 | } 446 | 447 | int maxTrackedSquadMembers = PersistenceGetArrayCount( "lastGameSquadStats" ) 448 | foreach ( index, member in GetParty().members ) 449 | { 450 | curPartyMemberUids.append( member.uid ) 451 | } 452 | 453 | for ( int i = 0; i < maxTrackedSquadMembers; i++ ) 454 | { 455 | string lastPlayedPlayerUid = expect string( GetPersistentVar( "lastGameSquadStats[" + i + "].platformUid" ) ) 456 | string lastPlayedNucleusID = expect string( GetPersistentVar( "lastGameSquadStats[" + i + "].nucleusId" ) ) 457 | int lastPlayedPlayerHardwareID = expect int( GetPersistentVar( "lastGameSquadStats[" + i + "].hardwareID" ) ) 458 | 459 | if ( lastPlayedPlayerUid == "" || lastPlayedPlayerHardwareID < 0 ) 460 | { 461 | continue 462 | } 463 | 464 | if ( !curPartyMemberUids.contains( lastPlayedPlayerUid ) ) 465 | { 466 | if ( file.lastPlayedPlayerPlatformUid0 == "" ) 467 | { 468 | file.lastPlayedPlayerPlatformUid0 = lastPlayedPlayerUid 469 | file.lastPlayedPlayerNucleusID0 = lastPlayedNucleusID 470 | file.lastPlayedPlayerHardwareID0 = lastPlayedPlayerHardwareID 471 | file.lastPlayedPlayerPersistenceIndex0 = i 472 | } 473 | else if ( file.lastPlayedPlayerPlatformUid1 == "" && lastPlayedPlayerUid != file.lastPlayedPlayerPlatformUid0 ) 474 | { 475 | file.lastPlayedPlayerPlatformUid1 = lastPlayedPlayerUid 476 | file.lastPlayedPlayerNucleusID1 = lastPlayedNucleusID 477 | file.lastPlayedPlayerHardwareID1 = lastPlayedPlayerHardwareID 478 | file.lastPlayedPlayerPersistenceIndex1 = i 479 | } 480 | } 481 | } 482 | 483 | if ( file.lastPlayedPlayerPlatformUid0 == oldUid1 ) 484 | { 485 | file.lastPlayedPlayerInviteSentTimestamp0 = file.lastPlayedPlayerInviteSentTimestamp1 486 | } 487 | 488 | if ( file.lastPlayedPlayerPlatformUid1 == oldUid0 ) 489 | { 490 | file.lastPlayedPlayerInviteSentTimestamp1 = file.lastPlayedPlayerInviteSentTimestamp0 491 | } 492 | } 493 | 494 | 495 | bool function InviteLastPlayedPanelShouldBeVisible() 496 | { 497 | if ( GetUnixTimestamp() - GetPersistentVarAsInt( "lastGameTime" ) > INVITE_LAST_PANEL_EXPIRATION ) 498 | return false 499 | 500 | if ( GetPersistentVarAsInt( "lastGamePlayers" ) == 0 && GetPersistentVarAsInt( "lastGameSquads" ) == 0 ) 501 | return false 502 | 503 | return true 504 | } 505 | 506 | 507 | bool function LastPlayedPlayerIsInMatch( string playerPlatformUid, int playerHardwareID ) 508 | { 509 | string hardware = GetNameFromHardware( playerHardwareID ) 510 | CommunityUserInfo ornull userInfoOrNull = GetUserInfo( hardware, playerPlatformUid ) 511 | if ( userInfoOrNull != null ) 512 | { 513 | CommunityUserInfo userInfo = expect CommunityUserInfo(userInfoOrNull) 514 | return userInfo.charData[ePlayerStryderCharDataArraySlots.PLAYER_IN_MATCH] == 1 515 | } 516 | return false 517 | } 518 | 519 | 520 | void function WatchForLTMModeExpiring( string plName ) 521 | { 522 | RegisterSignal( "WatchForLTMModeExpiring" ) 523 | 524 | thread function() : (plName) 525 | { 526 | Signal( uiGlobal.signalDummy, "WatchForLTMModeExpiring" ) 527 | EndSignal( uiGlobal.signalDummy, "WatchForLTMModeExpiring" ) 528 | EndSignal( uiGlobal.signalDummy, "LevelShutdown" ) 529 | EndSignal( uiGlobal.signalDummy, "CleanupInGameMenus" ) 530 | 531 | while ( !IsFullyConnected() ) 532 | WaitFrame() 533 | 534 | PlaylistScheduleData scheduleData = Playlist_GetScheduleData( plName ) 535 | if ( scheduleData.currentBlock == null ) 536 | return 537 | 538 | WaitForUnixTime( (expect TimestampRange(scheduleData.currentBlock)).endUnixTime ) 539 | 540 | printf( "%s() - Playlist '%s' has expired, so refreshing all.", FUNC_NAME(), plName ) 541 | if ( AreWeMatchmaking() ) 542 | { 543 | CancelMatchmaking() 544 | Remote_ServerCallFunction( "ClientCallback_CancelMatchSearch" ) 545 | EmitUISound( SOUND_STOP_MATCHMAKING_1P ) 546 | while( AreWeMatchmaking() ) 547 | WaitFrame() 548 | } 549 | Lobby_UpdatePlayPanelPlaylists() 550 | UpdateLobbyButtons() 551 | }() 552 | } 553 | 554 | 555 | var function GetModeSelectButton() 556 | { 557 | return file.modeButton 558 | } 559 | 560 | 561 | var function GetLobbyChatBox() 562 | { 563 | return file.chatBox 564 | } 565 | 566 | 567 | void function PlayPanel_OnShow( var panel ) 568 | { 569 | 570 | 571 | if ( IsFullyConnected() ) 572 | { 573 | AccessibilityHint( eAccessibilityHint.LOBBY_CHAT ) 574 | Lobby_UpdatePlayPanelPlaylists() 575 | } 576 | UpdateLobbyButtons() 577 | 578 | if ( file.chatroomMenu ) 579 | { 580 | Hud_Hide( file.chatroomMenu ) 581 | Hud_Hide( file.chatroomMenu_chatroomWidget ) 582 | } 583 | AddCallbackAndCallNow_OnGRXInventoryStateChanged( UpdatePlayPanelGRXDependantElements ) 584 | AddCallbackAndCallNow_OnGRXInventoryStateChanged( UpdateFriendButtons ) 585 | 586 | Remote_ServerCallFunction( "ClientCallback_ViewingMainLobbyPage" ) 587 | 588 | MiniPromo_Start() 589 | PromoDialog_InitPages() 590 | 591 | UI_ClearRespawnOverlay() 592 | 593 | UI_SetPresentationType( ePresentationType.PLAY ) 594 | 595 | bool v3PlaylistSelect = GamemodeSelect_IsEnabled() 596 | 597 | if ( v3PlaylistSelect ) 598 | { 599 | Hud_SetNavUp( file.readyButton, file.gamemodeSelectButton ) 600 | } 601 | else 602 | { 603 | Hud_SetNavUp( file.readyButton, file.modeButton ) 604 | } 605 | 606 | KeepUnixTimeDebugDisplayUpdated() 607 | 608 | thread Clubs_SetClubTabUserCount() 609 | thread TryRunDialogFlowThread() 610 | 611 | AddCallbackAndCallNow_UserInfoUpdated( Ranked_OnUserInfoUpdatedInPanelPlay ) 612 | 613 | file.nextAllowFriendsUpdateTime = UITime() 614 | 615 | ChallengeSwitch_RegisterInputCallbacks() 616 | 617 | file.isShowing = true 618 | 619 | } 620 | 621 | void function Thread_UpdateLobbyButtons() 622 | { 623 | EndSignal( uiGlobal.signalDummy, "LevelShutdown" ) 624 | EndSignal( uiGlobal.signalDummy, "CleanupInGameMenus" ) 625 | 626 | if( !IsLobby() || !IsConnectedServerInfo() ) 627 | return 628 | 629 | file.areLobbyButtonsUpdating = true 630 | 631 | UpdateFillButton() 632 | WaitFrame() 633 | 634 | UpdateReadyButton() 635 | WaitFrame() 636 | 637 | UpdateModeButton() 638 | WaitFrame() 639 | 640 | UpdateLTMButton() 641 | WaitFrame() 642 | 643 | UpdateFriendButtons() 644 | WaitFrame() 645 | 646 | UpdateLastPlayedButtons() 647 | WaitFrame() 648 | 649 | UpdateLowerLeftButtonPositions() 650 | WaitFrame() 651 | 652 | UpdateFooterOptions() 653 | 654 | file.areLobbyButtonsUpdating = false 655 | } 656 | 657 | void function UpdateLobbyButtons() 658 | { 659 | if ( !IsConnectedServerInfo() ) 660 | return 661 | 662 | if( !IsLobby() ) 663 | return 664 | 665 | 666 | 667 | 668 | 669 | if ( GetCurrentPlaylistVarBool( "thread_lobby_updates", true ) ) 670 | { 671 | if ( file.areLobbyButtonsUpdating == false ) 672 | thread Thread_UpdateLobbyButtons() 673 | } 674 | else 675 | { 676 | UpdateFillButton() 677 | UpdateReadyButton() 678 | UpdateModeButton() 679 | UpdateLTMButton() 680 | UpdateFriendButtons() 681 | UpdateLastPlayedButtons() 682 | UpdateLowerLeftButtonPositions() 683 | UpdateFooterOptions() 684 | } 685 | 686 | #if NX_PROG 687 | bool NewAoCAvailable = GetConVarBool( "NewAoCDownloadComplete" ) 688 | if ( NewAoCAvailable ) 689 | { 690 | OpenDownloadAoCNoticeDialog( false ) 691 | } 692 | #endif 693 | } 694 | 695 | void function UpdateLTMButton() 696 | { 697 | if( !IsLobby() || !IsConnected() ) 698 | return 699 | 700 | bool LTMisTakeover = GetPlaylistVarBool( Lobby_GetSelectedPlaylist(), "show_ltm_about_button_is_takeover", false ) 701 | var aboutButton = Hud_GetChild( file.panel, "AboutButton" ) 702 | Hud_ClearToolTipData( aboutButton ) 703 | if ( LTMisTakeover ) 704 | { 705 | string takeoverAbout = GetPlaylistVarString( Lobby_GetSelectedPlaylist(), "survival_takeover_about", "" ) 706 | if ( takeoverAbout != "" ) 707 | { 708 | ToolTipData td 709 | td.titleText = GetPlaylistVarString( Lobby_GetSelectedPlaylist(), "survival_takeover_title", "#PL_PLAY_APEX" ) 710 | td.descText = takeoverAbout 711 | Hud_SetToolTipData( aboutButton, td ) 712 | } 713 | } 714 | } 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | string function GetDebugTimeString() 725 | { 726 | Assert( GetDeveloperLevel() != 0 ) 727 | if ( GetDeveloperLevel() == 0 ) 728 | return "" 729 | 730 | bool dst = GetIsDSTActive() 731 | int utTime = dst ? GetUnixTimePDT() : GetUnixTimePST() 732 | string timeString = GetDateTimeString( utTime, 0 ) 733 | string dayName = GetDayOfWeekName( GetDayOfWeek( utTime ) ) 734 | return format( "%s, %s %s", Localize( dayName ), timeString, dst ? "PDT" : "PST" ) 735 | } 736 | 737 | 738 | void function KeepUnixTimeDebugDisplayUpdated() 739 | { 740 | RegisterSignal( "KeepFakeDaysDebugDisplayUpdated" ) 741 | 742 | thread function() : () 743 | { 744 | Signal( uiGlobal.signalDummy, "KeepFakeDaysDebugDisplayUpdated" ) 745 | EndSignal( uiGlobal.signalDummy, "KeepFakeDaysDebugDisplayUpdated" ) 746 | EndSignal( uiGlobal.signalDummy, "LevelShutdown" ) 747 | EndSignal( uiGlobal.signalDummy, "CleanupInGameMenus" ) 748 | 749 | var textLabel = Hud_GetChild( file.panel, "LobbyDebugText" ) 750 | 751 | int devLevelPrev = -99 752 | for ( ; ; ) 753 | { 754 | WaitFrame() 755 | 756 | if ( !IsFullyConnected() ) 757 | continue 758 | 759 | int devLevel = GetDeveloperLevel() 760 | if ( (devLevel == 0) && (devLevel == devLevelPrev) ) 761 | continue 762 | 763 | string str = ((devLevel == 0) ? "" : GetDebugTimeString()) 764 | Hud_SetText( textLabel, str ) 765 | devLevelPrev = devLevel 766 | } 767 | }() 768 | } 769 | 770 | 771 | void function UpdateHDTextureProgress() 772 | { 773 | 774 | HudElem_SetRuiArg( file.hdTextureProgress, "hdTextureProgress", GetGameFullyInstalledProgress() ) 775 | HudElem_SetRuiArg( file.hdTextureProgress, "hdTextureNeedsReboot", HasNonFullyInstalledAssetsLoaded() ) 776 | 777 | if ( ShowDownloadCompleteDialog() ) 778 | { 779 | ConfirmDialogData data 780 | data.headerText = "#TEXTURE_STREAM_REBOOT_HEADER" 781 | data.messageText = "#TEXTURE_STREAM_REBOOT_MESSAGE" 782 | data.yesText = ["#TEXTURE_STREAM_REBOOT", "#TEXTURE_STREAM_REBOOT_PC"] 783 | data.noText = ["#B_BUTTON_CANCEL", "#CANCEL"] 784 | 785 | data.resultCallback = void function ( int result ) : () 786 | { 787 | if ( result == eDialogResult.YES ) 788 | { 789 | 790 | ClientCommand( "disconnect" ) 791 | } 792 | 793 | return 794 | } 795 | 796 | OpenConfirmDialogFromData( data ) 797 | file.fullInstallNotification = true 798 | } 799 | } 800 | 801 | 802 | void function UpdateLastSquadDpadNav() 803 | { 804 | var buttonBeneathLastSquadPanel = file.modeButton 805 | var buttonRightOfLastSquadPanel = Hud_IsVisible( file.friendButton0 ) ? file.friendButton0 : file.inviteFriendsButton0 806 | 807 | if ( Hud_IsVisible( file.gamemodeSelectButton ) ) 808 | { 809 | buttonBeneathLastSquadPanel = file.gamemodeSelectButton 810 | } 811 | 812 | if ( Hud_IsVisible( file.fillButton ) ) 813 | { 814 | buttonBeneathLastSquadPanel = file.fillButton 815 | } 816 | 817 | bool isVisibleButton0 = Hud_IsVisible( file.inviteLastPlayedUnitFrame0 ) 818 | bool isVisibleButton1 = Hud_IsVisible( file.inviteLastPlayedUnitFrame1 ) 819 | 820 | if ( isVisibleButton0 ) 821 | { 822 | Hud_SetNavUp( buttonBeneathLastSquadPanel, isVisibleButton1 ? file.inviteLastPlayedUnitFrame1 : file.inviteLastPlayedUnitFrame0 ) 823 | Hud_SetNavDown( file.inviteLastPlayedUnitFrame0, isVisibleButton1 ? file.inviteLastPlayedUnitFrame1 : buttonBeneathLastSquadPanel ) 824 | Hud_SetNavDown( file.inviteLastPlayedUnitFrame1, buttonBeneathLastSquadPanel ) 825 | Hud_SetNavLeft( buttonRightOfLastSquadPanel, file.inviteLastPlayedUnitFrame0 ) 826 | Hud_SetNavRight( file.inviteLastPlayedUnitFrame0, buttonRightOfLastSquadPanel ) 827 | Hud_SetNavRight( file.inviteLastPlayedUnitFrame1, buttonRightOfLastSquadPanel ) 828 | } 829 | else 830 | { 831 | Hud_SetNavUp( buttonBeneathLastSquadPanel, buttonRightOfLastSquadPanel ) 832 | Hud_SetNavDown( buttonRightOfLastSquadPanel, buttonBeneathLastSquadPanel ) 833 | Hud_SetNavLeft( buttonRightOfLastSquadPanel, buttonBeneathLastSquadPanel ) 834 | Hud_SetNavRight( buttonBeneathLastSquadPanel, buttonRightOfLastSquadPanel ) 835 | } 836 | } 837 | 838 | 839 | bool function ShowDownloadCompleteDialog() 840 | { 841 | if ( GetGameFullyInstalledProgress() != 1 ) 842 | return false 843 | 844 | if ( !HasNonFullyInstalledAssetsLoaded() ) 845 | return false 846 | 847 | if ( file.fullInstallNotification ) 848 | return false 849 | 850 | if ( GetActiveMenu() != GetMenu( "LobbyMenu" ) ) 851 | return false 852 | 853 | if ( GetPersistentVar( "showGameSummary" ) && IsPostGameMenuValid( true ) ) 854 | return false 855 | 856 | return true 857 | } 858 | 859 | 860 | array function Lobby_GetPlaylistMods() 861 | { 862 | return file.playlistMods 863 | } 864 | 865 | 866 | array function Lobby_GetPlaylists() 867 | { 868 | return file.playlists 869 | } 870 | 871 | 872 | string function Lobby_GetSelectedPlaylist() 873 | { 874 | bool isLeader = IsPartyLeader() 875 | string playlistName = isLeader ? file.selectedPlaylist : GetParty().playlistName 876 | return playlistName 877 | } 878 | 879 | 880 | string function Lobby_GetLastSelectedPlaylist() 881 | { 882 | return file.lastPlaylistDisplayed 883 | } 884 | 885 | 886 | bool function Lobby_IsPlaylistAvailable( string playlistName ) 887 | { 888 | return Lobby_GetPlaylistState( playlistName ) == ePlaylistState.AVAILABLE 889 | } 890 | 891 | 892 | void function Lobby_SetSelectedPlaylistMods( string playlistModNames ) 893 | { 894 | printt( "Lobby_SetSelectedPlaylistMods " + playlistModNames ) 895 | file.selectedPlaylistMods = playlistModNames 896 | UpdateLobbyButtons() 897 | UpdateLobbyChallengeMenu() 898 | Lobby_UpdateLoadscreenFromPlaylist() 899 | 900 | if ( file.selectedPlaylist.len() > 0 ) 901 | SetMatchmakingPlaylist( file.selectedPlaylist + playlistModNames ) 902 | } 903 | 904 | 905 | int function Lobby_GetSelectedPlaylistExpectedSquadSize() 906 | { 907 | string selectedPlaylist = Lobby_GetSelectedPlaylist() 908 | return int ( GetPlaylistVarFloat( selectedPlaylist, "max_players", 60 ) / GetPlaylistVarFloat( selectedPlaylist, "max_teams", 20 ) ) 909 | } 910 | 911 | 912 | void function Lobby_SetSelectedPlaylist( string playlistName ) 913 | { 914 | printt( "Lobby_SetSelectedPlaylist " + playlistName ) 915 | file.selectedPlaylist = playlistName 916 | UpdateLobbyButtons() 917 | Lobby_UpdateLoadscreenFromPlaylist() 918 | 919 | if ( playlistName.len() > 0 ) 920 | SetMatchmakingPlaylist( playlistName + file.selectedPlaylistMods ) 921 | 922 | if( IsConnected() && IsLobby() && IsLocalClientEHIValid() ) 923 | UpdateLobbyChallengeMenu() 924 | 925 | WatchForLTMModeExpiring( playlistName ) 926 | } 927 | 928 | 929 | void function Lobby_ClearSelectedPlaylist() 930 | { 931 | file.selectedPlaylist = "" 932 | } 933 | 934 | 935 | void function Lobby_UpdateLoadscreenFromPlaylist() 936 | { 937 | if ( GetPlaylistVarBool( Lobby_GetSelectedPlaylist(), "force_level_loadscreen", false ) ) 938 | { 939 | SetCustomLoadScreen( $"" ) 940 | } 941 | else 942 | { 943 | thread Loadscreen_SetEquppedLoadscreenAsActive() 944 | } 945 | } 946 | 947 | 948 | void function PlayPanel_OnHide( var panel ) 949 | { 950 | Signal( uiGlobal.signalDummy, "UpdateFriendButtons" ) 951 | Hud_ClearToolTipData( file.modeButton ) 952 | 953 | RemoveCallback_OnGRXInventoryStateChanged( UpdatePlayPanelGRXDependantElements ) 954 | RemoveCallback_OnGRXInventoryStateChanged( UpdateFriendButtons ) 955 | 956 | 957 | 958 | MiniPromo_Stop() 959 | file.rankedRUIToUpdate = null 960 | RemoveCallback_UserInfoUpdated( Ranked_OnUserInfoUpdatedInPanelPlay ) 961 | 962 | ChallengeSwitch_RemoveInputCallbacks() 963 | 964 | file.isShowing = false 965 | } 966 | 967 | 968 | void function UpdateFriendButton( var rui, PartyMember info, bool inMatch ) 969 | { 970 | Party party = GetParty() 971 | 972 | string playerName = "" 973 | if ( info.clubTag != "" ) 974 | { 975 | playerName = "[" + info.clubTag + "]" + info.name 976 | } 977 | else 978 | { 979 | playerName = info.name 980 | } 981 | 982 | 983 | RuiSetString( rui, "playerName", playerName ) 984 | RuiSetBool( rui, "isLeader", party.originatorUID == info.uid && GetPartySize() > 1 ) 985 | RuiSetBool( rui, "isReady", info.ready ) 986 | RuiSetBool( rui, "inMatch", inMatch ) 987 | if ( inMatch ) 988 | { 989 | RuiSetString( rui, "footerText", "#PROMPT_IN_MATCH" ) 990 | } 991 | else 992 | { 993 | RuiSetString( rui, "footerText", "" ) 994 | } 995 | 996 | thread KeepMicIconUpdated( info, rui ) 997 | 998 | int rankScore = 0 999 | int ladderPosition = SHARED_RANKED_INVALID_LADDER_POSITION 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | CommunityUserInfo ornull userInfo = GetUserInfo( info.hardware, info.uid ) 1007 | if ( userInfo == null ) 1008 | { 1009 | if ( info.uid in file.s_cachedAccountXPFrac ) 1010 | RuiSetFloat( rui, "accountXPFrac", file.s_cachedAccountXPFrac[info.uid] ) 1011 | else 1012 | RuiSetFloat( rui, "accountXPFrac", 0 ) 1013 | 1014 | 1015 | int accountLevel = 0 1016 | if ( info.uid == GetPlayerUID() && IsPersistenceAvailable() ) 1017 | accountLevel = GetAccountLevelForXP( GetPersistentVarAsInt( "xp" ) ) 1018 | 1019 | 1020 | 1021 | var nestedAccountBadge = CreateNestedAccountDisplayBadge( rui, "accountBadgeHandle", accountLevel ) 1022 | 1023 | if ( info.uid == GetPlayerUID() && IsPersistenceAvailable() ) 1024 | { 1025 | rankScore = GetPlayerRankScore( GetLocalClientPlayer() ) 1026 | 1027 | 1028 | 1029 | } 1030 | } 1031 | else 1032 | { 1033 | expect CommunityUserInfo( userInfo ) 1034 | 1035 | float accountXPFrac = userInfo.charData[ePlayerStryderCharDataArraySlots.ACCOUNT_PROGRESS_INT] / 100.0 1036 | 1037 | file.s_cachedAccountXPFrac[info.uid] <- accountXPFrac 1038 | RuiSetFloat( rui, "accountXPFrac", accountXPFrac ) 1039 | 1040 | 1041 | 1042 | var accountBadge = CreateNestedAccountDisplayBadge( rui, "accountBadgeHandle", userInfo.charData[ePlayerStryderCharDataArraySlots.ACCOUNT_LEVEL] ) 1043 | 1044 | rankScore = userInfo.rankScore 1045 | ladderPosition = userInfo.rankedLadderPos 1046 | 1047 | string platformString = CrossplayUserOptIn() ? PlatformIDToIconString( GetHardwareFromName( info.hardware ) ) : "" 1048 | RuiSetString( rui, "platformString", platformString ) 1049 | } 1050 | 1051 | RuiSetBool( rui, "showRanked", false ) 1052 | 1053 | bool isRanked = IsRankedPlaylist( Lobby_GetSelectedPlaylist() ) 1054 | if ( isRanked ) 1055 | { 1056 | RuiSetBool( rui, "showRanked", isRanked ) 1057 | PopulateRuiWithRankedBadgeDetails( rui, rankScore, ladderPosition ) 1058 | float frac = 0.0 1059 | 1060 | SharedRankedDivisionData currentRank = GetCurrentRankedDivisionFromScoreAndLadderPosition( rankScore, ladderPosition ) 1061 | SharedRankedDivisionData ornull nextRank = GetNextRankedDivisionFromScore( rankScore ) 1062 | 1063 | if ( nextRank == null ) 1064 | { 1065 | frac = 1.0 1066 | } 1067 | else 1068 | { 1069 | expect SharedRankedDivisionData( nextRank ) 1070 | if ( nextRank != currentRank ) 1071 | { 1072 | frac = GraphCapped( float( rankScore ), currentRank.scoreMin, nextRank.scoreMin, 0.0, 1.0 ) 1073 | } 1074 | } 1075 | 1076 | RuiSetFloat( rui, "accountXPFrac", frac ) 1077 | } 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | } 1109 | 1110 | 1111 | void function KeepMicIconUpdated( PartyMember info, var rui ) 1112 | { 1113 | EndSignal( uiGlobal.signalDummy, "UpdateFriendButtons" ) 1114 | 1115 | while ( true ) 1116 | { 1117 | RuiSetInt( rui, "micStatus", GetChatroomMicStatus( info.uid, info.hardware ) ) 1118 | WaitFrame() 1119 | } 1120 | } 1121 | 1122 | void function UpdateFriendButtons() 1123 | { 1124 | if( !IsLobby() || !IsConnected() ) 1125 | return 1126 | 1127 | Signal( uiGlobal.signalDummy, "UpdateFriendButtons" ) 1128 | 1129 | Hud_SetVisible( file.inviteFriendsButton0, false ) 1130 | Hud_SetVisible( file.inviteFriendsButton1, false ) 1131 | Hud_SetVisible( file.friendButton0, false ) 1132 | Hud_SetVisible( file.friendButton1, false ) 1133 | 1134 | if( IsDialog( GetActiveMenu() ) ) 1135 | return 1136 | 1137 | Hud_SetVisible( file.inviteFriendsButton0, !file.personInLeftSpot ) 1138 | Hud_SetVisible( file.inviteFriendsButton1, !file.personInRightSlot ) 1139 | 1140 | var leftButton = file.personInLeftSpot ? file.friendButton0 : file.inviteFriendsButton0 1141 | var rightButton = file.personInRightSlot ? file.friendButton1 : file.inviteFriendsButton1 1142 | 1143 | Hud_SetNavRight( file.inviteLastPlayedUnitFrame0, leftButton ) 1144 | Hud_SetNavRight( file.inviteLastPlayedUnitFrame1, leftButton ) 1145 | 1146 | Hud_SetNavDown( file.selfButton, leftButton ) 1147 | Hud_SetNavLeft( file.selfButton, leftButton ) 1148 | Hud_SetNavRight( file.selfButton, rightButton ) 1149 | 1150 | Hud_SetNavLeft( file.miniPromoButton, rightButton ) 1151 | Hud_SetNavLeft( file.eventPrizeTrackButton , rightButton ) 1152 | Hud_SetNavLeft( Hud_GetChild( file.panel, "ChallengeCatergoryLeftButton" ), rightButton ) 1153 | 1154 | if ( file.nextAllowFriendsUpdateTime < UITime() ) 1155 | { 1156 | int count = GetInGameFriendCount( true ) 1157 | RuiSetInt( Hud_GetRui( file.inviteFriendsButton0 ), "onlineFriendCount", count ) 1158 | RuiSetInt( Hud_GetRui( file.inviteFriendsButton1 ), "onlineFriendCount", count ) 1159 | file.nextAllowFriendsUpdateTime = UITime() + 5.0 1160 | } 1161 | 1162 | Party party = GetParty() 1163 | string playerUID = GetPlayerUID() 1164 | foreach ( PartyMember partyMember in party.members ) 1165 | { 1166 | if ( partyMember.uid == playerUID ) 1167 | { 1168 | ToolTipData toolTipData 1169 | toolTipData.tooltipStyle = eTooltipStyle.BUTTON_PROMPT 1170 | toolTipData.actionHint1 = "#A_BUTTON_INSPECT" 1171 | 1172 | int blockSecondsLeft = CommunicationBlockGetBlockSeconds() 1173 | if ( blockSecondsLeft > 0 ) 1174 | { 1175 | int minutes = int( ceil( blockSecondsLeft / 60 ) ); 1176 | toolTipData.descText = format( Localize( "#TOXIC_CHAT_BLOCKED" ), minutes ) 1177 | } 1178 | 1179 | Hud_SetToolTipData( file.selfButton, toolTipData ) 1180 | 1181 | var friendRui = Hud_GetRui( file.selfButton ) 1182 | 1183 | RuiSetBool( friendRui, "canViewStats", true ) 1184 | 1185 | UpdateFriendButton( friendRui, partyMember, false ) 1186 | } 1187 | else if ( partyMember.uid == file.friendInLeftSpot.id ) 1188 | { 1189 | ToolTipData toolTipData 1190 | toolTipData.tooltipStyle = eTooltipStyle.BUTTON_PROMPT 1191 | toolTipData.actionHint1 = "#A_BUTTON_INSPECT" 1192 | toolTipData.actionHint2 = "" 1193 | toolTipData.actionHint2 = IsPlayerVoiceAndTextMutedForUID( partyMember.uid, partyMember.hardware ) ? "#X_BUTTON_UNMUTE" : "#X_BUTTON_MUTE" 1194 | 1195 | EadpPeopleData friendData = expect EadpPeopleData(file.friendInLeftSpot.eadpData) 1196 | string friendNucleus = friendData.eaid 1197 | string clubInviteTooltip = ( ClubIsValid() && !Clubs_IsUserAClubmate(friendNucleus)) ? Localize( "#LAST_SQUAD_BUTTON_CLUB_INVITE" ) : "" 1198 | 1199 | if(toolTipData.actionHint2 == "") 1200 | toolTipData.actionHint2 = clubInviteTooltip 1201 | else toolTipData.actionHint3 = clubInviteTooltip 1202 | Hud_SetToolTipData( file.friendButton0, toolTipData ) 1203 | 1204 | var friendRui = Hud_GetRui( file.friendButton0 ) 1205 | UpdateFriendButton( friendRui, partyMember, file.friendInLeftSpot.ingame ) 1206 | Hud_SetVisible( file.friendButton0, true ) 1207 | if ( file.leftWasReady != partyMember.ready ) 1208 | EmitUISound( partyMember.ready ? SOUND_START_MATCHMAKING_3P : SOUND_STOP_MATCHMAKING_3P ) 1209 | 1210 | file.leftWasReady = partyMember.ready 1211 | } 1212 | else if ( partyMember.uid == file.friendInRightSpot.id ) 1213 | { 1214 | ToolTipData toolTipData 1215 | toolTipData.tooltipStyle = eTooltipStyle.BUTTON_PROMPT 1216 | toolTipData.actionHint1 = "#A_BUTTON_INSPECT" 1217 | toolTipData.actionHint2 = IsPlayerVoiceAndTextMutedForUID( partyMember.uid, partyMember.hardware ) ? "#X_BUTTON_UNMUTE" : "#X_BUTTON_MUTE" 1218 | 1219 | EadpPeopleData friendData = expect EadpPeopleData(file.friendInRightSpot.eadpData) 1220 | string friendNucleus = friendData.eaid 1221 | string clubInviteTooltip = ( ClubIsValid() && !Clubs_IsUserAClubmate(friendNucleus)) ? Localize( "#LAST_SQUAD_BUTTON_CLUB_INVITE" ) : "" 1222 | 1223 | if(toolTipData.actionHint2 == "") 1224 | toolTipData.actionHint2 = clubInviteTooltip 1225 | else toolTipData.actionHint3 = clubInviteTooltip 1226 | Hud_SetToolTipData( file.friendButton1, toolTipData ) 1227 | 1228 | var friendRui = Hud_GetRui( file.friendButton1 ) 1229 | UpdateFriendButton( friendRui, partyMember, file.friendInRightSpot.ingame ) 1230 | Hud_SetVisible( file.friendButton1, true ) 1231 | 1232 | if ( file.rightWasReady != partyMember.ready ) 1233 | EmitUISound( partyMember.ready ? SOUND_START_MATCHMAKING_3P : SOUND_STOP_MATCHMAKING_3P ) 1234 | 1235 | file.rightWasReady = partyMember.ready 1236 | } 1237 | } 1238 | 1239 | ToolTipData toolTipData 1240 | toolTipData.titleText = "#INVITE" 1241 | toolTipData.descText = "#INVITE_HINT" 1242 | 1243 | entity player = GetLocalClientPlayer() 1244 | if ( IsLocalClientEHIValid() && IsValid( player ) ) 1245 | { 1246 | bool hasPremiumPass = false 1247 | if ( file.currentBPInfo.bpExpirationTimestamp < GetUnixTimestamp() ) 1248 | { 1249 | file.currentBPInfo.battlePassOrNull = GetActiveBattlePass() 1250 | if ( file.currentBPInfo.battlePassOrNull != null ) 1251 | file.currentBPInfo.bpExpirationTimestamp = CalEvent_GetFinishUnixTime( expect ItemFlavor( GetActiveSeason( GetUnixTimestamp() ) ) ) 1252 | } 1253 | ItemFlavor ornull activeBattlePass = file.currentBPInfo.battlePassOrNull 1254 | bool hasActiveBattlePass = activeBattlePass != null 1255 | if ( hasActiveBattlePass && GRX_IsInventoryReady() ) 1256 | { 1257 | expect ItemFlavor( activeBattlePass ) 1258 | hasPremiumPass = DoesPlayerOwnBattlePass( player, activeBattlePass ) 1259 | if ( hasPremiumPass ) 1260 | toolTipData.descText = Localize( "#INVITE_HINT_BP" ) 1261 | } 1262 | } 1263 | 1264 | #if PC_PROG 1265 | if ( !PCPlat_IsOverlayAvailable() && !GetCurrentPlaylistVarBool( "social_menu_enabled", true ) ) 1266 | { 1267 | string platname = PCPlat_IsOrigin() ? "ORIGIN" : "STEAM" 1268 | toolTipData.descText = "#" + platname + "_INGAME_REQUIRED" 1269 | Hud_SetLocked( file.inviteFriendsButton0, true ) 1270 | Hud_SetLocked( file.inviteFriendsButton1, true ) 1271 | } 1272 | #endif 1273 | 1274 | Hud_SetToolTipData( file.inviteFriendsButton0, toolTipData ) 1275 | Hud_SetToolTipData( file.inviteFriendsButton1, toolTipData ) 1276 | } 1277 | 1278 | 1279 | void function UpdateLowerLeftButtonPositions() 1280 | { 1281 | if( !IsLobby() || !IsConnected() ) 1282 | return 1283 | 1284 | bool v3PlaylistSelect = GamemodeSelect_IsEnabled() 1285 | 1286 | bool showLTMAboutButton = GetPlaylistVarBool( Lobby_GetSelectedPlaylist(), "show_ltm_about_button", false ) 1287 | var aboutButton = Hud_GetChild( file.panel, "AboutButton" ) 1288 | Hud_SetVisible( aboutButton, false ) 1289 | 1290 | bool shouldShowRankedBadge = IsRankedPlaylist( Lobby_GetSelectedPlaylist() ) 1291 | 1292 | var rankedBadge = Hud_GetChild( file.panel, "RankedBadge" ) 1293 | Hud_SetVisible( rankedBadge, false ) 1294 | 1295 | Hud_SetY( file.fillButton, 16 ) 1296 | 1297 | 1298 | 1299 | 1300 | 1301 | 1302 | 1303 | var buttonToTheRight = Hud_IsVisible( file.friendButton0 ) ? file.friendButton0 : file.inviteFriendsButton0 1304 | Hud_SetNavRight( rankedBadge, buttonToTheRight ) 1305 | 1306 | 1307 | 1308 | Hud_SetNavRight( aboutButton, buttonToTheRight ) 1309 | Hud_SetNavRight( file.fillButton, buttonToTheRight ) 1310 | 1311 | if ( v3PlaylistSelect ) 1312 | { 1313 | Hud_SetPinSibling( rankedBadge, Hud_GetHudName( file.gamemodeSelectButton ) ) 1314 | 1315 | 1316 | 1317 | Hud_SetPinSibling( aboutButton, Hud_GetHudName( file.gamemodeSelectButton ) ) 1318 | Hud_SetPinSibling( file.fillButton, Hud_GetHudName( file.gamemodeSelectButton ) ) 1319 | 1320 | Hud_SetNavUp( file.gamemodeSelectButton, file.inviteFriendsButton0 ) 1321 | 1322 | Hud_SetNavDown( rankedBadge, file.gamemodeSelectButton ) 1323 | 1324 | 1325 | 1326 | Hud_SetNavDown( aboutButton, file.gamemodeSelectButton ) 1327 | Hud_SetNavDown( file.fillButton, file.gamemodeSelectButton ) 1328 | } 1329 | else 1330 | { 1331 | Hud_SetPinSibling( rankedBadge, Hud_GetHudName( file.modeButton ) ) 1332 | Hud_SetPinSibling( aboutButton, Hud_GetHudName( file.modeButton ) ) 1333 | Hud_SetPinSibling( file.fillButton, Hud_GetHudName( file.modeButton ) ) 1334 | 1335 | Hud_SetNavDown( rankedBadge, file.modeButton ) 1336 | Hud_SetNavDown( aboutButton, file.modeButton ) 1337 | Hud_SetNavDown( file.fillButton, file.modeButton ) 1338 | } 1339 | 1340 | var msgLabel = Hud_GetChild( file.panel, "PlaylistNotificationMessage" ) 1341 | Hud_SetVisible( msgLabel, false ) 1342 | 1343 | if ( v3PlaylistSelect ) 1344 | { 1345 | Hud_SetPinSibling( msgLabel, Hud_GetHudName( file.gamemodeSelectButton ) ) 1346 | } 1347 | else 1348 | { 1349 | Hud_SetPinSibling( msgLabel, Hud_GetHudName( file.modeButton ) ) 1350 | } 1351 | 1352 | if ( shouldShowRankedBadge ) 1353 | { 1354 | Hud_SetVisible( rankedBadge, shouldShowRankedBadge ) 1355 | 1356 | if ( v3PlaylistSelect ) 1357 | { 1358 | Hud_SetNavUp( file.gamemodeSelectButton, rankedBadge ) 1359 | } 1360 | 1361 | var rui = Hud_GetRui( rankedBadge ) 1362 | 1363 | int score = GetPlayerRankScore( GetLocalClientPlayer() ) 1364 | bool isProvisional = Ranked_GetNumProvisionalMatchesCompleted( GetLocalClientPlayer() ) < Ranked_GetNumProvisionalMatchesRequired() 1365 | 1366 | if ( score == SHARED_RANKED_INVALID_RANK_SCORE ) 1367 | score = 0 1368 | 1369 | int ladderPosition = Ranked_GetLadderPosition( GetLocalClientPlayer() ) 1370 | if ( Ranked_ShouldUpdateWithComnunityUserInfo( score, ladderPosition ) ) 1371 | file.rankedRUIToUpdate = rui 1372 | 1373 | SharedRankedDivisionData data = GetCurrentRankedDivisionFromScoreAndLadderPosition( score, ladderPosition ) 1374 | RuiSetInt( rui, "score", score ) 1375 | RuiSetInt( rui, "scoreMax", 0 ) 1376 | RuiSetFloat( rui, "scoreFrac", 1.0 ) 1377 | RuiSetString( rui, "rankName", data.divisionName ) 1378 | PopulateRuiWithRankedBadgeDetails( rui, score, ladderPosition ) 1379 | 1380 | SharedRankedDivisionData currentRank = GetCurrentRankedDivisionFromScore ( score ) 1381 | int entryCost = Ranked_GetCostForEntry () 1382 | int tierFloor = currentRank.tier.scoreMin 1383 | bool showDemotionProtection = ((score - tierFloor) < entryCost && currentRank.tier.allowsDemotion ) && !isProvisional 1384 | 1385 | RuiSetBool ( rui, "showProtection" , showDemotionProtection ) 1386 | 1387 | if (showDemotionProtection) 1388 | { 1389 | RuiSetInt ( rui, "protectionCurrent" , GetDemotionProtectionBuffer ( GetLocalClientPlayer() ) ) 1390 | } 1391 | 1392 | RuiSetBool( rui, "inSeason", IsRankedInSeason() ) 1393 | RuiSetBool( rui, "inProvisional", isProvisional ) 1394 | 1395 | if ( data.tier.index != file.lobbyRankTier ) 1396 | { 1397 | RuiDestroyNestedIfAlive( rui, "rankedBadgeHandle" ) 1398 | CreateNestedRankedRui( rui, data.tier, "rankedBadgeHandle", score, ladderPosition ) 1399 | file.lobbyRankTier = data.tier.index 1400 | } 1401 | 1402 | ToolTipData tooltip 1403 | tooltip.titleText = data.divisionName 1404 | 1405 | SharedRankedDivisionData ornull nextData = GetNextRankedDivisionFromScore( score ) 1406 | 1407 | if (isProvisional ) 1408 | { 1409 | tooltip.descText = Localize( "#RANKED_PLACEMENT_TOOLTIP") 1410 | tooltip.titleText = "" 1411 | 1412 | RuiSetInt( rui, "score", Ranked_GetNumProvisionalMatchesCompleted( GetLocalClientPlayer() ) ) 1413 | RuiSetInt( rui, "scoreMax", Ranked_GetNumProvisionalMatchesRequired() ) 1414 | RuiSetString( rui, "rankName", Localize( "#RANKED_TIER_PROVISIONAL")) 1415 | 1416 | } 1417 | else if ( nextData != null ) 1418 | { 1419 | expect SharedRankedDivisionData( nextData ) 1420 | tooltip.descText = Localize( "#RANKED_TOOLTIP_NEXT", Localize( nextData.divisionName ).toupper(), (nextData.scoreMin - score) ) 1421 | 1422 | RuiSetInt( rui, "scoreMax", nextData.scoreMin ) 1423 | RuiSetFloat( rui, "scoreFrac", float( score - data.scoreMin ) / float( nextData.scoreMin - data.scoreMin ) ) 1424 | } 1425 | 1426 | Hud_SetToolTipData( rankedBadge, tooltip ) 1427 | return 1428 | } 1429 | 1430 | 1431 | 1432 | 1433 | 1434 | 1435 | 1436 | 1437 | 1438 | 1439 | 1440 | 1441 | 1442 | 1443 | 1444 | 1445 | 1446 | 1447 | 1448 | 1449 | 1450 | 1451 | 1452 | 1453 | 1454 | 1455 | 1456 | 1457 | 1458 | 1459 | 1460 | 1461 | 1462 | 1463 | 1464 | 1465 | 1466 | 1467 | 1468 | 1469 | 1470 | 1471 | 1472 | 1473 | 1474 | 1475 | 1476 | 1477 | 1478 | 1479 | 1480 | 1481 | 1482 | 1483 | 1484 | 1485 | 1486 | 1487 | 1488 | 1489 | 1490 | 1491 | 1492 | 1493 | 1494 | 1495 | 1496 | 1497 | 1498 | 1499 | 1500 | 1501 | 1502 | 1503 | if ( showLTMAboutButton ) 1504 | { 1505 | Hud_SetVisible( aboutButton, showLTMAboutButton ) 1506 | 1507 | if ( v3PlaylistSelect ) 1508 | { 1509 | Hud_SetNavUp( file.gamemodeSelectButton, aboutButton ) 1510 | } 1511 | 1512 | if ( DoesPlaylistSupportNoFill( Lobby_GetSelectedPlaylist() ) ) 1513 | Hud_SetNavUp( aboutButton, file.fillButton ) 1514 | 1515 | Hud_SetPinSibling( file.fillButton, Hud_GetHudName( aboutButton ) ) 1516 | Hud_SetY( file.fillButton, 10 ) 1517 | Hud_SetNavDown( file.fillButton, aboutButton ) 1518 | 1519 | array emblemColor = GetEmblemColor( GetSelectedPlaylist() ) 1520 | 1521 | var rui = Hud_GetRui( aboutButton ) 1522 | 1523 | bool LTMisTakeover = GetPlaylistVarBool( Lobby_GetSelectedPlaylist(), "show_ltm_about_button_is_takeover", false ) 1524 | var aboutButtonRui = Hud_GetRui( Hud_GetChild( file.panel, "AboutButton" ) ) 1525 | if ( LTMisTakeover ) 1526 | { 1527 | RuiSetBool( aboutButtonRui, "extendBorder", true ) 1528 | RuiSetString( aboutButtonRui, "buttonText", "#ABOUT_TAKEOVER" ) 1529 | } 1530 | else 1531 | { 1532 | RuiSetBool( aboutButtonRui, "extendBorder", false ) 1533 | RuiSetString( aboutButtonRui, "buttonText", "#ABOUT_GAMEMODE" ) 1534 | } 1535 | 1536 | asset emblemImage = GetModeEmblemImage( GetSelectedPlaylist() ) 1537 | RuiSetImage( rui, "emblemImage", emblemImage ) 1538 | RuiSetColorAlpha( rui, "emblemColor", SrgbToLinear( / 255.0 ), emblemColor[3] / 255.0 ) 1539 | 1540 | 1541 | 1542 | 1543 | 1544 | 1545 | 1546 | 1547 | 1548 | return 1549 | } 1550 | } 1551 | #if NX_PROG 1552 | bool function NXCanInviteUser(var playerId ) 1553 | { 1554 | 1555 | if( playerId == -1 ) 1556 | return false 1557 | 1558 | string characterGUIDString = string( GetPersistentVar( "lastGameSquadStats[" + playerId + "].platformUid" ) ) 1559 | 1560 | if( NX_IsSystemFriend(characterGUIDString) ) 1561 | return true 1562 | 1563 | if ( CrossplayEnabled() && CrossplayUserOptIn() ) 1564 | return true 1565 | 1566 | return false 1567 | } 1568 | #endif 1569 | 1570 | void function UpdateLastPlayedButtons() 1571 | { 1572 | if( !IsLobby() || !IsConnected() ) 1573 | return 1574 | 1575 | UpdateLastPlayedPlayerInfo() 1576 | 1577 | bool isVisibleButton0 = file.lastPlayedPlayerPlatformUid0 != "" && 1578 | !LastPlayedPlayerIsInMatch( file.lastPlayedPlayerPlatformUid0, file.lastPlayedPlayerHardwareID0 ) && 1579 | !EADP_IsBlockedByEAID( file.lastPlayedPlayerNucleusID0 ) 1580 | 1581 | bool isVisibleButton1 = file.lastPlayedPlayerPlatformUid1 != "" && 1582 | !LastPlayedPlayerIsInMatch( file.lastPlayedPlayerPlatformUid1, file.lastPlayedPlayerHardwareID1 ) && 1583 | !EADP_IsBlockedByEAID( file.lastPlayedPlayerNucleusID1 ) 1584 | 1585 | bool shouldUpdateDpadNav = false 1586 | 1587 | if ( isVisibleButton0 != Hud_IsVisible( file.inviteLastPlayedUnitFrame0 ) || isVisibleButton1 != Hud_IsVisible( file.inviteLastPlayedUnitFrame1 ) ) 1588 | { 1589 | shouldUpdateDpadNav = true 1590 | } 1591 | 1592 | isVisibleButton0 = isVisibleButton0 && CanInvite() 1593 | isVisibleButton1 = isVisibleButton1 && CanInvite() 1594 | 1595 | bool canInviteUserOne = true 1596 | bool canInviteUserTwo = true 1597 | 1598 | #if NX_PROG 1599 | canInviteUserOne = NXCanInviteUser(file.lastPlayedPlayerPersistenceIndex0) 1600 | canInviteUserTwo = NXCanInviteUser(file.lastPlayedPlayerPersistenceIndex1) 1601 | #endif 1602 | 1603 | if ( isVisibleButton0 ) 1604 | { 1605 | if ( file.lastPlayedPlayerPersistenceIndex0 == -1 ) 1606 | return 1607 | 1608 | string namePlayer0 = expect string( GetPersistentVar( "lastGameSquadStats[" + file.lastPlayedPlayerPersistenceIndex0 + "].playerName" ) ) 1609 | HudElem_SetRuiArg( file.inviteLastPlayedUnitFrame0, "name", namePlayer0 ) 1610 | 1611 | 1612 | int characterGUID = GetPersistentVarAsInt( "lastGameSquadStats[" + file.lastPlayedPlayerPersistenceIndex0 + "].character" ) 1613 | if ( IsValidItemFlavorGUID( characterGUID ) ) 1614 | { 1615 | ItemFlavor squadCharacterClass = GetItemFlavorByGUID( characterGUID ) 1616 | HudElem_SetRuiArg( file.inviteLastPlayedUnitFrame0, "icon", CharacterClass_GetGalleryPortrait( squadCharacterClass ), eRuiArgType.IMAGE ) 1617 | } 1618 | 1619 | if ( UITime() - file.lastPlayedPlayerInviteSentTimestamp0 > INVITE_LAST_TIMEOUT ) 1620 | { 1621 | if( canInviteUserOne ) 1622 | { 1623 | HudElem_SetRuiArg( file.inviteLastPlayedUnitFrame0, "unitframeFooterText", "#INVITE_PLAYER_UNITFRAME" ) 1624 | Hud_SetLocked( file.inviteLastPlayedUnitFrame0, false ) 1625 | } 1626 | else 1627 | { 1628 | HudElem_SetRuiArg( file.inviteLastPlayedUnitFrame0, "unitframeFooterText", "" ) 1629 | Hud_SetLocked( file.inviteLastPlayedUnitFrame0, true ) 1630 | } 1631 | } 1632 | 1633 | int hardwareID = expect int( GetPersistentVar( "lastGameSquadStats[" + file.lastPlayedPlayerPersistenceIndex0 + "].hardwareID" ) ) 1634 | string platformString = CrossplayUserOptIn() ? PlatformIDToIconString( hardwareID ) : "" 1635 | HudElem_SetRuiArg( file.inviteLastPlayedUnitFrame0, "platformString", platformString ) 1636 | } 1637 | 1638 | Hud_SetVisible( file.inviteLastPlayedUnitFrame0, isVisibleButton0 ) 1639 | 1640 | 1641 | if ( isVisibleButton1 ) 1642 | { 1643 | if ( file.lastPlayedPlayerPersistenceIndex1 == -1 ) 1644 | return 1645 | 1646 | string namePlayer1 = expect string( GetPersistentVar( "lastGameSquadStats[" + file.lastPlayedPlayerPersistenceIndex1 + "].playerName" ) ) 1647 | HudElem_SetRuiArg( file.inviteLastPlayedUnitFrame1, "name", namePlayer1 ) 1648 | 1649 | int characterGUID = GetPersistentVarAsInt( "lastGameSquadStats[" + file.lastPlayedPlayerPersistenceIndex1 + "].character" ) 1650 | if ( IsValidItemFlavorGUID( characterGUID ) ) 1651 | { 1652 | ItemFlavor squadCharacterClass = GetItemFlavorByGUID( characterGUID ) 1653 | HudElem_SetRuiArg( file.inviteLastPlayedUnitFrame1, "icon", CharacterClass_GetGalleryPortrait( squadCharacterClass ), eRuiArgType.IMAGE ) 1654 | } 1655 | 1656 | if ( UITime() - file.lastPlayedPlayerInviteSentTimestamp1 > INVITE_LAST_TIMEOUT ) 1657 | { 1658 | if( canInviteUserTwo ) 1659 | { 1660 | HudElem_SetRuiArg( file.inviteLastPlayedUnitFrame1, "unitframeFooterText", "#INVITE_PLAYER_UNITFRAME" ) 1661 | Hud_SetLocked( file.inviteLastPlayedUnitFrame1, false ) 1662 | } 1663 | else 1664 | { 1665 | HudElem_SetRuiArg( file.inviteLastPlayedUnitFrame1, "unitframeFooterText", "" ) 1666 | Hud_SetLocked( file.inviteLastPlayedUnitFrame1, true ) 1667 | } 1668 | } 1669 | 1670 | int hardwareID = expect int( GetPersistentVar( "lastGameSquadStats[" + file.lastPlayedPlayerPersistenceIndex1 + "].hardwareID" ) ) 1671 | string platformString = CrossplayUserOptIn() ? PlatformIDToIconString( hardwareID ) : "" 1672 | HudElem_SetRuiArg( file.inviteLastPlayedUnitFrame1, "platformString", platformString ) 1673 | } 1674 | 1675 | Hud_SetVisible( file.inviteLastPlayedUnitFrame1, isVisibleButton1 ) 1676 | Hud_SetVisible( file.inviteLastPlayedHeader, isVisibleButton0 || isVisibleButton1 ) 1677 | 1678 | if ( shouldUpdateDpadNav ) 1679 | { 1680 | UpdateLastSquadDpadNav() 1681 | } 1682 | 1683 | 1684 | 1685 | ToolTipData toolTipData0 1686 | toolTipData0.tooltipStyle = eTooltipStyle.BUTTON_PROMPT 1687 | 1688 | ToolTipData toolTipData1 1689 | toolTipData1.tooltipStyle = eTooltipStyle.BUTTON_PROMPT 1690 | 1691 | if ( !IsSocialPopupActive() ) 1692 | { 1693 | if ( UITime() - file.lastPlayedPlayerInviteSentTimestamp0 > INVITE_LAST_TIMEOUT ) 1694 | { 1695 | if( canInviteUserOne ) 1696 | { 1697 | toolTipData0.actionHint1 = "#A_BUTTON_INVITE" 1698 | toolTipData0.actionHint2 = "#X_BUTTON_INSPECT" 1699 | 1700 | string friendNucleus = file.lastPlayedPlayerNucleusID0 1701 | if ( ClubIsValid() && ClubGetMyMemberRank() >= CLUB_RANK_CAPTAIN && !Clubs_IsUserAClubmate(friendNucleus) ) 1702 | toolTipData0.actionHint3 = "#LAST_SQUAD_BUTTON_CLUB_INVITE" 1703 | 1704 | } 1705 | else 1706 | { 1707 | toolTipData0.actionHint1 = "#X_BUTTON_INSPECT" 1708 | 1709 | string friendNucleus = file.lastPlayedPlayerNucleusID0 1710 | if ( ClubIsValid() && ClubGetMyMemberRank() >= CLUB_RANK_CAPTAIN && !Clubs_IsUserAClubmate(friendNucleus) ) 1711 | toolTipData0.actionHint2 = "#LAST_SQUAD_BUTTON_CLUB_INVITE" 1712 | 1713 | } 1714 | 1715 | Hud_SetToolTipData( file.inviteLastPlayedUnitFrame0, toolTipData0 ) 1716 | } 1717 | else if ( UITime() - file.lastPlayedPlayerInviteSentTimestamp0 <= INVITE_LAST_TIMEOUT ) 1718 | { 1719 | toolTipData0.actionHint1 = "#X_BUTTON_INSPECT" 1720 | Hud_SetToolTipData( file.inviteLastPlayedUnitFrame0, toolTipData0 ) 1721 | } 1722 | 1723 | if ( UITime() - file.lastPlayedPlayerInviteSentTimestamp1 > INVITE_LAST_TIMEOUT ) 1724 | { 1725 | if( canInviteUserTwo ) 1726 | { 1727 | toolTipData1.actionHint1 = "#A_BUTTON_INVITE" 1728 | toolTipData1.actionHint2 = "#X_BUTTON_INSPECT" 1729 | 1730 | string friendNucleus = file.lastPlayedPlayerNucleusID1 1731 | if ( ClubIsValid() && ClubGetMyMemberRank() >= CLUB_RANK_CAPTAIN && !Clubs_IsUserAClubmate(friendNucleus) ) 1732 | toolTipData1.actionHint3 = "#LAST_SQUAD_BUTTON_CLUB_INVITE" 1733 | 1734 | 1735 | } 1736 | else 1737 | { 1738 | toolTipData1.actionHint1 = "#X_BUTTON_INSPECT" 1739 | 1740 | string friendNucleus = file.lastPlayedPlayerNucleusID1 1741 | if ( ClubIsValid() && ClubGetMyMemberRank() >= CLUB_RANK_CAPTAIN && !Clubs_IsUserAClubmate(friendNucleus) ) 1742 | toolTipData1.actionHint2 = "#LAST_SQUAD_BUTTON_CLUB_INVITE" 1743 | 1744 | } 1745 | 1746 | Hud_SetToolTipData( file.inviteLastPlayedUnitFrame1, toolTipData1 ) 1747 | } 1748 | else if ( UITime() - file.lastPlayedPlayerInviteSentTimestamp1 <= INVITE_LAST_TIMEOUT ) 1749 | { 1750 | toolTipData1.actionHint1 = "#X_BUTTON_INSPECT" 1751 | Hud_SetToolTipData( file.inviteLastPlayedUnitFrame1, toolTipData1 ) 1752 | } 1753 | } 1754 | else 1755 | { 1756 | Hud_ClearToolTipData( file.inviteLastPlayedUnitFrame1 ) 1757 | Hud_ClearToolTipData( file.inviteLastPlayedUnitFrame0 ) 1758 | } 1759 | } 1760 | 1761 | 1762 | void function ClientToUI_PartyMemberJoinedOrLeft( string leftSpotUID, string leftSpotEAID, string leftSpotHardware, string leftSpotUnspoofedHardware, string leftSpotName, bool leftSpotInMatch, string rightSpotUID, string rightSpotEAID, string rightSpotHardware, string rightSpotUnspoofedHardware, string rightSpotName, bool rightSpotInMatch ) 1763 | { 1764 | bool personInLeftSpot = leftSpotUID.len() > 0 1765 | bool persinInRightSpot = rightSpotUID.len() > 0 1766 | 1767 | file.friendInLeftSpot.id = leftSpotUID 1768 | file.friendInLeftSpot.hardware = leftSpotHardware 1769 | file.friendInLeftSpot.name = leftSpotName 1770 | file.friendInLeftSpot.ingame = leftSpotInMatch 1771 | file.friendInLeftSpot.eadpData = CreateEADPDataFromEAID( leftSpotEAID ) 1772 | 1773 | file.friendInRightSpot.id = rightSpotUID 1774 | file.friendInRightSpot.hardware = rightSpotHardware 1775 | file.friendInRightSpot.name = rightSpotName 1776 | file.friendInRightSpot.ingame = rightSpotInMatch 1777 | file.friendInRightSpot.eadpData = CreateEADPDataFromEAID( rightSpotEAID ) 1778 | 1779 | file.personInLeftSpot = personInLeftSpot 1780 | file.personInRightSlot = persinInRightSpot 1781 | 1782 | file.leftWasReady = file.leftWasReady && personInLeftSpot 1783 | file.rightWasReady = file.rightWasReady && persinInRightSpot 1784 | 1785 | file.unspoofedHardwareForLeftSlot = leftSpotUnspoofedHardware 1786 | file.unspoofedHardwareForRightSlot = rightSpotUnspoofedHardware 1787 | UpdateLobbyButtons() 1788 | } 1789 | 1790 | 1791 | bool function CanActivateReadyButton() 1792 | { 1793 | if ( IsConnectingToMatch() ) 1794 | return false 1795 | 1796 | 1797 | 1798 | if ( !file.skipDialogCheckForActivateReadyButton && IsDialog( GetActiveMenu() ) ) 1799 | return false 1800 | 1801 | bool isReady = GetConVarBool( "party_readyToSearch" ) 1802 | 1803 | 1804 | if ( isReady ) 1805 | return true 1806 | 1807 | if ( !Lobby_IsPlaylistAvailable( GetSelectedPlaylist() ) ) 1808 | return false 1809 | 1810 | #if PS5_PROG 1811 | 1812 | if ( PS5_WaitForMatchmakingToStart() ) 1813 | return false 1814 | #endif 1815 | 1816 | return true 1817 | } 1818 | 1819 | 1820 | string function GetSelectedPlaylist() 1821 | { 1822 | return IsPartyLeader() ? file.selectedPlaylist : GetParty().playlistName 1823 | } 1824 | 1825 | 1826 | int function Lobby_GetPlaylistState( string playlistName ) 1827 | { 1828 | if ( playlistName == "" ) 1829 | return ePlaylistState.NO_PLAYLIST 1830 | 1831 | if ( IsPrivateMatchLobby() ) 1832 | { 1833 | if ( GetPlaylistVarBool( playlistName, "private_match", false ) ) 1834 | return ePlaylistState.AVAILABLE 1835 | else 1836 | return ePlaylistState.LOCKED 1837 | } 1838 | 1839 | 1840 | if ( DoesPlaylistRequireNewPlayerOrientation( playlistName ) ) 1841 | return ePlaylistState.COMPLETED_ORIENTATION_REQUIRED 1842 | 1843 | 1844 | if ( DoesPlaylistRequireTraining( playlistName ) ) 1845 | { 1846 | if ( GetCurrentPlaylistVarBool( "full_training_required", true ) ) 1847 | return ePlaylistState.COMPLETED_TRAINING_REQUIRED 1848 | else 1849 | return ePlaylistState.TRAINING_REQUIRED 1850 | } 1851 | 1852 | if ( GetPlaylistVarBool ( playlistName, "DEV_Playtest", false )) 1853 | { 1854 | if ( GetPartySize() != 1 ) 1855 | { 1856 | return ePlaylistState.DEV_PLAYTEST 1857 | } 1858 | } 1859 | 1860 | if ( file.currentMaxMatchmakingDelayEndTime > 0 ) 1861 | return ePlaylistState.RANKED_MATCH_ABANDON_DELAY 1862 | 1863 | if ( GetPartySize() > GetMaxTeamSizeForPlaylist( playlistName ) ) 1864 | return ePlaylistState.PARTY_SIZE_OVER 1865 | 1866 | if ( IsRankedPlaylist( playlistName ) ) 1867 | { 1868 | if ( !SharedRanked_PartyHasRankedLevelAccess() ) 1869 | return ePlaylistState.RANKED_LEVEL_REQUIRED 1870 | else if ( !Ranked_PartyMeetsRankedDifferenceRequirements() ) 1871 | return ePlaylistState.RANKED_LARGE_RANK_DIFFERENCE 1872 | else if ( !Ranked_HasBeenInitialized() ) 1873 | return ePlaylistState.RANKED_NOT_INITIALIZED 1874 | } 1875 | 1876 | 1877 | 1878 | 1879 | 1880 | 1881 | 1882 | 1883 | 1884 | 1885 | 1886 | 1887 | 1888 | if ( !PartyHasPlaylistAccountLevelRequired( playlistName ) ) 1889 | return ePlaylistState.ACCOUNT_LEVEL_REQUIRED 1890 | 1891 | if ( IsPlaylistBeingRotated( playlistName ) && !IsPlaylistInActiveRotation( playlistName ) ) 1892 | return ePlaylistState.ROTATION_GROUP_MISMATCH 1893 | 1894 | 1895 | if ( playlistName == "private_match" && !IsTournamentMatchmaking() ) 1896 | return ePlaylistState.LOCKED 1897 | 1898 | 1899 | return ePlaylistState.AVAILABLE 1900 | } 1901 | 1902 | string function Lobby_GetPlaylistStateString( int playlistState ) 1903 | { 1904 | return playlistStateMap[playlistState] 1905 | } 1906 | 1907 | 1908 | void function UpdateReadyButton() 1909 | { 1910 | if( !IsLobby() || !IsConnectedServerInfo() ) 1911 | return 1912 | 1913 | bool isLeader = IsPartyLeader() 1914 | 1915 | bool isReady = GetConVarBool( "party_readyToSearch" ) 1916 | string buttonText 1917 | string buttonDescText 1918 | float buttonDescFontHeight = 0.0 1919 | 1920 | float timeRemaining = 0 1921 | if ( file.currentMaxMatchmakingDelayEndTime > 0 ) 1922 | timeRemaining = file.currentMaxMatchmakingDelayEndTime - UITime() 1923 | 1924 | if ( timeRemaining > 0 ) 1925 | { 1926 | buttonText = "#RANKED_ABANDON_PENALTY_PLAY_BUTTON_LABEL" 1927 | HudElem_SetRuiArg( file.readyButton, "expireTime", ClientTime() + timeRemaining, eRuiArgType.GAMETIME ) 1928 | } 1929 | else 1930 | { 1931 | file.currentMaxMatchmakingDelayEndTime = 0 1932 | if ( isReady ) 1933 | { 1934 | buttonText = IsControllerModeActive() ? "#B_BUTTON_CANCEL" : "#CANCEL" 1935 | } 1936 | else if ( ShouldForceShowModeSelection() ) 1937 | { 1938 | buttonText = IsControllerModeActive() ? "#Y_BUTTON_SELECT" : "#SELECT" 1939 | } 1940 | else 1941 | { 1942 | buttonText = IsControllerModeActive() ? "#Y_BUTTON_READY" : "#READY" 1943 | } 1944 | 1945 | if ( Dev_CommandLineHasParm( "-auto_ezlaunch" ) ) 1946 | { 1947 | buttonDescText = "-auto_ezlaunch" 1948 | buttonDescFontHeight = 24 1949 | } 1950 | 1951 | HudElem_SetRuiArg( file.readyButton, "expireTime", RUI_BADGAMETIME, eRuiArgType.GAMETIME ) 1952 | } 1953 | 1954 | 1955 | HudElem_SetRuiArg( file.readyButton, "isLeader", isLeader ) 1956 | HudElem_SetRuiArg( file.readyButton, "isReady", isReady ) 1957 | HudElem_SetRuiArg( file.readyButton, "buttonText", Localize( buttonText ) ) 1958 | HudElem_SetRuiArg( file.readyButton, "buttonDescText", buttonDescText ) 1959 | HudElem_SetRuiArg( file.readyButton, "buttonDescFontHeight", buttonDescFontHeight ) 1960 | 1961 | bool canActivateReadyButton = CanActivateReadyButton() 1962 | 1963 | Hud_SetLocked( file.readyButton, !canActivateReadyButton ) 1964 | Hud_SetEnabled( file.readyButton, canActivateReadyButton ) 1965 | 1966 | if ( !canActivateReadyButton ) 1967 | { 1968 | ToolTipData toolTipData 1969 | toolTipData.titleText = IsConnectingToMatch() ? "#UNAVAILABLE" : "#READY_UNAVAILABLE" 1970 | toolTipData.descText = IsConnectingToMatch() ? "#LOADINGPROGRESS_CONNECTING" : Lobby_GetPlaylistStateString( Lobby_GetPlaylistState( GetSelectedPlaylist() ) ) 1971 | 1972 | Hud_SetToolTipData( file.readyButton, toolTipData ) 1973 | } 1974 | else 1975 | { 1976 | Hud_ClearToolTipData( file.readyButton ) 1977 | } 1978 | } 1979 | 1980 | 1981 | bool function CanActivateModeButton() 1982 | { 1983 | bool isReady = GetConVarBool( "party_readyToSearch" ) 1984 | bool isLeader = IsPartyLeader() 1985 | 1986 | return !isReady && isLeader 1987 | } 1988 | 1989 | 1990 | bool function HasNewModes() 1991 | { 1992 | if ( !IsFullyConnected() ) 1993 | return false 1994 | 1995 | if ( Playlist_GetNewModeVersion() > GetPersistentVarAsInt( "newModeVersion" ) ) 1996 | return true 1997 | 1998 | string currentLTM = Playlist_GetLTMSlotPlaylist() 1999 | 2000 | if ( ( currentLTM != "" ) && !IsPlaylistBeingRotated( currentLTM ) && ( currentLTM != GetPersistentVar( "lastSeenLobbyLTM" ) ) && Lobby_IsPlaylistAvailable( currentLTM ) ) 2001 | return true 2002 | 2003 | return false 2004 | } 2005 | 2006 | 2007 | string function GetCrossplayStatus() 2008 | { 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | if ( GetPlayerHardware() == "" ) 2017 | { 2018 | return "" 2019 | } 2020 | 2021 | if ( !CrossplayEnabled() ) 2022 | { 2023 | return "" 2024 | } 2025 | 2026 | if ( !CrossplayUserOptIn() || !IsPartyAllowedCrossplay() ) 2027 | { 2028 | 2029 | 2030 | return Localize( "#CROSSPLAY_N_ONLY", Localize( PlatformIDToIconString( GetHardwareFromName( GetPlayerHardware() ) ) ) ) 2031 | } 2032 | 2033 | foreach ( index, member in GetParty().members ) 2034 | { 2035 | if ( GetHardwareFromName( member.hardware ) == HARDWARE_PC ) 2036 | return Localize( "#CROSSPLAY_N", Localize( PlatformIDToIconString( HARDWARE_PC ) ) ) 2037 | } 2038 | 2039 | #if PC_PROG 2040 | return Localize( "#CROSSPLAY_N", Localize( "#CROSSPLAY_ICON_PC" ) ) 2041 | #else 2042 | return Localize( "#CROSSPLAY_N", Localize( "#CROSSPLAY_ICON_CONTROLLER" ) ) 2043 | #endif 2044 | } 2045 | 2046 | void function RestartMatchmakingAfterRotation( string previousPlaylistName ) 2047 | { 2048 | EndSignal( uiGlobal.signalDummy, "CleanupInGameMenus" ) 2049 | EndSignal( uiGlobal.signalDummy, "LevelShutdown" ) 2050 | 2051 | int retryCount = 5 2052 | string activeUISlot = GetPlaylistVarString( previousPlaylistName, "ui_slot", "" ) 2053 | string nextUISlot = "" 2054 | 2055 | 2056 | if ( IsPartyLeader() ) 2057 | { 2058 | while ( activeUISlot != nextUISlot && retryCount > 0 ) 2059 | { 2060 | WaitFrame() 2061 | Lobby_UpdateSelectedPlaylistUsingUISlot( previousPlaylistName ) 2062 | nextUISlot = GetPlaylistVarString( Lobby_GetSelectedPlaylist(), "ui_slot", "" ) 2063 | --retryCount 2064 | } 2065 | } 2066 | 2067 | 2068 | 2069 | if ( activeUISlot == nextUISlot ) 2070 | { 2071 | printf( "Automatically trying to resume matchmaking with playlist '%s' (previously '%s' in ui_slot '%s')", Lobby_GetSelectedPlaylist(), previousPlaylistName, activeUISlot ) 2072 | Lobby_StartMatchmaking() 2073 | } 2074 | else 2075 | { 2076 | printf( "Could not find playlist for ui_slot '%s' to replace '%s'", activeUISlot, previousPlaylistName ) 2077 | } 2078 | } 2079 | 2080 | void function UpdateModeButton() 2081 | { 2082 | if ( !IsConnected() ) 2083 | return 2084 | 2085 | if( !IsLobby() ) 2086 | return 2087 | 2088 | string visiblePlaylistValue = GetConVarString( "match_visiblePlaylists" ) 2089 | int partySize = GetPartySize() 2090 | bool cuiIsValid = false 2091 | 2092 | #if CONSOLE_PROG 2093 | if( Console_IsSignedIn() && !Console_SkippedSignIn() ) 2094 | #endif 2095 | { 2096 | cuiIsValid = GetUserInfo( GetPlayerHardware(), GetPlayerUID() ) != null 2097 | } 2098 | 2099 | if ( visiblePlaylistValue != file.lastVisiblePlaylistValue || partySize != file.lastPartySize || cuiIsValid != file.lastCuiIsValid ) 2100 | { 2101 | Lobby_UpdatePlayPanelPlaylists() 2102 | file.lastVisiblePlaylistValue = visiblePlaylistValue 2103 | file.lastPartySize = partySize 2104 | file.lastCuiIsValid = cuiIsValid 2105 | } 2106 | 2107 | Hud_SetLocked( file.modeButton, !CanActivateModeButton() ) 2108 | 2109 | bool isReady = GetConVarBool( "party_readyToSearch" ) 2110 | Hud_SetEnabled( file.modeButton, !isReady && CanActivateModeButton() ) 2111 | HudElem_SetRuiArg( file.modeButton, "isReady", isReady ) 2112 | HudElem_SetRuiArg( file.gamemodeSelectButton, "isReady", isReady ) 2113 | HudElem_SetRuiArg( file.gamemodeSelectButton, "crossplayStatus", GetCrossplayStatus() ) 2114 | 2115 | bool hasNewModes = HasNewModes() 2116 | 2117 | Hud_SetNew( file.gamemodeSelectButton, hasNewModes && (HasLocalPlayerCompletedNewPlayerOrientation() || IsLocalPlayerExemptFromNewPlayerOrientation()) ) 2118 | 2119 | 2120 | 2121 | 2122 | if ( file.wasReady != isReady ) 2123 | { 2124 | UISize screenSize = GetScreenSize() 2125 | 2126 | float scale = float( GetScreenSize().width ) / 1920.0 2127 | int maxDist = int( screenSize.height * 0.08 ) 2128 | int maxDistNX = int( screenSize.height * 0.1 ) 2129 | 2130 | int x = Hud_GetX( file.modeButton ) 2131 | int y = isReady ? Hud_GetBaseY( file.modeButton ) + maxDist : Hud_GetBaseY( file.modeButton ) 2132 | int yNX = isReady ? Hud_GetBaseY( file.modeButton ) + maxDistNX : Hud_GetBaseY( file.modeButton ) 2133 | 2134 | int currentY = Hud_GetY( file.modeButton ) 2135 | int diff = abs( currentY - y ) 2136 | 2137 | #if NX_PROG || PC_PROG_NX_UI 2138 | if ( IsNxHandheldMode() ) 2139 | { 2140 | float duration = 0.15 * (float( diff ) / (float( maxDistNX ) * scale)) 2141 | Hud_MoveOverTime( file.modeButton, x, yNX, 0.15 ) 2142 | } 2143 | else 2144 | { 2145 | float duration = 0.15 * (float( diff ) / float( maxDist )) 2146 | Hud_MoveOverTime( file.modeButton, x, y, 0.15 ) 2147 | } 2148 | #else 2149 | float duration = 0.15 * (float( diff ) / float( maxDist )) 2150 | Hud_MoveOverTime( file.modeButton, x, y, 0.15 ) 2151 | #endif 2152 | 2153 | file.wasReady = isReady 2154 | } 2155 | 2156 | bool isLeader = IsPartyLeader() 2157 | string playlistName = isLeader ? (isReady ? GetConVarString( "match_playlist" ) : file.selectedPlaylist) : GetParty().playlistName 2158 | 2159 | UpdatePartyMemberNotice( playlistName, isLeader ) 2160 | 2161 | 2162 | string invalidPlaylistText = isLeader ? "#SELECT_PLAYLIST" : "#PARTY_LEADER_CHOICE" 2163 | string name = GetPlaylistVarString( playlistName, "name", invalidPlaylistText ) 2164 | HudElem_SetRuiArg( file.modeButton, "buttonText", Localize( name ) + file.selectedPlaylistMods ) 2165 | #if PS4_PROG || PS5_PROG 2166 | Sony_SetLobbyModeName( name ) 2167 | #endif 2168 | 2169 | bool useGamemodeSelect = GamemodeSelect_IsEnabled() && !(ShouldDisplayOptInOptions() && IsOptInEnabled()) 2170 | 2171 | Hud_SetVisible( file.modeButton, !useGamemodeSelect ) 2172 | Hud_SetVisible( file.gamemodeSelectButton, useGamemodeSelect ) 2173 | 2174 | RuiSetBool( Hud_GetRui( file.readyButton ), "showReadyFrame", !useGamemodeSelect ) 2175 | 2176 | if ( useGamemodeSelect && playlistName != "" ) 2177 | { 2178 | if ( ShouldTryToCancelMatchmakingFromInvalidPlaylistChange( playlistName, isReady ) ) 2179 | { 2180 | CancelMatchmaking() 2181 | Remote_ServerCallFunction( "ClientCallback_CancelMatchSearch" ) 2182 | EmitUISound( SOUND_STOP_MATCHMAKING_1P ) 2183 | 2184 | 2185 | 2186 | thread RestartMatchmakingAfterRotation( playlistName ) 2187 | } 2188 | 2189 | GamemodeSelect_UpdateSelectButton( file.gamemodeSelectButton, playlistName ) 2190 | HudElem_SetRuiArg( file.gamemodeSelectButton, "alwaysShowDesc", true ) 2191 | HudElem_SetRuiArg( file.gamemodeSelectButton, "isPartyLeader", isLeader ) 2192 | 2193 | HudElem_SetRuiArg( file.gamemodeSelectButton, "modeLockedReason", "" ) 2194 | Hud_SetLocked( file.gamemodeSelectButton, !CanActivateModeButton() ) 2195 | 2196 | 2197 | int mapIdx = playlistName != "" ? GetPlaylistActiveMapRotationIndex( playlistName ) : -1 2198 | string rotationMapName = GetPlaylistMapVarString( playlistName, mapIdx, "map_name", "" ) 2199 | int rotationTimeLeft = -1 2200 | 2201 | string currentPlaylist = Lobby_GetSelectedPlaylist() 2202 | if ( IsPlaylistBeingRotated( playlistName ) ) 2203 | { 2204 | string ornull rotationName = GetPlaylistRotationNameFromPlaylist( playlistName ) 2205 | rotationTimeLeft = GetPlaylistRotationNextTime( rotationName ? expect string( rotationName ) : "" ) - GetUnixTimestamp() 2206 | } 2207 | else if ( rotationMapName != "" ) 2208 | { 2209 | rotationTimeLeft = GetPlaylistActiveMapRotationTimeLeft( playlistName ) 2210 | } 2211 | 2212 | if ( rotationTimeLeft > 0 ) 2213 | { 2214 | string nextRotationTime = GetPlaylistRotationNextTimeFormatedString( rotationTimeLeft ) 2215 | HudElem_SetRuiArg( file.gamemodeSelectButton, "modeDescText", Localize( rotationMapName ).toupper() ) 2216 | HudElem_SetRuiArg( file.gamemodeSelectButton, "modeRotationTime", nextRotationTime ) 2217 | 2218 | #if NX_PROG || PC_PROG_NX_UI 2219 | Hud_ClearToolTipData( file.gamemodeSelectButton ) 2220 | #endif 2221 | } 2222 | else 2223 | { 2224 | 2225 | 2226 | HudElem_SetRuiArg( file.gamemodeSelectButton, "modeRotationTime", "" ) 2227 | 2228 | string modeDescText = playlistName == PLAYLIST_NEW_PLAYER_ORIENTATION ? Localize( "#PL_ORIENTATION_MATCH" ) : "" 2229 | 2230 | 2231 | 2232 | HudElem_SetRuiArg( file.gamemodeSelectButton, "modeDescText", modeDescText ) 2233 | 2234 | #if NX_PROG || PC_PROG_NX_UI 2235 | ToolTipData td 2236 | td.titleText = Localize( GetPlaylistMapVarString( playlistName, mapIdx, "name", "#HUD_UNKNOWN" ) ).toupper() 2237 | td.descText = Localize( GetPlaylistMapVarString( playlistName, mapIdx, "description", "#HUD_UNKNOWN" ) ) 2238 | Hud_SetToolTipData( file.gamemodeSelectButton, td ) 2239 | #endif 2240 | } 2241 | } 2242 | 2243 | if ( file.lastPlaylistDisplayed != playlistName ) 2244 | { 2245 | Lobby_UpdateLoadscreenFromPlaylist() 2246 | } 2247 | 2248 | if ( CanRunClientScript() ) 2249 | RunClientScript( "Lobby_SetBannerSkin", playlistName ) 2250 | 2251 | file.lastPlaylistDisplayed = playlistName 2252 | } 2253 | 2254 | 2255 | 2256 | void function UpdatePartyMemberNotice( string playlistName, bool isLeader ) 2257 | { 2258 | if ( playlistName == PLAYLIST_NEW_PLAYER_ORIENTATION && GetPartySize() > 1 && HasLocalPlayerCompletedNewPlayerOrientation() ) 2259 | { 2260 | string header 2261 | string message 2262 | 2263 | if ( isLeader ) 2264 | { 2265 | header = "#PARTY_MEMBER_NOTICE_NEW_PLAYER_HEADER" 2266 | message = "#PARTY_MEMBER_NOTICE_NEW_PLAYER_MESSAGE" 2267 | } 2268 | else 2269 | { 2270 | header = "#PARTY_MEMBER_NOTICE_NO_PROGRESSION_HEADER" 2271 | message = "#PARTY_MEMBER_NOTICE_NO_PROGRESSION_MESSAGE" 2272 | } 2273 | 2274 | HudElem_SetRuiArg( file.partyMemberNotice, "header", Localize( header ) ) 2275 | HudElem_SetRuiArg( file.partyMemberNotice, "message", Localize( message ) ) 2276 | Hud_SetVisible( file.partyMemberNotice, true ) 2277 | } 2278 | else 2279 | { 2280 | Hud_SetVisible( file.partyMemberNotice, false ) 2281 | } 2282 | } 2283 | 2284 | 2285 | 2286 | bool function ShouldTryToCancelMatchmakingFromInvalidPlaylistChange( string playlistName, bool isReady ) 2287 | { 2288 | 2289 | if ( IsConnectingToMatch() ) 2290 | return false 2291 | 2292 | if ( GetCurrentPlaylistVarBool( "cancel_matchmaking_after_invalid_playlist_change", false ) ) 2293 | return false 2294 | 2295 | if ( Lobby_IsPlaylistAvailable( playlistName ) ) 2296 | return false 2297 | 2298 | if ( !IsFullyConnected() || !IsPersistenceAvailable() ) 2299 | return false 2300 | 2301 | if ( (!AreWeMatchmaking() && !isReady ) ) 2302 | return false 2303 | 2304 | return true 2305 | } 2306 | 2307 | 2308 | void function ResetFillButton() 2309 | { 2310 | if ( !IsLobby() ) 2311 | return 2312 | 2313 | Hud_SetSelected( file.fillButton, file.fillButtonState ) 2314 | SetConVarBool( "party_nofill_selected", !file.fillButtonState ) 2315 | file.fillButtonWasFullSquad = false 2316 | file.fillButtonWasHidden = false 2317 | } 2318 | 2319 | 2320 | void function UpdateFillButton() 2321 | { 2322 | if( !IsLobby() || !IsConnectedServerInfo() ) 2323 | return 2324 | 2325 | Hud_ClearToolTipData( file.fillButton ) 2326 | 2327 | 2328 | bool shouldShowFillButton = DoesPlaylistSupportNoFill( Lobby_GetSelectedPlaylist() ) && IsPartyLeader() 2329 | bool shouldLockFillButton = false 2330 | 2331 | if ( shouldShowFillButton ) 2332 | { 2333 | string fillButtonToolTipText = "#MATCH_TEAM_FILL_DESC" 2334 | 2335 | if ( file.fillButtonWasHidden ) 2336 | { 2337 | ResetFillButton() 2338 | } 2339 | 2340 | if ( AreWeMatchmaking() || IsPreloadingMap() ) 2341 | { 2342 | fillButtonToolTipText = "#MATCH_TEAM_FILL_MATCHMAKING" 2343 | shouldLockFillButton = true 2344 | } 2345 | else if ( GetPartySize() >= Lobby_GetSelectedPlaylistExpectedSquadSize() ) 2346 | { 2347 | fillButtonToolTipText = "#MATCH_TEAM_FILL_ALREADY_FULL" 2348 | shouldLockFillButton = true 2349 | Hud_SetSelected( file.fillButton, false ) 2350 | SetConVarBool( "party_nofill_selected", false ) 2351 | file.fillButtonWasFullSquad = true 2352 | } 2353 | else if ( GetPartySize() < Lobby_GetSelectedPlaylistExpectedSquadSize() && file.fillButtonWasFullSquad ) 2354 | { 2355 | ResetFillButton() 2356 | } 2357 | else 2358 | { 2359 | Hud_SetSelected( file.fillButton, file.fillButtonState ) 2360 | SetConVarBool( "party_nofill_selected", !file.fillButtonState ) 2361 | } 2362 | 2363 | ToolTipData td 2364 | td.descText = fillButtonToolTipText 2365 | Hud_SetToolTipData( file.fillButton, td ) 2366 | 2367 | } 2368 | else 2369 | { 2370 | shouldLockFillButton = true 2371 | Hud_SetSelected( file.fillButton, false ) 2372 | SetConVarBool( "party_nofill_selected", false ) 2373 | file.fillButtonWasHidden = true 2374 | } 2375 | 2376 | Hud_SetVisible( file.fillButton, shouldShowFillButton ) 2377 | Hud_SetEnabled( file.fillButton, !shouldLockFillButton ) 2378 | Hud_SetLocked( file.fillButton, shouldLockFillButton ) 2379 | } 2380 | 2381 | 2382 | bool function IsPreloadingMap() 2383 | { 2384 | string compareSting = "#MATCHMAKING_LOADING" 2385 | string mmStatus = GetMyMatchmakingStatus() 2386 | return ( mmStatus.len() >= compareSting.len() && mmStatus.slice( 0, compareSting.len() ) == compareSting ) 2387 | } 2388 | void function FillButton_OnActivate( var button ) 2389 | { 2390 | file.fillButtonState = !( Hud_IsSelected( button ) ) 2391 | Hud_SetSelected( button, file.fillButtonState ) 2392 | 2393 | SetConVarBool( "party_nofill_selected", !file.fillButtonState ) 2394 | printt( "SHOULD WE FILL THE SQUAD? " + file.fillButtonState ) 2395 | } 2396 | 2397 | 2398 | void function ModeButton_OnActivate( var button ) 2399 | { 2400 | if ( Hud_IsLocked( button ) || !CanActivateModeButton() ) 2401 | return 2402 | 2403 | Remote_ServerCallFunction( "ClientCallback_ViewedModes" ) 2404 | file.newModesAcknowledged = true 2405 | 2406 | AdvanceMenu( GetMenu( "ModeSelectDialog" ) ) 2407 | } 2408 | 2409 | 2410 | void function GamemodeSelectButton_OnActivate( var button ) 2411 | { 2412 | if ( Hud_IsLocked( button ) || !CanActivateModeButton() ) 2413 | return 2414 | 2415 | Hud_SetVisible( file.gamemodeSelectButton, false ) 2416 | Hud_SetVisible( file.readyButton, false ) 2417 | 2418 | string currentLTM = Playlist_GetLTMSlotPlaylist() 2419 | bool resetMode = Lobby_IsPlaylistAvailable( currentLTM ) 2420 | if ( (currentLTM != "") && (currentLTM != GetPersistentVar( "lastSeenLobbyLTM" )) && Lobby_IsPlaylistAvailable( currentLTM ) ) 2421 | { 2422 | GamemodeSelect_SetFeaturedSlot( "ltm", "#HEADER_NEW_MODE" ) 2423 | } 2424 | else 2425 | { 2426 | array currentEvents = GetActiveBuffetEventArray( GetUnixTimestamp() ) 2427 | foreach ( event in currentEvents ) 2428 | { 2429 | var sBlock = ItemFlavor_GetSettingsBlock( event ) 2430 | string highlight = GetSettingsBlockString( sBlock, "highlightGamemodeSelectorSlot" ) 2431 | if ( highlight != "" && highlight != GetPersistentVar( "lastSeenLobbyLTM" ) ) 2432 | { 2433 | GamemodeSelect_SetFeaturedSlot( highlight, "#HEADER_NEW_EVENT" ) 2434 | resetMode = true 2435 | break 2436 | } 2437 | } 2438 | } 2439 | 2440 | if ( resetMode ) 2441 | Remote_ServerCallFunction( "ClientCallback_ViewedModes" ) 2442 | 2443 | AdvanceMenu( GetMenu( "GamemodeSelectDialog" ) ) 2444 | } 2445 | 2446 | 2447 | void function GamemodeSelectButton_OnGetFocus( var button ) 2448 | { 2449 | GamemodeSelect_PlayVideo( button, file.selectedPlaylist ) 2450 | } 2451 | 2452 | 2453 | void function GamemodeSelectButton_OnLoseFocus( var button ) 2454 | { 2455 | 2456 | } 2457 | 2458 | 2459 | void function Lobby_OnGamemodeSelectClose() 2460 | { 2461 | Hud_SetVisible( file.gamemodeSelectButton, true ) 2462 | Hud_SetVisible( file.readyButton, true ) 2463 | 2464 | SocialEventUpdate() 2465 | } 2466 | 2467 | 2468 | void function PlayPanel_OnNavBack( var panel ) 2469 | { 2470 | if ( !IsControllerModeActive() ) 2471 | return 2472 | 2473 | bool isReady = GetConVarBool( "party_readyToSearch" ) 2474 | if ( !AreWeMatchmaking() && !isReady ) 2475 | return 2476 | 2477 | CancelMatchmaking() 2478 | Remote_ServerCallFunction( "ClientCallback_CancelMatchSearch" ) 2479 | } 2480 | 2481 | 2482 | bool function ReadyShortcut_OnActivate( var panel ) 2483 | { 2484 | if ( AreWeMatchmaking() ) 2485 | return false 2486 | 2487 | ReadyButton_OnActivate( file.readyButton ) 2488 | return true 2489 | } 2490 | 2491 | 2492 | bool function SeasonShortcut_OnActivate( var panel ) 2493 | { 2494 | TabData lobbyTabData = GetTabDataForPanel( GetMenu( "LobbyMenu" ) ) 2495 | 2496 | if ( Hud_IsFocused( file.friendButton0 ) || Hud_IsFocused( file.friendButton1 ) ) 2497 | return false 2498 | 2499 | ActivateTab( lobbyTabData, Tab_GetTabIndexByBodyName( lobbyTabData, "SeasonPanel" ) ) 2500 | EmitUISound( "UI_Menu_ApexTab_Select" ) 2501 | return true 2502 | } 2503 | 2504 | 2505 | bool function ShouldForceShowModeSelection() 2506 | { 2507 | if ( !GetCurrentPlaylistVarBool( "force_show_mode_selection", true ) ) 2508 | return false 2509 | 2510 | if ( Hud_IsLocked( file.modeButton ) ) 2511 | return false 2512 | 2513 | if ( !CanActivateModeButton() ) 2514 | return false 2515 | 2516 | if ( !HasNewModes() ) 2517 | return false 2518 | 2519 | if ( file.newModesAcknowledged ) 2520 | return false 2521 | 2522 | if ( !HasLocalPlayerCompletedTraining() && !IsLocalPlayerExemptFromTraining() ) 2523 | return false 2524 | 2525 | 2526 | if ( !HasLocalPlayerCompletedNewPlayerOrientation() && !IsLocalPlayerExemptFromNewPlayerOrientation() ) 2527 | return false 2528 | 2529 | 2530 | if ( IsSelectedPlaylistQuestMission() ) 2531 | return false 2532 | 2533 | return true 2534 | } 2535 | 2536 | 2537 | void function ReadyButton_OnActivate( var button ) 2538 | { 2539 | if ( ShouldForceShowModeSelection() ) 2540 | { 2541 | if ( GamemodeSelect_IsEnabled() ) 2542 | GamemodeSelectButton_OnActivate( file.gamemodeSelectButton ) 2543 | else 2544 | ModeButton_OnActivate( file.modeButton ) 2545 | return 2546 | } 2547 | 2548 | if ( Hud_IsLocked( file.readyButton ) || !CanActivateReadyButton() ) 2549 | return 2550 | 2551 | bool isReady = GetConVarBool( "party_readyToSearch" ) 2552 | bool requireConsensusForSearch = GetConVarBool( "party_requireConsensusForSearch" ) 2553 | 2554 | if ( AreWeMatchmaking() || isReady ) 2555 | { 2556 | CancelMatchmaking() 2557 | Remote_ServerCallFunction( "ClientCallback_CancelMatchSearch" ) 2558 | EmitUISound( SOUND_STOP_MATCHMAKING_1P ) 2559 | } 2560 | else 2561 | { 2562 | if ( !IsGameFullyInstalled() || HasNonFullyInstalledAssetsLoaded() ) 2563 | { 2564 | ConfirmDialogData data 2565 | data.headerText = "#TEXTURE_STREAM_HEADER" 2566 | data.messageText = Localize( "#TEXTURE_STREAM_MESSAGE", floor( GetGameFullyInstalledProgress() * 100 ) ) 2567 | data.yesText = ["#TEXTURE_STREAM_PLAY", "#TEXTURE_STREAM_PLAY_PC"] 2568 | data.noText = ["#TEXTURE_STREAM_WAIT", "#TEXTURE_STREAM_WAIT_PC"] 2569 | if ( GetGameFullyInstalledProgress() >= 1 && HasNonFullyInstalledAssetsLoaded() ) 2570 | { 2571 | 2572 | data.headerText = "#TEXTURE_STREAM_REBOOT_HEADER" 2573 | data.messageText = "#TEXTURE_STREAM_REBOOT_MESSAGE" 2574 | data.yesText = ["#TEXTURE_STREAM_REBOOT", "#TEXTURE_STREAM_REBOOT_PC"] 2575 | data.noText = ["#TEXTURE_STREAM_PLAY_ON_NO", "#TEXTURE_STREAM_PLAY_PC"] 2576 | } 2577 | 2578 | data.resultCallback = void function ( int result ) : () 2579 | { 2580 | if ( GetGameFullyInstalledProgress() >= 1 && HasNonFullyInstalledAssetsLoaded() ) 2581 | { 2582 | 2583 | if ( result == eDialogResult.YES ) 2584 | { 2585 | 2586 | ClientCommand( "disconnect" ) 2587 | return 2588 | } 2589 | } 2590 | else if ( result != eDialogResult.YES ) 2591 | { 2592 | 2593 | return 2594 | } 2595 | 2596 | 2597 | ReadyButtonActivate() 2598 | 2599 | 2600 | file.skipDialogCheckForActivateReadyButton = false 2601 | } 2602 | 2603 | if ( !IsDialog( GetActiveMenu() ) ) 2604 | { 2605 | 2606 | 2607 | file.skipDialogCheckForActivateReadyButton = true 2608 | OpenConfirmDialogFromData( data ) 2609 | } 2610 | return 2611 | } 2612 | 2613 | ReadyButtonActivate() 2614 | } 2615 | } 2616 | 2617 | void function Lobby_StartMatchmaking() 2618 | { 2619 | var jsonTable = { 2620 | map = GetPlaylistRotationGroup() 2621 | next_map_time = GetPlaylistRotationNextTime() 2622 | } 2623 | PIN_UIInteraction_Select( GetActiveMenuName(), "readybutton", jsonTable ); 2624 | 2625 | if ( GetConVarBool( "match_teamNoFill" ) && DoesPlaylistSupportNoFillTeams( file.selectedPlaylist ) ) 2626 | StartMatchmakingWithNoFillTeams( file.selectedPlaylist ) 2627 | else 2628 | StartMatchmakingStandard( file.selectedPlaylist ) 2629 | } 2630 | 2631 | void function ReadyButtonActivate() 2632 | { 2633 | if ( Hud_IsLocked( file.readyButton ) || !CanActivateReadyButton() ) 2634 | { 2635 | return 2636 | } 2637 | else 2638 | { 2639 | EmitUISound( SOUND_START_MATCHMAKING_1P ) 2640 | Lobby_StartMatchmaking() 2641 | } 2642 | } 2643 | 2644 | 2645 | void function InviteFriendsButton_OnActivate( var button ) 2646 | { 2647 | if ( Hud_IsLocked( button ) ) 2648 | return 2649 | 2650 | #if PC_PROG 2651 | if ( !MeetsAgeRequirements() ) 2652 | { 2653 | ConfirmDialogData dialogData 2654 | dialogData.headerText = "#UNAVAILABLE" 2655 | dialogData.messageText = "#ORIGIN_UNDERAGE_ONLINE" 2656 | dialogData.contextImage = $"ui/menu/common/dialog_notice" 2657 | 2658 | OpenOKDialogFromData( dialogData ) 2659 | return 2660 | } 2661 | #endif 2662 | 2663 | thread CreatePartyAndInviteFriends() 2664 | } 2665 | 2666 | 2667 | void function InviteLastPlayedButton_OnActivate( var button ) 2668 | { 2669 | if ( Hud_IsLocked( button ) ) 2670 | return 2671 | 2672 | int scriptID = int( Hud_GetScriptID( button ) ) 2673 | 2674 | #if PC_PROG 2675 | if ( !MeetsAgeRequirements() ) 2676 | { 2677 | ConfirmDialogData dialogData 2678 | dialogData.headerText = "#UNAVAILABLE" 2679 | dialogData.messageText = "#ORIGIN_UNDERAGE_ONLINE" 2680 | dialogData.contextImage = $"ui/menu/common/dialog_notice" 2681 | 2682 | OpenOKDialogFromData( dialogData ) 2683 | return 2684 | } 2685 | #endif 2686 | 2687 | InviteLastPlayedToParty( scriptID ) 2688 | if ( button == file.inviteLastPlayedUnitFrame0 ) 2689 | file.lastPlayedPlayerInviteSentTimestamp0 = UITime() 2690 | if ( button == file.inviteLastPlayedUnitFrame1 ) 2691 | file.lastPlayedPlayerInviteSentTimestamp1 = UITime() 2692 | 2693 | HudElem_SetRuiArg( button, "unitframeFooterText", "#INVITE_PLAYER_INVITED" ) 2694 | Hud_SetLocked( button, true ) 2695 | } 2696 | 2697 | bool function IsSamePlatform(int hardwareID1, int hardwareID2 ) 2698 | { 2699 | #if PLAYSTATION_PROG 2700 | if( ( hardwareID1 == HARDWARE_PS4 || hardwareID1 == HARDWARE_PS5 ) && ( hardwareID2 == HARDWARE_PS4 || hardwareID2 == HARDWARE_PS5 ) ) 2701 | return true 2702 | #endif 2703 | 2704 | #if XBOX_PROG 2705 | if( ( hardwareID1 == HARDWARE_XBOXONE || hardwareID1 == HARDWARE_XB5 ) && ( hardwareID2 == HARDWARE_XBOXONE || hardwareID2 == HARDWARE_XB5 ) ) 2706 | return true 2707 | #endif 2708 | 2709 | return false 2710 | } 2711 | 2712 | void function InviteLastPlayedToParty( int scriptID ) 2713 | { 2714 | Assert( scriptID == 0 || scriptID == 1 ) 2715 | 2716 | string nucleusID 2717 | string platformUID 2718 | int hardwardID 2719 | 2720 | switch( scriptID ) 2721 | { 2722 | case 0: 2723 | nucleusID = file.lastPlayedPlayerNucleusID0 2724 | platformUID = file.lastPlayedPlayerPlatformUid0 2725 | hardwardID = file.lastPlayedPlayerHardwareID0 2726 | break 2727 | 2728 | case 1: 2729 | nucleusID = file.lastPlayedPlayerNucleusID1 2730 | platformUID = file.lastPlayedPlayerPlatformUid1 2731 | hardwardID = file.lastPlayedPlayerHardwareID1 2732 | break 2733 | } 2734 | 2735 | int localHardwareID = GetHardwareFromName( GetPlayerHardware() ) 2736 | bool isEADPFriend = localHardwareID != hardwardID 2737 | 2738 | #if PC_PROG 2739 | if ( PCPlat_IsSteam() ) 2740 | isEADPFriend = true 2741 | #endif 2742 | 2743 | #if (PLAYSTATION_PROG || XBOX_PROG ) 2744 | if( IsSamePlatform( localHardwareID, hardwardID ) ) 2745 | isEADPFriend = false 2746 | #endif 2747 | 2748 | 2749 | #if NX_PROG 2750 | 2751 | if( DoInviteToParty( [platformUID] ) == false ) 2752 | { 2753 | isEADPFriend = true 2754 | } 2755 | else 2756 | { 2757 | return 2758 | } 2759 | #endif 2760 | 2761 | if ( isEADPFriend ) 2762 | { 2763 | printt( " InviteEADPFriend id:", nucleusID ) 2764 | EADP_InviteToPlayByEAID( nucleusID, 0 ) 2765 | } 2766 | else 2767 | { 2768 | printt( " InviteFriend id:", platformUID ) 2769 | DoInviteToParty( [platformUID] ) 2770 | } 2771 | } 2772 | 2773 | 2774 | void function InviteLastPlayedButton_OnMiddleClick( var button ) 2775 | { 2776 | if ( Hud_IsLocked( button ) ) 2777 | return 2778 | 2779 | if ( !Clubs_IsEnabled() ) 2780 | return 2781 | 2782 | if ( !ClubIsValid() ) 2783 | return 2784 | 2785 | if ( IsSocialPopupActive() ) 2786 | return 2787 | 2788 | int scriptID = int( Hud_GetScriptID( button ) ) 2789 | 2790 | #if PC_PROG 2791 | if ( !MeetsAgeRequirements() ) 2792 | { 2793 | ConfirmDialogData dialogData 2794 | dialogData.headerText = "#UNAVAILABLE" 2795 | dialogData.messageText = "#ORIGIN_UNDERAGE_ONLINE" 2796 | dialogData.contextImage = $"ui/menu/common/dialog_notice" 2797 | 2798 | OpenOKDialogFromData( dialogData ) 2799 | return 2800 | } 2801 | #endif 2802 | 2803 | Assert( scriptID == 0 || scriptID == 1 ) 2804 | 2805 | string nucleusID 2806 | string platformUID 2807 | int hardwardID 2808 | 2809 | switch( scriptID ) 2810 | { 2811 | case 0: 2812 | nucleusID = file.lastPlayedPlayerNucleusID0 2813 | platformUID = file.lastPlayedPlayerPlatformUid0 2814 | hardwardID = file.lastPlayedPlayerHardwareID0 2815 | break 2816 | 2817 | case 1: 2818 | nucleusID = file.lastPlayedPlayerNucleusID1 2819 | platformUID = file.lastPlayedPlayerPlatformUid1 2820 | hardwardID = file.lastPlayedPlayerHardwareID1 2821 | break 2822 | } 2823 | 2824 | if ( nucleusID != "" ) 2825 | return 2826 | 2827 | if ( Clubs_IsUserAClubmate( nucleusID ) ) 2828 | return 2829 | 2830 | ClubInviteUser( nucleusID ) 2831 | HudElem_SetRuiArg( button, "unitframeFooterText", "#CLUB_INVITE_INVITED" ) 2832 | } 2833 | 2834 | 2835 | bool function InviteLastPlayedButton_OnKeyPress( var button, int keyId, bool isDown ) 2836 | { 2837 | printf( "LastSquadInputDebug: OnKeyPress" ) 2838 | if ( Hud_IsLocked( button ) ) 2839 | return false 2840 | 2841 | if ( !Clubs_IsEnabled() ) 2842 | return false 2843 | 2844 | if ( !ClubIsValid() ) 2845 | return false 2846 | 2847 | if ( !isDown ) 2848 | return false 2849 | 2850 | switch ( keyId ) 2851 | { 2852 | case MOUSE_MIDDLE: 2853 | case BUTTON_STICK_LEFT: 2854 | break 2855 | 2856 | default: 2857 | return false 2858 | } 2859 | 2860 | int scriptID = int( Hud_GetScriptID( button ) ) 2861 | 2862 | #if PC_PROG 2863 | if ( !MeetsAgeRequirements() ) 2864 | { 2865 | ConfirmDialogData dialogData 2866 | dialogData.headerText = "#UNAVAILABLE" 2867 | dialogData.messageText = "#ORIGIN_UNDERAGE_ONLINE" 2868 | dialogData.contextImage = $"ui/menu/common/dialog_notice" 2869 | 2870 | OpenOKDialogFromData( dialogData ) 2871 | return false 2872 | } 2873 | #endif 2874 | 2875 | Assert( scriptID == 0 || scriptID == 1 ) 2876 | printf( "LastSquadInputDebug: OnKeyPress: Club Invite Input Detected" ) 2877 | 2878 | string nucleusID 2879 | string platformUID 2880 | int hardwardID 2881 | 2882 | switch( scriptID ) 2883 | { 2884 | case 0: 2885 | nucleusID = file.lastPlayedPlayerNucleusID0 2886 | platformUID = file.lastPlayedPlayerPlatformUid0 2887 | hardwardID = file.lastPlayedPlayerHardwareID0 2888 | break 2889 | 2890 | case 1: 2891 | nucleusID = file.lastPlayedPlayerNucleusID1 2892 | platformUID = file.lastPlayedPlayerPlatformUid1 2893 | hardwardID = file.lastPlayedPlayerHardwareID1 2894 | break 2895 | } 2896 | 2897 | if ( nucleusID == "" ) 2898 | return false 2899 | 2900 | if ( Clubs_IsUserAClubmate( nucleusID ) ) 2901 | return false 2902 | 2903 | printf( "LastSquadInputDebug: OnKeyPress: Sending Invite" ) 2904 | 2905 | ClubInviteUser( nucleusID ) 2906 | HudElem_SetRuiArg( button, "unitframeFooterText", "#CLUB_INVITE_INVITED" ) 2907 | 2908 | return true 2909 | } 2910 | 2911 | 2912 | void function InviteLastPlayedButton_OnRightClick( var button ) 2913 | { 2914 | if ( IsSocialPopupActive() ) 2915 | return 2916 | 2917 | int scriptID = int( Hud_GetScriptID( button ) ) 2918 | int hardwareID = GetHardwareFromName( GetUnspoofedPlayerHardware() ) 2919 | 2920 | Friend friend 2921 | 2922 | if ( scriptID == 0 ) 2923 | { 2924 | friend.name = expect string( GetPersistentVar( "lastGameSquadStats[" + file.lastPlayedPlayerPersistenceIndex0 + "].playerName" ) ) 2925 | friend.hardware = GetNameFromHardware( file.lastPlayedPlayerHardwareID0 ) 2926 | friend.id = file.lastPlayedPlayerPlatformUid0 2927 | friend.eadpData = CreateEADPDataFromEAID( file.lastPlayedPlayerNucleusID0 ) 2928 | } 2929 | 2930 | if ( scriptID == 1 ) 2931 | { 2932 | friend.name = expect string( GetPersistentVar( "lastGameSquadStats[" + file.lastPlayedPlayerPersistenceIndex1 + "].playerName" ) ) 2933 | friend.hardware = GetNameFromHardware( file.lastPlayedPlayerHardwareID1 ) 2934 | friend.id = file.lastPlayedPlayerPlatformUid1 2935 | friend.eadpData = CreateEADPDataFromEAID( file.lastPlayedPlayerNucleusID1 ) 2936 | } 2937 | 2938 | if ( friend.id == "" ) 2939 | return 2940 | 2941 | InspectFriendForceEADP( friend, PCPlat_IsSteam() ) 2942 | } 2943 | 2944 | 2945 | void function FriendButton_OnActivate( var button ) 2946 | { 2947 | int scriptID = int( Hud_GetScriptID( button ) ) 2948 | if ( scriptID == -1 ) 2949 | { 2950 | Friend friend 2951 | friend.status = eFriendStatus.ONLINE_INGAME 2952 | friend.name = GetPlayerName() 2953 | friend.hardware = GetUnspoofedPlayerHardware() 2954 | friend.ingame = true 2955 | friend.id = GetPlayerUID() 2956 | friend.unspoofedid = GetPlayerUnSpoofedUID() 2957 | 2958 | Party party = GetParty() 2959 | friend.presence = Localize( "#PARTY_N_N", party.numClaimedSlots, party.numSlots ) 2960 | friend.inparty = party.numClaimedSlots > 0 2961 | 2962 | InspectFriend( friend, true ) 2963 | } 2964 | else 2965 | { 2966 | InspectFriend( scriptID == 0 ? file.friendInLeftSpot : file.friendInRightSpot, false ) 2967 | } 2968 | } 2969 | 2970 | bool function FriendButton_OnKeyPress( var button, int keyId, bool isDown ) 2971 | { 2972 | if ( !isDown ) 2973 | return false 2974 | int scriptID = int( Hud_GetScriptID( button ) ) 2975 | 2976 | if(keyId == BUTTON_STICK_LEFT || keyId == MOUSE_MIDDLE) 2977 | { 2978 | Friend friend = scriptID == 0 ? file.friendInLeftSpot : file.friendInRightSpot 2979 | string friendNucleusID = GetFriendNucleusID( friend ) 2980 | 2981 | if ( friendNucleusID != "" ) 2982 | { 2983 | if ( Clubs_IsEnabled() && ClubIsValid() && !Clubs_IsUserAClubmate( friendNucleusID ) ) 2984 | { 2985 | if ( ClubGetMyMemberRank() >= CLUB_RANK_CAPTAIN ) 2986 | { 2987 | HudElem_SetRuiArg( button, "actionSendTime", ClientTime(), eRuiArgType.GAMETIME ) 2988 | HudElem_SetRuiArg( button, "actionString", "#CLUB_INVITE_INVITED" ) 2989 | ClubInviteUser( friendNucleusID ) 2990 | } 2991 | else 2992 | { 2993 | Clubs_OpenTooLowRankToInviteDialog() 2994 | } 2995 | } 2996 | } 2997 | } 2998 | 2999 | if(keyId == BUTTON_A || keyId == MOUSE_LEFT) 3000 | { 3001 | if ( scriptID == -1 ) 3002 | { 3003 | Friend friend 3004 | friend.status = eFriendStatus.ONLINE_INGAME 3005 | friend.name = GetPlayerName() 3006 | friend.hardware = GetUnspoofedPlayerHardware() 3007 | friend.ingame = true 3008 | friend.id = GetPlayerUID() 3009 | 3010 | Party party = GetParty() 3011 | friend.presence = Localize( "#PARTY_N_N", party.numClaimedSlots, party.numSlots ) 3012 | friend.inparty = party.numClaimedSlots > 0 3013 | 3014 | InspectFriend( friend, true ) 3015 | } 3016 | else 3017 | { 3018 | Friend friendToInspect = scriptID == 0 ? file.friendInLeftSpot : file.friendInRightSpot 3019 | string spoofedHw = friendToInspect.hardware 3020 | friendToInspect.hardware = scriptID == 0 ? file.unspoofedHardwareForLeftSlot : file.unspoofedHardwareForRightSlot 3021 | InspectFriend( friendToInspect, false ) 3022 | friendToInspect.hardware = spoofedHw 3023 | } 3024 | } 3025 | 3026 | if(keyId == BUTTON_X || keyId == MOUSE_RIGHT) 3027 | { 3028 | 3029 | if ( scriptID == 0 ) 3030 | { 3031 | string eadpid = GetFriendNucleusID( file.friendInLeftSpot ); 3032 | TogglePlayerVoiceAndTextMuteForUID( file.friendInLeftSpot.id, file.friendInLeftSpot.hardware, eadpid ) 3033 | } 3034 | else 3035 | { 3036 | string eadpid = GetFriendNucleusID( file.friendInRightSpot ); 3037 | TogglePlayerVoiceAndTextMuteForUID( file.friendInRightSpot.id, file.friendInRightSpot.hardware, eadpid ) 3038 | } 3039 | } 3040 | 3041 | return true 3042 | } 3043 | 3044 | string function GetFriendNucleusID( Friend friend ) 3045 | { 3046 | string friendNucleusID = "" 3047 | string friendEadpHardwareName ="" 3048 | if( friend.eadpData != null ) 3049 | { 3050 | EadpPeopleData friendEadpData = expect EadpPeopleData( friend.eadpData ) 3051 | friendNucleusID = friendEadpData.eaid 3052 | } 3053 | else 3054 | { 3055 | friendNucleusID = EADP_GetEadpIdFromFirstPartyID( friend.id, GetHardwareFromName( friend.hardware ) ) 3056 | } 3057 | return friendNucleusID 3058 | } 3059 | 3060 | 3061 | void function CreatePartyAndInviteFriends() 3062 | { 3063 | if ( CanInvite() ) 3064 | { 3065 | while ( !PartyHasMembers() && !AmIPartyLeader() ) 3066 | { 3067 | printt( "creating a party in CreatePartyAndInviteFriends" ) 3068 | ClientCommand( "createparty" ) 3069 | WaitFrameOrUntilLevelLoaded() 3070 | } 3071 | 3072 | InviteFriends() 3073 | } 3074 | else 3075 | { 3076 | printt( "Not inviting friends - CanInvite() returned false" ) 3077 | } 3078 | } 3079 | 3080 | void function OpenLootBoxButton_OnActivate( var button ) 3081 | { 3082 | if ( Hud_IsLocked( button ) ) 3083 | return 3084 | 3085 | OnLobbyOpenLootBoxMenu_ButtonPress() 3086 | } 3087 | 3088 | 3089 | void function UpdatePlayPanelGRXDependantElements() 3090 | { 3091 | if ( GRX_IsInventoryReady() && IsLobby() ) 3092 | UpdateLobbyChallengeMenu() 3093 | 3094 | if ( !IsLobby() ) 3095 | Warning( "Called UpdatePlayPanelGRXDependantElements() from a map other than mp_lobby. This should not happen; UIVM cleanup isn't working correctly." ) 3096 | 3097 | #if NX_PROG || PC_PROG_NX_UI 3098 | if ( !IsNxHandheldMode() ) 3099 | UpdateMiniPromoPinning() 3100 | #else 3101 | UpdateMiniPromoPinning() 3102 | #endif 3103 | } 3104 | 3105 | 3106 | void function UpdateMiniPromoPinning() 3107 | { 3108 | 3109 | 3110 | 3111 | 3112 | 3113 | 3114 | 3115 | var miniPromoButton = Hud_GetChild( file.panel, "MiniPromo" ) 3116 | 3117 | array pinCandidates 3118 | 3119 | pinCandidates.append( Hud_GetChild( file.panel, "EventPrizeTrackButton" ) ) 3120 | pinCandidates.append( Hud_GetChild( file.panel, "ChallengeCatergoryLeftButton" ) ) 3121 | 3122 | array challengeButtons = GetLobbyChallengeButtons() 3123 | array storyChallengeButtons = GetLobbyStoryChallengeButtons() 3124 | 3125 | 3126 | challengeButtons.reverse() 3127 | pinCandidates.extend( challengeButtons ) 3128 | storyChallengeButtons.reverse() 3129 | pinCandidates.extend( storyChallengeButtons ) 3130 | 3131 | pinCandidates.append( Hud_GetChild( file.panel, "TopRightContentAnchor" ) ) 3132 | 3133 | var anchor = Hud_GetChild( file.panel, "TopRightContentAnchor" ) 3134 | 3135 | foreach ( pinCandidate in pinCandidates ) 3136 | { 3137 | if ( !Hud_IsVisible( pinCandidate ) ) 3138 | continue 3139 | 3140 | printt( "Pinning to:", Hud_GetHudName( pinCandidate ) ) 3141 | Hud_SetPinSibling( miniPromoButton, Hud_GetHudName( pinCandidate ) ) 3142 | 3143 | int vOffset = pinCandidate == anchor ? 0 : ContentScaledYAsInt( 24 ) 3144 | Hud_SetY( miniPromoButton, vOffset ) 3145 | break 3146 | } 3147 | } 3148 | 3149 | 3150 | void function UpdateLootBoxButton( var button, array specificPackFlavs = [] ) 3151 | { 3152 | ItemFlavor ornull packFlav 3153 | int lootBoxCount = 0 3154 | int totalPackCount = 0 3155 | string buttonText = "#APEX_PACKS" 3156 | string descText = "#UNAVAILABLE" 3157 | int nextRarity = -1 3158 | asset rarityIcon = $"" 3159 | vector themeCol = <1, 1, 1> 3160 | vector countTextCol = SrgbToLinear( <255, 78, 29> * 1.0 / 255.0 ) 3161 | 3162 | bool nextPackIsSpecial = false 3163 | asset packIcon = $"" 3164 | int specialPackCount = 0 3165 | 3166 | if ( GRX_IsInventoryReady() ) 3167 | { 3168 | ItemFlavor ornull nextPack = GetNextLootBox() 3169 | totalPackCount = GRX_GetTotalPackCount() 3170 | if ( totalPackCount > 0 ) 3171 | { 3172 | expect ItemFlavor( nextPack ) 3173 | GRX_GetPackCount( ItemFlavor_GetGRXIndex( nextPack ) ) 3174 | packIcon = GRXPack_GetOpenButtonIcon( nextPack ) 3175 | if ( packIcon != "" ) 3176 | specialPackCount = GRX_GetPackCount( ItemFlavor_GetGRXIndex( nextPack ) ) 3177 | } 3178 | 3179 | descText = "#REMAINING" 3180 | 3181 | if ( specificPackFlavs.len() > 0 ) 3182 | { 3183 | foreach ( ItemFlavor specificPackFlav in specificPackFlavs ) 3184 | { 3185 | int count = GRX_GetPackCount( ItemFlavor_GetGRXIndex( specificPackFlav ) ) 3186 | 3187 | if ( packFlav == null || (lootBoxCount == 0 && count > 0) ) 3188 | packFlav = specificPackFlav 3189 | 3190 | lootBoxCount += count 3191 | } 3192 | } 3193 | else if ( specialPackCount > 0 ) 3194 | { 3195 | lootBoxCount = specialPackCount 3196 | packFlav = nextPack 3197 | } 3198 | else 3199 | { 3200 | lootBoxCount = totalPackCount 3201 | if ( lootBoxCount > 0 ) 3202 | packFlav = nextPack 3203 | } 3204 | } 3205 | 3206 | if ( packFlav != null ) 3207 | { 3208 | expect ItemFlavor( packFlav ) 3209 | 3210 | if ( ItemFlavor_GetAccountPackType( packFlav ) == eAccountPackType.EVENT ) 3211 | { 3212 | buttonText = ItemFlavor_GetShortName( packFlav ) 3213 | descText = (lootBoxCount == 1 ? "#EVENT_PACK" : "#EVENT_PACKS") 3214 | } 3215 | else if ( ItemFlavor_GetAccountPackType( packFlav ) == eAccountPackType.THEMATIC || ItemFlavor_GetAccountPackType( packFlav ) == eAccountPackType.EVENT_THEMATIC ) 3216 | { 3217 | buttonText = ItemFlavor_GetShortName( packFlav ) 3218 | descText = (lootBoxCount == 1 ? "#THEMATIC_PACK" : "#THEMATIC_PACKS") 3219 | } 3220 | else 3221 | { 3222 | int packRarity = ItemFlavor_GetQuality( packFlav ) 3223 | if ( packRarity > 1 ) 3224 | { 3225 | string packTier = ItemFlavor_GetQualityName( packFlav ) 3226 | buttonText = ( lootBoxCount == 1 ? Localize( "#APEX_PACK_WITH_TIER", Localize( packTier ) ) : Localize( "#APEX_PACKS_WITH_TIER", Localize ( packTier ) ) ) 3227 | } 3228 | else 3229 | { 3230 | buttonText = (lootBoxCount == 1 ? "#APEX_PACK" : "#APEX_PACKS") 3231 | } 3232 | } 3233 | 3234 | nextRarity = ItemFlavor_GetQuality( packFlav ) 3235 | rarityIcon = GRXPack_GetOpenButtonIcon( packFlav ) 3236 | 3237 | vector ornull customCol0 = GRXPack_GetCustomColor( packFlav, 0 ) 3238 | if ( customCol0 != null ) 3239 | themeCol = SrgbToLinear( expect vector(customCol0) ) 3240 | else if ( nextRarity >= 2 ) 3241 | themeCol = SrgbToLinear( GetKeyColor( COLORID_TEXT_LOOT_TIER0, nextRarity + 1 ) / 255.0 ) 3242 | 3243 | vector ornull customCountTextCol = GRXPack_GetCustomCountTextCol( packFlav ) 3244 | if ( customCountTextCol != null ) 3245 | countTextCol = SrgbToLinear( expect vector(customCountTextCol) ) 3246 | } 3247 | 3248 | HudElem_SetRuiArg( button, "bigText", string( lootBoxCount ) ) 3249 | HudElem_SetRuiArg( button, "buttonText", buttonText ) 3250 | HudElem_SetRuiArg( button, "descText", descText ) 3251 | HudElem_SetRuiArg( button, "descTextRarity", nextRarity ) 3252 | HudElem_SetRuiArg( button, "rarityIcon", rarityIcon, eRuiArgType.ASSET ) 3253 | if ( lootBoxCount < totalPackCount ) 3254 | HudElem_SetRuiArg( button, "totalPackCount", totalPackCount ) 3255 | else 3256 | HudElem_SetRuiArg( button, "totalPackCount", 0 ) 3257 | RuiSetColorAlpha( Hud_GetRui( button ), "themeCol", themeCol, 1.0 ) 3258 | RuiSetColorAlpha( Hud_GetRui( button ), "countTextCol", countTextCol, 1.0 ) 3259 | 3260 | Hud_SetLocked( button, lootBoxCount == 0 ) 3261 | 3262 | 3263 | Hud_SetEnabled( button, lootBoxCount > 0 ) 3264 | } 3265 | 3266 | void function PlayPanelUpdate() 3267 | { 3268 | UpdateLobbyButtons() 3269 | UpdateHDTextureProgress() 3270 | } 3271 | 3272 | 3273 | #if DEV 3274 | void function LobbyAutomationThink( var menu ) 3275 | { 3276 | const float delayFactor = 2 3277 | if ( AutomateUi( delayFactor ) ) 3278 | { 3279 | string playlist = GetConVarString( "ui_automation_playlist" ) 3280 | if (playlist.len() > 0) 3281 | Lobby_SetSelectedPlaylist( playlist ) 3282 | 3283 | ReadyShortcut_OnActivate(null) 3284 | } 3285 | } 3286 | #endif 3287 | 3288 | 3289 | bool function ChatroomIsVisibleAndNotFocused() 3290 | { 3291 | if ( !file.chatroomMenu ) 3292 | return false 3293 | 3294 | return Hud_IsVisible( file.chatroomMenu ) && !Hud_IsFocused( file.chatroomMenu_chatroomWidget ) 3295 | } 3296 | 3297 | 3298 | bool function CanInvite() 3299 | { 3300 | if ( GetParty().amIInThis == false ) 3301 | return false 3302 | 3303 | if ( GetParty().numFreeSlots == 0 ) 3304 | return false 3305 | 3306 | #if XBOX_PROG 3307 | return (GetMenuVarBool( "isFullyConnected" ) && GetMenuVarBool( "Xbox_canInviteFriends" ) && GetMenuVarBool( "Xbox_isJoinable" )) 3308 | #elseif PLAYSTATION_PROG 3309 | return GetMenuVarBool( "PS4_canInviteFriends" ) 3310 | #elseif PC_PROG 3311 | return (GetMenuVarBool( "isFullyConnected" ) && GetMenuVarBool( "ORIGIN_isEnabled" ) && GetMenuVarBool( "ORIGIN_isJoinable" )) 3312 | #elseif NX_PROG 3313 | return GetMenuVarBool( "NX_canInviteFriends" ) 3314 | #endif 3315 | } 3316 | 3317 | 3318 | bool function IsLocalPlayerExemptFromTraining() 3319 | { 3320 | return true 3321 | /*if ( !IsFullyConnected() || !IsPersistenceAvailable() ) 3322 | return false 3323 | 3324 | 3325 | if ( IsTournamentMatchmaking() ) 3326 | return true 3327 | 3328 | 3329 | if ( file.isLocalPlayerExemptFromTraining == eTrainingExemptionState.UNINITIALIZED ) 3330 | { 3331 | bool isLevelHighEnough = ( GetAccountLevelForXP( GetPersistentVarAsInt( "xp" ) ) >= TRAINING_REQUIRED_BELOW_LEVEL_0_BASE ) 3332 | if ( isLevelHighEnough ) 3333 | file.isLocalPlayerExemptFromTraining = eTrainingExemptionState.TRUE 3334 | else 3335 | file.isLocalPlayerExemptFromTraining = eTrainingExemptionState.FALSE 3336 | } 3337 | 3338 | return ( file.isLocalPlayerExemptFromTraining == eTrainingExemptionState.TRUE )*/ 3339 | } 3340 | 3341 | 3342 | bool function DoesPlaylistRequireTraining( string playlist ) 3343 | { 3344 | return false 3345 | /*if ( playlist == PLAYLIST_TRAINING ) 3346 | return false 3347 | 3348 | if ( GetPartySize() > 1 ) 3349 | return false 3350 | 3351 | if ( IsLocalPlayerExemptFromTraining() ) 3352 | return false 3353 | 3354 | if ( HasLocalPlayerCompletedTraining() ) 3355 | return false 3356 | 3357 | return GetPlaylistVarBool( playlist, "require_training", true )*/ 3358 | } 3359 | 3360 | 3361 | bool function HasLocalPlayerCompletedTraining() 3362 | { 3363 | return true 3364 | /*if ( !IsFullyConnected() || !IsPersistenceAvailable() ) 3365 | return false 3366 | 3367 | if ( !GetVisiblePlaylistNames().contains( PLAYLIST_TRAINING ) ) 3368 | return true 3369 | 3370 | #if DEV 3371 | if ( GetBugReproNum() == 5000005 ) 3372 | return true 3373 | 3374 | if ( GetConVarBool( "skip_training" ) ) 3375 | return true 3376 | #endif 3377 | 3378 | if ( GetCurrentPlaylistVarBool( "require_training", true ) ) 3379 | return GetPersistentVarAsInt( "trainingCompleted" ) > 0 3380 | 3381 | return true*/ 3382 | } 3383 | 3384 | 3385 | 3386 | bool function IsLocalPlayerExemptFromNewPlayerOrientation() 3387 | { 3388 | return true 3389 | /*if( GetConVarBool( "orientation_matches_disabled" ) ) 3390 | return true 3391 | 3392 | if ( !IsFullyConnected() ) 3393 | return false 3394 | 3395 | #if CONSOLE_PROG 3396 | if( !Console_IsSignedIn() || Console_SkippedSignIn() ) 3397 | return false 3398 | #endif 3399 | 3400 | CommunityUserInfo ornull userInfo = GetUserInfo( GetPlayerHardware(), GetPlayerUID() ) 3401 | if ( userInfo == null ) 3402 | return false 3403 | 3404 | 3405 | if ( IsTournamentMatchmaking() ) 3406 | return true 3407 | 3408 | 3409 | return false*/ 3410 | } 3411 | 3412 | 3413 | bool function DoesPlaylistRequireNewPlayerOrientation( string playlist ) 3414 | { 3415 | return false 3416 | /*if( GetConVarBool( "orientation_matches_disabled" ) ) 3417 | return false 3418 | 3419 | if ( playlist == PLAYLIST_NEW_PLAYER_ORIENTATION ) 3420 | return false 3421 | 3422 | if ( IsLocalPlayerExemptFromNewPlayerOrientation() ) 3423 | return false 3424 | 3425 | if ( HasLocalPlayerCompletedNewPlayerOrientation() && !DoNonlocalPlayerPartyMembersNeedToCompleteNewPlayerOrientation() ) 3426 | return false 3427 | 3428 | return GetPlaylistVarBool( playlist, "require_new_player_orientation", true )*/ 3429 | } 3430 | 3431 | 3432 | bool function HasLocalPlayerCompletedNewPlayerOrientation() 3433 | { 3434 | return true 3435 | /*if( GetConVarBool( "orientation_matches_disabled" ) ) 3436 | return true 3437 | 3438 | if ( !IsFullyConnected() ) 3439 | return false 3440 | 3441 | #if CONSOLE_PROG 3442 | if( !Console_IsSignedIn() || Console_SkippedSignIn() ) 3443 | return false 3444 | #endif 3445 | 3446 | CommunityUserInfo ornull userInfo = GetUserInfo( GetPlayerHardware(), GetPlayerUID() ) 3447 | if ( userInfo == null ) 3448 | return false 3449 | expect CommunityUserInfo( userInfo ) 3450 | 3451 | if ( !GetVisiblePlaylistNames().contains( PLAYLIST_NEW_PLAYER_ORIENTATION ) ) 3452 | return true 3453 | 3454 | #if DEV 3455 | if ( GetConVarBool( "skip_training" ) ) 3456 | return true 3457 | #endif 3458 | 3459 | return userInfo.hasGraduatedBotsQueue*/ 3460 | } 3461 | 3462 | 3463 | bool function DoNonlocalPlayerPartyMembersNeedToCompleteNewPlayerOrientation() 3464 | { 3465 | return false 3466 | /*if( GetConVarBool( "orientation_matches_disabled" ) ) 3467 | return false 3468 | 3469 | Party party = GetParty() 3470 | string localPlayerUID = GetPlayerUID() 3471 | 3472 | foreach ( PartyMember partyMember in party.members ) 3473 | { 3474 | if ( partyMember.uid == localPlayerUID ) 3475 | continue 3476 | 3477 | CommunityUserInfo ornull userInfo = GetUserInfo( partyMember.hardware, partyMember.uid ) 3478 | if ( userInfo == null ) 3479 | continue 3480 | 3481 | expect CommunityUserInfo( userInfo ) 3482 | 3483 | if ( !userInfo.hasGraduatedBotsQueue ) 3484 | return true 3485 | } 3486 | 3487 | return false*/ 3488 | } 3489 | 3490 | 3491 | 3492 | var function GetPartyMemberButton( string uid ) 3493 | { 3494 | if ( uid == GetPlayerUID() ) 3495 | return file.selfButton 3496 | else if ( uid == file.friendInLeftSpot.id ) 3497 | return file.friendButton0 3498 | else if ( uid == file.friendInRightSpot.id ) 3499 | return file.friendButton1 3500 | 3501 | return null 3502 | } 3503 | 3504 | #if DEV 3505 | void function DEV_PrintPartyInfo() 3506 | { 3507 | Party party = GetParty() 3508 | printt( "party.playlistName", party.playlistName ) 3509 | printt( "party.originatorName", party.originatorName ) 3510 | printt( "party.originatorUID", party.originatorUID ) 3511 | printt( "party.numSlots", party.numSlots ) 3512 | printt( "party.numClaimedSlots", party.numClaimedSlots ) 3513 | printt( "party.numFreeSlots", party.numFreeSlots ) 3514 | printt( "party.amIInThis", party.amIInThis ) 3515 | printt( "party.amILeader", party.amILeader ) 3516 | printt( "party.searching", party.searching ) 3517 | 3518 | foreach ( member in party.members ) 3519 | { 3520 | printt( "\tmember.name", member.name ) 3521 | printt( "\tmember.uid", member.uid ) 3522 | printt( "\tmember.hardware", member.hardware ) 3523 | printt( "\tmember.ready", member.ready ) 3524 | 3525 | CommunityUserInfo ornull userInfo = GetUserInfo( member.hardware, member.uid ) 3526 | if ( userInfo == null ) 3527 | continue 3528 | 3529 | expect CommunityUserInfo( userInfo ) 3530 | 3531 | DEV_PrintUserInfo( userInfo, "\t\t" ) 3532 | } 3533 | } 3534 | 3535 | void function DEV_PrintUserInfo( CommunityUserInfo userInfo, string prefix = "" ) 3536 | { 3537 | printt( prefix + "userInfo.hardware", userInfo.hardware ) 3538 | printt( prefix + "userInfo.uid", userInfo.uid ) 3539 | printt( prefix + "userInfo.name", userInfo.name ) 3540 | printt( prefix + "userInfo.kills", userInfo.kills ) 3541 | printt( prefix + "userInfo.wins", userInfo.wins ) 3542 | printt( prefix + "userInfo.matches", userInfo.matches ) 3543 | printt( prefix + "userInfo.banReason", userInfo.banReason, "(see MATCHBANREASON_)" ) 3544 | printt( prefix + "userInfo.banSeconds", userInfo.banSeconds ) 3545 | printt( prefix + "userInfo.eliteStreak", userInfo.eliteStreak ) 3546 | printt( prefix + "userInfo.rankScore", userInfo.rankScore ) 3547 | printt( prefix + "userInfo.lastCharIdx", userInfo.lastCharIdx ) 3548 | printt( prefix + "userInfo.isLivestreaming", userInfo.isLivestreaming ) 3549 | printt( prefix + "userInfo.isOnline", userInfo.isOnline ) 3550 | printt( prefix + "userInfo.isJoinable", userInfo.isJoinable ) 3551 | printt( prefix + "userInfo.privacySetting", userInfo.privacySetting ) 3552 | printt( prefix + "userInfo.partyFull", userInfo.partyFull ) 3553 | printt( prefix + "userInfo.partyInMatch", userInfo.partyInMatch ) 3554 | printt( prefix + "userInfo.lastServerChangeTime", userInfo.lastServerChangeTime ) 3555 | 3556 | foreach ( int index, data in userInfo.charData ) 3557 | { 3558 | printt( prefix + "\tuserInfo.charData[" + index + "]", data, "\t" + DEV_GetEnumStringSafe( "ePlayerStryderCharDataArraySlots", index ) ) 3559 | } 3560 | } 3561 | #endif 3562 | 3563 | 3564 | void function AllChallengesButton_OnActivate( var button ) 3565 | { 3566 | if ( !GRX_IsInventoryReady() || !GRX_AreOffersReady() ) 3567 | return 3568 | 3569 | if ( IsDialog( GetActiveMenu() ) ) 3570 | return 3571 | 3572 | JumpToChallenges( "" ) 3573 | } 3574 | 3575 | 3576 | void function ChallengeSwitchLeft_OnClick( var button ) 3577 | { 3578 | if ( !IsConnected() ) 3579 | return 3580 | 3581 | Assert( file.challengeCategorySelection != null ) 3582 | DecrementCategorySelection() 3583 | UpdateLobbyChallengeMenu() 3584 | } 3585 | 3586 | 3587 | void function ChallengeSwitchRight_OnClick( var button ) 3588 | { 3589 | if ( !IsConnected() ) 3590 | return 3591 | 3592 | Assert( file.challengeCategorySelection != null ) 3593 | IncrementCategorySelection() 3594 | UpdateLobbyChallengeMenu() 3595 | } 3596 | 3597 | 3598 | void function ChallengeSwitch_RegisterInputCallbacks() 3599 | { 3600 | if ( file.challengeInputCallbacksRegistered ) 3601 | return 3602 | file.challengeInputCallbacksRegistered = true 3603 | 3604 | file.challengeLastStickState = eStickState.NEUTRAL 3605 | RegisterStickMovedCallback( ANALOG_RIGHT_X, ChallengeSwitchOnStickMoved ) 3606 | AddCallback_OnMouseWheelUp( ChallengeMouseUp ) 3607 | AddCallback_OnMouseWheelDown( ChallengeMouseDown ) 3608 | } 3609 | 3610 | 3611 | void function ChallengeSwitch_RemoveInputCallbacks() 3612 | { 3613 | if ( !file.challengeInputCallbacksRegistered ) 3614 | return 3615 | file.challengeInputCallbacksRegistered = false 3616 | 3617 | DeregisterStickMovedCallback( ANALOG_RIGHT_X, ChallengeSwitchOnStickMoved ) 3618 | RemoveCallback_OnMouseWheelUp( ChallengeMouseUp ) 3619 | RemoveCallback_OnMouseWheelDown( ChallengeMouseDown ) 3620 | } 3621 | 3622 | bool function ChallengeSwitch_CanChangeCategory() 3623 | { 3624 | return Hud_IsCursorOver( Hud_GetChild( file.panel, "ChallengesBounds" ) ) && !Hud_IsFocused( Hud_GetChild( file.panel, "MiniPromo" ) ) 3625 | } 3626 | 3627 | void function ChallengeMouseUp() 3628 | { 3629 | if ( !ChallengeSwitch_CanChangeCategory() ) 3630 | return 3631 | 3632 | EmitUISound( "UI_Menu_BattlePass_LevelTab" ) 3633 | ChallengeSwitchLeft_OnClick( null ) 3634 | } 3635 | 3636 | void function ChallengeMouseDown() 3637 | { 3638 | if ( !ChallengeSwitch_CanChangeCategory() ) 3639 | return 3640 | 3641 | EmitUISound( "UI_Menu_BattlePass_LevelTab" ) 3642 | ChallengeSwitchRight_OnClick( null ) 3643 | } 3644 | 3645 | void function ChallengeSwitchOnStickMoved( ... ) 3646 | { 3647 | float stickDeflection = expect float( vargv[1] ) 3648 | 3649 | 3650 | int stickState = eStickState.NEUTRAL 3651 | if ( stickDeflection > 0.25 ) 3652 | stickState = eStickState.RIGHT 3653 | else if ( stickDeflection < -0.25 ) 3654 | stickState = eStickState.LEFT 3655 | 3656 | if ( stickState != file.challengeLastStickState && ChallengeSwitch_CanChangeCategory() ) 3657 | { 3658 | if ( stickState == eStickState.RIGHT ) 3659 | { 3660 | EmitUISound( "UI_Menu_BattlePass_LevelTab" ) 3661 | ChallengeSwitchRight_OnClick( null ) 3662 | } 3663 | else if ( stickState == eStickState.LEFT ) 3664 | { 3665 | EmitUISound( "UI_Menu_BattlePass_LevelTab" ) 3666 | ChallengeSwitchLeft_OnClick( null ) 3667 | } 3668 | } 3669 | 3670 | file.challengeLastStickState = stickState 3671 | } 3672 | 3673 | 3674 | bool function IsTournamentMatchmaking() 3675 | { 3676 | if ( file.selectedPlaylist != "private_match" ) 3677 | return false 3678 | 3679 | return GetConVarString( "match_roleToken" ) != "" 3680 | } 3681 | 3682 | 3683 | void function Lobby_UpdatePlayPanelPlaylists() 3684 | { 3685 | file.playlistMods = GetPlaylistModNames() 3686 | file.playlists = GetVisiblePlaylistNames() 3687 | Assert( file.playlists.len() > 0 ) 3688 | 3689 | if ( !IsFullyConnected() ) 3690 | return 3691 | 3692 | if ( AreWeMatchmaking() ) 3693 | return 3694 | 3695 | if ( IsPreloadingMap() ) 3696 | return 3697 | 3698 | bool isPartyLeader = IsPartyLeader() 3699 | 3700 | if ( isPartyLeader ) 3701 | { 3702 | if ( GetPartySize() == 1 && !IsLocalPlayerExemptFromTraining() && !HasLocalPlayerCompletedTraining() ) 3703 | { 3704 | Lobby_SetSelectedPlaylist( PLAYLIST_TRAINING ) 3705 | return 3706 | } 3707 | 3708 | 3709 | if ( (!IsLocalPlayerExemptFromNewPlayerOrientation() && !HasLocalPlayerCompletedNewPlayerOrientation()) || DoNonlocalPlayerPartyMembersNeedToCompleteNewPlayerOrientation() ) 3710 | { 3711 | string currentSelectedPlaylist = Lobby_GetSelectedPlaylist() 3712 | if ( currentSelectedPlaylist != PLAYLIST_TRAINING && currentSelectedPlaylist != PLAYLIST_FIRING_RANGE ) 3713 | Lobby_SetSelectedPlaylist( PLAYLIST_NEW_PLAYER_ORIENTATION ) 3714 | 3715 | return 3716 | } 3717 | 3718 | } 3719 | 3720 | if ( file.playlists.contains( file.selectedPlaylist ) && file.selectedPlaylist != PLAYLIST_NEW_PLAYER_ORIENTATION ) 3721 | { 3722 | if ( CustomMatch_IsInCustomMatch() ) 3723 | return 3724 | 3725 | bool isMatchPlaylistCustomMatch = GetPlaylistVarBool( GetConVarString( "match_playlist" ), "private_match", false ) 3726 | if ( !isMatchPlaylistCustomMatch ) 3727 | return 3728 | } 3729 | 3730 | 3731 | if ( IsTournamentMatchmaking() ) 3732 | return 3733 | 3734 | 3735 | string newPlaylist = GetDefaultPlaylist() 3736 | if ( file.selectedPlaylist != "" ) 3737 | { 3738 | string uiSlot = GetPlaylistVarString( file.selectedPlaylist, "ui_slot", "" ) 3739 | string playlistInSlot = GetCurrentPlaylistInUiSlot( uiSlot ) 3740 | if ( playlistInSlot != "" ) 3741 | newPlaylist = playlistInSlot 3742 | } 3743 | 3744 | if ( isPartyLeader ) 3745 | Lobby_SetSelectedPlaylist( newPlaylist ) 3746 | } 3747 | 3748 | 3749 | void function PulseModeButton() 3750 | { 3751 | var rui = Hud_GetRui( file.modeButton ) 3752 | RuiSetGameTime( rui, "startPulseTime", ClientTime() ) 3753 | } 3754 | 3755 | 3756 | void function Ranked_OnPartyMemberAdded() 3757 | { 3758 | file.haveShownPartyMemberMatchmakingDelay = false 3759 | TryShowMatchmakingDelayDialog() 3760 | } 3761 | 3762 | void function OnPartySpectateSlotUnavailableWaitlisted() 3763 | { 3764 | JoinMatchAsPartySpectatorFailedAddedToWaitlistDialog() 3765 | } 3766 | 3767 | void function JoinMatchAsPartySpectatorFailedAddedToWaitlistDialog() 3768 | { 3769 | if ( !AmIPartyMember() || AmIPartyLeader() ) 3770 | return 3771 | 3772 | ConfirmDialogData data 3773 | data.headerText = "#JOIN_MATCH_AS_PARTY_SPECTATOR_ADDED_TO_WAITLIST" 3774 | data.messageText = "#JOIN_MATCH_AS_PARTY_SPECTATOR_ADDED_TO_WAITLIST_DESC" 3775 | 3776 | OpenOKDialogFromData( data ) 3777 | } 3778 | 3779 | void function OnPartySpectateSlotAvailable() 3780 | { 3781 | if( CanPromptUserToSpectatePartyInGame() ) 3782 | { 3783 | JoinMatchAsWaitlistedPartySpectatorDialog() 3784 | } 3785 | } 3786 | 3787 | void function JoinMatchAsWaitlistedPartySpectatorDialog() 3788 | { 3789 | if ( !AmIPartyMember() || AmIPartyLeader() ) 3790 | return 3791 | 3792 | ConfirmDialogData data 3793 | data.headerText = "#JOIN_MATCH_AS_WAITLISTED_PARTY_SPECTATOR" 3794 | data.messageText = "#JOIN_MATCH_AS_WAITLISTED_PARTY_SPECTATOR_DESC" 3795 | data.resultCallback = OnJoinMatchAsWaitlistedPartySpectatorDialogResult 3796 | 3797 | OpenConfirmDialogFromData( data ) 3798 | } 3799 | 3800 | void function OnJoinMatchAsWaitlistedPartySpectatorDialogResult( int result ) 3801 | { 3802 | if ( result != eDialogResult.YES ) 3803 | return 3804 | 3805 | Party_JoinUserPartyGame() 3806 | } 3807 | 3808 | void function UpdateCurrentMaxMatchmakingDelayEndTime() 3809 | { 3810 | file.currentMaxMatchmakingDelayEndTime = SharedRanked_GetMaxPartyMatchmakingDelay() + UITime() 3811 | } 3812 | 3813 | 3814 | void function TryShowMatchmakingDelayDialog() 3815 | { 3816 | if ( !ShouldShowMatchmakingDelayDialog() ) 3817 | return 3818 | 3819 | DialogFlow() 3820 | } 3821 | 3822 | 3823 | bool function ShouldShowMatchmakingDelayDialog() 3824 | { 3825 | if ( !IsLobby() ) 3826 | return false 3827 | 3828 | if ( !IsFullyConnected() ) 3829 | return false 3830 | 3831 | if ( GetActiveMenu() != GetMenu( "LobbyMenu" ) ) 3832 | return false 3833 | 3834 | if ( !IsTabPanelActive( GetPanel( "PlayPanel" ) ) ) 3835 | return false 3836 | 3837 | bool amIbanned = false 3838 | 3839 | array< PartyMember > bannedPartyMembers 3840 | foreach ( index, member in GetParty().members ) 3841 | { 3842 | CommunityUserInfo ornull userInfoOrNull = GetUserInfo( member.hardware, member.uid ) 3843 | if ( userInfoOrNull != null ) 3844 | { 3845 | CommunityUserInfo userInfo = expect CommunityUserInfo( userInfoOrNull ) 3846 | int matchMakingDelay = SharedRanked_GetMatchmakingDelayFromCommunityUserInfo( userInfo ) 3847 | if ( matchMakingDelay > 0 ) 3848 | { 3849 | bannedPartyMembers.append( member ) 3850 | 3851 | if ( GetPlayerUID() == userInfo.uid ) 3852 | { 3853 | amIbanned = true 3854 | } 3855 | } 3856 | } 3857 | } 3858 | 3859 | if ( bannedPartyMembers.len() == 0 ) 3860 | return false 3861 | 3862 | if ( amIbanned && bannedPartyMembers.len() == 1 && file.haveShownSelfMatchmakingDelay ) 3863 | return false 3864 | 3865 | return !(file.haveShownPartyMemberMatchmakingDelay) 3866 | } 3867 | 3868 | 3869 | void function ShowMatchmakingDelayDialog() 3870 | { 3871 | bool amIbanned = false 3872 | 3873 | array< PartyMember > bannedPartyMembers 3874 | int maxDelayTime = -1 3875 | foreach ( index, member in GetParty().members ) 3876 | { 3877 | CommunityUserInfo ornull userInfoOrNull = GetUserInfo( member.hardware, member.uid ) 3878 | if ( userInfoOrNull != null ) 3879 | { 3880 | CommunityUserInfo userInfo = expect CommunityUserInfo( userInfoOrNull ) 3881 | int matchMakingDelay = SharedRanked_GetMatchmakingDelayFromCommunityUserInfo( userInfo ) 3882 | if ( matchMakingDelay > 0 ) 3883 | { 3884 | bannedPartyMembers.append( member ) 3885 | 3886 | if ( GetPlayerUID() == userInfo.uid ) 3887 | { 3888 | amIbanned = true 3889 | } 3890 | 3891 | if ( matchMakingDelay > maxDelayTime ) 3892 | maxDelayTime = matchMakingDelay 3893 | } 3894 | } 3895 | } 3896 | 3897 | Assert( bannedPartyMembers.len() > 0 ) 3898 | ConfirmDialogData dialogData 3899 | dialogData.resultCallback = void function ( int result ) 3900 | { 3901 | DialogFlow() 3902 | } 3903 | 3904 | if ( amIbanned && bannedPartyMembers.len() == 1 ) 3905 | { 3906 | if ( !file.haveShownSelfMatchmakingDelay ) 3907 | { 3908 | dialogData.headerText = "#RANKED_ABANDON_PENALTY_HEADER" 3909 | dialogData.messageText = "#RANKED_ABANDON_PENALTY_MESSAGE" 3910 | file.haveShownSelfMatchmakingDelay = true 3911 | } 3912 | } 3913 | else 3914 | { 3915 | file.haveShownPartyMemberMatchmakingDelay = true 3916 | switch( bannedPartyMembers.len() ) 3917 | { 3918 | case 1: 3919 | dialogData.headerText = "#RANKED_ONE_PARTY_MEMBER_ABANDON_PENALTY_HEADER" 3920 | dialogData.messageText = Localize( "#RANKED_ONE_PARTY_MEMBER_ABANDON_PENALTY_MESSAGE", bannedPartyMembers[ 0 ].name ) 3921 | break 3922 | 3923 | case 2: 3924 | dialogData.headerText = "#RANKED_TWO_PARTY_MEMBER_ABANDON_PENALTY_HEADER" 3925 | dialogData.messageText = Localize( "#RANKED_TWO_PARTY_MEMBER_ABANDON_PENALTY_MESSAGE", bannedPartyMembers[ 0 ].name, bannedPartyMembers[ 1 ].name ) 3926 | break 3927 | 3928 | case 3: 3929 | dialogData.headerText = "#RANKED_ALL_PARTY_MEMBERS_ABANDON_PENALTY_HEADER" 3930 | dialogData.messageText = Localize( "#RANKED_ALL_PARTY_MEMBERS_ABANDON_PENALTY_MESSAGE", bannedPartyMembers[ 0 ].name, bannedPartyMembers[ 1 ].name, bannedPartyMembers[ 2 ].name ) 3931 | break 3932 | 3933 | default: 3934 | unreachable 3935 | } 3936 | } 3937 | 3938 | dialogData.contextImage = $"ui/menu/common/dialog_notice" 3939 | dialogData.timerEndTime = ClientTime() + maxDelayTime 3940 | 3941 | OpenOKDialogFromData( dialogData ) 3942 | } 3943 | 3944 | 3945 | bool function ShouldShowLastGameRankedAbandonForgivenessDialog() 3946 | { 3947 | if ( !IsLobby() ) 3948 | return false 3949 | 3950 | if ( !IsFullyConnected() ) 3951 | return false 3952 | 3953 | if ( GetActiveMenu() != GetMenu( "LobbyMenu" ) ) 3954 | return false 3955 | 3956 | if ( !IsTabPanelActive( GetPanel( "PlayPanel" ) ) ) 3957 | return false 3958 | 3959 | if ( file.haveShownLastGameRankedAbandonForgivenessDialog ) 3960 | return false 3961 | 3962 | return bool ( GetPersistentVarAsInt( "rankedGameData.lastGameAbandonForgiveness" ) ) 3963 | } 3964 | 3965 | 3966 | void function ShowLastGameRankedAbandonForgivenessDialog() 3967 | { 3968 | ConfirmDialogData dialogData 3969 | dialogData.resultCallback = void function ( int result ) 3970 | { 3971 | DialogFlow() 3972 | } 3973 | 3974 | int numUsedForgivenessAbandons = expect int ( GetPersistentVar( "numUsedForgivenessAbandons" ) ) 3975 | 3976 | if ( numUsedForgivenessAbandons == GetCurrentPlaylistVarInt( "ranked_num_abandon_forgiveness_games", SHARED_RANKED_NUM_ABANDON_FORGIVENESS_GAMES ) ) 3977 | { 3978 | dialogData.headerText = "#RANKED_ABANDON_FORGIVENESS_LAST_CHANCE_HEADER" 3979 | dialogData.messageText = "#RANKED_ABANDON_FORGIVENESS_LAST_CHANCE_MESSAGE" 3980 | } 3981 | else 3982 | { 3983 | dialogData.headerText = "#RANKED_ABANDON_FORGIVENESS_HEADER" 3984 | dialogData.messageText = "#RANKED_ABANDON_FORGIVENESS_MESSAGE" 3985 | } 3986 | 3987 | dialogData.contextImage = $"ui/menu/common/dialog_notice" 3988 | 3989 | file.haveShownLastGameRankedAbandonForgivenessDialog = true 3990 | 3991 | OpenOKDialogFromData( dialogData ) 3992 | } 3993 | 3994 | 3995 | void function SharedRanked_OnLevelInit() 3996 | { 3997 | if ( !IsLobby() ) 3998 | return 3999 | 4000 | file.haveShownSelfMatchmakingDelay = false 4001 | file.haveShownLastGameRankedAbandonForgivenessDialog = false 4002 | file.haveShownPartyMemberMatchmakingDelay = false 4003 | file.currentMaxMatchmakingDelayEndTime = -1 4004 | 4005 | if ( !file.rankedInitialized ) 4006 | { 4007 | AddCallbackAndCallNow_UserInfoUpdated( Ranked_OnUserInfoUpdatedForMatchmakingDelay ) 4008 | file.rankedInitialized = true 4009 | } 4010 | 4011 | TryShowMatchmakingDelayDialog() 4012 | } 4013 | 4014 | 4015 | void function Ranked_OnUserInfoUpdatedForMatchmakingDelay( string hardware, string id ) 4016 | { 4017 | if ( !IsConnected() ) 4018 | return 4019 | 4020 | if ( !IsLobby() ) 4021 | return 4022 | 4023 | if ( hardware == "" && id == "" ) 4024 | return 4025 | 4026 | CommunityUserInfo ornull cui = GetUserInfo( hardware, id ) 4027 | 4028 | if ( cui == null ) 4029 | return 4030 | 4031 | expect CommunityUserInfo( cui ) 4032 | 4033 | bool foundPartyMember = false 4034 | 4035 | foreach ( index, member in GetParty().members ) 4036 | { 4037 | if ( cui.hardware != member.hardware && cui.uid != member.uid ) 4038 | continue 4039 | 4040 | foundPartyMember = true 4041 | break 4042 | } 4043 | 4044 | if ( !foundPartyMember ) 4045 | return 4046 | 4047 | int matchMakingDelay = SharedRanked_GetMaxPartyMatchmakingDelay() 4048 | 4049 | if ( matchMakingDelay > 0 ) 4050 | { 4051 | file.currentMaxMatchmakingDelayEndTime = matchMakingDelay + UITime() 4052 | TryShowMatchmakingDelayDialog() 4053 | } 4054 | } 4055 | 4056 | 4057 | void function Ranked_OnUserInfoUpdatedInPanelPlay( string hardware, string id ) 4058 | { 4059 | if ( !IsConnected() ) 4060 | return 4061 | 4062 | if ( !IsLobby() ) 4063 | return 4064 | 4065 | if ( hardware == "" && id == "" ) 4066 | return 4067 | 4068 | CommunityUserInfo ornull cui = GetUserInfo( hardware, id ) 4069 | 4070 | if ( cui == null ) 4071 | return 4072 | 4073 | expect CommunityUserInfo( cui ) 4074 | 4075 | if ( cui.hardware == GetUnspoofedPlayerHardware() && cui.uid == GetPlayerUID() ) 4076 | { 4077 | if ( file.rankedRUIToUpdate != null ) 4078 | { 4079 | PopulateRuiWithRankedBadgeDetails( file.rankedRUIToUpdate, cui.rankScore, cui.rankedLadderPos ) 4080 | } 4081 | 4082 | 4083 | 4084 | 4085 | 4086 | 4087 | } 4088 | } 4089 | 4090 | 4091 | bool function Lobby_OpenBattlePassMilestoneDialog( bool forceShow = false ) 4092 | { 4093 | if ( !IsBattlepassMilestoneEnabled() || !GRX_IsInventoryReady() ) 4094 | return false 4095 | 4096 | ItemFlavor ornull activeBattlePass = GetActiveBattlePass() 4097 | if ( activeBattlePass == null ) 4098 | return false 4099 | 4100 | expect ItemFlavor( activeBattlePass ) 4101 | 4102 | entity player = GetLocalClientPlayer() 4103 | 4104 | string activeBattlePassGUID = ItemFlavor_GetGUIDString( activeBattlePass ) 4105 | 4106 | if ( DoesPlayerOwnBattlePass( player, activeBattlePass ) && forceShow == false ) 4107 | return false 4108 | 4109 | int currentXPProgress = GetPlayerBattlePassXPProgress( ToEHI( player ), activeBattlePass, false ) 4110 | int currentBPLevel = GetBattlePassLevelForXP( activeBattlePass, currentXPProgress ) 4111 | 4112 | var dataTable = GetDataTable( $"datatable/battlepass_season_milestone.rpak" ) 4113 | int numRows = GetDataTableRowCount( dataTable ) 4114 | int levelColumn = GetDataTableColumnByName( dataTable, "milestone_level" ) 4115 | 4116 | int lastSeenMilestone = expect int( player.GetPersistentVar( format( "battlePasses[%s].lastSeenMilestone", activeBattlePassGUID ) ) ) 4117 | bool showMilestoneMenu = false 4118 | 4119 | for ( int currentRow = numRows; currentRow > 0; currentRow-- ) 4120 | { 4121 | int milestoneLevel = GetDataTableInt( dataTable, currentRow - 1, levelColumn ) 4122 | 4123 | if ( currentBPLevel >= milestoneLevel - 1 ) 4124 | { 4125 | if ( currentRow > lastSeenMilestone ) 4126 | { 4127 | showMilestoneMenu = true 4128 | Remote_ServerCallFunction( "ClientCallback_MarkBattlePassMilestoneAsSeen", currentRow ) 4129 | break 4130 | } 4131 | } 4132 | } 4133 | 4134 | if ( showMilestoneMenu ) 4135 | { 4136 | thread function() : ( ) 4137 | { 4138 | wait 0.2 4139 | 4140 | if ( IsLobby() && IsBattlePassEnabled() && GRX_IsInventoryReady() ) 4141 | AdvanceMenu( GetMenu( "BattlePassMilestoneMenu" ) ) 4142 | }() 4143 | } 4144 | 4145 | return true 4146 | } 4147 | 4148 | 4149 | void function Lobby_ShowCallToActionPopup( bool challengesOnly ) 4150 | { 4151 | Signal( uiGlobal.signalDummy, "Lobby_ShowCallToActionPopup" ) 4152 | EndSignal( uiGlobal.signalDummy, "Lobby_ShowCallToActionPopup" ) 4153 | 4154 | file.dialogFlowDidCausePotentiallyInterruptingPopup = false 4155 | 4156 | while( !EventChallengesDidRefreshOnUI() ) 4157 | WaitFrame() 4158 | 4159 | while ( !GRX_IsInventoryReady() ) 4160 | WaitFrame() 4161 | 4162 | if ( Lobby_ShowStoryEventChallengesPopup() ) 4163 | return 4164 | 4165 | if ( !challengesOnly ) 4166 | { 4167 | if( Lobby_ShowLegendsTokenPopup() ) 4168 | return 4169 | 4170 | if( Lobby_ShowCurrencyExpirationPopup() ) 4171 | return 4172 | 4173 | if ( Lobby_ShowStoryEventAutoplayDialoguePopup() ) 4174 | return 4175 | 4176 | if ( Lobby_ShowBattlePassPopup() ) 4177 | return 4178 | 4179 | if ( Lobby_ShowHeirloomShopPopup() ) 4180 | return 4181 | 4182 | if ( Lobby_ShowQuestPopup() ) 4183 | return 4184 | } 4185 | } 4186 | 4187 | 4188 | void function Lobby_HideCallToActionPopup() 4189 | { 4190 | var popup = Hud_GetChild( file.panel, "PopupMessage" ) 4191 | Hud_Hide( popup ) 4192 | } 4193 | 4194 | 4195 | bool function Lobby_ShowBattlePassPopup( bool forceShow = false ) 4196 | { 4197 | 4198 | if ( IsBattlepassMilestoneEnabled() ) 4199 | return false 4200 | 4201 | 4202 | ItemFlavor ornull activeBattlePass = GetActiveBattlePass() 4203 | 4204 | if ( activeBattlePass == null ) 4205 | return false 4206 | 4207 | expect ItemFlavor( activeBattlePass ) 4208 | 4209 | entity player = GetLocalClientPlayer() 4210 | 4211 | if( IsFeatureSuppressed( eFeatureSuppressionFlags.BATTLE_PASS_POPUP ) && !forceShow ) 4212 | return false 4213 | 4214 | if ( DoesPlayerOwnBattlePass( player, activeBattlePass ) && !forceShow ) 4215 | return false 4216 | 4217 | int currentXPProgress = GetPlayerBattlePassXPProgress( ToEHI( player ), activeBattlePass, false ) 4218 | int bpLevel = GetBattlePassLevelForXP( activeBattlePass, currentXPProgress ) 4219 | 4220 | BattlePassReward ornull rewardToShow = null 4221 | 4222 | 4223 | array popupLevelMarkers_intArray 4224 | 4225 | 4226 | string popupLevelMarkers_stringOverride = GetCurrentPlaylistVarString( "battlepass_popup_level_markers", "" ) 4227 | 4228 | if ( popupLevelMarkers_stringOverride != "" ) 4229 | { 4230 | array popupLevelMarkers_stringArray = split( popupLevelMarkers_stringOverride, WHITESPACE_CHARACTERS ) 4231 | foreach ( levelString in popupLevelMarkers_stringArray ) 4232 | { 4233 | popupLevelMarkers_intArray.append( int( levelString ) ) 4234 | } 4235 | } 4236 | else 4237 | { 4238 | 4239 | popupLevelMarkers_intArray = GetRewardPromptLevelArray( activeBattlePass ) 4240 | } 4241 | 4242 | #if DEV 4243 | { 4244 | foreach (int i in popupLevelMarkers_intArray ) 4245 | { 4246 | printf( "popup level marker: " + string(i) ) 4247 | } 4248 | } 4249 | #endif 4250 | int markerLevel = 0 4251 | 4252 | foreach ( level in popupLevelMarkers_intArray ) 4253 | { 4254 | if ( level - 1 <= bpLevel ) 4255 | markerLevel = level - 1 4256 | } 4257 | 4258 | if ( markerLevel <= 0 && !forceShow ) 4259 | return false 4260 | 4261 | string bpString = ItemFlavor_GetGUIDString( activeBattlePass ) 4262 | 4263 | if ( markerLevel <= player.GetPersistentVar( format( "battlePasses[%s].lastPopupLevel", bpString ) ) && !forceShow ) 4264 | return false 4265 | 4266 | array rewards = GetBattlePassLevelRewards( activeBattlePass, markerLevel ) 4267 | 4268 | foreach ( reward in rewards ) 4269 | { 4270 | if ( !reward.isPremium ) 4271 | continue 4272 | 4273 | rewardToShow = reward 4274 | break 4275 | } 4276 | 4277 | if ( rewardToShow == null ) 4278 | return false 4279 | 4280 | expect BattlePassReward( rewardToShow ) 4281 | 4282 | file.onCallToActionFunc = void function() : () 4283 | { 4284 | JumpToSeasonTab( "PassPanel" ) 4285 | TabData tabData = GetTabDataForPanel( Hud_GetParent( file.panel ) ) 4286 | AdvanceMenu( GetMenu( "PassPurchaseMenu" ) ) 4287 | PIN_LobbyPopUp_Event( "battle_pass_pop_up", ePINPromoMessageStatus.CLICK ) 4288 | Lobby_HideCallToActionPopup() 4289 | } 4290 | 4291 | thread function() : ( rewardToShow, bpLevel, markerLevel ) 4292 | { 4293 | EndSignal( uiGlobal.signalDummy, "Lobby_ShowCallToActionPopup" ) 4294 | 4295 | var popup = Hud_GetChild( file.panel, "PopupMessage" ) 4296 | Lobby_MovePopupMessage( 1 ) 4297 | RuiSetImage( Hud_GetRui( popup ), "buttonImage", CustomizeMenu_GetRewardButtonImage( rewardToShow.flav ) ) 4298 | int rarity = ItemFlavor_HasQuality( rewardToShow.flav ) ? ItemFlavor_GetQuality( rewardToShow.flav ) : 0 4299 | RuiSetInt( Hud_GetRui( popup ), "rarity", rarity ) 4300 | RuiSetInt( Hud_GetRui( popup ), "level", bpLevel + 1 ) 4301 | BattlePass_SetRewardButtonIconSettings( rewardToShow.flav, Hud_GetRui( popup ), null, false ) 4302 | BattlePass_SetUnlockedString( popup, bpLevel + 1 ) 4303 | 4304 | HudElem_SetRuiArg( popup, "titleText", Localize( "#BATTLEPASS_POPUP_TITLE" ) ) 4305 | HudElem_SetRuiArg( popup, "subText", Localize( "#BATTLEPASS_POPUP_BODY", bpLevel + 1 ) ) 4306 | HudElem_SetRuiArg( popup, "detailText", Localize( "#BATTLEPASS_POPUP_UNLOCK" ) ) 4307 | 4308 | wait 0.2 4309 | 4310 | while ( GetActiveMenu() != GetMenu( "LobbyMenu" ) || !IsPanelActive( file.panel ) ) 4311 | WaitFrame() 4312 | 4313 | RuiSetGameTime( Hud_GetRui( popup ), "animStartTime", ClientTime() ) 4314 | Remote_ServerCallFunction( "ClientCallback_MarkBattlePassPopupAsSeen", markerLevel ) 4315 | PIN_LobbyPopUp_Event( "battle_pass_pop_up", ePINPromoMessageStatus.IMPRESSION ) 4316 | EmitUISound( SOUND_BP_POPUP ) 4317 | thread CallToActionPopupThink( popup, 10.0 ) 4318 | }() 4319 | 4320 | return true 4321 | } 4322 | 4323 | 4324 | bool function Lobby_ShowHeirloomShopPopup( bool forceShow = false ) 4325 | { 4326 | if( IsFeatureSuppressed( eFeatureSuppressionFlags.HEIRLOOM_SHOP_POPUP ) && !forceShow ) 4327 | return false 4328 | 4329 | if ( !GRX_AreOffersReady() && !forceShow ) 4330 | return false 4331 | 4332 | int heirloomShardBalance = GRXCurrency_GetPlayerBalance( GetLocalClientPlayer(), GRX_CURRENCIES[GRX_CURRENCY_HEIRLOOM] ) 4333 | int priceOfHeirloom = GetCurrentPlaylistVarInt( "grx_currency_bundle_heirloom_count", 50 ) * 3 4334 | if ( heirloomShardBalance < priceOfHeirloom && !forceShow ) 4335 | return false 4336 | 4337 | if ( GetUnixTimestamp() - expect int( GetPersistentVar( "heirloomShopLastSeen" ) ) < SECONDS_PER_DAY * 2 && !forceShow ) 4338 | return false 4339 | 4340 | 4341 | bool hasHeirloomsToCraft = false 4342 | foreach( scriptOffer in GRX_GetLocationOffers( "heirloom_set_shop" ) ) 4343 | { 4344 | if( !scriptOffer.isAvailable ) 4345 | continue 4346 | 4347 | Assert( scriptOffer.prices.len() == 1 ) 4348 | Assert( scriptOffer.prices[0].flavors.len() == 1 && scriptOffer.prices[0].flavors[0] == GRX_CURRENCIES[GRX_CURRENCY_HEIRLOOM] ) 4349 | Assert( scriptOffer.prices[0].quantities.len() == 1) 4350 | 4351 | if ( heirloomShardBalance < scriptOffer.prices[0].quantities[0] ) 4352 | continue 4353 | 4354 | ItemFlavor outputFlav = ItemFlavorBag_GetMeleeSkinItem( scriptOffer.output ) 4355 | 4356 | if ( !GRX_IsItemOwnedByPlayer_AllowOutOfDateData( outputFlav ) ) 4357 | { 4358 | hasHeirloomsToCraft = true 4359 | break 4360 | } 4361 | } 4362 | if( !hasHeirloomsToCraft ) 4363 | return false 4364 | 4365 | file.onCallToActionFunc = void function() : () 4366 | { 4367 | JumpToHeirloomShop() 4368 | PIN_LobbyPopUp_Event( "heirloom_crafting_pop_up", ePINPromoMessageStatus.CLICK ) 4369 | Lobby_HideCallToActionPopup() 4370 | } 4371 | 4372 | thread function() : () 4373 | { 4374 | EndSignal( uiGlobal.signalDummy, "Lobby_ShowCallToActionPopup" ) 4375 | 4376 | TabData lobbyTabData = GetTabDataForPanel( GetMenu( "LobbyMenu" ) ) 4377 | int idx = Tab_GetTabIndexByBodyName( lobbyTabData, "PassPanelV2" ) 4378 | var popup = Hud_GetChild( file.panel, "PopupMessage" ) 4379 | 4380 | HudElem_SetRuiArg( popup, "titleText", "#CTA_HEIRLOOM_SHOP_TITLE" ) 4381 | HudElem_SetRuiArg( popup, "subText", "#CTA_HEIRLOOM_SHOP_SUBTEXT" ) 4382 | HudElem_SetRuiArg( popup, "detailText", "#CTA_HEIRLOOM_SHOP_DETAIL" ) 4383 | HudElem_SetRuiArg( popup, "unlockedString", "" ) 4384 | HudElem_SetRuiArg( popup, "buttonImage", ItemFlavor_GetIcon( GRX_CURRENCIES[GRX_CURRENCY_HEIRLOOM] ), eRuiArgType.IMAGE ) 4385 | HudElem_SetRuiArg( popup, "forceFullIcon", false ) 4386 | HudElem_SetRuiArg( popup, "rarity", eRarityTier.MYTHIC ) 4387 | 4388 | HudElem_SetRuiArg( popup, "altStyle1Color", <0.55, 0.55, 0.55> ) 4389 | HudElem_SetRuiArg( popup, "altStyle2Color", <1.0, 1.0, 1.0> ) 4390 | HudElem_SetRuiArg( popup, "altStyle3Color", SrgbToLinear( GetKeyColor( COLORID_MENU_TEXT_LOOT_TIER0, eRarityTier.MYTHIC ) / 255.0 ) ) 4391 | 4392 | Lobby_MovePopupMessage( 2 ) 4393 | 4394 | 4395 | 4396 | 4397 | 4398 | 4399 | 4400 | 4401 | wait 0.2 4402 | 4403 | while ( GetActiveMenu() != GetMenu( "LobbyMenu" ) || !IsPanelActive( file.panel ) ) 4404 | WaitFrame() 4405 | 4406 | RuiSetGameTime( Hud_GetRui( popup ), "animStartTime", ClientTime() ) 4407 | Remote_ServerCallFunction( "ClientCallback_MarkHeirloomShopPopupAsSeen" ) 4408 | PIN_LobbyPopUp_Event( "heirloom_crafting_pop_up", ePINPromoMessageStatus.IMPRESSION ) 4409 | EmitUISound( SOUND_BP_POPUP ) 4410 | thread CallToActionPopupThink( popup, 10.0 ) 4411 | }() 4412 | 4413 | return true 4414 | } 4415 | 4416 | bool function Lobby_ShowLegendsTokenPopup( bool forceShow = false ) 4417 | { 4418 | if( ( !GRX_IsInventoryReady() || !GRX_AreOffersReady() ) && !forceShow ) 4419 | return false 4420 | 4421 | 4422 | if ( !GetConVarBool( "ftue_flow_enabled" ) && GetFirstTimePlayerState() >= eNewPlayerState.FIRST_MATCH_PLAYED && !forceShow ) 4423 | return false 4424 | 4425 | 4426 | 4427 | 4428 | if( expect int( GetPersistentVar( "legendTokensPopupLastSeen" ) ) > 0 && !forceShow ) 4429 | return false 4430 | 4431 | int playerBalance = GRXCurrency_GetPlayerBalance( GetLocalClientPlayer(), GRX_CURRENCIES[GRX_CURRENCY_CREDITS] ) 4432 | int legendTokensCost = -1 4433 | foreach ( ItemFlavor character in GetAllCharacters() ) 4434 | { 4435 | int ItemFlavourGRXMode = ItemFlavor_GetGRXMode( character ) 4436 | if( ItemFlavourGRXMode == GRX_ITEMFLAVORMODE_NONE ) 4437 | continue 4438 | 4439 | if ( ItemFlavor_IsItemDisabledForGRX( character ) ) 4440 | continue 4441 | 4442 | if ( ItemFlavourGRXMode == GRX_ITEMFLAVORMODE_REGULAR && Character_IsCharacterOwnedByPlayer( character ) ) 4443 | continue 4444 | 4445 | ItemFlavorPurchasabilityInfo ifpi = GRX_GetItemPurchasabilityInfo( character ) 4446 | foreach ( string location, array locationOfferList in ifpi.locationToDedicatedStoreOffersMap ) 4447 | { 4448 | foreach ( GRXScriptOffer locationOffer in locationOfferList ) 4449 | { 4450 | if ( locationOffer.isAvailable && locationOffer.offerType != GRX_OFFERTYPE_BUNDLE && locationOffer.output.flavors.len() == 1 ) 4451 | { 4452 | foreach ( ItemFlavorBag price in locationOffer.prices ) 4453 | { 4454 | if ( GRX_IsPremiumPrice( price ) || (!GRX_CanAfford( price, 1 )) ) 4455 | continue 4456 | 4457 | array priceArray = GRX_GetCurrencyArrayFromBag( price ) 4458 | int craftingPrice = priceArray[GRX_CURRENCY_CREDITS] 4459 | if ( legendTokensCost < 0 || legendTokensCost > craftingPrice ) 4460 | legendTokensCost = craftingPrice 4461 | } 4462 | } 4463 | } 4464 | } 4465 | } 4466 | 4467 | if( ( legendTokensCost < 0 || playerBalance < legendTokensCost ) && !forceShow ) 4468 | return false 4469 | 4470 | 4471 | file.onCallToActionFunc = void function() : () 4472 | { 4473 | JumpToCharactersTab() 4474 | PIN_LobbyPopUp_Event( "legend_token_pop_up", ePINPromoMessageStatus.CLICK ) 4475 | Lobby_HideCallToActionPopup() 4476 | } 4477 | 4478 | thread function() : () 4479 | { 4480 | EndSignal( uiGlobal.signalDummy, "Lobby_ShowCallToActionPopup" ) 4481 | 4482 | var popup = Hud_GetChild( file.panel, "PopupMessage" ) 4483 | var popupRui = Hud_GetRui( popup ) 4484 | 4485 | HudElem_SetRuiArg( popup, "titleText", "#CTA_LEGEND_TOKENS_TITLE" ) 4486 | HudElem_SetRuiArg( popup, "subText", "#CTA_LEGEND_TOKENS_SUBTEXT" ) 4487 | HudElem_SetRuiArg( popup, "detailText", "#CTA_LEGEND_TOKENS_DETAIL" ) 4488 | HudElem_SetRuiArg( popup, "unlockedString", "" ) 4489 | HudElem_SetRuiArg( popup, "buttonImage", ItemFlavor_GetIcon( GRX_CURRENCIES[GRX_CURRENCY_CREDITS] ), eRuiArgType.IMAGE ) 4490 | HudElem_SetRuiArg( popup, "forceFullIcon", false ) 4491 | HudElem_SetRuiArg( popup, "rarity", eRarityTier.RARE ) 4492 | 4493 | HudElem_SetRuiArg( popup, "showArrow", true ) 4494 | 4495 | #if NX_PROG || PC_PROG_NX_UI 4496 | RuiSetFloat2( popupRui, "arrowOffset", <0.32, 0.0, 0.0> ) 4497 | #else 4498 | RuiSetFloat2( popupRui, "arrowOffset", <0.39, 0.0, 0.0> ) 4499 | #endif 4500 | 4501 | 4502 | HudElem_SetRuiArg( popup, "altStyle1Color", <0.55, 0.55, 0.55> ) 4503 | HudElem_SetRuiArg( popup, "altStyle2Color", <1.0, 1.0, 1.0> ) 4504 | HudElem_SetRuiArg( popup, "altStyle3Color", SrgbToLinear( GetKeyColor( COLORID_MENU_TEXT_LOOT_TIER0, eRarityTier.RARE ) / 255.0 ) ) 4505 | 4506 | Lobby_MovePopupMessage( 2 ) 4507 | 4508 | wait 0.2 4509 | 4510 | while ( GetActiveMenu() != GetMenu( "LobbyMenu" ) || !IsPanelActive( file.panel ) ) 4511 | WaitFrame() 4512 | 4513 | RuiSetGameTime( Hud_GetRui( popup ), "animStartTime", ClientTime() ) 4514 | Remote_ServerCallFunction( "ClientCallback_MarkLegendTokensPopupAsSeen" ) 4515 | PIN_LobbyPopUp_Event( "legend_token_pop_up", ePINPromoMessageStatus.IMPRESSION ) 4516 | EmitUISound( SOUND_BP_POPUP ) 4517 | thread CallToActionPopupThink( popup, 10.0 ) 4518 | 4519 | }() 4520 | return true 4521 | } 4522 | 4523 | 4524 | bool function Lobby_ShowQuestPopup( bool forceShow = false ) 4525 | { 4526 | if( IsFeatureSuppressed( eFeatureSuppressionFlags.QUEST_POPUP ) && !forceShow ) 4527 | return false 4528 | 4529 | if ( GetUnixTimestamp() - expect int( GetPersistentVar( "questPopupLastSeen" ) ) < SECONDS_PER_DAY * 2 && !forceShow ) 4530 | return false 4531 | 4532 | ItemFlavor ornull quest = SeasonQuest_GetActiveSeasonQuest( GetUnixTimestamp() ) 4533 | if ( quest == null ) 4534 | return false 4535 | 4536 | expect ItemFlavor( quest ) 4537 | 4538 | entity player = GetLocalClientPlayer() 4539 | 4540 | bool isComic = false 4541 | int missionCount = SeasonQuest_GetMissionsMaxCount( quest ) 4542 | 4543 | if ( missionCount == 0 ) 4544 | { 4545 | missionCount = SeasonQuest_GetComicPagesMaxCount( quest ) 4546 | isComic = true 4547 | } 4548 | 4549 | int missionIndex = -1 4550 | for ( int index = 0; index < missionCount; index++ ) 4551 | { 4552 | bool launchable = isComic ? SeasonQuest_GetStatusForComicPageIndex( player, quest, index ) == eQuestMissionStatus.LAUNCHABLE : SeasonQuest_GetStatusForMissionIndex( player, quest, index ) == eQuestMissionStatus.LAUNCHABLE 4553 | 4554 | if ( launchable ) 4555 | { 4556 | missionIndex = index 4557 | break 4558 | } 4559 | } 4560 | 4561 | 4562 | if ( missionIndex < 0 ) 4563 | return false 4564 | 4565 | file.onCallToActionFunc = void function() : () 4566 | { 4567 | JumpToSeasonTab( "QuestPanel" ) 4568 | PIN_LobbyPopUp_Event( "season_quest_pop_up", ePINPromoMessageStatus.CLICK ) 4569 | Lobby_HideCallToActionPopup() 4570 | } 4571 | 4572 | thread function() : ( quest, missionIndex, isComic ) 4573 | { 4574 | EndSignal( uiGlobal.signalDummy, "Lobby_ShowCallToActionPopup" ) 4575 | 4576 | TabData lobbyTabData = GetTabDataForPanel( GetMenu( "LobbyMenu" ) ) 4577 | var popup = Hud_GetChild( file.panel, "PopupMessage" ) 4578 | 4579 | ItemFlavor mission = isComic ? SeasonQuest_GetComicPageForIndex( quest, missionIndex ) : SeasonQuest_GetMissionForIndex( quest, missionIndex ) 4580 | 4581 | HudElem_SetRuiArg( popup, "titleText", isComic ? "#CTA_QUEST_COMIC_TITLE" : "#CTA_QUEST_TITLE" ) 4582 | HudElem_SetRuiArg( popup, "subText", Localize( (isComic ? "#CTA_QUEST_COMIC_SUBTEXT" : "#CTA_QUEST_SUBTEXT"), string( missionIndex + 1 ), Localize( ItemFlavor_GetLongName( mission ) ) ) ) 4583 | HudElem_SetRuiArg( popup, "detailText", "#CTA_QUEST_DETAIL" ) 4584 | HudElem_SetRuiArg( popup, "unlockedString", "" ) 4585 | HudElem_SetRuiArg( popup, "buttonImage", isComic ? SeasonQuest_GetComicPagesIconForIndex( quest, missionIndex ) : SeasonQuest_GetMissionIconForMissionIndex( quest, missionIndex ), eRuiArgType.IMAGE ) 4586 | HudElem_SetRuiArg( popup, "forceFullIcon", false ) 4587 | HudElem_SetRuiArg( popup, "rarity", eRarityTier.LEGENDARY ) 4588 | 4589 | HudElem_SetRuiArg( popup, "altStyle1Color", <0.55, 0.55, 0.55> ) 4590 | HudElem_SetRuiArg( popup, "altStyle2Color", <1.0, 1.0, 1.0> ) 4591 | HudElem_SetRuiArg( popup, "altStyle3Color", SrgbToLinear( GetKeyColor( COLORID_MENU_TEXT_LOOT_TIER0, eRarityTier.MYTHIC ) / 255.0 ) ) 4592 | 4593 | Lobby_MovePopupMessage( 0, 0.288 ) 4594 | 4595 | wait 0.2 4596 | 4597 | while ( GetActiveMenu() != GetMenu( "LobbyMenu" ) || !IsPanelActive( file.panel ) ) 4598 | WaitFrame() 4599 | 4600 | RuiSetGameTime( Hud_GetRui( popup ), "animStartTime", ClientTime() ) 4601 | Remote_ServerCallFunction( "ClientCallback_MarkQuestPopupAsSeen" ) 4602 | PIN_LobbyPopUp_Event( "season_quest_pop_up", ePINPromoMessageStatus.IMPRESSION ) 4603 | EmitUISound( SOUND_BP_POPUP ) 4604 | thread CallToActionPopupThink( popup, 10.0 ) 4605 | }() 4606 | 4607 | return true 4608 | } 4609 | 4610 | bool function Lobby_ShowCurrencyExpirationPopup( bool forceShow = false ) 4611 | { 4612 | int nextExpirationTime = GRX_GetNextCurrencyExpirationTime() 4613 | 4614 | if( IsFeatureSuppressed( eFeatureSuppressionFlags.CURRENCY_EXPIRATION_POPUP ) && !forceShow ) 4615 | return false 4616 | 4617 | if( !forceShow && ( expect int( GetPersistentVar( "currencyExpPopupLastExpTime" ) ) == nextExpirationTime || nextExpirationTime - GetUnixTimestamp() > SECONDS_PER_DAY * 30 ) ) 4618 | return false 4619 | 4620 | entity player = GetLocalClientPlayer() 4621 | 4622 | file.onCallToActionFunc = void function() : () 4623 | { 4624 | PIN_LobbyPopUp_Event( "currency_expiration_pop_up", ePINPromoMessageStatus.CLICK ) 4625 | Lobby_HideCallToActionPopup() 4626 | } 4627 | 4628 | thread function() : ( nextExpirationTime ) 4629 | { 4630 | EndSignal( uiGlobal.signalDummy, "Lobby_ShowCallToActionPopup" ) 4631 | 4632 | TabData lobbyTabData = GetTabDataForPanel( GetMenu( "LobbyMenu" ) ) 4633 | var popup = Hud_GetChild( file.panel, "PopupMessage" ) 4634 | 4635 | HudElem_SetRuiArg( popup, "titleText", "#EXPIRING_CURRENCY_HEADER" ) 4636 | HudElem_SetRuiArg( popup, "subText", "#EXPIRING_CURRENCY_BODY" ) 4637 | HudElem_SetRuiArg( popup, "detailText", "" ) 4638 | HudElem_SetRuiArg( popup, "unlockedString", "" ) 4639 | HudElem_SetRuiArg( popup, "buttonImage", $"rui/menu/sku_store/apex_coins_card_t3", eRuiArgType.IMAGE ) 4640 | HudElem_SetRuiArg( popup, "forceFullIcon", false ) 4641 | 4642 | HudElem_SetRuiArg( popup, "altStyle1Color", <0.55, 0.55, 0.55> ) 4643 | HudElem_SetRuiArg( popup, "altStyle2Color", <1.0, 1.0, 1.0> ) 4644 | HudElem_SetRuiArg( popup, "altStyle3Color", SrgbToLinear( GetKeyColor( COLORID_MENU_TEXT_LOOT_TIER0, eRarityTier.MYTHIC ) / 255.0 ) ) 4645 | 4646 | Lobby_MovePopupMessage( 0, 0.288 ) 4647 | 4648 | wait 0.2 4649 | 4650 | while ( GetActiveMenu() != GetMenu( "LobbyMenu" ) || !IsPanelActive( file.panel ) || IsDialog( GetActiveMenu() ) ) 4651 | wait 0.2 4652 | 4653 | RuiSetGameTime( Hud_GetRui( popup ), "animStartTime", ClientTime() ) 4654 | Remote_ServerCallFunction( "ClientCallback_MarkCurrencyExpirationPopupAsSeen", nextExpirationTime ) 4655 | PIN_LobbyPopUp_Event( "currency_expiration_pop_up", ePINPromoMessageStatus.IMPRESSION ) 4656 | EmitUISound( SOUND_BP_POPUP ) 4657 | thread CallToActionPopupThink( popup, 10.0 ) 4658 | }() 4659 | 4660 | return true 4661 | } 4662 | 4663 | bool function Lobby_ShowStoryEventAutoplayDialoguePopup( bool forceShow = false ) 4664 | { 4665 | if( IsFeatureSuppressed( eFeatureSuppressionFlags.STORY_EVENT_AUTOPLAY_DIALOGUE_POPUP ) && !forceShow ) 4666 | return false 4667 | 4668 | array storyChallengeEvents = GetActiveStoryChallengeEvents( GetUnixTimestamp() ) 4669 | if ( storyChallengeEvents.len() <= 0 ) 4670 | return false 4671 | 4672 | entity player = GetLocalClientPlayer() 4673 | 4674 | 4675 | 4676 | if( ( GetUnixTimestamp() - expect int( GetPersistentVar( "storyEventDialoguePopupLastSeen" ) ) < SECONDS_PER_DAY * 2 ) && !forceShow ) 4677 | return false 4678 | 4679 | array dialogueDatas 4680 | foreach ( event in storyChallengeEvents ) 4681 | { 4682 | array temp = StoryChallengeEvent_GetAutoplayDialogueDataForPlayer( event, player ) 4683 | dialogueDatas.extend( temp ) 4684 | } 4685 | 4686 | 4687 | if ( dialogueDatas.len() > 0 ) 4688 | { 4689 | Remote_ServerCallFunction ("ClientCallback_MarkStoryEventDialoguePopupAsAttempted") 4690 | thread Lobby_ShowDialoguePopupFromData( dialogueDatas ) 4691 | return true 4692 | } 4693 | 4694 | return false 4695 | } 4696 | 4697 | void function Lobby_ShowDialoguePopupFromData( array dialogueDatas ) 4698 | { 4699 | Signal( uiGlobal.signalDummy, "Lobby_ShowCallToActionPopup" ) 4700 | EndSignal( uiGlobal.signalDummy, "Lobby_ShowCallToActionPopup" ) 4701 | 4702 | var popup = Hud_GetChild( file.panel, "StoryEventsMessage" ) 4703 | var rui = Hud_GetRui( popup ) 4704 | 4705 | foreach ( StoryEventDialogueData data in dialogueDatas ) 4706 | { 4707 | RuiSetBool( rui, "shouldHideInMenu", false ) 4708 | RuiSetString( rui, "displayText", data.bodyText ) 4709 | RuiSetString( rui, "speakerName", data.speakerName ) 4710 | RuiSetImage( rui, "portraitImage", data.speakerIcon ) 4711 | 4712 | wait 0.5 4713 | 4714 | while ( GetActiveMenu() != GetMenu( "LobbyMenu" ) || !IsPanelActive( file.panel ) ) 4715 | WaitFrame() 4716 | 4717 | RuiSetFloat( rui, "soundDuration", data.duration ) 4718 | RuiSetGameTime( rui, "startTimeOverride", ClientTime() ) 4719 | 4720 | thread CallToActionDialoguePopupAudioThink( popup, data ) 4721 | waitthread CallToActionDialoguePopupThink( popup, data ) 4722 | } 4723 | } 4724 | 4725 | bool function Lobby_ShowStoryEventChallengesPopup( bool forceShow = false ) 4726 | { 4727 | array< ItemFlavor > storyChallengeEvents = GetActiveStoryChallengeEvents( GetUnixTimestamp() ) 4728 | if ( storyChallengeEvents.len() <= 0 ) 4729 | return false 4730 | 4731 | entity player = GetLocalClientPlayer() 4732 | 4733 | foreach ( event in storyChallengeEvents ) 4734 | { 4735 | array appropriateSpecialEventChallenges = StoryChallengeEvent_GetActiveChallengesForPlayer( event, player ) 4736 | bool hasSeenPopupForSomeChallenges = false 4737 | array activeChallenges 4738 | array challengeDataForSeenPersistenceVarNames 4739 | 4740 | foreach ( ItemFlavor challenge in appropriateSpecialEventChallenges ) 4741 | { 4742 | 4743 | if ( Challenge_IsAssigned( player, challenge ) && !Challenge_IsComplete( player, challenge ) ) 4744 | { 4745 | activeChallenges.append( challenge ) 4746 | 4747 | StoryEventGroupChallengeData challengeData = StoryChallengeEvent_GetHasChallengesData( challenge, player ) 4748 | string ornull hasSeenPersistenceVarNameOrNull = challengeData.persistenceVarNameHasSeenOrNull 4749 | if ( hasSeenPersistenceVarNameOrNull != null && !challengeDataForSeenPersistenceVarNames.contains( challengeData ) ) 4750 | challengeDataForSeenPersistenceVarNames.append( challengeData ) 4751 | 4752 | if ( StoryChallengeEvent_HasChallengesPopupBeenSeen( challenge, player ) ) 4753 | hasSeenPopupForSomeChallenges = true 4754 | } 4755 | } 4756 | 4757 | if ( activeChallenges.len() == 0 ) 4758 | continue 4759 | 4760 | if ( challengeDataForSeenPersistenceVarNames.len() == 0 ) 4761 | continue 4762 | 4763 | 4764 | if ( hasSeenPopupForSomeChallenges ) 4765 | { 4766 | if ( GetUnixTimestamp() - expect int( GetPersistentVar( "storyEventChallengesPopupLastSeen" ) ) < SECONDS_PER_DAY * 2 && !forceShow ) 4767 | continue 4768 | } 4769 | 4770 | 4771 | 4772 | int kind = Challenge_GetTimeSpanKind( activeChallenges[0] ) 4773 | if ( kind == eChallengeTimeSpanKind.EVENT_SPECIAL ) 4774 | { 4775 | file.onCallToActionFunc = void function() : () 4776 | { 4777 | JumpToSeasonTab( "ChallengesPanel" ) 4778 | AllChallengesMenu_ForceClickSpecialEventButton( eChallengeTimeSpanKind.EVENT_SPECIAL ) 4779 | Lobby_HideCallToActionPopup() 4780 | } 4781 | } 4782 | else if ( kind == eChallengeTimeSpanKind.EVENT_SPECIAL_2 ) 4783 | { 4784 | ItemFlavor storyEvent = event 4785 | file.onCallToActionFunc = void function() : ( storyEvent ) 4786 | { 4787 | StoryEventAboutDialog_SetEvent( storyEvent ) 4788 | AdvanceMenu( GetMenu( "StoryEventAboutDialog" ) ) 4789 | Lobby_HideCallToActionPopup() 4790 | } 4791 | } 4792 | else 4793 | { 4794 | Assert( false, "StoryChallengeEvent challenges only support all EVENT_SPECIAL or all EVENT_SPECIAL_2 kinds" ) 4795 | } 4796 | 4797 | string eventTitle = ItemFlavor_GetShortName( event ) 4798 | string eventDesc = ItemFlavor_GetShortDescription( event ) 4799 | 4800 | int eventType = ItemFlavor_GetType( event ) 4801 | thread function() : ( challengeDataForSeenPersistenceVarNames, eventTitle, eventDesc, eventType ) 4802 | { 4803 | EndSignal( uiGlobal.signalDummy, "Lobby_ShowCallToActionPopup" ) 4804 | 4805 | TabData lobbyTabData = GetTabDataForPanel( GetMenu( "LobbyMenu" ) ) 4806 | var popup = Hud_GetChild( file.panel, "PopupMessage" ) 4807 | 4808 | HudElem_SetRuiArg( popup, "titleText", eventTitle ) 4809 | HudElem_SetRuiArg( popup, "subText", "#S08E04_CHALLENGES_NOTIFICATION" ) 4810 | HudElem_SetRuiArg( popup, "detailText", "" ) 4811 | HudElem_SetRuiArg( popup, "unlockedString", "" ) 4812 | HudElem_SetRuiArg( popup, "buttonImage", $"rui/events/s12e04/challenges_logo", eRuiArgType.IMAGE ) 4813 | HudElem_SetRuiArg( popup, "forceFullIcon", false ) 4814 | 4815 | 4816 | HudElem_SetRuiArg( popup, "altStyle1Color", <0.55, 0.55, 0.55> ) 4817 | HudElem_SetRuiArg( popup, "altStyle2Color", <1.0, 1.0, 1.0> ) 4818 | HudElem_SetRuiArg( popup, "altStyle3Color", SrgbToLinear( GetKeyColor( COLORID_MENU_TEXT_LOOT_TIER0, eRarityTier.MYTHIC ) / 255.0 ) ) 4819 | 4820 | Lobby_MovePopupMessage( 0, 0.288 ) 4821 | 4822 | wait 0.2 4823 | 4824 | while ( GetActiveMenu() != GetMenu( "LobbyMenu" ) || !IsPanelActive( file.panel ) ) 4825 | WaitFrame() 4826 | 4827 | RuiSetGameTime( Hud_GetRui( popup ), "animStartTime", ClientTime() ) 4828 | 4829 | if( eventType == eItemType.calevent_story_challenges ) 4830 | EmitUISound( "UI_Menu_StoryEvent_PopUp" ) 4831 | else 4832 | EmitUISound( SOUND_BP_POPUP ) 4833 | 4834 | 4835 | 4836 | foreach ( StoryEventGroupChallengeData data in challengeDataForSeenPersistenceVarNames ) 4837 | Remote_ServerCallFunction( "ClientCallback_MarkStoryEventChallengesPopupAsSeen", data.challengeGroupGuid, data.challengeBlockIndex ) 4838 | 4839 | thread CallToActionPopupThink( popup, 10.0 ) 4840 | }() 4841 | 4842 | return true 4843 | } 4844 | 4845 | return false 4846 | } 4847 | 4848 | void function CallToActionPopupThink( var popup, float timeout ) 4849 | { 4850 | Signal( uiGlobal.signalDummy, "CallToActionPopupThink" ) 4851 | EndSignal( uiGlobal.signalDummy, "CallToActionPopupThink" ) 4852 | 4853 | OnThreadEnd( 4854 | function() : ( popup ) 4855 | { 4856 | Hud_Hide( popup ) 4857 | } 4858 | ) 4859 | 4860 | Hud_Show( popup ) 4861 | 4862 | float showedTime = 0 4863 | while ( showedTime < timeout ) 4864 | { 4865 | wait 0.25 4866 | 4867 | if( GetActiveMenu() == GetMenu( "LobbyMenu" ) && IsPanelActive( file.panel ) && !IsDialog( GetActiveMenu() ) ) 4868 | showedTime += 0.25 4869 | } 4870 | 4871 | while ( GetFocus() == popup ) 4872 | wait 0.25 4873 | } 4874 | 4875 | 4876 | void function CallToActionDialoguePopupAudioThink( var popup, StoryEventDialogueData data ) 4877 | { 4878 | Signal( uiGlobal.signalDummy, "CallToActionPopupAudioThink" ) 4879 | EndSignal( uiGlobal.signalDummy, "CallToActionPopupAudioThink" ) 4880 | EndSignal( uiGlobal.signalDummy, "CallToActionPopupAudioCancel" ) 4881 | 4882 | OnThreadEnd( 4883 | function() : ( data ) 4884 | { 4885 | foreach ( string alias in data.audioAliases ) 4886 | StopUISoundByName( alias ) 4887 | } 4888 | ) 4889 | 4890 | EmitUISound( "SQ_UI_InGame_CommChime" ) 4891 | 4892 | foreach ( string alias in data.audioAliases ) 4893 | { 4894 | var handle = EmitUISound( alias ) 4895 | 4896 | WaitSignal( handle, "OnSoundFinished" ) 4897 | } 4898 | } 4899 | 4900 | 4901 | void function CallToActionDialoguePopupThink( var popup, StoryEventDialogueData data ) 4902 | { 4903 | const float DIALOGUE_FADE_OUT_TIME = 1.0 4904 | 4905 | Signal( uiGlobal.signalDummy, "CallToActionPopupThink" ) 4906 | EndSignal( uiGlobal.signalDummy, "CallToActionPopupThink" ) 4907 | 4908 | table results = { hasSeen = false } 4909 | 4910 | OnThreadEnd( 4911 | function() : ( popup, data, results ) 4912 | { 4913 | if ( results.hasSeen && !file.dialogFlowDidCausePotentiallyInterruptingPopup ) 4914 | { 4915 | int guid = data.dialogueGroupGuid 4916 | int index = data.dialogueBlockIndex 4917 | Remote_ServerCallFunction( "ClientCallback_MarkStoryEventDialoguePopupAsSeen", guid, index ) 4918 | } 4919 | 4920 | Hud_Hide( popup ) 4921 | Signal( uiGlobal.signalDummy, "CallToActionPopupAudioCancel" ) 4922 | } 4923 | ) 4924 | 4925 | Hud_Show( popup ) 4926 | 4927 | float totalDuration = data.duration + DIALOGUE_FADE_OUT_TIME 4928 | float startTime = UITime() 4929 | 4930 | float timeToWaitForMarkedAsSeen = data.duration 4931 | 4932 | 4933 | while ( true ) 4934 | { 4935 | if ( GetActiveMenu() != GetMenu( "LobbyMenu" ) || !IsPanelActive( file.panel ) ) 4936 | break 4937 | 4938 | WaitFrame() 4939 | 4940 | float elapsedTime = UITime() - startTime 4941 | 4942 | if ( !results.hasSeen && elapsedTime >= timeToWaitForMarkedAsSeen ) 4943 | results.hasSeen = true 4944 | 4945 | if ( elapsedTime >= totalDuration ) 4946 | break 4947 | } 4948 | } 4949 | 4950 | 4951 | void function DialogFlow_DidCausePotentiallyInterruptingPopup() 4952 | { 4953 | file.dialogFlowDidCausePotentiallyInterruptingPopup = true 4954 | } 4955 | 4956 | 4957 | void function OnClickCallToActionPopup( var button ) 4958 | { 4959 | file.onCallToActionFunc() 4960 | } 4961 | 4962 | 4963 | void function Lobby_MovePopupMessage( int tabIndex, float additionalOffsetFrac = 0.0 ) 4964 | { 4965 | var button = Hud_GetChild( file.panel, "PopupMessage" ) 4966 | 4967 | var lobbyTabs = Hud_GetChild( GetMenu( "LobbyMenu" ), "TabsCommon" ) 4968 | 4969 | var tabButton = Hud_GetChild( lobbyTabs, "Tab0" ) 4970 | 4971 | int offset = 0 4972 | if ( tabIndex==0 ) 4973 | { 4974 | offset += Hud_GetX( tabButton ) 4975 | offset += int( Hud_GetWidth( tabButton ) * additionalOffsetFrac ) 4976 | } 4977 | else 4978 | { 4979 | for ( int i = 0; i < tabIndex; i++ ) 4980 | { 4981 | var bt = Hud_GetChild( lobbyTabs, "Tab" + i ) 4982 | offset += Hud_GetWidth( bt ) 4983 | offset += Hud_GetX( bt ) 4984 | offset += int( Hud_GetWidth( tabButton ) * additionalOffsetFrac ) 4985 | } 4986 | } 4987 | 4988 | Hud_SetX( button, offset ) 4989 | } 4990 | 4991 | 4992 | void function OpenGameModeSelectDialog() 4993 | { 4994 | while ( GetActiveMenu() != GetMenu( "LobbyMenu" ) ) 4995 | CloseActiveMenu() 4996 | 4997 | TabData lobbyTabData = GetTabDataForPanel( GetMenu( "LobbyMenu" ) ) 4998 | ActivateTab( lobbyTabData, Tab_GetTabIndexByBodyName( lobbyTabData, "PlayPanel" ) ) 4999 | 5000 | Remote_ServerCallFunction( "ClientCallback_ViewedModes" ) 5001 | file.newModesAcknowledged = true 5002 | 5003 | AdvanceMenu( GetMenu( "GamemodeSelectDialog" ) ) 5004 | } 5005 | 5006 | void function Lobby_ResetAreLobbyButtonsUpdating() 5007 | { 5008 | file.areLobbyButtonsUpdating = false 5009 | } --------------------------------------------------------------------------------