forbid changing kart group after a player confirmed his selection

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@4911 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2010-03-03 00:48:31 +00:00
parent 72396ae3be
commit c17f4f0e07
5 changed files with 365 additions and 316 deletions

View File

@ -672,13 +672,11 @@ void Skin::drawRibbonChild(const core::rect< s32 > &rect, Widget* widget, const
if (mark_selected)
{
// selected tab should be slighlty bigger than others
if(vertical_flip)
rect2.UpperLeftCorner.Y -= 10;
else
rect2.LowerRightCorner.Y += 10;
if (vertical_flip) rect2.UpperLeftCorner.Y -= 10;
else rect2.LowerRightCorner.Y += 10;
}
drawBoxFromStretchableTexture(widget, rect2, *params);
drawBoxFromStretchableTexture(widget, rect2, *params, parentRibbon->m_deactivated);
}

View File

@ -417,6 +417,8 @@ void DynamicRibbonWidget::registerHoverListener(DynamicRibbonHoverListener* list
// -----------------------------------------------------------------------------
EventPropagation DynamicRibbonWidget::rightPressed(const int playerID)
{
if (m_deactivated) return EVENT_LET;
RibbonWidget* w = getSelectedRibbon(playerID);
if (w != NULL)
{
@ -443,6 +445,8 @@ EventPropagation DynamicRibbonWidget::rightPressed(const int playerID)
// -----------------------------------------------------------------------------
EventPropagation DynamicRibbonWidget::leftPressed(const int playerID)
{
if (m_deactivated) return EVENT_LET;
RibbonWidget* w = getSelectedRibbon(playerID);
if (w != NULL)
{
@ -465,6 +469,8 @@ EventPropagation DynamicRibbonWidget::leftPressed(const int playerID)
// -----------------------------------------------------------------------------
EventPropagation DynamicRibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
{
if (m_deactivated) return EVENT_LET;
if (originator=="left")
{
scroll(-1);
@ -492,6 +498,7 @@ EventPropagation DynamicRibbonWidget::transmitEvent(Widget* w, std::string& orig
// -----------------------------------------------------------------------------
EventPropagation DynamicRibbonWidget::mouseHovered(Widget* child, const int playerID)
{
if (m_deactivated) return EVENT_LET;
//std::cout << "DynamicRibbonWidget::mouseHovered " << playerID << std::endl;
updateLabel();
@ -536,6 +543,8 @@ void DynamicRibbonWidget::onRibbonWidgetScroll(const int delta_x)
void DynamicRibbonWidget::onRibbonWidgetFocus(RibbonWidget* emitter, const int playerID)
{
if (m_deactivated) return;
if (emitter->m_selection[playerID] >= emitter->m_children.size())
{
emitter->m_selection[playerID] = emitter->m_children.size()-1;

View File

@ -252,6 +252,8 @@ void RibbonWidget::select(std::string item, const int mousePlayerID)
// -----------------------------------------------------------------------------
EventPropagation RibbonWidget::rightPressed(const int playerID)
{
if (m_deactivated) return EVENT_LET;
m_selection[playerID]++;
if (m_selection[playerID] >= m_children.size())
{
@ -285,6 +287,8 @@ EventPropagation RibbonWidget::rightPressed(const int playerID)
// -----------------------------------------------------------------------------
EventPropagation RibbonWidget::leftPressed(const int playerID)
{
if (m_deactivated) return EVENT_LET;
m_selection[playerID]--;
if (m_selection[playerID] < 0)
{
@ -340,6 +344,8 @@ EventPropagation RibbonWidget::focused(const int playerID)
// -----------------------------------------------------------------------------
EventPropagation RibbonWidget::mouseHovered(Widget* child, const int mousePlayerID)
{
if (m_deactivated) return EVENT_LET;
//std::cout << "RibbonWidget::mouseHovered " << mousePlayerID << std::endl;
const int subbuttons_amount = m_children.size();
@ -417,19 +423,22 @@ void RibbonWidget::updateSelection()
// -----------------------------------------------------------------------------
EventPropagation RibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
{
const int subbuttons_amount = m_children.size();
for (int i=0; i<subbuttons_amount; i++)
if (!m_deactivated)
{
if (m_children[i].m_properties[PROP_ID] == originator)
const int subbuttons_amount = m_children.size();
for (int i=0; i<subbuttons_amount; i++)
{
m_selection[playerID] = i;
break;
if (m_children[i].m_properties[PROP_ID] == originator)
{
m_selection[playerID] = i;
break;
}
}
updateSelection();
}
updateSelection();
// bring focus back to enclosing ribbon widget
this->setFocusForPlayer( playerID );

View File

@ -601,6 +601,14 @@ public:
}
};
/** Small utility function that returns whether the two given players chose the same kart.
* The advantage of this function is that it can handle "random kart" selection. */
bool sameKart(const PlayerKartWidget& player1, const PlayerKartWidget& player2)
{
return player1.getKartInternalName() == player2.getKartInternalName() &&
player1.getKartInternalName() != RANDOM_KART_ID;
}
#if 0
#pragma mark -
#pragma mark KartHoverListener
@ -690,6 +698,7 @@ KartHoverListener* karthoverListener = NULL;
KartSelectionScreen::KartSelectionScreen() : Screen("karts.stkgui")
{
g_dispatcher = new FocusDispatcher(this);
m_player_confirmed = false;
// Dynamically add tabs
// FIXME: it's not very well documented that RibbonWidgets can have dynamically generated contents
@ -715,15 +724,118 @@ KartSelectionScreen::KartSelectionScreen() : Screen("karts.stkgui")
item->m_properties[PROP_ID] = ALL_KART_GROUPS_ID;
tabs->m_children.push_back(item);
}
// -----------------------------------------------------------------------------
void KartSelectionScreen::init()
{
m_player_confirmed = false;
RibbonWidget* tabs = this->getWidget<RibbonWidget>("kartgroups");
assert( tabs != NULL );
tabs->m_deactivated = false;
// FIXME: Reload previous kart selection screen state
m_kart_widgets.clearAndDeleteAll();
StateManager::get()->resetActivePlayers();
input_manager->getDeviceList()->setAssignMode(DETECT_NEW);
DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("karts");
assert( w != NULL );
if (karthoverListener == NULL)
{
karthoverListener = new KartHoverListener(this);
w->registerHoverListener(karthoverListener);
}
// Build kart list
// (it is built everytikme, to account for .g. locking)
w->clearItems();
std::vector<int> group = kart_properties_manager->getKartsInGroup("standard");
const int kart_amount = group.size();
// add Tux (or whatever default kart) first
std::string& default_kart = UserConfigParams::m_default_kart;
for(int n=0; n<kart_amount; n++)
{
const KartProperties* prop = kart_properties_manager->getKartById(group[n]);
if (prop->getIdent() == default_kart)
{
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
const bool locked = unlock_manager->isLocked(prop->getIdent());
w->addItem(prop->getName(), prop->getIdent().c_str(), icon_path.c_str(), locked);
//std::cout << "Add item : " << prop->getIdent().c_str() << std::endl;
break;
}
}
// add others
for(int n=0; n<kart_amount; n++)
{
const KartProperties* prop = kart_properties_manager->getKartById(group[n]);
if (prop->getIdent() != default_kart)
{
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
const bool locked = unlock_manager->isLocked(prop->getIdent());
w->addItem(prop->getName(), prop->getIdent().c_str(), icon_path.c_str(), locked);
//std::cout << "Add item : " << prop->getIdent().c_str() << std::endl;
}
}
// add random
w->addItem(_("Random Kart"), RANDOM_KART_ID, "/gui/random_kart.png");
/*
TODO: Ultimately, it'd be nice to *not* delete g_player_karts so that
when players return to the kart selection screen, it will appear as
it did when they left (at least when returning from the track menu).
Rebuilding the screen is a little tricky.
*/
if (m_kart_widgets.size() > 0)
{
// FIXME: trying to rebuild the screen
for (int n = 0; n < m_kart_widgets.size(); n++)
{
PlayerKartWidget *pkw;
pkw = m_kart_widgets.get(n);
this->manualAddWidget(pkw);
pkw->add();
}
}
else // For now this is what will happen
{
playerJoin( input_manager->getDeviceList()->getLatestUsedDevice(), true );
w->updateItemDisplay();
}
// Player 0 select first kart (Tux)
w->setSelection(0, 0, true);
}
// -----------------------------------------------------------------------------
void KartSelectionScreen::tearDown()
{
//g_player_karts.clearWithoutDeleting();
m_kart_widgets.clearAndDeleteAll();
}
// -----------------------------------------------------------------------------
void KartSelectionScreen::forgetWhatWasLoaded()
{
Screen::forgetWhatWasLoaded();
// these pointers is no more valid (have been deleted along other widgets)
// these pointers are no more valid (have been deleted along other widgets)
g_dispatcher = NULL;
karthoverListener = NULL;
}
// -----------------------------------------------------------------------------
// Return true if event was handled successfully
bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
@ -904,311 +1016,13 @@ void KartSelectionScreen::onUpdate(float delta, irr::video::IVideoDriver*)
}
}
// -----------------------------------------------------------------------------
void KartSelectionScreen::tearDown()
{
//g_player_karts.clearWithoutDeleting();
m_kart_widgets.clearAndDeleteAll();
}
// -----------------------------------------------------------------------------
void KartSelectionScreen::init()
{
// FIXME: Reload previous kart selection screen state
m_kart_widgets.clearAndDeleteAll();
StateManager::get()->resetActivePlayers();
input_manager->getDeviceList()->setAssignMode(DETECT_NEW);
DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("karts");
assert( w != NULL );
if (karthoverListener == NULL)
{
karthoverListener = new KartHoverListener(this);
w->registerHoverListener(karthoverListener);
}
// Build kart list
// (it is built everytikme, to account for .g. locking)
w->clearItems();
std::vector<int> group = kart_properties_manager->getKartsInGroup("standard");
const int kart_amount = group.size();
// add Tux (or whatever default kart) first
std::string& default_kart = UserConfigParams::m_default_kart;
for(int n=0; n<kart_amount; n++)
{
const KartProperties* prop = kart_properties_manager->getKartById(group[n]);
if (prop->getIdent() == default_kart)
{
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
const bool locked = unlock_manager->isLocked(prop->getIdent());
w->addItem(prop->getName(), prop->getIdent().c_str(), icon_path.c_str(), locked);
//std::cout << "Add item : " << prop->getIdent().c_str() << std::endl;
break;
}
}
// add others
for(int n=0; n<kart_amount; n++)
{
const KartProperties* prop = kart_properties_manager->getKartById(group[n]);
if (prop->getIdent() != default_kart)
{
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
const bool locked = unlock_manager->isLocked(prop->getIdent());
w->addItem(prop->getName(), prop->getIdent().c_str(), icon_path.c_str(), locked);
//std::cout << "Add item : " << prop->getIdent().c_str() << std::endl;
}
}
// add random
w->addItem(_("Random Kart"), RANDOM_KART_ID, "/gui/random_kart.png");
/*
TODO: Ultimately, it'd be nice to *not* delete g_player_karts so that
when players return to the kart selection screen, it will appear as
it did when they left (at least when returning from the track menu).
Rebuilding the screen is a little tricky.
*/
if (m_kart_widgets.size() > 0)
{
// FIXME: trying to rebuild the screen
for (int n = 0; n < m_kart_widgets.size(); n++)
{
PlayerKartWidget *pkw;
pkw = m_kart_widgets.get(n);
this->manualAddWidget(pkw);
pkw->add();
}
}
else // For now this is what will happen
{
playerJoin( input_manager->getDeviceList()->getLatestUsedDevice(), true );
w->updateItemDisplay();
}
// Player 0 select first kart (Tux)
w->setSelection(0, 0, true);
}
// -----------------------------------------------------------------------------
void KartSelectionScreen::allPlayersDone()
{
input_manager->setMasterPlayerOnly(true);
DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("karts");
assert( w != NULL );
const ptr_vector< StateManager::ActivePlayer, HOLD >& players = StateManager::get()->getActivePlayers();
// ---- Print selection (for debugging purposes)
std::cout << "==========\n" << players.size() << " players :\n";
for (int n=0; n<players.size(); n++)
{
std::cout << " Player " << n << " is " << players[n].getConstProfile()->getName()
<< " on " << players[n].getDevice()->m_name << std::endl;
}
std::cout << "==========\n";
// ---- Give player info to race manager
race_manager->setNumPlayers( players.size() );
race_manager->setNumLocalPlayers( players.size() );
// ---- Manage 'random kart' selection(s)
RandomGenerator random;
//g_player_karts.clearAndDeleteAll();
//race_manager->setLocalKartInfo(0, w->getSelectionIDString());
std::vector<ItemDescription> items = w->getItems();
// remove the 'random' item itself
const int item_count = items.size();
for (int n=0; n<item_count; n++)
{
if (items[n].m_code_name == RANDOM_KART_ID)
{
items[n].m_code_name = ID_DONT_USE;
break;
}
}
// pick random karts
const int kart_count = m_kart_widgets.size();
for (int n = 0; n < kart_count; n++)
{
std::string selection = m_kart_widgets[n].m_kartInternalName;
if (selection == RANDOM_KART_ID)
{
// don't select an already selected kart
int randomID;
bool done = false;
do
{
randomID = random.get(item_count);
if (items[randomID].m_code_name != ID_DONT_USE)
{
selection = items[randomID].m_code_name;
done = true;
}
items[randomID].m_code_name = ID_DONT_USE;
} while (!done);
}
else
{
// mark the item as taken
for (int i=0; i<item_count; i++)
{
if (items[i].m_code_name == items[n].m_code_name)
{
items[i].m_code_name = ID_DONT_USE;
break;
}
}
}
// std::cout << "selection=" << selection.c_str() << std::endl;
race_manager->setLocalKartInfo(n, selection);
}
// ---- Switch to assign mode
input_manager->getDeviceList()->setAssignMode(ASSIGN);
StateManager::get()->pushScreen( RaceSetupScreen::getInstance() );
}
// -----------------------------------------------------------------------------
bool KartSelectionScreen::validateIdentChoices()
{
bool ok = true;
const int amount = m_kart_widgets.size();
// reset all marks, we'll re-add them next if errors are still there
for (int n=0; n<amount; n++)
{
// first check if the player name widget is still there, it won't be for those that confirmed
if (m_kart_widgets[n].playerName != NULL)
{
m_kart_widgets[n].playerName->markAsCorrect();
// verify internal consistency in debug mode
assert( m_kart_widgets[n].getAssociatedPlayer()->getProfile() ==
UserConfigParams::m_all_players.get(m_kart_widgets[n].playerName->getValue()) );
}
}
for (int n=0; n<amount; n++)
{
for (int m=n+1; m<amount; m++)
{
// check if 2 players took the same name
if (m_kart_widgets[n].getAssociatedPlayer()->getProfile() == m_kart_widgets[m].getAssociatedPlayer()->getProfile())
{
printf("\n***\n*** Identity conflict!! ***\n***\n\n");
std::cout << " Player " << n << " chose " << m_kart_widgets[n].getAssociatedPlayer()->getProfile()->getName() << std::endl;
std::cout << " Player " << m << " chose " << m_kart_widgets[m].getAssociatedPlayer()->getProfile()->getName() << std::endl;
// two players took the same name. check if one is ready
if (!m_kart_widgets[n].isReady() && m_kart_widgets[m].isReady())
{
// player m is ready, so player n should not choose this name
m_kart_widgets[n].playerName->markAsIncorrect();
}
else if (m_kart_widgets[n].isReady() && !m_kart_widgets[m].isReady())
{
// player n is ready, so player m should not choose this name
m_kart_widgets[m].playerName->markAsIncorrect();
}
else if (m_kart_widgets[n].isReady() && m_kart_widgets[m].isReady())
{
// it should be impossible for two players to confirm they're ready with the same name
assert(false);
}
ok = false;
}
} // end for
}
return ok;
}
// -----------------------------------------------------------------------------
/** Small utility that returns whether the two given players chose the same kart.
* The advantage of this function is that it can handle "random kart" selection. */
bool sameKart(const PlayerKartWidget& player1, const PlayerKartWidget& player2)
{
return player1.getKartInternalName() == player2.getKartInternalName() &&
player1.getKartInternalName() != RANDOM_KART_ID;
}
bool KartSelectionScreen::validateKartChoices()
{
bool ok = true;
const int amount = m_kart_widgets.size();
// reset all marks, we'll re-add them next if errors are still there
for (int n=0; n<amount; n++)
{
m_kart_widgets[n].modelView->unsetBadge(BAD_BADGE);
}
for (int n=0; n<amount; n++)
{
for (int m=n+1; m<amount; m++)
{
// check if 2 players took the same name
if (sameKart(m_kart_widgets[n], m_kart_widgets[m]))
{
printf("\n***\n*** Kart conflict!! ***\n***\n\n");
std::cout << " Player " << n << " chose " << m_kart_widgets[n].getKartInternalName() << std::endl;
std::cout << " Player " << m << " chose " << m_kart_widgets[m].getKartInternalName() << std::endl;
// two players took the same kart. check if one is ready
if (!m_kart_widgets[n].isReady() && m_kart_widgets[m].isReady())
{
std::cout << "--> Setting red badge on player " << n << std::endl;
// player m is ready, so player n should not choose this name
m_kart_widgets[n].modelView->setBadge(BAD_BADGE);
}
else if (m_kart_widgets[n].isReady() && !m_kart_widgets[m].isReady())
{
std::cout << "--> Setting red badge on player " << m << std::endl;
// player n is ready, so player m should not choose this name
m_kart_widgets[m].modelView->setBadge(BAD_BADGE);
}
else if (m_kart_widgets[n].isReady() && m_kart_widgets[m].isReady())
{
// it should be impossible for two players to confirm they're ready with the same kart
assert(false);
}
// we know it's not ok (but don't stop right now, all bad ones need red badges)
ok = false;
}
} // end for
}
return ok;
}
// -----------------------------------------------------------------------------
/**
* Callback handling events from the kart selection menu
*/
void KartSelectionScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
{
if (name == "kartgroups")
if (name == "kartgroups" && !m_player_confirmed) // don't allow changing group after someone confirmed
{
RibbonWidget* tabs = this->getWidget<RibbonWidget>("kartgroups");
assert(tabs != NULL);
@ -1314,6 +1128,11 @@ void KartSelectionScreen::eventCallback(Widget* widget, const std::string& name,
// Mark this player as ready to start
m_kart_widgets[playerID].markAsReady();
m_player_confirmed = true;
RibbonWidget* tabs = this->getWidget<RibbonWidget>("kartgroups");
assert( tabs != NULL );
tabs->m_deactivated = true;
// validate choices to notify player of duplicates
const bool names_ok = validateIdentChoices();
@ -1349,6 +1168,211 @@ void KartSelectionScreen::eventCallback(Widget* widget, const std::string& name,
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark KartSelectionScreen (private)
#endif
void KartSelectionScreen::allPlayersDone()
{
input_manager->setMasterPlayerOnly(true);
DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("karts");
assert( w != NULL );
const ptr_vector< StateManager::ActivePlayer, HOLD >& players = StateManager::get()->getActivePlayers();
// ---- Print selection (for debugging purposes)
std::cout << "==========\n" << players.size() << " players :\n";
for (int n=0; n<players.size(); n++)
{
std::cout << " Player " << n << " is " << players[n].getConstProfile()->getName()
<< " on " << players[n].getDevice()->m_name << std::endl;
}
std::cout << "==========\n";
// ---- Give player info to race manager
race_manager->setNumPlayers( players.size() );
race_manager->setNumLocalPlayers( players.size() );
// ---- Manage 'random kart' selection(s)
RandomGenerator random;
//g_player_karts.clearAndDeleteAll();
//race_manager->setLocalKartInfo(0, w->getSelectionIDString());
std::vector<ItemDescription> items = w->getItems();
// remove the 'random' item itself
const int item_count = items.size();
for (int n=0; n<item_count; n++)
{
if (items[n].m_code_name == RANDOM_KART_ID)
{
items[n].m_code_name = ID_DONT_USE;
break;
}
}
// pick random karts
const int kart_count = m_kart_widgets.size();
for (int n = 0; n < kart_count; n++)
{
std::string selection = m_kart_widgets[n].m_kartInternalName;
if (selection == RANDOM_KART_ID)
{
// don't select an already selected kart
int randomID;
bool done = false;
do
{
randomID = random.get(item_count);
if (items[randomID].m_code_name != ID_DONT_USE)
{
selection = items[randomID].m_code_name;
done = true;
}
items[randomID].m_code_name = ID_DONT_USE;
} while (!done);
}
else
{
// mark the item as taken
for (int i=0; i<item_count; i++)
{
if (items[i].m_code_name == items[n].m_code_name)
{
items[i].m_code_name = ID_DONT_USE;
break;
}
}
}
// std::cout << "selection=" << selection.c_str() << std::endl;
race_manager->setLocalKartInfo(n, selection);
}
// ---- Switch to assign mode
input_manager->getDeviceList()->setAssignMode(ASSIGN);
StateManager::get()->pushScreen( RaceSetupScreen::getInstance() );
}
// -----------------------------------------------------------------------------
bool KartSelectionScreen::validateIdentChoices()
{
bool ok = true;
const int amount = m_kart_widgets.size();
// reset all marks, we'll re-add them next if errors are still there
for (int n=0; n<amount; n++)
{
// first check if the player name widget is still there, it won't be for those that confirmed
if (m_kart_widgets[n].playerName != NULL)
{
m_kart_widgets[n].playerName->markAsCorrect();
// verify internal consistency in debug mode
assert( m_kart_widgets[n].getAssociatedPlayer()->getProfile() ==
UserConfigParams::m_all_players.get(m_kart_widgets[n].playerName->getValue()) );
}
}
for (int n=0; n<amount; n++)
{
for (int m=n+1; m<amount; m++)
{
// check if 2 players took the same name
if (m_kart_widgets[n].getAssociatedPlayer()->getProfile() == m_kart_widgets[m].getAssociatedPlayer()->getProfile())
{
printf("\n***\n*** Identity conflict!! ***\n***\n\n");
std::cout << " Player " << n << " chose " << m_kart_widgets[n].getAssociatedPlayer()->getProfile()->getName() << std::endl;
std::cout << " Player " << m << " chose " << m_kart_widgets[m].getAssociatedPlayer()->getProfile()->getName() << std::endl;
// two players took the same name. check if one is ready
if (!m_kart_widgets[n].isReady() && m_kart_widgets[m].isReady())
{
// player m is ready, so player n should not choose this name
m_kart_widgets[n].playerName->markAsIncorrect();
}
else if (m_kart_widgets[n].isReady() && !m_kart_widgets[m].isReady())
{
// player n is ready, so player m should not choose this name
m_kart_widgets[m].playerName->markAsIncorrect();
}
else if (m_kart_widgets[n].isReady() && m_kart_widgets[m].isReady())
{
// it should be impossible for two players to confirm they're ready with the same name
assert(false);
}
ok = false;
}
} // end for
}
return ok;
}
// -----------------------------------------------------------------------------
bool KartSelectionScreen::validateKartChoices()
{
bool ok = true;
const int amount = m_kart_widgets.size();
// reset all marks, we'll re-add them next if errors are still there
for (int n=0; n<amount; n++)
{
m_kart_widgets[n].modelView->unsetBadge(BAD_BADGE);
}
for (int n=0; n<amount; n++)
{
for (int m=n+1; m<amount; m++)
{
// check if 2 players took the same name
if (sameKart(m_kart_widgets[n], m_kart_widgets[m]))
{
printf("\n***\n*** Kart conflict!! ***\n***\n\n");
std::cout << " Player " << n << " chose " << m_kart_widgets[n].getKartInternalName() << std::endl;
std::cout << " Player " << m << " chose " << m_kart_widgets[m].getKartInternalName() << std::endl;
// two players took the same kart. check if one is ready
if (!m_kart_widgets[n].isReady() && m_kart_widgets[m].isReady())
{
std::cout << "--> Setting red badge on player " << n << std::endl;
// player m is ready, so player n should not choose this name
m_kart_widgets[n].modelView->setBadge(BAD_BADGE);
}
else if (m_kart_widgets[n].isReady() && !m_kart_widgets[m].isReady())
{
std::cout << "--> Setting red badge on player " << m << std::endl;
// player n is ready, so player m should not choose this name
m_kart_widgets[m].modelView->setBadge(BAD_BADGE);
}
else if (m_kart_widgets[n].isReady() && m_kart_widgets[m].isReady())
{
// it should be impossible for two players to confirm they're ready with the same kart
assert(false);
}
// we know it's not ok (but don't stop right now, all bad ones need red badges)
ok = false;
}
} // end for
}
return ok;
}
// -----------------------------------------------------------------------------
void KartSelectionScreen::renumberKarts()

View File

@ -35,12 +35,19 @@ class KartSelectionScreen : public GUIEngine::Screen, public GUIEngine::ScreenSi
friend class PlayerNameSpinner;
friend class FocusDispatcher;
// ref only since we're adding them to a Screen, and the Screen will take ownership of these widgets
/** Contains the custom widget shown for every player. (ref only since we're adding them to a
* Screen, and the Screen will take ownership of these widgets)
*/
ptr_vector<PlayerKartWidget, REF> m_kart_widgets;
friend class GUIEngine::ScreenSingleton<KartSelectionScreen>;
KartSelectionScreen();
/** Stores whether any player confirmed their choice; then, some things are "frozen", for instance
* the selected kart group tab
*/
bool m_player_confirmed;
/** Called when all players selected their kart */
void allPlayersDone();
@ -48,11 +55,13 @@ class KartSelectionScreen : public GUIEngine::Screen, public GUIEngine::ScreenSi
void renumberKarts();
/** Checks identities chosen by players, making sure no duplicates are used.
\return Whether all choices are ok */
* \return Whether all choices are ok
*/
bool validateIdentChoices();
/** Checks karts chosen by players, making sure no duplicates are used.
\return Whether all choices are ok */
* \return Whether all choices are ok
*/
bool validateKartChoices();
public: