Back to index

supertuxkart  0.5+dfsg1
player_kart.cpp
Go to the documentation of this file.
00001 //  $Id: player_kart.cpp 2111 2008-05-31 07:04:30Z cosmosninja $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2004-2005 Steve Baker <sjbaker1@airmail.net>
00005 //  Copyright (C) 2006 Joerg Henrichs, Steve Baker
00006 //
00007 //  This program is free software; you can redistribute it and/or
00008 //  modify it under the terms of the GNU General Public License
00009 //  as published by the Free Software Foundation; either version 2
00010 //  of the License, or (at your option) any later version.
00011 //
00012 //  This program is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU General Public License
00018 //  along with this program; if not, write to the Free Software
00019 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020 
00021 #include "constants.hpp"
00022 #include "sound_manager.hpp"
00023 #include "player_kart.hpp"
00024 #include "player.hpp"
00025 #include "sdldrv.hpp"
00026 #include "herring.hpp"
00027 #include "world.hpp"
00028 #include "gui/menu_manager.hpp"
00029 #include "gui/race_gui.hpp"
00030 #include "translation.hpp"
00031 #include "scene.hpp"
00032 #include "camera.hpp"
00033 
00034 PlayerKart::PlayerKart(const std::string& kart_name, int position, Player *player,
00035                        sgCoord init_pos, int player_index) :
00036             Kart(kart_name, position, init_pos)
00037 {
00038     m_player       = player;
00039     m_penalty_time = 0.0f;
00040     m_camera       = scene->createCamera(player_index, this);
00041     m_camera->setMode(Camera::CM_NORMAL);
00042     reset();
00043 }   // PlayerKart
00044 
00045 //-----------------------------------------------------------------------------
00046 void PlayerKart::reset()
00047 {
00048     m_steer_val_l = 0;
00049     m_steer_val_r = 0;
00050     m_steer_val = 0;
00051     m_accel_val = 0;
00052     m_controls.accel = 0.0;
00053     m_controls.brake =false;
00054     m_controls.fire = false;
00055     m_controls.wheelie = false;
00056     m_controls.jump = false;
00057     m_penalty_time = 0;
00058     m_time_last_crash_sound = -10.0f;
00059     m_camera->setMode(Camera::CM_NORMAL);   // can be changed if camera was eliminated
00060     Kart::reset();
00061 }   // reset
00062 
00063 // ----------------------------------------------------------------------------
00064 void PlayerKart::action(KartAction action, int value)
00065 {
00066     switch (action)
00067     {
00068     case KA_LEFT:
00069         m_steer_val_l = -value;
00070         if (value)
00071           m_steer_val = -value;
00072         else
00073           m_steer_val = m_steer_val_r;
00074 
00075         break;
00076     case KA_RIGHT:
00077         m_steer_val_r = value;
00078         if (value)
00079           m_steer_val = value;
00080         else
00081           m_steer_val = m_steer_val_l;
00082 
00083         break;
00084     case KA_ACCEL:
00085         m_accel_val = value;
00086         break;
00087     case KA_BRAKE:
00088         if (value)
00089             m_accel_val = 0;
00090         m_controls.brake = (value!=0);  // This syntax avoid visual c++ warning (when brake=value)
00091         break;
00092     case KA_WHEELIE:
00093         m_controls.wheelie = (value!=0);
00094         break;
00095     case KA_RESCUE:
00096         m_controls.rescue = (value!=0);
00097         break;
00098     case KA_FIRE:
00099         m_controls.fire = (value!=0);
00100         break;
00101     case KA_LOOK_BACK:
00102         m_camera->setMode(value!=0 ? Camera::CM_REVERSE : Camera::CM_NORMAL);
00103         break;
00104     case KA_JUMP:
00105         m_controls.jump = (value!=0);
00106         break;
00107     }
00108 }   // action
00109 
00110 //-----------------------------------------------------------------------------
00111 void PlayerKart::steer(float dt, int steer_val)
00112 {
00113     const float STEER_CHANGE = dt/getTimeFullSteer();  // amount the steering is changed
00114     if (steer_val < 0)
00115     {
00116       // If we got analog values do not cumulate.
00117       if (steer_val > -32767)
00118         m_controls.lr = -steer_val/32767.0f;
00119       else
00120         m_controls.lr += STEER_CHANGE;
00121     }
00122     else if(steer_val > 0)
00123     {
00124       // If we got analog values do not cumulate.
00125       if (steer_val < 32767)
00126         m_controls.lr = -steer_val/32767.0f;
00127       else
00128         m_controls.lr -= STEER_CHANGE;
00129     }
00130     else
00131     {   // no key is pressed
00132         if(m_controls.lr>0.0f)
00133         {
00134             m_controls.lr -= STEER_CHANGE;
00135             if(m_controls.lr<0.0f) m_controls.lr=0.0f;
00136         }
00137         else
00138         {   // m_controls.lr<=0.0f;
00139             m_controls.lr += STEER_CHANGE;
00140             if(m_controls.lr>0.0f) m_controls.lr=0.0f;
00141         }   // if m_controls.lr<=0.0f
00142     }   // no key is pressed
00143 
00144     m_controls.lr = std::min(1.0f, std::max(-1.0f, m_controls.lr));
00145 
00146 }   // steer
00147 
00148 //-----------------------------------------------------------------------------
00149 void PlayerKart::update(float dt)
00150 {
00151     steer(dt, m_steer_val);
00152 
00153     m_controls.accel = m_accel_val / 32768.0f;
00154 
00155     if(world->isStartPhase())
00156     {
00157         if(m_controls.accel!=0.0 || m_controls.brake!=false ||
00158            m_controls.fire|m_controls.wheelie|m_controls.jump)
00159         {
00160             //JH Some sound here?
00161             m_penalty_time=1.0;
00162             // A warning gets displayed in RaceGUI
00163         }
00164         placeModel();
00165         return;
00166     }
00167     if(m_penalty_time>0.0)
00168     {
00169         m_penalty_time-=dt;
00170         return;
00171     }
00172 
00173     if ( m_controls.fire && !isRescue())
00174     {
00175         if (m_collectable.getType()==COLLECT_NOTHING) sound_manager->playSfx(SOUND_BEEP);
00176         // use() needs to be called even if there currently is no collecteable
00177         // since use() can test if something needs to be switched on/off.
00178         m_collectable.use() ;
00179         m_controls.fire = false;
00180     }
00181 
00182     // We can't restrict rescue to fulfil isOnGround() (which would be more like
00183     // MK), since e.g. in the City track it is possible for the kart to end
00184     // up sitting on a brick wall, with all wheels in the air :((
00185     if ( m_controls.rescue )
00186     {
00187         sound_manager -> playSfx ( SOUND_BEEP ) ;
00188         forceRescue();
00189         m_controls.rescue=false;
00190     }
00191 
00192     Kart::update(dt);
00193 }   // update
00194 
00195 //-----------------------------------------------------------------------------
00196 void PlayerKart::crashed()
00197 {
00198     Kart::crashed();
00199     // A collision is usually reported several times, even when hitting
00200     // something only once. This results in a kind of 'machine gun'
00201     // noise by playing the crash sound over and over again. To prevent
00202     // this, the crash sound is only played if there was at least 0.5
00203     // seconds since the last time it was played (for this kart)
00204     if(world->getTime() - m_time_last_crash_sound > 0.5f) 
00205     {
00206         sound_manager->playSfx( SOUND_CRASH );
00207         m_time_last_crash_sound = world->getTime();
00208     }
00209 }   // crashed
00210 
00211 //-----------------------------------------------------------------------------
00214 void PlayerKart::setPosition(int p)
00215 {
00216     if(getPosition()<p)
00217     {
00218         sound_manager->playSfx(SOUND_BEEP);
00219     }
00220     Kart::setPosition(p);
00221 }   // setPosition
00222 
00223 //-----------------------------------------------------------------------------
00224 void PlayerKart::handleZipper()
00225 {
00226     Kart::handleZipper();
00227     sound_manager->playSfx ( SOUND_WEE );
00228 }   // handleZipper
00229 
00230 //-----------------------------------------------------------------------------
00231 void PlayerKart::collectedHerring(Herring* herring)
00232 {
00233     Kart::collectedHerring(herring);
00234     sound_manager->playSfx ( ( herring->getType()==HE_GREEN ) ? SOUND_UGH:SOUND_GRAB);
00235 }   // collectedHerring
00236 
00237 //-----------------------------------------------------------------------------
00243 void PlayerKart::addMessages()
00244 {
00245     RaceGUI* m=menu_manager->getRaceMenu();
00246     // This can happen if the option menu is called, since the
00247     // racegui gets deleted
00248     if(!m) return;
00249 
00250     // 1) check if the player is going in the wrong direction
00251     // ------------------------------------------------------
00252     if(race_manager->getDifficulty()==RaceManager::RD_EASY)
00253     {
00254         float angle_diff = getCoord()->hpr[0] - world->m_track->m_angle[getSector()];
00255         if(angle_diff > 180.0f) angle_diff -= 360.0f;
00256         else if (angle_diff < -180.0f) angle_diff += 360.0f;
00257         // Display a warning message if the kart is going back way (unless
00258         // the kart has already finished the race).
00259         if ((angle_diff > 120.0f || angle_diff < -120.0f)   &&
00260             getVelocity().getY() > 0.0f  && !raceIsFinished() )
00261         {
00262             m->addMessage(_("WRONG WAY!"), this, -1.0f, 60);
00263         }  // if angle is too big
00264     }  // if difficulty easy
00265 
00266 }   // addMessages
00267 /* EOF */