course_stopped_by_pause_menu= false local prompt_text= { Start= THEME:GetString("ScreenGameplay", "GiveUpStartText"), Select= THEME:GetString("ScreenGameplay", "GiveUpSelectText"), Back= THEME:GetString("ScreenGameplay", "GiveUpBackText"), } local prompt_actor= false local screen_gameplay= false local menu_items= {[PLAYER_1]= {}, [PLAYER_2]= {}} local menu_frames= {} local menu_choices= { "continue_playing", "restart_song", "forfeit_song", } if GAMESTATE:IsCourseMode() then menu_choices= { "continue_playing", "skip_song", "forfeit_course", "end_course", } end local menu_spacing= 32 local menu_bg_width= _screen.w * .2 local menu_text_width= _screen.w * .35 local menu_x= {[PLAYER_1]= THEME:GetMetric(Var "LoadingScreen","PlayerP1MiscX"), [PLAYER_2]= THEME:GetMetric(Var "LoadingScreen","PlayerP2MiscX")} local menu_y= _screen.cy - (#menu_choices * .5 * menu_spacing) local current_menu_choice= {} local menu_is_showing= {} local enabled_players= {} local function create_menu_item(pn, x, y, item_name) return Def.BitmapText{ Font= "Common Condensed", Text= THEME:GetString("PauseMenu", item_name), InitCommand= function(self) self:xy(x, y) table.insert(menu_items[pn], self) self:playcommand("LoseFocus") end, LoseFocusCommand= function(self) self:diffusealpha(0.5) end, GainFocusCommand= function(self) self:diffusealpha(1) end, } end local function create_menu_frame(pn, x, y) local frame= Def.ActorFrame{ InitCommand= function(self) self:xy(x, y):playcommand("Hide") menu_frames[pn]= self end, ShowCommand= function(self) self:visible(true) end, HideCommand= function(self) self:visible(false) end, Def.Quad{ InitCommand= function(self) self:setsize(menu_bg_width, menu_spacing * (#menu_choices + 1)) :y(-menu_spacing):vertalign(top) :diffuse{0, 0, 0, .75} :playcommand("Hide") end, }, } for i, choice in ipairs(menu_choices) do frame[#frame+1]= create_menu_item(pn, 0, (i-1)*menu_spacing, choice) end return frame end local function backout(screen) screen_gameplay:SetPrevScreenName(screen):begin_backing_out() end local function show_menu(pn) menu_frames[pn]:playcommand("Show") for i, item in ipairs(menu_items[pn]) do item:playcommand("LoseFocus") end current_menu_choice[pn]= 1 menu_items[pn][current_menu_choice[pn]]:playcommand("GainFocus") menu_is_showing[pn]= true end local function close_menu(pn) menu_frames[pn]:playcommand("Hide") menu_is_showing[pn]= false local stay_paused= false for pn, showing in pairs(menu_is_showing) do if showing then stay_paused= true end end if not stay_paused then local fg= screen_gameplay:GetChild("SongForeground") if fg then fg:visible(old_fg_visible) end screen_gameplay:PauseGame(false) end end local choice_actions= { continue_playing= function(pn) close_menu(pn) end, restart_song= function(pn) backout("ScreenStageInformation") end, forfeit_song= function(pn) backout(SelectMusicOrCourse()) end, skip_song= function(pn) screen_gameplay:PostScreenMessage("SM_NotesEnded", 0) end, forfeit_course= function(pn) backout(SelectMusicOrCourse()) end, end_course= function(pn) course_stopped_by_pause_menu= true screen_gameplay:PostScreenMessage("SM_NotesEnded", 0) end, } local menu_actions= { Start= function(pn) local choice_name= menu_choices[current_menu_choice[pn]] if choice_actions[choice_name] then choice_actions[choice_name](pn) end end, Left= function(pn) if current_menu_choice[pn] > 1 then menu_items[pn][current_menu_choice[pn]]:playcommand("LoseFocus") current_menu_choice[pn]= current_menu_choice[pn] - 1 menu_items[pn][current_menu_choice[pn]]:playcommand("GainFocus") end end, Right= function(pn) if current_menu_choice[pn] < #menu_choices then menu_items[pn][current_menu_choice[pn]]:playcommand("LoseFocus") current_menu_choice[pn]= current_menu_choice[pn] + 1 menu_items[pn][current_menu_choice[pn]]:playcommand("GainFocus") end end, } menu_actions.Up= menu_actions.Left menu_actions.Down= menu_actions.Right menu_actions.MenuLeft= menu_actions.Left menu_actions.MenuRight= menu_actions.Right menu_actions.MenuUp= menu_actions.Up menu_actions.MenuDown= menu_actions.Down local function pause_and_show(pn) gameplay_pause_count= gameplay_pause_count + 1 screen_gameplay:PauseGame(true) local fg= screen_gameplay:GetChild("SongForeground") if fg then old_fg_visible= fg:GetVisible() fg:visible(false) end prompt_actor:playcommand("Hide") show_menu(pn) end local function show_prompt(button) prompt_actor:playcommand("Show", {text= prompt_text[button]}) end local function hide_prompt() prompt_actor:playcommand("Hide") end local function input(event) local pn= event.PlayerNumber if not enabled_players[pn] then return end local button= event.GameButton if not button then return end if event.type == "InputEventType_Release" then return end local is_paused= screen_gameplay:IsPaused() if is_paused then if menu_is_showing[pn] then if menu_actions[button] then menu_actions[button](pn) return end else if button == "Start" then show_menu(pn) return end end end end local frame= Def.ActorFrame{ OnCommand= function(self) screen_gameplay= SCREENMAN:GetTopScreen() if screen_gameplay:GetName() == "ScreenGameplaySyncMachine" then return end screen_gameplay:AddInputCallback(input) end, PlayerHitPauseMessageCommand= function(self, params) pause_and_show(params.pn) end, ShowPausePromptMessageCommand= function(self, params) show_prompt(params.button) end, HidePausePromptMessageCommand= function(self) hide_prompt() end, pause_controller_actor(), Def.BitmapText{ Font= "Common Normal", InitCommand= function(self) prompt_actor= self self:xy(_screen.cx, _screen.h*.75):zoom(.75):diffusealpha(0) end, ShowCommand= function(self, param) self:stoptweening():settext(param.text):accelerate(.25):diffusealpha(1) :sleep(1):queuecommand("Hide") end, HideCommand= function(self) self:stoptweening():decelerate(.25):diffusealpha(0) end, }, } for i, pn in ipairs(GAMESTATE:GetEnabledPlayers()) do enabled_players[pn]= true frame[#frame+1]= create_menu_frame(pn, menu_x[pn], menu_y) end return frame