Split kart selection screen into more files
This commit is contained in:
parent
4fe34007cd
commit
bfd54cf37c
725
src/guiengine/widgets/player_kart_widget.cpp
Normal file
725
src/guiengine/widgets/player_kart_widget.cpp
Normal file
@ -0,0 +1,725 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
//
|
||||
// Copyright (C) 2006-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "config/player_manager.hpp"
|
||||
#include "guiengine/widgets/kart_stats_widget.hpp"
|
||||
#include "guiengine/widgets/model_view_widget.hpp"
|
||||
#include "guiengine/widgets/player_kart_widget.hpp"
|
||||
#include "guiengine/widgets/player_name_spinner.hpp"
|
||||
#include "input/input_device.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "online/online_profile.hpp"
|
||||
#include "states_screens/kart_selection.hpp"
|
||||
#include <IGUIEnvironment.h>
|
||||
|
||||
static int g_root_id;
|
||||
static const char RANDOM_KART_ID[] = "randomkart";
|
||||
|
||||
using namespace GUIEngine;
|
||||
|
||||
PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
|
||||
StateManager::ActivePlayer* associated_player,
|
||||
Online::OnlineProfile* associated_user,
|
||||
core::recti area, const int player_id,
|
||||
std::string kart_group,
|
||||
const int irrlicht_widget_id) : Widget(WTYPE_DIV)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (associated_player)
|
||||
assert(associated_player->ok());
|
||||
m_magic_number = 0x33445566;
|
||||
#endif
|
||||
m_ready_text = NULL;
|
||||
m_parent_screen = parent;
|
||||
|
||||
m_associated_user = associated_user;
|
||||
m_associated_player = associated_player;
|
||||
x_speed = 1.0f;
|
||||
y_speed = 1.0f;
|
||||
w_speed = 1.0f;
|
||||
h_speed = 1.0f;
|
||||
m_ready = false;
|
||||
m_not_updated_yet = true;
|
||||
|
||||
m_irrlicht_widget_id = irrlicht_widget_id;
|
||||
|
||||
m_player_id = player_id;
|
||||
m_properties[PROP_ID] = StringUtils::insertValues("@p%i", m_player_id);
|
||||
|
||||
setSize(area.UpperLeftCorner.X, area.UpperLeftCorner.Y,
|
||||
area.getWidth(), area.getHeight() );
|
||||
target_x = m_x;
|
||||
target_y = m_y;
|
||||
target_w = m_w;
|
||||
target_h = m_h;
|
||||
|
||||
// ---- Player identity spinner
|
||||
m_player_ident_spinner = NULL;
|
||||
|
||||
m_player_ident_spinner = new PlayerNameSpinner(parent, m_player_id);
|
||||
m_player_ident_spinner->m_x = player_name_x;
|
||||
m_player_ident_spinner->m_y = player_name_y;
|
||||
m_player_ident_spinner->m_w = player_name_w;
|
||||
m_player_ident_spinner->m_h = player_name_h;
|
||||
|
||||
// ---- KartStatsWidget
|
||||
m_kart_stats = NULL;
|
||||
|
||||
// area for the stats widget
|
||||
core::recti statsArea;
|
||||
if (!parent->m_multiplayer)
|
||||
{
|
||||
statsArea = core::recti(m_kart_stats_x,
|
||||
m_kart_stats_y,
|
||||
m_kart_stats_x + m_kart_stats_w,
|
||||
m_kart_stats_y + m_kart_stats_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
statsArea = core::recti(m_x , m_y + m_h/2,
|
||||
m_x + m_w, m_y + m_h);
|
||||
}
|
||||
|
||||
|
||||
m_kart_stats = new GUIEngine::KartStatsWidget(statsArea, player_id, kart_group,
|
||||
m_parent_screen->m_multiplayer,
|
||||
!m_parent_screen->m_multiplayer || parent->m_kart_widgets.size() == 0);
|
||||
m_kart_stats->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_stats", m_player_id);
|
||||
m_children.push_back(m_kart_stats);
|
||||
|
||||
m_difficulty = new GUIEngine::SpinnerWidget();
|
||||
m_children.push_back(m_difficulty);
|
||||
|
||||
if (parent->m_multiplayer && associated_player)
|
||||
{
|
||||
if (associated_player->getDevice()->getType() == DT_KEYBOARD)
|
||||
{
|
||||
m_player_ident_spinner->setBadge(KEYBOARD_BADGE);
|
||||
}
|
||||
else if (associated_player->getDevice()->getType() == DT_GAMEPAD)
|
||||
{
|
||||
m_player_ident_spinner->setBadge(GAMEPAD_BADGE);
|
||||
}
|
||||
}
|
||||
else if (m_associated_user) // online user, FIXME is that useful ?
|
||||
{
|
||||
m_player_ident_spinner->setBadge(OK_BADGE);
|
||||
}
|
||||
|
||||
if (irrlicht_widget_id == -1)
|
||||
{
|
||||
m_player_ident_spinner->m_tab_down_root = g_root_id;
|
||||
}
|
||||
|
||||
spinnerID = StringUtils::insertValues("@p%i_spinner", m_player_id);
|
||||
|
||||
m_player_ident_spinner->m_properties[PROP_ID] = spinnerID;
|
||||
if (parent->m_multiplayer)
|
||||
{
|
||||
const int player_amount = PlayerManager::get()->getNumPlayers();
|
||||
m_player_ident_spinner->m_properties[PROP_MIN_VALUE] = "0";
|
||||
m_player_ident_spinner->m_properties[PROP_MAX_VALUE] =
|
||||
StringUtils::toString(player_amount-1);
|
||||
m_player_ident_spinner->m_properties[PROP_WRAP_AROUND] = "true";
|
||||
m_difficulty->m_properties[PROP_MIN_VALUE] = StringUtils::toString(RaceManager::PLAYER_DIFFICULTY_EASIEST);
|
||||
m_difficulty->m_properties[PROP_MAX_VALUE] = StringUtils::toString(RaceManager::PLAYER_DIFFICULTY_HARDEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_player_ident_spinner->m_properties[PROP_MIN_VALUE] = "0";
|
||||
m_player_ident_spinner->m_properties[PROP_MAX_VALUE] = "0";
|
||||
m_difficulty->m_properties[PROP_MIN_VALUE] = StringUtils::toString(RaceManager::PLAYER_DIFFICULTY_NORMAL);
|
||||
m_difficulty->m_properties[PROP_MAX_VALUE] = StringUtils::toString(RaceManager::PLAYER_DIFFICULTY_NORMAL);
|
||||
}
|
||||
|
||||
//m_player_ident_spinner->m_event_handler = this;
|
||||
m_children.push_back(m_player_ident_spinner);
|
||||
|
||||
// ----- Kart model view
|
||||
m_model_view = new ModelViewWidget();
|
||||
|
||||
m_model_view->m_x = model_x;
|
||||
m_model_view->m_y = model_y;
|
||||
m_model_view->m_w = model_w;
|
||||
m_model_view->m_h = model_h;
|
||||
m_model_view->m_properties[PROP_ID] =
|
||||
StringUtils::insertValues("@p%i_model", m_player_id);
|
||||
//m_model_view->setParent(this);
|
||||
m_children.push_back(m_model_view);
|
||||
|
||||
// Init kart model
|
||||
const std::string default_kart = UserConfigParams::m_default_kart;
|
||||
const KartProperties* props =
|
||||
kart_properties_manager->getKart(default_kart);
|
||||
|
||||
if(!props)
|
||||
{
|
||||
// If the default kart can't be found (e.g. previously a addon
|
||||
// kart was used, but the addon package was removed), use the
|
||||
// first kart as a default. This way we don't have to hardcode
|
||||
// any kart names.
|
||||
int id = kart_properties_manager->getKartByGroup(kart_group, 0);
|
||||
if (id == -1)
|
||||
{
|
||||
props = kart_properties_manager->getKartById(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
props = kart_properties_manager->getKartById(id);
|
||||
}
|
||||
|
||||
if(!props)
|
||||
Log::fatal("KartSelectionScreen", "Can't find default "
|
||||
"kart '%s' nor any other kart.",
|
||||
default_kart.c_str());
|
||||
}
|
||||
m_kartInternalName = props->getIdent();
|
||||
|
||||
const KartModel &kart_model = props->getMasterKartModel();
|
||||
|
||||
float scale = 35.0f;
|
||||
if (kart_model.getLength() > 1.45f)
|
||||
{
|
||||
// if kart is too long, size it down a bit so that it fits
|
||||
scale = 30.0f;
|
||||
}
|
||||
|
||||
m_model_view->addModel( kart_model.getModel(), Vec3(0,0,0),
|
||||
Vec3(scale, scale, scale),
|
||||
kart_model.getBaseFrame() );
|
||||
m_model_view->addModel( kart_model.getWheelModel(0),
|
||||
kart_model.getWheelGraphicsPosition(0) );
|
||||
m_model_view->addModel( kart_model.getWheelModel(1),
|
||||
kart_model.getWheelGraphicsPosition(1) );
|
||||
m_model_view->addModel( kart_model.getWheelModel(2),
|
||||
kart_model.getWheelGraphicsPosition(2) );
|
||||
m_model_view->addModel( kart_model.getWheelModel(3),
|
||||
kart_model.getWheelGraphicsPosition(3) );
|
||||
for(size_t i=0 ; i < kart_model.getSpeedWeightedObjectsCount() ; i++)
|
||||
{
|
||||
const SpeedWeightedObject& obj = kart_model.getSpeedWeightedObject(i);
|
||||
m_model_view->addModel(obj.m_model, obj.m_position);
|
||||
}
|
||||
m_model_view->setRotateContinuously( 35.0f );
|
||||
|
||||
// ---- Kart name label
|
||||
m_kart_name = new LabelWidget(true, true);
|
||||
m_kart_name->setText(props->getName(), false);
|
||||
m_kart_name->m_properties[PROP_TEXT_ALIGN] = "center";
|
||||
m_kart_name->m_properties[PROP_ID] =
|
||||
StringUtils::insertValues("@p%i_kartname", m_player_id);
|
||||
m_kart_name->m_x = kart_name_x;
|
||||
m_kart_name->m_y = kart_name_y;
|
||||
m_kart_name->m_w = kart_name_w;
|
||||
m_kart_name->m_h = kart_name_h;
|
||||
m_children.push_back(m_kart_name);
|
||||
} // PlayerKartWidget
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
PlayerKartWidget::~PlayerKartWidget()
|
||||
{
|
||||
if (GUIEngine::getFocusForPlayer(m_player_id) == this)
|
||||
{
|
||||
GUIEngine::focusNothingForPlayer(m_player_id);
|
||||
}
|
||||
|
||||
//if (m_player_ID_label->getIrrlichtElement() != NULL)
|
||||
// m_player_ID_label->getIrrlichtElement()->remove();
|
||||
|
||||
if (m_player_ident_spinner != NULL)
|
||||
{
|
||||
m_player_ident_spinner->setListener(NULL);
|
||||
|
||||
if (m_player_ident_spinner->getIrrlichtElement() != NULL)
|
||||
{
|
||||
m_player_ident_spinner->getIrrlichtElement()->remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_model_view->getIrrlichtElement() != NULL)
|
||||
m_model_view->getIrrlichtElement()->remove();
|
||||
|
||||
if (m_kart_name->getIrrlichtElement() != NULL)
|
||||
m_kart_name->getIrrlichtElement()->remove();
|
||||
getCurrentScreen()->manualRemoveWidget(this);
|
||||
|
||||
#ifdef DEBUG
|
||||
m_magic_number = 0xDEADBEEF;
|
||||
#endif
|
||||
} // ~PlayerKartWidget
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when players are renumbered (changes the player ID) */
|
||||
void PlayerKartWidget::setPlayerID(const int newPlayerID)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
|
||||
if (StateManager::get()->getActivePlayer(newPlayerID)
|
||||
!= m_associated_player)
|
||||
{
|
||||
Log::error("KartSelectionScreen", "Internal "
|
||||
"inconsistency, PlayerKartWidget has IDs and "
|
||||
"pointers that do not correspond to one player");
|
||||
Log::fatal("KartSelectionScreen", " Player: %p - Index: %d - m_associated_player: %p",
|
||||
StateManager::get()->getActivePlayer(newPlayerID),
|
||||
newPlayerID, m_associated_player);
|
||||
}
|
||||
|
||||
// Remove current focus, but remember it
|
||||
Widget* focus = GUIEngine::getFocusForPlayer(m_player_id);
|
||||
GUIEngine::focusNothingForPlayer(m_player_id);
|
||||
|
||||
// Change the player ID
|
||||
m_player_id = newPlayerID;
|
||||
m_player_ident_spinner->setID(m_player_id);
|
||||
m_kart_stats->setDisplayText(m_player_id == 0);
|
||||
// restore previous focus, but with new player ID
|
||||
if (focus != NULL) focus->setFocusForPlayer(m_player_id);
|
||||
|
||||
if (m_player_ident_spinner != NULL)
|
||||
{
|
||||
m_player_ident_spinner->setID(m_player_id);
|
||||
}
|
||||
} // setPlayerID
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ID of this player */
|
||||
int PlayerKartWidget::getPlayerID() const
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_player_id;
|
||||
} // getPlayerID
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add the widgets to the current screen */
|
||||
void PlayerKartWidget::add()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
|
||||
assert(KartSelectionScreen::getRunningInstance()
|
||||
->m_kart_widgets.contains(this));
|
||||
if (m_associated_player) // if player is local
|
||||
{
|
||||
bool mineInList = false;
|
||||
for (unsigned int p=0; p<StateManager::get()->activePlayerCount(); p++)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
assert(StateManager::get()->getActivePlayer(p)->ok());
|
||||
#endif
|
||||
if (StateManager::get()->getActivePlayer(p) == m_associated_player)
|
||||
{
|
||||
mineInList = true;
|
||||
}
|
||||
}
|
||||
assert(mineInList);
|
||||
}
|
||||
|
||||
//m_player_ID_label->add();
|
||||
|
||||
// the first player will have an ID of its own to allow for keyboard
|
||||
// navigation despite this widget being added last
|
||||
if (m_irrlicht_widget_id != -1)
|
||||
m_player_ident_spinner->m_reserved_id = m_irrlicht_widget_id;
|
||||
else
|
||||
m_player_ident_spinner->m_reserved_id = Widget::getNewNoFocusID();
|
||||
|
||||
m_player_ident_spinner->add();
|
||||
m_player_ident_spinner->getIrrlichtElement()->setTabStop(false);
|
||||
m_player_ident_spinner->setListener(this);
|
||||
m_difficulty->add();
|
||||
m_kart_stats->add();
|
||||
m_model_view->add();
|
||||
m_kart_name->add();
|
||||
|
||||
m_model_view->update(0);
|
||||
|
||||
m_player_ident_spinner->clearLabels();
|
||||
m_difficulty->clearLabels();
|
||||
|
||||
irr::core::stringw name; // name of the player
|
||||
if (m_associated_player)
|
||||
name = m_associated_player->getProfile()->getName();
|
||||
if (m_associated_user)
|
||||
name = m_associated_user->getUserName();
|
||||
|
||||
if (m_parent_screen->m_multiplayer)
|
||||
{
|
||||
const int player_amount = PlayerManager::get()->getNumPlayers();
|
||||
for (int n=0; n<player_amount; n++)
|
||||
{
|
||||
core::stringw name = PlayerManager::get()->getPlayer(n)->getName();
|
||||
m_player_ident_spinner->addLabel(translations->fribidize(name));
|
||||
}
|
||||
|
||||
// select the right player profile in the spinner
|
||||
m_player_ident_spinner->setValue(name);
|
||||
m_difficulty->addLabel(_("Easiest"));
|
||||
m_difficulty->addLabel(_("Easy"));
|
||||
m_difficulty->addLabel(_("Normal"));
|
||||
m_difficulty->addLabel(_("Hard"));
|
||||
m_difficulty->addLabel(_("Hardest"));
|
||||
m_difficulty->setValue(RaceManager::PLAYER_DIFFICULTY_NORMAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_player_ident_spinner->addLabel(name);
|
||||
m_player_ident_spinner->setVisible(false);
|
||||
m_difficulty->addLabel(_("Normal"));
|
||||
m_difficulty->setVisible(false);
|
||||
}
|
||||
|
||||
assert(m_player_ident_spinner->getStringValue() == name);
|
||||
} // add
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the associated ActivePlayer object*/
|
||||
StateManager::ActivePlayer* PlayerKartWidget::getAssociatedPlayer()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_associated_player;
|
||||
} // getAssociatedPlayer
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Starts a 'move/resize' animation, by simply passing destination coords.
|
||||
* The animation will then occur on each call to 'onUpdate'. */
|
||||
void PlayerKartWidget::move(const int x, const int y, const int w, const int h)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
target_x = x;
|
||||
target_y = y;
|
||||
target_w = w;
|
||||
target_h = h;
|
||||
|
||||
x_speed = abs( m_x - x ) / 300.0f;
|
||||
y_speed = abs( m_y - y ) / 300.0f;
|
||||
w_speed = abs( m_w - w ) / 300.0f;
|
||||
h_speed = abs( m_h - h ) / 300.0f;
|
||||
} // move
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Call when player confirmed his identity and kart */
|
||||
void PlayerKartWidget::markAsReady()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
if (m_ready) return; // already ready
|
||||
|
||||
m_ready = true;
|
||||
|
||||
stringw playerNameString = m_player_ident_spinner->getStringValue();
|
||||
core::rect<s32> rect(core::position2di(m_player_ident_spinner->m_x,
|
||||
m_player_ident_spinner->m_y),
|
||||
core::dimension2di(m_player_ident_spinner->m_w,
|
||||
m_player_ident_spinner->m_h));
|
||||
// 'playerNameString' is already fribidize, so we need to use
|
||||
// 'insertValues' and not _("...", a) so it's not flipped again
|
||||
m_ready_text =
|
||||
GUIEngine::getGUIEnv()->addStaticText(
|
||||
StringUtils::insertValues(_("%s is ready"),
|
||||
playerNameString).c_str(),
|
||||
rect );
|
||||
m_ready_text->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER );
|
||||
|
||||
m_children.remove(m_player_ident_spinner);
|
||||
m_player_ident_spinner->setListener(NULL);
|
||||
m_player_ident_spinner->getIrrlichtElement()->remove();
|
||||
m_player_ident_spinner->elementRemoved();
|
||||
delete m_player_ident_spinner;
|
||||
m_player_ident_spinner = NULL;
|
||||
|
||||
sfx_manager->quickSound( "wee" );
|
||||
|
||||
m_model_view->setRotateTo(30.0f, 1.0f);
|
||||
|
||||
player_id_w *= 2;
|
||||
player_name_w = 0;
|
||||
|
||||
m_model_view->setBadge(OK_BADGE);
|
||||
} // markAsReady
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \return Whether this player confirmed his kart and indent selection */
|
||||
bool PlayerKartWidget::isReady()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_ready;
|
||||
} // isReady
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Updates the animation (moving/shrinking/etc.) */
|
||||
void PlayerKartWidget::onUpdate(float delta)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
if (target_x == m_x && target_y == m_y &&
|
||||
target_w == m_w && target_h == m_h) return;
|
||||
|
||||
int move_step = (int)(delta*1000.0f);
|
||||
|
||||
// move x towards target
|
||||
if (m_x < target_x)
|
||||
{
|
||||
m_x += (int)(move_step*x_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_x > target_x) m_x = target_x;
|
||||
}
|
||||
else if (m_x > target_x)
|
||||
{
|
||||
m_x -= (int)(move_step*x_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_x < target_x) m_x = target_x;
|
||||
}
|
||||
|
||||
// move y towards target
|
||||
if (m_y < target_y)
|
||||
{
|
||||
m_y += (int)(move_step*y_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_y > target_y) m_y = target_y;
|
||||
}
|
||||
else if (m_y > target_y)
|
||||
{
|
||||
m_y -= (int)(move_step*y_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_y < target_y) m_y = target_y;
|
||||
}
|
||||
|
||||
// move w towards target
|
||||
if (m_w < target_w)
|
||||
{
|
||||
m_w += (int)(move_step*w_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_w > target_w) m_w = target_w;
|
||||
}
|
||||
else if (m_w > target_w)
|
||||
{
|
||||
m_w -= (int)(move_step*w_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_w < target_w) m_w = target_w;
|
||||
}
|
||||
// move h towards target
|
||||
if (m_h < target_h)
|
||||
{
|
||||
m_h += (int)(move_step*h_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_h > target_h) m_h = target_h;
|
||||
}
|
||||
else if (m_h > target_h)
|
||||
{
|
||||
m_h -= (int)(move_step*h_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_h < target_h) m_h = target_h;
|
||||
}
|
||||
|
||||
setSize(m_x, m_y, m_w, m_h);
|
||||
|
||||
if (m_player_ident_spinner != NULL)
|
||||
{
|
||||
m_player_ident_spinner->move(player_name_x,
|
||||
player_name_y,
|
||||
player_name_w,
|
||||
player_name_h );
|
||||
}
|
||||
if (m_ready_text != NULL)
|
||||
{
|
||||
m_ready_text->setRelativePosition(
|
||||
core::recti(core::position2di(player_name_x, player_name_y),
|
||||
core::dimension2di(player_name_w, player_name_h)) );
|
||||
}
|
||||
if (!m_parent_screen->m_multiplayer)
|
||||
{
|
||||
m_kart_stats->move(m_kart_stats_x,
|
||||
m_kart_stats_y,
|
||||
m_kart_stats_w,
|
||||
m_kart_stats_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_kart_stats->move(m_x, m_y + m_h/2,
|
||||
m_w, m_h/2);
|
||||
m_difficulty->move(m_difficulty_x, m_difficulty_y,
|
||||
m_difficulty_w, m_difficulty_h);
|
||||
}
|
||||
|
||||
|
||||
m_model_view->move(model_x,
|
||||
model_y,
|
||||
model_w,
|
||||
model_h);
|
||||
|
||||
m_kart_name->move(kart_name_x,
|
||||
kart_name_y,
|
||||
kart_name_w,
|
||||
kart_name_h);
|
||||
|
||||
// When coming from the overworld, we must rebuild the preview scene at
|
||||
// least once, since the scene is being cleared by leaving the overworld
|
||||
if (m_not_updated_yet)
|
||||
{
|
||||
m_model_view->clearRttProvider();
|
||||
m_not_updated_yet = false;
|
||||
}
|
||||
} // onUpdate
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Event callback */
|
||||
GUIEngine::EventPropagation PlayerKartWidget::transmitEvent(Widget* w,
|
||||
const std::string& originator,
|
||||
const int m_player_id )
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
// if it's declared ready, there is really nothing to process
|
||||
if (m_ready) return EVENT_LET;
|
||||
|
||||
//std::cout << "= kart selection :: transmitEvent "
|
||||
// << originator << " =\n";
|
||||
|
||||
std::string name = w->m_properties[PROP_ID];
|
||||
|
||||
//std::cout << " (checking if that's me: I am "
|
||||
// << spinnerID << ")\n";
|
||||
|
||||
// update player profile when spinner changed
|
||||
if (originator == spinnerID)
|
||||
{
|
||||
if(UserConfigParams::logGUI())
|
||||
{
|
||||
Log::info("[KartSelectionScreen]", "Identity changed "
|
||||
"for player %s : %s",m_player_id,
|
||||
irr::core::stringc(
|
||||
m_player_ident_spinner->getStringValue()
|
||||
.c_str()).c_str());
|
||||
}
|
||||
|
||||
if (m_parent_screen->m_multiplayer)
|
||||
{
|
||||
m_associated_player->setPlayerProfile(
|
||||
PlayerManager::get()->getPlayer(m_player_ident_spinner
|
||||
->getValue()) );
|
||||
}
|
||||
}
|
||||
|
||||
return EVENT_LET; // continue propagating the event
|
||||
} // transmitEvent
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Sets the size of the widget as a whole, and placed children widgets
|
||||
* inside itself */
|
||||
void PlayerKartWidget::setSize(const int x, const int y, const int w, const int h)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_w = w;
|
||||
m_h = h;
|
||||
|
||||
// -- sizes
|
||||
player_id_w = w;
|
||||
player_id_h = GUIEngine::getFontHeight();
|
||||
|
||||
m_difficulty_h = GUIEngine::getFontHeight();
|
||||
|
||||
player_name_h = 40;
|
||||
player_name_w = std::min(400, w);
|
||||
|
||||
kart_name_w = w;
|
||||
kart_name_h = 25;
|
||||
|
||||
// for shrinking effect
|
||||
if (h < 175)
|
||||
{
|
||||
const float factor = h / 175.0f;
|
||||
kart_name_h = (int)(kart_name_h*factor);
|
||||
player_name_h = (int)(player_name_h*factor);
|
||||
player_id_h = (int)(player_id_h*factor);
|
||||
}
|
||||
|
||||
// --- layout
|
||||
player_id_x = x;
|
||||
player_id_y = y;
|
||||
|
||||
player_name_x = x + w/2 - player_name_w/2;
|
||||
player_name_y = y + player_id_h;
|
||||
|
||||
if (m_parent_screen->m_multiplayer)
|
||||
{
|
||||
const int modelMaxHeight = (h - kart_name_h - player_name_h
|
||||
- player_id_h - m_difficulty_h)/2;
|
||||
const int modelMaxWidth = w;
|
||||
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
|
||||
model_x = x + w/2 - (int)(bestSize/2);
|
||||
model_y = y + player_name_h + player_id_h;
|
||||
model_w = bestSize;
|
||||
model_h = bestSize;
|
||||
|
||||
m_kart_stats_w = model_w;
|
||||
m_kart_stats_h = model_h;
|
||||
m_kart_stats_x = x + w/2 - (int)(bestSize/2);
|
||||
m_kart_stats_y = model_y + model_h + m_difficulty_h;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int modelMaxHeight = h - kart_name_h - player_name_h
|
||||
- player_id_h - m_difficulty_h;
|
||||
const int modelMaxWidth = w;
|
||||
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
|
||||
const int modelY = y + player_name_h + player_id_h;
|
||||
model_x = x + w/4 - (int)(bestSize/2);
|
||||
model_y = modelY + modelMaxHeight/2 - bestSize/2;
|
||||
model_w = (int)(bestSize);
|
||||
model_h = bestSize;
|
||||
|
||||
m_kart_stats_w = w/2;
|
||||
m_kart_stats_h = h;
|
||||
m_kart_stats_x = x + w/2;
|
||||
m_kart_stats_y = y;
|
||||
}
|
||||
|
||||
kart_name_x = x;
|
||||
kart_name_y = y + h - kart_name_h;
|
||||
|
||||
m_difficulty_w = w * 2 / 3;
|
||||
m_difficulty_x = x + (w - m_difficulty_w) / 2;
|
||||
m_difficulty_y = model_y + model_h;
|
||||
} // setSize
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** Sets which kart was selected for this player */
|
||||
void PlayerKartWidget::setKartInternalName(const std::string& whichKart)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
m_kartInternalName = whichKart;
|
||||
} // setKartInternalName
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
const std::string& PlayerKartWidget::getKartInternalName() const
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_kartInternalName;
|
||||
} // getKartInternalName
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** \brief Event callback from ISpinnerConfirmListener */
|
||||
EventPropagation PlayerKartWidget::onSpinnerConfirmed()
|
||||
{
|
||||
KartSelectionScreen::getRunningInstance()->playerConfirm(m_player_id);
|
||||
return EVENT_BLOCK;
|
||||
} // onSpinnerConfirmed
|
||||
|
175
src/guiengine/widgets/player_kart_widget.hpp
Normal file
175
src/guiengine/widgets/player_kart_widget.hpp
Normal file
@ -0,0 +1,175 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
//
|
||||
// Copyright (C) 2006-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef PLAYER_KART_WIDGET_HPP
|
||||
#define PLAYER_KART_WIDGET_HPP
|
||||
|
||||
#include "guiengine/widgets/spinner_widget.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include <IGUIStaticText.h>
|
||||
#include <IGUIImage.h>
|
||||
#include <string>
|
||||
|
||||
namespace Online
|
||||
{
|
||||
class OnlineProfile;
|
||||
}
|
||||
|
||||
class KartSelectionScreen;
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
class PlayerNameSpinner;
|
||||
class KartStatsWidget;
|
||||
class ModelViewWidget;
|
||||
class LabelWidget;
|
||||
|
||||
/** A widget representing the kart selection for a player (i.e. the player's
|
||||
* number, name, the kart view, the kart's name) */
|
||||
class PlayerKartWidget : public GUIEngine::Widget,
|
||||
public GUIEngine::SpinnerWidget::ISpinnerConfirmListener
|
||||
{
|
||||
/** Whether this player confirmed their selection */
|
||||
bool m_ready;
|
||||
|
||||
/** widget coordinates */
|
||||
int player_id_x, player_id_y, player_id_w, player_id_h;
|
||||
int player_name_x, player_name_y, player_name_w, player_name_h;
|
||||
int model_x, model_y, model_w, model_h;
|
||||
int kart_name_x, kart_name_y, kart_name_w, kart_name_h;
|
||||
int m_kart_stats_x, m_kart_stats_y, m_kart_stats_w, m_kart_stats_h;
|
||||
int m_difficulty_x, m_difficulty_y, m_difficulty_w, m_difficulty_h;
|
||||
|
||||
/** A reserved ID for this widget if any, -1 otherwise. (If no ID is
|
||||
* reserved, widget will not be in the regular tabbing order */
|
||||
int m_irrlicht_widget_id;
|
||||
|
||||
/** For animation purposes (see method 'move') */
|
||||
int target_x, target_y, target_w, target_h;
|
||||
float x_speed, y_speed, w_speed, h_speed;
|
||||
|
||||
/** Object representing this player */
|
||||
/** Local info about the player. */
|
||||
StateManager::ActivePlayer* m_associated_player;
|
||||
int m_player_id;
|
||||
|
||||
/** Network info about the user. */
|
||||
Online::OnlineProfile* m_associated_user;
|
||||
|
||||
/** Internal name of the spinner; useful to interpret spinner events,
|
||||
* which contain the name of the activated object */
|
||||
std::string spinnerID;
|
||||
|
||||
#ifdef DEBUG
|
||||
long m_magic_number;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
LEAK_CHECK()
|
||||
|
||||
/** Sub-widgets created by this widget */
|
||||
PlayerNameSpinner* m_player_ident_spinner;
|
||||
SpinnerWidget* m_difficulty;
|
||||
KartStatsWidget* m_kart_stats;
|
||||
ModelViewWidget* m_model_view;
|
||||
LabelWidget* m_kart_name;
|
||||
|
||||
KartSelectionScreen* m_parent_screen;
|
||||
|
||||
irr::gui::IGUIStaticText* m_ready_text;
|
||||
|
||||
//LabelWidget *getPlayerIDLabel() {return m_player_ID_label;}
|
||||
core::stringw deviceName;
|
||||
std::string m_kartInternalName;
|
||||
|
||||
bool m_not_updated_yet;
|
||||
|
||||
PlayerKartWidget(KartSelectionScreen* parent,
|
||||
StateManager::ActivePlayer* associated_player,
|
||||
Online::OnlineProfile* associated_user,
|
||||
core::recti area, const int player_id,
|
||||
std::string kart_group,
|
||||
const int irrlicht_idget_id=-1);
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
~PlayerKartWidget();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when players are renumbered (changes the player ID) */
|
||||
void setPlayerID(const int newPlayerID);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ID of this player */
|
||||
int getPlayerID() const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add the widgets to the current screen */
|
||||
virtual void add();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the associated ActivePlayer object*/
|
||||
StateManager::ActivePlayer* getAssociatedPlayer();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Starts a 'move/resize' animation, by simply passing destination coords.
|
||||
* The animation will then occur on each call to 'onUpdate'. */
|
||||
void move(const int x, const int y, const int w, const int h);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Call when player confirmed his identity and kart */
|
||||
void markAsReady();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \return Whether this player confirmed his kart and indent selection */
|
||||
bool isReady();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Updates the animation (moving/shrinking/etc.) */
|
||||
void onUpdate(float delta);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Event callback */
|
||||
virtual GUIEngine::EventPropagation transmitEvent(
|
||||
GUIEngine::Widget* w,
|
||||
const std::string& originator,
|
||||
const int m_player_id);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Sets the size of the widget as a whole, and placed children widgets
|
||||
* inside itself */
|
||||
void setSize(const int x, const int y, const int w, const int h);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** Sets which kart was selected for this player */
|
||||
void setKartInternalName(const std::string& whichKart);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
const std::string& getKartInternalName() const;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** \brief Event callback from ISpinnerConfirmListener */
|
||||
virtual GUIEngine::EventPropagation onSpinnerConfirmed();
|
||||
}; // PlayerKartWidget
|
||||
}
|
||||
|
||||
#endif
|
||||
|
77
src/guiengine/widgets/player_name_spinner.cpp
Normal file
77
src/guiengine/widgets/player_name_spinner.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
//
|
||||
// Copyright (C) 2006-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#include "guiengine/widgets/player_name_spinner.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include <IGUIEnvironment.h>
|
||||
|
||||
using namespace GUIEngine;
|
||||
|
||||
PlayerNameSpinner::PlayerNameSpinner(KartSelectionScreen* parent,
|
||||
const int player_id)
|
||||
{
|
||||
m_player_id = player_id;
|
||||
m_incorrect = false;
|
||||
m_red_mark_widget = NULL;
|
||||
m_parent = parent;
|
||||
setUseBackgroundColor();//except for multiplayer kart selection, this is false
|
||||
setSpinnerWidgetPlayerID(m_player_id);
|
||||
} // PlayerNameSpinner
|
||||
// ------------------------------------------------------------------------
|
||||
void PlayerNameSpinner::setID(const int m_player_id)
|
||||
{
|
||||
PlayerNameSpinner::m_player_id = m_player_id;
|
||||
setSpinnerWidgetPlayerID(m_player_id);
|
||||
} // setID
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add a red mark on the spinner to mean "invalid choice" */
|
||||
void PlayerNameSpinner::markAsIncorrect()
|
||||
{
|
||||
if (m_incorrect) return; // already flagged as incorrect
|
||||
|
||||
m_incorrect = true;
|
||||
|
||||
irr::video::ITexture* texture = irr_driver->getTexture(FileManager::GUI,
|
||||
"red_mark.png" );
|
||||
const int mark_size = m_h;
|
||||
const int mark_x = m_w - mark_size*2;
|
||||
const int mark_y = 0;
|
||||
core::recti red_mark_area(mark_x, mark_y, mark_x + mark_size,
|
||||
mark_y + mark_size);
|
||||
m_red_mark_widget = GUIEngine::getGUIEnv()->addImage( red_mark_area,
|
||||
/* parent */ m_element );
|
||||
m_red_mark_widget->setImage(texture);
|
||||
m_red_mark_widget->setScaleImage(true);
|
||||
m_red_mark_widget->setTabStop(false);
|
||||
m_red_mark_widget->setUseAlphaChannel(true);
|
||||
} // markAsIncorrect
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Remove any red mark set with 'markAsIncorrect' */
|
||||
void PlayerNameSpinner::markAsCorrect()
|
||||
{
|
||||
if (m_incorrect)
|
||||
{
|
||||
m_red_mark_widget->remove();
|
||||
m_red_mark_widget = NULL;
|
||||
m_incorrect = false;
|
||||
}
|
||||
} // markAsCorrect
|
||||
|
54
src/guiengine/widgets/player_name_spinner.hpp
Normal file
54
src/guiengine/widgets/player_name_spinner.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
//
|
||||
// Copyright (C) 2006-2013 SuperTuxKart-Team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef PLAYER_NAME_SPINNER_HPP
|
||||
#define PLAYER_NAME_SPINNER_HPP
|
||||
|
||||
#include "guiengine/widgets/spinner_widget.hpp"
|
||||
#include <IGUIImage.h>
|
||||
|
||||
class KartSelectionScreen;
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
/** A small extension to the spinner widget to add features like player ID
|
||||
* management or badging */
|
||||
class PlayerNameSpinner : public GUIEngine::SpinnerWidget
|
||||
{
|
||||
int m_player_id;
|
||||
bool m_incorrect;
|
||||
irr::gui::IGUIImage* m_red_mark_widget;
|
||||
KartSelectionScreen* m_parent;
|
||||
//virtual EventPropagation focused(const int m_playerID) ;
|
||||
|
||||
public:
|
||||
PlayerNameSpinner(KartSelectionScreen* parent, const int playerID);
|
||||
// ------------------------------------------------------------------------
|
||||
void setID(const int m_playerID);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add a red mark on the spinner to mean "invalid choice" */
|
||||
void markAsIncorrect();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Remove any red mark set with 'markAsIncorrect' */
|
||||
void markAsCorrect();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -20,52 +20,41 @@
|
||||
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "config/player_manager.hpp"
|
||||
#include "config/player_profile.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widgets/bubble_widget.hpp"
|
||||
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/label_widget.hpp"
|
||||
#include "guiengine/widgets/kart_stats_widget.hpp"
|
||||
#include "guiengine/widgets/model_view_widget.hpp"
|
||||
#include "guiengine/widgets/ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/spinner_widget.hpp"
|
||||
#include "input/input.hpp"
|
||||
#include "guiengine/widgets/player_kart_widget.hpp"
|
||||
#include "guiengine/widgets/player_name_spinner.hpp"
|
||||
#include "input/input_manager.hpp"
|
||||
#include "input/device_manager.hpp"
|
||||
#include "input/input_device.hpp"
|
||||
#include "items/item_manager.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "modes/overworld.hpp"
|
||||
#include "online/online_profile.hpp"
|
||||
#include "states_screens/race_setup_screen.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "utils/log.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <IGUIEnvironment.h>
|
||||
#include <IGUIImage.h>
|
||||
#include <IGUIButton.h>
|
||||
|
||||
using namespace GUIEngine;
|
||||
using irr::core::stringw;
|
||||
|
||||
|
||||
static const char RANDOM_KART_ID[] = "randomkart";
|
||||
static const char ID_DONT_USE[] = "x";
|
||||
// Use '/' as special character to avoid that someone creates
|
||||
// a kart called 'locked'
|
||||
static const char ID_LOCKED[] = "locked/";
|
||||
KartSelectionScreen* KartSelectionScreen::m_instance_ptr = NULL;
|
||||
//DEFINE_SCREEN_SINGLETON( KartSelectionScreen );
|
||||
|
||||
class PlayerKartWidget;
|
||||
//DEFINE_SCREEN_SINGLETON( KartSelectionScreen );
|
||||
KartSelectionScreen* KartSelectionScreen::m_instance_ptr = NULL;
|
||||
|
||||
static int g_root_id;
|
||||
|
||||
/** Currently, navigation for multiple players at the same time is implemented
|
||||
in a somewhat clunky way. An invisible "dispatcher" widget is added above
|
||||
@ -73,7 +62,6 @@ class PlayerKartWidget;
|
||||
turn moves the selection to the appropriate spinner. "tabbing roots" are
|
||||
used to make navigation back down possible. (FIXME: maybe find a cleaner
|
||||
way?) */
|
||||
static int g_root_id;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
FocusDispatcher::FocusDispatcher(KartSelectionScreen* parent) : Widget(WTYPE_BUTTON)
|
||||
@ -119,772 +107,48 @@ void FocusDispatcher::add()
|
||||
m_element->setTabOrder(m_id);
|
||||
}
|
||||
|
||||
EventPropagation FocusDispatcher::focused(const int playerID)
|
||||
{
|
||||
if (!m_is_initialised) return EVENT_LET;
|
||||
|
||||
if(UserConfigParams::logGUI())
|
||||
Log::info("[KartSelectionScreen]", "FocusDispatcher focused by player %u",
|
||||
playerID);
|
||||
|
||||
// since this screen is multiplayer, redirect focus to the right widget
|
||||
const int amount = m_parent->m_kart_widgets.size();
|
||||
for (int n=0; n<amount; n++)
|
||||
{
|
||||
if (m_parent->m_kart_widgets[n].getPlayerID() == playerID)
|
||||
{
|
||||
// If player is done, don't do anything with focus
|
||||
if (m_parent->m_kart_widgets[n].isReady())
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
|
||||
//std::cout << "--> Redirecting focus for player " << playerID
|
||||
// << " from FocusDispatcher " <<
|
||||
// " (ID " << m_element->getID() <<
|
||||
// ") to spinner " << n << " (ID " <<
|
||||
// m_parent->m_kart_widgets[n].m_player_ident_spinner
|
||||
// ->getIrrlichtElement()->getID() <<
|
||||
// ")" << std::endl;
|
||||
|
||||
m_parent->m_kart_widgets[n].m_player_ident_spinner
|
||||
->setFocusForPlayer(playerID);
|
||||
|
||||
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
//std::cerr << "[KartSelectionScreen] WARNING: the focus dispatcher can't
|
||||
// find the widget for player " << playerID << "!\n";
|
||||
//assert(false);
|
||||
return GUIEngine::EVENT_LET;
|
||||
} // focused
|
||||
|
||||
static FocusDispatcher* g_dispatcher = NULL;
|
||||
|
||||
// ============================================================================
|
||||
|
||||
/** A small extension to the spinner widget to add features like player ID
|
||||
* management or badging */
|
||||
|
||||
PlayerNameSpinner::PlayerNameSpinner(KartSelectionScreen* parent,
|
||||
const int player_id)
|
||||
{
|
||||
m_player_id = player_id;
|
||||
m_incorrect = false;
|
||||
m_red_mark_widget = NULL;
|
||||
m_parent = parent;
|
||||
setUseBackgroundColor();//except for multiplayer kart selection, this is false
|
||||
setSpinnerWidgetPlayerID(m_player_id);
|
||||
} // PlayerNameSpinner
|
||||
// ------------------------------------------------------------------------
|
||||
void PlayerNameSpinner::setID(const int m_player_id)
|
||||
{
|
||||
PlayerNameSpinner::m_player_id = m_player_id;
|
||||
setSpinnerWidgetPlayerID(m_player_id);
|
||||
} // setID
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add a red mark on the spinner to mean "invalid choice" */
|
||||
void PlayerNameSpinner::markAsIncorrect()
|
||||
{
|
||||
if (m_incorrect) return; // already flagged as incorrect
|
||||
|
||||
m_incorrect = true;
|
||||
|
||||
irr::video::ITexture* texture = irr_driver->getTexture(FileManager::GUI,
|
||||
"red_mark.png" );
|
||||
const int mark_size = m_h;
|
||||
const int mark_x = m_w - mark_size*2;
|
||||
const int mark_y = 0;
|
||||
core::recti red_mark_area(mark_x, mark_y, mark_x + mark_size,
|
||||
mark_y + mark_size);
|
||||
m_red_mark_widget = GUIEngine::getGUIEnv()->addImage( red_mark_area,
|
||||
/* parent */ m_element );
|
||||
m_red_mark_widget->setImage(texture);
|
||||
m_red_mark_widget->setScaleImage(true);
|
||||
m_red_mark_widget->setTabStop(false);
|
||||
m_red_mark_widget->setUseAlphaChannel(true);
|
||||
} // markAsIncorrect
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Remove any red mark set with 'markAsIncorrect' */
|
||||
void PlayerNameSpinner::markAsCorrect()
|
||||
{
|
||||
if (m_incorrect)
|
||||
{
|
||||
m_red_mark_widget->remove();
|
||||
m_red_mark_widget = NULL;
|
||||
m_incorrect = false;
|
||||
}
|
||||
} // markAsCorrect
|
||||
// ============================================================================
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#pragma mark PlayerKartWidget
|
||||
#endif
|
||||
|
||||
/** A widget representing the kart selection for a player (i.e. the player's
|
||||
* number, name, the kart view, the kart's name) */
|
||||
|
||||
PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent,
|
||||
StateManager::ActivePlayer* associated_player,
|
||||
Online::OnlineProfile* associated_user,
|
||||
core::recti area, const int player_id,
|
||||
std::string kart_group,
|
||||
const int irrlicht_widget_id) : Widget(WTYPE_DIV)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (associated_player)
|
||||
assert(associated_player->ok());
|
||||
m_magic_number = 0x33445566;
|
||||
#endif
|
||||
m_ready_text = NULL;
|
||||
m_parent_screen = parent;
|
||||
|
||||
m_associated_user = associated_user;
|
||||
m_associated_player = associated_player;
|
||||
x_speed = 1.0f;
|
||||
y_speed = 1.0f;
|
||||
w_speed = 1.0f;
|
||||
h_speed = 1.0f;
|
||||
m_ready = false;
|
||||
m_not_updated_yet = true;
|
||||
|
||||
m_irrlicht_widget_id = irrlicht_widget_id;
|
||||
|
||||
m_player_id = player_id;
|
||||
m_properties[PROP_ID] = StringUtils::insertValues("@p%i", m_player_id);
|
||||
|
||||
setSize(area.UpperLeftCorner.X, area.UpperLeftCorner.Y,
|
||||
area.getWidth(), area.getHeight() );
|
||||
target_x = m_x;
|
||||
target_y = m_y;
|
||||
target_w = m_w;
|
||||
target_h = m_h;
|
||||
|
||||
// ---- Player identity spinner
|
||||
m_player_ident_spinner = NULL;
|
||||
|
||||
m_player_ident_spinner = new PlayerNameSpinner(parent, m_player_id);
|
||||
m_player_ident_spinner->m_x = player_name_x;
|
||||
m_player_ident_spinner->m_y = player_name_y;
|
||||
m_player_ident_spinner->m_w = player_name_w;
|
||||
m_player_ident_spinner->m_h = player_name_h;
|
||||
|
||||
// ---- KartStatsWidget
|
||||
m_kart_stats = NULL;
|
||||
|
||||
// area for the stats widget
|
||||
core::recti statsArea;
|
||||
if (!parent->m_multiplayer)
|
||||
{
|
||||
statsArea = core::recti(m_kart_stats_x,
|
||||
m_kart_stats_y,
|
||||
m_kart_stats_x + m_kart_stats_w,
|
||||
m_kart_stats_y + m_kart_stats_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
statsArea = core::recti(m_x , m_y + m_h/2,
|
||||
m_x + m_w, m_y + m_h);
|
||||
}
|
||||
|
||||
|
||||
m_kart_stats = new GUIEngine::KartStatsWidget(statsArea, player_id, kart_group,
|
||||
m_parent_screen->m_multiplayer,
|
||||
!m_parent_screen->m_multiplayer || parent->m_kart_widgets.size() == 0);
|
||||
m_kart_stats->m_properties[PROP_ID] = StringUtils::insertValues("@p%i_stats", m_player_id);
|
||||
m_children.push_back(m_kart_stats);
|
||||
|
||||
m_difficulty = new GUIEngine::SpinnerWidget();
|
||||
//TODO set difficulty to normal
|
||||
m_children.push_back(m_difficulty);
|
||||
|
||||
if (parent->m_multiplayer && associated_player)
|
||||
{
|
||||
if (associated_player->getDevice()->getType() == DT_KEYBOARD)
|
||||
{
|
||||
m_player_ident_spinner->setBadge(KEYBOARD_BADGE);
|
||||
}
|
||||
else if (associated_player->getDevice()->getType() == DT_GAMEPAD)
|
||||
{
|
||||
m_player_ident_spinner->setBadge(GAMEPAD_BADGE);
|
||||
}
|
||||
}
|
||||
else if (m_associated_user) // online user, FIXME is that useful ?
|
||||
{
|
||||
m_player_ident_spinner->setBadge(OK_BADGE);
|
||||
}
|
||||
|
||||
if (irrlicht_widget_id == -1)
|
||||
{
|
||||
m_player_ident_spinner->m_tab_down_root = g_root_id;
|
||||
}
|
||||
|
||||
spinnerID = StringUtils::insertValues("@p%i_spinner", m_player_id);
|
||||
|
||||
m_player_ident_spinner->m_properties[PROP_ID] = spinnerID;
|
||||
if (parent->m_multiplayer)
|
||||
{
|
||||
const int player_amount = PlayerManager::get()->getNumPlayers();
|
||||
m_player_ident_spinner->m_properties[PROP_MIN_VALUE] = "0";
|
||||
m_player_ident_spinner->m_properties[PROP_MAX_VALUE] =
|
||||
StringUtils::toString(player_amount-1);
|
||||
m_player_ident_spinner->m_properties[PROP_WRAP_AROUND] = "true";
|
||||
m_difficulty->m_properties[PROP_MIN_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_EASIEST);
|
||||
m_difficulty->m_properties[PROP_MAX_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_HARDEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_player_ident_spinner->m_properties[PROP_MIN_VALUE] = "0";
|
||||
m_player_ident_spinner->m_properties[PROP_MAX_VALUE] = "0";
|
||||
m_difficulty->m_properties[PROP_MIN_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_NORMAL);
|
||||
m_difficulty->m_properties[PROP_MAX_VALUE] = StringUtils::toString(PLAYER_DIFFICULTY_NORMAL);
|
||||
}
|
||||
|
||||
//m_player_ident_spinner->m_event_handler = this;
|
||||
m_children.push_back(m_player_ident_spinner);
|
||||
|
||||
// ----- Kart model view
|
||||
m_model_view = new ModelViewWidget();
|
||||
|
||||
m_model_view->m_x = model_x;
|
||||
m_model_view->m_y = model_y;
|
||||
m_model_view->m_w = model_w;
|
||||
m_model_view->m_h = model_h;
|
||||
m_model_view->m_properties[PROP_ID] =
|
||||
StringUtils::insertValues("@p%i_model", m_player_id);
|
||||
//m_model_view->setParent(this);
|
||||
m_children.push_back(m_model_view);
|
||||
|
||||
// Init kart model
|
||||
const std::string default_kart = UserConfigParams::m_default_kart;
|
||||
const KartProperties* props =
|
||||
kart_properties_manager->getKart(default_kart);
|
||||
|
||||
if(!props)
|
||||
{
|
||||
// If the default kart can't be found (e.g. previously a addon
|
||||
// kart was used, but the addon package was removed), use the
|
||||
// first kart as a default. This way we don't have to hardcode
|
||||
// any kart names.
|
||||
int id = kart_properties_manager->getKartByGroup(kart_group, 0);
|
||||
if (id == -1)
|
||||
{
|
||||
props = kart_properties_manager->getKartById(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
props = kart_properties_manager->getKartById(id);
|
||||
}
|
||||
|
||||
if(!props)
|
||||
Log::fatal("KartSelectionScreen", "Can't find default "
|
||||
"kart '%s' nor any other kart.",
|
||||
default_kart.c_str());
|
||||
}
|
||||
m_kartInternalName = props->getIdent();
|
||||
|
||||
const KartModel &kart_model = props->getMasterKartModel();
|
||||
|
||||
float scale = 35.0f;
|
||||
if (kart_model.getLength() > 1.45f)
|
||||
{
|
||||
// if kart is too long, size it down a bit so that it fits
|
||||
scale = 30.0f;
|
||||
}
|
||||
|
||||
m_model_view->addModel( kart_model.getModel(), Vec3(0,0,0),
|
||||
Vec3(scale, scale, scale),
|
||||
kart_model.getBaseFrame() );
|
||||
m_model_view->addModel( kart_model.getWheelModel(0),
|
||||
kart_model.getWheelGraphicsPosition(0) );
|
||||
m_model_view->addModel( kart_model.getWheelModel(1),
|
||||
kart_model.getWheelGraphicsPosition(1) );
|
||||
m_model_view->addModel( kart_model.getWheelModel(2),
|
||||
kart_model.getWheelGraphicsPosition(2) );
|
||||
m_model_view->addModel( kart_model.getWheelModel(3),
|
||||
kart_model.getWheelGraphicsPosition(3) );
|
||||
for(size_t i=0 ; i < kart_model.getSpeedWeightedObjectsCount() ; i++)
|
||||
{
|
||||
const SpeedWeightedObject& obj = kart_model.getSpeedWeightedObject(i);
|
||||
m_model_view->addModel(obj.m_model, obj.m_position);
|
||||
}
|
||||
m_model_view->setRotateContinuously( 35.0f );
|
||||
|
||||
// ---- Kart name label
|
||||
m_kart_name = new LabelWidget(true, true);
|
||||
m_kart_name->setText(props->getName(), false);
|
||||
m_kart_name->m_properties[PROP_TEXT_ALIGN] = "center";
|
||||
m_kart_name->m_properties[PROP_ID] =
|
||||
StringUtils::insertValues("@p%i_kartname", m_player_id);
|
||||
m_kart_name->m_x = kart_name_x;
|
||||
m_kart_name->m_y = kart_name_y;
|
||||
m_kart_name->m_w = kart_name_w;
|
||||
m_kart_name->m_h = kart_name_h;
|
||||
m_children.push_back(m_kart_name);
|
||||
} // PlayerKartWidget
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
PlayerKartWidget::~PlayerKartWidget()
|
||||
{
|
||||
if (GUIEngine::getFocusForPlayer(m_player_id) == this)
|
||||
{
|
||||
GUIEngine::focusNothingForPlayer(m_player_id);
|
||||
}
|
||||
|
||||
//if (m_player_ID_label->getIrrlichtElement() != NULL)
|
||||
// m_player_ID_label->getIrrlichtElement()->remove();
|
||||
|
||||
if (m_player_ident_spinner != NULL)
|
||||
{
|
||||
m_player_ident_spinner->setListener(NULL);
|
||||
|
||||
if (m_player_ident_spinner->getIrrlichtElement() != NULL)
|
||||
{
|
||||
m_player_ident_spinner->getIrrlichtElement()->remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_model_view->getIrrlichtElement() != NULL)
|
||||
m_model_view->getIrrlichtElement()->remove();
|
||||
|
||||
if (m_kart_name->getIrrlichtElement() != NULL)
|
||||
m_kart_name->getIrrlichtElement()->remove();
|
||||
getCurrentScreen()->manualRemoveWidget(this);
|
||||
|
||||
#ifdef DEBUG
|
||||
m_magic_number = 0xDEADBEEF;
|
||||
#endif
|
||||
} // ~PlayerKartWidget
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when players are renumbered (changes the player ID) */
|
||||
void PlayerKartWidget::setPlayerID(const int newPlayerID)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
|
||||
if (StateManager::get()->getActivePlayer(newPlayerID)
|
||||
!= m_associated_player)
|
||||
{
|
||||
Log::error("KartSelectionScreen", "Internal "
|
||||
"inconsistency, PlayerKartWidget has IDs and "
|
||||
"pointers that do not correspond to one player");
|
||||
Log::fatal("KartSelectionScreen", " Player: %p - Index: %d - m_associated_player: %p",
|
||||
StateManager::get()->getActivePlayer(newPlayerID),
|
||||
newPlayerID, m_associated_player);
|
||||
}
|
||||
|
||||
// Remove current focus, but remember it
|
||||
Widget* focus = GUIEngine::getFocusForPlayer(m_player_id);
|
||||
GUIEngine::focusNothingForPlayer(m_player_id);
|
||||
|
||||
// Change the player ID
|
||||
m_player_id = newPlayerID;
|
||||
m_player_ident_spinner->setID(m_player_id);
|
||||
m_kart_stats->setDisplayText(m_player_id == 0);
|
||||
// restore previous focus, but with new player ID
|
||||
if (focus != NULL) focus->setFocusForPlayer(m_player_id);
|
||||
|
||||
if (m_player_ident_spinner != NULL)
|
||||
{
|
||||
m_player_ident_spinner->setID(m_player_id);
|
||||
}
|
||||
} // setPlayerID
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ID of this player */
|
||||
int PlayerKartWidget::getPlayerID() const
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_player_id;
|
||||
} // getPlayerID
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add the widgets to the current screen */
|
||||
void PlayerKartWidget::add()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
|
||||
assert(KartSelectionScreen::getRunningInstance()
|
||||
->m_kart_widgets.contains(this));
|
||||
if (m_associated_player) // if player is local
|
||||
{
|
||||
bool mineInList = false;
|
||||
for (unsigned int p=0; p<StateManager::get()->activePlayerCount(); p++)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
assert(StateManager::get()->getActivePlayer(p)->ok());
|
||||
#endif
|
||||
if (StateManager::get()->getActivePlayer(p) == m_associated_player)
|
||||
{
|
||||
mineInList = true;
|
||||
}
|
||||
}
|
||||
assert(mineInList);
|
||||
}
|
||||
|
||||
//m_player_ID_label->add();
|
||||
|
||||
// the first player will have an ID of its own to allow for keyboard
|
||||
// navigation despite this widget being added last
|
||||
if (m_irrlicht_widget_id != -1)
|
||||
m_player_ident_spinner->m_reserved_id = m_irrlicht_widget_id;
|
||||
else
|
||||
m_player_ident_spinner->m_reserved_id = Widget::getNewNoFocusID();
|
||||
|
||||
m_player_ident_spinner->add();
|
||||
m_player_ident_spinner->getIrrlichtElement()->setTabStop(false);
|
||||
m_player_ident_spinner->setListener(this);
|
||||
m_difficulty->add();
|
||||
m_kart_stats->add();
|
||||
m_model_view->add();
|
||||
m_kart_name->add();
|
||||
|
||||
m_model_view->update(0);
|
||||
|
||||
m_player_ident_spinner->clearLabels();
|
||||
m_difficulty->clearLabels();
|
||||
|
||||
irr::core::stringw name; // name of the player
|
||||
if (m_associated_player)
|
||||
name = m_associated_player->getProfile()->getName();
|
||||
if (m_associated_user)
|
||||
name = m_associated_user->getUserName();
|
||||
|
||||
if (m_parent_screen->m_multiplayer)
|
||||
{
|
||||
const int player_amount = PlayerManager::get()->getNumPlayers();
|
||||
for (int n=0; n<player_amount; n++)
|
||||
{
|
||||
core::stringw name = PlayerManager::get()->getPlayer(n)->getName();
|
||||
m_player_ident_spinner->addLabel(translations->fribidize(name));
|
||||
}
|
||||
|
||||
// select the right player profile in the spinner
|
||||
m_player_ident_spinner->setValue(name);
|
||||
m_difficulty->addLabel(_("Easiest"));
|
||||
m_difficulty->addLabel(_("Easy"));
|
||||
m_difficulty->addLabel(_("Normal"));
|
||||
m_difficulty->addLabel(_("Hard"));
|
||||
m_difficulty->addLabel(_("Hardest"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_player_ident_spinner->addLabel(name);
|
||||
m_player_ident_spinner->setVisible(false);
|
||||
m_difficulty->addLabel(_("Normal"));
|
||||
m_difficulty->setVisible(false);
|
||||
}
|
||||
|
||||
assert(m_player_ident_spinner->getStringValue() == name);
|
||||
} // add
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the associated ActivePlayer object*/
|
||||
StateManager::ActivePlayer* PlayerKartWidget::getAssociatedPlayer()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_associated_player;
|
||||
} // getAssociatedPlayer
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Starts a 'move/resize' animation, by simply passing destination coords.
|
||||
* The animation will then occur on each call to 'onUpdate'. */
|
||||
void PlayerKartWidget::move(const int x, const int y, const int w, const int h)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
target_x = x;
|
||||
target_y = y;
|
||||
target_w = w;
|
||||
target_h = h;
|
||||
|
||||
x_speed = abs( m_x - x ) / 300.0f;
|
||||
y_speed = abs( m_y - y ) / 300.0f;
|
||||
w_speed = abs( m_w - w ) / 300.0f;
|
||||
h_speed = abs( m_h - h ) / 300.0f;
|
||||
} // move
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Call when player confirmed his identity and kart */
|
||||
void PlayerKartWidget::markAsReady()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
if (m_ready) return; // already ready
|
||||
|
||||
m_ready = true;
|
||||
|
||||
stringw playerNameString = m_player_ident_spinner->getStringValue();
|
||||
core::rect<s32> rect(core::position2di(m_player_ident_spinner->m_x,
|
||||
m_player_ident_spinner->m_y),
|
||||
core::dimension2di(m_player_ident_spinner->m_w,
|
||||
m_player_ident_spinner->m_h));
|
||||
// 'playerNameString' is already fribidize, so we need to use
|
||||
// 'insertValues' and not _("...", a) so it's not flipped again
|
||||
m_ready_text =
|
||||
GUIEngine::getGUIEnv()->addStaticText(
|
||||
StringUtils::insertValues(_("%s is ready"),
|
||||
playerNameString).c_str(),
|
||||
rect );
|
||||
m_ready_text->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER );
|
||||
|
||||
m_children.remove(m_player_ident_spinner);
|
||||
m_player_ident_spinner->setListener(NULL);
|
||||
m_player_ident_spinner->getIrrlichtElement()->remove();
|
||||
m_player_ident_spinner->elementRemoved();
|
||||
delete m_player_ident_spinner;
|
||||
m_player_ident_spinner = NULL;
|
||||
|
||||
sfx_manager->quickSound( "wee" );
|
||||
|
||||
m_model_view->setRotateTo(30.0f, 1.0f);
|
||||
|
||||
player_id_w *= 2;
|
||||
player_name_w = 0;
|
||||
|
||||
m_model_view->setBadge(OK_BADGE);
|
||||
} // markAsReady
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \return Whether this player confirmed his kart and indent selection */
|
||||
bool PlayerKartWidget::isReady()
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_ready;
|
||||
} // isReady
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Updates the animation (moving/shrinking/etc.) */
|
||||
void PlayerKartWidget::onUpdate(float delta)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
if (target_x == m_x && target_y == m_y &&
|
||||
target_w == m_w && target_h == m_h) return;
|
||||
|
||||
int move_step = (int)(delta*1000.0f);
|
||||
|
||||
// move x towards target
|
||||
if (m_x < target_x)
|
||||
{
|
||||
m_x += (int)(move_step*x_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_x > target_x) m_x = target_x;
|
||||
}
|
||||
else if (m_x > target_x)
|
||||
{
|
||||
m_x -= (int)(move_step*x_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_x < target_x) m_x = target_x;
|
||||
}
|
||||
|
||||
// move y towards target
|
||||
if (m_y < target_y)
|
||||
{
|
||||
m_y += (int)(move_step*y_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_y > target_y) m_y = target_y;
|
||||
}
|
||||
else if (m_y > target_y)
|
||||
{
|
||||
m_y -= (int)(move_step*y_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_y < target_y) m_y = target_y;
|
||||
}
|
||||
|
||||
// move w towards target
|
||||
if (m_w < target_w)
|
||||
{
|
||||
m_w += (int)(move_step*w_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_w > target_w) m_w = target_w;
|
||||
}
|
||||
else if (m_w > target_w)
|
||||
{
|
||||
m_w -= (int)(move_step*w_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_w < target_w) m_w = target_w;
|
||||
}
|
||||
// move h towards target
|
||||
if (m_h < target_h)
|
||||
{
|
||||
m_h += (int)(move_step*h_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_h > target_h) m_h = target_h;
|
||||
}
|
||||
else if (m_h > target_h)
|
||||
{
|
||||
m_h -= (int)(move_step*h_speed);
|
||||
// don't move to the other side of the target
|
||||
if (m_h < target_h) m_h = target_h;
|
||||
}
|
||||
|
||||
setSize(m_x, m_y, m_w, m_h);
|
||||
|
||||
if (m_player_ident_spinner != NULL)
|
||||
{
|
||||
m_player_ident_spinner->move(player_name_x,
|
||||
player_name_y,
|
||||
player_name_w,
|
||||
player_name_h );
|
||||
}
|
||||
if (m_ready_text != NULL)
|
||||
{
|
||||
m_ready_text->setRelativePosition(
|
||||
core::recti(core::position2di(player_name_x, player_name_y),
|
||||
core::dimension2di(player_name_w, player_name_h)) );
|
||||
}
|
||||
if (!m_parent_screen->m_multiplayer)
|
||||
{
|
||||
m_kart_stats->move(m_kart_stats_x,
|
||||
m_kart_stats_y,
|
||||
m_kart_stats_w,
|
||||
m_kart_stats_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_kart_stats->move(m_x, m_y + m_h/2,
|
||||
m_w, m_h/2);
|
||||
m_difficulty->move(m_difficulty_x, m_difficulty_y,
|
||||
m_difficulty_w, m_difficulty_h);
|
||||
}
|
||||
|
||||
|
||||
m_model_view->move(model_x,
|
||||
model_y,
|
||||
model_w,
|
||||
model_h);
|
||||
|
||||
m_kart_name->move(kart_name_x,
|
||||
kart_name_y,
|
||||
kart_name_w,
|
||||
kart_name_h);
|
||||
|
||||
// When coming from the overworld, we must rebuild the preview scene at
|
||||
// least once, since the scene is being cleared by leaving the overworld
|
||||
if (m_not_updated_yet)
|
||||
{
|
||||
m_model_view->clearRttProvider();
|
||||
m_not_updated_yet = false;
|
||||
}
|
||||
} // onUpdate
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Event callback */
|
||||
GUIEngine::EventPropagation PlayerKartWidget::transmitEvent(Widget* w,
|
||||
const std::string& originator,
|
||||
const int m_player_id )
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
// if it's declared ready, there is really nothing to process
|
||||
if (m_ready) return EVENT_LET;
|
||||
|
||||
//std::cout << "= kart selection :: transmitEvent "
|
||||
// << originator << " =\n";
|
||||
|
||||
std::string name = w->m_properties[PROP_ID];
|
||||
|
||||
//std::cout << " (checking if that's me: I am "
|
||||
// << spinnerID << ")\n";
|
||||
|
||||
// update player profile when spinner changed
|
||||
if (originator == spinnerID)
|
||||
{
|
||||
if(UserConfigParams::logGUI())
|
||||
{
|
||||
Log::info("[KartSelectionScreen]", "Identity changed "
|
||||
"for player %s : %s",m_player_id,
|
||||
irr::core::stringc(
|
||||
m_player_ident_spinner->getStringValue()
|
||||
.c_str()).c_str());
|
||||
}
|
||||
|
||||
if (m_parent_screen->m_multiplayer)
|
||||
{
|
||||
m_associated_player->setPlayerProfile(
|
||||
PlayerManager::get()->getPlayer(m_player_ident_spinner
|
||||
->getValue()) );
|
||||
}
|
||||
}
|
||||
|
||||
return EVENT_LET; // continue propagating the event
|
||||
} // transmitEvent
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Sets the size of the widget as a whole, and placed children widgets
|
||||
* inside itself */
|
||||
void PlayerKartWidget::setSize(const int x, const int y, const int w, const int h)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_w = w;
|
||||
m_h = h;
|
||||
|
||||
// -- sizes
|
||||
player_id_w = w;
|
||||
player_id_h = GUIEngine::getFontHeight();
|
||||
|
||||
m_difficulty_h = GUIEngine::getFontHeight();
|
||||
|
||||
player_name_h = 40;
|
||||
player_name_w = std::min(400, w);
|
||||
|
||||
kart_name_w = w;
|
||||
kart_name_h = 25;
|
||||
|
||||
// for shrinking effect
|
||||
if (h < 175)
|
||||
{
|
||||
const float factor = h / 175.0f;
|
||||
kart_name_h = (int)(kart_name_h*factor);
|
||||
player_name_h = (int)(player_name_h*factor);
|
||||
player_id_h = (int)(player_id_h*factor);
|
||||
}
|
||||
|
||||
// --- layout
|
||||
player_id_x = x;
|
||||
player_id_y = y;
|
||||
|
||||
player_name_x = x + w/2 - player_name_w/2;
|
||||
player_name_y = y + player_id_h;
|
||||
|
||||
if (m_parent_screen->m_multiplayer)
|
||||
{
|
||||
const int modelMaxHeight = (h - kart_name_h - player_name_h
|
||||
- player_id_h - m_difficulty_h)/2;
|
||||
const int modelMaxWidth = w;
|
||||
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
|
||||
model_x = x + w/2 - (int)(bestSize/2);
|
||||
model_y = y + player_name_h + player_id_h;
|
||||
model_w = bestSize;
|
||||
model_h = bestSize;
|
||||
|
||||
m_kart_stats_w = model_w;
|
||||
m_kart_stats_h = model_h;
|
||||
m_kart_stats_x = x + w/2 - (int)(bestSize/2);
|
||||
m_kart_stats_y = model_y + model_h + m_difficulty_h;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int modelMaxHeight = h - kart_name_h - player_name_h
|
||||
- player_id_h - m_difficulty_h;
|
||||
const int modelMaxWidth = w;
|
||||
const int bestSize = std::min(modelMaxWidth, modelMaxHeight);
|
||||
const int modelY = y + player_name_h + player_id_h;
|
||||
model_x = x + w/4 - (int)(bestSize/2);
|
||||
model_y = modelY + modelMaxHeight/2 - bestSize/2;
|
||||
model_w = (int)(bestSize);
|
||||
model_h = bestSize;
|
||||
|
||||
m_kart_stats_w = w/2;
|
||||
m_kart_stats_h = h;
|
||||
m_kart_stats_x = x + w/2;
|
||||
m_kart_stats_y = y;
|
||||
}
|
||||
|
||||
kart_name_x = x;
|
||||
kart_name_y = y + h - kart_name_h;
|
||||
|
||||
m_difficulty_w = w * 2 / 3;
|
||||
m_difficulty_x = x + (w - m_difficulty_w) / 2;
|
||||
m_difficulty_y = model_y + model_h;
|
||||
} // setSize
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** Sets which kart was selected for this player */
|
||||
void PlayerKartWidget::setKartInternalName(const std::string& whichKart)
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
m_kartInternalName = whichKart;
|
||||
} // setKartInternalName
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
const std::string& PlayerKartWidget::getKartInternalName() const
|
||||
{
|
||||
assert(m_magic_number == 0x33445566);
|
||||
return m_kartInternalName;
|
||||
} // getKartInternalName
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** \brief Event callback from ISpinnerConfirmListener */
|
||||
EventPropagation PlayerKartWidget::onSpinnerConfirmed()
|
||||
{
|
||||
KartSelectionScreen::getRunningInstance()->playerConfirm(m_player_id);
|
||||
return EVENT_BLOCK;
|
||||
} // onSpinnerConfirmed
|
||||
|
||||
/** 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
|
||||
@ -941,6 +205,17 @@ void KartHoverListener::onSelectionChanged(DynamicRibbonWidget* theWidget,
|
||||
|
||||
// ============================================================================
|
||||
|
||||
/** 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;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
KartSelectionScreen::KartSelectionScreen(const char* filename) : Screen(filename)
|
||||
{
|
||||
m_removed_widget = NULL;
|
||||
@ -1836,7 +1111,7 @@ void KartSelectionScreen::allPlayersDone()
|
||||
for (unsigned int n=0; n<players.size(); n++)
|
||||
{
|
||||
StateManager::get()->getActivePlayer(n)->getProfile()
|
||||
->incrementUseFrequency();
|
||||
->incrementUseFrequency();
|
||||
}
|
||||
// ---- Give player info to race manager
|
||||
race_manager->setNumLocalPlayers( players.size() );
|
||||
@ -1913,7 +1188,7 @@ void KartSelectionScreen::allPlayersDone()
|
||||
if (!m_multiplayer)
|
||||
{
|
||||
input_manager->getDeviceList()
|
||||
->setSinglePlayer( StateManager::get()->getActivePlayer(0) );
|
||||
->setSinglePlayer( StateManager::get()->getActivePlayer(0) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2186,46 +1461,3 @@ void KartSelectionScreen::setKartsFromCurrentGroup()
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
// FIXME : clean this mess, this file should not contain so many classes
|
||||
// spread all over the place
|
||||
|
||||
EventPropagation FocusDispatcher::focused(const int playerID)
|
||||
{
|
||||
if (!m_is_initialised) return EVENT_LET;
|
||||
|
||||
if(UserConfigParams::logGUI())
|
||||
Log::info("[KartSelectionScreen]", "FocusDispatcher focused by player %u",
|
||||
playerID);
|
||||
|
||||
// since this screen is multiplayer, redirect focus to the right widget
|
||||
const int amount = m_parent->m_kart_widgets.size();
|
||||
for (int n=0; n<amount; n++)
|
||||
{
|
||||
if (m_parent->m_kart_widgets[n].getPlayerID() == playerID)
|
||||
{
|
||||
// If player is done, don't do anything with focus
|
||||
if (m_parent->m_kart_widgets[n].isReady())
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
|
||||
//std::cout << "--> Redirecting focus for player " << playerID
|
||||
// << " from FocusDispatcher " <<
|
||||
// " (ID " << m_element->getID() <<
|
||||
// ") to spinner " << n << " (ID " <<
|
||||
// m_parent->m_kart_widgets[n].m_player_ident_spinner
|
||||
// ->getIrrlichtElement()->getID() <<
|
||||
// ")" << std::endl;
|
||||
|
||||
m_parent->m_kart_widgets[n].m_player_ident_spinner
|
||||
->setFocusForPlayer(playerID);
|
||||
|
||||
|
||||
return GUIEngine::EVENT_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
//std::cerr << "[KartSelectionScreen] WARNING: the focus dispatcher can't
|
||||
// find the widget for player " << playerID << "!\n";
|
||||
//assert(false);
|
||||
return GUIEngine::EVENT_LET;
|
||||
} // focused
|
||||
|
||||
|
@ -21,23 +21,14 @@
|
||||
|
||||
#include "guiengine/screen.hpp"
|
||||
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
|
||||
#include "guiengine/widgets/label_widget.hpp"
|
||||
#include "guiengine/widgets/model_view_widget.hpp"
|
||||
#include "guiengine/widgets/spinner_widget.hpp"
|
||||
#include "guiengine/widgets/progress_bar_widget.hpp"
|
||||
#include "states_screens/state_manager.hpp"
|
||||
#include "guiengine/widgets/kart_stats_widget.hpp"
|
||||
|
||||
#include <IGUIImage.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace GUIEngine
|
||||
{
|
||||
class Widget;
|
||||
class BubbleWidget;
|
||||
class PlayerKartWidget;
|
||||
enum EventPropagation;
|
||||
|
||||
}
|
||||
namespace Online
|
||||
{
|
||||
@ -46,7 +37,6 @@ namespace Online
|
||||
}
|
||||
|
||||
class InputDevice;
|
||||
class PlayerKartWidget;
|
||||
class KartHoverListener;
|
||||
|
||||
/**
|
||||
@ -63,10 +53,10 @@ protected:
|
||||
* we're adding them to a Screen, and the Screen will take ownership
|
||||
* of these widgets)
|
||||
*/
|
||||
PtrVector<PlayerKartWidget, REF> m_kart_widgets;
|
||||
PtrVector<GUIEngine::PlayerKartWidget, REF> m_kart_widgets;
|
||||
|
||||
friend class GUIEngine::ScreenSingleton<KartSelectionScreen>;
|
||||
friend class PlayerKartWidget;
|
||||
friend class GUIEngine::PlayerKartWidget;
|
||||
|
||||
bool m_multiplayer;
|
||||
|
||||
@ -82,7 +72,7 @@ protected:
|
||||
*/
|
||||
bool m_game_master_confirmed;
|
||||
|
||||
PlayerKartWidget* m_removed_widget;
|
||||
GUIEngine::PlayerKartWidget* m_removed_widget;
|
||||
|
||||
/** Message shown in multiplayer mode */
|
||||
GUIEngine::BubbleWidget* m_multiplayer_message;
|
||||
@ -204,165 +194,9 @@ public:
|
||||
virtual GUIEngine::EventPropagation focused(const int playerID);
|
||||
}; // FocusDispatcher
|
||||
|
||||
//!----------------------------------------------------------------------------
|
||||
//! PlayerNameSpinner :
|
||||
/** A small extension to the spinner widget to add features like player ID
|
||||
* management or badging */
|
||||
class PlayerNameSpinner : public GUIEngine::SpinnerWidget
|
||||
{
|
||||
int m_player_id;
|
||||
bool m_incorrect;
|
||||
irr::gui::IGUIImage* m_red_mark_widget;
|
||||
KartSelectionScreen* m_parent;
|
||||
//virtual EventPropagation focused(const int m_playerID) ;
|
||||
|
||||
public:
|
||||
PlayerNameSpinner(KartSelectionScreen* parent, const int playerID);
|
||||
// ------------------------------------------------------------------------
|
||||
void setID(const int m_playerID);
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add a red mark on the spinner to mean "invalid choice" */
|
||||
void markAsIncorrect();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Remove any red mark set with 'markAsIncorrect' */
|
||||
void markAsCorrect();
|
||||
};
|
||||
|
||||
/** A widget representing the kart selection for a player (i.e. the player's
|
||||
* number, name, the kart view, the kart's name) */
|
||||
class PlayerKartWidget : public GUIEngine::Widget,
|
||||
public GUIEngine::SpinnerWidget::ISpinnerConfirmListener
|
||||
{
|
||||
/** Whether this player confirmed their selection */
|
||||
bool m_ready;
|
||||
|
||||
/** widget coordinates */
|
||||
int player_id_x, player_id_y, player_id_w, player_id_h;
|
||||
int player_name_x, player_name_y, player_name_w, player_name_h;
|
||||
int model_x, model_y, model_w, model_h;
|
||||
int kart_name_x, kart_name_y, kart_name_w, kart_name_h;
|
||||
int m_kart_stats_x, m_kart_stats_y, m_kart_stats_w, m_kart_stats_h;
|
||||
int m_difficulty_x, m_difficulty_y, m_difficulty_w, m_difficulty_h;
|
||||
|
||||
/** A reserved ID for this widget if any, -1 otherwise. (If no ID is
|
||||
* reserved, widget will not be in the regular tabbing order */
|
||||
int m_irrlicht_widget_id;
|
||||
|
||||
/** For animation purposes (see method 'move') */
|
||||
int target_x, target_y, target_w, target_h;
|
||||
float x_speed, y_speed, w_speed, h_speed;
|
||||
|
||||
/** Object representing this player */
|
||||
/** Local info about the player. */
|
||||
StateManager::ActivePlayer* m_associated_player;
|
||||
int m_player_id;
|
||||
|
||||
/** Network info about the user. */
|
||||
Online::OnlineProfile* m_associated_user;
|
||||
|
||||
/** Internal name of the spinner; useful to interpret spinner events,
|
||||
* which contain the name of the activated object */
|
||||
std::string spinnerID;
|
||||
|
||||
#ifdef DEBUG
|
||||
long m_magic_number;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
LEAK_CHECK()
|
||||
|
||||
/** Sub-widgets created by this widget */
|
||||
PlayerNameSpinner* m_player_ident_spinner;
|
||||
GUIEngine::SpinnerWidget* m_difficulty;
|
||||
GUIEngine::KartStatsWidget* m_kart_stats;
|
||||
GUIEngine::ModelViewWidget* m_model_view;
|
||||
GUIEngine::LabelWidget* m_kart_name;
|
||||
|
||||
KartSelectionScreen* m_parent_screen;
|
||||
|
||||
irr::gui::IGUIStaticText* m_ready_text;
|
||||
|
||||
//LabelWidget *getPlayerIDLabel() {return m_player_ID_label;}
|
||||
core::stringw deviceName;
|
||||
std::string m_kartInternalName;
|
||||
|
||||
bool m_not_updated_yet;
|
||||
|
||||
PlayerKartWidget(KartSelectionScreen* parent,
|
||||
StateManager::ActivePlayer* associated_player,
|
||||
Online::OnlineProfile* associated_user,
|
||||
core::recti area, const int player_id,
|
||||
std::string kart_group,
|
||||
const int irrlicht_idget_id=-1);
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
~PlayerKartWidget();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Called when players are renumbered (changes the player ID) */
|
||||
void setPlayerID(const int newPlayerID);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the ID of this player */
|
||||
int getPlayerID() const;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Add the widgets to the current screen */
|
||||
virtual void add();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Get the associated ActivePlayer object*/
|
||||
StateManager::ActivePlayer* getAssociatedPlayer();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Starts a 'move/resize' animation, by simply passing destination coords.
|
||||
* The animation will then occur on each call to 'onUpdate'. */
|
||||
void move(const int x, const int y, const int w, const int h);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Call when player confirmed his identity and kart */
|
||||
void markAsReady();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** \return Whether this player confirmed his kart and indent selection */
|
||||
bool isReady();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Updates the animation (moving/shrinking/etc.) */
|
||||
void onUpdate(float delta);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Event callback */
|
||||
virtual GUIEngine::EventPropagation transmitEvent(
|
||||
GUIEngine::Widget* w,
|
||||
const std::string& originator,
|
||||
const int m_player_id);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
/** Sets the size of the widget as a whole, and placed children widgets
|
||||
* inside itself */
|
||||
void setSize(const int x, const int y, const int w, const int h);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** Sets which kart was selected for this player */
|
||||
void setKartInternalName(const std::string& whichKart);
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
const std::string& getKartInternalName() const;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** \brief Event callback from ISpinnerConfirmListener */
|
||||
virtual GUIEngine::EventPropagation onSpinnerConfirmed();
|
||||
}; // PlayerKartWidget
|
||||
|
||||
//!----------------------------------------------------------------------------
|
||||
//! KartHoverListener :
|
||||
|
||||
class KartHoverListener : public GUIEngine::DynamicRibbonHoverListener
|
||||
{
|
||||
KartSelectionScreen* m_parent;
|
||||
@ -382,3 +216,4 @@ public:
|
||||
}; // KartHoverListener
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "challenges/unlock_manager.hpp"
|
||||
#include "config/player_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "graphics/irr_driver.hpp"
|
||||
#include "guiengine/widgets/player_kart_widget.hpp"
|
||||
#include "items/item_manager.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user