Add grandprix highscore (#4566)

This commit is contained in:
Kuba 2021-08-02 05:38:07 +02:00 committed by GitHub
parent 0db347739e
commit 0b45ac9fd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 199 additions and 41 deletions

View File

@ -49,10 +49,16 @@
</div>
</box>
<spacer width="2%" height="1"/>
<!-- Track list -->
<box width="43%" height="100%" layout="vertical-row">
<list id="tracks" width="100%" height="100%"/>
</box>
<div width="43%" height="100%" layout="vertical-row">
<!-- Track list -->
<box width="100%" height="49%" layout="vertical-row">
<list id="tracks" width="100%" height="100%"/>
</box>
<spacer width="1" height="2%" layout="vertical-row"/>
<box width="100%" height="49%" layout="vertical-row">
<list id="highscore-entries" width="100%" height="100%"/>
</box>
</div>
</div>
<spacer width="1" height="1%"/>

View File

@ -1277,6 +1277,21 @@ Highscores* World::getHighscores() const
return highscores;
} // getHighscores
// ---------------------------------------------------------------------------
Highscores* World::getGPHighscores() const
{
if (isNetworkWorld() || RaceManager::get()->getMajorMode() != RaceManager::MAJOR_MODE_GRAND_PRIX)
return NULL;
const Highscores::HighscoreType type = "HST_GRANDPRIX";
Highscores* highscores = highscore_manager->getHighscores(type,
RaceManager::get()->getNumNonGhostKarts(),
RaceManager::get()->getDifficulty(),
RaceManager::get()->getGrandPrix().getId(),
0,
RaceManager::get()->getGrandPrix().getReverseType() == GrandPrixData::GP_ALL_REVERSE);
return highscores;
}
// ----------------------------------------------------------------------------
/** Called at the end of a race. Checks if the current times are worth a new
* score, if so it notifies the HighscoreManager so the new score is added

View File

@ -315,6 +315,7 @@ public:
// Other functions
// ===============
Highscores *getHighscores() const;
Highscores *getGPHighscores() const;
void schedulePause(Phase phase);
void scheduleUnpause();
void scheduleExitRace() { m_schedule_exit_race = true; }

View File

@ -159,14 +159,8 @@ int Highscores::matches(const HighscoreType &highscore_type,
m_reverse == reverse );
} // matches
// -----------------------------------------------------------------------------
/** Inserts the data into the highscore list.
* If the new entry is fast enough to
* be in the highscore list, the new position (1-HIGHSCORE_LEN) is returned,
* otherwise a 0.
*/
int Highscores::addData(const std::string& kart_name,
const core::stringw& name, const float time)
int Highscores::findHighscorePosition(const std::string& kart_name,
const core::stringw& name, const float time)
{
int position=-1;
for(int i=0; i<HIGHSCORE_LEN; i++)
@ -191,7 +185,19 @@ int Highscores::addData(const std::string& kart_name,
break;
}
}//next score slot
return position;
}
// -----------------------------------------------------------------------------
/** Inserts the data into the highscore list.
* If the new entry is fast enough to
* be in the highscore list, the new position (1-HIGHSCORE_LEN) is returned,
* otherwise a 0.
*/
int Highscores::addData(const std::string& kart_name,
const core::stringw& name, const float time)
{
int position = findHighscorePosition(kart_name, name, time);
if(position>=0)
{
m_track = RaceManager::get()->getTrackName();
@ -206,6 +212,25 @@ int Highscores::addData(const std::string& kart_name,
return position+1;
} // addData
// -----------------------------------------------------------------------------
int Highscores::addGPData(const std::string& kart_name,
const core::stringw& name, std::string track_name, const float time)
{
int position = findHighscorePosition(kart_name, name, time);
if(position>=0)
{
m_track = track_name;
m_number_of_karts = RaceManager::get()->getNumNonGhostKarts();
m_difficulty = RaceManager::get()->getDifficulty();
m_number_of_laps = 0;
m_reverse = RaceManager::get()->getReverseTrack();
m_name[position] = name;
m_time[position] = time;
m_kart_name[position] = kart_name;
}
return position+1;
}
// -----------------------------------------------------------------------------
int Highscores::getNumberEntries() const

View File

@ -68,6 +68,9 @@ private:
static SortOrder m_sort_order;
int findHighscorePosition(const std::string& kart_name,
const core::stringw& name, const float time);
public:
bool operator < (const Highscores& hi) const;
@ -93,6 +96,8 @@ public:
// ------------------------------------------------------------------------
int addData (const std::string& kart_name,
const irr::core::stringw& name, const float time);
int addGPData (const std::string& kart_name,
const irr::core::stringw& name, std::string gp_name, const float time);
// ------------------------------------------------------------------------
int getNumberEntries() const;
// ------------------------------------------------------------------------

View File

@ -23,6 +23,8 @@
#include "config/player_manager.hpp"
#include "config/saved_grand_prix.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/widgets/icon_button_widget.hpp"
@ -34,11 +36,14 @@
#include "race/grand_prix_manager.hpp"
#include "race/grand_prix_data.hpp"
#include "race/race_manager.hpp"
#include "race/highscore_manager.hpp"
#include "states_screens/state_manager.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
#include "karts/kart_properties_manager.hpp"
#include "karts/kart_properties.hpp"
#include <IGUIEnvironment.h>
#include <IGUIStaticText.h>
@ -85,6 +90,18 @@ void GPInfoScreen::loadedFromFile()
GUIEngine::IconButtonWidget* screenshot = getWidget<IconButtonWidget>("screenshot");
screenshot->setFocusable(false);
screenshot->m_tab_stop = false;
m_highscore_list = getWidget<ListWidget>("highscore-entries");
m_icon_bank = new irr::gui::STKModifiedSpriteBank(GUIEngine::getGUIEnv());
for(unsigned int i=0; i < kart_properties_manager->getNumberOfKarts(); i++)
{
const KartProperties* prop = kart_properties_manager->getKartById(i);
m_icon_bank->addTextureAsSprite(prop->getIconMaterial()->getTexture());
}
video::ITexture* kart_not_found = irr_driver->getTexture(file_manager->getAsset(FileManager::GUI_ICON, "random_kart.png"));
m_unknown_kart_icon = m_icon_bank->addTextureAsSprite(kart_not_found);
} // loadedFromFile
// ----------------------------------------------------------------------------
@ -93,8 +110,9 @@ void GPInfoScreen::loadedFromFile()
*/
void GPInfoScreen::setGP(const std::string &gp_ident)
{
if(gp_ident!=GrandPrixData::getRandomGPID())
if(gp_ident!=GrandPrixData::getRandomGPID()){
m_gp = *grand_prix_manager->getGrandPrix(gp_ident);
}
else
{
// Doesn't matter what kind of GP we create, it just gets the
@ -172,6 +190,31 @@ void GPInfoScreen::init()
getWidget<LabelWidget >("group-text" )->setVisible(random);
m_group_spinner->setVisible(random);
// Number of AIs
// -------------
const bool has_AI = RaceManager::get()->hasAI();
m_ai_kart_spinner->setVisible(has_AI);
getWidget<LabelWidget>("ai-text")->setVisible(has_AI);
if (has_AI)
{
const int local_players = RaceManager::get()->getNumLocalPlayers();
int min_ai = 0;
int num_ai = int(UserConfigParams::m_num_karts_per_gamemode
[RaceManager::MAJOR_MODE_GRAND_PRIX]) - local_players;
// A ftl reace needs at least three karts to make any sense
if (RaceManager::get()->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER)
{
min_ai = std::max(0, 3 - local_players);
}
num_ai = std::max(min_ai, num_ai);
m_ai_kart_spinner->setActive(true);
m_ai_kart_spinner->setValue(num_ai);
m_ai_kart_spinner->setMax(stk_config->m_max_karts - local_players);
m_ai_kart_spinner->setMin(min_ai);
} // has_AI
if(random)
{
@ -222,35 +265,17 @@ void GPInfoScreen::init()
{
getWidget<LabelWidget>("name")->setText(m_gp.getName(), false);
m_gp.checkConsistency();
int icon_height = GUIEngine::getFontHeight();
int row_height = GUIEngine::getFontHeight() * 1.2f;
m_icon_bank->setScale(icon_height/128.0f);
m_icon_bank->setTargetIconSize(128,128);
m_highscore_list->setIcons(m_icon_bank,row_height);
RaceManager::get()->setNumKarts(RaceManager::get()->getNumLocalPlayers() + m_ai_kart_spinner->getValue());
// We don't save highscores for random gps so load highscores here
updateHighscores();
}
// Number of AIs
// -------------
const bool has_AI = RaceManager::get()->hasAI();
m_ai_kart_spinner->setVisible(has_AI);
getWidget<LabelWidget>("ai-text")->setVisible(has_AI);
if (has_AI)
{
const int local_players = RaceManager::get()->getNumLocalPlayers();
int min_ai = 0;
int num_ai = int(UserConfigParams::m_num_karts_per_gamemode
[RaceManager::MAJOR_MODE_GRAND_PRIX]) - local_players;
// A ftl reace needs at least three karts to make any sense
if (RaceManager::get()->getMinorMode()==RaceManager::MINOR_MODE_FOLLOW_LEADER)
{
min_ai = std::max(0, 3 - local_players);
}
num_ai = std::max(min_ai, num_ai);
m_ai_kart_spinner->setActive(true);
m_ai_kart_spinner->setValue(num_ai);
m_ai_kart_spinner->setMax(stk_config->m_max_karts - local_players);
m_ai_kart_spinner->setMin(min_ai);
} // has_AI
addTracks();
addScreenshot();
@ -360,11 +385,16 @@ void GPInfoScreen::eventCallback(Widget *, const std::string &name,
const int num_ai = m_ai_kart_spinner->getValue();
RaceManager::get()->setNumKarts( RaceManager::get()->getNumLocalPlayers() + num_ai );
UserConfigParams::m_num_karts_per_gamemode[RaceManager::MAJOR_MODE_GRAND_PRIX] = RaceManager::get()->getNumLocalPlayers() + num_ai;
updateHighscores();
}
else if(name=="back")
{
StateManager::get()->escapePressed();
}
else if(name=="reverse-spinner")
{
updateHighscores();
}
} // eventCallback
@ -430,4 +460,54 @@ int GPInfoScreen::getMaxNumTracks(std::string group)
}
return max_num_tracks;
}
} // getNumTracks
// -----------------------------------------------------------------------
void GPInfoScreen::updateHighscores()
{
if(m_gp.isRandomGP())
return;
const Highscores::HighscoreType type = "HST_GRANDPRIX";
Highscores* highscores = highscore_manager->getHighscores(type,
RaceManager::get()->getNumberOfKarts(),
RaceManager::get()->getDifficulty(),
m_gp.getId(),
0,
getReverse() == GrandPrixData::GP_ALL_REVERSE);
m_highscore_list->clear();
int count = highscores->getNumberEntries();
std::string kart;
irr::core::stringw name;
float time;
for(int i=0; i<Highscores::HIGHSCORE_LEN; i++)
{
irr::core::stringw line;
int icon = -1;
if(i < count)
{
highscores->getEntry(i, kart, name, &time);
std::string time_string = StringUtils::timeToString(time);
for(unsigned int n=0; n<kart_properties_manager->getNumberOfKarts(); n++)
{
const KartProperties* prop = kart_properties_manager->getKartById(n);
if(kart == prop->getIdent())
{
icon = n;
break;
}
}
line = name + " " + irr::core::stringw(time_string.c_str());
}
else
{
line = _("(Empty)");
}
if(icon == -1)
{
icon = m_unknown_kart_icon;
}
std::vector<ListWidget::ListCell> row;
row.push_back(ListWidget::ListCell(line, icon, 1, false));
m_highscore_list->addItem(StringUtils::toString(i),row);
}
} // updateHighscores

