This is a bit spaghetti right now, and this is compounding it further, so let's
look at all the cases:
Generic ScreenSelect, eg. ScreenSelectStyle:
A non-joined player START press can join. On successful join, discard the
input; the start press that joins the player should not also make a selection
on the menu. Non-joined players can make no other inputs. (ALLOW_DISABLED_PLAYER_INPUT
is false.)
- on start press
- attempt to join the player; if successful:
- play start sound (normally done by the derived class, eg. ScreenSelectMaster::MenuStart,
but we're not going there)
- return, so this start press that just joined the player doesn't also make a selection
- any other button, return and ignore the press ("block input of disabled players")
- on any other button press, just ignore it
ScreenJoin:
Pressing start on a non-joined player joins the player, and unlike the generic case,
it also passes the start press on as input, selecting the default option and starting the
game. (ALLOW_DISABLED_PLAYER_INPUT is true.)
We don't have any visible menu selections, so other player inputs don't matter.
- This screen assumes that a player can join, and that the first successful join
will move on. Pressing start and having it not join has never been tested or
used, and in fact crashes: it'll be passed on as a selection, and
SM_BeginFadingOut dies, because m_MasterPlayerNumber is invalid.
ScreenTitleMenu:
Like SJoin, pressing start will select the current option and start the game. Unlike
SJoin, this screen has options; arrow key inputs on a non-joined player must be
passed on, so the cursor can be moved. (ALLOW_DISABLED_PLAYER_INPUT is true.)
This "always joins" assumption is bad, and was probably never intended. Fix by
never allowing start on a non-joined player (unless the start just joined the
player, in which case he'll be joined by the time of this check).
This commit is contained in:
@@ -123,12 +123,18 @@ void ScreenSelect::Input( const InputEventPlus &input )
|
||||
return; // don't let the screen handle the MENU_START press
|
||||
}
|
||||
|
||||
// block input of disabled players
|
||||
if( !ALLOW_DISABLED_PLAYER_INPUT && !GAMESTATE->IsPlayerEnabled(input.pn) )
|
||||
return;
|
||||
if( !GAMESTATE->IsPlayerEnabled(input.pn) )
|
||||
{
|
||||
// block input of disabled players
|
||||
if( !ALLOW_DISABLED_PLAYER_INPUT )
|
||||
return;
|
||||
|
||||
if( IsTransitioning() )
|
||||
return;
|
||||
/* Never allow a START press by a player that's still not joined, even if ALLOW_DISABLED_PLAYER_INPUT
|
||||
* would allow other types of input. If we let a non-joined player start, we might start the
|
||||
* game with no players joined (eg. if ScreenTitleJoin is started in pay with no credits). */
|
||||
if( input.MenuI == GAME_BUTTON_START )
|
||||
return;
|
||||
}
|
||||
|
||||
ScreenWithMenuElements::Input( input ); // default input handler
|
||||
}
|
||||
@@ -144,6 +150,7 @@ void ScreenSelect::HandleScreenMessage( const ScreenMessage SM )
|
||||
* if so, call ApplyToAll instead.
|
||||
* TODO: Think of a better way to handle this.
|
||||
*/
|
||||
ASSERT( GAMESTATE->m_MasterPlayerNumber != PlayerNumber_Invalid );
|
||||
int iMastersIndex = this->GetSelectionIndex( GAMESTATE->m_MasterPlayerNumber );
|
||||
bool bAllPlayersChoseTheSame = true;
|
||||
FOREACH_HumanPlayer( p )
|
||||
|
||||
Reference in New Issue
Block a user