Back to index

extremetuxracer  0.5beta
player.cpp
Go to the documentation of this file.
00001 /* 
00002  * Extreme Tux Racer
00003  * Copyleft 2007-2008 The ETR Team <http://www.extremetuxracer.com/>
00004  * 
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018  */
00019 
00020 #include "player.h"
00021 #include "model_hndl.h"
00022 #include "game_config.h"
00023 #include "course_load.h"
00024 
00025 #define PLAYER_MAX_LIVES 5
00026 
00027 Player players[1];
00028 
00029 PlayerCourseData::PlayerCourseData()
00030  : won(false), time(0.0), herring(0), score(0)
00031 {      
00032 }
00033 
00034 bool
00035 PlayerCourseData::update(double time,int herring,int score, bool won)
00036 {
00037        this->won=won;
00038        if(this->score<score){
00039               this->time=time;
00040               this->herring=herring;
00041               this->score=score;
00042               return true;
00043        }
00044        return false;
00045 }
00046 
00047 PlayerEventData::PlayerEventData()
00048  : won(false), loaded(false)
00049 {      
00050 }
00051 
00052 bool
00053 PlayerEventData::isCupWon(std::string cup)
00054 {
00055        std::map<std::string,PlayerCupData>::iterator it;
00056        
00057        if((it=cups.find(cup))!=cups.end()){
00058               return (*it).second.won;
00059        }else{
00060               return false; 
00061        }      
00062 }
00063 
00064 bool
00065 PlayerEventData::getCupCourseData(std::string cup,
00066                                    std::string course,
00067                                    PlayerCourseData& data)
00068 {
00069        std::map<std::string,PlayerCupData>::iterator it;
00070        if( (it=cups.find(cup))!=cups.end() ){
00071               return (*it).second.getCupCourseData(course,data);
00072        }
00073        return false; 
00074 }
00075 
00076 bool
00077 PlayerEventData::updateCupCourseData(std::string cup,
00078                                    std::string course, 
00079                                    double time, 
00080                                    int herring,
00081                                    int score,
00082                                    bool won)
00083 {
00084        return cups[cup].updateCupCourseData(course,time,herring,score,won);
00085 }
00086 
00087 void
00088 PlayerEventData::setCupComplete(std::string cup)
00089 {
00090        cups[cup].won=true;  
00091 }
00092 
00093 void
00094 PlayerEventData::clearCupData(std::string cup)
00095 {
00096        std::map<std::string,PlayerCupData>::iterator it;
00097        if( (it=cups.find( cup ))!=cups.end() ){
00098               cups.erase(it);
00099        }      
00100 }
00101 
00102 void
00103 PlayerEventData::saveData(std::ofstream& sfile)
00104 {
00105               sfile << won << std::endl;
00106               sfile << cups.size() << std::endl;
00107               if(cups.size()>0){   
00108                      std::map<std::string,PlayerCupData>::iterator it;
00109                      for(it=cups.begin(); it!=cups.end(); it++){
00110                             sfile << (*it).first << std::endl;
00111                             (*it).second.saveData(sfile);      
00112                      }
00113               }
00114 }
00115 
00116 void
00117 PlayerEventData::loadData(std::ifstream& sfile)
00118 {
00119        char buff[256];
00120        int numcups;
00121        
00122        sfile >> won;
00123        sfile >> numcups;
00124        for(int i=0; i<numcups; i++){      
00125               sfile.get();
00126               sfile.getline(buff,256);
00127               cups[buff].loadData(sfile);
00128        }
00129        loaded=true;
00130 }
00131 
00132 PlayerCupData::PlayerCupData()
00133  : won(false), loaded(false)
00134 {
00135 }
00136 
00137 bool
00138 PlayerCupData::getCupCourseData(std::string course,
00139                                           PlayerCourseData& data)
00140 {
00141        std::map<std::string,PlayerCourseData>::iterator it;
00142        if( (it=courses.find(course))!=courses.end() ){
00143               data = (*it).second;
00144               return true;
00145        }
00146        return false; 
00147 }
00148 
00149 bool
00150 PlayerCupData::updateCupCourseData(std::string course, 
00151                                    double time, 
00152                                    int herring,
00153                                    int score,
00154                                    bool won)
00155 {
00156        return courses[course].update(time,herring,score,won);
00157 }
00158 
00159 void
00160 PlayerCupData::saveData(std::ofstream& sfile)
00161 {
00162               sfile << won << std::endl;
00163               sfile << courses.size() << std::endl;
00164               if(courses.size()>0){
00165                      std::map<std::string,PlayerCourseData>::iterator it;
00166                      for(it=courses.begin(); it!=courses.end(); it++){
00167                             sfile << (*it).first << std::endl;
00168                             sfile << (*it).second.won << std::endl;
00169                             sfile << (*it).second.time << std::endl;
00170                             sfile << (*it).second.herring << std::endl;
00171                             sfile << (*it).second.score << std::endl;
00172                      }
00173               }
00174 }
00175 
00176 void
00177 PlayerCupData::loadData(std::ifstream& sfile)
00178 {
00179        char buff[256];
00180        int numcourses;
00181        
00182        sfile >> won;
00183        sfile >> numcourses;
00184        for(int i=0; i<numcourses; i++){   
00185               sfile.get();
00186               sfile.getline(buff,256);
00187               PlayerCourseData& course=courses[buff];
00188               sfile >> course.won;
00189               sfile >> course.time;
00190               sfile >> course.herring;
00191               sfile >> course.score;             
00192        }
00193        loaded = true;
00194 }
00195 
00196 Player::Player()
00197  : health(100), loaded(false)
00198 {
00199 }
00200        
00201 Player::~Player()
00202 {      
00203 }
00204 
00205 bool
00206 Player::isCupComplete( std::string event,
00207                                           std::string cup)
00208 {
00209        std::map<std::string,PlayerEventData>::iterator it;     
00210        if( (it=events.find( event ))!=events.end() ){
00211               return (*it).second.isCupWon( cup );
00212        }else{
00213               return false; 
00214        }
00215 }
00216 
00217 bool
00218 Player::isFirstIncompleteCup( std::list<EventData>::iterator event,
00219                                           std::list<CupData>::iterator cup)
00220 {
00221        if (cup==(*event).cupList.begin()){
00222               //first cup in event always playable
00223               return true;
00224        } else {
00225               //check if previous cup was completed
00226               cup--;
00227               return isCupComplete((*event).name,(*cup).name);
00228        }
00229 }
00230 
00231 bool
00232 Player::getCupCourseData(std::string event,
00233                                    std::string cup,
00234                                    std::string course,
00235                                    PlayerCourseData& data)
00236 {
00237        std::map<std::string,PlayerEventData>::iterator it;
00238        if( (it=events.find( event ))!=events.end() ){
00239               return (*it).second.getCupCourseData(cup,course,data);
00240        }
00241        return false; 
00242 }
00243 
00244 bool
00245 Player::updateCupCourseData(std::string event,
00246                                    std::string cup,
00247                                    std::string course, 
00248                                    double time, 
00249                                    int herring,
00250                                    int score,
00251                                    bool won)
00252 {
00253        return events[event].updateCupCourseData(cup,course,time,herring,score,won);
00254 }
00255 
00256 void
00257 Player::setCupComplete(std::string event, std::string cup)
00258 {
00259        events[event].setCupComplete(cup); 
00260 }
00261        
00262 void
00263 Player::setEventComplete(std::string event)
00264 {
00265        events[event].won=true;     
00266 }
00267 
00268 void
00269 Player::clearCupData(std::string event, std::string cup)
00270 {
00271        std::map<std::string,PlayerEventData>::iterator it;
00272        if( (it=events.find( event ))!=events.end() ){
00273               (*it).second.clearCupData(cup);
00274        }
00275 }
00276 
00277 void
00278 Player::resetLives()
00279 {
00280        m_lives = INIT_NUM_LIVES;
00281 }
00282        
00283 int
00284 Player::getLives()
00285 {
00286        return m_lives;
00287 }
00288        
00289 void
00290 Player::decLives()
00291 {
00292        m_lives--;
00293 }
00294 
00295 void
00296 Player::incLives()
00297 {
00298        // todo:
00299        // in practicing mode incrementing lives should increase score
00300        if(m_lives < PLAYER_MAX_LIVES){
00301               m_lives++;
00302        }
00303 }
00304 
00305 
00306 
00307 bool
00308 Player::getOpenCourseData(std::string course, PlayerCourseData& data)
00309 {
00310        std::map<std::string,PlayerCourseData>::iterator it;
00311        
00312        if( (it=courses.find( course ))!=courses.end() ){
00313               data = (*it).second;
00314               return true;
00315        }
00316        return false;
00317 }
00318 
00319 bool
00320 Player::updateOpenCourseData(std::string course, double time, 
00321                                                         int herring, int score)
00322 {
00323        return courses[course].update(time,herring,score);
00324 }
00325 
00326 bool
00327 Player::saveData()
00328 {
00329        char buff[256];
00330 
00331     if (get_config_dir_name( buff, 255 ) != 0) {
00332               return false;
00333     }
00334        
00335        std::string filename(buff);
00336        
00337        filename+="/";
00338        //filename+=name;
00339        /*Load from same config for all different nicks, but save last used nick in file*/
00340        filename+="player";
00341        filename+=".sav";
00342        
00343        std::ofstream sfile(filename.c_str());
00344        
00345        if(name.compare("") == 0) {
00346               name="tux"; //Make sure the name isn't empty, since it causes errors in the loading.
00347        }
00348        
00349        sfile << "ETRacer SAVE " << FILE_VERSION << std::endl;
00350        sfile << "tux" << std::endl;
00351        sfile << "easy" << std::endl;
00352        sfile << 1 << std::endl;
00353        sfile << name << std::endl;
00354        sfile << ModelHndl->cur_model <<std::endl;
00355        sfile << courses.size() << std::endl;
00356        
00357        std::map<std::string,PlayerCourseData>::iterator it;
00358        
00359        for(it=courses.begin(); it!=courses.end(); it++){
00360               sfile << (*it).first << std::endl;
00361               sfile << (*it).second.time << std::endl;
00362               sfile << (*it).second.herring << std::endl;
00363               sfile << (*it).second.score << std::endl;
00364        }
00365        
00366        
00367        sfile << events.size() << std::endl;
00368        
00369        if(events.size()>0){
00370               std::map<std::string,PlayerEventData>::iterator it;
00371               for (it=events.begin(); it!=events.end(); it++){
00372                      sfile << (*it).first << std::endl; 
00373                      (*it).second.saveData(sfile);             
00374               }
00375        }
00376        
00377        return true;
00378 }
00379 
00380 bool
00381 Player::loadData()
00382 {
00383        char buff[256];
00384 
00385     if (get_config_dir_name( buff, 255 ) != 0) {
00386               return false;
00387     }
00388        
00389        std::string filename(buff);
00390               
00391        filename+="/";
00392        //filename+=name;
00393        /*Load from same config for all different nicks, but save last used nick in file*/
00394        filename+="player";
00395        filename+=".sav";
00396        
00397        std::ifstream sfile(filename.c_str());
00398        
00399        if(!sfile) return false;
00400        
00401        int version;
00402        int numcourses;
00403        int model;
00404        
00405        std::string notused;
00406                      
00407        sfile >> buff >> buff >> version;
00408        if(version==FILE_VERSION) {
00409               sfile >> notused; //character
00410               sfile >> notused; //difficulty
00411               sfile >> notused; //num difficulties
00412               sfile >> name;
00413               sfile >> model;
00414               sfile >> numcourses;
00415               
00416               for (int i=0; i<numcourses ;i++){
00417                      double time;
00418                      int herring;
00419                      int score;
00420                      sfile.get();  
00421                      sfile.getline(buff,256);
00422                      sfile >> time >> herring >> score;
00423                      PlayerCourseData& data = courses[buff];
00424                      data.time=time;
00425                      data.herring=herring;
00426                      data.score=score;           
00427               }
00428               
00429               int numevents;
00430               
00431               sfile >> numevents;
00432               for(int i=0; i<numevents; i++){    
00433                      sfile.get();
00434                      sfile.getline(buff,256);
00435                      events[buff].loadData(sfile);
00436               }
00437        } else {
00438               std::cout<<"File versions mismatch, sorry, saved data deleted"<<std::endl;
00439        }
00440        ModelHndl->load_model(model);
00441        loaded=true;
00442        return true;
00443 }
00444 
00445 
00446 float
00447 Player::getCoursePercentage()
00450 {
00451        if(pos.y<0){
00452               float x,y;    
00453               get_course_dimensions( &x,&y );
00454               float correction = 100/tan((get_course_angle())*M_PI/180.0);
00455               return (((-1)*pos.y)/y)*correction;
00456        }else{
00457               return 0;
00458        }
00459 }