FFA for offline play (#3708)

* added widget to track info screen to select between Free-For-All and Three Strikes Battle

* setting AI to zero and setting time target to 2 minutes for testing

* setting also hitcapture limit to prevent immediate race end

* setting m_count_down_reached_zero to false in ffa reset to allow starting a new race after the previous ended through time limit

* integrated necessary adjustments and made possible to set time target

* removed unused spinner variable

* use translations

* centralized is_soccer and show_ffa_spinner variables

* setting target value spinner visible/invisible depending on ffa game type

* using no hittarget and fix for this in free for all mode

* set use_highscores to false for FFA

* disabling AI for FFA

* disable hit limit icon for FFA if no hit limit is set ( = 0 )

* changed icon and name of three strikes battle to only battle in race setup screen

* set AI to Battle AI if mode is FFA

* added config parameters for FFA

* added define which can be used to enable FFA AI

* resolved merge conflict

* moved ffa options higher

* fix for setting ai karts

* improved m_show_ffa_spinner and m_is_soccer

* removed code for disabling widgets for FFA AI

* implemented requested changes
This commit is contained in:
Mrxx99 2019-02-21 01:18:02 +01:00 committed by auriamg
parent 6e18dce622
commit b55ec5cfb8
8 changed files with 108 additions and 35 deletions

View File

@ -81,7 +81,7 @@
wrap_around="true" />
</div>
<spacer width="3%"/>
<label id="target-type-text" proportion="3" I18N="In the track info screen" text="Soccer game type" text_align="left" />
<label id="target-type-text" proportion="3" I18N="In the track info screen" text_align="left" />
</div>
<spacer width="1" height="2%"/>
<div width="100%" height="fit" layout="horizontal-row" >

View File

@ -413,6 +413,12 @@ namespace UserConfigParams
PARAM_PREFIX IntUserConfigParam m_num_laps
PARAM_DEFAULT( IntUserConfigParam(4, "numlaps",
&m_race_setup_group, "Default number of laps.") );
PARAM_PREFIX IntUserConfigParam m_ffa_time_limit
PARAM_DEFAULT(IntUserConfigParam(3, "ffa-time-limit",
&m_race_setup_group, "Time limit in ffa mode."));
PARAM_PREFIX BoolUserConfigParam m_use_ffa_mode
PARAM_DEFAULT(BoolUserConfigParam(false, "use-ffa-mode",
&m_race_setup_group, "Use ffa mode instead of 3 strikes battle."));
PARAM_PREFIX IntUserConfigParam m_num_goals
PARAM_DEFAULT( IntUserConfigParam(3, "numgoals",
&m_race_setup_group, "Default number of goals in soccer mode.") );

View File

@ -54,6 +54,7 @@ void FreeForAll::init()
WorldWithRank::init();
m_display_rank = false;
m_count_down_reached_zero = false;
m_use_highscores = false;
} // init
// ----------------------------------------------------------------------------
@ -62,6 +63,7 @@ void FreeForAll::init()
void FreeForAll::reset(bool restart)
{
WorldWithRank::reset(restart);
m_count_down_reached_zero = false;
if (race_manager->hasTimeTarget())
{
WorldStatus::setClockMode(WorldStatus::CLOCK_COUNTDOWN,
@ -186,9 +188,12 @@ bool FreeForAll::isRaceOver()
if (!getKartAtPosition(1))
return false;
int top_id = getKartAtPosition(1)->getWorldKartId();
const int top_id = getKartAtPosition(1)->getWorldKartId();
const int hit_capture_limit = race_manager->getHitCaptureLimit();
return (m_count_down_reached_zero && race_manager->hasTimeTarget()) ||
m_scores[top_id] >= race_manager->getHitCaptureLimit();
(hit_capture_limit != 0 && m_scores[top_id] >= hit_capture_limit);
} // isRaceOver
// ----------------------------------------------------------------------------

View File

@ -521,7 +521,8 @@ Controller* World::loadAIController(AbstractKart* kart)
Controller *controller;
int turn=0;
if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_3_STRIKES)
if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_3_STRIKES
|| race_manager->getMinorMode()==RaceManager::MINOR_MODE_FREE_FOR_ALL)
turn=1;
else if(race_manager->getMinorMode()==RaceManager::MINOR_MODE_SOCCER)
turn=2;

View File

