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
|
||||
(bomb-time 30.0 ) ;; time till a bomb explodes
|
||||
(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
|
||||
(zipper-time 3.0 ) ;; time a zipper is active
|
||||
(zipper-force 800.0 ) ;; additional zipper force
|
||||
|
@ -38,6 +38,7 @@ supertuxkart_SOURCES = main.cpp \
|
||||
music_ogg.cpp music_ogg.hpp \
|
||||
music_information.cpp music_information.hpp \
|
||||
sfx_openal.cpp sfx_openal.hpp \
|
||||
smoke.cpp smoke.hpp \
|
||||
input.hpp \
|
||||
isect.cpp isect.hpp \
|
||||
track.cpp track.hpp \
|
||||
@ -95,6 +96,7 @@ supertuxkart_SOURCES = main.cpp \
|
||||
challenges/all_tracks.cpp challenges/all_tracks.hpp \
|
||||
challenges/energy_math_class.cpp challenges/energy_math_class.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/lexer.cpp lisp/lexer.hpp \
|
||||
lisp/parser.cpp lisp/parser.hpp \
|
||||
@ -118,6 +120,7 @@ supertuxkart_SOURCES = main.cpp \
|
||||
gui/game_mode.cpp gui/game_mode.hpp \
|
||||
gui/difficulty.cpp gui/difficulty.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/help_page_one.cpp gui/help_page_one.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)
|
||||
: m_reverse(false)
|
||||
{
|
||||
m_which_kart = which; // Just for now
|
||||
m_mode = CM_NORMAL;
|
||||
m_context = new ssgContext ;
|
||||
m_mode = CM_NORMAL;
|
||||
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
|
||||
const Track* track = world->getTrack();
|
||||
@ -101,7 +103,10 @@ Camera::Camera(int numPlayers, int which)
|
||||
//-----------------------------------------------------------------------------
|
||||
void Camera::setMode(Mode mode)
|
||||
{
|
||||
m_mode = mode;
|
||||
m_mode = mode;
|
||||
m_LastPitch = 0.0f;
|
||||
if(m_mode==CM_LEADER_MODE)
|
||||
setReverseHeading(true);
|
||||
} // setMode
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -122,32 +127,44 @@ void Camera::reset()
|
||||
//-----------------------------------------------------------------------------
|
||||
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;
|
||||
const Kart *kart=world->getPlayerKart(m_which_kart);
|
||||
sgCopyCoord(&kartcoord, world->getPlayerKart(m_which_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)
|
||||
const Kart *kart;
|
||||
// Update the camera
|
||||
if(m_mode==CM_LEADER_MODE)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
kart=world->getKart(0);
|
||||
sgCopyCoord(&kartcoord, kart->getCoord());
|
||||
// This gives a camera slightly above the kart, facing downwards
|
||||
// But this works only when the karts are within a certain distance
|
||||
// otherwise only the track is seen :(
|
||||
// kartcoord.xyz[2]+=3.0f; // raise camera
|
||||
kartcoord.hpr[1]+=17; // face downwards
|
||||
}
|
||||
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)
|
||||
kartcoord.hpr[0] = 0;
|
||||
@ -180,7 +197,7 @@ void Camera::update (float dt)
|
||||
}
|
||||
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 tmp;
|
||||
|
@ -36,9 +36,9 @@ public:
|
||||
CM_SIMPLE_REPLAY
|
||||
};
|
||||
protected:
|
||||
ssgContext *m_context ;
|
||||
ssgContext *m_context ;
|
||||
|
||||
int m_which_kart ;
|
||||
int m_which_kart;
|
||||
Mode m_mode;
|
||||
float m_last_steer_offset;
|
||||
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->getNumPlayers() > 1) return false;
|
||||
// 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);
|
||||
if(k->isPlayerKart()) return k->getPosition()==1;
|
||||
if(k->isPlayerKart() && !k->isEliminated()) return k->getPosition()==1;
|
||||
}
|
||||
return false;
|
||||
} // raceFinished
|
||||
|
@ -74,17 +74,17 @@ void Collectable::use()
|
||||
case COLLECT_ANVIL:
|
||||
//Attach an anvil(twice as good as the one given
|
||||
//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;
|
||||
if(world->getKart(i)->getPosition() == 1)
|
||||
Kart *kart=world->getKart(i);
|
||||
if(kart->isEliminated()) continue;
|
||||
if(kart == m_owner) continue;
|
||||
if(kart->getPosition() == 1)
|
||||
{
|
||||
world->getKart(i)->
|
||||
attach(ATTACH_ANVIL, stk_config->m_anvil_time);
|
||||
|
||||
world->getKart(i)->adjustSpeedWeight(stk_config->m_anvil_speed_factor*0.5f);
|
||||
kart->attach(ATTACH_ANVIL, stk_config->m_anvil_time);
|
||||
kart->adjustSpeedWeight(stk_config->m_anvil_speed_factor*0.5f);
|
||||
|
||||
if(world->getKart(i)->isPlayerKart())
|
||||
if(kart->isPlayerKart())
|
||||
sound_manager->playSfx(SOUND_USE_ANVIL);
|
||||
break;
|
||||
}
|
||||
@ -98,16 +98,15 @@ void Collectable::use()
|
||||
//Attach a parachutte(that last as twice as the
|
||||
//one from the bananas) to all the karts that
|
||||
//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;
|
||||
if(m_owner->getPosition() > world->
|
||||
getKart(i)->getPosition())
|
||||
Kart *kart=world->getKart(i);
|
||||
if(kart->isEliminated() || kart== m_owner) continue;
|
||||
if(m_owner->getPosition() > kart->getPosition())
|
||||
{
|
||||
world->getKart(i)->attach(
|
||||
ATTACH_PARACHUTE, stk_config->m_parachute_time_other);
|
||||
kart->attach(ATTACH_PARACHUTE, stk_config->m_parachute_time_other);
|
||||
|
||||
if(world->getKart(i)->isPlayerKart())
|
||||
if(kart->isPlayerKart())
|
||||
player_affected = true;
|
||||
}
|
||||
|
||||
@ -137,18 +136,18 @@ void Collectable::hitRedHerring(int n)
|
||||
|
||||
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()));
|
||||
const int RAND_NUM = rand()%100;
|
||||
if(RAND_NUM <= SPECIAL_PROB)
|
||||
{
|
||||
//If the driver in the first position has finished, give the driver
|
||||
//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;
|
||||
if(world->getKart(i)->getPosition() == 1 && world->getKart(i)->
|
||||
raceIsFinished())
|
||||
Kart *kart = world->getKart(i);
|
||||
if(kart->isEliminated() || kart == m_owner) continue;
|
||||
if(kart->getPosition() == 1 && kart->raceIsFinished())
|
||||
{
|
||||
m_type = COLLECT_PARACHUTE;
|
||||
m_number = 1;
|
||||
|
@ -150,10 +150,10 @@ void Flyable::getClosestKart(const Kart **minKart, float *minDist, btVector3 *mi
|
||||
{
|
||||
btTransform tProjectile=getTrans();
|
||||
*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);
|
||||
if(kart == m_owner) continue;
|
||||
if(kart->isEliminated() || kart == m_owner) continue;
|
||||
btTransform t=kart->getTrans();
|
||||
|
||||
btVector3 delta = t.getOrigin()-tProjectile.getOrigin();
|
||||
@ -224,9 +224,9 @@ void Flyable::explode(Kart *kart_hit, MovingPhysics* moving_physics)
|
||||
world->getPhysics()->removeBody(getBody());
|
||||
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.
|
||||
kart->handleExplosion(m_curr_pos.xyz, kart==kart_hit);
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ enum WidgetTokens
|
||||
WTOK_GP,
|
||||
WTOK_QUICKRACE,
|
||||
WTOK_TIMETRIAL,
|
||||
WTOK_FOLLOW_LEADER,
|
||||
WTOK_EMPTY,
|
||||
WTOK_BACK
|
||||
};
|
||||
@ -68,7 +69,16 @@ GameMode::GameMode()
|
||||
widget_manager->addWgt(WTOK_TIMETRIAL, 50, 7);
|
||||
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->hideWgtRect( WTOK_EMPTY );
|
||||
widget_manager->hideWgtText( WTOK_EMPTY );
|
||||
@ -101,6 +111,10 @@ void GameMode::select()
|
||||
race_manager->setRaceMode(RaceManager::RM_QUICK_RACE);
|
||||
menu_manager->pushMenu(MENUID_DIFFICULTY);
|
||||
break;
|
||||
case WTOK_FOLLOW_LEADER:
|
||||
race_manager->setRaceMode(RaceManager::RM_FOLLOW_LEADER);
|
||||
menu_manager->pushMenu(MENUID_DIFFICULTY);
|
||||
break;
|
||||
case WTOK_TIMETRIAL:
|
||||
race_manager->setRaceMode(RaceManager::RM_TIME_TRIAL);
|
||||
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 "challenges_menu.hpp"
|
||||
#include "feature_unlocked.hpp"
|
||||
#include "leader_result.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -187,6 +188,9 @@ void MenuManager::update()
|
||||
case MENUID_RACERESULT:
|
||||
m_current_menu= new RaceResultsGUI();
|
||||
break;
|
||||
case MENUID_LEADERRESULT:
|
||||
m_current_menu= new LeaderResult();
|
||||
break;
|
||||
case MENUID_GRANDPRIXEND:
|
||||
m_current_menu= new GrandPrixEnd();
|
||||
break;
|
||||
|
@ -36,6 +36,7 @@ enum MenuManagerIDs
|
||||
MENUID_DIFFICULTY,
|
||||
MENUID_GAMEMODE,
|
||||
MENUID_RACERESULT,
|
||||
MENUID_LEADERRESULT,
|
||||
MENUID_GRANDPRIXEND,
|
||||
MENUID_RACEMENU,
|
||||
MENUID_TRACKSEL,
|
||||
|
@ -167,21 +167,21 @@ RaceGUI::handle(GameAction ga, int value)
|
||||
switch (ga)
|
||||
{
|
||||
case GA_DEBUG_ADD_SPARK:
|
||||
if (world->getNumPlayers() ==1 )
|
||||
if (race_manager->getNumPlayers() ==1 )
|
||||
{
|
||||
Kart* kart = world->getPlayerKart(0);
|
||||
kart->setCollectable(COLLECT_SPARK, 10000);
|
||||
}
|
||||
break;
|
||||
case GA_DEBUG_ADD_MISSILE:
|
||||
if (world->getNumPlayers() ==1 )
|
||||
if (race_manager->getNumPlayers() ==1 )
|
||||
{
|
||||
Kart* kart = world->getPlayerKart(0);
|
||||
kart->setCollectable(COLLECT_MISSILE, 10000);
|
||||
}
|
||||
break;
|
||||
case GA_DEBUG_ADD_HOMING:
|
||||
if (world->getNumPlayers() ==1 )
|
||||
if (race_manager->getNumPlayers() ==1 )
|
||||
{
|
||||
Kart* kart = world->getPlayerKart(0);
|
||||
kart->setCollectable(COLLECT_HOMING, 10000);
|
||||
@ -289,11 +289,12 @@ void RaceGUI::drawMap ()
|
||||
|
||||
glBegin ( GL_QUADS ) ;
|
||||
|
||||
for ( unsigned int i = 0 ; i < world->getNumKarts() ; i++ )
|
||||
for ( unsigned int i = 0 ; i < race_manager->getNumKarts() ; i++ )
|
||||
{
|
||||
sgCoord *c ;
|
||||
|
||||
Kart* kart = world->getKart(i);
|
||||
if(kart->isEliminated()) continue; // don't draw eliminated kart
|
||||
glColor3fv ( *kart->getColor());
|
||||
c = kart->getCoord () ;
|
||||
|
||||
@ -336,9 +337,10 @@ void RaceGUI::drawPlayerIcons ()
|
||||
// Find the best time for the lap. We can't simply use
|
||||
// the time of the kart at position 1, since the kart
|
||||
// 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);
|
||||
if(kart->isEliminated()) continue;
|
||||
float lap_time = kart->getTimeAtLap();
|
||||
int laps = kart->getLap();
|
||||
|
||||
@ -355,9 +357,10 @@ void RaceGUI::drawPlayerIcons ()
|
||||
} // for i<getNumKarts
|
||||
|
||||
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);
|
||||
if(kart->isEliminated()) continue;
|
||||
int position = kart->getPosition();
|
||||
int lap = kart->getLap();
|
||||
|
||||
@ -395,8 +398,9 @@ void RaceGUI::drawPlayerIcons ()
|
||||
str[0]='+'; str[1]=0;
|
||||
TimeToString(timeBehind, str+1);
|
||||
}
|
||||
font_race->PrintShadow(str, 30, ICON_PLAYER_WIDHT+x, y+5,
|
||||
red, green, blue);
|
||||
if(race_manager->raceHasLaps())
|
||||
font_race->PrintShadow(str, 30, ICON_PLAYER_WIDHT+x, y+5,
|
||||
red, green, blue);
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
// 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);
|
||||
char str[256];
|
||||
@ -909,7 +913,7 @@ void RaceGUI::drawStatusText(const float dt)
|
||||
}
|
||||
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())
|
||||
{
|
||||
@ -922,14 +926,14 @@ void RaceGUI::drawStatusText(const float dt)
|
||||
|
||||
float split_screen_ratio_x, split_screen_ratio_y;
|
||||
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;
|
||||
if(world->getNumPlayers() >= 3)
|
||||
if(race_manager->getNumPlayers() >= 3)
|
||||
split_screen_ratio_x = 0.5;
|
||||
|
||||
if ( world->isRacePhase() )
|
||||
{
|
||||
const int numPlayers = world->getNumPlayers();
|
||||
const int numPlayers = race_manager->getNumPlayers();
|
||||
|
||||
for(int pla = 0; pla < numPlayers; pla++)
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ RaceResultsGUI::RaceResultsGUI()
|
||||
|
||||
|
||||
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];
|
||||
m_score = new char[NUM_KARTS * MAX_STR_LEN];
|
||||
@ -82,7 +82,7 @@ RaceResultsGUI::RaceResultsGUI()
|
||||
|
||||
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;
|
||||
const std::string& s = k->getName();
|
||||
unsigned int l = (unsigned int)s.size();
|
||||
|
@ -853,6 +853,10 @@
|
||||
RelativePath="../../../src\skid_mark.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\smoke.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="../../../src\sound_manager.cpp"
|
||||
>
|
||||
@ -992,6 +996,10 @@
|
||||
RelativePath="..\..\gui\help_page_two.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\leader_result.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="../../../src\gui\main_menu.cpp"
|
||||
>
|
||||
@ -1080,6 +1088,10 @@
|
||||
RelativePath="..\..\challenges\energy_math_class.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\challenges\race_track_time.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\challenges\win_gotm_cup.cpp"
|
||||
>
|
||||
@ -1315,6 +1327,10 @@
|
||||
RelativePath="../../../src\skid_mark.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\smoke.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="../../../src\sound_manager.hpp"
|
||||
>
|
||||
@ -1454,6 +1470,10 @@
|
||||
RelativePath="..\..\gui\help_page_two.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\leader_result.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="../../../src\gui\main_menu.hpp"
|
||||
>
|
||||
@ -1542,6 +1562,10 @@
|
||||
RelativePath="..\..\challenges\energy_math_class.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\challenges\race_track_time.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\challenges\win_gotm_cup.hpp"
|
||||
>
|
||||
|
107
src/kart.cpp
107
src/kart.cpp
@ -20,6 +20,7 @@
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <plib/ssg.h>
|
||||
#include "bullet/Demos/OpenGL/GL_ShapeDrawer.h"
|
||||
|
||||
#include "loader.hpp"
|
||||
#include "herring_manager.hpp"
|
||||
@ -38,87 +39,12 @@
|
||||
#include "gui/menu_manager.hpp"
|
||||
#include "gui/race_gui.hpp"
|
||||
#include "translation.hpp"
|
||||
#include "bullet/Demos/OpenGL/GL_ShapeDrawer.h"
|
||||
#include "smoke.hpp"
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
# define snprintf _snprintf
|
||||
#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_ ,
|
||||
sgCoord init_pos)
|
||||
: 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_grid_position = position_ ;
|
||||
m_num_herrings_gobbled = 0;
|
||||
m_eliminated = false;
|
||||
m_finished_race = false;
|
||||
m_finish_time = 0.0f;
|
||||
m_prev_accel = 0.0f;
|
||||
@ -325,6 +252,17 @@ 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'
|
||||
*
|
||||
@ -352,6 +290,10 @@ void Kart::adjustSpeedWeight(float f)
|
||||
//-----------------------------------------------------------------------------
|
||||
void Kart::reset()
|
||||
{
|
||||
if(m_eliminated)
|
||||
{
|
||||
world->getPhysics()->addKart(this, m_vehicle);
|
||||
}
|
||||
Moveable::reset();
|
||||
|
||||
m_attachment.clear();
|
||||
@ -363,6 +305,7 @@ void Kart::reset()
|
||||
m_shortcut_sector = Track::UNKNOWN_SECTOR;
|
||||
m_race_position = 9;
|
||||
m_finished_race = false;
|
||||
m_eliminated = false;
|
||||
m_finish_time = 0.0f;
|
||||
m_zipper_time_left = 0.0f;
|
||||
m_num_herrings_gobbled = 0;
|
||||
@ -460,7 +403,8 @@ void Kart::doLapCounting ()
|
||||
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);
|
||||
RaceGUI* m=(RaceGUI*)menu_manager->getRaceMenu();
|
||||
@ -490,6 +434,13 @@ void Kart::doLapCounting ()
|
||||
// Prevent cheating by setting time to a negative number, indicating
|
||||
// that the line wasn't crossed properly.
|
||||
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
|
||||
|
||||
@ -1118,7 +1069,7 @@ void Kart::loadData()
|
||||
|
||||
// Attach Particle System
|
||||
//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);
|
||||
//JH m_smoke_system -> setState (getMaterial ("smoke.png")-> getState() );
|
||||
//m_smoke_system -> setState ( m_smokepuff ) ;
|
||||
|
23
src/kart.hpp
23
src/kart.hpp
@ -25,7 +25,6 @@
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
|
||||
#include "moveable.hpp"
|
||||
#include "particle_system.hpp"
|
||||
#include "kart_properties.hpp"
|
||||
#include "attachment.hpp"
|
||||
#include "collectable.hpp"
|
||||
@ -46,24 +45,9 @@ struct KartControl
|
||||
};
|
||||
|
||||
class SkidMark;
|
||||
class Kart;
|
||||
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
|
||||
{
|
||||
protected:
|
||||
@ -105,7 +89,7 @@ private:
|
||||
int m_num_herrings_gobbled;
|
||||
ssgSimpleState* m_smokepuff;
|
||||
// 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;
|
||||
|
||||
float m_wheel_rotation;
|
||||
@ -124,6 +108,7 @@ private:
|
||||
|
||||
float m_speed;
|
||||
bool m_rescue;
|
||||
bool m_eliminated;
|
||||
|
||||
protected:
|
||||
float m_rescue_pitch, m_rescue_roll;
|
||||
@ -217,6 +202,8 @@ public:
|
||||
float handleWheelie (float dt);
|
||||
float getActualWheelForce();
|
||||
bool isOnGround () const;
|
||||
bool isEliminated () const {return m_eliminated;}
|
||||
void eliminate ();
|
||||
bool isRescue () const {return m_rescue;}
|
||||
void resetBrakes ();
|
||||
void adjustSpeedWeight(float f);
|
||||
|
@ -219,6 +219,7 @@ void PlayerKart::reset()
|
||||
m_controls.jump = false;
|
||||
m_penalty_time = 0;
|
||||
m_time_last_crash_sound = -10.0f;
|
||||
m_camera->setMode(Camera::CM_NORMAL); // can be changed if camera was eliminated
|
||||
m_camera->setReverseHeading(false);
|
||||
Kart::reset();
|
||||
} // reset
|
||||
|
@ -204,11 +204,23 @@ void RaceManager::exit_race()
|
||||
//-----------------------------------------------------------------------------
|
||||
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_last_score = m_score_for_position[pos-1];
|
||||
m_kart_status[kart].m_overall_time += time;
|
||||
m_kart_status[kart].m_last_time = time;
|
||||
} // addKartResult
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void RaceManager::restartRace()
|
||||
{
|
||||
|
@ -87,6 +87,12 @@ private:
|
||||
unsigned int m_num_finished_players;
|
||||
|
||||
void startNextRace(); // start a next race
|
||||
|
||||
friend bool operator< (const KartStatus& left, const KartStatus& right)
|
||||
{
|
||||
return (left.m_score < right.m_score);
|
||||
}
|
||||
|
||||
public:
|
||||
bool m_active_race; //True if there is a race
|
||||
|
||||
@ -119,10 +125,12 @@ public:
|
||||
{ return m_kart_status[kart].m_ident;}
|
||||
const std::string& getHerringStyle() const
|
||||
{ return m_cup.getHerringStyle(); }
|
||||
int getKartScore(int kart) const { return m_kart_status[kart].m_score;}
|
||||
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;}
|
||||
int getKartScore(int krt) const { return m_kart_status[krt].m_score;}
|
||||
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;}
|
||||
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 PlayerFinishes() { m_num_finished_players++; }
|
||||
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 restartRace(); // restart same race again
|
||||
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;
|
||||
|
@ -556,7 +556,7 @@ void DefaultRobot::check_crashes( const int STEPS, sgVec3 const pos )
|
||||
|
||||
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
|
||||
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 )
|
||||
{
|
||||
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,
|
||||
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)
|
||||
{
|
||||
(*i)->update(dt);
|
||||
(*i) -> apply () ;
|
||||
(*i)->apply ();
|
||||
|
||||
if(!user_config->m_bullet_debug)
|
||||
{
|
||||
@ -179,15 +179,16 @@ void Scene::draw(float dt)
|
||||
glFrustum(-f, f, -f, f, 1.0, 1000.0);
|
||||
|
||||
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,
|
||||
c->xyz[0], c->xyz[1], c->xyz[2],
|
||||
0.0f, 0.0f, 1.0f);
|
||||
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();
|
||||
} // 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");
|
||||
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_grid_order, "grid-order" );
|
||||
|
||||
@ -148,6 +153,7 @@ void STKConfig::init_defaults()
|
||||
m_grid_order = -100;
|
||||
m_title_music = NULL;
|
||||
m_scores.clear();
|
||||
m_leader_intervals.clear();
|
||||
} // init_defaults
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -166,6 +172,7 @@ void STKConfig::getAllData(const lisp::Lisp* lisp)
|
||||
lisp->get("jump-impulse", m_jump_impulse );
|
||||
lisp->get("bomb-time", m_bomb_time );
|
||||
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("zipper-time", m_zipper_time );
|
||||
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, ...
|
||||
int m_max_karts; // maximum number of karts
|
||||
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
|
||||
|
||||
MusicInformation* m_title_music; // filename of the title music to play
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "challenges/all_tracks.hpp"
|
||||
#include "challenges/energy_math_class.hpp"
|
||||
#include "challenges/win_gotm_cup.hpp"
|
||||
#include "challenges/race_track_time.hpp"
|
||||
#include "user_config.hpp"
|
||||
|
||||
UnlockManager* unlock_manager=0;
|
||||
@ -39,6 +40,7 @@ UnlockManager::UnlockManager()
|
||||
c=new AllTracks(); 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 RaceTrackTime(); m_all_challenges[c->getId()]=c;
|
||||
|
||||
computeActive();
|
||||
} // UnlockManager
|
||||
|
147
src/world.cpp
147
src/world.cpp
@ -49,7 +49,6 @@
|
||||
# include "replay_player.hpp"
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WIN32) && !defined(__CYGWIN__)
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
@ -62,14 +61,15 @@ World::World()
|
||||
#endif
|
||||
{
|
||||
delete world;
|
||||
world = this;
|
||||
m_phase = SETUP_PHASE;
|
||||
m_track = NULL;
|
||||
|
||||
m_clock = 0.0f;
|
||||
m_fastest_lap = 9999999.9f;
|
||||
m_fastest_kart = 0;
|
||||
|
||||
world = this;
|
||||
m_phase = SETUP_PHASE;
|
||||
m_track = NULL;
|
||||
m_clock = 0.0f;
|
||||
m_fastest_lap = 9999999.9f;
|
||||
m_fastest_kart = 0;
|
||||
m_eliminated_karts = 0;
|
||||
m_eliminated_players = 0;
|
||||
m_leader_intervals = stk_config->m_leader_intervals;
|
||||
|
||||
// Grab the track file
|
||||
try
|
||||
@ -251,6 +251,11 @@ void World::update(float dt)
|
||||
|
||||
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,
|
||||
// so that the timing of the fastest kart is added first (otherwise
|
||||
// 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);
|
||||
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);
|
||||
@ -300,8 +306,9 @@ void World::update(float dt)
|
||||
|
||||
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);
|
||||
m_kart[i]->addMessages();
|
||||
if(m_kart[i]->isPlayerKart()) m_kart[i]->addMessages(); // add 'wrong direction'
|
||||
}
|
||||
|
||||
/* Routine stuff we do even when paused */
|
||||
@ -412,7 +419,10 @@ void World::updateRaceStatus(float dt)
|
||||
case SET_PHASE : if(m_clock>2.0)
|
||||
{
|
||||
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);
|
||||
// Reset the brakes now that the prestart
|
||||
// phase is over (braking prevents the karts
|
||||
@ -427,9 +437,57 @@ void World::updateRaceStatus(float dt)
|
||||
#endif
|
||||
}
|
||||
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;
|
||||
} // 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
|
||||
// ===========================
|
||||
@ -442,6 +500,7 @@ void World::updateRaceStatus(float dt)
|
||||
int new_finished_karts = 0;
|
||||
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
|
||||
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();
|
||||
} // 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 )
|
||||
{
|
||||
@ -530,7 +636,8 @@ void World::updateRacePosition ( int k )
|
||||
|
||||
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
|
||||
// finished (the current kart k has not yet finished!!), have done more
|
||||
@ -542,10 +649,9 @@ void World::updateRacePosition ( int k )
|
||||
p++ ;
|
||||
}
|
||||
|
||||
m_kart [ k ] -> setPosition ( p ) ;
|
||||
m_kart[k]->setPosition(p);
|
||||
} // updateRacePosition
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void World::loadTrack()
|
||||
{
|
||||
@ -588,8 +694,11 @@ void World::loadTrack()
|
||||
//-----------------------------------------------------------------------------
|
||||
void World::restartRace()
|
||||
{
|
||||
m_clock = 0.0f;
|
||||
m_phase = SETUP_PHASE;
|
||||
m_clock = 0.0f;
|
||||
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 )
|
||||
{
|
||||
|
@ -90,8 +90,10 @@ public:
|
||||
kartId < int(m_kart.size()));
|
||||
return m_kart[kartId];
|
||||
}
|
||||
unsigned int getNumKarts() const {return (int)m_kart.size(); }
|
||||
unsigned int getNumPlayers() const {return (unsigned int)m_player_karts.size();}
|
||||
unsigned int getCurrentNumKarts() const { return (int)m_kart.size()-
|
||||
m_eliminated_karts; }
|
||||
unsigned int getCurrentNumPlayers() const { return (int)m_player_karts.size()-
|
||||
m_eliminated_players; }
|
||||
|
||||
/** Returns the phase of the game */
|
||||
Phase getPhase() const { return m_phase; }
|
||||
@ -116,11 +118,15 @@ private:
|
||||
Highscores* m_highscores;
|
||||
Phase m_phase;
|
||||
float m_clock;
|
||||
|
||||
void updateRacePosition( int k );
|
||||
void loadTrack();
|
||||
void updateRaceStatus(float dt);
|
||||
void resetAllKarts();
|
||||
int m_eliminated_karts; // number of eliminated karts
|
||||
int m_eliminated_players; // number of eliminated players
|
||||
std::vector<float>
|
||||
m_leader_intervals; // time till elimination in follow leader
|
||||
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,
|
||||
sgCoord init_pos);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user