WIP soccer mode GUI setup screen, don't draw player icons when in soccer mode, painted soccer cages in blue and red

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/christmas@12346 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
funto66 2013-01-09 21:32:43 +00:00
parent 4c160eb065
commit 45790c0db4
8 changed files with 297 additions and 171 deletions

View File

@ -6,7 +6,7 @@
<header width="80%" text="Race Setup" align="center" text_align="center" />
<spacer proportion="1" width="25"/>
<spacer height="25" width="25"/>
<div layout="horizontal-row" width="100%" height="50" align="center">
<bright proportion="1" height="100%"
@ -15,41 +15,16 @@
<spinner id="goalamount" proportion="1" height="100%" min_value="1" max_value="30" wrap_around="true"/>
</div>
<spacer proportion="1" width="25" />
<spacer height="15" width="25"/>
<roundedbox x="2%" y="5%" width="100%" height="50%" layout="vertical-row" id="players-table">
<!-- Content is added programmatically -->
<!-- TODO: remove these tests and actually do this in the code -->
<!--
<div layout="horizontal-row" width="100%" height="50" align="center">
<spacer proportion="1" />
<icon-button id="kart-0" height="100%" icon="karts/beastie/beastie-icon.png"/>
<label proportion="1" height="100%"
I18N="In soccer setup menu" text="funto" text_align="left" />
<button id="team-0" I18N="In soccer setup screen" text="Team: blue" width="30%"/>
<spacer proportion="1" />
</div>
<div layout="horizontal-row" width="100%" height="50" align="center">
<spacer proportion="1" />
<icon-button id="kart-1" height="100%" icon="karts/tux/tuxicon.png"/>
<label proportion="1" height="100%"
I18N="In soccer setup menu" text="bouYou" text_align="left" />
<button id="team-1" I18N="In soccer setup screen" text="Team: red" width="30%"/>
<spacer proportion="1" />
</div>
-->
<label proportion="1" height="100%"
I18N="In soccer setup menu" text="TODO" text_align="left" />
</roundedbox>
<spacer proportion="1" width="25" />
<div id="central_div" layout="horizontal-row" width="100%" proportion="1" align="center">
<roundedbox x="2%" y="5%" proportion="1" layout="horizontal-row" height="100%">
<!-- Content is added programmatically -->
</roundedbox>
</div>
<button id="continue" I18N="In soccer setup screen" text="Continue" align="center" width="60%"/>
</div>
</stkgui>

View File

@ -52,6 +52,8 @@ AbstractKart::AbstractKart(const std::string& ident,
m_kart_width = m_kart_model->getWidth();
m_kart_height = m_kart_model->getHeight();
m_kart_length = m_kart_model->getLength();
m_soccer_team = SOCCER_TEAM_NONE;
} // AbstractKart
// ----------------------------------------------------------------------------
@ -71,6 +73,7 @@ void AbstractKart::reset()
delete m_kart_animation;
m_kart_animation = NULL;
}
m_soccer_team = SOCCER_TEAM_NONE;
} // reset
// ----------------------------------------------------------------------------

View File

