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:
parent
72396ae3be
commit
c17f4f0e07
@ -672,13 +672,11 @@ void Skin::drawRibbonChild(const core::rect< s32 > &rect, Widget* widget, const
|
|||||||
if (mark_selected)
|
if (mark_selected)
|
||||||
{
|
{
|
||||||
// selected tab should be slighlty bigger than others
|
// selected tab should be slighlty bigger than others
|
||||||
if(vertical_flip)
|
if (vertical_flip) rect2.UpperLeftCorner.Y -= 10;
|
||||||
rect2.UpperLeftCorner.Y -= 10;
|
else rect2.LowerRightCorner.Y += 10;
|
||||||
else
|
|
||||||
rect2.LowerRightCorner.Y += 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
drawBoxFromStretchableTexture(widget, rect2, *params);
|
drawBoxFromStretchableTexture(widget, rect2, *params, parentRibbon->m_deactivated);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -417,6 +417,8 @@ void DynamicRibbonWidget::registerHoverListener(DynamicRibbonHoverListener* list
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
EventPropagation DynamicRibbonWidget::rightPressed(const int playerID)
|
EventPropagation DynamicRibbonWidget::rightPressed(const int playerID)
|
||||||
{
|
{
|
||||||
|
if (m_deactivated) return EVENT_LET;
|
||||||
|
|
||||||
RibbonWidget* w = getSelectedRibbon(playerID);
|
RibbonWidget* w = getSelectedRibbon(playerID);
|
||||||
if (w != NULL)
|
if (w != NULL)
|
||||||
{
|
{
|
||||||
@ -443,6 +445,8 @@ EventPropagation DynamicRibbonWidget::rightPressed(const int playerID)
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
EventPropagation DynamicRibbonWidget::leftPressed(const int playerID)
|
EventPropagation DynamicRibbonWidget::leftPressed(const int playerID)
|
||||||
{
|
{
|
||||||
|
if (m_deactivated) return EVENT_LET;
|
||||||
|
|
||||||
RibbonWidget* w = getSelectedRibbon(playerID);
|
RibbonWidget* w = getSelectedRibbon(playerID);
|
||||||
if (w != NULL)
|
if (w != NULL)
|
||||||
{
|
{
|
||||||
@ -465,6 +469,8 @@ EventPropagation DynamicRibbonWidget::leftPressed(const int playerID)
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
EventPropagation DynamicRibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
|
EventPropagation DynamicRibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
|
||||||
{
|
{
|
||||||
|
if (m_deactivated) return EVENT_LET;
|
||||||
|
|
||||||
if (originator=="left")
|
if (originator=="left")
|
||||||
{
|
{
|
||||||
scroll(-1);
|
scroll(-1);
|
||||||
@ -492,6 +498,7 @@ EventPropagation DynamicRibbonWidget::transmitEvent(Widget* w, std::string& orig
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
EventPropagation DynamicRibbonWidget::mouseHovered(Widget* child, const int playerID)
|
EventPropagation DynamicRibbonWidget::mouseHovered(Widget* child, const int playerID)
|
||||||
{
|
{
|
||||||
|
if (m_deactivated) return EVENT_LET;
|
||||||
//std::cout << "DynamicRibbonWidget::mouseHovered " << playerID << std::endl;
|
//std::cout << "DynamicRibbonWidget::mouseHovered " << playerID << std::endl;
|
||||||
|
|
||||||
updateLabel();
|
updateLabel();
|
||||||
@ -536,6 +543,8 @@ void DynamicRibbonWidget::onRibbonWidgetScroll(const int delta_x)
|
|||||||
|
|
||||||
void DynamicRibbonWidget::onRibbonWidgetFocus(RibbonWidget* emitter, const int playerID)
|
void DynamicRibbonWidget::onRibbonWidgetFocus(RibbonWidget* emitter, const int playerID)
|
||||||
{
|
{
|
||||||
|
if (m_deactivated) return;
|
||||||
|
|
||||||
if (emitter->m_selection[playerID] >= emitter->m_children.size())
|
if (emitter->m_selection[playerID] >= emitter->m_children.size())
|
||||||
{
|
{
|
||||||
emitter->m_selection[playerID] = emitter->m_children.size()-1;
|
emitter->m_selection[playerID] = emitter->m_children.size()-1;
|
||||||
|
@ -252,6 +252,8 @@ void RibbonWidget::select(std::string item, const int mousePlayerID)
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
EventPropagation RibbonWidget::rightPressed(const int playerID)
|
EventPropagation RibbonWidget::rightPressed(const int playerID)
|
||||||
{
|
{
|
||||||
|
if (m_deactivated) return EVENT_LET;
|
||||||
|
|
||||||
m_selection[playerID]++;
|
m_selection[playerID]++;
|
||||||
if (m_selection[playerID] >= m_children.size())
|
if (m_selection[playerID] >= m_children.size())
|
||||||
{
|
{
|
||||||
@ -285,6 +287,8 @@ EventPropagation RibbonWidget::rightPressed(const int playerID)
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
EventPropagation RibbonWidget::leftPressed(const int playerID)
|
EventPropagation RibbonWidget::leftPressed(const int playerID)
|
||||||
{
|
{
|
||||||
|
if (m_deactivated) return EVENT_LET;
|
||||||
|
|
||||||
m_selection[playerID]--;
|
m_selection[playerID]--;
|
||||||
if (m_selection[playerID] < 0)
|
if (m_selection[playerID] < 0)
|
||||||
{
|
{
|
||||||
@ -340,6 +344,8 @@ EventPropagation RibbonWidget::focused(const int playerID)
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
EventPropagation RibbonWidget::mouseHovered(Widget* child, const int mousePlayerID)
|
EventPropagation RibbonWidget::mouseHovered(Widget* child, const int mousePlayerID)
|
||||||
{
|
{
|
||||||
|
if (m_deactivated) return EVENT_LET;
|
||||||
|
|
||||||
//std::cout << "RibbonWidget::mouseHovered " << mousePlayerID << std::endl;
|
//std::cout << "RibbonWidget::mouseHovered " << mousePlayerID << std::endl;
|
||||||
const int subbuttons_amount = m_children.size();
|
const int subbuttons_amount = m_children.size();
|
||||||
|
|
||||||
@ -417,6 +423,8 @@ void RibbonWidget::updateSelection()
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
EventPropagation RibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
|
EventPropagation RibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
|
||||||
{
|
{
|
||||||
|
if (!m_deactivated)
|
||||||
|
{
|
||||||
const int subbuttons_amount = m_children.size();
|
const int subbuttons_amount = m_children.size();
|
||||||
|
|
||||||
for (int i=0; i<subbuttons_amount; i++)
|
for (int i=0; i<subbuttons_amount; i++)
|
||||||
@ -429,6 +437,7 @@ EventPropagation RibbonWidget::transmitEvent(Widget* w, std::string& originator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateSelection();
|
updateSelection();
|
||||||
|
}
|
||||||
|
|
||||||
// bring focus back to enclosing ribbon widget
|
// bring focus back to enclosing ribbon widget
|
||||||
this->setFocusForPlayer( playerID );
|
this->setFocusForPlayer( playerID );
|
||||||
|
@ -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
|
#if 0
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
#pragma mark KartHoverListener
|
#pragma mark KartHoverListener
|
||||||
@ -690,6 +698,7 @@ KartHoverListener* karthoverListener = NULL;
|
|||||||
KartSelectionScreen::KartSelectionScreen() : Screen("karts.stkgui")
|
KartSelectionScreen::KartSelectionScreen() : Screen("karts.stkgui")
|
||||||
{
|
{
|
||||||
g_dispatcher = new FocusDispatcher(this);
|
g_dispatcher = new FocusDispatcher(this);
|
||||||
|
m_player_confirmed = false;
|
||||||
|
|
||||||
// Dynamically add tabs
|
// Dynamically add tabs
|
||||||
// FIXME: it's not very well documented that RibbonWidgets can have dynamically generated contents
|
// 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;
|
item->m_properties[PROP_ID] = ALL_KART_GROUPS_ID;
|
||||||
tabs->m_children.push_back(item);
|
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()
|
void KartSelectionScreen::forgetWhatWasLoaded()
|
||||||
{
|
{
|
||||||
Screen::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;
|
g_dispatcher = NULL;
|
||||||
karthoverListener = NULL;
|
karthoverListener = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Return true if event was handled successfully
|
// Return true if event was handled successfully
|
||||||
bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
|
bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer)
|
||||||
@ -905,98 +1017,165 @@ void KartSelectionScreen::onUpdate(float delta, irr::video::IVideoDriver*)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
void KartSelectionScreen::tearDown()
|
/**
|
||||||
|
* Callback handling events from the kart selection menu
|
||||||
|
*/
|
||||||
|
void KartSelectionScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
|
||||||
{
|
{
|
||||||
//g_player_karts.clearWithoutDeleting();
|
if (name == "kartgroups" && !m_player_confirmed) // don't allow changing group after someone confirmed
|
||||||
m_kart_widgets.clearAndDeleteAll();
|
{
|
||||||
}
|
RibbonWidget* tabs = this->getWidget<RibbonWidget>("kartgroups");
|
||||||
|
assert(tabs != NULL);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
std::string selection = tabs->getSelectionIDString(GUI_PLAYER_ID);
|
||||||
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");
|
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();
|
w->clearItems();
|
||||||
std::vector<int> group = kart_properties_manager->getKartsInGroup("standard");
|
|
||||||
|
// TODO : preserve selection of karts for all players
|
||||||
|
// FIXME: merge this code with the code that adds karts initially, copy-and-paste is ugly
|
||||||
|
|
||||||
|
if (selection == ALL_KART_GROUPS_ID)
|
||||||
|
{
|
||||||
|
const int kart_amount = kart_properties_manager->getNumberOfKarts();
|
||||||
|
|
||||||
|
for(int n=0; n<kart_amount; n++)
|
||||||
|
{
|
||||||
|
const KartProperties* prop = kart_properties_manager->getKartById(n);
|
||||||
|
|
||||||
|
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
|
||||||
|
w->addItem(prop->getName().c_str(), prop->getIdent().c_str(), icon_path.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (selection == "locked")
|
||||||
|
{
|
||||||
|
unlock_manager->playLockSound();
|
||||||
|
}
|
||||||
|
else if (selection == NO_ITEM_ID)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::vector<int> group = kart_properties_manager->getKartsInGroup(selection);
|
||||||
const int kart_amount = group.size();
|
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++)
|
for(int n=0; n<kart_amount; n++)
|
||||||
{
|
{
|
||||||
const KartProperties* prop = kart_properties_manager->getKartById(group[n]);
|
const KartProperties* prop = kart_properties_manager->getKartById(group[n]);
|
||||||
if (prop->getIdent() == default_kart)
|
|
||||||
{
|
|
||||||
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
|
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
|
||||||
const bool locked = unlock_manager->isLocked(prop->getIdent());
|
w->addItem(prop->getName().c_str(), prop->getIdent().c_str(), icon_path.c_str());
|
||||||
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");
|
||||||
|
|
||||||
|
w->updateItemDisplay();
|
||||||
|
|
||||||
|
// update players selections
|
||||||
|
const int num_players = m_kart_widgets.size();
|
||||||
|
for (int n=0; n<num_players; n++)
|
||||||
|
{
|
||||||
|
// player 0 is the one that can change the groups, leave his focus on the tabs
|
||||||
|
if (n > 0) GUIEngine::focusNothingForPlayer(n);
|
||||||
|
|
||||||
|
const std::string& selection = m_kart_widgets[n].getKartInternalName();
|
||||||
|
if (!w->setSelection( selection, n, true ))
|
||||||
|
{
|
||||||
|
std::cout << "Player " << n << " lost their selection when switching tabs!!!\n";
|
||||||
|
// For now, select a random kart in this case (TODO : maybe do something better? )
|
||||||
|
RandomGenerator random;
|
||||||
|
const int count = w->getItems().size();
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
const int randomID = random.get( count );
|
||||||
|
w->setSelection( randomID, n, n > 0 ); // preserve selection for players > 0 (player 0 is the one that can change the groups)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "WARNING : kart selection screen has 0 items in the ribbon\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end for
|
||||||
|
}
|
||||||
|
else if (name == "karts")
|
||||||
|
{
|
||||||
|
// make sure no other player selected the same identity or kart
|
||||||
|
//std::cout << "\n\n\\\\\\\\ Kart Selected ////\n";
|
||||||
|
//std::cout << "Making sure no other player has ident " << g_player_karts[playerID].getAssociatedPlayer()->getProfile()->getName() << std::endl;
|
||||||
|
const int amount = m_kart_widgets.size();
|
||||||
|
for (int n=0; n<amount; n++)
|
||||||
|
{
|
||||||
|
if (n == playerID) continue; // don't check a kart against itself
|
||||||
|
|
||||||
|
if (m_kart_widgets[n].isReady() &&
|
||||||
|
(m_kart_widgets[n].getAssociatedPlayer()->getProfile() ==
|
||||||
|
m_kart_widgets[playerID].getAssociatedPlayer()->getProfile() ||
|
||||||
|
sameKart(m_kart_widgets[n], m_kart_widgets[playerID])))
|
||||||
|
{
|
||||||
|
printf("\n***\n*** You can't select this identity or kart, someone already took it!! ***\n***\n\n");
|
||||||
|
|
||||||
|
//SFXType sound;
|
||||||
|
//SOUND_UGH SOUND_CRASH SOUND_USE_ANVIL SOUND_EXPLOSION SOUND_MOVE_MENU SOUND_SELECT_MENU
|
||||||
|
sfx_manager->quickSound( "use_anvil" );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If two PlayerKart entries are associated to the same ActivePlayer, something went wrong
|
||||||
|
assert(m_kart_widgets[n].getAssociatedPlayer() != m_kart_widgets[playerID].getAssociatedPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
const bool karts_ok = validateKartChoices();
|
||||||
|
|
||||||
|
if (!names_ok || !karts_ok) return;
|
||||||
|
|
||||||
|
// check if all players are ready
|
||||||
|
bool allPlayersReady = true;
|
||||||
|
for (int n=0; n<amount; n++)
|
||||||
|
{
|
||||||
|
if (!m_kart_widgets[n].isReady())
|
||||||
|
{
|
||||||
|
allPlayersReady = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add others
|
if (allPlayersReady) allPlayersDone();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Transmit to all subwindows, maybe *they* care about this event
|
||||||
|
const int amount = m_kart_widgets.size();
|
||||||
|
for (int n=0; n<amount; n++)
|
||||||
|
{
|
||||||
|
m_kart_widgets[n].transmitEvent(widget, name, playerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add random
|
// those events may mean that a player selection changed, so validate again
|
||||||
w->addItem(_("Random Kart"), RANDOM_KART_ID, "/gui/random_kart.png");
|
validateIdentChoices();
|
||||||
|
validateKartChoices();
|
||||||
/*
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark KartSelectionScreen (private)
|
||||||
|
#endif
|
||||||
|
|
||||||
void KartSelectionScreen::allPlayersDone()
|
void KartSelectionScreen::allPlayersDone()
|
||||||
{
|
{
|
||||||
input_manager->setMasterPlayerOnly(true);
|
input_manager->setMasterPlayerOnly(true);
|
||||||
@ -1142,14 +1321,6 @@ bool KartSelectionScreen::validateIdentChoices()
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
/** 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 KartSelectionScreen::validateKartChoices()
|
||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
@ -1202,153 +1373,6 @@ bool KartSelectionScreen::validateKartChoices()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Callback handling events from the kart selection menu
|
|
||||||
*/
|
|
||||||
void KartSelectionScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
|
|
||||||
{
|
|
||||||
if (name == "kartgroups")
|
|
||||||
{
|
|
||||||
RibbonWidget* tabs = this->getWidget<RibbonWidget>("kartgroups");
|
|
||||||
assert(tabs != NULL);
|
|
||||||
|
|
||||||
std::string selection = tabs->getSelectionIDString(GUI_PLAYER_ID);
|
|
||||||
|
|
||||||
DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("karts");
|
|
||||||
w->clearItems();
|
|
||||||
|
|
||||||
// TODO : preserve selection of karts for all players
|
|
||||||
// FIXME: merge this code with the code that adds karts initially, copy-and-paste is ugly
|
|
||||||
|
|
||||||
if (selection == ALL_KART_GROUPS_ID)
|
|
||||||
{
|
|
||||||
const int kart_amount = kart_properties_manager->getNumberOfKarts();
|
|
||||||
|
|
||||||
for(int n=0; n<kart_amount; n++)
|
|
||||||
{
|
|
||||||
const KartProperties* prop = kart_properties_manager->getKartById(n);
|
|
||||||
|
|
||||||
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
|
|
||||||
w->addItem(prop->getName().c_str(), prop->getIdent().c_str(), icon_path.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (selection == "locked")
|
|
||||||
{
|
|
||||||
unlock_manager->playLockSound();
|
|
||||||
}
|
|
||||||
else if (selection == NO_ITEM_ID)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::vector<int> group = kart_properties_manager->getKartsInGroup(selection);
|
|
||||||
const int kart_amount = group.size();
|
|
||||||
|
|
||||||
for(int n=0; n<kart_amount; n++)
|
|
||||||
{
|
|
||||||
const KartProperties* prop = kart_properties_manager->getKartById(group[n]);
|
|
||||||
|
|
||||||
std::string icon_path = "/karts/" + prop->getIdent() + "/" + prop->getIconFile();
|
|
||||||
w->addItem(prop->getName().c_str(), prop->getIdent().c_str(), icon_path.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add random
|
|
||||||
w->addItem(_("Random Kart"), RANDOM_KART_ID, "/gui/random_kart.png");
|
|
||||||
|
|
||||||
w->updateItemDisplay();
|
|
||||||
|
|
||||||
// update players selections
|
|
||||||
const int num_players = m_kart_widgets.size();
|
|
||||||
for (int n=0; n<num_players; n++)
|
|
||||||
{
|
|
||||||
// player 0 is the one that can change the groups, leave his focus on the tabs
|
|
||||||
if (n > 0) GUIEngine::focusNothingForPlayer(n);
|
|
||||||
|
|
||||||
const std::string& selection = m_kart_widgets[n].getKartInternalName();
|
|
||||||
if (!w->setSelection( selection, n, true ))
|
|
||||||
{
|
|
||||||
std::cout << "Player " << n << " lost their selection when switching tabs!!!\n";
|
|
||||||
// For now, select a random kart in this case (TODO : maybe do something better? )
|
|
||||||
RandomGenerator random;
|
|
||||||
const int count = w->getItems().size();
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
const int randomID = random.get( count );
|
|
||||||
w->setSelection( randomID, n, n > 0 ); // preserve selection for players > 0 (player 0 is the one that can change the groups)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "WARNING : kart selection screen has 0 items in the ribbon\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // end for
|
|
||||||
}
|
|
||||||
else if (name == "karts")
|
|
||||||
{
|
|
||||||
// make sure no other player selected the same identity or kart
|
|
||||||
//std::cout << "\n\n\\\\\\\\ Kart Selected ////\n";
|
|
||||||
//std::cout << "Making sure no other player has ident " << g_player_karts[playerID].getAssociatedPlayer()->getProfile()->getName() << std::endl;
|
|
||||||
const int amount = m_kart_widgets.size();
|
|
||||||
for (int n=0; n<amount; n++)
|
|
||||||
{
|
|
||||||
if (n == playerID) continue; // don't check a kart against itself
|
|
||||||
|
|
||||||
if (m_kart_widgets[n].isReady() &&
|
|
||||||
(m_kart_widgets[n].getAssociatedPlayer()->getProfile() ==
|
|
||||||
m_kart_widgets[playerID].getAssociatedPlayer()->getProfile() ||
|
|
||||||
sameKart(m_kart_widgets[n], m_kart_widgets[playerID])))
|
|
||||||
{
|
|
||||||
printf("\n***\n*** You can't select this identity or kart, someone already took it!! ***\n***\n\n");
|
|
||||||
|
|
||||||
//SFXType sound;
|
|
||||||
//SOUND_UGH SOUND_CRASH SOUND_USE_ANVIL SOUND_EXPLOSION SOUND_MOVE_MENU SOUND_SELECT_MENU
|
|
||||||
sfx_manager->quickSound( "use_anvil" );
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If two PlayerKart entries are associated to the same ActivePlayer, something went wrong
|
|
||||||
assert(m_kart_widgets[n].getAssociatedPlayer() != m_kart_widgets[playerID].getAssociatedPlayer());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark this player as ready to start
|
|
||||||
m_kart_widgets[playerID].markAsReady();
|
|
||||||
|
|
||||||
// validate choices to notify player of duplicates
|
|
||||||
const bool names_ok = validateIdentChoices();
|
|
||||||
const bool karts_ok = validateKartChoices();
|
|
||||||
|
|
||||||
if (!names_ok || !karts_ok) return;
|
|
||||||
|
|
||||||
// check if all players are ready
|
|
||||||
bool allPlayersReady = true;
|
|
||||||
for (int n=0; n<amount; n++)
|
|
||||||
{
|
|
||||||
if (!m_kart_widgets[n].isReady())
|
|
||||||
{
|
|
||||||
allPlayersReady = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allPlayersReady) allPlayersDone();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Transmit to all subwindows, maybe *they* care about this event
|
|
||||||
const int amount = m_kart_widgets.size();
|
|
||||||
for (int n=0; n<amount; n++)
|
|
||||||
{
|
|
||||||
m_kart_widgets[n].transmitEvent(widget, name, playerID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// those events may mean that a player selection changed, so validate again
|
|
||||||
validateIdentChoices();
|
|
||||||
validateKartChoices();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void KartSelectionScreen::renumberKarts()
|
void KartSelectionScreen::renumberKarts()
|
||||||
|
@ -35,12 +35,19 @@ class KartSelectionScreen : public GUIEngine::Screen, public GUIEngine::ScreenSi
|
|||||||
friend class PlayerNameSpinner;
|
friend class PlayerNameSpinner;
|
||||||
friend class FocusDispatcher;
|
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;
|
ptr_vector<PlayerKartWidget, REF> m_kart_widgets;
|
||||||
|
|
||||||
friend class GUIEngine::ScreenSingleton<KartSelectionScreen>;
|
friend class GUIEngine::ScreenSingleton<KartSelectionScreen>;
|
||||||
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 */
|
/** Called when all players selected their kart */
|
||||||
void allPlayersDone();
|
void allPlayersDone();
|
||||||
|
|
||||||
@ -48,11 +55,13 @@ class KartSelectionScreen : public GUIEngine::Screen, public GUIEngine::ScreenSi
|
|||||||
void renumberKarts();
|
void renumberKarts();
|
||||||
|
|
||||||
/** Checks identities chosen by players, making sure no duplicates are used.
|
/** 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();
|
bool validateIdentChoices();
|
||||||
|
|
||||||
/** Checks karts chosen by players, making sure no duplicates are used.
|
/** 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();
|
bool validateKartChoices();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user