Skip to content

Commit

Permalink
libcommon|Menu: Skip Episode selection menu when navigating backwards
Browse files Browse the repository at this point in the history
If only one playable episode is available we shouldn't bother the
user to manually select it. In such a case, automatically select the
episode and proceed to next/previous page.

Note that the demo/shareware versions are exempted because they use
this menu to prompt the user to buy the full version.

IssueID #1911
  • Loading branch information
danij-deng committed Nov 30, 2014
1 parent 28423fb commit 618b3a8
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 13 deletions.
7 changes: 5 additions & 2 deletions doomsday/plugins/common/include/menu/page.h
Expand Up @@ -46,15 +46,18 @@ typedef QList<Widget *> WidgetList;
/**
* UI menu page (dialog).
*
* @todo Menu pages should not have a "fixed" previous page mechanism, this should
* be described in a more flexible manner -ds
*
* @ingroup menu
*/
class Page
{
public:
enum Flag
{
FixedLayout = 0x1, ///< Children are positioned using a fixed layout.
NoScroll = 0x2, ///< Scrolling is disabled.
FixedLayout = 0x1, ///< Children are positioned using a fixed layout.
NoScroll = 0x2, ///< Scrolling is disabled.

DefaultFlags = 0
};
Expand Down
73 changes: 62 additions & 11 deletions doomsday/plugins/common/src/hu_menu.cpp
Expand Up @@ -133,6 +133,7 @@ void Hu_MenuDrawMultiplayerPage(Page const &page, Vector2i const &origin);
void Hu_MenuDrawPlayerSetupPage(Page const &page, Vector2i const &origin);

int Hu_MenuColorWidgetCmdResponder(Page &page, menucommand_e cmd);
int Hu_MenuSkipPreviousPageIfSkippingEpisodeSelection(Page &page, menucommand_e cmd);

void Hu_MenuSaveSlotEdit(Widget &wi, Widget::Action action);

Expand Down Expand Up @@ -577,7 +578,8 @@ void Hu_MenuInitSkillPage()
};
#endif

Page *page = Hu_MenuAddPage(new Page("Skill", origin, Page::FixedLayout | Page::NoScroll, Hu_MenuDrawSkillPage));
Page *page = Hu_MenuAddPage(new Page("Skill", origin, Page::FixedLayout | Page::NoScroll,
Hu_MenuDrawSkillPage, Hu_MenuSkipPreviousPageIfSkippingEpisodeSelection));
page->setPredefinedFont(MENU_FONT1, FID(GF_FONTB));
page->setPreviousPage(Hu_MenuPagePtr("Episode"));

Expand Down Expand Up @@ -1890,7 +1892,8 @@ void Hu_MenuInitPlayerClassPage()
}
}

Page *page = Hu_MenuAddPage(new Page("PlayerClass", Vector2i(66, 66), Page::FixedLayout | Page::NoScroll, Hu_MenuDrawPlayerClassPage));
Page *page = Hu_MenuAddPage(new Page("PlayerClass", Vector2i(66, 66), Page::FixedLayout | Page::NoScroll,
Hu_MenuDrawPlayerClassPage, Hu_MenuSkipPreviousPageIfSkippingEpisodeSelection));
page->setPredefinedFont(MENU_FONT1, FID(GF_FONTB));
page->setPreviousPage(Hu_MenuPagePtr("Episode"));

Expand Down Expand Up @@ -2398,6 +2401,53 @@ int Hu_MenuColorWidgetCmdResponder(Page &page, menucommand_e cmd)
return false;
}

/**
* Determines if manual episode selection via the menu can be skipped if only one
* episode is playable.
*
* Some demo/shareware game versions use the episode selection menu for the purpose
* of prompting the user to buy the full version. In such a case, disable skipping.
*
* @return @c true if skipping is allowed.
*/
static bool allowSkipEpisodeSelection()
{
#if __JDOOM__
if(gameMode == doom_shareware) return false; // Never.
#elif __JHERETIC__
if(gameMode == heretic_shareware) return false; // Never.
#endif
return true;
}

int Hu_MenuSkipPreviousPageIfSkippingEpisodeSelection(Page &page, menucommand_e cmd)
{
// All we react to are MCMD_NAV_OUT commands.
if(cmd != MCMD_NAV_OUT) return false;

Page *previous = page.previousPage();

// Skip this page if only one episode is playable.
if(allowSkipEpisodeSelection() && PlayableEpisodeCount() == 1)
{
previous = previous->previousPage();
}

if(previous)
{
S_LocalSound(SFX_MENU_CANCEL, nullptr);
Hu_MenuSetPage(previous);
}
else
{
// No previous page so just close the menu.
S_LocalSound(SFX_MENU_CLOSE, nullptr);
Hu_MenuCommand(MCMD_CLOSE);
}

return true;
}

/// Depending on the current menu state some commands require translating.
static menucommand_e translateCommand(menucommand_e cmd)
{
Expand Down Expand Up @@ -2943,27 +2993,28 @@ void Hu_MenuSelectSingleplayer(Widget & /*wi*/, Widget::Action action)
{
if(action != Widget::Deactivated) return;

// If a networked game is already in progress inform the user we can't continue.
/// @todo Allow continue: Ask the user if the networked game should be stopped.
if(IS_NETGAME)
{
Hu_MsgStart(MSG_ANYKEY, NEWGAME, NULL, 0, NULL);
Hu_MsgStart(MSG_ANYKEY, NEWGAME, nullptr, 0, nullptr);
return;
}

// Skip episode selection if only one is defined.
DictionaryValue::Elements const &episodesById = Defs().episodes.lookup("id").elements();
if(episodesById.size() == 1)
// Skip episode selection if only one is playable.
if(allowSkipEpisodeSelection() && PlayableEpisodeCount() == 1)
{
mnEpisode = episodesById.begin()->second->as<RecordValue>().record()->gets("id");
mnEpisode = FirstPlayableEpisodeId();
#if __JHEXEN__
Hu_MenuSetPage("PlayerClass");
#else
Hu_MenuSetPage("Skill");
#endif
return;
}
else
{
Hu_MenuSetPage("Episode");
}

// Show the episode selection menu.
Hu_MenuSetPage("Episode");
}

void Hu_MenuSelectMultiplayer(Widget & /*wi*/, Widget::Action action)
Expand Down

0 comments on commit 618b3a8

Please sign in to comment.