tutorial developing progress commit

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7087 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
aeonphyxius 2010-12-19 20:23:32 +00:00
parent 5a74502c29
commit 2e5689134c
6 changed files with 605 additions and 90 deletions

View File

@ -2,21 +2,18 @@
<div x="5%" y="2%" width="90%" height="96%" layout="vertical-row" >
<header I18N="Title for challenges screen" text="Tutorial : Selection Room" text_align="center" width="100%" />
<box id="animated_area" width="100%" proportion="1" layout="vertical-row">
<ribbon_grid id="tutorial" proportion="3" width="100%"
label_location="bottom" align="center" child_width="128" child_height="128" />
<header I18N="Title for tutorials screen" text="Tutorial : Selection Room" text_align="center" width="100%" />
<spacer proportion="1" width="100%"/>
<list id="tutorials" proportion="5" width="75%" align="center"/>
<spacer proportion="1" width="100%"/>
</box>
<spacer width="100%" height="45"/>
</div>
<button id="back" x="20" y="-40" height="35" align="left" text="Back to main menu"/>
<button id="play" x="-200" y="-40" height="35" align="right" text="Play all"/>
</stkgui>

View File

@ -15,10 +15,13 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/tutorial_screen.hpp"
#include "challenges/unlock_manager.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "utils/string_utils.hpp"
#include "graphics/irr_driver.hpp"
#include "tutorial/tutorial_manager.hpp"
#include "config/user_config.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/widgets/dynamic_ribbon_widget.hpp"
@ -65,46 +68,62 @@ void TutorialScreen::onUpdate(float elapsed_time, irr::video::IVideoDriver*)
void TutorialScreen::init()
{
Screen::init();
DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("tutorial");
assert( w != NULL );
ListWidget* tutorials_list = this->getWidget<ListWidget>("tutorials");
assert( tutorials_list != NULL );
// FIXME different icons for each tutorial option & add then to
video::ITexture* tutorial_icon = irr_driver->getTexture( file_manager->getGUIDir() + "/keyboard.png" );
m_icon_bank = new irr::gui::STKModifiedSpriteBank( GUIEngine::getGUIEnv() );
m_icon_bank->addTextureAsSprite(tutorial_icon);
// scale icons depending on screen resolution. the numbers below are a bit arbitrary
const int screen_width = irr_driver->getFrameSize().Width;
const float scale = 0.3f + 0.2f*std::max(0, screen_width - 640)/564.0f;
m_icon_bank->setScale(scale);
// Add the icons to our list
tutorials_list->setIcons(m_icon_bank);
// Re-build track list everytime (accounts for locking changes, etc.)
w->clearItems();
//tutorials_list->clearItems();
const std::vector<const Challenge*>& activeChallenges = unlock_manager->getActiveChallenges();
const std::vector<const Challenge*>& solvedChallenges = unlock_manager->getUnlockedFeatures();
const std::vector<const Challenge*>& lockedChallenges = unlock_manager->getLockedChallenges();
/* const std::vector<const Challenge*>& activeTutorials = tutorial_manager->getActiveChallenges();
const std::vector<const Challenge*>& solvedTutorials = tutorial_manager->getUnlockedFeatures();
const std::vector<const Challenge*>& lockedTutorials = tutorial_manager->getLockedChallenges();
const int activeChallengeAmount = activeChallenges.size();
const int solvedChallengeAmount = solvedChallenges.size();
const int lockedChallengeAmount = lockedChallenges.size();
const int activeTutorialAmount = activeTutorials.size();
const int solvedTutorialAmount = solvedTutorials.size();
const int lockedTutorialAmount = lockedTutorials.size();
*/
for (int n=0; n<activeChallengeAmount; n++)
// FIXME Hard coded tutorial options
tutorials_list->addItem(BASIC_DRIVING, " Basic Driving" , 0);
tutorials_list->addItem(SHARP_TURN, " Sharp Turn" , 0);
tutorials_list->addItem(NITRO, " Nitro" , 0 );
tutorials_list->addItem(COLLECTIBLE_WEAPONS, " Collectible Weapons" , 0);
tutorials_list->addItem(SHOOTING_BACKWARDS, " Shooting Backwards" , 0);
/* for (int i=0;i<5;i++)
{
w->addItem(activeChallenges[n]->getName() + L"\n" + activeChallenges[n]->getChallengeDescription(),
activeChallenges[n]->getId(), "/gui/tutorial.png");
}
for (int n=0; n<solvedChallengeAmount; n++)
{
// TODO : add bronze/silver/gold difficulties to challenges
w->addItem(solvedChallenges[n]->getName() + L"\n" + solvedChallenges[n]->getChallengeDescription(),
solvedChallenges[n]->getId(), "/textures/cup_gold.png");
}
for (int n=0; n<lockedChallengeAmount; n++)
{
w->addItem( _("Locked : solve active tutorial to gain access to more!"), "locked",
"/gui/tutorial.png", LOCKED_BADGE);
//KeyboardConfig *config = input_manager->getDeviceList()->getKeyboardConfig(i);
std::ostringstream kbname;
kbname << "keyboard" << i;
const std::string internal_name = kbname.str();
//FIXME: I18N: since irrLicht's list widget has the nasty tendency to put the
// icons very close to the text, I'm adding spaces to compensate...
}
// tutorials_list->updateItemDisplay();
w->updateItemDisplay();
if (w->getItems().empty())
/* if (tutorials_list->getItems().empty())
{
fprintf(stderr, "Error, no tutorial!\n");
return;
}
w->setSelection(0 /* whatever is first */, PLAYER_ID_GAME_MASTER, true /* focus it */);
}*/
//tutorials_list->setSelection(0 /* whatever is first */, PLAYER_ID_GAME_MASTER, true /* focus it */);
}
// ------------------------------------------------------------------------------------------------------
@ -115,15 +134,104 @@ void TutorialScreen::eventCallback(GUIEngine::Widget* widget, const std::string&
{
StateManager::get()->escapePressed();
}
else if (name == "tutorial")
else if (name == "tutorials")
{
DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("tutorial");
ListWidget* tutorials = this->getWidget<ListWidget>("tutorials");
const std::string& selection = tutorials->getSelectionInternalName();
if (selection == BASIC_DRIVING)
{
//FIXME: simplify and centralize race start sequence!!
// Verify the kart in the config exists
if (kart_properties_manager->getKart(UserConfigParams::m_default_kart) == NULL)
{
UserConfigParams::m_default_kart.revertToDefaults();
}
// Use latest used device
InputDevice* device = input_manager->getDeviceList()->getLatestUsedDevice();
// Create player and associate player with device (FIXME: ask for player ident)
StateManager::get()->createActivePlayer( UserConfigParams::m_all_players.get(0), device );
// Set up race manager appropriately
race_manager->setNumLocalPlayers(1);
race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart);
// ASSIGN should make sure that only input from assigned devices is read.
input_manager->getDeviceList()->setAssignMode(ASSIGN);
// Go straight to the race
StateManager::get()->enterGameState();
// Initialise global data - necessary even in local games to avoid
// many if tests in other places (e.g. if network_game call
// network_manager else call race_manager).
network_manager->initCharacterDataStructures();
// Launch tutorial
//tutorial_manager->getTutorial(selection)->setRace();
// FIXME this code have to be in Tutorial class (and loaded from file xD)
RaceManager::MajorRaceModeType m_major;
RaceManager::MinorRaceModeType m_minor;
RaceManager::Difficulty m_difficulty;
m_minor = RaceManager::MINOR_MODE_NORMAL_RACE;
m_major = RaceManager::MAJOR_MODE_SINGLE;
m_difficulty = RaceManager::RD_EASY;
race_manager->setMinorMode(m_minor);
race_manager->setMajorMode(m_major);
race_manager->setTrack((std::string)"canyon");
race_manager->setDifficulty(m_difficulty);
race_manager->setNumLaps(1);
race_manager->setNumKarts(1);
race_manager->setNumPlayers(1);
race_manager->setNumLocalPlayers(1);
//race_manager->setCoinTarget(m_energy);
// Sets up kart info, including random list of kart for AI
network_manager->setupPlayerKartInfo();
race_manager->startNew();
}
else if (name == SHARP_TURN)
{
}
else if (name == NITRO)
{
}
else if (name == COLLECTIBLE_WEAPONS)
{
}
else if (name == SHOOTING_BACKWARDS)
{
}
}
}
/*int i = -1, read = 0;
read = sscanf( selection.c_str(), "gamepad%i", &i );
if (read == 1 && i != -1)
{
OptionsScreenInput2::getInstance()->setDevice( input_manager->getDeviceList()->getGamepadConfig(i) );
StateManager::get()->replaceTopMostScreen(OptionsScreenInput2::getInstance());
//updateInputButtons( input_manager->getDeviceList()->getGamepadConfig(i) );
}
else
{
std::cerr << "Cannot read internal gamepad input device ID : " << selection.c_str() << std::endl;
}*/
/* DynamicRibbonWidget* w = this->getWidget<DynamicRibbonWidget>("tutorial");
assert( w != NULL );
// only player 0 can start a challenge (i.e. we have no multiplayer tutorial)
std::string selection = w->getSelectionIDString( PLAYER_ID_GAME_MASTER );
if (selection == "locked")
/*if (selection == "locked")
{
unlock_manager->playLockSound();
}
@ -164,9 +272,9 @@ void TutorialScreen::eventCallback(GUIEngine::Widget* widget, const std::string&
// Sets up kart info, including random list of kart for AI
network_manager->setupPlayerKartInfo();
race_manager->startNew();
}
//}
}
}
}*/
// ------------------------------------------------------------------------------------------------------

