Merge branch 'a' of https://github.com/konstin/stk-code into konstin-a

This commit is contained in:
hiker 2014-07-07 16:15:34 +10:00
commit c222bbcb1c
17 changed files with 611 additions and 204 deletions

View File

@ -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);

View File

@ -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)
{ {

View File

@ -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))

View File

@ -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.

View File

@ -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)
{ {

View File

@ -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

View File

@ -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)

View File

@ -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();

View File

@ -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;

View File

@ -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);
/** /**

View File

@ -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++)

View File

@ -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);
} }
// ------------------------------------------------------------------------------------------------------

View File

@ -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

View 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;
}

View 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

View File

@ -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();

View File

@ -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);