iw6-lui/lui/menuautonav.dec.lua
2024-09-12 17:25:45 +02:00

781 lines
17 KiB
Lua

local f0_local0 = module
local f0_local1, f0_local2 = ...
f0_local0( f0_local1, package.seeall )
CoD.PrintModuleLoad( _NAME )
INTERVAL_MS = 25
MAX_COUNTER = 200
MAX_COUNTER_GOBACK = 20
MAX_DURATION_COUNTER = 400
DISABLE_NAVIGATING_OVERLAY = 0
STATE = {
IDLE = 0,
WORKING_DROPBACK = 1,
WORKING_MOVEFORWARD = 2
}
LUI.MenuAutoNav.m_menuAutoNav = 0
s_navTableSP = {
{
destScreen = "resume_campaign",
route = {
{
topScreen = "main_menu",
action = "sp_button"
},
{
topScreen = "main_campaign",
action = "btn_resume_id"
},
{
topScreen = "resume_game_menu",
action = ""
}
}
},
{
destScreen = "mission_select",
route = {
{
topScreen = "main_menu",
action = "sp_button"
},
{
topScreen = "main_campaign",
action = "btn_mission_select_id"
},
{
topScreen = "level_select_iw6",
action = ""
}
}
},
{
destScreen = "mp",
route = {
{
topScreen = "main_menu",
action = "mp_button"
}
},
routeOverlayDelay = 5000
},
{
destScreen = "aliens",
route = {
{
topScreen = "main_menu",
action = "extinction_button"
}
},
routeOverlayDelay = 5000
},
{
destScreen = "squads",
route = {
{
topScreen = "main_menu",
action = "squadvssquad_button"
}
},
routeOverlayDelay = 5000
}
}
s_navTableMP = {
{
destScreen = "sp",
route = {
{
topScreen = "mp_main_menu",
action = "button_secondary"
},
{
topScreen = "main_choose_exe_popup_menu",
action = "main_choose_sp_button"
}
},
routeOverlayDelay = 5000
},
{
destScreen = "mp",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_7"
}
}
},
{
destScreen = "aliens",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_9"
}
}
},
{
destScreen = "squads",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_8"
}
}
},
{
destScreen = "xboxlive",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive",
action = ""
}
}
},
{
destScreen = "splitscreen",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_1"
},
{
topScreen = "menu_splitscreensignin",
action = ""
}
}
},
{
destScreen = "systemlink",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_2"
},
{
topScreen = "menu_systemlink",
action = ""
}
}
},
{
destScreen = "options",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_6"
}
}
},
{
destScreen = "xboxlive_findmatch",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive",
action = "find_match_button_id"
},
{
topScreen = "playlist_main",
action = ""
}
}
},
{
destScreen = "xboxlive_privatematch",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive",
action = "private_match_button_id"
},
{
topScreen = "menu_xboxlive_privatelobby",
action = ""
}
}
},
{
destScreen = "xboxlive_privatematch_gamesetup",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive",
action = "private_match_button_id"
},
{
topScreen = "menu_xboxlive_privatelobby",
action = "setup_match_button_id"
},
{
topScreen = "menu_systemlink_gamesetup_root",
action = ""
}
}
},
{
destScreen = "xboxlive_create_squad",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive",
action = "create_squad_button_id"
},
{
topScreen = "cac_edit_main",
action = ""
}
}
},
{
destScreen = "xboxlive_barracks_leaderboards",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive",
action = "barracks_button_id"
},
{
topScreen = "menu_barracks",
action = "leaderboard_button_id"
},
{
topScreen = "leaderboards",
action = ""
}
}
},
{
destScreen = "xboxlive_aliens_loadout",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive",
action = "aliens_loadout_btn_id"
},
{
topScreen = "aliens_cac_menu",
action = ""
}
}
},
{
destScreen = "xboxlive_aliens_leaderboards",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive",
action = "leaderboards_button_id"
},
{
topScreen = "mp_leaderboard_main",
action = ""
}
}
},
{
destScreen = "squadvssquad_squad_assault",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive*",
action = "squads_mode_button_squad_assault"
}
}
},
{
destScreen = "squadvssquad_squad_vs_squad",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive*",
action = "squads_mode_button_squad_vs_squad"
}
}
},
{
destScreen = "squadvssquad_safeguard",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive*",
action = "squads_mode_button_safeguard"
}
}
},
{
destScreen = "squadvssquad_wargame",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive*",
action = "squads_mode_button_wargame"
}
}
},
{
destScreen = "squadvssquad_squad_reports",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_0"
},
{
topScreen = "menu_xboxlive*",
action = "squads_mode_button_squad_reports"
},
{
topScreen = "squads_hq_menu*",
action = "squads_mode_button_squad_reports"
}
}
},
{
destScreen = "squadvssquad_local_play",
route = {
{
topScreen = "mp_main_menu",
action = "btn_MPMain_1"
},
{
topScreen = "menu_splitscreensignin",
action = ""
}
}
}
}
function new()
local f1_local0 = {}
setmetatable( f1_local0, {
__index = _M
} )
f1_local0.m_state = STATE.IDLE
f1_local0.m_controller = -1
f1_local0.m_counter = 0
f1_local0.m_durationCounter = 0
f1_local0.m_currentRoute = {}
f1_local0.m_root = 0
f1_local0.m_timerElement = 0
return f1_local0
end
function Reset()
if LUI.MenuAutoNav.ShouldCloseOverlay() then
LUI.MenuAutoNav.CloseOverlay()
end
local f2_local0 = LUI.MenuAutoNav.GetInstance()
if f2_local0.m_timerElement and f2_local0.m_timerElement ~= 0 and f2_local0.m_root and f2_local0.m_root ~= 0 then
f2_local0.m_root:removeElement( f2_local0.m_timerElement )
f2_local0.m_timerElement:close()
end
f2_local0.m_state = STATE.IDLE
f2_local0.m_controller = -1
f2_local0.m_counter = 0
f2_local0.m_durationCounter = 0
f2_local0.m_currentRoute = {}
f2_local0.m_root = 0
f2_local0.m_timerElement = 0
end
function GetInstance()
if LUI.MenuAutoNav.m_menuAutoNav == 0 then
LUI.MenuAutoNav.m_menuAutoNav = LUI.MenuAutoNav.new()
end
return LUI.MenuAutoNav.m_menuAutoNav
end
function IsRunning()
local f4_local0 = LUI.MenuAutoNav.GetInstance()
if f4_local0.m_state ~= STATE.IDLE then
return true
else
return false
end
end
function Stop()
if IsRunning() then
Reset()
end
end
function SendButtonPress( f6_arg0, f6_arg1, f6_arg2 )
local f6_local0 = {
name = "gamepad_button",
immediate = true,
down = true,
button = f6_arg0,
qualifier = f6_arg1,
controller = f6_arg2
}
local f6_local1 = Engine.GetLuiRoot()
if not f6_local1 then
return false
else
f6_local1:dispatchEventToRoot( f6_local0 )
return true
end
end
function FindRouteEntry( f7_arg0 )
local f7_local0 = LUI.MenuAutoNav.GetInstance()
assert( f7_arg0 )
local f7_local1 = nil
if Engine.IsMultiplayer() then
f7_local1 = s_navTableMP
else
f7_local1 = s_navTableSP
end
if f7_local1 then
for f7_local5, f7_local6 in ipairs( f7_local1 ) do
if f7_local6.route and string.lower( f7_arg0 ) == string.lower( f7_local6.destScreen ) then
return f7_local6
end
end
end
return nil
end
function Yield()
local f8_local0 = LUI.MenuAutoNav.GetInstance()
f8_local0.m_counter = f8_local0.m_counter + 1
if f8_local0.m_counter > MAX_COUNTER then
DebugPrint( "MenuAutoNav: Timeout!" )
LUI.MenuAutoNav.Stop()
return
else
end
end
function IsMenuInCurrentRoute( f9_arg0 )
local f9_local0 = LUI.MenuAutoNav.GetInstance()
assert( f9_arg0 )
local f9_local1 = LUI.MenuAutoNav.GetInstance()
if f9_local1.m_currentRoute then
for f9_local5, f9_local6 in ipairs( f9_local1.m_currentRoute ) do
if string.lower( f9_local6.topScreen ) == string.lower( f9_arg0 ) then
return true, f9_local5
end
end
end
return false, -1
end
function HandleMenuAutoNavOverlayRefresh( f10_arg0, f10_arg1 )
if LUI.MenuAutoNav.ShouldCloseOverlay() then
LUI.MenuAutoNav.CloseOverlay()
end
end
function menu_auto_nav_overlay()
return {
type = "UIElement",
id = "menu_auto_nav_overlay_id",
states = {
default = {
topAnchor = true,
bottomAnchor = true,
leftAnchor = true,
rightAnchor = true,
left = 0,
right = 0,
top = 0,
bottom = 0
}
},
handlers = {
menu_auto_nav_overlay_refresh = HandleMenuAutoNavOverlayRefresh
},
children = {
{
type = "UIImage",
id = "menu_auto_nav_background_id",
states = {
default = CoD.ColorizeState( Swatches.Overlay.Color, {
topAnchor = true,
bottomAnchor = true,
leftAnchor = true,
rightAnchor = true,
left = 0,
right = 0,
top = 0,
bottom = 0,
material = RegisterMaterial( "white" ),
alpha = 1
} )
},
children = {
{
type = "generic_loading_widget",
properties = {
message = Engine.Localize( "@SPEECH_NAVIGATING" )
}
}
}
},
{
type = "UITimer",
id = "menu_auto_nav_overlay_timer",
properties = {
event = "menu_auto_nav_overlay_refresh",
interval = 25,
disposable = false,
broadcastToRoot = false
}
}
}
}
end
function OpenOverlay( f12_arg0 )
if DISABLE_NAVIGATING_OVERLAY ~= 0 then
return
end
local f12_local0 = Engine.GetLuiRoot()
if not f12_local0 then
DebugPrint( "MenuAutoNavOverlay: Error, no root found. Cannot open overlay." )
return
elseif f12_local0.m_menuAutoNavOverlay then
DebugPrint( "MenuAutoNavOverlay: Ignoring open request because we are already open." )
return
end
local m_menuAutoNavOverlay = LUI.MenuBuilder.buildItems( menu_auto_nav_overlay(), {}, f12_local0 )
m_menuAutoNavOverlay:animateToState( "default" )
m_menuAutoNavOverlay:setPriority( 400 )
f12_local0:addElement( m_menuAutoNavOverlay )
f12_local0.m_menuAutoNavOverlay = m_menuAutoNavOverlay
if f12_arg0 and f12_arg0 > 0 then
f12_local0.m_menuAutoNavOverlayDelay = f12_arg0
f12_local0.m_menuAutoNavOverlayTimeStamp = 0
else
f12_local0.m_menuAutoNavOverlayDelay = 0
f12_local0.m_menuAutoNavOverlayTimeStamp = 0
end
end
function CloseOverlay()
local f13_local0 = Engine.GetLuiRoot()
if not f13_local0 then
DebugPrint( "MenuAutoNavOverlay: Error, no root found, therefore we cannot close overlay." )
return
elseif not f13_local0.m_menuAutoNavOverlay then
DebugPrint( "MenuAutoNavOverlay: Warning, ignoring attempt to close overlay because it is already closed." )
return
else
f13_local0:removeElement( f13_local0.m_menuAutoNavOverlay )
f13_local0.m_menuAutoNavOverlay = nil
f13_local0.m_menuAutoNavOverlayDelay = nil
f13_local0.m_menuAutoNavOverlayTimeStamp = nil
end
end
function ShouldCloseOverlay()
if LUI.MenuAutoNav.IsRunning() then
return false
end
local f14_local0 = Engine.GetLuiRoot()
if not f14_local0 then
return false
elseif not f14_local0.m_menuAutoNavOverlay then
return false
elseif f14_local0.m_menuAutoNavOverlayDelay and f14_local0.m_menuAutoNavOverlayTimeStamp and f14_local0.m_menuAutoNavOverlayDelay > 0 then
local f14_local1 = Engine.GetMilliseconds()
if f14_local0.m_menuAutoNavOverlayTimeStamp == 0 then
f14_local0.m_menuAutoNavOverlayTimeStamp = f14_local1 + f14_local0.m_menuAutoNavOverlayDelay
return false
elseif f14_local1 < f14_local0.m_menuAutoNavOverlayTimeStamp then
return false
end
end
return true
end
function HandleTimerEvent( f15_arg0, f15_arg1 )
local f15_local0 = LUI.MenuAutoNav.GetInstance()
if not f15_local0.m_currentRoute then
DebugPrint( "MenuAutoNav: Current route is empty. Bailing" )
Stop()
return
elseif #f15_local0.m_currentRoute < 1 then
DebugPrint( "MenuAutoNav: Current route is empty. Bailing" )
Stop()
return
end
f15_local0.m_durationCounter = f15_local0.m_durationCounter + 1
if f15_local0.m_durationCounter > MAX_DURATION_COUNTER then
DebugPrint( "MenuAutoNav: Max duration counter exceeded. Bailing" )
Stop()
return
elseif f15_local0.m_state == STATE.WORKING_DROPBACK then
if LUI.FlowManager.IsTopMenuModal() then
DebugPrint( "MenuAutoNav: A modal menu popped up while attempting to find a starting point. We are stopping here." )
LUI.MenuAutoNav.Stop()
return
end
local f15_local1 = LUI.FlowManager.GetTopOpenAndVisibleMenuName()
if not f15_local1 then
Yield()
return
end
local f15_local2, f15_local3 = nil
f15_local2, f15_local3 = IsMenuInCurrentRoute( f15_local1 )
if not f15_local2 or f15_local2 ~= true then
f15_local0.m_counter = f15_local0.m_counter + 1
if f15_local0.m_counter <= MAX_COUNTER_GOBACK then
return
elseif string.lower( f15_local1 ) == string.lower( "main_menu" ) or string.lower( f15_local1 ) == string.lower( "mp_main_menu" ) then
DebugPrint( "MenuAutoNav: Menu we are looking for not found, and we cannot move back any more. Stopping!" )
LUI.MenuAutoNav.Stop()
return
elseif string.lower( f15_local1 ) == string.lower( "menu_splitscreensignin" ) then
LUI.FlowManager.RequestLeaveMenuByName( "menu_splitscreensignin" )
f15_local0.m_counter = 0
elseif LUI.MenuAutoNav.SendButtonPress( "secondary", nil, f15_local0.m_controller ) == true then
f15_local0.m_counter = 0
end
return
elseif f15_local3 > 1 then
else
f15_local0.m_state = STATE.WORKING_MOVEFORWARD
f15_local0.m_counter = 0
end
while f15_local3 > 1 do
table.remove( f15_local0.m_currentRoute, 1 )
f15_local3 = f15_local3 - 1
end
f15_local0.m_state = STATE.WORKING_MOVEFORWARD
f15_local0.m_counter = 0
end
if f15_local0.m_state == STATE.WORKING_MOVEFORWARD then
local f15_local1 = Engine.GetLuiRoot()
if f15_local1 == nil then
DebugPrint( "MenuAutoNav: Error, we have no root! Stopping" )
Stop()
return
end
local f15_local2 = f15_local0.m_currentRoute[1]
if string.lower( f15_local2.action ) == string.lower( "" ) then
DebugPrint( "MenuAutoNav: Our current route action is empty, therefore we should be at our destination. Done." )
Stop()
return
elseif string.lower( f15_local2.action ) == string.lower( "button_secondary" ) then
if LUI.MenuAutoNav.SendButtonPress( "secondary", nil, f15_local0.m_controller ) ~= true then
Yield()
return
end
else
local f15_local3 = f15_local1:getFirstDescendentById( f15_local2.action )
if not f15_local3 then
Yield()
return
elseif f15_local3.disabled and not f15_local3.locked then
Yield()
return
end
f15_local3:processEvent( {
name = "button_action",
controller = f15_local0.m_controller
} )
f15_local3:processEvent( {
name = "button_down",
controller = f15_local0.m_controller
} )
end
table.remove( f15_local0.m_currentRoute, 1 )
if #f15_local0.m_currentRoute >= 1 then
f15_local0.m_counter = 0
return
end
DebugPrint( "MenuAutoNav: Done!" )
end
Stop()
end
function DebugDumpRoute( f16_arg0 )
local f16_local0 = LUI.MenuAutoNav.GetInstance()
DebugPrint( "----------------------------------------------------------------" )
DebugPrint( "MenuAutoNav: Route:" )
for f16_local4, f16_local5 in ipairs( f16_arg0 ) do
DebugPrint( " #" .. tostring( f16_local4 ) .. " : topScreen=\"" .. tostring( f16_local5.topScreen ) .. "\", action=\"" .. tostring( f16_local5.action ) .. "\"" )
end
DebugPrint( "----------------------------------------------------------------" )
end
function Goto( f17_arg0, f17_arg1 )
assert( f17_arg0 )
local f17_local0 = LUI.MenuAutoNav.GetInstance()
if IsRunning() then
DebugPrint( "MenuAutoNav: Error, an outstanding auto navigation is still working. Unable to navigate to \"" .. f17_arg0 .. "\"!" )
return false
end
local f17_local1 = FindRouteEntry( f17_arg0 )
if not f17_local1 then
DebugPrint( "MenuAutoNav: Error, unable to find a route to \"" .. f17_arg0 .. "\"!" )
return false
end
local f17_local2 = f17_local1.route
local f17_local3 = f17_local1.routeOverlayDelay or 0
local f17_local4 = Engine.GetLuiRoot()
if f17_local4 == nil then
DebugPrint( "MenuAutoNav: Error, we do not appear to have a root! Unable to create timer for autonav process!" )
return false
end
f17_local0.m_controller = f17_arg1
f17_local0.m_counter = 0
f17_local0.m_currentRoute = {}
for f17_local8, f17_local9 in ipairs( f17_local2 ) do
table.insert( f17_local0.m_currentRoute, f17_local9 )
end
f17_local0.m_state = STATE.WORKING_DROPBACK
self = LUI.UITimer.new( INTERVAL_MS, {
name = "menu_auto_nav_timer"
} )
self.id = "MenuAutoNavTimer"
f17_local4:addElement( self )
f17_local0.m_root = f17_local4
f17_local0.m_timerElement = self
DebugPrint( "MenuAutoNav: Goto( \"" .. f17_arg0 .. "\") started" )
LUI.MenuAutoNav.OpenOverlay( f17_local3 )
return true
end
LockTable( _M )