@ -1172,7 +1172,8 @@ void RaceGUI::drawLap(const AbstractKart* kart,
static video::SColor color = video::SColor(255, 255, 255, 255);
int hit_capture_limit =
race_manager->getHitCaptureLimit() != std::numeric_limits<int>::max()
(race_manager->getHitCaptureLimit() != std::numeric_limits<int>::max()
&& race_manager->getHitCaptureLimit() != 0)
? race_manager->getHitCaptureLimit() : -1;
int score_limit = sw && !race_manager->hasTimeTarget() ?
race_manager->getMaxGoal() : ctf ? hit_capture_limit : -1;

View File

@ -108,11 +108,10 @@ void RaceSetupScreen::init()
w2->addItem(name3, IDENT_FTL, RaceManager::getIconOf(RaceManager::MINOR_MODE_FOLLOW_LEADER), false);
}
irr::core::stringw name4 = irr::core::stringw(
RaceManager::getNameOf(RaceManager::MINOR_MODE_3_STRIKES)) + L"\n";
irr::core::stringw name4 = irr::core::stringw(_("Battle")) + L"\n";
//FIXME: avoid duplicating descriptions from the help menu!
name4 += _("Hit others with weapons until they lose all their lives.");
w2->addItem( name4, IDENT_STRIKES, RaceManager::getIconOf(RaceManager::MINOR_MODE_3_STRIKES));
w2->addItem( name4, IDENT_STRIKES, RaceManager::getIconOf(RaceManager::MINOR_MODE_FREE_FOR_ALL));
irr::core::stringw name5 = irr::core::stringw(
RaceManager::getNameOf(RaceManager::MINOR_MODE_SOCCER)) + L"\n";

View File