View File

@ -22,6 +22,7 @@
#include "guiengine/screen.hpp"
#include "race/grand_prix_data.hpp"
#include "guiengine/CGUISpriteBank.hpp"
#include <vector>
@ -31,6 +32,7 @@ namespace GUIEngine
{
class IconButtonWidget;
class SpinnerWidget;
class ListWidget;
}
/**
@ -53,6 +55,9 @@ private:
/** Spinner for number of AI karts. */
GUIEngine::SpinnerWidget* m_ai_kart_spinner;
/** List with last 5 highscores */
GUIEngine::ListWidget* m_highscore_list;
/** The currently selected group name. */
std::string m_group_name;
@ -62,9 +67,16 @@ private:
/** Number of available tracks */
int m_max_num_tracks;
irr::gui::STKModifiedSpriteBank* m_icon_bank;
/** Icon for unknown kart in highscore list */
int m_unknown_kart_icon;
/** Get number of available tracks for random GPs */
int getMaxNumTracks(std::string group);
/** Load highscores for grandprix */
void updateHighscores();
protected: // Necessary for RandomGPInfoScreen
float m_curr_time;

View File

@ -54,6 +54,7 @@
#include "network/stk_host.hpp"
#include "network/protocols/client_lobby.hpp"
#include "race/highscores.hpp"
#include "race/highscore_manager.hpp"
#include "replay/replay_play.hpp"
#include "replay/replay_recorder.hpp"
#include "scriptengine/property_animator.hpp"
@ -201,6 +202,19 @@ void RaceResultGUI::init()
MessageQueue::add(MessageQueue::MT_GENERIC, tips_string);
}
#endif
if(RaceManager::get()->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
{
if(RaceManager::get()->getNumOfTracks() == RaceManager::get()->getTrackNumber() + 1
&& !RaceManager::get()->getGrandPrix().isRandomGP())
{
Highscores* highscores = World::getWorld()->getGPHighscores();
const AbstractKart* k = RaceManager::get()->getKartWithGPRank(RaceManager::get()->getLocalPlayerGPRank(PLAYER_ID_GAME_MASTER));
float full_time = RaceManager::get()->getOverallTime(RaceManager::get()->getLocalPlayerGPRank(PLAYER_ID_GAME_MASTER));
std::string gp_name = RaceManager::get()->getGrandPrix().getId();
highscores->addGPData(k->getIdent(), k->getController()->getName(), gp_name, full_time);
}
}
} // init
//-----------------------------------------------------------------------------