@ -39,6 +39,14 @@ class Powerup;
class Skidding;
class SlipStream;
enum SoccerTeam
{
SOCCER_TEAM_NONE=-1,
SOCCER_TEAM_RED=0,
SOCCER_TEAM_BLUE,
NB_SOCCER_TEAMS
};
/** An abstract interface for the actual karts. Some functions are actually
* implemented here in order to allow inlining.
* \ingroup karts
@ -75,6 +83,8 @@ protected:
/** A kart animation object to handle rescue, explosion etc. */
AbstractKartAnimation *m_kart_animation;
SoccerTeam m_soccer_team;
public:
AbstractKart(const std::string& ident,
int world_kart_id,
@ -268,6 +278,12 @@ public:
/** Returns the initial position of this kart. */
virtual int getInitialPosition() const = 0;
// ------------------------------------------------------------------------
/** Returns the current soccer team */
SoccerTeam getSoccerTeam() const {return m_soccer_team;}
// ------------------------------------------------------------------------
/** Sets the current soccer team */
void setSoccerTeam(SoccerTeam team) { m_soccer_team = team; }
// ------------------------------------------------------------------------
/** True if the wheels are touching the ground. */
virtual bool isOnGround() const = 0;
// ------------------------------------------------------------------------

View File

@ -52,6 +52,7 @@ void SoccerWorld::init()
m_display_rank = false;
m_can_score_points = true;
memset(m_team_goals, 0, sizeof(m_team_goals));
// check for possible problems if AI karts were incorrectly added
if(getNumKarts() > race_manager->getNumPlayers())
@ -60,24 +61,7 @@ void SoccerWorld::init()
exit(1);
}
const unsigned int kart_amount = m_karts.size();
for(unsigned int n=0; n<kart_amount; n++)
{
// create the struct that ill hold each player's number of goals
SoccerInfo info;
info.m_goals = 0;
m_kart_info.push_back(info);
// no positions in this mode
m_karts[n]->setPosition(-1);
}// next kart
SoccerEvent evt;
evt.m_time = 0.0f;
evt.m_kart_info = m_kart_info;
m_soccer_events.push_back(evt);
initKartList();
} // SoccerWorld
@ -136,59 +120,6 @@ void SoccerWorld::onCheckGoalTriggered(bool first_goal)
// TODO: score a point
}
//-----------------------------------------------------------------------------
/** Updates the ranking of the karts.
*/
void SoccerWorld::updateKartRanks()
{
beginSetKartPositions();
// sort karts by their times then give each one its position.
// in battle-mode, long time = good (meaning he survived longer)
const unsigned int NUM_KARTS = getNumKarts();
int *karts_list = new int[NUM_KARTS];
for( unsigned int n = 0; n < NUM_KARTS; ++n ) karts_list[n] = n;
bool sorted=false;
do
{
sorted = true;
for( unsigned int n = 0; n < NUM_KARTS-1; ++n )
{
const int this_karts_time =
m_karts[karts_list[n]]->hasFinishedRace()
? (int)m_karts[karts_list[n]]->getFinishTime()
: (int)WorldStatus::getTime();
const int next_karts_time =
m_karts[karts_list[n+1]]->hasFinishedRace()
? (int)m_karts[karts_list[n+1]]->getFinishTime()
: (int)WorldStatus::getTime();
// Swap if next kart survived longer or has more lives
bool swap = next_karts_time > this_karts_time ||
m_kart_info[karts_list[n+1]].m_goals
> m_kart_info[karts_list[n]].m_goals;
if(swap)
{
int tmp = karts_list[n+1];
karts_list[n+1] = karts_list[n];
karts_list[n] = tmp;
sorted = false;
break;
}
} // for n = 0; n < NUM_KARTS-1
} while(!sorted);
for( unsigned int n = 0; n < NUM_KARTS; ++n )
{
setKartPosition(karts_list[n], n+1);
}
delete [] karts_list;
endSetKartPositions();
} // updateKartRank
//-----------------------------------------------------------------------------
/** The battle is over if only one kart is left, or no player kart.
*/
@ -212,7 +143,6 @@ bool SoccerWorld::isRaceOver()
void SoccerWorld::terminateRace()
{
m_can_score_points = false;
updateKartRanks();
WorldWithRank::terminateRace();
} // terminateRace
@ -224,25 +154,10 @@ void SoccerWorld::restartRace()
WorldWithRank::restartRace();
m_can_score_points = true;
memset(m_team_goals, 0, sizeof(m_team_goals));
const unsigned int kart_amount = m_karts.size();
for(unsigned int n=0; n<kart_amount; n++)
{
m_kart_info[n].m_goals = 0;
// no positions in this mode
m_karts[n]->setPosition(-1);
}// next kart
// remove old soccer events
m_soccer_events.clear();
initKartList();
// add initial occer event
SoccerEvent evt;
evt.m_time = 0.0f;
evt.m_kart_info = m_kart_info;
m_soccer_events.push_back(evt);
} // restartRace
//-----------------------------------------------------------------------------
@ -259,14 +174,25 @@ void SoccerWorld::getKartsDisplayInfo(
// reset color
rank_info.lap = -1;
rank_info.r = 0.5;
rank_info.g = 0.5;
rank_info.b = 0.5;
char goals[4];
sprintf(goals, "%i", m_kart_info[i].m_goals);
rank_info.m_text = goals;
AbstractKart* kart = getKart(i);
switch(kart->getSoccerTeam())
{
case SOCCER_TEAM_BLUE:
rank_info.r = 0.0f;
rank_info.g = 0.0f;
rank_info.b = 0.7f;
break;
case SOCCER_TEAM_RED:
rank_info.r = 0.9f;
rank_info.g = 0.0f;
rank_info.b = 0.0f;
break;
default:
assert(false && "Soccer team not set to blue or red");
rank_info.r = 0.0f;
rank_info.g = 0.0f;
rank_info.b = 0.0f;
}
}
} // getKartsDisplayInfo
@ -351,3 +277,52 @@ void SoccerWorld::moveKartAfterRescue(AbstractKart* kart)
(kart->getIdent().c_str()), m_track->getIdent().c_str());
}
} // moveKartAfterRescue
/** Set position and team for the karts */
void SoccerWorld::initKartList()
{
const unsigned int kart_amount = m_karts.size();
// Set kart positions, ordering them by team
for(unsigned int n=0; n<kart_amount; n++)
{
m_karts[n]->setPosition(-1);
}
// TODO: remove
/*
const unsigned int kart_amount = m_karts.size();
int team_karts_amount[NB_SOCCER_TEAMS];
memset(team_karts_amount, 0, sizeof(team_karts_amount));
{
// Set the kart teams if they haven't been already set by the setup screen
// (happens when the setup screen is skipped, with 1 player)
SoccerTeam round_robin_team = SOCCER_TEAM_RED;
for(unsigned int n=0; n<kart_amount; n++)
{
if(m_karts[n]->getSoccerTeam() == SOCCER_TEAM_NONE)
m_karts[n]->setSoccerTeam(round_robin_team);
team_karts_amount[m_karts[n]->getSoccerTeam()]++;
round_robin_team = (round_robin_team==SOCCER_TEAM_RED ?
SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
}// next kart
}
// Compute start positions for each team
int team_cur_position[NB_SOCCER_TEAMS];
team_cur_position[0] = 1;
for(int i=1 ; i < (int)NB_SOCCER_TEAMS ; i++)
team_cur_position[i] = team_karts_amount[i-1] + team_cur_position[i-1];
// Set kart positions, ordering them by team
for(unsigned int n=0; n<kart_amount; n++)
{
SoccerTeam team = m_karts[n]->getSoccerTeam();
m_karts[n]->setPosition(team_cur_position[team]);
team_cur_position[team]++;
}// next kart
*/
}

