Make soccer menu useful in single player

Notice: As race_manager->setKartSoccerTeam(i, info.team) already
pre-set karts team, there is no need to test for
(getNumKartsInTeam(SOCCER_TEAM_RED) == 0 || getNumKartsInTeam(SOCCER_TEAM_BLUE) == 0),
so the the menu code is simplified.
This commit is contained in:
Benau
2016-01-16 16:11:33 +08:00
parent b45d926a00
commit b410c8f67c
7 changed files with 77 additions and 99 deletions

View File

@@ -6,38 +6,39 @@
<header width="80%" text="Race Setup" align="center" text_align="center" />
<spacer height="25" width="25"/>
<spacer height="10" width="25"/>
<div layout="horizontal-row" width="fit" height="35" align="left">
<bright proportion="1" height="100%"
I18N="In soccer setup screen" text="Number of goals to win" text_align="left" />
<spacer width="50" height="25"/>
<spacer width="10" height="25"/>
<spinner id="goalamount" width="200" height="90%" min_value="1" max_value="10"/>
</div>
<div layout="horizontal-row" width="fit" height="35" align="left">
<bright proportion="1" height="100%"
I18N="In soccer setup screen" text="Maximum time (min.)" text_align="left" />
<spacer width="50" height ="25"/>
<spacer width="10" height ="25"/>
<spinner id="timeamount" width="200" height="90%" min_value="1" max_value="15"/>
</div>
<div layout="horizontal-row" width="fit" height="35" align="left">
<bright proportion="1" height="100%"
I18N="In soccer setup screen" text="Game type (Goals limit / Time limit)" text_align="left" />
<spacer width="50" height="25"/>
<spacer width="10" height="25"/>
<checkbox id="time_enabled"/>
</div>
<spacer height="40" width="25"/>
<spacer height="10" width="25"/>
<bright height="15" width="25" I18N="In soccer setup screen" text="Use left/right to choose your team and press fire" text_align="center" align="center" />
<bright height="10" width="25" I18N="In soccer setup screen" text="Use left/right to choose your team and press fire" text_align="center" align="center" />
<div id="central_div" layout="horizontal-row" width="100%" proportion="1" align="center">
<roundedbox y="5%" width="100%" layout="horizontal-row" height="100%">
<roundedbox y="5%" width="100%" layout="horizontal-row" height="95%">
<!-- Content is added programmatically -->
</roundedbox>
<header id="vs" text="VS"/> <!-- Layout is done programmatically -->
<bright I18N="In soccer setup screen" id="red_team" text="Red Team"/> <!-- Layout is done programmatically -->
<bright I18N="In soccer setup screen" id="blue_team" text="Blue Team"/>
</div>
<button id="continue" I18N="In soccer setup screen" text="Continue" align="center" width="60%"/>

View File

