iw7-mod/data/cdata/ui_scripts/MainMenu/MPMainMenu.lua
2024-08-10 03:13:11 +03:00

450 lines
18 KiB
Lua

LUI.FlowManager.RegisterFenceGroup("MPMainMenu", {
"mp",
"mpInstall",
"onlineServices",
"onlineData",
"patch",
"exchange",
"playlists",
"dailyReward"
})
LUI.FlowManager.RequestSetStack("MPMainMenu", {
{ name = "MainLockoutMenu" },
{ name = "MainMenu" }
})
local HandleSplitscreenRefresh = function ()
if Engine.SplitscreenPlayerCount() > 0 then
local activeController = Engine.GetFirstActiveController()
if activeController and Engine.IsUserSignedIn(activeController) then
Engine.PLMRefreshData()
end
end
end
local HandleBackButton = function(f2_arg0, f2_arg1)
local f2_local0 = Engine.HasActiveLocalClient( f2_arg1.controller )
if f2_local0 then
f2_local0 = not Engine.IsActiveLocalClientPrimary( f2_arg1.controller )
end
if f2_local0 then
local f2_local1 = LUI.FlowManager.GetScopedData( f2_arg0 )
if f2_local1 and f2_local1.focusedPage and f2_local1.focusedPage > 2 then
f2_arg0:dispatchEventToRoot( {
name = "lobby_slide_left",
immediate = true
} )
end
elseif Lobby.IsNotAloneInPrivateParty() then
if Engine.IsXB3() then
LUI.FlowManager.RequestPopupMenu( f2_arg0, "RateLimitedLeaveCommonMPMainMenuPopup", true, f2_arg1.controller, false, {
menu = f2_arg0,
rateLimitIntervalMS = 5000,
rateLimitAttempts = 3
} )
else
LUI.FlowManager.RequestPopupMenu( f2_arg0, "LeaveCommonMPMainMenuPopup", true, f2_arg1.controller, false, {
menu = f2_arg0
} )
end
else
Lobby.LeaveCommonMPMainMenu( f2_arg0, f2_arg1.controller )
end
return true
end
local InitializeMainMenu = function(arg0, arg1)
local activeController = Engine.GetFirstActiveController()
if Engine.GetDvarBool("xblive_competitionmatch") then
Engine.SetDvarBool("xblive_competitionmatch", false)
Engine.Exec("set remove_mlg_rules 1")
end
Engine.ExecNow(MPConfig.default_xboxlive, activeController)
end
local UpdatePlayerData = function(arg0)
local postShipFlag = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.Ranked, "postShipFlags", 3)
if postShipFlag == nil or postShipFlag == false then
local archetypePreferences = {
{ "head", 1, "head_160", "head_287" },
{ "head", 3, "head_167", "head_294" },
{ "body", 1, "body_90", "body_217" },
{ "body", 3, "body_97", "body_224" }
}
for _, pref in ipairs(archetypePreferences) do
local currentValue = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.RankedLoadouts, "squadMembers", "archetypePreferences", pref[2], pref[1])
if currentValue ~= nil and currentValue == pref[3] then
Engine.SetPlayerDataEx(arg0, CoD.StatsGroup.RankedLoadouts, "squadMembers", "archetypePreferences", pref[2], pref[1], pref[4])
end
end
local headData = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.RankedLoadouts, "squadMembers", "head")
local bodyData = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.RankedLoadouts, "squadMembers", "body")
if headData ~= nil and (headData == 160 or headData == 167) then
Engine.SetPlayerDataEx(arg0, CoD.StatsGroup.RankedLoadouts, "squadMembers", "head", headData == 160 and 287 or 294)
end
if bodyData ~= nil and (bodyData == 90 or bodyData == 97) then
Engine.SetPlayerDataEx(arg0, CoD.StatsGroup.RankedLoadouts, "squadMembers", "body", bodyData == 90 and 217 or 224)
end
-- Same operation for private loadouts
for _, pref in ipairs(archetypePreferences) do
local currentValue = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.PrivateLoadouts, "squadMembers", "archetypePreferences", pref[2], pref[1])
if currentValue ~= nil and currentValue == pref[3] then
Engine.SetPlayerDataEx(arg0, CoD.StatsGroup.PrivateLoadouts, "squadMembers", "archetypePreferences", pref[2], pref[1], pref[4])
end
end
local privateHeadData = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.PrivateLoadouts, "squadMembers", "head")
local privateBodyData = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.PrivateLoadouts, "squadMembers", "body")
if privateHeadData ~= nil and (privateHeadData == 160 or privateHeadData == 167) then
Engine.SetPlayerDataEx(arg0, CoD.StatsGroup.PrivateLoadouts, "squadMembers", "head", privateHeadData == 160 and 287 or 294)
end
if privateBodyData ~= nil and (privateBodyData == 90 or privateBodyData == 97) then
Engine.SetPlayerDataEx(arg0, CoD.StatsGroup.PrivateLoadouts, "squadMembers", "body", privateBodyData == 90 and 217 or 224)
end
local characterHead = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.RankedLoadouts, "squadMembers", "head")
local characterBody = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.RankedLoadouts, "squadMembers", "body")
local characterSuper = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.RankedLoadouts, "squadMembers", "archetypeSuper")
local characterArchetype = Engine.GetPlayerDataEx(arg0, CoD.StatsGroup.RankedLoadouts, "squadMembers", "archetype")
if characterHead ~= nil and characterBody ~= nil then
FrontEndScene.SetCharacterModelsByIndex(FrontEndScene.ClientCharacters.Self, characterBody, characterHead)
end
if characterSuper ~= nil and characterArchetype ~= nil then
FrontEndScene.SetWeaponForSuper(FrontEndScene.ClientCharacters.Self, characterSuper, characterArchetype)
FrontEndScene.PlayIdleForSuper(FrontEndScene.ClientCharacters.Self, characterSuper, characterArchetype)
end
Engine.SetPlayerDataEx(arg0, CoD.StatsGroup.Ranked, "postShipFlags", 3, true)
Engine.ExecNow("uploadstats", arg0)
end
end
local LoadMainMenu = function(controller)
UpdatePlayerData(controller)
end
-- Function to set up the main menu for multiplayer
local SetupMainMenu = function(menu, controller)
-- Disable UI version display and online requirement
Engine.SetDvarString("ui_version_show", "0")
Engine.SetDvarBool("ui_onlineRequired", false)
-- Set up front end scene
FrontEndScene.CurrentMissionTeam = MissionDirector.InvalidTeamID
FrontEndScene.SetScene("mp_main")
-- Get controller index
local controllerIndex = controller and controller.controller or Engine.GetFirstActiveController()
-- Check title update requirement
CheckTURequirement(menu, controllerIndex)
-- Set up player character based on loadout data
local loadoutData = DataSources.alwaysLoaded.playerData.MP.rankedloadouts.squadMembers
local rigAnim = Cac.GetRigFrontEndProfileAnim(loadoutData.archetype:GetValue(controllerIndex))
FrontEndScene.SetCharacterModelsByIndex(
FrontEndScene.ClientCharacters.Profile,
loadoutData.body:GetValue(controllerIndex),
loadoutData.head:GetValue(controllerIndex)
)
ClientCharacter.SetCharacterWeapons(FrontEndScene.ClientCharacters.Profile, nil)
ClientCharacter.PlayCharacterAnim(FrontEndScene.ClientCharacters.Profile, rigAnim)
ClientCharacter.SetCharacterVisible(FrontEndScene.ClientCharacters.Profile, true)
-- Set up weapon visibility
ClientWeapon.SetWeaponIsViewModel(0, true)
ClientWeapon.SetWeaponVisible(0, false)
-- Initialize main menu
InitializeMainMenu(menu, controller)
-- Sync unlocks if enabled
if Engine.GetDvarBool("enable_unlock_sync") then
local unlockTypes = {}
for _, unlockType in pairs(AAR.UnlockTypes) do
table.insert(unlockTypes, unlockType)
end
Rewards.SyncUnlocks(controllerIndex, unlockTypes, #unlockTypes)
end
-- Start private party if not already in one
if not Lobby.IsInPrivateParty() then
Engine.ExecNow("xstartprivateparty", controllerIndex)
end
-- Handle events related to party and CRM (Customer Relationship Management)
menu:registerEventHandler("not_below_blocking_fence", function()
Engine.SetDvarBool("cg_mlg_gamebattles_match", false)
if not MLG.IsGameBattleMatch() then
Lobby.WakePrivateParty(controllerIndex)
end
end)
-- Set up party UI and CRM
Lobby.SetPartyUIRoot(PartyUIRoot.MAIN_MENU)
menu.nextLocation = CRM.locations.MP_MOTD
CRM.OpenNextCRMWindow(menu)
menu:addEventHandler("gain_focus", CRM.OpenNextCRMWindow)
menu:addEventHandler("restore_focus", CRM.OpenNextCRMWindow)
end
-- Post-load function to handle game battles and other settings
local PostLoadFunc = function(menu, controllerIndex, controller)
if GAMEBATTLES.ScheduleRefreshRequest then
GAMEBATTLES.ScheduleRefreshRequest = false
OpenGameBattlesLobby(controllerIndex)
else
local currentMatch = GAMEBATTLES.GetCurrentMatch(controllerIndex)
if currentMatch then
if GAMEBATTLES.MatchForfeitWinningTeamIndex ~= 0 then
GAMEBATTLES.ShowMatchForfeitPopup(controllerIndex, currentMatch, GAMEBATTLES.MatchForfeitWinningTeamIndex)
GAMEBATTLES.MatchForfeitWinningTeamIndex = 0
else
local victoryInfo, progressInfo = GAMEBATTLES.GetMatchProgressInfo(currentMatch)
if progressInfo then
local alliesWins, axisWins, matchVictory = GAMEBATTLES.GetMatchVictoryInfo(currentMatch)
if not matchVictory then
LUI.FlowManager.RequestPopupMenu(menu, "MLGGamebattlesMatchResultsPopup", false, controllerIndex, false, {
controllerIndex = controllerIndex,
gbMatch = currentMatch,
alliesWins = alliesWins,
axisWins = axisWins
})
end
else
local dsAcquisitionState = MLG.GetGameBattleDSAcquisitionState(controllerIndex)
if dsAcquisitionState == GAMEBATTLES.MLG_DS_ACQUISITION_STATE.COULD_NOT_ACQUIRE or dsAcquisitionState == GAMEBATTLES.MLG_DS_ACQUISITION_STATE.ACQUISITION_ERROR then
MLG.ResetGameBattleDSAcquisitionState()
LUI.FlowManager.RequestPopupMenu(menu, "MLGGamebattlesMatchCancelledPopup", false, controllerIndex, false, {
matchID = currentMatch.matchId
})
end
end
end
MLG.ResetGameBattleMatchId(controllerIndex)
end
end
-- Additional setup and event handling
assert(menu.bindButton)
menu.isSignInMenu = true
menu.bindButton:addEventHandler("button_secondary", HandleBackButton)
menu:addEventHandler("menu_create", SetupMainMenu)
-- Adjust UI elements based on various conditions
local adjustButtonDescription = function()
local _, top, _, bottom = menu.ButtonDescription:getLocalRect()
local buttonSpacing = menu.MPMainMenuButtons.buttonSpacing
menu.ButtonDescription:SetTop(top - buttonSpacing)
menu.ButtonDescription:SetBottom(bottom - buttonSpacing)
end
if not CONDITIONS.IsGameBattlesAllowed() then
adjustButtonDescription()
end
if not CODTV.IsCODTVEnabled() then
adjustButtonDescription()
end
if not CONDITIONS.IsStoreAllowed(menu) then
adjustButtonDescription()
end
if Engine.GetDvarFloat("r_filmGrainAtten") == 1 then
Engine.SetDvarFloat("r_filmGrainAtten", 0.25)
Engine.ExecNow("profile_setFilmGrain " .. tostring(0.25), controllerIndex)
end
-- Handle NAT type warning
local natType = Lobby.GetNATType()
if natType then
if natType == "NETWORK_STRICT" and not Engine.GetDvarBool("strict_nat_warning_viewed") then
LUI.FlowManager.RequestPopupMenu(menu, "strict_nat_warning", true, controllerIndex, false, data)
Engine.SetDvarBool("strict_nat_warning_viewed", true)
end
menu:processEvent({
name = "add_button_helper_text",
button_ref = "nat",
helper_text = Engine.Localize("NETWORK_YOURNATTYPE", natType),
side = "right",
clickable = false
})
end
Engine.SetDvarInt("lui_mc_numGamesFinishedInLobby", 0)
MissionDirector.PlayTeamMusic()
Engine.StopMenuVideo()
-- Handle trial license popup
local scopedData = LUI.FlowManager.GetScopedData(menu)
if CONDITIONS.IsTrialLicense() and not scopedData.trialPopupShown then
scopedData.trialPopupShown = true
LUI.FlowManager.RequestPopupMenu(menu, "TrialFullWindow", true, controllerIndex, false)
end
menu:addElement(Lobby.GetMPMapMaterialStreamer())
LoadMainMenu(controllerIndex)
end
function MPMainMenu(menu, controller)
local self = LUI.UIHorizontalNavigator.new()
self.id = "MPMainMenu"
-- Determine controller index
local controllerIndex = controller and controller.controllerIndex
if not controllerIndex and not Engine.InFrontend() then
controllerIndex = self:getRootController()
end
assert(controllerIndex)
-- Initialize the main menu
InitializeMainMenu(self, controllerIndex, controller)
self:playSound("menu_open")
-- Helper bar
local HelperBar = MenuBuilder.BuildRegisteredType("ButtonHelperBar", {
controllerIndex = controllerIndex
})
HelperBar.id = "HelperBar"
HelperBar:SetAnchorsAndPosition(0, 0, 1, 0, 0, 0, _1080p * -85, 0)
self:addElement(HelperBar)
self.HelperBar = HelperBar
-- Button description
local ButtonDescription = MenuBuilder.BuildRegisteredType("ButtonDescriptionText", {
controllerIndex = controllerIndex
})
ButtonDescription.id = "ButtonDescription"
ButtonDescription.Description:SetRight(_1080p * 415, 0)
ButtonDescription:SetAnchorsAndPosition(0, 1, 0, 1, _1080p * 130, _1080p * 645, _1080p * 594, _1080p * 694)
self:addElement(ButtonDescription)
self.ButtonDescription = ButtonDescription
-- Social feed
local SocialFeed = MenuBuilder.BuildRegisteredType("SocialFeed", {
controllerIndex = controllerIndex
})
SocialFeed.id = "SocialFeed"
SocialFeed:SetAnchorsAndPosition(0, 1, 0, 1, 0, _1080p * 1920, _1080p * 965, _1080p * 995)
self:addElement(SocialFeed)
self.SocialFeed = SocialFeed
-- Main menu buttons
local MPMainMenuButtons = MenuBuilder.BuildRegisteredType("MPMainMenuButtons", {
controllerIndex = controllerIndex
})
MPMainMenuButtons.id = "MPMainMenuButtons"
MPMainMenuButtons:SetAnchorsAndPosition(0, 1, 0, 1, _1080p * 130, _1080p * 630, _1080p * 360, _1080p * 564)
self:addElement(MPMainMenuButtons)
self.MPMainMenuButtons = MPMainMenuButtons
-- Friends widget
local FriendsElement = MenuBuilder.BuildRegisteredType("online_friends_widget", {
controllerIndex = controllerIndex
})
FriendsElement.id = "FriendsElement"
FriendsElement:SetFont(FONTS.GetFont(FONTS.Dev.File))
FriendsElement:SetAlignment(LUI.Alignment.Left)
FriendsElement:SetAnchorsAndPosition(0, 1, 0, 1, _1080p * 1420, _1080p * 1920, _1080p * 1026, _1080p * 1071)
self:addElement(FriendsElement)
self.FriendsElement = FriendsElement
-- Lobby members list
local LobbyMembers = MenuBuilder.BuildRegisteredType("LobbyMembers", {
controllerIndex = controllerIndex
})
LobbyMembers.id = "LobbyMembers"
LobbyMembers:SetAnchorsAndPosition(1, 0, 0, 1, _1080p * -700, 0, _1080p * 273, _1080p * 917)
self:addElement(LobbyMembers)
self.LobbyMembers = LobbyMembers
-- COD logo
local CODLogo = LUI.UIImage.new()
CODLogo.id = "CODLogo"
CODLogo:setImage(RegisterMaterial("cod_logo"), 0)
CODLogo:SetAnchorsAndPosition(0, 0, 0, 0, _1080p * 108, _1080p * -1272, _1080p * 120, _1080p * -825)
self:addElement(CODLogo)
self.CODLogo = CODLogo
-- Menu title
local MenuTitle = LUI.UIStyledText.new()
MenuTitle.id = "MenuTitle"
MenuTitle:setText(ToUpperCase(Engine.Localize("MENU_MULTIPLAYER")), 0)
MenuTitle:SetFontSize(50 * _1080p)
MenuTitle:SetFont(FONTS.GetFont(FONTS.MainMedium.File))
MenuTitle:SetAlignment(LUI.Alignment.Left)
MenuTitle:SetStartupDelay(1250)
MenuTitle:SetLineHoldTime(400)
MenuTitle:SetAnimMoveTime(300)
MenuTitle:SetEndDelay(1000)
MenuTitle:SetCrossfadeTime(500)
MenuTitle:SetAutoScrollStyle(LUI.UIStyledText.AutoScrollStyle.ScrollH)
MenuTitle:SetMaxVisibleLines(1)
MenuTitle:SetDecodeLetterLength(25)
MenuTitle:SetDecodeMaxRandChars(3)
MenuTitle:SetDecodeUpdatesPerLetter(4)
MenuTitle:SetAnchorsAndPosition(0, 1, 0, 1, _1080p * 130, _1080p * 660, _1080p * 296.5, _1080p * 346.5)
self:addElement(MenuTitle)
self.MenuTitle = MenuTitle
-- Double XP notifications
local DoubleXPNotifications = MenuBuilder.BuildRegisteredType("DoubleXPNotifications", {
controllerIndex = controllerIndex
})
DoubleXPNotifications.id = "DoubleXPNotifications"
DoubleXPNotifications:SetScale(-0.5, 0)
DoubleXPNotifications:SetAnchorsAndPosition(0.5, 0.5, 0, 1, _1080p * -370, _1080p * -114, _1080p * 104, _1080p * 232)
self:addElement(DoubleXPNotifications)
self.DoubleXPNotifications = DoubleXPNotifications
-- Button helper function
self.addButtonHelperFunction = function(arg0, arg1)
arg0:AddButtonHelperText({
helper_text = Engine.Localize("LUA_MENU_SELECT"),
button_ref = "button_primary",
side = "left",
clickable = true
})
arg0:AddButtonHelperText({
helper_text = Engine.Localize("MENU_BACK"),
button_ref = "button_secondary",
side = "left",
priority = 1,
clickable = true
})
arg0:AddButtonHelperText({
helper_text = Engine.Localize("LUA_MENU_OPTIONS_CAPS"),
button_ref = "button_start",
side = "left",
priority = 4,
clickable = true
})
end
self:addEventHandler("menu_create", self.addButtonHelperFunction)
-- Bind button handler
local bindButton = LUI.UIBindButton.new()
bindButton.id = "selfBindButton"
self:addElement(bindButton)
self.bindButton = bindButton
self.bindButton:addEventHandler("button_start", function(arg0, arg1)
ACTIONS.OpenMenu("OptionsMenu", true, arg1.controller or controllerIndex)
end)
PostLoadFunc(self, controllerIndex, controller)
return self
end
MenuBuilder.m_types["MPMainMenu"] = MPMainMenu
LUI.FlowManager.RegisterStackPushBehaviour( "MPMainMenu", PushFunc )