Back to index

supertuxkart  0.5+dfsg1
unlock_manager.cpp
Go to the documentation of this file.
00001 //  $Id: challenge_manager.cpp 1259 2007-09-24 12:28:19Z hiker $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2008 Joerg Henrichs
00005 //
00006 //  This program is free software; you can redistribute it and/or
00007 //  modify it under the terms of the GNU General Public License
00008 //  as published by the Free Software Foundation; either version 2
00009 //  of the License, or (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020 #include "unlock_manager.hpp"
00021 #include "race_manager.hpp"
00022 
00023 #include "challenges/energy_math_class.hpp"
00024 #include "challenges/penguin_playground_gp.hpp"
00025 #include "challenges/race_track_time.hpp"
00026 #include "challenges/tollway_time.hpp"
00027 #include "challenges/jungle_follow.hpp"
00028 #include "challenges/energy_shifting_sands.hpp"
00029 #include "challenges/moon_and_back_gp.hpp"
00030 #include "challenges/city_time.hpp"
00031 #include "challenges/island_follow.hpp"
00032 #include "challenges/worlds_end_gp.hpp"
00033 #include "challenges/tollway_head2head.hpp"
00034 #include "user_config.hpp"
00035 
00036 UnlockManager* unlock_manager=0;
00037 //-----------------------------------------------------------------------------
00038 
00039 UnlockManager::UnlockManager()
00040 {
00041     // The global variable 'unlock_manager' is needed in the challenges,
00042     // but it's not set yet - so we define it here (and it gets re-assign
00043     // in main).
00044     unlock_manager=this;
00045 
00046     // Add all challenges:
00047     Challenge *c;
00048     c=new EnergyMathClass(); m_all_challenges[c->getId()]=c;
00049     c=new PenguinPlaygroundGP(); m_all_challenges[c->getId()]=c;
00050     c=new RaceTrackTime();   m_all_challenges[c->getId()]=c;
00051     c=new TollwayTime();     m_all_challenges[c->getId()]=c;
00052     c=new JungleFollow();    m_all_challenges[c->getId()]=c;
00053     c=new EnergyShiftingSands(); m_all_challenges[c->getId()]=c;
00054     c=new MoonAndBackGP();   m_all_challenges[c->getId()]=c;
00055     c=new CityTime();        m_all_challenges[c->getId()]=c;
00056     c=new IslandFollow();        m_all_challenges[c->getId()]=c;
00057     c=new WorldsEndGP();        m_all_challenges[c->getId()]=c;
00058     c=new TollwayHead2Head(); m_all_challenges[c->getId()]=c;
00059     
00060     computeActive();
00061 }   // UnlockManager
00062 
00063 //-----------------------------------------------------------------------------
00064 std::vector<const Challenge*> UnlockManager::getActiveChallenges()
00065 {
00066     computeActive();
00067     std::vector<const Challenge*> all_active;
00068     for(AllChallengesType::iterator i =m_all_challenges.begin(); 
00069                                     i!=m_all_challenges.end();  i++)
00070     {
00071         if(i->second->isActive()) all_active.push_back(i->second);
00072     }
00073     return all_active;
00074 }   // getActiveChallenges
00075 
00076 //-----------------------------------------------------------------------------
00077 Challenge* UnlockManager::getChallenge(const std::string& id)
00078 {
00079     if(m_all_challenges.find(id)==m_all_challenges.end()) return NULL;
00080     return m_all_challenges[id];
00081 }   // getChallenge
00082 
00083 //-----------------------------------------------------------------------------
00086 void UnlockManager::load(const lisp::Lisp* config)
00087 {
00088     for(AllChallengesType::iterator i =m_all_challenges.begin(); 
00089                                     i!=m_all_challenges.end();  i++)
00090     {
00091         i->second->load(config);
00092     }
00093     computeActive();
00094 }   // load
00095 
00096 //-----------------------------------------------------------------------------
00097 void UnlockManager::save(lisp::Writer* writer)
00098 {
00099     for(AllChallengesType::iterator i =m_all_challenges.begin(); 
00100                                     i!=m_all_challenges.end();  i++)
00101     {
00102         i->second->save(writer);
00103     }   // for i in m_all_challenges
00104 }   // save
00105 
00106 //-----------------------------------------------------------------------------
00107 void UnlockManager::computeActive()
00108 {
00109     for(AllChallengesType::iterator i =m_all_challenges.begin(); 
00110                                     i!=m_all_challenges.end();  i++)
00111     {
00112         // Changed challenge
00113         // -----------------
00114         if((i->second)->isSolved()) 
00115         {
00116             // The constructor calls computeActive, which actually locks 
00117             // all features, so unlock the solved ones (and don't try to
00118             // save the state, since we are currently reading it)
00119             
00120             unlockFeature(i->second, /*save*/ false);
00121             continue;
00122         }
00123 
00124         // Otherwise lock the feature, and check if the challenge is active
00125         // ----------------------------------------------------------------
00126         lockFeature(i->second);
00127         std::vector<std::string> pre_req=(i->second)->getPrerequisites();
00128         bool allSolved=true;
00129         for(std::vector<std::string>::iterator pre =pre_req.begin();
00130                                                pre!=pre_req.end(); pre++)
00131         {
00132             const Challenge*p = getChallenge(*pre);
00133             if(!p)
00134             {
00135                 fprintf(stderr,"Challenge prerequisite '%s' of '%s' not found - ignored\n",
00136                         pre->c_str(), i->first.c_str());
00137                 continue;
00138             }
00139             if(!p->isSolved())
00140             {
00141                 allSolved=false;
00142                 break;
00143             }
00144         }   // for all pre in pre_req
00145         if(allSolved)
00146         {
00147             i->second->setActive();
00148         }   // if solved
00149     }   // for i
00150     clearUnlocked();
00151 }   // computeActive
00152 
00153 //-----------------------------------------------------------------------------
00156 void UnlockManager::raceFinished()
00157 {
00158     for(AllChallengesType::iterator i =m_all_challenges.begin(); 
00159                                     i!=m_all_challenges.end();  i++)
00160     {
00161         if(i->second->isActive() && i->second->raceFinished())
00162         {
00163             unlockFeature(i->second);
00164         }   // if isActive && challenge solved
00165     }
00166     race_manager->setCoinTarget(0);  //reset
00167 }   // raceFinished
00168 
00169 //-----------------------------------------------------------------------------
00170 void UnlockManager::grandPrixFinished()
00171 {
00172     for(AllChallengesType::iterator i =m_all_challenges.begin(); 
00173                                     i!=m_all_challenges.end();  i++)
00174     {
00175         if(i->second->isActive() &&i->second->grandPrixFinished())
00176         {
00177             unlockFeature(i->second);
00178         }
00179     }
00180     race_manager->setCoinTarget(0);
00181 }   // grandPrixFinished
00182 
00183 //-----------------------------------------------------------------------------
00184 void UnlockManager::lockFeature(Challenge* challenge)
00185 {
00186     const unsigned int amount = challenge->getFeatures().size();
00187     for(unsigned int n=0; n<amount; n++)
00188         m_locked_features[challenge->getFeatures()[n].name]=true;
00189 }   // lockFeature
00190 
00191 //-----------------------------------------------------------------------------
00192 
00193 void UnlockManager::unlockFeature(Challenge* c, bool save)
00194 {
00195     const unsigned int amount = c->getFeatures().size();
00196     for(unsigned int n=0; n<amount; n++)
00197     {
00198         std::string feature = c->getFeatures()[n].name;
00199         std::map<std::string,bool>::iterator p=m_locked_features.find(feature);
00200         if(p==m_locked_features.end())
00201         {
00202             //fprintf(stderr,"Unlocking feature '%s' failed: feature is not locked.\n",
00203             //        (feature).c_str());
00204             return;
00205         }
00206         m_locked_features.erase(p);
00207     }
00208     
00209     // Add to list of recently unlocked features
00210     m_unlocked_features.push_back(c);
00211     c->setSolved();  // reset isActive flag
00212     
00213     // Save the new unlock information
00214     if(save) user_config->saveConfig();
00215 }   // unlockFeature
00216 
00217 //-----------------------------------------------------------------------------
00218 bool UnlockManager::isLocked(const std::string& feature)
00219 {
00220     return m_locked_features.find(feature)!=m_locked_features.end();
00221 }  // featureIsLocked