A player can now remove himself by pressing rescue at the kart selection screen
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3733 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
0e890dc5cc
commit
ab4cdcae00
@ -73,6 +73,10 @@ public:
|
||||
m_player = player;
|
||||
m_device = NULL;
|
||||
}
|
||||
~ActivePlayer()
|
||||
{
|
||||
setDevice(NULL);
|
||||
}
|
||||
|
||||
Player* getPlayer()
|
||||
{
|
||||
@ -86,6 +90,8 @@ public:
|
||||
InputDevice* getDevice() const { return m_device; }
|
||||
void setDevice(InputDevice* device)
|
||||
{
|
||||
if (m_device != NULL) m_device->setPlayer(NULL);
|
||||
|
||||
m_device = device;
|
||||
|
||||
if(device != NULL)
|
||||
|
@ -45,11 +45,14 @@ namespace StateManager
|
||||
class PlayerKartWidget;
|
||||
|
||||
// ref only since we're adding them to a Screen, and the Screen will take ownership of these widgets
|
||||
// FIXME : delete these objects when leaving the screen (especially when suing escape)
|
||||
ptr_vector<PlayerKartWidget, REF> g_player_karts;
|
||||
|
||||
class PlayerKartWidget : public Widget
|
||||
{
|
||||
ActivePlayer* m_associatedPlayer;
|
||||
float x_speed, y_speed, w_speed, h_speed;
|
||||
|
||||
public:
|
||||
LabelWidget* playerIDLabel;
|
||||
SpinnerWidget* playerName;
|
||||
@ -69,7 +72,11 @@ namespace StateManager
|
||||
PlayerKartWidget(ActivePlayer* associatedPlayer, Widget* area, const int playerID) : Widget()
|
||||
{
|
||||
m_associatedPlayer = associatedPlayer;
|
||||
|
||||
x_speed = 1.0f;
|
||||
y_speed = 1.0f;
|
||||
w_speed = 1.0f;
|
||||
h_speed = 1.0f;
|
||||
|
||||
this->playerID = playerID;
|
||||
|
||||
// FIXME : if a player removes itself, all IDs need to be updated
|
||||
@ -140,6 +147,32 @@ namespace StateManager
|
||||
//kartName->setParent(this);
|
||||
m_children.push_back(kartName);
|
||||
}
|
||||
|
||||
~PlayerKartWidget()
|
||||
{
|
||||
if (playerIDLabel->getIrrlichtElement() != NULL)
|
||||
playerIDLabel->getIrrlichtElement()->remove();
|
||||
|
||||
if (playerName->getIrrlichtElement() != NULL)
|
||||
playerName->getIrrlichtElement()->remove();
|
||||
|
||||
if (modelView->getIrrlichtElement() != NULL)
|
||||
modelView->getIrrlichtElement()->remove();
|
||||
|
||||
if (kartName->getIrrlichtElement() != NULL)
|
||||
kartName->getIrrlichtElement()->remove();
|
||||
}
|
||||
|
||||
void setPlayerID(const int newPlayerID)
|
||||
{
|
||||
if (StateManager::getActivePlayers().get(newPlayerID) != m_associatedPlayer)
|
||||
{
|
||||
std::cerr << "Internal inconsistency, PlayerKartWidget has IDs and pointers that do not correspond to one player\n";
|
||||
assert(false);
|
||||
}
|
||||
playerID = newPlayerID;
|
||||
}
|
||||
|
||||
virtual void add()
|
||||
{
|
||||
playerIDLabel->add();
|
||||
@ -157,12 +190,18 @@ namespace StateManager
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void move(const int x, const int y, const int w, const int h)
|
||||
{
|
||||
target_x = x;
|
||||
target_y = y;
|
||||
target_w = w;
|
||||
target_h = h;
|
||||
|
||||
x_speed = abs( this->x - x ) / 300.0f;
|
||||
y_speed = abs( this->y - y ) / 300.0f;
|
||||
w_speed = abs( this->w - w ) / 300.0f;
|
||||
h_speed = abs( this->h - h ) / 300.0f;
|
||||
}
|
||||
|
||||
void onUpdate(float delta)
|
||||
@ -174,47 +213,47 @@ namespace StateManager
|
||||
// move x towards target
|
||||
if (x < target_x)
|
||||
{
|
||||
x += move_step;
|
||||
x += move_step*x_speed;
|
||||
if (x > target_x) x = target_x; // don't move to the other side of the target
|
||||
}
|
||||
else if (x > target_x)
|
||||
{
|
||||
x -= move_step;
|
||||
x -= move_step*x_speed;
|
||||
if (x < target_x) x = target_x; // don't move to the other side of the target
|
||||
}
|
||||
|
||||
// move y towards target
|
||||
if (y < target_y)
|
||||
{
|
||||
y += move_step;
|
||||
y += move_step*y_speed;
|
||||
if (y > target_y) y = target_y; // don't move to the other side of the target
|
||||
}
|
||||
else if (y > target_y)
|
||||
{
|
||||
y -= move_step;
|
||||
y -= move_step*y_speed;
|
||||
if (y < target_y) y = target_y; // don't move to the other side of the target
|
||||
}
|
||||
|
||||
// move w towards target
|
||||
if (w < target_w)
|
||||
{
|
||||
w += move_step;
|
||||
w += move_step*w_speed;
|
||||
if (w > target_w) w = target_w; // don't move to the other side of the target
|
||||
}
|
||||
else if (w > target_w)
|
||||
{
|
||||
w -= move_step;
|
||||
w -= move_step*w_speed;
|
||||
if (w < target_w) w = target_w; // don't move to the other side of the target
|
||||
}
|
||||
// move h towards target
|
||||
if (h < target_h)
|
||||
{
|
||||
h += move_step;
|
||||
h += move_step*h_speed;
|
||||
if (h > target_h) h = target_h; // don't move to the other side of the target
|
||||
}
|
||||
else if (h > target_h)
|
||||
{
|
||||
h -= move_step;
|
||||
h -= move_step*h_speed;
|
||||
if (h < target_h) h = target_h; // don't move to the other side of the target
|
||||
}
|
||||
|
||||
@ -298,6 +337,15 @@ namespace StateManager
|
||||
kart_name_y = y + h - 25;;
|
||||
kart_name_w = w;
|
||||
kart_name_h = 25;
|
||||
|
||||
// for shrinking effect
|
||||
if (h < 150)
|
||||
{
|
||||
const float factor = h / 150.0f;
|
||||
kart_name_h *= factor;
|
||||
player_name_h *= factor;
|
||||
player_id_h *= factor;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -364,6 +412,7 @@ void firePressedOnNewDevice(InputDevice* device)
|
||||
newPlayer->add();
|
||||
|
||||
StateManager::addActivePlayer(aplayer);
|
||||
aplayer->setDevice(device);
|
||||
|
||||
const int amount = g_player_karts.size();
|
||||
|
||||
@ -408,6 +457,30 @@ void setPlayer0Device(InputDevice* device)
|
||||
// input_manager->getDeviceList()->setNoAssignMode(true);
|
||||
}
|
||||
|
||||
PlayerKartWidget* removedWidget = NULL;
|
||||
|
||||
void playerPressedRescue(int playerID)
|
||||
{
|
||||
std::cout << "Player " << playerID << " no more wishes to play!\n";
|
||||
|
||||
removedWidget = g_player_karts.remove(playerID);
|
||||
StateManager::removeActivePlayer(playerID);
|
||||
|
||||
const int amount = g_player_karts.size();
|
||||
|
||||
Widget* fullarea = getCurrentScreen()->getWidget("playerskarts");
|
||||
const int splitWidth = fullarea->w / amount;
|
||||
|
||||
assert( amount == StateManager::activePlayerCount() );
|
||||
|
||||
for (int n=0; n<amount; n++)
|
||||
{
|
||||
g_player_karts[n].setPlayerID(n);
|
||||
g_player_karts[n].move( fullarea->x + splitWidth*n, fullarea->y, splitWidth, fullarea->h );
|
||||
}
|
||||
removedWidget->move( removedWidget->x + removedWidget->w/2, fullarea->y + fullarea->h,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
void kartSelectionUpdate(float delta)
|
||||
{
|
||||
@ -416,6 +489,19 @@ void kartSelectionUpdate(float delta)
|
||||
{
|
||||
g_player_karts[n].onUpdate(delta);
|
||||
}
|
||||
|
||||
if (removedWidget != NULL)
|
||||
{
|
||||
removedWidget->onUpdate(delta);
|
||||
|
||||
if (removedWidget->w == 0 || removedWidget->h == 0)
|
||||
{
|
||||
// destruct when too small (for "disappear" effects)
|
||||
GUIEngine::getCurrentScreen()->manualRemoveWidget(removedWidget);
|
||||
delete removedWidget;
|
||||
removedWidget = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,6 +29,8 @@ namespace StateManager
|
||||
{
|
||||
void setPlayer0Device(InputDevice* device);
|
||||
void firePressedOnNewDevice(InputDevice* device);
|
||||
void playerPressedRescue(int playerID);
|
||||
|
||||
void kartSelectionUpdate(float delta);
|
||||
|
||||
void menuEventKarts(GUIEngine::Widget* widget, std::string& name);
|
||||
|
@ -308,6 +308,11 @@ void Screen::manualAddWidget(Widget* w)
|
||||
m_widgets.push_back(w);
|
||||
}
|
||||
|
||||
void Screen::manualRemoveWidget(Widget* w)
|
||||
{
|
||||
m_widgets.remove(w);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#pragma mark Getting widgets
|
||||
|
@ -84,7 +84,8 @@ namespace GUIEngine
|
||||
void calculateLayout();
|
||||
|
||||
void manualAddWidget(Widget* w);
|
||||
|
||||
void manualRemoveWidget(Widget* w);
|
||||
|
||||
const std::string& getName() const { return m_filename; }
|
||||
|
||||
void elementsWereDeleted(ptr_vector<Widget>* within_vector = NULL);
|
||||
|
@ -64,6 +64,14 @@ namespace StateManager
|
||||
{
|
||||
g_active_players.push_back(p);
|
||||
}
|
||||
void removeActivePlayer(int id)
|
||||
{
|
||||
g_active_players.erase(id);
|
||||
}
|
||||
int activePlayerCount()
|
||||
{
|
||||
return g_active_players.size();
|
||||
}
|
||||
|
||||
void resetActivePlayers()
|
||||
{
|
||||
|
@ -44,7 +44,9 @@ namespace StateManager
|
||||
* so no need to delete it yourself.
|
||||
*/
|
||||
void addActivePlayer(ActivePlayer* p);
|
||||
|
||||
void removeActivePlayer(int id);
|
||||
|
||||
int activePlayerCount();
|
||||
void resetActivePlayers();
|
||||
|
||||
void escapePressed();
|
||||
|
@ -131,7 +131,7 @@ bool DeviceManager::mapInputToPlayerAndAction( Input::InputType type, int device
|
||||
if( m_keyboards[n].hasBinding(btnID, action) )
|
||||
{
|
||||
// We found which device was triggered.
|
||||
|
||||
|
||||
if(m_assign_mode == NO_ASSIGN)
|
||||
{
|
||||
// In no-assign mode, simply keep track of which device is used
|
||||
@ -143,7 +143,7 @@ bool DeviceManager::mapInputToPlayerAndAction( Input::InputType type, int device
|
||||
{
|
||||
// In assign mode, find to which active player this binding belongs
|
||||
// FIXME : in order to speed this use, a Player* pointer could be
|
||||
// stored inside the device so we don't need to iterate through devices
|
||||
// stored inside the device so we don't need to iterate through players
|
||||
const ptr_vector<ActivePlayer, HOLD>& players = StateManager::getActivePlayers();
|
||||
const int playerAmount = players.size();
|
||||
for(int n=0; n<playerAmount; n++)
|
||||
@ -152,6 +152,14 @@ bool DeviceManager::mapInputToPlayerAndAction( Input::InputType type, int device
|
||||
{
|
||||
// we found which active player has this binding
|
||||
*player = n;
|
||||
|
||||
if (m_assign_mode == DETECT_NEW && *action == PA_RESCUE)
|
||||
{
|
||||
if (value > Input::MAX_VALUE/2) StateManager::playerPressedRescue( *player );
|
||||
*action = PA_FIRST; // FIXME : returning PA_FIRST is quite a hackish way to tell input was handled internally
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -163,9 +171,13 @@ bool DeviceManager::mapInputToPlayerAndAction( Input::InputType type, int device
|
||||
for(unsigned int n=0; n<m_keyboard_amount; n++)
|
||||
{
|
||||
PlayerAction localaction = PA_FIRST; // none
|
||||
if (m_keyboards[n].hasBinding(btnID, &localaction) && localaction == PA_FIRE)
|
||||
if (m_keyboards[n].hasBinding(btnID, &localaction))
|
||||
{
|
||||
if (value > Input::MAX_VALUE/2) StateManager::firePressedOnNewDevice( m_keyboards.get(n) );
|
||||
if(localaction == PA_FIRE)
|
||||
{
|
||||
if (value > Input::MAX_VALUE/2) StateManager::firePressedOnNewDevice( m_keyboards.get(n) );
|
||||
}
|
||||
|
||||
*action = PA_FIRST; // FIXME : returning PA_FIRST is quite a hackish way to tell input was handled internally
|
||||
return true;
|
||||
}
|
||||
@ -237,6 +249,12 @@ bool DeviceManager::mapInputToPlayerAndAction( Input::InputType type, int device
|
||||
|
||||
if(gamepad->hasBinding(type, btnID /* axis or button */, value, *player, action /* out */) )
|
||||
{
|
||||
if (m_assign_mode == DETECT_NEW && *action == PA_RESCUE)
|
||||
{
|
||||
if (value > Input::MAX_VALUE/2) StateManager::playerPressedRescue( *player );
|
||||
*action = PA_FIRST; // FIXME : returning PA_FIRST is quite a hackish way to tell input was handled internally
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ void InputDevice::setPlayer(ActivePlayer* owner)
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::cerr << "\n\nError, trying to assign that doesn't exist to a device!!!\n\n";
|
||||
std::cerr << "\n\nError, trying to assign a player that doesn't exist to a device!!!\n\n";
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
void InputDevice::serialize(std::ofstream& stream)
|
||||
|
@ -105,12 +105,14 @@ void erase(const int ID)
|
||||
contentsVector.erase(contentsVector.begin()+ID);
|
||||
}
|
||||
|
||||
void remove(const int ID)
|
||||
TYPE* remove(const int ID)
|
||||
{
|
||||
assert(ID > -1);
|
||||
assert((unsigned int)ID < contentsVector.size());
|
||||
|
||||
TYPE* out = contentsVector[ID];
|
||||
contentsVector.erase(contentsVector.begin()+ID);
|
||||
return out;
|
||||
}
|
||||
|
||||
bool contains( TYPE* instance ) const
|
||||
|
Loading…
x
Reference in New Issue
Block a user