View File

@ -21,13 +21,26 @@
#include "irrlicht.h"
#include "guiengine/screen.hpp"
#include "utils/ptr_vector.hpp"
#include "guiengine/CGUISpriteBank.h"
using namespace irr::core;
const std::string BASIC_DRIVING = "bd";
const std::string SHARP_TURN = "st";
const std::string NITRO = "nt";
const std::string COLLECTIBLE_WEAPONS = "cw";
const std::string SHOOTING_BACKWARDS = "sb";
class TutorialScreen : public GUIEngine::Screen, public GUIEngine::ScreenSingleton<TutorialScreen>
{
{
friend class GUIEngine::ScreenSingleton<TutorialScreen>;
TutorialScreen();
irr::gui::STKModifiedSpriteBank* m_icon_bank;
public:
/** \brief implement callback from parent class GUIEngine::Screen */

View File

@ -27,12 +27,12 @@
#include <vector>
#include <fstream>
#include <irrlicht.h>
// SuperTuxKart includes
#include "utils/no_copy.hpp"
using namespace std; // To avoid using std:: all the time
using namespace irr::core;
class XMLNode;
enum REWARD_TYPE
@ -42,14 +42,14 @@ enum REWARD_TYPE
UNLOCK_KART,
UNLOCK_DIFFICULTY};
struct UnlockableFeature
/*struct UnlockableFeature
{
string name; // internal name
irr::core::stringw user_name; // not all types of feature have one
stringw user_name; // not all types of feature have one
REWARD_TYPE type;
const irr::core::stringw getUnlockedMessage() const;
};
const stringw getUnlockedMessage() const;
};*/
/**
@ -59,61 +59,62 @@ struct UnlockableFeature
class Tutorial : public NoCopy
{
private:
enum {CH_INACTIVE, // challenge not yet possible
// TBR ????
enum {CH_INACTIVE, // tutorial not yet possible
CH_ACTIVE, // challenge possible, but not yet solved
CH_SOLVED} m_state; // challenge was solved
string m_Id; // short, internal name for this tutorial
irr::core::stringw m_Name; // name used in menu for this tutorial
irr::core::stringw m_challenge_description; // Message the user gets when the feature is not yet unlocked
vector<UnlockableFeature> m_feature; // Features to unlock
vector<string> m_prerequisites; // what needs to be done before accessing this tutorial
std::string m_Id; // short, internal name for this tutorial
irr::core::stringw m_Name; // name used in menu for this tutorial
irr::core::stringw m_challenge_description; // Message the user gets when the feature is not yet unlocked
// vector<UnlockableFeature> m_feature; // Features to unlock
// vector<string> m_prerequisites; // what needs to be done before accessing this tutorial
public:
// Constructors + Destructor
Tutorial(const string &id, const string &name);
Tutorial(const std::string &id, const std::string &name);
Tutorial() {m_Id=""; m_Name="";m_state=CH_INACTIVE;}
virtual ~Tutorial() {};
const string &getId() const { return m_Id; }
const irr::core::stringw &getName() const { return m_Name; }
void setName(const irr::core::stringw & s) { m_Name = s; }
void setId(const string& s) { m_Id = s; }
void addUnlockTrackReward(const string &track_name);
void addUnlockModeReward(const string &internal_mode_name,
const std::string &getId() const { return m_Id;}
irr::core::stringw getName() const { return m_Name;}
void setName(const irr::core::stringw & s) { m_Name = s;}
void setId(const std::string& s) { m_Id = s;}
void addUnlockTrackReward(const std::string &track_name);
void addUnlockModeReward(const std::string &internal_mode_name,
const irr::core::stringw &user_mode_name);
void addUnlockGPReward(const string &gp_name);
void addUnlockDifficultyReward(const string &internal_name,
/* void addUnlockGPReward(const std::string &gp_name);
void addUnlockDifficultyReward(const std::string &internal_name,
const irr::core::stringw &user_name);
void addUnlockKartReward(const string &internal_name,
void addUnlockKartReward(const std::string &internal_name,
const irr::core::stringw &user_name);
const vector<UnlockableFeature>&
/*const vector<UnlockableFeature>&
getFeatures() const { return m_feature; }
void setChallengeDescription(const irr::core::stringw& d)
{m_challenge_description=d; }
const irr::core::stringw&
getChallengeDescription() const {return m_challenge_description; }
void addDependency(const string id) {m_prerequisites.push_back(id); }
void addDependency(const std::string id) {m_prerequisites.push_back(id); }
bool isSolved() const {return m_state==CH_SOLVED; }
bool isActive() const {return m_state==CH_ACTIVE; }
void setSolved() {m_state = CH_SOLVED; }
void setActive() {m_state = CH_ACTIVE; }
const vector<string>&
const vector<std::string>&
getPrerequisites() const {return m_prerequisites; }
void load(const XMLNode* config);
void save(ofstream& writer);
// These functions are meant for customisation, e.g. load/save
// additional state information specific to the challenge
virtual void loadAdditionalInfo(const XMLNode* config) {};
virtual void saveAdditionalInfo(ofstream& writer) {};
// additional state information specific to the tutorial
virtual void loadAdditionalInfo(const XMLNode* config) {};
virtual void saveAdditionalInfo(ofstream& writer) {};
// These functions are called when a race/gp is finished. It allows
// the challenge to unlock features (when returning true), otherwise
// the feature remains locked.
virtual bool raceFinished() {return false;} // end of a race
virtual bool grandPrixFinished() {return false;} // end of a GP
//virtual bool grandPrixFinished() {return false;} // end of a GP
/** sets the right parameters in RaceManager to try this tutorial */
virtual void setRace() const = 0;

View File

@ -1,11 +1,406 @@
#include "tutorial_manager.hpp"
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Alejandro Santiago
//
// 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 "tutorial/tutorial_manager.hpp"
#include <set>
#include <string>
#include <vector>
#include <stdio.h>
#include "audio/sfx_base.hpp"
#include "audio/sfx_manager.hpp"
#include "config/user_config.hpp"
#include "io/file_manager.hpp"
#include "karts/kart_properties_manager.hpp"
#include "race/race_manager.hpp"
#include "tracks/track_manager.hpp"
#include "utils/string_utils.hpp"
TutorialManager* tutorial_manager=0;
//-----------------------------------------------------------------------------
TutorialManager::TutorialManager()
{
//ctor
}
// The global variable 'tutorial_manager' is needed in the tutorials,
// but it's not set yet - so we define it here (and it gets re-assign
// in main).
tutorial_manager=this;
m_locked_sound = sfx_manager->createSoundSource("locked");
// FIXME : Read tutorials from .../data
// -----------------------------
//std::set<std::string> result;
//file_manager->listFiles(result, "data");
//for(std::set<std::string>::iterator i = result.begin();
// i != result.end() ; i++)
//{
// if (StringUtils::hasSuffix(*i, ".challenge"))
// addChallenge(file_manager->getDataFile(*i));
//} // for i
//// Read tutorials from .../data/tracks/*
//// --------------------------------------
//const std::vector<std::string> *all_track_dirs = track_manager->getAllTrackDirs();
//for(std::vector<std::string>::const_iterator dir=all_track_dirs->begin();
// dir!=all_track_dirs->end(); dir++)
//{
// std::set<std::string> all_files;
// file_manager->listFiles(all_files, *dir, /*is_full_path*/ true);
// for(std::set<std::string>::iterator file=all_files.begin();
// file!=all_files.end(); file++)
// {
// if(!StringUtils::hasSuffix(*file,".challenge")) continue;
// std::string filename=*dir+"/"+*file;
// FILE *f=fopen(filename.c_str(), "r");
// if(f)
// {
// fclose(f);
// ChallengeData* newChallenge = NULL;
// try
// {
// newChallenge = new ChallengeData(filename);
// }
// catch (std::runtime_error& ex)
// {
// std::cerr << "\n/!\\ An error occurred while loading challenge file '" << filename << "' : "
// << ex.what() << " : challenge will be ignored.\n\n";
// continue;
// }
// addChallenge(newChallenge);
// } // if file
// } // for file in files
//} // for dir in all_track_dirs
//// Load challenges from .../data/karts (FIXME: the code below is just copied and pasted from above xD)
//// -----------------------------------
//const std::vector<std::string> *all_kart_dirs =
// kart_properties_manager->getAllKartDirs();
//// Find out which characters are available and load them
//for(std::vector<std::string>::const_iterator dir = all_kart_dirs->begin();
// dir != all_kart_dirs->end(); dir++)
//{
// std::set<std::string> all_files;
// file_manager->listFiles(all_files, *dir, /*is_full_path*/ true);
// for(std::set<std::string>::iterator file=all_files.begin();
// file!=all_files.end(); file++)
// {
// if(!StringUtils::hasSuffix(*file,".challenge")) continue;
// std::string filename=*dir+"/"+*file;
// FILE *f=fopen(filename.c_str(), "r");
// if(f)
// {
// fclose(f);
//
// ChallengeData* newChallenge = NULL;
// try
// {
// newChallenge = new ChallengeData(filename);
// }
// catch (std::runtime_error& ex)
// {
// std::cerr << "\n/!\\ An error occurred while loading challenge file '" << filename << "' : "
// << ex.what() << " : challenge will be ignored.\n\n";
// continue;
// }
// addChallenge(newChallenge);
// } // if file
// } // for file in files
//} // for dir in all_karts_dirs
//// Challenges from .../data/grandprix
//// ----------------------------------
//file_manager->listFiles(result, "data/grandprix");
//for(std::set<std::string>::iterator i = result.begin();
// i != result.end() ; i++)
//{
// if (StringUtils::hasSuffix(*i, ".challenge"))
// addChallenge(file_manager->getDataFile("grandprix/"+*i));
//} // for i
//// Hard coded challenges can be added here.
//computeActive(); //FIXME: 'load' calls 'computeActive', not sure this call here is needed
load();
} // UnlockManager
/*-----------------------------------------------------------------------------
** Saves the challenge status.
*/
TutorialManager::~TutorialManager()
{
//dtor
//save();
// sfx_manager is destroyed before UnlockManager is, so SFX will be already deleted
// sfx_manager->deleteSFX(m_locked_sound);
} // ~UnlockManager
//-----------------------------------------------------------------------------
void TutorialManager::addTutorial(Tutorial * m_tutorial)
{
m_all_tutorials[m_tutorial->getId()]=m_tutorial;
} // addTutorial
//-----------------------------------------------------------------------------
void TutorialManager::addTutorial(const std::string& filename)
{
/* ChallengeData* newChallenge = NULL;
try
{
newChallenge = new ChallengeData(filename);
newChallenge->check();
}
catch (std::runtime_error& ex)
{
std::cerr << "\n/!\\ An error occurred while loading challenge file '" << filename << "' : "
<< ex.what() << " : challenge will be ignored.\n\n";
if (newChallenge != NULL) delete newChallenge;
return;
}
addChallenge(newChallenge);*/
} // addChallenge
//-----------------------------------------------------------------------------
std::vector<const Tutorial*> TutorialManager::getActiveTutorials()
{
computeActive();
std::vector<const Tutorial*> all_active;
//for(AllChallengesType::iterator i =m_all_challenges.begin();
// i!=m_all_challenges.end(); i++)
//{
// if(i->second->isActive()) all_active.push_back(i->second);
//}
return all_active;
} // getActiveChallenges
//-----------------------------------------------------------------------------
const Tutorial* TutorialManager::getTutorial(const std::string& id)
{
if(m_all_tutorials.find(id)==m_all_tutorials.end()) return NULL;
return m_all_tutorials[id];
} // getTutorial
/*-----------------------------------------------------------------------------
** This is called from user_config when reading the config file
*/
void TutorialManager::load()
{
const std::string filename=file_manager->getChallengeFile("challenges.xml");
XMLNode* root = file_manager->createXMLTree(filename);
if(!root || root->getName() != "challenges")
{
std::cerr << "Challenge file '" << filename << "' will be created."
<< std::endl;
save();
if (root) delete root;
return;
}
for(AllTutorialsType::iterator i = m_all_tutorials.begin();
i!= m_all_tutorials.end(); i++)
{
// i->second->load(root);
}
computeActive();
delete root;
} // load
//-----------------------------------------------------------------------------
void TutorialManager::save()
{
//std::ofstream challenge_file;
//std::string filename = file_manager->getChallengeFile("challenges.xml");
//challenge_file.open(filename.c_str());
//if(!challenge_file.is_open())
//{
// std::cerr << "Failed to open " << filename << " for writing, challenges won't be saved\n";
// return;
//}
//challenge_file << "<?xml version=\"1.0\"?>\n";
//challenge_file << "<challenges>\n";
//
//for(AllChallengesType::iterator i = m_all_challenges.begin();
// i!= m_all_challenges.end(); i++)
//{
// i->second->save(challenge_file);
//}
//
//challenge_file << "</challenges>\n\n";
//challenge_file.close();
} // save
void TutorialManager::playLockSound() const
{
m_locked_sound->play();
}
//-----------------------------------------------------------------------------
void TutorialManager::computeActive()
{
// for(AllChallengesType::iterator i =m_all_challenges.begin();
// i!=m_all_challenges.end(); i++)
// {
// // Changed challenge
// // -----------------
// if((i->second)->isSolved())
// {
// // The constructor calls computeActive, which actually locks
// // all features, so unlock the solved ones (and don't try to
// // save the state, since we are currently reading it)
//
// unlockFeature(i->second, /*save*/ false);
// continue;
// }
//
// // Otherwise lock the feature, and check if the challenge is active
// // ----------------------------------------------------------------
// lockFeature(i->second);
// std::vector<std::string> pre_req=(i->second)->getPrerequisites();
// bool allSolved=true;
// for(std::vector<std::string>::iterator pre =pre_req.begin();
// pre!=pre_req.end(); pre++)
// {
// const Challenge*p = getChallenge(*pre);
// if(!p)
// {
// fprintf(stderr,"Challenge prerequisite '%s' of '%s' not found - ignored\n",
// pre->c_str(), i->first.c_str());
// //continue;
// allSolved=false;
// break;
// }
// else if(!p->isSolved())
// {
// allSolved=false;
// break;
// }
// } // for all pre in pre_req
// if(allSolved)
// {
// i->second->setActive();
// } // if solved
// } // for i
// clearUnlocked();
//
} // computeActive
/*-----------------------------------------------------------------------------
** This is called when a race is finished. Call all active challenges
*/
//void TutorialManager::raceFinished()
//{
// //for(AllChallengesType::iterator i =m_all_challenges.begin();
// // i!=m_all_challenges.end(); i++)
// //{
// // if(i->second->isActive() && i->second->raceFinished())
// // {
// // unlockFeature(i->second);
// // } // if isActive && challenge solved
// //}
// //race_manager->setCoinTarget(0); //reset
//} // raceFinished
////-----------------------------------------------------------------------------
//void UnlockManager::grandPrixFinished()
//{
// for(AllChallengesType::iterator i =m_all_challenges.begin();
// i!=m_all_challenges.end(); i++)
// {
// if(i->second->isActive() && i->second->grandPrixFinished())
// {
// std::cout << "===== A FEATURE WAS UNLOCKED BECAUSE YOU WON THE GP!! ==\n";
// unlockFeature(i->second);
// }
// }
// race_manager->setCoinTarget(0);
//} // grandPrixFinished
////-----------------------------------------------------------------------------
//void UnlockManager::lockFeature(Challenge* challenge)
//{
// const unsigned int amount = (unsigned int)challenge->getFeatures().size();
// for(unsigned int n=0; n<amount; n++)
// m_locked_features[challenge->getFeatures()[n].name]=true;
//} // lockFeature
//
////-----------------------------------------------------------------------------
//void UnlockManager::unlockFeature(Challenge* c, bool do_save)
//{
// const unsigned int amount = (unsigned int)c->getFeatures().size();
// for(unsigned int n=0; n<amount; n++)
// {
// std::string feature = c->getFeatures()[n].name;
// std::map<std::string,bool>::iterator p=m_locked_features.find(feature);
// if(p==m_locked_features.end())
// {
// //fprintf(stderr,"Unlocking feature '%s' failed: feature is not locked.\n",
// // (feature).c_str());
// return;
// }
// m_locked_features.erase(p);
// }
//
// // Add to list of recently unlocked features
// m_unlocked_features.push_back(c);
// c->setSolved(); // reset isActive flag
//
// // Save the new unlock information
// if(do_save) save();
//} // unlockFeature
//
////-----------------------------------------------------------------------------
//bool UnlockManager::isLocked(const std::string& feature)
//{
// return m_locked_features.find(feature)!=m_locked_features.end();
//} // featureIsLocked
////-----------------------------------------------------------------------------
//const std::vector<const Challenge*> UnlockManager::getUnlockedFeatures()
//{
// std::vector<const Challenge*> out;
//
// for(AllChallengesType::const_iterator i =m_all_challenges.begin();
// i!=m_all_challenges.end(); i++)
// {
// if (i->second->isSolved()) out.push_back(i->second);
// }
//
// return out;
//}
////-----------------------------------------------------------------------------
//const std::vector<const Challenge*> UnlockManager::getLockedChallenges()
//{
// std::vector<const Challenge*> out;
//
// for(AllChallengesType::const_iterator i =m_all_challenges.begin();
// i!=m_all_challenges.end(); i++)
// {
// if (!i->second->isSolved() && !i->second->isActive()) out.push_back(i->second);
// }
//
// return out;
//}