View File

@ -21,6 +21,7 @@
#include "modes/world_with_rank.hpp"
#include "states_screens/race_gui_base.hpp"
#include "karts/abstract_kart.hpp"
#include <IMesh.h>
@ -37,14 +38,9 @@ class PhysicalObject;
class SoccerWorld : public WorldWithRank
{
private:
struct SoccerInfo
{
int m_goals;
};
/** This vector contains an 'SoccerInfo' struct for every kart in the race.
*/
std::vector<SoccerInfo> m_kart_info;
/** Number of goals each team scored
*/
int m_team_goals[NB_SOCCER_TEAMS];
/** Whether or not goals can be scored (they are disabled when a point is scored
and re-enabled when the next game can be played)*/
@ -52,14 +48,6 @@ private:
public:
/** Used to show a nice graph when battle is over */
struct SoccerEvent
{
float m_time;
std::vector<SoccerInfo> m_kart_info;
};
std::vector<SoccerEvent> m_soccer_events;
SoccerWorld();
virtual ~SoccerWorld() {}
@ -83,7 +71,9 @@ public:
virtual void update(float dt);
void onCheckGoalTriggered(bool first_goal);
void updateKartRanks();
private:
void initKartList();
}; // SoccerWorld

View File

@ -720,6 +720,11 @@ void RaceGUIBase::drawGlobalReadySetGo()
*/
void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
{
// For now, don't draw player icons when in soccer mode
const RaceManager::MinorRaceModeType minor_mode = race_manager->getMinorMode();
if(minor_mode == RaceManager::MINOR_MODE_SOCCER)
return;
int x_base = 10;
int y_base = 20;
unsigned int y_space = UserConfigParams::m_height - bottom_margin - y_base;
@ -806,10 +811,8 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
//x,y is the target position
int lap = info.lap;
// In battle mode and soccer mode there is no distance along track etc.
const RaceManager::MinorRaceModeType minor_mode = race_manager->getMinorMode();
if( minor_mode==RaceManager::MINOR_MODE_3_STRIKES ||
minor_mode==RaceManager::MINOR_MODE_SOCCER)
// In battle mode mode there is no distance along track etc.
if( minor_mode==RaceManager::MINOR_MODE_3_STRIKES )
{
x = x_base;
y = previous_y+ICON_PLAYER_WIDTH+2;

View File

@ -19,6 +19,15 @@
#include "states_screens/state_manager.hpp"
#include "states_screens/arenas_screen.hpp"
#include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/spinner_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/model_view_widget.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp"
#include "karts/kart_properties_manager.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_model.hpp"
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( SoccerSetupScreen );
@ -48,33 +57,182 @@ void SoccerSetupScreen::eventCallback(Widget* widget, const std::string& name, c
}
}
// -----------------------------------------------------------------------------
void SoccerSetupScreen::beforeAddingWidget()
{
Widget* central_div = getWidget<Widget>("central_div");
/*
const unsigned int kart_amount = m_karts.size();
int team_karts_amount[NB_SOCCER_TEAMS];
memset(team_karts_amount, 0, sizeof(team_karts_amount));
{
// Set the kart teams if they haven't been already set by the setup screen
// (happens when the setup screen is skipped, with 1 player)
SoccerTeam round_robin_team = SOCCER_TEAM_RED;
for(unsigned int n=0; n<kart_amount; n++)
{
if(m_karts[n]->getSoccerTeam() == SOCCER_TEAM_NONE)
m_karts[n]->setSoccerTeam(round_robin_team);
team_karts_amount[m_karts[n]->getSoccerTeam()]++;
round_robin_team = (round_robin_team==SOCCER_TEAM_RED ?
SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
}// next kart
}
// Compute start positions for each team
int team_cur_position[NB_SOCCER_TEAMS];
team_cur_position[0] = 1;
for(int i=1 ; i < (int)NB_SOCCER_TEAMS ; i++)
team_cur_position[i] = team_karts_amount[i-1] + team_cur_position[i-1];
// Set kart positions, ordering them by team
for(unsigned int n=0; n<kart_amount; n++)
{
SoccerTeam team = m_karts[n]->getSoccerTeam();
m_karts[n]->setPosition(team_cur_position[team]);
team_cur_position[team]++;
}// next kart
*/
// BEGIN TEST
ModelViewWidget* kart_view = new ModelViewWidget();
kart_view->m_x = central_div->m_x + 10;
kart_view->m_y = central_div->m_y + 10;
kart_view->m_w = 200;
kart_view->m_h = 200;
kart_view->clearModels();
const std::string default_kart = UserConfigParams::m_default_kart;
const KartProperties* props =
kart_properties_manager->getKart(default_kart);
const KartModel &kart_model = props->getMasterKartModel();
kart_view->addModel( kart_model.getModel(), Vec3(0,0,0),
Vec3(35.0f, 35.0f, 35.0f),
kart_model.getBaseFrame() );
kart_view->addModel( kart_model.getWheelModel(0),
kart_model.getWheelGraphicsPosition(0) );
kart_view->addModel( kart_model.getWheelModel(1),
kart_model.getWheelGraphicsPosition(1) );
kart_view->addModel( kart_model.getWheelModel(2),
kart_model.getWheelGraphicsPosition(2) );
kart_view->addModel( kart_model.getWheelModel(3),
kart_model.getWheelGraphicsPosition(3) );
kart_view->setRotateContinuously( 35.0f );
kart_view->update(0);
central_div->getChildren().push_back(kart_view);
// END TEST
// Add "VS" label at the center of the rounded box
m_label_vs = new LabelWidget(true, false);
core::dimension2d<u32> vs_size = GUIEngine::getTitleFont()->getDimension( L"VS" );
m_label_vs->m_x = central_div->m_x + central_div->m_w/2 - vs_size.Width/2;
m_label_vs->m_y = central_div->m_y + central_div->m_h/2 - vs_size.Height/2;
m_label_vs->m_w = vs_size.Width;
m_label_vs->m_h = vs_size.Height;
central_div->getChildren().push_back(m_label_vs);
}
// -----------------------------------------------------------------------------
void SoccerSetupScreen::init()
{
Screen::init();
// TODO: remember in config.xml the last number of goals
SpinnerWidget* goalamount = getWidget<SpinnerWidget>("goalamount");
goalamount->setValue(3);
// Set focus on "continue"
ButtonWidget* bt_continue = getWidget<ButtonWidget>("continue");
bt_continue->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
// "VS" (needs to be done here for the Irrlicht element to be here)
m_label_vs->setText("VS", true);
/*
Widget* players_table = getWidget<Widget>("players-table");
assert(players_table != NULL);
// BEGIN TODO
/*
Widget* div = new Widget(WTYPE_DIV);
div->m_properties[PROP_LAYOUT] = "horizontal-row";
//widget.m_properties[prop_flag] = core::stringc(prop_name).c_str(); else widget.m_properties[prop_flag] = ""
div->setParent(players_table->getIrrlichtElement());
players_table->getChildren().push_back(div);
//players_table->add();
manualAddWidget(new TeamViewWidget(this));
*/
/* LabelWidget* lbl = new LabelWidget();
lbl->m_properties[PROP_PROPORTION] = "1";
lbl->m_properties[PROP_HEIGHT] = "100%";
lbl->setText(L"bouYou", false);
lbl->m_properties[PROP_TEXT_ALIGN] = "left";
//widget.m_properties[prop_flag] = core::stringc(prop_name).c_str(); else widget.m_properties[prop_flag] = ""
//lbl->setParent(players_table->getIrrlichtElement());
players_table->getChildren().push_back(lbl);
calculateLayout();
*/
// END TODO
/*// ----- 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_playerID);
//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(kartGroup, 0);
if (id == -1)
{
props = kart_properties_manager->getKartById(0);
}
else
{
props = kart_properties_manager->getKartById(id);
}
if(!props)
{
fprintf(stderr,
"[KartSelectionScreen] WARNING: Can't find default "
"kart '%s' nor any other kart.\n",
default_kart.c_str());
exit(-1);
}
}
m_kartInternalName = props->getIdent();
const KartModel &kart_model = props->getMasterKartModel();
m_model_view->addModel( kart_model.getModel(), Vec3(0,0,0),
Vec3(35.0f, 35.0f, 35.0f),
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) );
m_model_view->setRotateContinuously( 35.0f );
// ---- Kart name label
m_kart_name = new LabelWidget();
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_playerID);
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_kart_name->setParent(this);
m_children.push_back(m_kart_name);*/
}

View File

@ -20,7 +20,7 @@
#include "guiengine/screen.hpp"
namespace GUIEngine { class Widget; }
namespace GUIEngine { class Widget; class LabelWidget; }
/**
* \brief Screen with soccer setup options
@ -32,6 +32,9 @@ class SoccerSetupScreen : public GUIEngine::Screen, public GUIEngine::ScreenSing
SoccerSetupScreen();
/** The "VS" text at the center of the screen */
GUIEngine::LabelWidget* m_label_vs;
public:
/** \brief implement callback from parent class GUIEngine::Screen */
@ -41,6 +44,9 @@ public:
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name,
const int playerID) OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void beforeAddingWidget() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init() OVERRIDE;
};