@@ -82,8 +82,25 @@ void SoccerAI::reset()
ArenaAI::reset();
AIBaseController::reset();
m_cur_team = (m_kart->getWorldKartId() % 2 == 0 ?
SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
if (race_manager->getNumPlayers() == 1)
{
// Same handle in SoccerWorld::createKart
if (race_manager->getKartInfo(0).getSoccerTeam() == SOCCER_TEAM_RED)
{
m_cur_team = (m_kart->getWorldKartId() % 2 == 0 ?
SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
}
else
{
m_cur_team = (m_kart->getWorldKartId() % 2 == 0 ?
SOCCER_TEAM_RED : SOCCER_TEAM_BLUE);
}
}
else
{
m_cur_team = (m_kart->getWorldKartId() % 2 == 0 ?
SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
}
} // reset
//-----------------------------------------------------------------------------

View File

@@ -321,7 +321,22 @@ AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
if (kart_type == RaceManager::KT_AI)
{
team = (index % 2 == 0 ? SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
if (race_manager->getNumPlayers() == 1)
{
// Make AI even when single player choose a different team
if (race_manager->getKartInfo(0).getSoccerTeam() == SOCCER_TEAM_RED)
{
team = (index % 2 == 0 ? SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
}
else
{
team = (index % 2 == 0 ? SOCCER_TEAM_RED : SOCCER_TEAM_BLUE);
}
}
else
{
team = (index % 2 == 0 ? SOCCER_TEAM_BLUE : SOCCER_TEAM_RED);
}
m_kart_team_map[index] = team;
}
else

View File

@@ -198,14 +198,6 @@ void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const
Track* clicked_track = track_manager->getTrack(selection);
if (clicked_track != NULL)
{
//HACK hardcode for single player soccer
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER &&
race_manager->getNumPlayers() == 1)
{
race_manager->setMaxGoal(4);
race_manager->setKartSoccerTeam(0, SOCCER_TEAM_RED);
}
TrackInfoScreen::getInstance()->setTrack(clicked_track);
TrackInfoScreen::getInstance()->push();
} // clickedTrack != NULL

View File

@@ -33,8 +33,6 @@
#include "states_screens/tracks_screen.hpp"
#include "utils/translation.hpp"
#define ENABLE_SOCCER_MODE
const int CONFIG_CODE_NORMAL = 0;
const int CONFIG_CODE_TIMETRIAL = 1;
const int CONFIG_CODE_FTL = 2;
@@ -114,12 +112,10 @@ void RaceSetupScreen::init()
name4 += _("Hit others with weapons until they lose all their lives (only in multiplayer games).");
w2->addItem( name4, IDENT_STRIKES, RaceManager::getIconOf(RaceManager::MINOR_MODE_3_STRIKES));
#ifdef ENABLE_SOCCER_MODE
irr::core::stringw name5 = irr::core::stringw(
RaceManager::getNameOf(RaceManager::MINOR_MODE_SOCCER)) + L"\n";
name5 += _("Push the ball to the opposite cage to score goals (only in multiplayer games).");
w2->addItem( name5, IDENT_SOCCER, RaceManager::getIconOf(RaceManager::MINOR_MODE_SOCCER));
#endif
#define ENABLE_EASTER_EGG_MODE
#ifdef ENABLE_EASTER_EGG_MODE
@@ -234,11 +230,7 @@ void RaceSetupScreen::eventCallback(Widget* widget, const std::string& name,
{
race_manager->setMinorMode(RaceManager::MINOR_MODE_SOCCER);
UserConfigParams::m_game_mode = CONFIG_CODE_SOCCER;
// 1 player -> no need to choose a team or determine when the match ends
if(race_manager->getNumLocalPlayers() <= 1)
ArenasScreen::getInstance()->push();
else
SoccerSetupScreen::getInstance()->push();
SoccerSetupScreen::getInstance()->push();
}
else if (selectedMode == "locked")
{

View File

@@ -34,7 +34,6 @@
#include "states_screens/arenas_screen.hpp"
#include "states_screens/state_manager.hpp"
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( SoccerSetupScreen );
@@ -65,20 +64,7 @@ void SoccerSetupScreen::eventCallback(Widget* widget, const std::string& name,
{
int nb_players = (int)m_kart_view_info.size();
if (getNumKartsInTeam(SOCCER_TEAM_RED) == 0 ||
getNumKartsInTeam(SOCCER_TEAM_BLUE) == 0)
{
for(int i=0 ; i < nb_players ; i++)
{
if (!m_kart_view_info[i].confirmed)
{
m_kart_view_info[i].view->setBadge(BAD_BADGE);
}
}
SFXManager::get()->quickSound( "anvil" );
return;
}
else if(!areAllKartsConfirmed())
if(!areAllKartsConfirmed())
{
for(int i=0 ; i < nb_players ; i++)
{
@@ -123,18 +109,22 @@ void SoccerSetupScreen::beforeAddingWidget()
Widget* central_div = getWidget<Widget>("central_div");
// Compute some dimensions
const core::dimension2d<u32> vs_size = GUIEngine::getTitleFont()->getDimension( L"VS" );
const int vs_width = (int)vs_size.Width;
const int vs_height = (int)vs_size.Height;
const int center_x = central_div->m_x + central_div->m_w/2;
const int center_y = central_div->m_y + central_div->m_h/2;
const core::dimension2d<u32> text_size = GUIEngine::getFont()->getDimension( L"X" );
const int text_width = (int)text_size.Width;
const int text_height = (int)text_size.Height;
// Add "VS" label at the center of the rounded box
LabelWidget* label_vs = getWidget<LabelWidget>("vs");
label_vs->m_x = center_x - vs_width/2;
label_vs->m_y = center_y - vs_height/2;
label_vs->m_w = vs_width;
label_vs->m_h = vs_height;
// Add team name label above the karts
LabelWidget* label_red = getWidget<LabelWidget>("red_team");
LabelWidget* label_blue = getWidget<LabelWidget>("blue_team");
label_red->m_x = central_div->m_x + central_div->m_w/4;
label_red->m_y = central_div->m_y + text_height;
label_red->m_w = text_width;
label_red->m_h = text_height;
label_blue->m_x = central_div->m_x + (central_div->m_w/4)*3;
label_blue->m_y = central_div->m_y + text_height;
label_blue->m_w = text_width;
label_blue->m_h = text_height;
// Add the 3D views for the karts
int nb_players = race_manager->getNumPlayers();
@@ -191,10 +181,10 @@ void SoccerSetupScreen::init()
m_schedule_continue = false;
Screen::init();
if (UserConfigParams::m_num_goals <= 0)
UserConfigParams::m_num_goals = 3;
if (UserConfigParams::m_soccer_time_limit <= 0)
UserConfigParams::m_soccer_time_limit = 3;
@@ -229,7 +219,7 @@ void SoccerSetupScreen::tearDown()
// Reset the 'map fire to select' option of the device manager
input_manager->getDeviceManager()->mapFireToSelect(false);
UserConfigParams::m_num_goals = getWidget<SpinnerWidget>("goalamount")->getValue();
UserConfigParams::m_soccer_time_limit = getWidget<SpinnerWidget>("timeamount")->getValue();
@@ -308,22 +298,12 @@ GUIEngine::EventPropagation SoccerSetupScreen::filterActions(PlayerAction action
return EVENT_BLOCK;
}
if (getNumConfirmedKarts() > nb_players-2 &&
(getNumKartsInTeam(SOCCER_TEAM_RED) == 0 ||
getNumKartsInTeam(SOCCER_TEAM_BLUE) == 0))
{
SFXManager::get()->quickSound( "anvil" );
m_kart_view_info[playerId].view->setBadge(BAD_BADGE);
}
else
{
// Confirm team selection
m_kart_view_info[playerId].confirmed = true;
m_kart_view_info[playerId].view->setRotateTo( KART_CONFIRMATION_TARGET_ANGLE, KART_CONFIRMATION_ROTATION_SPEED );
m_kart_view_info[playerId].view->setBadge(OK_BADGE);
m_kart_view_info[playerId].view->unsetBadge(BAD_BADGE);
SFXManager::get()->quickSound( "wee" );
}
// Confirm team selection
m_kart_view_info[playerId].confirmed = true;
m_kart_view_info[playerId].view->setRotateTo( KART_CONFIRMATION_TARGET_ANGLE, KART_CONFIRMATION_ROTATION_SPEED );
m_kart_view_info[playerId].view->setBadge(OK_BADGE);
m_kart_view_info[playerId].view->unsetBadge(BAD_BADGE);
SFXManager::get()->quickSound( "wee" );
return EVENT_BLOCK;
}
case PA_MENU_CANCEL:
@@ -349,15 +329,13 @@ GUIEngine::EventPropagation SoccerSetupScreen::filterActions(PlayerAction action
default:
break;
}
if(team_switch != SOCCER_TEAM_NONE) // A player wants to change his team?
{
race_manager->setKartSoccerTeam(playerId, team_switch);
m_kart_view_info[playerId].team = team_switch;
updateKartViewsLayout();
}
return result;
} // filterActions
@@ -366,7 +344,7 @@ GUIEngine::EventPropagation SoccerSetupScreen::filterActions(PlayerAction action
void SoccerSetupScreen::onUpdate(float delta)
{
int nb_players = (int)m_kart_view_info.size();
if(m_schedule_continue)
{
for(int i=0 ; i < nb_players ; i++)
@@ -377,7 +355,7 @@ void SoccerSetupScreen::onUpdate(float delta)
m_schedule_continue = false;
ArenasScreen::getInstance()->push();
}
} // onUPdate
} // onUpdate
// ----------------------------------------------------------------------------
bool SoccerSetupScreen::areAllKartsConfirmed() const
@@ -395,19 +373,6 @@ bool SoccerSetupScreen::areAllKartsConfirmed() const
return all_confirmed;
} // areAllKartsConfirmed
// ----------------------------------------------------------------------------
int SoccerSetupScreen::getNumKartsInTeam(int team)
{
int karts_in_team = 0;
int nb_players = (int)m_kart_view_info.size();
for(int i=0 ; i < nb_players ; i++)
{
if(m_kart_view_info[i].team == team)
karts_in_team++;
}
return karts_in_team;
} // getNumKartsInTeam
// -----------------------------------------------------------------------------
int SoccerSetupScreen::getNumConfirmedKarts()
{
@@ -427,10 +392,8 @@ void SoccerSetupScreen::updateKartViewsLayout()
Widget* central_div = getWidget<Widget>("central_div");
// Compute/get some dimensions
LabelWidget* label_vs = getWidget<LabelWidget>("vs");
const int vs_width = label_vs->m_w;
const int nb_columns = 2; // two karts maximum per column
const int kart_area_width = (central_div->m_w - vs_width) / 2; // size of one half of the screen
const int kart_area_width = (central_div->m_w) / 2; // size of one half of the screen
const int kart_view_size = kart_area_width/nb_columns; // Size (width and height) of a kart view
const int center_x = central_div->m_x + central_div->m_w/2;
const int center_y = central_div->m_y + central_div->m_h/2;
@@ -448,8 +411,8 @@ void SoccerSetupScreen::updateKartViewsLayout()
const int start_y[2] = {center_y - nb_rows_per_team[0] * kart_view_size / 2,
center_y - nb_rows_per_team[1] * kart_view_size / 2};
// - center of each half-screen
const int center_x_per_team[2] = { ( central_div->m_x + (center_x - vs_width) ) / 2,
( central_div->m_x+central_div->m_w + (center_x + vs_width) ) / 2,
const int center_x_per_team[2] = { ( central_div->m_x + center_x ) / 2,
( central_div->m_x+central_div->m_w + center_x ) / 2,
};
// Update the layout of the 3D views for the karts
@@ -474,4 +437,3 @@ void SoccerSetupScreen::updateKartViewsLayout()
view_info.view->move(pos_x, pos_y, kart_view_size, kart_view_size);
}
} // updateKartViewsLayout

View File

@@ -43,7 +43,7 @@ class SoccerSetupScreen : public GUIEngine::Screen, public GUIEngine::ScreenSing
};
AlignedArray<KartViewInfo> m_kart_view_info;
bool m_schedule_continue;
public:
@@ -75,7 +75,6 @@ public:
private:
bool areAllKartsConfirmed() const;
int getNumKartsInTeam(int team);
int getNumConfirmedKarts();
void updateKartViewsLayout();
};