@ -68,6 +68,7 @@ void TrackInfoScreen::loadedFromFile()
m_target_value_spinner = getWidget<SpinnerWidget>("target-value-spinner");
m_target_value_label = getWidget<LabelWidget>("target-value-text");
m_ai_kart_spinner = getWidget<SpinnerWidget>("ai-spinner");
m_ai_kart_label = getWidget<LabelWidget>("ai-text");
m_option = getWidget<CheckBoxWidget>("option");
m_record_race = getWidget<CheckBoxWidget>("record");
m_option->setState(false);
@ -84,14 +85,24 @@ void TrackInfoScreen::loadedFromFile()
GUIEngine::IconButtonWidget* screenshot = getWidget<IconButtonWidget>("screenshot");
screenshot->setFocusable(false);
screenshot->m_tab_stop = false;
m_is_soccer = false;
m_show_ffa_spinner = false;
} // loadedFromFile
void TrackInfoScreen::beforeAddingWidget()
{
const bool is_soccer = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
m_target_type_div->setCollapsed(!is_soccer, this);
} // beforeAddingWidget
m_is_soccer = race_manager->isSoccerMode();
m_show_ffa_spinner = race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES
|| race_manager->getMinorMode() == RaceManager::MINOR_MODE_FREE_FOR_ALL;
if (m_is_soccer || m_show_ffa_spinner)
m_target_type_div->setCollapsed(false, this);
else
m_target_type_div->setCollapsed(true, this);
} // beforeAddingWidget
// ----------------------------------------------------------------------------
void TrackInfoScreen::setTrack(Track *track)
@ -150,9 +161,10 @@ void TrackInfoScreen::init()
// Soccer options
// -------------
const bool is_soccer = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
if (is_soccer)
if (m_is_soccer)
{
m_target_type_label->setText(_("Soccer game type"), false);
m_target_value_spinner->setVisible(true);
m_target_value_label->setVisible(true);
@ -179,6 +191,23 @@ void TrackInfoScreen::init()
}
}
// options for free-for-all and three strikes battle
// -------------
if (m_show_ffa_spinner)
{
m_target_type_label->setText(_("Game mode"), false);
m_target_type_spinner->clearLabels();
m_target_type_spinner->addLabel(_("3 Strikes Battle"));
m_target_type_spinner->addLabel(_("Free-For-All"));
m_target_type_spinner->setValue(UserConfigParams::m_use_ffa_mode ? 1 : 0);
m_target_value_label->setText(_("Maximum time (min.)"), false);
m_target_value_spinner->setValue(UserConfigParams::m_ffa_time_limit);
m_target_value_label->setVisible(UserConfigParams::m_use_ffa_mode);
m_target_value_spinner->setVisible(UserConfigParams::m_use_ffa_mode);
}
// Lap count m_lap_spinner
// -----------------------
if (has_laps)
@ -201,11 +230,12 @@ void TrackInfoScreen::init()
const int local_players = race_manager->getNumLocalPlayers();
const bool has_AI =
(race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES ||
race_manager->getMinorMode() == RaceManager::MINOR_MODE_FREE_FOR_ALL ||
race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER ?
m_track->hasNavMesh() && (max_arena_players - local_players) > 0 :
race_manager->hasAI());
m_ai_kart_spinner->setVisible(has_AI);
getWidget<LabelWidget>("ai-text")->setVisible(has_AI);
m_ai_kart_label->setVisible(has_AI);
if (has_AI)
{
@ -411,6 +441,7 @@ void TrackInfoScreen::onEnterPressedInternal()
const int local_players = race_manager->getNumLocalPlayers();
const bool has_AI =
(race_manager->getMinorMode() == RaceManager::MINOR_MODE_3_STRIKES ||
race_manager->getMinorMode() == RaceManager::MINOR_MODE_FREE_FOR_ALL ||
race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER ?
m_track->hasNavMesh() && (max_arena_players - local_players) > 0 :
race_manager->hasAI());
@ -419,18 +450,18 @@ void TrackInfoScreen::onEnterPressedInternal()
if (has_AI)
num_ai = m_ai_kart_spinner->getValue();
if (UserConfigParams::m_num_karts_per_gamemode
[race_manager->getMinorMode()] != unsigned(local_players + num_ai))
{
race_manager->setNumKarts(local_players + num_ai);
UserConfigParams::m_num_karts_per_gamemode[race_manager->getMinorMode()] = local_players + num_ai;
}
const int selected_target_type = m_target_type_spinner->getValue();
const int selected_target_value = m_target_value_spinner->getValue();
if (race_manager->isSoccerMode())
const bool enable_ffa = m_show_ffa_spinner && selected_target_type != 0;
if (enable_ffa)
{
race_manager->setMinorMode(RaceManager::MINOR_MODE_FREE_FOR_ALL);
race_manager->setHitCaptureTime(0, static_cast<float>(selected_target_value) * 60);
}
if (m_is_soccer)
{
if (selected_target_type == 0)
race_manager->setTimeTarget(static_cast<float>(selected_target_value) * 60);
@ -438,9 +469,16 @@ void TrackInfoScreen::onEnterPressedInternal()
race_manager->setMaxGoal(selected_target_value);
}
if (UserConfigParams::m_num_karts_per_gamemode
[race_manager->getMinorMode()] != unsigned(local_players + num_ai))
{
UserConfigParams::m_num_karts_per_gamemode[race_manager->getMinorMode()] = local_players + num_ai;
}
// Disable accidentally unlocking of a challenge
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
race_manager->setNumKarts(num_ai + local_players);
race_manager->startSingleRace(m_track->getIdent(), num_laps, false);
} // onEnterPressedInternal
@ -463,25 +501,35 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name,
}
else if (name == "target-type-spinner")
{
const bool timed = m_target_type_spinner->getValue() == 0;
UserConfigParams::m_soccer_use_time_limit = timed;
if (timed)
const bool target_value = m_target_type_spinner->getValue();
if (m_is_soccer)
{
m_target_value_label->setText(_("Maximum time (min.)"), false);
m_target_value_spinner->setValue(UserConfigParams::m_soccer_time_limit);
const bool timed = target_value == 0;
UserConfigParams::m_soccer_use_time_limit = timed;
if (timed)
{
m_target_value_label->setText(_("Maximum time (min.)"), false);
m_target_value_spinner->setValue(UserConfigParams::m_soccer_time_limit);
}
else
{
m_target_value_label->setText(_("Number of goals to win"), false);
m_target_value_spinner->setValue(UserConfigParams::m_num_goals);
}
}
else
else if (m_show_ffa_spinner)
{
m_target_value_label->setText(_("Number of goals to win"), false);
m_target_value_spinner->setValue(UserConfigParams::m_num_goals);
const bool enable_ffa = target_value != 0;
UserConfigParams::m_use_ffa_mode = enable_ffa;
m_target_value_label->setVisible(enable_ffa);
m_target_value_spinner->setVisible(enable_ffa);
}
}
else if (name == "target-value-spinner")
{
const bool is_soccer = race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER;
if (is_soccer)
if (m_is_soccer)
{
const bool timed = m_target_type_spinner->getValue() == 0;
if (timed)
@ -489,6 +537,13 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name,
else
UserConfigParams::m_num_goals = m_target_value_spinner->getValue();
}
else if (m_show_ffa_spinner)
{
const bool enable_ffa = m_target_type_spinner->getValue() != 0;
if (enable_ffa)
UserConfigParams::m_ffa_time_limit = m_target_value_spinner->getValue();
}
else
{
assert(race_manager->modeHasLaps());
@ -532,7 +587,6 @@ void TrackInfoScreen::eventCallback(Widget* widget, const std::string& name,
else if (name=="ai-spinner")
{
const int num_ai = m_ai_kart_spinner->getValue();
race_manager->setNumKarts( race_manager->getNumLocalPlayers() + num_ai );
UserConfigParams::m_num_karts_per_gamemode[race_manager->getMinorMode()] = race_manager->getNumLocalPlayers() + num_ai;
updateHighScores();
}

View File

@ -46,6 +46,10 @@ class TrackInfoScreen : public GUIEngine::Screen,
bool m_record_this_race;
bool m_is_soccer;
bool m_show_ffa_spinner;
// When there is no need to tab through / click on images/labels, we can add directly
// irrlicht labels (more complicated uses require the use of our widget set)
@ -67,6 +71,9 @@ class TrackInfoScreen : public GUIEngine::Screen,
/** Spinner for number of AI karts. */
GUIEngine::SpinnerWidget* m_ai_kart_spinner;
/** The label besides the AI karts spinner. */
GUIEngine::LabelWidget* m_ai_kart_label;
/** Check box for reverse mode or random item in arena. */
GUIEngine::CheckBoxWidget* m_option;