Back to index

supertuxkart  0.5+dfsg1
collectable.cpp
Go to the documentation of this file.
00001 //  $Id: collectable.cpp 2111 2008-05-31 07:04:30Z cosmosninja $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2006 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 "collectable.hpp"
00021 #include "user_config.hpp"
00022 #include "race_manager.hpp"
00023 #include "projectile_manager.hpp"
00024 #include "kart.hpp"
00025 #include "sound_manager.hpp"
00026 #include "world.hpp"
00027 #include "stk_config.hpp"
00028 
00029 //-----------------------------------------------------------------------------
00030 Collectable::Collectable(Kart* kart_)
00031 {
00032     m_owner  = kart_;
00033     reset();
00034 }   // Collectable
00035 
00036 //-----------------------------------------------------------------------------
00037 void Collectable::reset()
00038 {
00039     if(race_manager->getRaceMode()==RaceManager::RM_TIME_TRIAL)
00040     {
00041         m_type   = COLLECT_ZIPPER;
00042         m_number = race_manager->getNumLaps();
00043     }
00044     else
00045     {
00046         m_type   = COLLECT_NOTHING;
00047         m_number = 0;
00048     }
00049 }   // reset
00050 
00051 //-----------------------------------------------------------------------------
00052 void Collectable::set(CollectableType type, int n)
00053 {
00054     if (m_type==type)
00055     {
00056         m_number+=n;
00057         return;
00058     }
00059     m_type=type;
00060     m_number=n;
00061 }  // set
00062 
00063 //-----------------------------------------------------------------------------
00064 Material *Collectable::getIcon()
00065 {
00066     // Check if it's one of the types which have a separate
00067     // data file which includes the icon:
00068     return collectable_manager->getIcon(m_type);
00069 }
00070 
00071 //-----------------------------------------------------------------------------
00072 void Collectable::use()
00073 {
00074     m_number--;
00075     switch (m_type)
00076     {
00077     case COLLECT_ZIPPER:   m_owner->handleZipper();
00078         break ;
00079     case COLLECT_HOMING:
00080     case COLLECT_SPARK:
00081     case COLLECT_MISSILE:
00082         if(m_owner->isPlayerKart())
00083             sound_manager->playSfx(SOUND_SHOT);
00084 
00085         projectile_manager->newProjectile(m_owner, m_type);
00086         break ;
00087 
00088     case COLLECT_ANVIL:
00089         //Attach an anvil(twice as good as the one given
00090         //by the bananas) to the kart in the 1st position.
00091         for(unsigned int i = 0 ; i < race_manager->getNumKarts(); ++i)
00092         {
00093             Kart *kart=world->getKart(i);
00094             if(kart->isEliminated()) continue;
00095             if(kart == m_owner) continue;
00096             if(kart->getPosition() == 1)
00097             {
00098                 kart->attach(ATTACH_ANVIL, stk_config->m_anvil_time);
00099                 kart->adjustSpeedWeight(stk_config->m_anvil_speed_factor*0.5f);
00100 
00101                 if(kart->isPlayerKart())
00102                     sound_manager->playSfx(SOUND_USE_ANVIL);
00103                 break;
00104             }
00105         }
00106 
00107         break;
00108 
00109     case COLLECT_PARACHUTE:
00110         {
00111             bool player_affected = false;
00112             //Attach a parachutte(that last as twice as the
00113             //one from the bananas) to all the karts that
00114             //are in front of this one.
00115             for(unsigned int i = 0 ; i < race_manager->getNumKarts(); ++i)
00116             {
00117                 Kart *kart=world->getKart(i);
00118                 if(kart->isEliminated() || kart== m_owner) continue;
00119                 if(m_owner->getPosition() > kart->getPosition())
00120                 {
00121                     kart->attach(ATTACH_PARACHUTE, stk_config->m_parachute_time_other);
00122 
00123                     if(kart->isPlayerKart())
00124                         player_affected = true;
00125                 }
00126 
00127             }
00128 
00129             if(player_affected)
00130                 sound_manager->playSfx(SOUND_USE_PARACHUTE);
00131         }
00132         break;
00133 
00134     case COLLECT_NOTHING:
00135     default :              break ;
00136     }
00137 
00138     if ( m_number <= 0 )
00139     {
00140         m_number = 0;
00141         m_type   = COLLECT_NOTHING;
00142     }
00143 }   // use
00144 
00145 //-----------------------------------------------------------------------------
00146 void Collectable::hitRedHerring(int n)
00147 {
00148     //The probabilities of getting the anvil or the parachute increase
00149     //depending on how bad the owner's position is. For the first
00150     //driver the posibility is none, for the last player is 15 %.
00151 
00152     if(m_owner->getPosition() != 1 && m_type == COLLECT_NOTHING)
00153     {
00154         const int SPECIAL_PROB = (int)(15.0 / ((float)world->getCurrentNumKarts() /
00155                                          (float)m_owner->getPosition()));
00156         const int RAND_NUM = rand()%100;
00157         if(RAND_NUM <= SPECIAL_PROB)
00158         {
00159             //If the driver in the first position has finished, give the driver
00160             //the parachute.
00161             for(unsigned int i=0; i < race_manager->getNumKarts(); ++i)
00162             {
00163                 Kart *kart = world->getKart(i);
00164                 if(kart->isEliminated() || kart == m_owner) continue;
00165                 if(kart->getPosition() == 1 && kart->raceIsFinished())
00166                 {
00167                     m_type = COLLECT_PARACHUTE;
00168                     m_number = 1;
00169                     return;
00170                 }
00171             }
00172 
00173             m_type = rand()%(2) == 0 ? COLLECT_ANVIL : COLLECT_PARACHUTE;
00174             m_number = 1;
00175             return;
00176         }
00177     }
00178 
00179     //rand() is moduled by COLLECT_MAX - 1 - 2 because because we have to
00180     //exclude the anvil and the parachute, but later we have to add 1 to prevent
00181     //having a value of 0 since that isn't a valid collectable.
00182     CollectableType newC;
00183     if(!user_config->m_profile)
00184     {
00185         newC = (CollectableType)(rand()%(COLLECT_MAX - 1 - 2) + 1);
00186     }
00187     else
00188       {   // for now: no collectables when profiling
00189         return;
00190         // No random effects when profiling!
00191         static int simpleCounter=-1;
00192         simpleCounter++;
00193         newC = (CollectableType)(simpleCounter%(COLLECT_MAX - 1 - 2) + 1);
00194     }
00195     if(m_type==COLLECT_NOTHING)
00196     {
00197         m_type=newC;
00198         m_number = n;
00199     }
00200     else if(newC==m_type)
00201     {
00202         m_number+=n;
00203         if(m_number > MAX_COLLECTABLES) m_number = MAX_COLLECTABLES;
00204     }
00205     // Ignore new collectable if it is different from the current one
00206 }   // hitRedHerring