Added first beta version of 'follow the leader' mode.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1683 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
0867675fb9
commit
68dae90d15
@ -21,6 +21,7 @@
|
|||||||
(parachute-done-fraction 0.7 ) ;; fraction of speed when lost will detach parachute
|
(parachute-done-fraction 0.7 ) ;; fraction of speed when lost will detach parachute
|
||||||
(bomb-time 30.0 ) ;; time till a bomb explodes
|
(bomb-time 30.0 ) ;; time till a bomb explodes
|
||||||
(bomb-time-increase -5.0 ) ;; time added to timer when bomb is passed on
|
(bomb-time-increase -5.0 ) ;; time added to timer when bomb is passed on
|
||||||
|
(leader-intervals 30 20 10) ;; Time till a kart is removed in follow leader mode
|
||||||
(anvil-time 2.0 ) ;; time an anvil is active
|
(anvil-time 2.0 ) ;; time an anvil is active
|
||||||
(zipper-time 3.0 ) ;; time a zipper is active
|
(zipper-time 3.0 ) ;; time a zipper is active
|
||||||
(zipper-force 800.0 ) ;; additional zipper force
|
(zipper-force 800.0 ) ;; additional zipper force
|
||||||
|
@ -38,6 +38,7 @@ supertuxkart_SOURCES = main.cpp \
|
|||||||
music_ogg.cpp music_ogg.hpp \
|
music_ogg.cpp music_ogg.hpp \
|
||||||
music_information.cpp music_information.hpp \
|
music_information.cpp music_information.hpp \
|
||||||
sfx_openal.cpp sfx_openal.hpp \
|
sfx_openal.cpp sfx_openal.hpp \
|
||||||
|
smoke.cpp smoke.hpp \
|
||||||
input.hpp \
|
input.hpp \
|
||||||
isect.cpp isect.hpp \
|
isect.cpp isect.hpp \
|
||||||
track.cpp track.hpp \
|
track.cpp track.hpp \
|
||||||
@ -95,6 +96,7 @@ supertuxkart_SOURCES = main.cpp \
|
|||||||
challenges/all_tracks.cpp challenges/all_tracks.hpp \
|
challenges/all_tracks.cpp challenges/all_tracks.hpp \
|
||||||
challenges/energy_math_class.cpp challenges/energy_math_class.hpp\
|
challenges/energy_math_class.cpp challenges/energy_math_class.hpp\
|
||||||
challenges/win_gotm_cup.cpp challenges/win_gotm_cup.hpp \
|
challenges/win_gotm_cup.cpp challenges/win_gotm_cup.hpp \
|
||||||
|
challenges/race_track_time.cpp challenges/race_track_time.hpp\
|
||||||
lisp/lisp.cpp lisp/lisp.hpp \
|
lisp/lisp.cpp lisp/lisp.hpp \
|
||||||
lisp/lexer.cpp lisp/lexer.hpp \
|
lisp/lexer.cpp lisp/lexer.hpp \
|
||||||
lisp/parser.cpp lisp/parser.hpp \
|
lisp/parser.cpp lisp/parser.hpp \
|
||||||
@ -118,6 +120,7 @@ supertuxkart_SOURCES = main.cpp \
|
|||||||
gui/game_mode.cpp gui/game_mode.hpp \
|
gui/game_mode.cpp gui/game_mode.hpp \
|
||||||
gui/difficulty.cpp gui/difficulty.hpp \
|
gui/difficulty.cpp gui/difficulty.hpp \
|
||||||
gui/char_sel.cpp gui/char_sel.hpp \
|
gui/char_sel.cpp gui/char_sel.hpp \
|
||||||
|
gui/leader_result.cpp gui/leader_result.hpp \
|
||||||
gui/main_menu.cpp gui/main_menu.hpp \
|
gui/main_menu.cpp gui/main_menu.hpp \
|
||||||
gui/help_page_one.cpp gui/help_page_one.hpp \
|
gui/help_page_one.cpp gui/help_page_one.hpp \
|
||||||
gui/help_page_two.cpp gui/help_page_two.hpp \
|
gui/help_page_two.cpp gui/help_page_two.hpp \
|
||||||
|
@ -83,9 +83,11 @@ void Camera::setScreenPosition ( int numPlayers, int pos )
|
|||||||
Camera::Camera(int numPlayers, int which)
|
Camera::Camera(int numPlayers, int which)
|
||||||
: m_reverse(false)
|
: m_reverse(false)
|
||||||
{
|
{
|
||||||
m_which_kart = which; // Just for now
|
m_mode = CM_NORMAL;
|
||||||
m_mode = CM_NORMAL;
|
m_context = new ssgContext ;
|
||||||
m_context = new ssgContext ;
|
m_which_kart = which;
|
||||||
|
if(m_which_kart >= int(race_manager->getNumKarts()) || m_which_kart < 0 )
|
||||||
|
m_which_kart =0;
|
||||||
|
|
||||||
// FIXME: clipping should be configurable for slower machines
|
// FIXME: clipping should be configurable for slower machines
|
||||||
const Track* track = world->getTrack();
|
const Track* track = world->getTrack();
|
||||||
@ -101,7 +103,10 @@ Camera::Camera(int numPlayers, int which)
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Camera::setMode(Mode mode)
|
void Camera::setMode(Mode mode)
|
||||||
{
|
{
|
||||||
m_mode = mode;
|
m_mode = mode;
|
||||||
|
m_LastPitch = 0.0f;
|
||||||
|
if(m_mode==CM_LEADER_MODE)
|
||||||
|
setReverseHeading(true);
|
||||||
} // setMode
|
} // setMode
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -122,32 +127,44 @@ void Camera::reset()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Camera::update (float dt)
|
void Camera::update (float dt)
|
||||||
{
|
{
|
||||||
// Update the camera
|
|
||||||
if ( m_which_kart >= int(world->getNumKarts()) || m_which_kart < 0 ) m_which_kart = 0 ;
|
|
||||||
|
|
||||||
sgCoord kartcoord;
|
sgCoord kartcoord;
|
||||||
const Kart *kart=world->getPlayerKart(m_which_kart);
|
const Kart *kart;
|
||||||
sgCopyCoord(&kartcoord, world->getPlayerKart(m_which_kart)->getCoord());
|
// Update the camera
|
||||||
|
if(m_mode==CM_LEADER_MODE)
|
||||||
// Use the terrain pitch to avoid the camera following a wheelie the kart is doing
|
|
||||||
kartcoord.hpr[1]=RAD_TO_DEGREE( kart->getTerrainPitch(DEGREE_TO_RAD(kartcoord.hpr[0])) );
|
|
||||||
kartcoord.hpr[2] = 0;
|
|
||||||
// Only adjust the pitch if it's not the first frame (which is indicated by having
|
|
||||||
// dt=0). Otherwise the camera will change pitch during ready-set-go.
|
|
||||||
if(dt>0)
|
|
||||||
{
|
{
|
||||||
// If the terrain pitch is 'significantly' different from the camera angle,
|
kart=world->getKart(0);
|
||||||
// start adjusting the camera. This helps with steep declines, where
|
sgCopyCoord(&kartcoord, kart->getCoord());
|
||||||
// otherwise the track is not visible anymore.
|
// This gives a camera slightly above the kart, facing downwards
|
||||||
if(fabsf(kartcoord.hpr[1]-m_LastPitch)>1.0f) {
|
// But this works only when the karts are within a certain distance
|
||||||
kartcoord.hpr[1] = m_LastPitch + (kartcoord.hpr[1]-m_LastPitch)*2.0f*dt;
|
// otherwise only the track is seen :(
|
||||||
}
|
// kartcoord.xyz[2]+=3.0f; // raise camera
|
||||||
else
|
kartcoord.hpr[1]+=17; // face downwards
|
||||||
{
|
|
||||||
kartcoord.hpr[1]=m_LastPitch;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m_LastPitch = kartcoord.hpr[1];
|
else
|
||||||
|
{
|
||||||
|
kart=world->getPlayerKart(m_which_kart);
|
||||||
|
sgCopyCoord(&kartcoord, kart->getCoord());
|
||||||
|
|
||||||
|
// Use the terrain pitch to avoid the camera following a wheelie the kart is doing
|
||||||
|
kartcoord.hpr[1]=RAD_TO_DEGREE( kart->getTerrainPitch(DEGREE_TO_RAD(kartcoord.hpr[0])) );
|
||||||
|
kartcoord.hpr[2] = 0;
|
||||||
|
// Only adjust the pitch if it's not the first frame (which is indicated by having
|
||||||
|
// dt=0). Otherwise the camera will change pitch during ready-set-go.
|
||||||
|
if(dt>0)
|
||||||
|
{
|
||||||
|
// If the terrain pitch is 'significantly' different from the camera angle,
|
||||||
|
// start adjusting the camera. This helps with steep declines, where
|
||||||
|
// otherwise the track is not visible anymore.
|
||||||
|
if(fabsf(kartcoord.hpr[1]-m_LastPitch)>1.0f) {
|
||||||
|
kartcoord.hpr[1] = m_LastPitch + (kartcoord.hpr[1]-m_LastPitch)*2.0f*dt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kartcoord.hpr[1]=m_LastPitch;
|
||||||
|
}
|
||||||
|
} // dt>0.0
|
||||||
|
m_LastPitch = kartcoord.hpr[1];
|
||||||
|
} // m_mode!=CM_LEADER_MODE
|
||||||
|
|
||||||
if (m_mode == CM_SIMPLE_REPLAY)
|
if (m_mode == CM_SIMPLE_REPLAY)
|
||||||
kartcoord.hpr[0] = 0;
|
kartcoord.hpr[0] = 0;
|
||||||
@ -180,7 +197,7 @@ void Camera::update (float dt)
|
|||||||
}
|
}
|
||||||
else if (m_mode == CM_NO_FAKE_DRIFT)
|
else if (m_mode == CM_NO_FAKE_DRIFT)
|
||||||
{
|
{
|
||||||
const float STEER_OFFSET = world->getPlayerKart(m_which_kart)->getSteerAngle()*-10.0f;
|
const float STEER_OFFSET = kart->getSteerAngle()*-10.0f;
|
||||||
|
|
||||||
sgMat4 cam_rot;
|
sgMat4 cam_rot;
|
||||||
sgMat4 tmp;
|
sgMat4 tmp;
|
||||||
|
@ -36,9 +36,9 @@ public:
|
|||||||
CM_SIMPLE_REPLAY
|
CM_SIMPLE_REPLAY
|
||||||
};
|
};
|
||||||
protected:
|
protected:
|
||||||
ssgContext *m_context ;
|
ssgContext *m_context ;
|
||||||
|
|
||||||
int m_which_kart ;
|
int m_which_kart;
|
||||||
Mode m_mode;
|
Mode m_mode;
|
||||||
float m_last_steer_offset;
|
float m_last_steer_offset;
|
||||||
float m_x, m_y, m_w, m_h ;
|
float m_x, m_y, m_w, m_h ;
|
||||||
|
41
src/challenges/race_track_time.cpp
Executable file
41
src/challenges/race_track_time.cpp
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
// $Id: race_track_time.cpp 1259 2007-09-24 12:28:19Z hiker $
|
||||||
|
//
|
||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2008 Joerg Henrichs
|
||||||
|
//
|
||||||
|
// 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 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be ruseful,
|
||||||
|
// 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 <algorithm>
|
||||||
|
#include "challenges/race_track_time.hpp"
|
||||||
|
#include "world.hpp"
|
||||||
|
|
||||||
|
RaceTrackTime::RaceTrackTime() : Challenge("racetracktime", "Finish Race track in 1:15")
|
||||||
|
{
|
||||||
|
setChallengeDescription("Finish 3 laps in the Race track\nwith 3 AI karts\nin under 1:15 minutes.");
|
||||||
|
setFeatureDescription("New game mode\n'Follow Leader'\nnow available");
|
||||||
|
setFeature("followleader");
|
||||||
|
} // RaceTrackTime
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
bool RaceTrackTime::raceFinished()
|
||||||
|
{
|
||||||
|
std::string track_name = world->getTrack()->getIdent();
|
||||||
|
if(track_name!="race" ) return false; // wrong track
|
||||||
|
Kart* kart=world->getPlayerKart(0);
|
||||||
|
if(kart->getFinishTime()>75) return false; // too slow
|
||||||
|
if(kart->getLap()!=3 ) return false; // wrong number of laps
|
||||||
|
return true;
|
||||||
|
} // raceFinished
|
||||||
|
//-----------------------------------------------------------------------------
|
35
src/challenges/race_track_time.hpp
Executable file
35
src/challenges/race_track_time.hpp
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
// $Id: race_track_time.hpp 1259 2007-09-24 12:28:19Z hiker $
|
||||||
|
//
|
||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2008 Joerg Henrichs
|
||||||
|
//
|
||||||
|
// 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 2
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef HEADER_RACE_TRACK_TIME_H
|
||||||
|
#define HEADER_RACE_TRACK_TIME_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "challenges/challenge.hpp"
|
||||||
|
|
||||||
|
class RaceTrackTime : public Challenge
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RaceTrackTime();
|
||||||
|
virtual bool raceFinished();
|
||||||
|
}; // RaceTrackTime
|
||||||
|
|
||||||
|
#endif
|
@ -39,10 +39,10 @@ bool WinGOTMCup::grandPrixFinished()
|
|||||||
race_manager->getNumKarts() < 4 ||
|
race_manager->getNumKarts() < 4 ||
|
||||||
race_manager->getNumPlayers() > 1) return false;
|
race_manager->getNumPlayers() > 1) return false;
|
||||||
// Check if the player was number one:
|
// Check if the player was number one:
|
||||||
for(int i=0; i<(int)world->getNumKarts(); i++)
|
for(int i=0; i<(int)race_manager->getNumKarts(); i++)
|
||||||
{
|
{
|
||||||
const Kart* k=world->getKart(i);
|
const Kart* k=world->getKart(i);
|
||||||
if(k->isPlayerKart()) return k->getPosition()==1;
|
if(k->isPlayerKart() && !k->isEliminated()) return k->getPosition()==1;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} // raceFinished
|
} // raceFinished
|
||||||
|
@ -74,17 +74,17 @@ void Collectable::use()
|
|||||||
case COLLECT_ANVIL:
|
case COLLECT_ANVIL:
|
||||||
//Attach an anvil(twice as good as the one given
|
//Attach an anvil(twice as good as the one given
|
||||||
//by the bananas) to the kart in the 1st position.
|
//by the bananas) to the kart in the 1st position.
|
||||||
for(unsigned int i = 0 ; i < world->getNumKarts(); ++i)
|
for(unsigned int i = 0 ; i < race_manager->getNumKarts(); ++i)
|
||||||
{
|
{
|
||||||
if(world->getKart(i) == m_owner) continue;
|
Kart *kart=world->getKart(i);
|
||||||
if(world->getKart(i)->getPosition() == 1)
|
if(kart->isEliminated()) continue;
|
||||||
|
if(kart == m_owner) continue;
|
||||||
|
if(kart->getPosition() == 1)
|
||||||
{
|
{
|
||||||
world->getKart(i)->
|
kart->attach(ATTACH_ANVIL, stk_config->m_anvil_time);
|
||||||
attach(ATTACH_ANVIL, stk_config->m_anvil_time);
|
kart->adjustSpeedWeight(stk_config->m_anvil_speed_factor*0.5f);
|
||||||
|
|
||||||
world->getKart(i)->adjustSpeedWeight(stk_config->m_anvil_speed_factor*0.5f);
|
|
||||||
|
|
||||||
if(world->getKart(i)->isPlayerKart())
|
if(kart->isPlayerKart())
|
||||||
sound_manager->playSfx(SOUND_USE_ANVIL);
|
sound_manager->playSfx(SOUND_USE_ANVIL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -98,16 +98,15 @@ void Collectable::use()
|
|||||||
//Attach a parachutte(that last as twice as the
|
//Attach a parachutte(that last as twice as the
|
||||||
//one from the bananas) to all the karts that
|
//one from the bananas) to all the karts that
|
||||||
//are in front of this one.
|
//are in front of this one.
|
||||||
for(unsigned int i = 0 ; i < world->getNumKarts(); ++i)
|
for(unsigned int i = 0 ; i < race_manager->getNumKarts(); ++i)
|
||||||
{
|
{
|
||||||
if(world->getKart(i) == m_owner) continue;
|
Kart *kart=world->getKart(i);
|
||||||
if(m_owner->getPosition() > world->
|
if(kart->isEliminated() || kart== m_owner) continue;
|
||||||
getKart(i)->getPosition())
|
if(m_owner->getPosition() > kart->getPosition())
|
||||||
{
|
{
|
||||||
world->getKart(i)->attach(
|
kart->attach(ATTACH_PARACHUTE, stk_config->m_parachute_time_other);
|
||||||
ATTACH_PARACHUTE, stk_config->m_parachute_time_other);
|
|
||||||
|
|
||||||
if(world->getKart(i)->isPlayerKart())
|
if(kart->isPlayerKart())
|
||||||
player_affected = true;
|
player_affected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,18 +136,18 @@ void Collectable::hitRedHerring(int n)
|
|||||||
|
|
||||||
if(m_owner->getPosition() != 1 && m_type == COLLECT_NOTHING)
|
if(m_owner->getPosition() != 1 && m_type == COLLECT_NOTHING)
|
||||||
{
|
{
|
||||||
const int SPECIAL_PROB = (int)(15.0 / ((float)world->getNumKarts() /
|
const int SPECIAL_PROB = (int)(15.0 / ((float)world->getCurrentNumKarts() /
|
||||||
(float)m_owner->getPosition()));
|
(float)m_owner->getPosition()));
|
||||||
const int RAND_NUM = rand()%100;
|
const int RAND_NUM = rand()%100;
|
||||||
if(RAND_NUM <= SPECIAL_PROB)
|
if(RAND_NUM <= SPECIAL_PROB)
|
||||||
{
|
{
|
||||||
//If the driver in the first position has finished, give the driver
|
//If the driver in the first position has finished, give the driver
|
||||||
//the parachute.
|
//the parachute.
|
||||||
for(unsigned int i=0; i < world->getNumKarts(); ++i)
|
for(unsigned int i=0; i < race_manager->getNumKarts(); ++i)
|
||||||
{
|
{
|
||||||
if(world->getKart(i) == m_owner) continue;
|
Kart *kart = world->getKart(i);
|
||||||
if(world->getKart(i)->getPosition() == 1 && world->getKart(i)->
|
if(kart->isEliminated() || kart == m_owner) continue;
|
||||||
raceIsFinished())
|
if(kart->getPosition() == 1 && kart->raceIsFinished())
|
||||||
{
|
{
|
||||||
m_type = COLLECT_PARACHUTE;
|
m_type = COLLECT_PARACHUTE;
|
||||||
m_number = 1;
|
m_number = 1;
|
||||||
|
@ -150,10 +150,10 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDist, btVector3 *mi
|
|||||||
{
|
{
|
||||||
btTransform tProjectile=getTrans();
|
btTransform tProjectile=getTrans();
|
||||||
*minDist = 99999.9f;
|
*minDist = 99999.9f;
|
||||||
for(unsigned int i=0 ; i<world->getNumKarts(); i++ )
|
for(unsigned int i=0 ; i<race_manager->getNumKarts(); i++ )
|
||||||
{
|
{
|
||||||
Kart *kart = world -> getKart(i);
|
Kart *kart = world -> getKart(i);
|
||||||
if(kart == m_owner) continue;
|
if(kart->isEliminated() || kart == m_owner) continue;
|
||||||
btTransform t=kart->getTrans();
|
btTransform t=kart->getTrans();
|
||||||
|
|
||||||
btVector3 delta = t.getOrigin()-tProjectile.getOrigin();
|
btVector3 delta = t.getOrigin()-tProjectile.getOrigin();
|
||||||
@ -224,9 +224,9 @@ void Flyable::explode(Kart *kart_hit, MovingPhysics* moving_physics)
|
|||||||
world->getPhysics()->removeBody(getBody());
|
world->getPhysics()->removeBody(getBody());
|
||||||
m_exploded=true;
|
m_exploded=true;
|
||||||
|
|
||||||
for ( unsigned int i = 0 ; i < world->getNumKarts() ; i++ )
|
for ( unsigned int i = 0 ; i < race_manager->getNumKarts() ; i++ )
|
||||||
{
|
{
|
||||||
Kart *kart = world -> getKart(i);
|
Kart *kart = world->getKart(i);
|
||||||
// handle the actual explosion. Set a flag it if was a direct hit.
|
// handle the actual explosion. Set a flag it if was a direct hit.
|
||||||
kart->handleExplosion(m_curr_pos.xyz, kart==kart_hit);
|
kart->handleExplosion(m_curr_pos.xyz, kart==kart_hit);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ enum WidgetTokens
|
|||||||
WTOK_GP,
|
WTOK_GP,
|
||||||
WTOK_QUICKRACE,
|
WTOK_QUICKRACE,
|
||||||
WTOK_TIMETRIAL,
|
WTOK_TIMETRIAL,
|
||||||
|
WTOK_FOLLOW_LEADER,
|
||||||
WTOK_EMPTY,
|
WTOK_EMPTY,
|
||||||
WTOK_BACK
|
WTOK_BACK
|
||||||
};
|
};
|
||||||
@ -68,7 +69,16 @@ GameMode::GameMode()
|
|||||||
widget_manager->addWgt(WTOK_TIMETRIAL, 50, 7);
|
widget_manager->addWgt(WTOK_TIMETRIAL, 50, 7);
|
||||||
widget_manager->setWgtText( WTOK_TIMETRIAL, _("Time Trial"));
|
widget_manager->setWgtText( WTOK_TIMETRIAL, _("Time Trial"));
|
||||||
}
|
}
|
||||||
|
widget_manager->addWgt(WTOK_FOLLOW_LEADER, 50, 7);
|
||||||
|
if(unlock_manager->isLocked("followleader"))
|
||||||
|
{
|
||||||
|
widget_manager->setWgtText( WTOK_FOLLOW_LEADER, "???");
|
||||||
|
widget_manager->deactivateWgt(WTOK_FOLLOW_LEADER);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
widget_manager->setWgtText( WTOK_FOLLOW_LEADER, _("Follow the Leader"));
|
||||||
|
}
|
||||||
widget_manager->addWgt(WTOK_EMPTY, 50, 7);
|
widget_manager->addWgt(WTOK_EMPTY, 50, 7);
|
||||||
widget_manager->hideWgtRect( WTOK_EMPTY );
|
widget_manager->hideWgtRect( WTOK_EMPTY );
|
||||||
widget_manager->hideWgtText( WTOK_EMPTY );
|
widget_manager->hideWgtText( WTOK_EMPTY );
|
||||||
@ -101,6 +111,10 @@ void GameMode::select()
|
|||||||
race_manager->setRaceMode(RaceManager::RM_QUICK_RACE);
|
race_manager->setRaceMode(RaceManager::RM_QUICK_RACE);
|
||||||
menu_manager->pushMenu(MENUID_DIFFICULTY);
|
menu_manager->pushMenu(MENUID_DIFFICULTY);
|
||||||
break;
|
break;
|
||||||
|
case WTOK_FOLLOW_LEADER:
|
||||||
|
race_manager->setRaceMode(RaceManager::RM_FOLLOW_LEADER);
|
||||||
|
menu_manager->pushMenu(MENUID_DIFFICULTY);
|
||||||
|
break;
|
||||||
case WTOK_TIMETRIAL:
|
case WTOK_TIMETRIAL:
|
||||||
race_manager->setRaceMode(RaceManager::RM_TIME_TRIAL);
|
race_manager->setRaceMode(RaceManager::RM_TIME_TRIAL);
|
||||||
menu_manager->pushMenu(MENUID_CHARSEL_P1); //difficulty makes no sense here
|
menu_manager->pushMenu(MENUID_CHARSEL_P1); //difficulty makes no sense here
|
||||||
|
240
src/gui/leader_result.cpp
Normal file
240
src/gui/leader_result.cpp
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
// $Id: grand_prix_ending.cpp 1681 2008-04-09 13:52:48Z hikerstk $
|
||||||
|
//
|
||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2008 Joerg Henrichs
|
||||||
|
//
|
||||||
|
// 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 2
|
||||||
|
// 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 <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
|
#include "leader_result.hpp"
|
||||||
|
#include "loader.hpp"
|
||||||
|
#include "sound_manager.hpp"
|
||||||
|
#include "kart_properties_manager.hpp"
|
||||||
|
#include "unlock_manager.hpp"
|
||||||
|
#include "widget_manager.hpp"
|
||||||
|
#include "race_manager.hpp"
|
||||||
|
#include "game_manager.hpp"
|
||||||
|
#include "user_config.hpp"
|
||||||
|
#include "menu_manager.hpp"
|
||||||
|
#include "kart_properties.hpp"
|
||||||
|
#include "translation.hpp"
|
||||||
|
#include "kart.hpp"
|
||||||
|
#include "world.hpp"
|
||||||
|
#include "scene.hpp"
|
||||||
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||||
|
# define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum WidgetTokens
|
||||||
|
{
|
||||||
|
WTOK_TITLE,
|
||||||
|
WTOK_QUIT,
|
||||||
|
|
||||||
|
WTOK_FIRSTKART
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
LeaderResult::LeaderResult()
|
||||||
|
: m_kart(0)
|
||||||
|
{
|
||||||
|
// for some strange reasons plib calls makeCurrent() in ssgContext
|
||||||
|
// constructor, so we have to save the old one here and restore it
|
||||||
|
ssgContext* oldContext = ssgGetCurrentContext();
|
||||||
|
m_context = new ssgContext;
|
||||||
|
oldContext->makeCurrent();
|
||||||
|
|
||||||
|
const unsigned int MAX_STR_LEN = 60;
|
||||||
|
const unsigned int NUM_KARTS = race_manager->getNumKarts();
|
||||||
|
|
||||||
|
int *scores = new int[NUM_KARTS];
|
||||||
|
int *position = new int[NUM_KARTS];
|
||||||
|
double *race_time = new double[NUM_KARTS];
|
||||||
|
|
||||||
|
// Ignore kart 0, since it was the leader
|
||||||
|
for( unsigned int kart_id = 1; kart_id < NUM_KARTS; ++kart_id )
|
||||||
|
{
|
||||||
|
position[kart_id] = kart_id;
|
||||||
|
scores[kart_id] = race_manager->getKartScore(kart_id);
|
||||||
|
race_time[kart_id] = race_manager->getOverallTime(kart_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Bubblesort
|
||||||
|
bool sorted;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
sorted = true;
|
||||||
|
for( unsigned int i = 1; i < NUM_KARTS - 1; ++i )
|
||||||
|
{
|
||||||
|
if( scores[i] < scores[i+1] || (scores[i] == scores[i+1]
|
||||||
|
&& race_time[i] > race_time[i+1]))
|
||||||
|
{
|
||||||
|
int tmp_score[2];
|
||||||
|
double tmp_time;
|
||||||
|
|
||||||
|
tmp_score[0] = position[i];
|
||||||
|
tmp_score[1] = scores[i];
|
||||||
|
tmp_time = race_time[i];
|
||||||
|
|
||||||
|
position[i] = position[i+1];
|
||||||
|
scores[i] = scores[i+1];
|
||||||
|
race_time[i] = race_time[i+1];
|
||||||
|
|
||||||
|
position[i+1] = tmp_score[0];
|
||||||
|
scores[i+1] = tmp_score[1];
|
||||||
|
race_time[i+1] = tmp_time;
|
||||||
|
|
||||||
|
sorted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(!sorted);
|
||||||
|
|
||||||
|
static char output[MAX_MESSAGE_LENGTH];
|
||||||
|
snprintf(output, sizeof(output),
|
||||||
|
_("The winner is %s!"),race_manager->getKartName(position[1]).c_str());
|
||||||
|
widget_manager->addWgt( WTOK_TITLE, 60, 10);
|
||||||
|
widget_manager->showWgtRect(WTOK_TITLE);
|
||||||
|
widget_manager->showWgtText(WTOK_TITLE);
|
||||||
|
widget_manager->setWgtText(WTOK_TITLE, output);
|
||||||
|
widget_manager->setWgtTextSize(WTOK_TITLE, WGT_FNT_LRG);
|
||||||
|
widget_manager->breakLine();
|
||||||
|
|
||||||
|
m_score = new char[MAX_STR_LEN*NUM_KARTS];
|
||||||
|
|
||||||
|
for(unsigned int i=1; i < NUM_KARTS; ++i)
|
||||||
|
{
|
||||||
|
char sTime[20];
|
||||||
|
TimeToString(race_time[i], sTime);
|
||||||
|
sprintf((char*)(m_score + MAX_STR_LEN * i), "%d. %s %d %s",
|
||||||
|
i + 1, race_manager->getKartName(position[i]).c_str(), scores[i], sTime );
|
||||||
|
|
||||||
|
widget_manager->addWgt(WTOK_FIRSTKART + i, 40, 5);
|
||||||
|
widget_manager->showWgtRect(WTOK_FIRSTKART + i);
|
||||||
|
widget_manager->showWgtText(WTOK_FIRSTKART + i);
|
||||||
|
widget_manager->setWgtText(WTOK_FIRSTKART + i,
|
||||||
|
(char*)(m_score + MAX_STR_LEN * i));
|
||||||
|
widget_manager->setWgtTextSize(WTOK_FIRSTKART + i, WGT_FNT_SML);
|
||||||
|
widget_manager->breakLine();
|
||||||
|
}
|
||||||
|
const std::string KART_NAME = race_manager->getKartName(position[1]);
|
||||||
|
const KartProperties* WINNING_KART = kart_properties_manager->getKart(KART_NAME);
|
||||||
|
delete []scores;
|
||||||
|
delete []position;
|
||||||
|
delete []race_time;
|
||||||
|
|
||||||
|
widget_manager->addWgt(WTOK_QUIT, 50, 7);
|
||||||
|
widget_manager->activateWgt(WTOK_QUIT);
|
||||||
|
widget_manager->showWgtRect(WTOK_QUIT);
|
||||||
|
widget_manager->showWgtText(WTOK_QUIT);
|
||||||
|
if(unlock_manager->getUnlockedFeatures().size()>0)
|
||||||
|
{
|
||||||
|
widget_manager->setWgtText(WTOK_QUIT, _("Continue"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
widget_manager->setWgtText(WTOK_QUIT, _("Back to the main menu"));
|
||||||
|
}
|
||||||
|
|
||||||
|
widget_manager->layout(WGT_AREA_TOP);
|
||||||
|
|
||||||
|
m_kart = new ssgTransform;
|
||||||
|
m_kart->ref();
|
||||||
|
ssgEntity* kartentity = WINNING_KART->getModel();
|
||||||
|
m_kart->addKid(kartentity);
|
||||||
|
|
||||||
|
sound_manager->playSfx(SOUND_WINNER);
|
||||||
|
|
||||||
|
m_clock = 0;
|
||||||
|
|
||||||
|
//FIXME: this is taken from RaceMode::exit_race,
|
||||||
|
//this should be organized better.
|
||||||
|
scene->clear();
|
||||||
|
delete world;
|
||||||
|
world = 0;
|
||||||
|
race_manager->m_active_race = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
LeaderResult::~LeaderResult()
|
||||||
|
{
|
||||||
|
widget_manager->reset();
|
||||||
|
ssgDeRefDelete(m_kart);
|
||||||
|
|
||||||
|
delete m_context;
|
||||||
|
delete[] m_score;
|
||||||
|
|
||||||
|
//The next line prevents textures like the background of the main menu from
|
||||||
|
//going white after finishing the grandprix
|
||||||
|
// FIXME: I think this is not necessary anymore after the
|
||||||
|
// texture bug fix (r733) - but I can't currently test this.
|
||||||
|
loader->shared_textures.removeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void LeaderResult::update(float dt)
|
||||||
|
{
|
||||||
|
m_clock += dt * 40.0f;
|
||||||
|
|
||||||
|
glClearColor (0.1f, 0.1f, 0.1f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
ssgContext* oldContext = ssgGetCurrentContext();
|
||||||
|
m_context -> makeCurrent();
|
||||||
|
|
||||||
|
// FIXME: A bit hackish...
|
||||||
|
glViewport ( 0, 0, 800, 320);
|
||||||
|
|
||||||
|
m_context -> setFOV ( 45.0f, 45.0f * 320.0f/800.0f ) ;
|
||||||
|
m_context -> setNearFar ( 0.05f, 1000.0f ) ;
|
||||||
|
|
||||||
|
sgCoord cam_pos;
|
||||||
|
sgSetCoord(&cam_pos, 0, 0, 0, 0, 0, 0);
|
||||||
|
m_context -> setCamera ( &cam_pos ) ;
|
||||||
|
|
||||||
|
glEnable (GL_DEPTH_TEST);
|
||||||
|
sgCoord trans;
|
||||||
|
sgSetCoord(&trans, 0, 3, -.4f, m_clock, 0, 0);
|
||||||
|
m_kart->setTransform (&trans) ;
|
||||||
|
//glShadeModel(GL_SMOOTH);
|
||||||
|
ssgCullAndDraw ( m_kart ) ;
|
||||||
|
glViewport ( 0, 0, user_config->m_width, user_config->m_height ) ;
|
||||||
|
|
||||||
|
glDisable (GL_DEPTH_TEST);
|
||||||
|
oldContext->makeCurrent();
|
||||||
|
BaseGUI::update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void LeaderResult::select()
|
||||||
|
{
|
||||||
|
// If a new feature was unlocked, display the new feature first
|
||||||
|
// before returning to the main menu
|
||||||
|
if(unlock_manager->getUnlockedFeatures().size()>0)
|
||||||
|
{
|
||||||
|
// This removes this menu from the stack, and adds the main menu.
|
||||||
|
// Then we push the new feature menu on top, so that it will be
|
||||||
|
// displayed next, and on return the main menu is shown.
|
||||||
|
menu_manager->switchToMainMenu();
|
||||||
|
menu_manager->pushMenu(MENUID_UNLOCKED_FEATURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
menu_manager->switchToMainMenu();
|
||||||
|
}
|
47
src/gui/leader_result.hpp
Executable file
47
src/gui/leader_result.hpp
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
// $Id: grand_prix_ending.hpp 1023 2007-04-29 22:23:46Z coz $
|
||||||
|
//
|
||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2008 Joerg Henrichs
|
||||||
|
//
|
||||||
|
// 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 2
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef HEADER_LEADER_RESULT_H
|
||||||
|
#define HEADER_LEADER_RESULT_H
|
||||||
|
|
||||||
|
#include "base_gui.hpp"
|
||||||
|
|
||||||
|
class ssgBranch;
|
||||||
|
class ssgTransform;
|
||||||
|
class ssgContext;
|
||||||
|
|
||||||
|
class LeaderResult: public BaseGUI
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
ssgContext* m_context;
|
||||||
|
ssgTransform* m_kart;
|
||||||
|
int m_current_kart;
|
||||||
|
int m_kart_name_label;
|
||||||
|
char* m_score;
|
||||||
|
float m_clock;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LeaderResult();
|
||||||
|
~LeaderResult();
|
||||||
|
|
||||||
|
void update(float dt);
|
||||||
|
void select();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -54,6 +54,7 @@
|
|||||||
#include "widget_manager.hpp"
|
#include "widget_manager.hpp"
|
||||||
#include "challenges_menu.hpp"
|
#include "challenges_menu.hpp"
|
||||||
#include "feature_unlocked.hpp"
|
#include "feature_unlocked.hpp"
|
||||||
|
#include "leader_result.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -187,6 +188,9 @@ void MenuManager::update()
|
|||||||
case MENUID_RACERESULT:
|
case MENUID_RACERESULT:
|
||||||
m_current_menu= new RaceResultsGUI();
|
m_current_menu= new RaceResultsGUI();
|
||||||
break;
|
break;
|
||||||
|
case MENUID_LEADERRESULT:
|
||||||
|
m_current_menu= new LeaderResult();
|
||||||
|
break;
|
||||||
case MENUID_GRANDPRIXEND:
|
case MENUID_GRANDPRIXEND:
|
||||||
m_current_menu= new GrandPrixEnd();
|
m_current_menu= new GrandPrixEnd();
|
||||||
break;
|
break;
|
||||||
|
@ -36,6 +36,7 @@ enum MenuManagerIDs
|
|||||||
MENUID_DIFFICULTY,
|
MENUID_DIFFICULTY,
|
||||||
MENUID_GAMEMODE,
|
MENUID_GAMEMODE,
|
||||||
MENUID_RACERESULT,
|
MENUID_RACERESULT,
|
||||||
|
MENUID_LEADERRESULT,
|
||||||
MENUID_GRANDPRIXEND,
|
MENUID_GRANDPRIXEND,
|
||||||
MENUID_RACEMENU,
|
MENUID_RACEMENU,
|
||||||
MENUID_TRACKSEL,
|
MENUID_TRACKSEL,
|
||||||
|
@ -167,21 +167,21 @@ RaceGUI::handle(GameAction ga, int value)
|
|||||||
switch (ga)
|
switch (ga)
|
||||||
{
|
{
|
||||||
case GA_DEBUG_ADD_SPARK:
|
case GA_DEBUG_ADD_SPARK:
|
||||||
if (world->getNumPlayers() ==1 )
|
if (race_manager->getNumPlayers() ==1 )
|
||||||
{
|
{
|
||||||
Kart* kart = world->getPlayerKart(0);
|
Kart* kart = world->getPlayerKart(0);
|
||||||
kart->setCollectable(COLLECT_SPARK, 10000);
|
kart->setCollectable(COLLECT_SPARK, 10000);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GA_DEBUG_ADD_MISSILE:
|
case GA_DEBUG_ADD_MISSILE:
|
||||||
if (world->getNumPlayers() ==1 )
|
if (race_manager->getNumPlayers() ==1 )
|
||||||
{
|
{
|
||||||
Kart* kart = world->getPlayerKart(0);
|
Kart* kart = world->getPlayerKart(0);
|
||||||
kart->setCollectable(COLLECT_MISSILE, 10000);
|
kart->setCollectable(COLLECT_MISSILE, 10000);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GA_DEBUG_ADD_HOMING:
|
case GA_DEBUG_ADD_HOMING:
|
||||||
if (world->getNumPlayers() ==1 )
|
if (race_manager->getNumPlayers() ==1 )
|
||||||
{
|
{
|
||||||
Kart* kart = world->getPlayerKart(0);
|
Kart* kart = world->getPlayerKart(0);
|
||||||
kart->setCollectable(COLLECT_HOMING, 10000);
|
kart->setCollectable(COLLECT_HOMING, 10000);
|
||||||
@ -289,11 +289,12 @@ void RaceGUI::drawMap ()
|
|||||||
|
|
||||||
glBegin ( GL_QUADS ) ;
|
glBegin ( GL_QUADS ) ;
|
||||||
|
|
||||||
for ( unsigned int i = 0 ; i < world->getNumKarts() ; i++ )
|
for ( unsigned int i = 0 ; i < race_manager->getNumKarts() ; i++ )
|
||||||
{
|
{
|
||||||
sgCoord *c ;
|
sgCoord *c ;
|
||||||
|
|
||||||
Kart* kart = world->getKart(i);
|
Kart* kart = world->getKart(i);
|
||||||
|
if(kart->isEliminated()) continue; // don't draw eliminated kart
|
||||||
glColor3fv ( *kart->getColor());
|
glColor3fv ( *kart->getColor());
|
||||||
c = kart->getCoord () ;
|
c = kart->getCoord () ;
|
||||||
|
|
||||||
@ -336,9 +337,10 @@ void RaceGUI::drawPlayerIcons ()
|
|||||||
// Find the best time for the lap. We can't simply use
|
// Find the best time for the lap. We can't simply use
|
||||||
// the time of the kart at position 1, since the kart
|
// the time of the kart at position 1, since the kart
|
||||||
// might have been overtaken by now
|
// might have been overtaken by now
|
||||||
for(unsigned int i = 0; i < world->getNumKarts() ; i++)
|
for(unsigned int i = 0; i < race_manager->getNumKarts() ; i++)
|
||||||
{
|
{
|
||||||
Kart* kart = world->getKart(i);
|
Kart* kart = world->getKart(i);
|
||||||
|
if(kart->isEliminated()) continue;
|
||||||
float lap_time = kart->getTimeAtLap();
|
float lap_time = kart->getTimeAtLap();
|
||||||
int laps = kart->getLap();
|
int laps = kart->getLap();
|
||||||
|
|
||||||
@ -355,9 +357,10 @@ void RaceGUI::drawPlayerIcons ()
|
|||||||
} // for i<getNumKarts
|
} // for i<getNumKarts
|
||||||
|
|
||||||
int bFirst = 1;
|
int bFirst = 1;
|
||||||
for(unsigned int i = 0; i < world->getNumKarts() ; i++)
|
for(unsigned int i = 0; i < race_manager->getNumKarts() ; i++)
|
||||||
{
|
{
|
||||||
Kart* kart = world->getKart(i);
|
Kart* kart = world->getKart(i);
|
||||||
|
if(kart->isEliminated()) continue;
|
||||||
int position = kart->getPosition();
|
int position = kart->getPosition();
|
||||||
int lap = kart->getLap();
|
int lap = kart->getLap();
|
||||||
|
|
||||||
@ -395,8 +398,9 @@ void RaceGUI::drawPlayerIcons ()
|
|||||||
str[0]='+'; str[1]=0;
|
str[0]='+'; str[1]=0;
|
||||||
TimeToString(timeBehind, str+1);
|
TimeToString(timeBehind, str+1);
|
||||||
}
|
}
|
||||||
font_race->PrintShadow(str, 30, ICON_PLAYER_WIDHT+x, y+5,
|
if(race_manager->raceHasLaps())
|
||||||
red, green, blue);
|
font_race->PrintShadow(str, 30, ICON_PLAYER_WIDHT+x, y+5,
|
||||||
|
red, green, blue);
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
@ -746,7 +750,7 @@ void RaceGUI::drawLap(Kart* kart, int offset_x, int offset_y,
|
|||||||
float ratio_x, float ratio_y )
|
float ratio_x, float ratio_y )
|
||||||
{
|
{
|
||||||
// Don't display laps in follow the leader mode
|
// Don't display laps in follow the leader mode
|
||||||
if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER) return;
|
if(!race_manager->raceHasLaps()) return;
|
||||||
|
|
||||||
float maxRatio = std::max(ratio_x, ratio_y);
|
float maxRatio = std::max(ratio_x, ratio_y);
|
||||||
char str[256];
|
char str[256];
|
||||||
@ -909,7 +913,7 @@ void RaceGUI::drawStatusText(const float dt)
|
|||||||
}
|
}
|
||||||
if(world->isStartPhase())
|
if(world->isStartPhase())
|
||||||
{
|
{
|
||||||
for(unsigned int i=0; i<world->getNumPlayers(); i++)
|
for(unsigned int i=0; i<race_manager->getNumPlayers(); i++)
|
||||||
{
|
{
|
||||||
if(world->getPlayerKart(i)->earlyStartPenalty())
|
if(world->getPlayerKart(i)->earlyStartPenalty())
|
||||||
{
|
{
|
||||||
@ -922,14 +926,14 @@ void RaceGUI::drawStatusText(const float dt)
|
|||||||
|
|
||||||
float split_screen_ratio_x, split_screen_ratio_y;
|
float split_screen_ratio_x, split_screen_ratio_y;
|
||||||
split_screen_ratio_x = split_screen_ratio_y = 1.0;
|
split_screen_ratio_x = split_screen_ratio_y = 1.0;
|
||||||
if(world->getNumPlayers() >= 2)
|
if(race_manager->getNumPlayers() >= 2)
|
||||||
split_screen_ratio_y = 0.5;
|
split_screen_ratio_y = 0.5;
|
||||||
if(world->getNumPlayers() >= 3)
|
if(race_manager->getNumPlayers() >= 3)
|
||||||
split_screen_ratio_x = 0.5;
|
split_screen_ratio_x = 0.5;
|
||||||
|
|
||||||
if ( world->isRacePhase() )
|
if ( world->isRacePhase() )
|
||||||
{
|
{
|
||||||
const int numPlayers = world->getNumPlayers();
|
const int numPlayers = race_manager->getNumPlayers();
|
||||||
|
|
||||||
for(int pla = 0; pla < numPlayers; pla++)
|
for(int pla = 0; pla < numPlayers; pla++)
|
||||||
{
|
{
|
||||||
|
@ -74,7 +74,7 @@ RaceResultsGUI::RaceResultsGUI()
|
|||||||
|
|
||||||
|
|
||||||
const unsigned int MAX_STR_LEN = 60;
|
const unsigned int MAX_STR_LEN = 60;
|
||||||
const unsigned int NUM_KARTS = world->getNumKarts();
|
const unsigned int NUM_KARTS = race_manager->getNumKarts();
|
||||||
|
|
||||||
int* order = new int [NUM_KARTS];
|
int* order = new int [NUM_KARTS];
|
||||||
m_score = new char[NUM_KARTS * MAX_STR_LEN];
|
m_score = new char[NUM_KARTS * MAX_STR_LEN];
|
||||||
@ -82,7 +82,7 @@ RaceResultsGUI::RaceResultsGUI()
|
|||||||
|
|
||||||
for(unsigned int i=0; i < NUM_KARTS; i++)
|
for(unsigned int i=0; i < NUM_KARTS; i++)
|
||||||
{
|
{
|
||||||
Kart *k = world->getKart(i);
|
Kart *k = world->getKart(i); // Display even for eliminated karts!
|
||||||
order[k->getPosition()-1] = i;
|
order[k->getPosition()-1] = i;
|
||||||
const std::string& s = k->getName();
|
const std::string& s = k->getName();
|
||||||
unsigned int l = (unsigned int)s.size();
|
unsigned int l = (unsigned int)s.size();
|
||||||
|
@ -853,6 +853,10 @@
|
|||||||
RelativePath="../../../src\skid_mark.cpp"
|
RelativePath="../../../src\skid_mark.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\smoke.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\sound_manager.cpp"
|
RelativePath="../../../src\sound_manager.cpp"
|
||||||
>
|
>
|
||||||
@ -992,6 +996,10 @@
|
|||||||
RelativePath="..\..\gui\help_page_two.cpp"
|
RelativePath="..\..\gui\help_page_two.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\gui\leader_result.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\gui\main_menu.cpp"
|
RelativePath="../../../src\gui\main_menu.cpp"
|
||||||
>
|
>
|
||||||
@ -1080,6 +1088,10 @@
|
|||||||
RelativePath="..\..\challenges\energy_math_class.cpp"
|
RelativePath="..\..\challenges\energy_math_class.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\challenges\race_track_time.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\challenges\win_gotm_cup.cpp"
|
RelativePath="..\..\challenges\win_gotm_cup.cpp"
|
||||||
>
|
>
|
||||||
@ -1315,6 +1327,10 @@
|
|||||||
RelativePath="../../../src\skid_mark.hpp"
|
RelativePath="../../../src\skid_mark.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\smoke.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\sound_manager.hpp"
|
RelativePath="../../../src\sound_manager.hpp"
|
||||||
>
|
>
|
||||||
@ -1454,6 +1470,10 @@
|
|||||||
RelativePath="..\..\gui\help_page_two.hpp"
|
RelativePath="..\..\gui\help_page_two.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\gui\leader_result.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="../../../src\gui\main_menu.hpp"
|
RelativePath="../../../src\gui\main_menu.hpp"
|
||||||
>
|
>
|
||||||
@ -1542,6 +1562,10 @@
|
|||||||
RelativePath="..\..\challenges\energy_math_class.hpp"
|
RelativePath="..\..\challenges\energy_math_class.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\challenges\race_track_time.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\challenges\win_gotm_cup.hpp"
|
RelativePath="..\..\challenges\win_gotm_cup.hpp"
|
||||||
>
|
>
|
||||||
|
107
src/kart.cpp
107
src/kart.cpp
@ -20,6 +20,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <plib/ssg.h>
|
#include <plib/ssg.h>
|
||||||
|
#include "bullet/Demos/OpenGL/GL_ShapeDrawer.h"
|
||||||
|
|
||||||
#include "loader.hpp"
|
#include "loader.hpp"
|
||||||
#include "herring_manager.hpp"
|
#include "herring_manager.hpp"
|
||||||
@ -38,87 +39,12 @@
|
|||||||
#include "gui/menu_manager.hpp"
|
#include "gui/menu_manager.hpp"
|
||||||
#include "gui/race_gui.hpp"
|
#include "gui/race_gui.hpp"
|
||||||
#include "translation.hpp"
|
#include "translation.hpp"
|
||||||
#include "bullet/Demos/OpenGL/GL_ShapeDrawer.h"
|
#include "smoke.hpp"
|
||||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||||
# define snprintf _snprintf
|
# define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
KartParticleSystem::KartParticleSystem(Kart* kart_,
|
|
||||||
int num, float _create_rate, int _ttf,
|
|
||||||
float sz, float bsphere_size)
|
|
||||||
: ParticleSystem (num, _create_rate, _ttf, sz, bsphere_size),
|
|
||||||
m_kart(kart_)
|
|
||||||
{
|
|
||||||
getBSphere () -> setCenter ( 0, 0, 0 ) ;
|
|
||||||
getBSphere () -> setRadius ( 1000.0f ) ;
|
|
||||||
dirtyBSphere();
|
|
||||||
} // KartParticleSystem
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void KartParticleSystem::update ( float t )
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
std::cout << "BSphere: r:" << getBSphere()->radius
|
|
||||||
<< " (" << getBSphere()->center[0]
|
|
||||||
<< ", " << getBSphere()->center[1]
|
|
||||||
<< ", " << getBSphere()->center[2]
|
|
||||||
<< ")"
|
|
||||||
<< std::endl;
|
|
||||||
#endif
|
|
||||||
getBSphere () -> setRadius ( 1000.0f ) ;
|
|
||||||
ParticleSystem::update(t);
|
|
||||||
} // update
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void KartParticleSystem::particle_create(int, Particle *p)
|
|
||||||
{
|
|
||||||
sgSetVec4 ( p -> m_col, 1, 1, 1, 1 ) ; /* initially white */
|
|
||||||
sgSetVec3 ( p -> m_pos, 0, 0, 0 ) ; /* start off on the ground */
|
|
||||||
sgSetVec3 ( p -> m_vel, 0, 0, 0 ) ;
|
|
||||||
sgSetVec3 ( p -> m_acc, 0, 0, 2.0f ) ; /* Gravity */
|
|
||||||
p -> m_size = .5f;
|
|
||||||
p -> m_time_to_live = 0.5 ; /* Droplets evaporate after 5 seconds */
|
|
||||||
|
|
||||||
const sgCoord* POS = m_kart->getCoord();
|
|
||||||
const btVector3 VEL = m_kart->getVelocity();
|
|
||||||
|
|
||||||
const float X_DIRECTION = sgCos (POS->hpr[0] - 90.0f); // Point at the rear
|
|
||||||
const float Y_DIRECTION = sgSin (POS->hpr[0] - 90.0f); // Point at the rear
|
|
||||||
|
|
||||||
sgCopyVec3 (p->m_pos, POS->xyz);
|
|
||||||
|
|
||||||
p->m_pos[0] += X_DIRECTION * 0.7f;
|
|
||||||
p->m_pos[1] += Y_DIRECTION * 0.7f;
|
|
||||||
|
|
||||||
const float ABS_VEL = sqrt((VEL.getX() * VEL.getX()) + (VEL.getY() * VEL.getY()));
|
|
||||||
|
|
||||||
p->m_vel[0] = X_DIRECTION * -ABS_VEL/2;
|
|
||||||
p->m_vel[1] = Y_DIRECTION * -ABS_VEL/2;
|
|
||||||
|
|
||||||
p->m_vel[0] += sgCos ((float)(rand()%180));
|
|
||||||
p->m_vel[1] += sgSin ((float)(rand()%180));
|
|
||||||
p->m_vel[2] += sgSin ((float)(rand()%100));
|
|
||||||
|
|
||||||
getBSphere () -> setCenter ( POS->xyz[0], POS->xyz[1], POS->xyz[2] ) ;
|
|
||||||
} // particle_create
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void KartParticleSystem::particle_update (float delta, int,
|
|
||||||
Particle * particle)
|
|
||||||
{
|
|
||||||
particle->m_size += delta*2.0f;
|
|
||||||
particle->m_col[3] -= delta * 2.0f;
|
|
||||||
|
|
||||||
particle->m_pos[0] += particle->m_vel[0] * delta;
|
|
||||||
particle->m_pos[1] += particle->m_vel[1] * delta;
|
|
||||||
particle->m_pos[2] += particle->m_vel[2] * delta;
|
|
||||||
} // particle_update
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
void KartParticleSystem::particle_delete (int , Particle* )
|
|
||||||
{} // particle_delete
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
Kart::Kart (const std::string& kart_name, int position_ ,
|
Kart::Kart (const std::string& kart_name, int position_ ,
|
||||||
sgCoord init_pos)
|
sgCoord init_pos)
|
||||||
: TerrainInfo(1),
|
: TerrainInfo(1),
|
||||||
@ -134,6 +60,7 @@ Kart::Kart (const std::string& kart_name, int position_ ,
|
|||||||
m_kart_properties = kart_properties_manager->getKart(kart_name);
|
m_kart_properties = kart_properties_manager->getKart(kart_name);
|
||||||
m_grid_position = position_ ;
|
m_grid_position = position_ ;
|
||||||
m_num_herrings_gobbled = 0;
|
m_num_herrings_gobbled = 0;
|
||||||
|
m_eliminated = false;
|
||||||
m_finished_race = false;
|
m_finished_race = false;
|
||||||
m_finish_time = 0.0f;
|
m_finish_time = 0.0f;
|
||||||
m_prev_accel = 0.0f;
|
m_prev_accel = 0.0f;
|
||||||
@ -325,6 +252,17 @@ Kart::~Kart()
|
|||||||
}
|
}
|
||||||
} // ~Kart
|
} // ~Kart
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Kart::eliminate()
|
||||||
|
{
|
||||||
|
m_eliminated = true;
|
||||||
|
world->getPhysics()->removeKart(this);
|
||||||
|
|
||||||
|
// make the kart invisible by placing it way under the track
|
||||||
|
sgVec3 hell; hell[0]=0.0f; hell[1]=0.0f; hell[2] = -10000.0f;
|
||||||
|
getModelTransform()->setTransform(hell);
|
||||||
|
} // eliminate
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Returns true if the kart is 'resting'
|
/** Returns true if the kart is 'resting'
|
||||||
*
|
*
|
||||||
@ -352,6 +290,10 @@ void Kart::adjustSpeedWeight(float f)
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void Kart::reset()
|
void Kart::reset()
|
||||||
{
|
{
|
||||||
|
if(m_eliminated)
|
||||||
|
{
|
||||||
|
world->getPhysics()->addKart(this, m_vehicle);
|
||||||
|
}
|
||||||
Moveable::reset();
|
Moveable::reset();
|
||||||
|
|
||||||
m_attachment.clear();
|
m_attachment.clear();
|
||||||
@ -363,6 +305,7 @@ void Kart::reset()
|
|||||||
m_shortcut_sector = Track::UNKNOWN_SECTOR;
|
m_shortcut_sector = Track::UNKNOWN_SECTOR;
|
||||||
m_race_position = 9;
|
m_race_position = 9;
|
||||||
m_finished_race = false;
|
m_finished_race = false;
|
||||||
|
m_eliminated = false;
|
||||||
m_finish_time = 0.0f;
|
m_finish_time = 0.0f;
|
||||||
m_zipper_time_left = 0.0f;
|
m_zipper_time_left = 0.0f;
|
||||||
m_num_herrings_gobbled = 0;
|
m_num_herrings_gobbled = 0;
|
||||||
@ -460,7 +403,8 @@ void Kart::doLapCounting ()
|
|||||||
time_per_lap=world->getTime()-m_lap_start_time;
|
time_per_lap=world->getTime()-m_lap_start_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(time_per_lap < world->getFastestLapTime() )
|
if(time_per_lap < world->getFastestLapTime() &&
|
||||||
|
race_manager->raceHasLaps())
|
||||||
{
|
{
|
||||||
world->setFastestLap(this, time_per_lap);
|
world->setFastestLap(this, time_per_lap);
|
||||||
RaceGUI* m=(RaceGUI*)menu_manager->getRaceMenu();
|
RaceGUI* m=(RaceGUI*)menu_manager->getRaceMenu();
|
||||||
@ -490,6 +434,13 @@ void Kart::doLapCounting ()
|
|||||||
// Prevent cheating by setting time to a negative number, indicating
|
// Prevent cheating by setting time to a negative number, indicating
|
||||||
// that the line wasn't crossed properly.
|
// that the line wasn't crossed properly.
|
||||||
m_lap_start_time = -1.0f;
|
m_lap_start_time = -1.0f;
|
||||||
|
} else
|
||||||
|
{ // Switch to fast music in case of follow the leader when only 3 karts are left
|
||||||
|
if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER &&
|
||||||
|
world->getCurrentNumKarts()==3)
|
||||||
|
{
|
||||||
|
sound_manager->switchToFastMusic();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // doLapCounting
|
} // doLapCounting
|
||||||
|
|
||||||
@ -1118,7 +1069,7 @@ void Kart::loadData()
|
|||||||
|
|
||||||
// Attach Particle System
|
// Attach Particle System
|
||||||
//JH sgCoord pipe_pos = {{0, 0, .3}, {0, 0, 0}} ;
|
//JH sgCoord pipe_pos = {{0, 0, .3}, {0, 0, 0}} ;
|
||||||
m_smoke_system = new KartParticleSystem(this, 50, 100.0f, true, 0.35f, 1000);
|
m_smoke_system = new Smoke(this, 50, 100.0f, true, 0.35f, 1000);
|
||||||
m_smoke_system -> init(5);
|
m_smoke_system -> init(5);
|
||||||
//JH m_smoke_system -> setState (getMaterial ("smoke.png")-> getState() );
|
//JH m_smoke_system -> setState (getMaterial ("smoke.png")-> getState() );
|
||||||
//m_smoke_system -> setState ( m_smokepuff ) ;
|
//m_smoke_system -> setState ( m_smokepuff ) ;
|
||||||
|
23
src/kart.hpp
23
src/kart.hpp
@ -25,7 +25,6 @@
|
|||||||
#include "btBulletDynamicsCommon.h"
|
#include "btBulletDynamicsCommon.h"
|
||||||
|
|
||||||
#include "moveable.hpp"
|
#include "moveable.hpp"
|
||||||
#include "particle_system.hpp"
|
|
||||||
#include "kart_properties.hpp"
|
#include "kart_properties.hpp"
|
||||||
#include "attachment.hpp"
|
#include "attachment.hpp"
|
||||||
#include "collectable.hpp"
|
#include "collectable.hpp"
|
||||||
@ -46,24 +45,9 @@ struct KartControl
|
|||||||
};
|
};
|
||||||
|
|
||||||
class SkidMark;
|
class SkidMark;
|
||||||
class Kart;
|
|
||||||
class Herring;
|
class Herring;
|
||||||
|
class Smoke;
|
||||||
|
|
||||||
class KartParticleSystem : public ParticleSystem
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Kart* m_kart;
|
|
||||||
|
|
||||||
public:
|
|
||||||
KartParticleSystem (Kart* kart, int num, float _create_rate,
|
|
||||||
int _turn_to_face, float sz, float bsphere_size);
|
|
||||||
virtual void update (float t );
|
|
||||||
virtual void particle_create(int index, Particle* p );
|
|
||||||
virtual void particle_update(float deltaTime, int index, Particle *p );
|
|
||||||
virtual void particle_delete(int index, Particle* p );
|
|
||||||
};
|
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
class Kart : public TerrainInfo, public Moveable
|
class Kart : public TerrainInfo, public Moveable
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -105,7 +89,7 @@ private:
|
|||||||
int m_num_herrings_gobbled;
|
int m_num_herrings_gobbled;
|
||||||
ssgSimpleState* m_smokepuff;
|
ssgSimpleState* m_smokepuff;
|
||||||
// don't delete the following 2 vars (they're kids in the hirarchy)
|
// don't delete the following 2 vars (they're kids in the hirarchy)
|
||||||
KartParticleSystem* m_smoke_system;
|
Smoke *m_smoke_system;
|
||||||
ssgTransform* m_exhaust_pipe;
|
ssgTransform* m_exhaust_pipe;
|
||||||
|
|
||||||
float m_wheel_rotation;
|
float m_wheel_rotation;
|
||||||
@ -124,6 +108,7 @@ private:
|
|||||||
|
|
||||||
float m_speed;
|
float m_speed;
|
||||||
bool m_rescue;
|
bool m_rescue;
|
||||||
|
bool m_eliminated;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float m_rescue_pitch, m_rescue_roll;
|
float m_rescue_pitch, m_rescue_roll;
|
||||||
@ -217,6 +202,8 @@ public:
|
|||||||
float handleWheelie (float dt);
|
float handleWheelie (float dt);
|
||||||
float getActualWheelForce();
|
float getActualWheelForce();
|
||||||
bool isOnGround () const;
|
bool isOnGround () const;
|
||||||
|
bool isEliminated () const {return m_eliminated;}
|
||||||
|
void eliminate ();
|
||||||
bool isRescue () const {return m_rescue;}
|
bool isRescue () const {return m_rescue;}
|
||||||
void resetBrakes ();
|
void resetBrakes ();
|
||||||
void adjustSpeedWeight(float f);
|
void adjustSpeedWeight(float f);
|
||||||
|
@ -219,6 +219,7 @@ void PlayerKart::reset()
|
|||||||
m_controls.jump = false;
|
m_controls.jump = false;
|
||||||
m_penalty_time = 0;
|
m_penalty_time = 0;
|
||||||
m_time_last_crash_sound = -10.0f;
|
m_time_last_crash_sound = -10.0f;
|
||||||
|
m_camera->setMode(Camera::CM_NORMAL); // can be changed if camera was eliminated
|
||||||
m_camera->setReverseHeading(false);
|
m_camera->setReverseHeading(false);
|
||||||
Kart::reset();
|
Kart::reset();
|
||||||
} // reset
|
} // reset
|
||||||
|
@ -204,11 +204,23 @@ void RaceManager::exit_race()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void RaceManager::addKartResult(int kart, int pos, float time)
|
void RaceManager::addKartResult(int kart, int pos, float time)
|
||||||
{
|
{
|
||||||
|
// In follow the leader mode, kart 0 does not get any points,
|
||||||
|
// so the position of each kart is actually one better --> decrease pos
|
||||||
|
if(m_race_mode==RM_FOLLOW_LEADER)
|
||||||
|
{
|
||||||
|
pos--;
|
||||||
|
// If the position is negative (i.e. follow leader and kart on
|
||||||
|
// position 0) set the score of this kart to the lowest possible
|
||||||
|
// score, since the kart is ahead of the leader
|
||||||
|
if(pos<=0) pos=stk_config->m_max_karts;
|
||||||
|
}
|
||||||
|
|
||||||
m_kart_status[kart].m_score += m_score_for_position[pos-1];
|
m_kart_status[kart].m_score += m_score_for_position[pos-1];
|
||||||
m_kart_status[kart].m_last_score = m_score_for_position[pos-1];
|
m_kart_status[kart].m_last_score = m_score_for_position[pos-1];
|
||||||
m_kart_status[kart].m_overall_time += time;
|
m_kart_status[kart].m_overall_time += time;
|
||||||
m_kart_status[kart].m_last_time = time;
|
m_kart_status[kart].m_last_time = time;
|
||||||
} // addKartResult
|
} // addKartResult
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void RaceManager::restartRace()
|
void RaceManager::restartRace()
|
||||||
{
|
{
|
||||||
|
@ -87,6 +87,12 @@ private:
|
|||||||
unsigned int m_num_finished_players;
|
unsigned int m_num_finished_players;
|
||||||
|
|
||||||
void startNextRace(); // start a next race
|
void startNextRace(); // start a next race
|
||||||
|
|
||||||
|
friend bool operator< (const KartStatus& left, const KartStatus& right)
|
||||||
|
{
|
||||||
|
return (left.m_score < right.m_score);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool m_active_race; //True if there is a race
|
bool m_active_race; //True if there is a race
|
||||||
|
|
||||||
@ -119,10 +125,12 @@ public:
|
|||||||
{ return m_kart_status[kart].m_ident;}
|
{ return m_kart_status[kart].m_ident;}
|
||||||
const std::string& getHerringStyle() const
|
const std::string& getHerringStyle() const
|
||||||
{ return m_cup.getHerringStyle(); }
|
{ return m_cup.getHerringStyle(); }
|
||||||
int getKartScore(int kart) const { return m_kart_status[kart].m_score;}
|
int getKartScore(int krt) const { return m_kart_status[krt].m_score;}
|
||||||
int getPositionScore(int p) const { return m_score_for_position[p-1];}
|
int getPositionScore(int p) const { return m_score_for_position[p-1]; }
|
||||||
double getOverallTime(int kart) const {return m_kart_status[kart].m_overall_time;}
|
double getOverallTime(int kart) const { return m_kart_status[kart].m_overall_time;}
|
||||||
bool isEliminated(int kart) const { return m_kart_status[kart].m_is_eliminated;}
|
bool isEliminated(int kart) const { return m_kart_status[kart].m_is_eliminated;}
|
||||||
|
bool raceHasLaps() const { return m_race_mode!=RM_FOLLOW_LEADER;}
|
||||||
|
void eliminate(int kart) { m_kart_status[kart].m_is_eliminated=true;}
|
||||||
void addFinishedKarts(int num) { m_num_finished_karts += num; }
|
void addFinishedKarts(int num) { m_num_finished_karts += num; }
|
||||||
void PlayerFinishes() { m_num_finished_players++; }
|
void PlayerFinishes() { m_num_finished_players++; }
|
||||||
int allPlayerFinished() const {return m_num_finished_players==m_player_karts.size();}
|
int allPlayerFinished() const {return m_num_finished_players==m_player_karts.size();}
|
||||||
@ -136,13 +144,6 @@ public:
|
|||||||
void next(); // start the next race or go back to the start screen
|
void next(); // start the next race or go back to the start screen
|
||||||
void restartRace(); // restart same race again
|
void restartRace(); // restart same race again
|
||||||
void exit_race(); // exit a race (and don't start the next one)
|
void exit_race(); // exit a race (and don't start the next one)
|
||||||
|
|
||||||
friend bool operator< (const KartStatus& left, const KartStatus& right)
|
|
||||||
{
|
|
||||||
return (left.m_score < right.m_score);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern RaceManager *race_manager;
|
extern RaceManager *race_manager;
|
||||||
|
@ -556,7 +556,7 @@ void DefaultRobot::check_crashes( const int STEPS, sgVec3 const pos )
|
|||||||
|
|
||||||
m_crashes.clear();
|
m_crashes.clear();
|
||||||
|
|
||||||
const size_t NUM_KARTS = world->getNumKarts();
|
const size_t NUM_KARTS = race_manager->getNumKarts();
|
||||||
|
|
||||||
//Protection against having vel_normal with nan values
|
//Protection against having vel_normal with nan values
|
||||||
const btVector3 &VEL = getVelocity();
|
const btVector3 &VEL = getVelocity();
|
||||||
@ -581,7 +581,8 @@ void DefaultRobot::check_crashes( const int STEPS, sgVec3 const pos )
|
|||||||
{
|
{
|
||||||
for( unsigned int j = 0; j < NUM_KARTS; ++j )
|
for( unsigned int j = 0; j < NUM_KARTS; ++j )
|
||||||
{
|
{
|
||||||
if(world->getKart(j) == this) continue;
|
const Kart* kart=world->getKart(j);
|
||||||
|
if(kart==this||kart->isEliminated()) continue; // ignore eliminated karts
|
||||||
|
|
||||||
kart_distance = sgDistanceVec2( step_coord,
|
kart_distance = sgDistanceVec2( step_coord,
|
||||||
world->getKart(j)->getCoord()->xyz );
|
world->getKart(j)->getCoord()->xyz );
|
||||||
|
@ -135,7 +135,7 @@ void Scene::draw(float dt)
|
|||||||
for (Cameras::iterator i = m_cameras.begin(); i != m_cameras.end(); ++i)
|
for (Cameras::iterator i = m_cameras.begin(); i != m_cameras.end(); ++i)
|
||||||
{
|
{
|
||||||
(*i)->update(dt);
|
(*i)->update(dt);
|
||||||
(*i) -> apply () ;
|
(*i)->apply ();
|
||||||
|
|
||||||
if(!user_config->m_bullet_debug)
|
if(!user_config->m_bullet_debug)
|
||||||
{
|
{
|
||||||
@ -179,15 +179,16 @@ void Scene::draw(float dt)
|
|||||||
glFrustum(-f, f, -f, f, 1.0, 1000.0);
|
glFrustum(-f, f, -f, f, 1.0, 1000.0);
|
||||||
|
|
||||||
btVector3 pos;
|
btVector3 pos;
|
||||||
sgCoord *c = world->getKart(world->getNumKarts()-1)->getCoord();
|
sgCoord *c = world->getKart(race_manager->getNumKarts()-1)->getCoord();
|
||||||
gluLookAt(c->xyz[0], c->xyz[1]-5.f, c->xyz[2]+4,
|
gluLookAt(c->xyz[0], c->xyz[1]-5.f, c->xyz[2]+4,
|
||||||
c->xyz[0], c->xyz[1], c->xyz[2],
|
c->xyz[0], c->xyz[1], c->xyz[2],
|
||||||
0.0f, 0.0f, 1.0f);
|
0.0f, 0.0f, 1.0f);
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
for (World::Karts::size_type i = 0 ; i < world->getNumKarts(); ++i)
|
for (World::Karts::size_type i = 0 ; i < race_manager->getNumKarts(); ++i)
|
||||||
{
|
{
|
||||||
world->getKart((int)i)->draw();
|
Kart *kart=world->getKart((int)i);
|
||||||
|
if(!kart->isEliminated()) kart->draw();
|
||||||
}
|
}
|
||||||
world->getPhysics()->draw();
|
world->getPhysics()->draw();
|
||||||
} // bullet_debug
|
} // bullet_debug
|
||||||
|
98
src/smoke.cpp
Executable file
98
src/smoke.cpp
Executable file
@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
// $Id: dust_cloud.cpp 1681 2008-04-09 13:52:48Z hikerstk $
|
||||||
|
//
|
||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2006 SuperTuxKart-Team
|
||||||
|
//
|
||||||
|
// 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 2
|
||||||
|
// 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 "smoke.hpp"
|
||||||
|
#include "kart.hpp"
|
||||||
|
|
||||||
|
Smoke::Smoke(Kart* kart_,
|
||||||
|
int num, float _create_rate, int _ttf,
|
||||||
|
float sz, float bsphere_size)
|
||||||
|
: ParticleSystem (num, _create_rate, _ttf, sz, bsphere_size),
|
||||||
|
m_kart(kart_)
|
||||||
|
{
|
||||||
|
getBSphere () -> setCenter ( 0, 0, 0 ) ;
|
||||||
|
getBSphere () -> setRadius ( 1000.0f ) ;
|
||||||
|
dirtyBSphere();
|
||||||
|
} // KartParticleSystem
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Smoke::update ( float t )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
std::cout << "BSphere: r:" << getBSphere()->radius
|
||||||
|
<< " (" << getBSphere()->center[0]
|
||||||
|
<< ", " << getBSphere()->center[1]
|
||||||
|
<< ", " << getBSphere()->center[2]
|
||||||
|
<< ")"
|
||||||
|
<< std::endl;
|
||||||
|
#endif
|
||||||
|
getBSphere () -> setRadius ( 1000.0f ) ;
|
||||||
|
ParticleSystem::update(t);
|
||||||
|
} // update
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Smoke::particle_create(int, Particle *p)
|
||||||
|
{
|
||||||
|
sgSetVec4 ( p -> m_col, 1, 1, 1, 1 ) ; /* initially white */
|
||||||
|
sgSetVec3 ( p -> m_pos, 0, 0, 0 ) ; /* start off on the ground */
|
||||||
|
sgSetVec3 ( p -> m_vel, 0, 0, 0 ) ;
|
||||||
|
sgSetVec3 ( p -> m_acc, 0, 0, 2.0f ) ; /* Gravity */
|
||||||
|
p -> m_size = .5f;
|
||||||
|
p -> m_time_to_live = 0.5 ; /* Droplets evaporate after 5 seconds */
|
||||||
|
|
||||||
|
const sgCoord* POS = m_kart->getCoord();
|
||||||
|
const btVector3 VEL = m_kart->getVelocity();
|
||||||
|
|
||||||
|
const float X_DIRECTION = sgCos (POS->hpr[0] - 90.0f); // Point at the rear
|
||||||
|
const float Y_DIRECTION = sgSin (POS->hpr[0] - 90.0f); // Point at the rear
|
||||||
|
|
||||||
|
sgCopyVec3 (p->m_pos, POS->xyz);
|
||||||
|
|
||||||
|
p->m_pos[0] += X_DIRECTION * 0.7f;
|
||||||
|
p->m_pos[1] += Y_DIRECTION * 0.7f;
|
||||||
|
|
||||||
|
const float ABS_VEL = sqrt((VEL.getX() * VEL.getX()) + (VEL.getY() * VEL.getY()));
|
||||||
|
|
||||||
|
p->m_vel[0] = X_DIRECTION * -ABS_VEL/2;
|
||||||
|
p->m_vel[1] = Y_DIRECTION * -ABS_VEL/2;
|
||||||
|
|
||||||
|
p->m_vel[0] += sgCos ((float)(rand()%180));
|
||||||
|
p->m_vel[1] += sgSin ((float)(rand()%180));
|
||||||
|
p->m_vel[2] += sgSin ((float)(rand()%100));
|
||||||
|
|
||||||
|
getBSphere () -> setCenter ( POS->xyz[0], POS->xyz[1], POS->xyz[2] ) ;
|
||||||
|
} // particle_create
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Smoke::particle_update (float delta, int,
|
||||||
|
Particle * particle)
|
||||||
|
{
|
||||||
|
particle->m_size += delta*2.0f;
|
||||||
|
particle->m_col[3] -= delta * 2.0f;
|
||||||
|
|
||||||
|
particle->m_pos[0] += particle->m_vel[0] * delta;
|
||||||
|
particle->m_pos[1] += particle->m_vel[1] * delta;
|
||||||
|
particle->m_pos[2] += particle->m_vel[2] * delta;
|
||||||
|
} // particle_update
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void Smoke::particle_delete (int , Particle* )
|
||||||
|
{} // particle_delete
|
||||||
|
|
41
src/smoke.hpp
Executable file
41
src/smoke.hpp
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
// $Id: dust_cloud.hpp 1681 2008-04-09 13:52:48Z hikerstk $
|
||||||
|
//
|
||||||
|
// SuperTuxKart - a fun racing game with go-kart
|
||||||
|
// Copyright (C) 2006 SuperTuxKart-Team
|
||||||
|
//
|
||||||
|
// 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 2
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef HEADER_SMOKE_H
|
||||||
|
#define HEADER_SMOKE_H
|
||||||
|
|
||||||
|
#include <plib/sg.h>
|
||||||
|
#include "particle_system.hpp"
|
||||||
|
|
||||||
|
class Kart;
|
||||||
|
|
||||||
|
class Smoke : public ParticleSystem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Kart* m_kart;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Smoke(Kart* kart, int num, float _create_rate,
|
||||||
|
int _turn_to_face, float sz, float bsphere_size);
|
||||||
|
virtual void update (float t );
|
||||||
|
virtual void particle_create(int index, Particle* p );
|
||||||
|
virtual void particle_update(float deltaTime, int index, Particle *p );
|
||||||
|
virtual void particle_delete(int index, Particle* p );
|
||||||
|
};
|
||||||
|
#endif
|
@ -62,6 +62,11 @@ void STKConfig::load(const std::string filename)
|
|||||||
fprintf(stderr,"Not or not enough scores defined in stk_config");
|
fprintf(stderr,"Not or not enough scores defined in stk_config");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
if(m_leader_intervals.size()==0)
|
||||||
|
{
|
||||||
|
fprintf(stderr,"No follow leader interval(s) defined in stk_config");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
CHECK_NEG(m_max_karts, "max-karts" );
|
CHECK_NEG(m_max_karts, "max-karts" );
|
||||||
CHECK_NEG(m_grid_order, "grid-order" );
|
CHECK_NEG(m_grid_order, "grid-order" );
|
||||||
|
|
||||||
@ -148,6 +153,7 @@ void STKConfig::init_defaults()
|
|||||||
m_grid_order = -100;
|
m_grid_order = -100;
|
||||||
m_title_music = NULL;
|
m_title_music = NULL;
|
||||||
m_scores.clear();
|
m_scores.clear();
|
||||||
|
m_leader_intervals.clear();
|
||||||
} // init_defaults
|
} // init_defaults
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -166,6 +172,7 @@ void STKConfig::getAllData(const lisp::Lisp* lisp)
|
|||||||
lisp->get("jump-impulse", m_jump_impulse );
|
lisp->get("jump-impulse", m_jump_impulse );
|
||||||
lisp->get("bomb-time", m_bomb_time );
|
lisp->get("bomb-time", m_bomb_time );
|
||||||
lisp->get("bomb-time-increase", m_bomb_time_increase );
|
lisp->get("bomb-time-increase", m_bomb_time_increase );
|
||||||
|
lisp->getVector("leader-intervals", m_leader_intervals );
|
||||||
lisp->get("anvil-time", m_anvil_time );
|
lisp->get("anvil-time", m_anvil_time );
|
||||||
lisp->get("zipper-time", m_zipper_time );
|
lisp->get("zipper-time", m_zipper_time );
|
||||||
lisp->get("zipper-force", m_zipper_force );
|
lisp->get("zipper-force", m_zipper_force );
|
||||||
|
@ -46,6 +46,8 @@ public:
|
|||||||
float m_explosion_impulse_objects;// impulse of explosion on moving objects, e.g. road cones, ...
|
float m_explosion_impulse_objects;// impulse of explosion on moving objects, e.g. road cones, ...
|
||||||
int m_max_karts; // maximum number of karts
|
int m_max_karts; // maximum number of karts
|
||||||
int m_grid_order; // whether grand prix grid is in point or reverse point order
|
int m_grid_order; // whether grand prix grid is in point or reverse point order
|
||||||
|
std::vector<float>
|
||||||
|
m_leader_intervals; // interval in follow the leader till last kart is reomved
|
||||||
std::vector<int> m_scores; // scores depending on position
|
std::vector<int> m_scores; // scores depending on position
|
||||||
|
|
||||||
MusicInformation* m_title_music; // filename of the title music to play
|
MusicInformation* m_title_music; // filename of the title music to play
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "challenges/all_tracks.hpp"
|
#include "challenges/all_tracks.hpp"
|
||||||
#include "challenges/energy_math_class.hpp"
|
#include "challenges/energy_math_class.hpp"
|
||||||
#include "challenges/win_gotm_cup.hpp"
|
#include "challenges/win_gotm_cup.hpp"
|
||||||
|
#include "challenges/race_track_time.hpp"
|
||||||
#include "user_config.hpp"
|
#include "user_config.hpp"
|
||||||
|
|
||||||
UnlockManager* unlock_manager=0;
|
UnlockManager* unlock_manager=0;
|
||||||
@ -39,6 +40,7 @@ UnlockManager::UnlockManager()
|
|||||||
c=new AllTracks(); m_all_challenges[c->getId()]=c;
|
c=new AllTracks(); m_all_challenges[c->getId()]=c;
|
||||||
c=new EnergyMathClass(); m_all_challenges[c->getId()]=c;
|
c=new EnergyMathClass(); m_all_challenges[c->getId()]=c;
|
||||||
c=new WinGOTMCup(); m_all_challenges[c->getId()]=c;
|
c=new WinGOTMCup(); m_all_challenges[c->getId()]=c;
|
||||||
|
c=new RaceTrackTime(); m_all_challenges[c->getId()]=c;
|
||||||
|
|
||||||
computeActive();
|
computeActive();
|
||||||
} // UnlockManager
|
} // UnlockManager
|
||||||
|
147
src/world.cpp
147
src/world.cpp
@ -49,7 +49,6 @@
|
|||||||
# include "replay_player.hpp"
|
# include "replay_player.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||||
# define snprintf _snprintf
|
# define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
@ -62,14 +61,15 @@ World::World()
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
delete world;
|
delete world;
|
||||||
world = this;
|
world = this;
|
||||||
m_phase = SETUP_PHASE;
|
m_phase = SETUP_PHASE;
|
||||||
m_track = NULL;
|
m_track = NULL;
|
||||||
|
m_clock = 0.0f;
|
||||||
m_clock = 0.0f;
|
m_fastest_lap = 9999999.9f;
|
||||||
m_fastest_lap = 9999999.9f;
|
m_fastest_kart = 0;
|
||||||
m_fastest_kart = 0;
|
m_eliminated_karts = 0;
|
||||||
|
m_eliminated_players = 0;
|
||||||
|
m_leader_intervals = stk_config->m_leader_intervals;
|
||||||
|
|
||||||
// Grab the track file
|
// Grab the track file
|
||||||
try
|
try
|
||||||
@ -251,6 +251,11 @@ void World::update(float dt)
|
|||||||
|
|
||||||
if( getPhase() == FINISH_PHASE )
|
if( getPhase() == FINISH_PHASE )
|
||||||
{
|
{
|
||||||
|
if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER)
|
||||||
|
{
|
||||||
|
menu_manager->pushMenu(MENUID_LEADERRESULT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Add times to highscore list. First compute the order of karts,
|
// Add times to highscore list. First compute the order of karts,
|
||||||
// so that the timing of the fastest kart is added first (otherwise
|
// so that the timing of the fastest kart is added first (otherwise
|
||||||
// someone might get into the highscore list, only to be kicked out
|
// someone might get into the highscore list, only to be kicked out
|
||||||
@ -290,9 +295,10 @@ void World::update(float dt)
|
|||||||
}
|
}
|
||||||
if(!user_config->m_replay_history) history->StoreDelta(dt);
|
if(!user_config->m_replay_history) history->StoreDelta(dt);
|
||||||
m_physics->update(dt);
|
m_physics->update(dt);
|
||||||
for ( Karts::size_type i = 0 ; i < m_kart.size(); ++i)
|
for (int i = 0 ; i <(int) m_kart.size(); ++i)
|
||||||
{
|
{
|
||||||
m_kart[i]->update(dt) ;
|
// Update all karts that are not eliminated
|
||||||
|
if(!race_manager->isEliminated(i)) m_kart[i]->update(dt) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
projectile_manager->update(dt);
|
projectile_manager->update(dt);
|
||||||
@ -300,8 +306,9 @@ void World::update(float dt)
|
|||||||
|
|
||||||
for ( Karts::size_type i = 0 ; i < m_kart.size(); ++i)
|
for ( Karts::size_type i = 0 ; i < m_kart.size(); ++i)
|
||||||
{
|
{
|
||||||
|
if(!m_kart[i]) continue; // ignore eliminated kart
|
||||||
if(!m_kart[i]->raceIsFinished()) updateRacePosition((int)i);
|
if(!m_kart[i]->raceIsFinished()) updateRacePosition((int)i);
|
||||||
m_kart[i]->addMessages();
|
if(m_kart[i]->isPlayerKart()) m_kart[i]->addMessages(); // add 'wrong direction'
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Routine stuff we do even when paused */
|
/* Routine stuff we do even when paused */
|
||||||
@ -412,7 +419,10 @@ void World::updateRaceStatus(float dt)
|
|||||||
case SET_PHASE : if(m_clock>2.0)
|
case SET_PHASE : if(m_clock>2.0)
|
||||||
{
|
{
|
||||||
m_phase=GO_PHASE;
|
m_phase=GO_PHASE;
|
||||||
m_clock=0.0f;
|
if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER)
|
||||||
|
m_clock=m_leader_intervals[0];
|
||||||
|
else
|
||||||
|
m_clock=0.0f;
|
||||||
sound_manager->playSfx(SOUND_START);
|
sound_manager->playSfx(SOUND_START);
|
||||||
// Reset the brakes now that the prestart
|
// Reset the brakes now that the prestart
|
||||||
// phase is over (braking prevents the karts
|
// phase is over (braking prevents the karts
|
||||||
@ -427,9 +437,57 @@ void World::updateRaceStatus(float dt)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GO_PHASE : if(m_clock>1.0) m_phase=RACE_PHASE; break;
|
case GO_PHASE : if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER)
|
||||||
|
{
|
||||||
|
// Switch to race if more than 1 second has past
|
||||||
|
if(m_clock<m_leader_intervals[0]-1.0f)
|
||||||
|
m_phase=RACE_PHASE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(m_clock>1.0) // how long to display the 'go' message
|
||||||
|
m_phase=RACE_PHASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
default : break;
|
default : break;
|
||||||
} // switch
|
} // switch
|
||||||
|
if(race_manager->getRaceMode()==RaceManager::RM_FOLLOW_LEADER)
|
||||||
|
{
|
||||||
|
// Count 'normal' till race phase has started, then count backwards
|
||||||
|
if(m_phase==RACE_PHASE || m_phase==GO_PHASE)
|
||||||
|
m_clock -=dt;
|
||||||
|
else
|
||||||
|
m_clock +=dt;
|
||||||
|
if(m_clock<0.0f)
|
||||||
|
{
|
||||||
|
if(m_leader_intervals.size()>1)
|
||||||
|
m_leader_intervals.erase(m_leader_intervals.begin());
|
||||||
|
m_clock=m_leader_intervals[0];
|
||||||
|
int kart_number;
|
||||||
|
for (kart_number=0; kart_number<(int)m_kart.size(); kart_number++)
|
||||||
|
{
|
||||||
|
if(m_kart[kart_number]->isEliminated()) continue;
|
||||||
|
if(m_kart[kart_number]->getPosition()==getCurrentNumKarts())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(kart_number!=m_kart.size());
|
||||||
|
removeKart(kart_number);
|
||||||
|
// The follow the leader race is over if there isonly one kart left,
|
||||||
|
// or if all players have gone
|
||||||
|
if(getCurrentNumKarts()==2 ||getCurrentNumPlayers()==0)
|
||||||
|
{
|
||||||
|
// Add the results for the remaining kart
|
||||||
|
for(int i=1; i<(int)race_manager->getNumKarts(); i++)
|
||||||
|
if(!m_kart[i]->isEliminated())
|
||||||
|
race_manager->addKartResult(i, m_kart[i]->getPosition(),
|
||||||
|
m_clock);
|
||||||
|
m_phase=FINISH_PHASE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} // m_clock<0
|
||||||
|
return;
|
||||||
|
} // if is follow leader mode
|
||||||
|
|
||||||
// Now handling of normal race
|
// Now handling of normal race
|
||||||
// ===========================
|
// ===========================
|
||||||
@ -442,6 +500,7 @@ void World::updateRaceStatus(float dt)
|
|||||||
int new_finished_karts = 0;
|
int new_finished_karts = 0;
|
||||||
for ( Karts::size_type i = 0; i < m_kart.size(); ++i)
|
for ( Karts::size_type i = 0; i < m_kart.size(); ++i)
|
||||||
{
|
{
|
||||||
|
if(m_kart[i]->isEliminated()) continue;
|
||||||
// FIXME: this part should be done as part of Kart::update
|
// FIXME: this part should be done as part of Kart::update
|
||||||
if ((m_kart[i]->getLap () >= race_manager->getNumLaps()) && !m_kart[i]->raceIsFinished())
|
if ((m_kart[i]->getLap () >= race_manager->getNumLaps()) && !m_kart[i]->raceIsFinished())
|
||||||
{
|
{
|
||||||
@ -521,6 +580,53 @@ void World::updateRaceStatus(float dt)
|
|||||||
if(m_phase==FINISH_PHASE) unlock_manager->raceFinished();
|
if(m_phase==FINISH_PHASE) unlock_manager->raceFinished();
|
||||||
} // updateRaceStatus
|
} // updateRaceStatus
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Called in follow-leader-mode to remove the last kart
|
||||||
|
*/
|
||||||
|
void World::removeKart(int kart_number)
|
||||||
|
{
|
||||||
|
Kart *kart = m_kart[kart_number];
|
||||||
|
// Display a message about the eliminated kart in the race gui
|
||||||
|
RaceGUI* m=(RaceGUI*)menu_manager->getRaceMenu();
|
||||||
|
if(m)
|
||||||
|
{
|
||||||
|
for (std::vector<PlayerKart*>::iterator i = m_player_karts.begin();
|
||||||
|
i != m_player_karts.end(); i++ )
|
||||||
|
{
|
||||||
|
if(*i==kart)
|
||||||
|
{
|
||||||
|
m->addMessage(_("You have been\neliminated!"), *i, 2.0f, 60);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char s[MAX_MESSAGE_LENGTH];
|
||||||
|
snprintf(s, MAX_MESSAGE_LENGTH,_("'%s' has\nbeen eliminated."),
|
||||||
|
kart->getName().c_str());
|
||||||
|
m->addMessage( s, *i, 2.0f, 60);
|
||||||
|
}
|
||||||
|
} // for i in kart
|
||||||
|
} // if raceMenu exist
|
||||||
|
if(kart->isPlayerKart())
|
||||||
|
{
|
||||||
|
// Change the camera so that it will be attached to the leader
|
||||||
|
// and facing backwards.
|
||||||
|
Camera* camera=((PlayerKart*)kart)->getCamera();
|
||||||
|
camera->setMode(Camera::CM_LEADER_MODE);
|
||||||
|
m_eliminated_players++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The kart can't be eliminated, since otherwise a race can't be restarted.
|
||||||
|
// So it's only marked to be eliminated (and ignored in all loops). Important:
|
||||||
|
// world->getCurrentNumKarts() returns the number of still racing karts. This
|
||||||
|
// value can not be used for loops over all karts, use race_manager->getNumKarts()
|
||||||
|
// instead!
|
||||||
|
race_manager->addKartResult(kart_number, kart->getPosition(), m_clock);
|
||||||
|
race_manager->eliminate(kart_number);
|
||||||
|
kart->eliminate();
|
||||||
|
m_eliminated_karts++;
|
||||||
|
|
||||||
|
} // removeKart
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void World::updateRacePosition ( int k )
|
void World::updateRacePosition ( int k )
|
||||||
{
|
{
|
||||||
@ -530,7 +636,8 @@ void World::updateRacePosition ( int k )
|
|||||||
|
|
||||||
for ( Karts::size_type j = 0 ; j < m_kart.size() ; ++j )
|
for ( Karts::size_type j = 0 ; j < m_kart.size() ; ++j )
|
||||||
{
|
{
|
||||||
if ( int(j) == k ) continue ;
|
if(int(j) == k) continue;
|
||||||
|
if(!m_kart[j]) continue; // eliminated karts
|
||||||
|
|
||||||
// Count karts ahead of the current kart, i.e. kart that are already
|
// Count karts ahead of the current kart, i.e. kart that are already
|
||||||
// finished (the current kart k has not yet finished!!), have done more
|
// finished (the current kart k has not yet finished!!), have done more
|
||||||
@ -542,10 +649,9 @@ void World::updateRacePosition ( int k )
|
|||||||
p++ ;
|
p++ ;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_kart [ k ] -> setPosition ( p ) ;
|
m_kart[k]->setPosition(p);
|
||||||
} // updateRacePosition
|
} // updateRacePosition
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void World::loadTrack()
|
void World::loadTrack()
|
||||||
{
|
{
|
||||||
@ -588,8 +694,11 @@ void World::loadTrack()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void World::restartRace()
|
void World::restartRace()
|
||||||
{
|
{
|
||||||
m_clock = 0.0f;
|
m_clock = 0.0f;
|
||||||
m_phase = SETUP_PHASE;
|
m_phase = SETUP_PHASE;
|
||||||
|
m_eliminated_karts = 0;
|
||||||
|
m_eliminated_players = 0;
|
||||||
|
m_leader_intervals = stk_config->m_leader_intervals;
|
||||||
|
|
||||||
for ( Karts::iterator i = m_kart.begin(); i != m_kart.end() ; ++i )
|
for ( Karts::iterator i = m_kart.begin(); i != m_kart.end() ; ++i )
|
||||||
{
|
{
|
||||||
|
@ -90,8 +90,10 @@ public:
|
|||||||
kartId < int(m_kart.size()));
|
kartId < int(m_kart.size()));
|
||||||
return m_kart[kartId];
|
return m_kart[kartId];
|
||||||
}
|
}
|
||||||
unsigned int getNumKarts() const {return (int)m_kart.size(); }
|
unsigned int getCurrentNumKarts() const { return (int)m_kart.size()-
|
||||||
unsigned int getNumPlayers() const {return (unsigned int)m_player_karts.size();}
|
m_eliminated_karts; }
|
||||||
|
unsigned int getCurrentNumPlayers() const { return (int)m_player_karts.size()-
|
||||||
|
m_eliminated_players; }
|
||||||
|
|
||||||
/** Returns the phase of the game */
|
/** Returns the phase of the game */
|
||||||
Phase getPhase() const { return m_phase; }
|
Phase getPhase() const { return m_phase; }
|
||||||
@ -116,11 +118,15 @@ private:
|
|||||||
Highscores* m_highscores;
|
Highscores* m_highscores;
|
||||||
Phase m_phase;
|
Phase m_phase;
|
||||||
float m_clock;
|
float m_clock;
|
||||||
|
int m_eliminated_karts; // number of eliminated karts
|
||||||
void updateRacePosition( int k );
|
int m_eliminated_players; // number of eliminated players
|
||||||
void loadTrack();
|
std::vector<float>
|
||||||
void updateRaceStatus(float dt);
|
m_leader_intervals; // time till elimination in follow leader
|
||||||
void resetAllKarts();
|
void updateRacePosition( int k );
|
||||||
|
void loadTrack();
|
||||||
|
void updateRaceStatus(float dt);
|
||||||
|
void resetAllKarts();
|
||||||
|
void removeKart(int kart_number);
|
||||||
Kart* loadRobot(const std::string& kart_name, int position,
|
Kart* loadRobot(const std::string& kart_name, int position,
|
||||||
sgCoord init_pos);
|
sgCoord init_pos);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user