Merge branch 'a' of https://github.com/konstin/stk-code into konstin-a
This commit is contained in:
commit
c222bbcb1c
@ -376,8 +376,7 @@ void ChallengeData::setRace(RaceManager::Difficulty d) const
|
|||||||
else if(m_mode==CM_GRAND_PRIX)
|
else if(m_mode==CM_GRAND_PRIX)
|
||||||
{
|
{
|
||||||
race_manager->setMinorMode(m_minor);
|
race_manager->setMinorMode(m_minor);
|
||||||
const GrandPrixData *gp = grand_prix_manager->getGrandPrix(m_gp_id);
|
race_manager->setGrandPrix(grand_prix_manager->getGrandPrix(m_gp_id));
|
||||||
race_manager->setGrandPrix(*gp);
|
|
||||||
race_manager->setDifficulty(d);
|
race_manager->setDifficulty(d);
|
||||||
race_manager->setNumKarts(m_num_karts[d]);
|
race_manager->setNumKarts(m_num_karts[d]);
|
||||||
race_manager->setNumLocalPlayers(1);
|
race_manager->setNumLocalPlayers(1);
|
||||||
|
@ -160,7 +160,7 @@ void SpinnerWidget::add()
|
|||||||
{
|
{
|
||||||
label->setText(m_labels[m_value].c_str() );
|
label->setText(m_labels[m_value].c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ void SpinnerWidget::add()
|
|||||||
m_children[2].m_id = m_children[2].m_element->getID();
|
m_children[2].m_id = m_children[2].m_element->getID();
|
||||||
|
|
||||||
// refresh display
|
// refresh display
|
||||||
|
|
||||||
|
|
||||||
setValue(m_value);
|
setValue(m_value);
|
||||||
}
|
}
|
||||||
@ -333,7 +333,7 @@ void SpinnerWidget::setValue(const int new_value)
|
|||||||
assert(new_value >= 0);
|
assert(new_value >= 0);
|
||||||
assert(new_value < (int)m_labels.size());
|
assert(new_value < (int)m_labels.size());
|
||||||
|
|
||||||
m_children[1].m_element->setText(m_labels[new_value].c_str() );
|
m_children[1].m_element->setText(m_labels[new_value].c_str());
|
||||||
}
|
}
|
||||||
else if (m_text.size() > 0 && m_children.size() > 0)
|
else if (m_text.size() > 0 && m_children.size() > 0)
|
||||||
{
|
{
|
||||||
|
@ -847,14 +847,14 @@ int handleCmdLine()
|
|||||||
if(CommandLine::has("--gp", &s))
|
if(CommandLine::has("--gp", &s))
|
||||||
{
|
{
|
||||||
race_manager->setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX);
|
race_manager->setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX);
|
||||||
const GrandPrixData *gp = grand_prix_manager->getGrandPrix(s);
|
GrandPrixData *gp = grand_prix_manager->getGrandPrix(s);
|
||||||
|
|
||||||
if (!gp)
|
if (!gp)
|
||||||
{
|
{
|
||||||
Log::warn("main", "There is no GP named '%s'.", s.c_str());
|
Log::warn("main", "There is no GP named '%s'.", s.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
race_manager->setGrandPrix(*gp);
|
race_manager->setGrandPrix(gp);
|
||||||
} // --gp
|
} // --gp
|
||||||
|
|
||||||
if(CommandLine::has("--numkarts", &n) ||CommandLine::has("-k", &n))
|
if(CommandLine::has("--numkarts", &n) ||CommandLine::has("-k", &n))
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include "race/race_manager.hpp"
|
#include "race/race_manager.hpp"
|
||||||
#include "utils/log.hpp"
|
#include "utils/log.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
/** \brief Gets the element with the highest count in a std::map<S,int>.
|
/** \brief Gets the element with the highest count in a std::map<S,int>.
|
||||||
* \param histogram : A pointer to the histogram.
|
* \param histogram : A pointer to the histogram.
|
||||||
* \return The key of type S that has the highest second value.
|
* \return The key of type S that has the highest second value.
|
||||||
|
@ -24,13 +24,15 @@
|
|||||||
#include "config/player_manager.hpp"
|
#include "config/player_manager.hpp"
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "io/utf_writer.hpp"
|
#include "io/utf_writer.hpp"
|
||||||
|
#include "states_screens/dialogs/random_gp_dialog.hpp"
|
||||||
#include "tracks/track_manager.hpp"
|
#include "tracks/track_manager.hpp"
|
||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
#include "utils/string_utils.hpp"
|
#include "utils/string_utils.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
|
||||||
@ -44,6 +46,94 @@ GrandPrixData::GrandPrixData(const std::string& filename)
|
|||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
GrandPrixData::GrandPrixData(const unsigned int number_of_tracks,
|
||||||
|
const std::string& track_group,
|
||||||
|
const RandomGPInfoDialog::REVERSED use_reverse)
|
||||||
|
{
|
||||||
|
m_filename = "Random GP - Not loaded from a file!";
|
||||||
|
m_id = "random";
|
||||||
|
m_name = "Random Grand Prix";
|
||||||
|
m_editable = false;
|
||||||
|
|
||||||
|
m_tracks.reserve(number_of_tracks);
|
||||||
|
m_laps.reserve(number_of_tracks);
|
||||||
|
m_reversed.reserve(number_of_tracks);
|
||||||
|
|
||||||
|
changeTrackNumber(number_of_tracks, track_group);
|
||||||
|
changeReverse(use_reverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void GrandPrixData::changeTrackNumber(const unsigned int number_of_tracks,
|
||||||
|
const std::string& track_group)
|
||||||
|
{
|
||||||
|
// The problem with the track groups is that "all" isn't a track group
|
||||||
|
// TODO: Add "all" to the track groups and rewrite this more elegant
|
||||||
|
std::vector<int> track_indices;
|
||||||
|
size_t available_tracks;
|
||||||
|
if (track_group == "all")
|
||||||
|
{
|
||||||
|
available_tracks = track_manager->getNumberOfTracks();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
track_indices = track_manager->getTracksInGroup(track_group);
|
||||||
|
available_tracks = track_indices.size();
|
||||||
|
}
|
||||||
|
assert(number_of_tracks <= available_tracks);
|
||||||
|
|
||||||
|
// add or remove the right number of tracks
|
||||||
|
if (m_tracks.size() < number_of_tracks)
|
||||||
|
{
|
||||||
|
while (m_tracks.size() < number_of_tracks)
|
||||||
|
{
|
||||||
|
int index = (track_group == "all") ?
|
||||||
|
rand() % available_tracks :
|
||||||
|
track_indices[rand() % available_tracks];
|
||||||
|
|
||||||
|
std::string id = track_manager->getTrack(index)->getIdent();
|
||||||
|
// Avoid duplicate tracks
|
||||||
|
if (std::find(m_tracks.begin(), m_tracks.end(), id) != m_tracks.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_tracks.push_back(id);
|
||||||
|
m_laps.push_back(3); // TODO: Take the default number from the track
|
||||||
|
m_reversed.push_back(false); // This will be changed later
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_tracks.size() > number_of_tracks)
|
||||||
|
{
|
||||||
|
while (m_tracks.size() > number_of_tracks)
|
||||||
|
{
|
||||||
|
m_tracks.pop_back();
|
||||||
|
m_laps.pop_back();
|
||||||
|
m_reversed.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(m_tracks.size() == m_laps.size() );
|
||||||
|
assert(m_laps.size() == m_reversed.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void GrandPrixData::changeReverse(const RandomGPInfoDialog::REVERSED use_reverse)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < m_tracks.size(); i++)
|
||||||
|
{
|
||||||
|
if (use_reverse == RandomGPInfoDialog::NO_REVERSE)
|
||||||
|
m_reversed[i] = false;
|
||||||
|
else if (use_reverse == RandomGPInfoDialog::MIXED)
|
||||||
|
if (track_manager->getTrack(m_tracks[i])->reverseAvailable())
|
||||||
|
m_reversed[i] = rand() % 2;
|
||||||
|
else
|
||||||
|
m_reversed[i] = false;
|
||||||
|
else // all reversed
|
||||||
|
m_reversed[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void GrandPrixData::setId(const std::string& id)
|
void GrandPrixData::setId(const std::string& id)
|
||||||
{
|
{
|
||||||
|
@ -20,14 +20,15 @@
|
|||||||
#ifndef HEADER_GRAND_PRIX_DATA_HPP
|
#ifndef HEADER_GRAND_PRIX_DATA_HPP
|
||||||
#define HEADER_GRAND_PRIX_DATA_HPP
|
#define HEADER_GRAND_PRIX_DATA_HPP
|
||||||
|
|
||||||
|
#include <irrString.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cassert>
|
|
||||||
#include <irrString.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
|
#include "states_screens/dialogs/random_gp_dialog.hpp"
|
||||||
#include "utils/translation.hpp"
|
#include "utils/translation.hpp"
|
||||||
|
|
||||||
|
using irr::core::stringw;
|
||||||
|
|
||||||
class Track;
|
class Track;
|
||||||
|
|
||||||
/** Simple class that hold the data relevant to a 'grand_prix', aka. a number
|
/** Simple class that hold the data relevant to a 'grand_prix', aka. a number
|
||||||
@ -76,6 +77,13 @@ public:
|
|||||||
GrandPrixData(const std::string& filename);
|
GrandPrixData(const std::string& filename);
|
||||||
/** Needed for simple creation of an instance of GrandPrixData */
|
/** Needed for simple creation of an instance of GrandPrixData */
|
||||||
GrandPrixData() {};
|
GrandPrixData() {};
|
||||||
|
/** Creates a new random GP */
|
||||||
|
GrandPrixData(const unsigned int number_of_tracks,
|
||||||
|
const std::string& track_group,
|
||||||
|
const RandomGPInfoDialog::REVERSED use_reverse);
|
||||||
|
void changeTrackNumber(const unsigned int number_of_tracks,
|
||||||
|
const std::string& track_group);
|
||||||
|
void changeReverse(const RandomGPInfoDialog::REVERSED use_reverse);
|
||||||
|
|
||||||
// Methods for the GP editor
|
// Methods for the GP editor
|
||||||
void setId(const std::string& id);
|
void setId(const std::string& id);
|
||||||
@ -117,7 +125,6 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Returns the filename of the grand prix xml file. */
|
/** Returns the filename of the grand prix xml file. */
|
||||||
const std::string& getFilename() const { return m_filename; }
|
const std::string& getFilename() const { return m_filename; }
|
||||||
|
|
||||||
}; // GrandPrixData
|
}; // GrandPrixData
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,6 +31,24 @@ GrandPrixManager *grand_prix_manager = NULL;
|
|||||||
|
|
||||||
const char* GrandPrixManager::SUFFIX = ".grandprix";
|
const char* GrandPrixManager::SUFFIX = ".grandprix";
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
GrandPrixManager::GrandPrixManager()
|
||||||
|
{
|
||||||
|
m_random_gp = NULL; // better do it explicitly and avoid weird stuff
|
||||||
|
loadFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
GrandPrixManager::~GrandPrixManager()
|
||||||
|
{
|
||||||
|
for(unsigned int i=0; i<m_gp_data.size(); i++)
|
||||||
|
{
|
||||||
|
delete m_gp_data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_random_gp;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void GrandPrixManager::loadFiles()
|
void GrandPrixManager::loadFiles()
|
||||||
{
|
{
|
||||||
@ -130,21 +148,6 @@ bool GrandPrixManager::existsName(const irr::core::stringw& name) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
GrandPrixManager::GrandPrixManager()
|
|
||||||
{
|
|
||||||
loadFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
GrandPrixManager::~GrandPrixManager()
|
|
||||||
{
|
|
||||||
for(unsigned int i=0; i<m_gp_data.size(); i++)
|
|
||||||
{
|
|
||||||
delete m_gp_data[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
GrandPrixData* GrandPrixManager::getGrandPrix(const std::string& s) const
|
GrandPrixData* GrandPrixManager::getGrandPrix(const std::string& s) const
|
||||||
{
|
{
|
||||||
@ -154,6 +157,9 @@ GrandPrixData* GrandPrixManager::getGrandPrix(const std::string& s) const
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
GrandPrixData* GrandPrixManager::editGrandPrix(const std::string& s) const
|
GrandPrixData* GrandPrixManager::editGrandPrix(const std::string& s) const
|
||||||
{
|
{
|
||||||
|
if (s == "random")
|
||||||
|
return m_random_gp;
|
||||||
|
|
||||||
for(unsigned int i=0; i<m_gp_data.size(); i++)
|
for(unsigned int i=0; i<m_gp_data.size(); i++)
|
||||||
{
|
{
|
||||||
if(m_gp_data[i]->getId() == s)
|
if(m_gp_data[i]->getId() == s)
|
||||||
|
@ -47,6 +47,10 @@ private:
|
|||||||
bool existsName(const irr::core::stringw& name) const;
|
bool existsName(const irr::core::stringw& name) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/** saved here by a random GP dialog to avoid dangling pinters or
|
||||||
|
* memory leaks */
|
||||||
|
GrandPrixData* m_random_gp;
|
||||||
|
|
||||||
GrandPrixManager();
|
GrandPrixManager();
|
||||||
~GrandPrixManager();
|
~GrandPrixManager();
|
||||||
void reload();
|
void reload();
|
||||||
|
@ -283,9 +283,9 @@ void RaceManager::startNew(bool from_overworld)
|
|||||||
if(m_major_mode==MAJOR_MODE_GRAND_PRIX)
|
if(m_major_mode==MAJOR_MODE_GRAND_PRIX)
|
||||||
{
|
{
|
||||||
// GP: get tracks, laps and reverse info from grand prix
|
// GP: get tracks, laps and reverse info from grand prix
|
||||||
m_tracks = m_grand_prix.getTrackNames();
|
m_tracks = m_grand_prix->getTrackNames();
|
||||||
m_num_laps = m_grand_prix.getLaps();
|
m_num_laps = m_grand_prix->getLaps();
|
||||||
m_reverse_track = m_grand_prix.getReverse();
|
m_reverse_track = m_grand_prix->getReverse();
|
||||||
}
|
}
|
||||||
//assert(m_player_karts.size() > 0);
|
//assert(m_player_karts.size() > 0);
|
||||||
|
|
||||||
@ -348,7 +348,7 @@ void RaceManager::startNew(bool from_overworld)
|
|||||||
SavedGrandPrix* gp = SavedGrandPrix::getSavedGP( StateManager::get()
|
SavedGrandPrix* gp = SavedGrandPrix::getSavedGP( StateManager::get()
|
||||||
->getActivePlayerProfile(0)
|
->getActivePlayerProfile(0)
|
||||||
->getUniqueID(),
|
->getUniqueID(),
|
||||||
m_grand_prix.getId(),
|
m_grand_prix->getId(),
|
||||||
m_difficulty,
|
m_difficulty,
|
||||||
m_num_karts,
|
m_num_karts,
|
||||||
m_player_karts.size());
|
m_player_karts.size());
|
||||||
@ -499,7 +499,7 @@ void RaceManager::next()
|
|||||||
SavedGrandPrix::getSavedGP(StateManager::get()
|
SavedGrandPrix::getSavedGP(StateManager::get()
|
||||||
->getActivePlayerProfile(0)
|
->getActivePlayerProfile(0)
|
||||||
->getUniqueID(),
|
->getUniqueID(),
|
||||||
m_grand_prix.getId(),
|
m_grand_prix->getId(),
|
||||||
m_difficulty,
|
m_difficulty,
|
||||||
m_num_karts,
|
m_num_karts,
|
||||||
m_player_karts.size());
|
m_player_karts.size());
|
||||||
@ -516,7 +516,7 @@ void RaceManager::next()
|
|||||||
new SavedGrandPrix(
|
new SavedGrandPrix(
|
||||||
StateManager::get()->getActivePlayerProfile(0)
|
StateManager::get()->getActivePlayerProfile(0)
|
||||||
->getUniqueID(),
|
->getUniqueID(),
|
||||||
m_grand_prix.getId(),
|
m_grand_prix->getId(),
|
||||||
m_difficulty,
|
m_difficulty,
|
||||||
m_player_karts.size(),
|
m_player_karts.size(),
|
||||||
m_track_number,
|
m_track_number,
|
||||||
@ -635,7 +635,7 @@ void RaceManager::exitRace(bool delete_world)
|
|||||||
SavedGrandPrix::getSavedGP(StateManager::get()
|
SavedGrandPrix::getSavedGP(StateManager::get()
|
||||||
->getActivePlayerProfile(0)
|
->getActivePlayerProfile(0)
|
||||||
->getUniqueID(),
|
->getUniqueID(),
|
||||||
m_grand_prix.getId(),
|
m_grand_prix->getId(),
|
||||||
m_difficulty,
|
m_difficulty,
|
||||||
m_num_karts,
|
m_num_karts,
|
||||||
m_player_karts.size());
|
m_player_karts.size());
|
||||||
@ -767,13 +767,14 @@ void RaceManager::rerunRace()
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void RaceManager::startGP(const GrandPrixData* gp, bool from_overworld,
|
void RaceManager::startGP(GrandPrixData* gp, bool from_overworld,
|
||||||
bool continue_saved_gp)
|
bool continue_saved_gp)
|
||||||
{
|
{
|
||||||
assert(gp != NULL);
|
assert(gp != NULL);
|
||||||
|
//std::cout << gp->getId();
|
||||||
|
|
||||||
StateManager::get()->enterGameState();
|
StateManager::get()->enterGameState();
|
||||||
setGrandPrix(*gp);
|
setGrandPrix(gp);
|
||||||
setCoinTarget( 0 ); // Might still be set from a previous challenge
|
setCoinTarget( 0 ); // Might still be set from a previous challenge
|
||||||
race_manager->setupPlayerKartInfo();
|
race_manager->setupPlayerKartInfo();
|
||||||
m_continue_saved_gp = continue_saved_gp;
|
m_continue_saved_gp = continue_saved_gp;
|
||||||
|
@ -324,14 +324,14 @@ private:
|
|||||||
* same list of AIs is used for all tracks of a GP. */
|
* same list of AIs is used for all tracks of a GP. */
|
||||||
std::vector<std::string> m_ai_kart_list;
|
std::vector<std::string> m_ai_kart_list;
|
||||||
int m_track_number;
|
int m_track_number;
|
||||||
GrandPrixData m_grand_prix;
|
GrandPrixData* m_grand_prix;
|
||||||
int m_num_karts;
|
int m_num_karts;
|
||||||
unsigned int m_num_finished_karts;
|
unsigned int m_num_finished_karts;
|
||||||
unsigned int m_num_finished_players;
|
unsigned int m_num_finished_players;
|
||||||
int m_coin_target;
|
int m_coin_target;
|
||||||
bool m_has_time_target;
|
bool m_has_time_target;
|
||||||
float m_time_target;
|
float m_time_target;
|
||||||
int m_goal_target;
|
int m_goal_target;
|
||||||
|
|
||||||
void startNextRace(); // start a next race
|
void startNextRace(); // start a next race
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ private:
|
|||||||
|
|
||||||
bool m_have_kart_last_position_on_overworld;
|
bool m_have_kart_last_position_on_overworld;
|
||||||
Vec3 m_kart_last_position_on_overworld;
|
Vec3 m_kart_last_position_on_overworld;
|
||||||
|
|
||||||
/** Determines if saved GP should be continued or not*/
|
/** Determines if saved GP should be continued or not*/
|
||||||
bool m_continue_saved_gp;
|
bool m_continue_saved_gp;
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ public:
|
|||||||
void setDifficulty(Difficulty diff);
|
void setDifficulty(Difficulty diff);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setGrandPrix(const GrandPrixData &gp)
|
void setGrandPrix(GrandPrixData* gp)
|
||||||
{
|
{
|
||||||
m_grand_prix = gp;
|
m_grand_prix = gp;
|
||||||
m_coin_target = 0;
|
m_coin_target = 0;
|
||||||
@ -525,7 +525,7 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
const std::string& getTrackName() const { return m_tracks[m_track_number];}
|
const std::string& getTrackName() const { return m_tracks[m_track_number];}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
const GrandPrixData *getGrandPrix() const { return &m_grand_prix; }
|
GrandPrixData* getGrandPrix() const { return m_grand_prix; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
unsigned int getFinishedKarts() const { return m_num_finished_karts; }
|
unsigned int getFinishedKarts() const { return m_num_finished_karts; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -682,7 +682,7 @@ public:
|
|||||||
* \brief Higher-level method to start a GP without having to care about
|
* \brief Higher-level method to start a GP without having to care about
|
||||||
* the exact startup sequence
|
* the exact startup sequence
|
||||||
*/
|
*/
|
||||||
void startGP(const GrandPrixData* gp, bool from_overworld,
|
void startGP(GrandPrixData* gp, bool from_overworld,
|
||||||
bool continue_saved_gp);
|
bool continue_saved_gp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,7 +81,7 @@ void EnterGPNameDialog::onEnterPressedInternal()
|
|||||||
TextBoxWidget* textCtrl = getWidget<TextBoxWidget>("textfield");
|
TextBoxWidget* textCtrl = getWidget<TextBoxWidget>("textfield");
|
||||||
assert(textCtrl != NULL);
|
assert(textCtrl != NULL);
|
||||||
stringw name = textCtrl->getText().trim();
|
stringw name = textCtrl->getText().trim();
|
||||||
if (name.size() > 0)
|
if (name.size() > 0 && name != "Random Grand Prix")
|
||||||
{
|
{
|
||||||
// check for duplicate names
|
// check for duplicate names
|
||||||
for (unsigned int i = 0; i < grand_prix_manager->getNumberOfGrandPrix(); i++)
|
for (unsigned int i = 0; i < grand_prix_manager->getNumberOfGrandPrix(); i++)
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "guiengine/widgets/label_widget.hpp"
|
#include "guiengine/widgets/label_widget.hpp"
|
||||||
#include "io/file_manager.hpp"
|
#include "io/file_manager.hpp"
|
||||||
#include "race/grand_prix_manager.hpp"
|
#include "race/grand_prix_manager.hpp"
|
||||||
|
#include "race/grand_prix_data.hpp"
|
||||||
#include "race/race_manager.hpp"
|
#include "race/race_manager.hpp"
|
||||||
#include "states_screens/state_manager.hpp"
|
#include "states_screens/state_manager.hpp"
|
||||||
#include "states_screens/tracks_screen.hpp"
|
#include "states_screens/tracks_screen.hpp"
|
||||||
@ -35,143 +36,187 @@
|
|||||||
#include "tracks/track_manager.hpp"
|
#include "tracks/track_manager.hpp"
|
||||||
#include "utils/translation.hpp"
|
#include "utils/translation.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <IGUIEnvironment.h>
|
#include <IGUIEnvironment.h>
|
||||||
#include <IGUIStaticText.h>
|
#include <IGUIStaticText.h>
|
||||||
|
|
||||||
using namespace irr::gui;
|
using irr::gui::IGUIStaticText;
|
||||||
using namespace irr::video;
|
using GUIEngine::PROP_ID;
|
||||||
using namespace irr::core;
|
|
||||||
using namespace GUIEngine;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------
|
typedef GUIEngine::LabelWidget Label;
|
||||||
|
|
||||||
GPInfoDialog::GPInfoDialog(const std::string& gpIdent, const float w, const float h) : ModalDialog(w, h)
|
GPInfoDialog::GPInfoDialog(const std::string& gp_ident) :
|
||||||
|
ModalDialog(PERCENT_WIDTH, PERCENT_HEIGHT)
|
||||||
{
|
{
|
||||||
doInit();
|
doInit();
|
||||||
m_curr_time = 0.0f;
|
m_curr_time = 0.0f;
|
||||||
|
|
||||||
const int y1 = m_area.getHeight()/7;
|
m_gp = grand_prix_manager->getGrandPrix(gp_ident);
|
||||||
const int y2 = m_area.getHeight()*6/7;
|
m_gp->checkConsistency();
|
||||||
|
|
||||||
m_gp_ident = gpIdent;
|
m_under_title = m_area.getHeight()/7;
|
||||||
|
m_over_body = m_area.getHeight()/7;
|
||||||
|
m_lower_bound = m_area.getHeight()*6/7;
|
||||||
|
|
||||||
const GrandPrixData* gp = grand_prix_manager->getGrandPrix(gpIdent);
|
addTitle();
|
||||||
assert (gp != NULL);
|
addTracks();
|
||||||
|
addScreenshot();
|
||||||
|
addButtons();
|
||||||
|
}
|
||||||
|
|
||||||
// ---- GP Name
|
// ----------------------------------------------------------------------------
|
||||||
core::rect< s32 > area_top(0, 0, m_area.getWidth(), y1);
|
|
||||||
IGUIStaticText* title = GUIEngine::getGUIEnv()->addStaticText( translations->fribidize(gp->getName()),
|
GPInfoDialog::~GPInfoDialog()
|
||||||
area_top, false, true, // border, word wrap
|
{
|
||||||
m_irrlicht_window);
|
GUIEngine::Screen* curr_screen = GUIEngine::getCurrentScreen();
|
||||||
|
if (curr_screen->getName() == "tracks.stkgui")
|
||||||
|
static_cast<TracksScreen*>(curr_screen)->setFocusOnGP(m_gp->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void GPInfoDialog::addTitle()
|
||||||
|
{
|
||||||
|
core::rect< s32 > area_top(0, 0, m_area.getWidth(), m_under_title);
|
||||||
|
IGUIStaticText* title = GUIEngine::getGUIEnv()->addStaticText(
|
||||||
|
translations->fribidize(m_gp->getName()),
|
||||||
|
area_top, false, true, // border, word wrap
|
||||||
|
m_irrlicht_window);
|
||||||
title->setTabStop(false);
|
title->setTabStop(false);
|
||||||
title->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
|
title->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// ---- Track listings
|
void GPInfoDialog::addTracks()
|
||||||
const std::vector<std::string> tracks = gp->getTrackNames();
|
{
|
||||||
const int trackAmount = tracks.size();
|
const std::vector<std::string> tracks = m_gp->getTrackNames();
|
||||||
|
const unsigned int track_amount = tracks.size();
|
||||||
|
|
||||||
int height_of_one_line = (y2 - y1)/(trackAmount+1);
|
int height_of_one_line = std::min((m_lower_bound - m_over_body)/(track_amount+1),
|
||||||
const int textHeight = GUIEngine::getFontHeight();
|
(unsigned int)(GUIEngine::getFontHeight()*1.5f));
|
||||||
if (height_of_one_line > (int)(textHeight*1.5f)) height_of_one_line = (int)(textHeight*1.5f);
|
|
||||||
|
|
||||||
bool gp_ok = true;
|
// Count the number of label already existing labels representing a track
|
||||||
|
unsigned int existing = 0;
|
||||||
for (int t=0; t<trackAmount; t++)
|
for (unsigned int i = 0; i < m_widgets.size(); i++)
|
||||||
{
|
{
|
||||||
const int from_y = y1 + height_of_one_line*(t+1);
|
if (m_widgets.get(i)->m_properties[PROP_ID] == "Track label")
|
||||||
|
existing++;
|
||||||
Track* track = track_manager->getTrack(tracks[t]);
|
|
||||||
stringw lineText;
|
|
||||||
if (track == NULL)
|
|
||||||
{
|
|
||||||
lineText = L"MISSING : ";
|
|
||||||
lineText.append( stringw(tracks[t].c_str()) );
|
|
||||||
gp_ok = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lineText = track->getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
LabelWidget* widget = new LabelWidget();
|
|
||||||
widget->setText(translations->fribidize(lineText), false);
|
|
||||||
widget->m_x = 20;
|
|
||||||
widget->m_y = from_y;
|
|
||||||
widget->m_w = m_area.getWidth()/2 - 20;
|
|
||||||
widget->m_h = height_of_one_line;
|
|
||||||
widget->setParent(m_irrlicht_window);
|
|
||||||
|
|
||||||
m_widgets.push_back(widget);
|
|
||||||
widget->add();
|
|
||||||
|
|
||||||
// IGUIStaticText* line = GUIEngine::getGUIEnv()->addStaticText( lineText.c_str(),
|
|
||||||
// entry_area, false , true , // border, word wrap
|
|
||||||
// m_irrlicht_window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Track screenshot
|
unsigned int reuse = std::min(existing, track_amount);
|
||||||
|
// m_widgets has the type PtrVector<Widget, HOLD>
|
||||||
|
unsigned int widgets_iter = 0;
|
||||||
|
for (unsigned int i = 0; i < reuse; i++)
|
||||||
|
{
|
||||||
|
Track* track = track_manager->getTrack(tracks[i]);
|
||||||
|
|
||||||
m_screenshot_widget = new IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_CUSTOM_ASPECT_RATIO,
|
// Find the next widget that is a track label
|
||||||
false /* tab stop */, false /* focusable */,
|
while (m_widgets.get(widgets_iter)->m_properties[PROP_ID] != "Track label")
|
||||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE /* Track gives us absolute paths */);
|
widgets_iter++;
|
||||||
|
|
||||||
|
Label* widget = dynamic_cast<Label*>(m_widgets.get(widgets_iter));
|
||||||
|
widget->setText(translations->fribidize(track->getName()), false);
|
||||||
|
widget->move(20, m_over_body + height_of_one_line*(i+1),
|
||||||
|
m_area.getWidth()/2 - 20, height_of_one_line);
|
||||||
|
|
||||||
|
widgets_iter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existing < track_amount)
|
||||||
|
{
|
||||||
|
// There are not enough labels for all the track names, so we have to
|
||||||
|
// add some more
|
||||||
|
for (unsigned int i = reuse; i < track_amount; i++)
|
||||||
|
{
|
||||||
|
Track* track = track_manager->getTrack(tracks[i]);
|
||||||
|
assert(track != NULL);
|
||||||
|
|
||||||
|
Label* widget = new Label();
|
||||||
|
widget->m_properties[PROP_ID] = "Track label";
|
||||||
|
widget->setText(translations->fribidize(track->getName()), false);
|
||||||
|
widget->setParent(m_irrlicht_window);
|
||||||
|
m_widgets.push_back(widget);
|
||||||
|
widget->add();
|
||||||
|
|
||||||
|
widget->move(20, m_over_body + height_of_one_line*(i+1),
|
||||||
|
m_area.getWidth()/2 - 20, height_of_one_line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (existing > track_amount)
|
||||||
|
{
|
||||||
|
// There are label which are not necessary anymore so they're deleted
|
||||||
|
for (unsigned int i = widgets_iter; i < m_widgets.size(); i++)
|
||||||
|
{
|
||||||
|
if (m_widgets.get(i)->m_properties[PROP_ID] == "Track label")
|
||||||
|
{
|
||||||
|
m_irrlicht_window->removeChild(m_widgets.get(i)->getIrrlichtElement());
|
||||||
|
m_widgets.remove(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void GPInfoDialog::addScreenshot()
|
||||||
|
{
|
||||||
|
m_screenshot_widget = new GUIEngine::IconButtonWidget(
|
||||||
|
GUIEngine::IconButtonWidget::SCALE_MODE_KEEP_CUSTOM_ASPECT_RATIO,
|
||||||
|
false, false, GUIEngine::IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||||
// images are saved squared, but must be stretched to 4:3
|
// images are saved squared, but must be stretched to 4:3
|
||||||
m_screenshot_widget->setCustomAspectRatio(4.0f / 3.0f);
|
m_screenshot_widget->setCustomAspectRatio(4.0f / 3.0f);
|
||||||
|
|
||||||
m_screenshot_widget->m_x = m_area.getWidth()/2;
|
m_screenshot_widget->m_x = m_area.getWidth()/2-20;
|
||||||
m_screenshot_widget->m_y = y1;
|
m_screenshot_widget->m_y = m_over_body + 10;
|
||||||
m_screenshot_widget->m_w = m_area.getWidth()/2;
|
|
||||||
m_screenshot_widget->m_h = y2 - y1 - 10;
|
|
||||||
|
|
||||||
Track* track = (tracks.size() == 0 ? NULL : track_manager->getTrack(tracks[0]));
|
// Scale the picture to the biggest possible size without an overflow
|
||||||
|
if (m_lower_bound - m_over_body - 20 < m_area.getWidth()/2*3/4)
|
||||||
|
{
|
||||||
|
m_screenshot_widget->m_w = (m_lower_bound - m_over_body - 30)*4/3;
|
||||||
|
m_screenshot_widget->m_h = m_lower_bound - m_over_body - 30;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_screenshot_widget->m_w = m_area.getWidth()/2;
|
||||||
|
m_screenshot_widget->m_h = m_area.getWidth()*3/8; // *(3/4)*(1/2)
|
||||||
|
}
|
||||||
|
|
||||||
m_screenshot_widget->m_properties[PROP_ICON] = (track != NULL ?
|
Track* track = track_manager->getTrack(m_gp->getTrackNames()[0]);
|
||||||
track->getScreenshotFile().c_str() :
|
m_screenshot_widget->m_properties[GUIEngine::PROP_ICON] = (track->getScreenshotFile().c_str());
|
||||||
file_manager->getAsset(FileManager::GUI,"main_help.png"));
|
|
||||||
m_screenshot_widget->setParent(m_irrlicht_window);
|
m_screenshot_widget->setParent(m_irrlicht_window);
|
||||||
m_screenshot_widget->add();
|
m_screenshot_widget->add();
|
||||||
m_widgets.push_back(m_screenshot_widget);
|
m_widgets.push_back(m_screenshot_widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void GPInfoDialog::addButtons()
|
||||||
|
{
|
||||||
// ---- Start button
|
// ---- Start button
|
||||||
ButtonWidget* okBtn = new ButtonWidget();
|
GUIEngine::ButtonWidget* okBtn = new GUIEngine::ButtonWidget();
|
||||||
ButtonWidget* continueBtn = new ButtonWidget();
|
GUIEngine::ButtonWidget* continueBtn = new GUIEngine::ButtonWidget();
|
||||||
|
|
||||||
SavedGrandPrix* saved_gp = SavedGrandPrix::getSavedGP( StateManager::get()
|
SavedGrandPrix* saved_gp = SavedGrandPrix::getSavedGP( StateManager::get()
|
||||||
->getActivePlayerProfile(0)
|
->getActivePlayerProfile(0)
|
||||||
->getUniqueID(),
|
->getUniqueID(),
|
||||||
gpIdent,
|
m_gp->getId(),
|
||||||
race_manager->getDifficulty(),
|
race_manager->getDifficulty(),
|
||||||
race_manager->getNumberOfKarts(),
|
race_manager->getNumberOfKarts(),
|
||||||
race_manager->getNumLocalPlayers());
|
race_manager->getNumLocalPlayers());
|
||||||
|
|
||||||
if (tracks.size() == 0)
|
okBtn->m_properties[PROP_ID] = "start";
|
||||||
{
|
okBtn->setText(_("Start Grand Prix"));
|
||||||
okBtn->m_properties[PROP_ID] = "cannot_start";
|
|
||||||
okBtn->setText(_("Sorry, no tracks available"));
|
|
||||||
}
|
|
||||||
else if (gp_ok)
|
|
||||||
{
|
|
||||||
okBtn->m_properties[PROP_ID] = "start";
|
|
||||||
okBtn->setText(_("Start Grand Prix"));
|
|
||||||
|
|
||||||
continueBtn->m_properties[PROP_ID] = "continue";
|
continueBtn->m_properties[PROP_ID] = "continue";
|
||||||
continueBtn->setText(_("Continue"));
|
continueBtn->setText(_("Continue"));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
okBtn->m_properties[PROP_ID] = "cannot_start";
|
|
||||||
okBtn->setText(_("This Grand Prix is broken!"));
|
|
||||||
okBtn->setBadge(BAD_BADGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (saved_gp && gp_ok)
|
if (saved_gp)
|
||||||
{
|
{
|
||||||
continueBtn->m_x = m_area.getWidth()/2 + 110;
|
continueBtn->m_x = m_area.getWidth()/2 + 110;
|
||||||
continueBtn->m_y = y2;
|
continueBtn->m_y = m_lower_bound;
|
||||||
continueBtn->m_w = 200;
|
continueBtn->m_w = 200;
|
||||||
continueBtn->m_h = m_area.getHeight() - y2 - 15;
|
continueBtn->m_h = m_area.getHeight() - m_lower_bound - 15;
|
||||||
continueBtn->setParent(m_irrlicht_window);
|
continueBtn->setParent(m_irrlicht_window);
|
||||||
m_widgets.push_back(continueBtn);
|
m_widgets.push_back(continueBtn);
|
||||||
continueBtn->add();
|
continueBtn->add();
|
||||||
@ -185,9 +230,9 @@ GPInfoDialog::GPInfoDialog(const std::string& gpIdent, const float w, const floa
|
|||||||
okBtn->m_x = m_area.getWidth()/2 - 200;
|
okBtn->m_x = m_area.getWidth()/2 - 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
okBtn->m_y = y2;
|
okBtn->m_y = m_lower_bound;
|
||||||
okBtn->m_w = 400;
|
okBtn->m_w = 400;
|
||||||
okBtn->m_h = m_area.getHeight() - y2 - 15;
|
okBtn->m_h = m_area.getHeight() - m_lower_bound - 15;
|
||||||
okBtn->setParent(m_irrlicht_window);
|
okBtn->setParent(m_irrlicht_window);
|
||||||
m_widgets.push_back(okBtn);
|
m_widgets.push_back(okBtn);
|
||||||
okBtn->add();
|
okBtn->add();
|
||||||
@ -195,87 +240,57 @@ GPInfoDialog::GPInfoDialog(const std::string& gpIdent, const float w, const floa
|
|||||||
okBtn->getIrrlichtElement()->setTabGroup(false);
|
okBtn->getIrrlichtElement()->setTabGroup(false);
|
||||||
|
|
||||||
okBtn->setFocusForPlayer( PLAYER_ID_GAME_MASTER );
|
okBtn->setFocusForPlayer( PLAYER_ID_GAME_MASTER );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
GPInfoDialog::~GPInfoDialog()
|
|
||||||
{
|
|
||||||
// Place focus back on selected GP, in case the dialog was cancelled and we're back to
|
|
||||||
// the track selection screen after
|
|
||||||
Screen* curr_screen = GUIEngine::getCurrentScreen();
|
|
||||||
if (curr_screen->getName() == "tracks.stkgui")
|
|
||||||
{
|
|
||||||
((TracksScreen*)curr_screen)->setFocusOnGP(m_gp_ident);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void GPInfoDialog::onEnterPressedInternal()
|
void GPInfoDialog::onEnterPressedInternal()
|
||||||
{
|
{
|
||||||
// Save the gp identifier, since dismiss will delete this object.
|
// Save the GP id because dismiss() will destroy this instance
|
||||||
std::string gp_id = m_gp_ident;
|
std::string gp_id = m_gp->getId();
|
||||||
ModalDialog::dismiss();
|
ModalDialog::dismiss();
|
||||||
// Disable accidentally unlocking of a challenge
|
// Disable accidentally unlocking of a challenge
|
||||||
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
|
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
|
||||||
race_manager->startGP(grand_prix_manager->getGrandPrix(gp_id), false, false);
|
race_manager->startGP(grand_prix_manager->getGrandPrix(gp_id), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
GUIEngine::EventPropagation GPInfoDialog::processEvent(const std::string& eventSource)
|
GUIEngine::EventPropagation GPInfoDialog::processEvent(const std::string& eventSource)
|
||||||
{
|
{
|
||||||
if (eventSource == "start")
|
if (eventSource == "start" || eventSource == "continue")
|
||||||
{
|
{
|
||||||
// Save GP identifier, since dismiss will delete this object.
|
// Save GP identifier, since dismiss will delete this object.
|
||||||
std::string gp_id = m_gp_ident;
|
std::string gp_id = m_gp->getId();
|
||||||
ModalDialog::dismiss();
|
ModalDialog::dismiss();
|
||||||
race_manager->startGP(grand_prix_manager->getGrandPrix(gp_id), false, false);
|
race_manager->startGP(grand_prix_manager->getGrandPrix(gp_id), false,
|
||||||
|
(eventSource == "continue"));
|
||||||
return GUIEngine::EVENT_BLOCK;
|
return GUIEngine::EVENT_BLOCK;
|
||||||
}
|
}
|
||||||
if (eventSource == "continue")
|
|
||||||
{
|
|
||||||
// Save GP identifier, since dismiss will delete this object.
|
|
||||||
std::string gp_id = m_gp_ident;
|
|
||||||
ModalDialog::dismiss();
|
|
||||||
race_manager->startGP(grand_prix_manager->getGrandPrix(gp_id), false, true);
|
|
||||||
return GUIEngine::EVENT_BLOCK;
|
|
||||||
}
|
|
||||||
else if (eventSource == "cannot_start")
|
|
||||||
{
|
|
||||||
sfx_manager->quickSound( "anvil" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return GUIEngine::EVENT_LET;
|
return GUIEngine::EVENT_LET;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void GPInfoDialog::onUpdate(float dt)
|
void GPInfoDialog::onUpdate(float dt)
|
||||||
{
|
{
|
||||||
const int frameBefore = (int)(m_curr_time / 1.5f);
|
if (dt == 0)
|
||||||
|
return; // if nothing changed, return right now
|
||||||
|
|
||||||
m_curr_time += dt;
|
m_curr_time += dt;
|
||||||
int frameAfter = (int)(m_curr_time / 1.5f);
|
int frameAfter = (int)(m_curr_time / 1.5f);
|
||||||
|
|
||||||
if (frameAfter == frameBefore) return; // if nothing changed, return right now
|
const std::vector<std::string> tracks = m_gp->getTrackNames();
|
||||||
|
|
||||||
const GrandPrixData* gp = grand_prix_manager->getGrandPrix(m_gp_ident);
|
|
||||||
assert(gp != NULL);
|
|
||||||
const std::vector<std::string> tracks = gp->getTrackNames();
|
|
||||||
if (frameAfter >= (int)tracks.size())
|
if (frameAfter >= (int)tracks.size())
|
||||||
{
|
{
|
||||||
frameAfter = 0;
|
frameAfter = 0;
|
||||||
m_curr_time = 0;
|
m_curr_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Track* track = (tracks.size() == 0 ? NULL :
|
Track* track = track_manager->getTrack(tracks[frameAfter]);
|
||||||
track_manager->getTrack(tracks[frameAfter]));
|
std::string file = track->getScreenshotFile();
|
||||||
std::string fn = track ? track->getScreenshotFile()
|
typedef GUIEngine::IconButtonWidget Icon;
|
||||||
: file_manager->getAsset(FileManager::GUI, "main_help.png");
|
m_screenshot_widget->setImage(file.c_str(), Icon::ICON_PATH_TYPE_ABSOLUTE);
|
||||||
m_screenshot_widget->setImage(fn.c_str(), IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------
|
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
#define HEADER_GP_INFO_DIALOG_HPP
|
#define HEADER_GP_INFO_DIALOG_HPP
|
||||||
|
|
||||||
#include "guiengine/modaldialog.hpp"
|
#include "guiengine/modaldialog.hpp"
|
||||||
|
// Don't include grand_prix_data.hpp here or the compilation will fail
|
||||||
|
|
||||||
|
|
||||||
|
class GrandPrixData;
|
||||||
|
|
||||||
namespace GUIEngine
|
namespace GUIEngine
|
||||||
{
|
{
|
||||||
@ -32,23 +36,45 @@ namespace GUIEngine
|
|||||||
*/
|
*/
|
||||||
class GPInfoDialog : public GUIEngine::ModalDialog
|
class GPInfoDialog : public GUIEngine::ModalDialog
|
||||||
{
|
{
|
||||||
std::string m_gp_ident;
|
protected: // Necessary for RandomGPInfoDialog
|
||||||
GUIEngine::IconButtonWidget* m_screenshot_widget;
|
GUIEngine::IconButtonWidget* m_screenshot_widget;
|
||||||
|
|
||||||
float m_curr_time;
|
float m_curr_time;
|
||||||
|
GrandPrixData* m_gp;
|
||||||
|
|
||||||
|
/** height of the separator over the body */
|
||||||
|
int m_over_body;
|
||||||
|
/** height of the separator under the titlebar, which is equal to
|
||||||
|
* m_over_body in a normal GPInfoDialo and lower in RandomGPInfoDialog. */
|
||||||
|
int m_under_title;
|
||||||
|
/** height of the seperator over the buttons */
|
||||||
|
int m_lower_bound;
|
||||||
|
|
||||||
|
void addTitle();
|
||||||
|
/** \brief display all the tracks according to the current gp
|
||||||
|
* For a normal gp info dialog, it just creates a label for every track.
|
||||||
|
* But with a random gp info dialog, it tries to reuse as many
|
||||||
|
* labels as possible by just changing their text. */
|
||||||
|
void addTracks();
|
||||||
|
void addScreenshot();
|
||||||
|
/** display a ok-button and eventually a continue-button */
|
||||||
|
void addButtons();
|
||||||
|
|
||||||
|
/** only used for track_screen.cpp */
|
||||||
|
GPInfoDialog() : ModalDialog(PERCENT_WIDTH, PERCENT_HEIGHT) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
static const float PERCENT_WIDTH = 0.8f;
|
||||||
* Creates a modal dialog with given percentage of screen width and height
|
static const float PERCENT_HEIGHT = 0.7f;
|
||||||
*/
|
|
||||||
GPInfoDialog(const std::string& gpIdent, const float percentWidth, const float percentHeight);
|
GPInfoDialog(const std::string& gpIdent);
|
||||||
|
/** Places the focus back on the selected GP, in the case that the dialog
|
||||||
|
* was cancelled and we're returning to the track selection screen */
|
||||||
virtual ~GPInfoDialog();
|
virtual ~GPInfoDialog();
|
||||||
|
|
||||||
void onEnterPressedInternal();
|
void onEnterPressedInternal();
|
||||||
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
|
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
|
||||||
|
|
||||||
virtual void onUpdate(float dt);
|
|
||||||
|
|
||||||
|
virtual void onUpdate(float dt);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
195
src/states_screens/dialogs/random_gp_dialog.cpp
Normal file
195
src/states_screens/dialogs/random_gp_dialog.cpp
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2014 konstin
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 3
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#include "guiengine/engine.hpp"
|
||||||
|
#include "guiengine/widgets/icon_button_widget.hpp"
|
||||||
|
#include "guiengine/widgets/spinner_widget.hpp"
|
||||||
|
#include "race/grand_prix_manager.hpp"
|
||||||
|
#include "race/race_manager.hpp"
|
||||||
|
#include "states_screens/dialogs/random_gp_dialog.hpp"
|
||||||
|
#include "tracks/track_manager.hpp"
|
||||||
|
|
||||||
|
#include <IGUIEnvironment.h>
|
||||||
|
#include <IGUIStaticText.h>
|
||||||
|
|
||||||
|
using irr::core::stringc;
|
||||||
|
using irr::core::stringw;
|
||||||
|
using irr::gui::IGUIStaticText;
|
||||||
|
|
||||||
|
typedef GUIEngine::SpinnerWidget Spinner;
|
||||||
|
|
||||||
|
RandomGPInfoDialog::RandomGPInfoDialog()
|
||||||
|
{
|
||||||
|
// Defaults - loading selection from last time frrom a file would be better
|
||||||
|
m_number_of_tracks = 2; // We can assume that there are at least 2 standard tracks
|
||||||
|
m_trackgroup = "standard";
|
||||||
|
m_use_reverse = NO_REVERSE;
|
||||||
|
|
||||||
|
doInit();
|
||||||
|
m_curr_time = 0.0f;
|
||||||
|
|
||||||
|
m_under_title = m_area.getHeight()/7;
|
||||||
|
m_over_body = m_area.getHeight()/7 + SPINNER_HEIGHT + 10; // 10px space
|
||||||
|
m_lower_bound = m_area.getHeight()*6/7;
|
||||||
|
|
||||||
|
// The GP manager is be used to make the GP live longer than this dialog
|
||||||
|
if (grand_prix_manager->m_random_gp)
|
||||||
|
{
|
||||||
|
delete grand_prix_manager->m_random_gp;
|
||||||
|
grand_prix_manager->m_random_gp = NULL;
|
||||||
|
}
|
||||||
|
m_gp = new GrandPrixData(m_number_of_tracks, m_trackgroup, m_use_reverse);
|
||||||
|
grand_prix_manager->m_random_gp = m_gp;
|
||||||
|
|
||||||
|
addTitle();
|
||||||
|
addSpinners();
|
||||||
|
addTracks();
|
||||||
|
addScreenshot();
|
||||||
|
addButtons();
|
||||||
|
addRestartButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RandomGPInfoDialog::addSpinners()
|
||||||
|
{
|
||||||
|
const int trackgroup_width = 200, laps_with = 150, reverse_width = 200;
|
||||||
|
const int left = (m_area.getWidth() - trackgroup_width - 150 - 250)/2;
|
||||||
|
|
||||||
|
// Trackgroup chooser
|
||||||
|
Spinner* spinner = new Spinner(false);
|
||||||
|
spinner->m_properties[GUIEngine::PROP_ID] = "Trackgroup";
|
||||||
|
spinner->m_properties[GUIEngine::PROP_WRAP_AROUND] = "true";
|
||||||
|
spinner->setParent(m_irrlicht_window);
|
||||||
|
m_widgets.push_back(spinner);
|
||||||
|
spinner->add();
|
||||||
|
spinner->move(left, m_under_title, trackgroup_width, SPINNER_HEIGHT);
|
||||||
|
// Fill it with all the track group names
|
||||||
|
spinner->addLabel("all");
|
||||||
|
int index_standard;
|
||||||
|
const std::vector<std::string>& groups = track_manager->getAllTrackGroups();
|
||||||
|
for (unsigned int i = 0; i < groups.size(); i++)
|
||||||
|
{
|
||||||
|
// FIXME: The NULL check is necessary until #1348 on github is fixed
|
||||||
|
if (groups[i].c_str() != NULL)
|
||||||
|
{
|
||||||
|
spinner->addLabel(stringw(groups[i].c_str()));
|
||||||
|
if(groups[i] == "standard")
|
||||||
|
index_standard = i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// The value can only be set here because SpinnerWidget resets the value
|
||||||
|
// every time a label is added
|
||||||
|
spinner->setValue(index_standard);
|
||||||
|
|
||||||
|
// Number of laps chooser
|
||||||
|
spinner = new Spinner(false);
|
||||||
|
spinner->setValue(m_number_of_tracks);
|
||||||
|
spinner->setMin(1);
|
||||||
|
spinner->setMax(track_manager->getTracksInGroup("standard").size());
|
||||||
|
spinner->setParent(m_irrlicht_window);
|
||||||
|
spinner->m_properties[GUIEngine::PROP_ID] = "Number of tracks";
|
||||||
|
spinner->m_properties[GUIEngine::PROP_WRAP_AROUND] = "true";
|
||||||
|
m_widgets.push_back(spinner);
|
||||||
|
spinner->add();
|
||||||
|
spinner->move(left + trackgroup_width + 10, m_under_title, laps_with, SPINNER_HEIGHT);
|
||||||
|
|
||||||
|
// reverse choose
|
||||||
|
spinner = new Spinner(false);
|
||||||
|
spinner->setParent(m_irrlicht_window);
|
||||||
|
spinner->m_properties[GUIEngine::PROP_ID] = "reverse";
|
||||||
|
spinner->m_properties[GUIEngine::PROP_WRAP_AROUND] = "true";
|
||||||
|
m_widgets.push_back(spinner);
|
||||||
|
spinner->add();
|
||||||
|
spinner->move(left + trackgroup_width + laps_with + 10, m_under_title, reverse_width, SPINNER_HEIGHT);
|
||||||
|
spinner->addLabel("no reverse");
|
||||||
|
spinner->addLabel("all reverse");
|
||||||
|
spinner->addLabel("mixed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RandomGPInfoDialog::addRestartButton()
|
||||||
|
{
|
||||||
|
GUIEngine::IconButtonWidget* button = new GUIEngine::IconButtonWidget();
|
||||||
|
button->setImage("gui/restart.png");
|
||||||
|
button->setParent(m_irrlicht_window);
|
||||||
|
button->m_properties[GUIEngine::PROP_ID] = "reload";
|
||||||
|
m_widgets.push_back(button);
|
||||||
|
button->add();
|
||||||
|
button->move(m_area.getWidth() - 20 - 32, 20, 32, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
GUIEngine::EventPropagation RandomGPInfoDialog::processEvent(
|
||||||
|
const std::string& eventSource)
|
||||||
|
{
|
||||||
|
if (eventSource == "start")
|
||||||
|
{
|
||||||
|
ModalDialog::dismiss();
|
||||||
|
race_manager->startGP(grand_prix_manager->m_random_gp, false, false);
|
||||||
|
return GUIEngine::EVENT_BLOCK;
|
||||||
|
}
|
||||||
|
else if (eventSource == "Number of tracks")
|
||||||
|
{
|
||||||
|
// The old gp can be reused because there's only track deletion/adding
|
||||||
|
m_number_of_tracks = getWidget<Spinner>("Number of tracks")->getValue();
|
||||||
|
m_gp->changeTrackNumber(m_number_of_tracks, m_trackgroup);
|
||||||
|
addTracks();
|
||||||
|
}
|
||||||
|
else if (eventSource == "Trackgroup")
|
||||||
|
{
|
||||||
|
Spinner* t = getWidget<Spinner>("Trackgroup");
|
||||||
|
Spinner* s = getWidget<Spinner>("Number of tracks");
|
||||||
|
|
||||||
|
m_trackgroup = stringc(t->getStringValue()).c_str();
|
||||||
|
|
||||||
|
// Update the maximum for the number of tracks since it's depending on
|
||||||
|
// the current track. The current value in the Number-of-tracks-spinner
|
||||||
|
// has to be updated, since otherwise the displayed (and used) value
|
||||||
|
// can be bigger than the maximum. (Might be a TODO to fix this)
|
||||||
|
unsigned int max = (m_trackgroup == "all") ?
|
||||||
|
track_manager->getNumberOfTracks() :
|
||||||
|
track_manager->getTracksInGroup(m_trackgroup).size();
|
||||||
|
m_number_of_tracks = std::min(max, m_number_of_tracks);
|
||||||
|
s->setMax(max);
|
||||||
|
if (s->getValue() > (signed)max)
|
||||||
|
s->setValue(max);
|
||||||
|
|
||||||
|
delete m_gp;
|
||||||
|
m_gp = new GrandPrixData(m_number_of_tracks, m_trackgroup, m_use_reverse);
|
||||||
|
grand_prix_manager->m_random_gp = m_gp;
|
||||||
|
addTracks();
|
||||||
|
}
|
||||||
|
else if (eventSource == "reverse")
|
||||||
|
{
|
||||||
|
Spinner* r = getWidget<Spinner>("reverse");
|
||||||
|
m_use_reverse = static_cast<REVERSED>(r->getValue());
|
||||||
|
m_gp->changeReverse(m_use_reverse);
|
||||||
|
}
|
||||||
|
else if (eventSource == "reload")
|
||||||
|
{
|
||||||
|
delete m_gp;
|
||||||
|
m_gp = new GrandPrixData(m_number_of_tracks, m_trackgroup, m_use_reverse);
|
||||||
|
grand_prix_manager->m_random_gp = m_gp;
|
||||||
|
addTracks();
|
||||||
|
}
|
||||||
|
|
||||||
|
return GUIEngine::EVENT_LET;
|
||||||
|
}
|
||||||
|
|
53
src/states_screens/dialogs/random_gp_dialog.hpp
Normal file
53
src/states_screens/dialogs/random_gp_dialog.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2014 konstin
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 3
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
#ifndef HEADER_RANDOM_GP_INFO_DIALOG_HPP
|
||||||
|
#define HEADER_RANDOM_GP_INFO_DIALOG_HPP
|
||||||
|
|
||||||
|
#include "states_screens/dialogs/gp_info_dialog.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class RandomGPInfoDialog : public GPInfoDialog
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum REVERSED
|
||||||
|
{
|
||||||
|
NO_REVERSE = 0,
|
||||||
|
ALL_REVERSE = 1,
|
||||||
|
MIXED = 2
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
unsigned int m_number_of_tracks;
|
||||||
|
std::string m_trackgroup;
|
||||||
|
REVERSED m_use_reverse;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const int SPINNER_HEIGHT = 40;
|
||||||
|
|
||||||
|
RandomGPInfoDialog();
|
||||||
|
|
||||||
|
/** Adds a SpinnerWidgets to choose the track groups, one to choose the
|
||||||
|
* number of tracks and one to choose if the tracks should be raced in
|
||||||
|
* reverse. The Spinners are centered. */
|
||||||
|
void addSpinners();
|
||||||
|
void addRestartButton();
|
||||||
|
|
||||||
|
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -29,6 +29,7 @@
|
|||||||
#include "race/grand_prix_manager.hpp"
|
#include "race/grand_prix_manager.hpp"
|
||||||
#include "states_screens/state_manager.hpp"
|
#include "states_screens/state_manager.hpp"
|
||||||
#include "states_screens/dialogs/gp_info_dialog.hpp"
|
#include "states_screens/dialogs/gp_info_dialog.hpp"
|
||||||
|
#include "states_screens/dialogs/random_gp_dialog.hpp"
|
||||||
#include "states_screens/dialogs/track_info_dialog.hpp"
|
#include "states_screens/dialogs/track_info_dialog.hpp"
|
||||||
#include "tracks/track.hpp"
|
#include "tracks/track.hpp"
|
||||||
#include "tracks/track_manager.hpp"
|
#include "tracks/track_manager.hpp"
|
||||||
@ -121,9 +122,16 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name,
|
|||||||
gps_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
gps_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
|
||||||
|
|
||||||
if (selection == "locked")
|
if (selection == "locked")
|
||||||
|
{
|
||||||
unlock_manager->playLockSound();
|
unlock_manager->playLockSound();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
new GPInfoDialog(selection, 0.8f, 0.7f);
|
{
|
||||||
|
if (selection == "Random Grand Prix")
|
||||||
|
new RandomGPInfoDialog();
|
||||||
|
else
|
||||||
|
new GPInfoDialog(selection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (name == "trackgroups")
|
else if (name == "trackgroups")
|
||||||
{
|
{
|
||||||
@ -214,12 +222,13 @@ void TracksScreen::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*// Random GP - not finished yet
|
// Random GP
|
||||||
std::vector<std::string> screenshots;
|
std::vector<std::string> screenshots;
|
||||||
screenshots.push_back("gui/main_help.png");
|
screenshots.push_back(file_manager->getAsset(FileManager::GUI, "main_help.png"));
|
||||||
gps_widget->addAnimatedItem(translations->fribidize("Random"), "Random",
|
gps_widget->addAnimatedItem(translations->fribidize("Random Grand Prix"),
|
||||||
|
"Random Grand Prix",
|
||||||
screenshots, 1.5f, 0,
|
screenshots, 1.5f, 0,
|
||||||
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);*/
|
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE);
|
||||||
|
|
||||||
gps_widget->updateItemDisplay();
|
gps_widget->updateItemDisplay();
|
||||||
|
|
||||||
|
@ -521,10 +521,10 @@ void Track::loadTrackInfo()
|
|||||||
delete root;
|
delete root;
|
||||||
|
|
||||||
std::string dir = StringUtils::getPath(m_filename);
|
std::string dir = StringUtils::getPath(m_filename);
|
||||||
std::string easter_name = dir+"/easter_eggs.xml";
|
std::string easter_name = dir + "/easter_eggs.xml";
|
||||||
|
|
||||||
XMLNode *easter = file_manager->createXMLTree(easter_name);
|
XMLNode *easter = file_manager->createXMLTree(easter_name);
|
||||||
|
|
||||||
if(easter)
|
if(easter)
|
||||||
{
|
{
|
||||||
for(unsigned int i=0; i<easter->getNumNodes(); i++)
|
for(unsigned int i=0; i<easter->getNumNodes(); i++)
|
||||||
@ -932,7 +932,7 @@ bool Track::loadMainTrack(const XMLNode &root)
|
|||||||
{
|
{
|
||||||
mesh = irr_driver->getMesh(full_path);
|
mesh = irr_driver->getMesh(full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!mesh)
|
if(!mesh)
|
||||||
{
|
{
|
||||||
Log::fatal("track",
|
Log::fatal("track",
|
||||||
@ -1960,7 +1960,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
|
|||||||
libroot = library_nodes[name];
|
libroot = library_nodes[name];
|
||||||
create_lod_definitions = false; // LOD definitions are already created, don't create them again
|
create_lod_definitions = false; // LOD definitions are already created, don't create them again
|
||||||
}
|
}
|
||||||
|
|
||||||
scene::ISceneNode* parent = irr_driver->getSceneManager()->addEmptySceneNode();
|
scene::ISceneNode* parent = irr_driver->getSceneManager()->addEmptySceneNode();
|
||||||
parent->setPosition(xyz);
|
parent->setPosition(xyz);
|
||||||
parent->setRotation(hpr);
|
parent->setRotation(hpr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user