View File

@ -28,7 +28,6 @@
class XMLNode;
class SFXBase;
using namespace std;
/**
* \brief main class to handle the tutorials list
* \ingroup tutorial
@ -36,11 +35,13 @@ using namespace std;
class TutorialManager : public NoCopy
{
private:
SFXBase *m_locked_sound;
typedef map<string, Tutorial*> AllChallengesType;
AllChallengesType m_all_tutorial;
map<string, bool> m_locked_tutorials;
vector<const Tutorial*> m_unlocked_tutorials;
typedef std::map<std::string, Tutorial*> AllTutorialsType;
SFXBase *m_locked_sound;
AllTutorialsType m_all_tutorials;
std::map<std::string, bool> m_locked_tutorials;
std::vector<const Tutorial*> m_unlocked_tutorials;
void computeActive ();
void load ();
@ -49,8 +50,8 @@ private:
public:
TutorialManager ();
~TutorialManager ();
void addTutorial (Tutorial *t);
void addTutorial (const string& filename);
void addTutorial (Tutorial * m_tutorial);
void addTutorial (const std::string& filename);
void save ();
vector<const Tutorial*> getActiveTutorials();
@ -67,12 +68,12 @@ public:
/** Returns the list of currently inaccessible (locked) challenges */
const vector<const Tutorial*> getLockedTutorials();
const Tutorial *getTutorial (const string& id);
const Tutorial *getTutorial (const std::string& id);
void raceFinished ();
/*void raceFinished ();
void grandPrixFinished ();
void lockFeature (Tutorial* tutorial);
bool isLocked (const string& feature);
bool isLocked (const string& feature);*/
/** Eye- (or rather ear-) candy. Play a sound when user tries to access a locked area */
void playLockSound() const;