1) Added support for kart groups, added all current karts to the group 'standard'.

2) Cleaned up unused kart physics parameters, added new suspension_travel_cm parameter.
3) Renamed TrackManager::getTrackCount() to getNumberOfTracks() (to follow the same pattern as
   getNumberOfKarts()).
4) Minor code cleanup, warnings removal, ...


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2148 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2008-07-03 03:14:27 +00:00
parent 511292b62d
commit dde2f508d3
25 changed files with 1692 additions and 1521 deletions

View File

@@ -69,6 +69,7 @@
(gravity-center-shift 0.4 ) ;; Shift center of gravity down by that many
;; units of kart_height (usually between 0 and 0.5)
(suspension-rest 0.1 )
(suspension-travel-cm 500 )
;; The z-axis velocity set when a jump is initiated. This will cause the
;; kart to start rising, till it is pulled back by gravity. A higher value

View File

@@ -1,318 +1,415 @@
// $Id$
//
// 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 3
// 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 "char_sel.hpp"
#include "kart_properties_manager.hpp"
#include "widget_manager.hpp"
#include "race_manager.hpp"
#include "user_config.hpp"
#include "menu_manager.hpp"
#include "kart_properties.hpp"
#include "material_manager.hpp"
#include "material.hpp"
#include "unlock_manager.hpp"
#include "translation.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
enum WidgetTokens
{
WTOK_TITLE,
WTOK_QUIT,
WTOK_EMPTY_UP,
WTOK_UP,
WTOK_EMPTY_DOWN,
WTOK_DOWN,
WTOK_EMPTY0 = 10,
WTOK_NAME0 = 20,
WTOK_RACER0 = 30
};
CharSel::CharSel(int whichPlayer)
: m_kart(0), m_player_index(whichPlayer)
{
// 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();
// If m_player_index is 0 then this is a single player game or the first
// player of a multiplayer game so we need to ensure that all karts are available.
// If m_player_index is less than the number of elements in selected_karts then
// the user is moving back through the menus and the last value in the vector
// needs to be made available again.
if (m_player_index == 0)
kart_properties_manager->m_selected_karts.clear();
if (m_player_index < (int)kart_properties_manager->m_selected_karts.size())
kart_properties_manager->m_selected_karts.pop_back();
char heading[MAX_MESSAGE_LENGTH];
snprintf(heading, sizeof(heading), _("Player %d, choose a driver"),
m_player_index + 1);
widget_manager->addTitleWgt( WTOK_TITLE, 100, 10, heading );
widget_manager->breakLine();
widget_manager->addEmptyWgt( WidgetManager::WGT_NONE, 1, 2);
widget_manager->breakLine();
m_num_entries = 0;
for(unsigned int i=0; i<kart_properties_manager->getNumberOfKarts(); i++)
{
if(kartAvailable(i))
{
m_indexAvailKart.push_back(i);
m_num_entries++;
}
}
if(m_num_entries>7) m_num_entries = 7;
const int HEIGHT = 10;
widget_manager->addEmptyWgt(WTOK_EMPTY_UP, computeIndent(0), HEIGHT/2);
widget_manager->addTextButtonWgt(WTOK_UP, 20, HEIGHT/2, "^");
widget_manager->breakLine();
int indx;
const KartProperties* kp;
for (unsigned int i = 0; i < m_num_entries; i++)
{
indx = m_indexAvailKart[i];
kp = kart_properties_manager->getKartById(indx);
widget_manager->addEmptyWgt( WTOK_EMPTY0+i, computeIndent(i), HEIGHT );
widget_manager->addImgButtonWgt(WTOK_RACER0 + i, 8, HEIGHT,
kp->getIconFile() );
widget_manager->addTextButtonWgt(WTOK_NAME0+i, 30, HEIGHT, kp->getName());
widget_manager->setWgtTextSize(WTOK_NAME0+i, WGT_FNT_SML);
widget_manager->breakLine();
}
widget_manager->addEmptyWgt(WTOK_EMPTY_DOWN, computeIndent(m_num_entries), HEIGHT/2);
widget_manager->addTextButtonWgt(WTOK_DOWN, 20, HEIGHT/2, "v");
widget_manager->breakLine();
widget_manager->breakLine();
widget_manager->addEmptyWgt( WidgetManager::WGT_NONE, 1, 2);
widget_manager->breakLine();
widget_manager->layout(WGT_AREA_RGT);
m_current_kart = -1;
const int LAST_KART = user_config->m_player[m_player_index].getLastKartId();
if( LAST_KART != -1 && kartAvailable(LAST_KART))// is LAST_KART not in vector of selected karts
{
m_offset = LAST_KART - m_num_entries/2;
widget_manager->setSelectedWgt(WTOK_RACER0 + LAST_KART);
switchCharacter(LAST_KART);
}
else
{
m_offset = 0;
switchCharacter(0);
}
updateScrollPosition();
m_clock = 0;
//test
} // CharSel
//-----------------------------------------------------------------------------
CharSel::~CharSel()
{
widget_manager->reset();
ssgDeRefDelete(m_kart);
delete m_context;
} // ~CharSel
//-----------------------------------------------------------------------------
void CharSel::updateScrollPosition()
{
for(unsigned int i=0; i<m_num_entries; i++)
{
int indx = (i+m_offset) % m_indexAvailKart.size();
indx = m_indexAvailKart[indx];
const KartProperties* kp= kart_properties_manager->getKartById(indx);
if(unlock_manager->isLocked(kp->getIdent())) continue;
widget_manager->setWgtText(WTOK_NAME0 + i, kp->getName());
widget_manager->setWgtTexture(WTOK_RACER0 + i, kp->getIconFile() );
} // for i
} // updateScrollPosition<
//-----------------------------------------------------------------------------
void CharSel::switchCharacter(int n)
{
const KartProperties* kp= kart_properties_manager->getKartById(m_indexAvailKart[n]);
if (m_current_kart != n && kp != NULL)
{
m_current_kart = n;
ssgDeRefDelete(m_kart);
m_kart = new ssgTransform;
m_kart->ref();
ssgEntity* kartentity = kp->getModel();
m_kart->addKid(kartentity);
}
} // switchCharacter
//-----------------------------------------------------------------------------
void CharSel::update(float dt)
{
m_clock += dt * 40.0f;
if( widget_manager->selectionChanged() )
{
int token = widget_manager->getSelectedWgt() - WTOK_RACER0;
if(token<0 || token>(int)m_num_entries)
token = widget_manager->getSelectedWgt() - WTOK_NAME0;
switchCharacter((token+m_offset)%kart_properties_manager->getNumberOfKarts());
}
if (m_kart != NULL)
{
ssgContext* oldContext = ssgGetCurrentContext();
m_context -> makeCurrent();
glClear(GL_DEPTH_BUFFER_BIT);
// Puts the character in the center. Scaling is done by
// applying a big camera FOV.
int w = user_config->m_width;
int h = user_config->m_height;
glViewport ( 0, h*1/4, (int)(0.7f*w), (int)(0.7f*h));
m_context -> setFOV ( 65.0f, 65.0f * h/w ) ;
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();
}
widget_manager->update(dt);
} // update
//----------------------------------------------------------------------------
void CharSel::select()
{
int wgt = widget_manager->getSelectedWgt();
if(wgt==WTOK_UP)
{
m_offset--;
if(m_offset < 0) m_offset = m_indexAvailKart.size() - 1;
updateScrollPosition();
return;
}
if(wgt==WTOK_DOWN)
{
m_offset++;
if( m_offset >= (int)m_indexAvailKart.size() ) m_offset=0;
updateScrollPosition();
return;
}
int token = widget_manager->getSelectedWgt() - WTOK_RACER0;
if(token<0 || token>(int)m_num_entries)
{
token = widget_manager->getSelectedWgt() - WTOK_NAME0;
}
token = (token+m_offset) % m_indexAvailKart.size();
int kart_id = m_indexAvailKart[token];
const KartProperties* KP = kart_properties_manager->getKartById(kart_id);
if (KP != NULL)
{
race_manager->setPlayerKart(m_player_index, KP->getIdent());
user_config->m_player[m_player_index].setLastKartId(kart_id);
// Add selected kart (token) to selected karts vector so it cannot be
// selected again
kart_properties_manager->m_selected_karts.push_back(kart_id);
}
if (race_manager->getNumPlayers() > 1)
{
if (menu_manager->isCurrentMenu(MENUID_CHARSEL_P1))
{
menu_manager->pushMenu(MENUID_CHARSEL_P2);
return;
}
}
if (race_manager->getNumPlayers() > 2)
{
if (menu_manager->isCurrentMenu(MENUID_CHARSEL_P2))
{
menu_manager->pushMenu(MENUID_CHARSEL_P3);
return;
}
}
if (race_manager->getNumPlayers() > 3)
{
if (menu_manager->isCurrentMenu(MENUID_CHARSEL_P3))
{
menu_manager->pushMenu(MENUID_CHARSEL_P4);
return;
}
}
if (race_manager->getRaceMode() == RaceManager::RM_GRAND_PRIX)
menu_manager->pushMenu(MENUID_GRANDPRIXSELECT);
else
menu_manager->pushMenu(MENUID_TRACKSEL);
} // select
//----------------------------------------------------------------------------
// Function checks the vector of previously selected karts and returns true if
// kart i is in the vector and false if it is not.
bool CharSel::kartAvailable(int kart)
{
if (!kart_properties_manager->m_selected_karts.empty())
{
std::vector<int>::iterator it;
for (it = kart_properties_manager->m_selected_karts.begin();
it < kart_properties_manager->m_selected_karts.end(); it++)
{
if ( kart == *it)
return false;
}
}
return true;
} // kartAvailable
// $Id$
//
// 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 3
// 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 "char_sel.hpp"
#include "kart_properties_manager.hpp"
#include "widget_manager.hpp"
#include "race_manager.hpp"
#include "user_config.hpp"
#include "menu_manager.hpp"
#include "kart_properties.hpp"
#include "material_manager.hpp"
#include "material.hpp"
#include "unlock_manager.hpp"
#include "translation.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
enum WidgetTokens
{
WTOK_TITLE,
WTOK_QUIT,
WTOK_EMPTY_UP,
WTOK_UP,
WTOK_EMPTY_DOWN,
WTOK_DOWN,
WTOK_EMPTY0 = 10,
WTOK_NAME0 = 20,
WTOK_RACER0 = 30
};
CharSel::CharSel(int whichPlayer)
: m_kart(0), m_player_index(whichPlayer)
{
// 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();
// If m_player_index is 0 then this is a single player game or the first
// player of a multiplayer game so we need to ensure that all karts are available.
// If m_player_index is less than the number of elements in selected_karts then
// the user is moving back through the menus and the last value in the vector
// needs to be made available again.
if (m_player_index == 0)
kart_properties_manager->m_selected_karts.clear();
if (m_player_index < (int)kart_properties_manager->m_selected_karts.size())
kart_properties_manager->m_selected_karts.pop_back();
char heading[MAX_MESSAGE_LENGTH];
snprintf(heading, sizeof(heading), _("Player %d, choose a driver"),
m_player_index + 1);
widget_manager->addTitleWgt( WTOK_TITLE, 100, 10, heading );
widget_manager->breakLine();
widget_manager->addEmptyWgt( WidgetManager::WGT_NONE, 1, 2);
widget_manager->breakLine();
const int HEIGHT = 10;
widget_manager->addEmptyWgt(WTOK_EMPTY_UP, computeIndent(0), HEIGHT/2);
widget_manager->addTextButtonWgt(WTOK_UP, 20, HEIGHT/2, "^");
widget_manager->breakLine();
for (unsigned int i = 0; i < m_max_entries; i++)
{
// Depending on previously selected kart indx here might be a group,
// i.e. indx is negative, and kp is not defined. To avoid this,
// all widgets are _initialised_ with kart 0 (which surely exists),
// before later calling switchCharacter, which will define the
// proper icons and texts.
const KartProperties* kp = kart_properties_manager->getKartById(0);
widget_manager->addEmptyWgt(WTOK_EMPTY0+i, computeIndent(i), HEIGHT );
widget_manager->addImgButtonWgt(WTOK_RACER0 + i, 8, HEIGHT,
kp->getIconFile() );
widget_manager->addTextButtonWgt(WTOK_NAME0+i, 30, HEIGHT, "");
widget_manager->setWgtTextSize(WTOK_NAME0+i, WGT_FNT_SML);
widget_manager->breakLine();
}
widget_manager->addEmptyWgt(WTOK_EMPTY_DOWN, computeIndent(m_max_entries), HEIGHT/2);
widget_manager->addTextButtonWgt(WTOK_DOWN, 20, HEIGHT/2, "v");
//widget_manager->breakLine();
switchGroup(); // select all karts from the currently selected group
//widget_manager->breakLine();
//widget_manager->addEmptyWgt( WidgetManager::WGT_NONE, 1, 2);
//widget_manager->breakLine();
widget_manager->layout(WGT_AREA_RGT);
m_current_kart = -1;
const int LAST_KART = user_config->m_player[m_player_index].getLastKartId();
if( LAST_KART != -1 && kartAvailable(LAST_KART))// is LAST_KART not in vector of selected karts
{
int local_index = 0;
for(unsigned int i=0; i<m_index_avail_karts.size(); i++)
{
if(m_index_avail_karts[i]==LAST_KART)
{
local_index = i;
break;
}
}
m_offset = local_index - m_max_entries/2;
if(m_offset<0) m_offset+=(int)m_index_avail_karts.size();
widget_manager->setSelectedWgt(WTOK_RACER0 + local_index);
switchCharacter(local_index);
}
else
{
m_offset = 0;
switchCharacter(0);
}
updateScrollPosition();
m_clock = 0;
//test
} // CharSel
//-----------------------------------------------------------------------------
CharSel::~CharSel()
{
widget_manager->reset();
ssgDeRefDelete(m_kart);
delete m_context;
} // ~CharSel
//-----------------------------------------------------------------------------
void CharSel::updateScrollPosition()
{
// Handle the special case of less karts (plus groups) than widgets.
// Some of the widgets then need to be disabled.
unsigned int start = 0, end=m_max_entries;
if(m_index_avail_karts.size()<m_max_entries)
{
start = (unsigned int)(m_max_entries-m_index_avail_karts.size()+1)/2;
end = start+m_index_avail_karts.size()-1;
}
for(unsigned int i=0; i<m_max_entries; i++)
{
if(i<start || i>end)
{
widget_manager->hideWgtRect (WTOK_NAME0 +i);
widget_manager->hideWgtRect (WTOK_RACER0+i);
widget_manager->hideWgtText (WTOK_NAME0 +i);
widget_manager->hideWgtTexture(WTOK_RACER0+i);
continue;
}
// Otherwise enable the widgets again (just in case that they
// had been disabled before)
widget_manager->showWgtRect (WTOK_NAME0 +i);
widget_manager->showWgtText (WTOK_NAME0 +i);
int indx = (i+m_offset)%m_index_avail_karts.size();
indx = m_index_avail_karts[indx];
if(indx>=0) // It's a kart, not a group
{
const KartProperties* kp= kart_properties_manager->getKartById(indx);
if(unlock_manager->isLocked(kp->getIdent())) continue;
widget_manager->setWgtText(WTOK_NAME0 + i, kp->getName());
widget_manager->setWgtTexture(WTOK_RACER0 + i, kp->getIconFile() );
widget_manager->showWgtTexture(WTOK_RACER0 + i);
widget_manager->showWgtRect(WTOK_RACER0 + i);
}
else
{
const std::vector<std::string> groups=kart_properties_manager->getAllGroups();
widget_manager->setWgtText(WTOK_NAME0+i, groups[-indx-1]);
widget_manager->hideWgtTexture(WTOK_RACER0 + i);
widget_manager->hideWgtRect(WTOK_RACER0 + i);
}
} // for i
} // updateScrollPosition
//-----------------------------------------------------------------------------
void CharSel::switchGroup()
{
m_index_avail_karts.clear();
// This loop is too long (since getNumberOfKarts returns all karts in all groups),
// but the loop is left if no more kart is found.
for(unsigned int i=0; i<kart_properties_manager->getNumberOfKarts(); i++)
{
int globalIndex = kart_properties_manager->getKartByGroup(user_config->m_kart_group, i);
if(globalIndex==-1) break;
if(kartAvailable(globalIndex))
{
m_index_avail_karts.push_back(globalIndex);
}
}
// Now add the groups, indicated by a negative number as kart index
// ----------------------------------------------------------------
const std::vector<std::string> groups=kart_properties_manager->getAllGroups();
for(int i =0; i<(int)groups.size(); i++)
{
// Only add groups other than the current one
if(groups[i]!=user_config->m_kart_group) m_index_avail_karts.push_back(-i-1);
}
if(m_index_avail_karts.size()>=m_max_entries)
{
m_offset = 0;
widget_manager->showWgtRect(WTOK_DOWN);
widget_manager->showWgtText(WTOK_DOWN);
widget_manager->showWgtRect(WTOK_UP);
widget_manager->showWgtText(WTOK_UP);
}
else
{
// Less entries than maximum -> set m_offset to a negative number, so
// that the actual existing entries are displayed
m_offset = - (int)(m_max_entries-m_index_avail_karts.size())/2-1;
widget_manager->hideWgtRect(WTOK_DOWN);
widget_manager->hideWgtText(WTOK_DOWN);
widget_manager->hideWgtRect(WTOK_UP);
widget_manager->hideWgtText(WTOK_UP);
}
} // switchGroup
//-----------------------------------------------------------------------------
void CharSel::switchCharacter(int n)
{
int indx=m_index_avail_karts[n];
// if a group is hovered about, don't do anything
if(indx<0) return;
const KartProperties* kp= kart_properties_manager->getKartById(indx);
if (m_current_kart != n && kp != NULL)
{
m_current_kart = n;
ssgDeRefDelete(m_kart);
m_kart = new ssgTransform;
m_kart->ref();
ssgEntity* kartentity = kp->getModel();
m_kart->addKid(kartentity);
}
} // switchCharacter
//-----------------------------------------------------------------------------
void CharSel::update(float dt)
{
m_clock += dt * 40.0f;
if( widget_manager->selectionChanged() )
{
int token = widget_manager->getSelectedWgt() - WTOK_RACER0;
if(token<0 || token>(int)m_index_avail_karts.size())
token = widget_manager->getSelectedWgt() - WTOK_NAME0;
switchCharacter((token+m_offset)%(int)m_index_avail_karts.size());
}
if (m_kart != NULL)
{
ssgContext* oldContext = ssgGetCurrentContext();
m_context -> makeCurrent();
glClear(GL_DEPTH_BUFFER_BIT);
// Puts the character in the center. Scaling is done by
// applying a big camera FOV.
int w = user_config->m_width;
int h = user_config->m_height;
glViewport ( 0, h*1/4, (int)(0.7f*w), (int)(0.7f*h));
m_context -> setFOV ( 65.0f, 65.0f * h/w ) ;
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();
}
widget_manager->update(dt);
} // update
//----------------------------------------------------------------------------
void CharSel::select()
{
int wgt = widget_manager->getSelectedWgt();
if(wgt==WTOK_UP)
{
m_offset--;
if(m_offset < 0) m_offset = (int)m_index_avail_karts.size() - 1;
updateScrollPosition();
return;
}
if(wgt==WTOK_DOWN)
{
m_offset++;
if( m_offset >= (int)m_index_avail_karts.size() ) m_offset=0;
updateScrollPosition();
return;
}
int token = widget_manager->getSelectedWgt() - WTOK_RACER0;
if(token<0 || token>(int)m_index_avail_karts.size())
{
token = widget_manager->getSelectedWgt() - WTOK_NAME0;
}
token = (token+m_offset) % (int)m_index_avail_karts.size();
int kart_id = m_index_avail_karts[token];
if(kart_id < 0) // group selected
{
user_config->m_kart_group = kart_properties_manager->getAllGroups()[-kart_id-1];
switchGroup();
// forces redraw of the model, otherwise (if m_current_kart=0) the new
// model would not be displayed.
m_current_kart = -1;
switchCharacter(0);
updateScrollPosition();
return;
}
const KartProperties* KP = kart_properties_manager->getKartById(kart_id);
if (KP != NULL)
{
race_manager->setPlayerKart(m_player_index, KP->getIdent());
user_config->m_player[m_player_index].setLastKartId(kart_id);
// Add selected kart (token) to selected karts vector so it cannot be
// selected again
kart_properties_manager->m_selected_karts.push_back(kart_id);
}
if (race_manager->getNumPlayers() > 1)
{
if (menu_manager->isCurrentMenu(MENUID_CHARSEL_P1))
{
menu_manager->pushMenu(MENUID_CHARSEL_P2);
return;
}
}
if (race_manager->getNumPlayers() > 2)
{
if (menu_manager->isCurrentMenu(MENUID_CHARSEL_P2))
{
menu_manager->pushMenu(MENUID_CHARSEL_P3);
return;
}
}
if (race_manager->getNumPlayers() > 3)
{
if (menu_manager->isCurrentMenu(MENUID_CHARSEL_P3))
{
menu_manager->pushMenu(MENUID_CHARSEL_P4);
return;
}
}
if (race_manager->getRaceMode() == RaceManager::RM_GRAND_PRIX)
menu_manager->pushMenu(MENUID_GRANDPRIXSELECT);
else
menu_manager->pushMenu(MENUID_TRACKSEL);
} // select
//----------------------------------------------------------------------------
// Function checks the vector of previously selected karts and returns true if
// kart i is in the vector and false if it is not.
bool CharSel::kartAvailable(int kart)
{
if (!kart_properties_manager->m_selected_karts.empty())
{
std::vector<int>::iterator it;
for (it = kart_properties_manager->m_selected_karts.begin();
it < kart_properties_manager->m_selected_karts.end(); it++)
{
if ( kart == *it)
return false;
}
}
return true;
} // kartAvailable

View File

@@ -1,53 +1,54 @@
// $Id$
//
// 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 3
// 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_CHARSEL_H
#define HEADER_CHARSEL_H
#include <vector>
#include "base_gui.hpp"
class ssgTransform;
class ssgContext;
class CharSel: public BaseGUI
{
private:
ssgContext *m_context;
ssgTransform *m_kart;
int m_current_kart;
float m_clock;
int m_player_index;
int m_offset; // index of first racer displayed
unsigned int m_num_entries; // number of entries to display
std::vector<int> m_indexAvailKart;
bool kartAvailable(int kart);
void updateScrollPosition();
int computeIndent(int n) {return 40+abs((m_num_entries-1)/2 - n)*3;}
public:
CharSel(int which_player);
~CharSel();
void switchCharacter(int n);
void update(float dt);
void select();
};
#endif
// $Id$
//
// 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 3
// 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_CHARSEL_H
#define HEADER_CHARSEL_H
#include <vector>
#include "base_gui.hpp"
class ssgTransform;
class ssgContext;
class CharSel: public BaseGUI
{
private:
ssgContext *m_context;
ssgTransform *m_kart;
int m_current_kart;
float m_clock;
int m_player_index;
int m_offset; // index of first racer displayed
unsigned int m_num_entries; // number of entries to display
std::vector<int> m_index_avail_karts;
static const int m_max_entries=7;
bool kartAvailable(int kart);
void updateScrollPosition();
int computeIndent(int n) {return 40+abs((int)(m_max_entries-1)/2 - n)*3;}
void switchGroup();
public:
CharSel(int which_player);
~CharSel();
void switchCharacter(int n);
void update(float dt);
void select();
};
#endif

View File

@@ -25,9 +25,9 @@
#include "menu_manager.hpp"
#include "translation.hpp"
#include "sdldrv.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
enum WidgetTokens
{

View File

@@ -28,9 +28,9 @@
#include "material_manager.hpp"
#include "unlock_manager.hpp"
#include "translation.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
enum WidgetTokens
{
@@ -53,7 +53,7 @@ TrackSel::TrackSel()
widget_manager->addWgt( WidgetManager::WGT_NONE, 100, 1);
widget_manager->breakLine();
for (unsigned int i = 0; i != track_manager->getTrackCount(); ++i)
for (unsigned int i = 0; i != track_manager->getNumberOfTracks(); ++i)
{
// snowtuxpeak must be unlocked
const Track *track = track_manager->getTrack(i);
@@ -71,7 +71,7 @@ TrackSel::TrackSel()
widget_manager->setWgtText(WTOK_TRACK0+i, _("Fulfil challenge to unlock"));
}
if( i%2 != 0 ) widget_manager->breakLine();
else if (i + 1 == track_manager->getTrackCount() )
else if (i + 1 == track_manager->getNumberOfTracks() )
{
widget_manager->addEmptyWgt( WidgetManager::WGT_NONE, 40, 6 );
widget_manager->breakLine();
@@ -102,7 +102,7 @@ void TrackSel::update(float dt)
const int SELECTED_TRACK = widget_manager->getSelectedWgt() - WTOK_TRACK0;
if( widget_manager->selectionChanged() &&
SELECTED_TRACK >= 0 &&
SELECTED_TRACK < (int)track_manager->getTrackCount() )
SELECTED_TRACK < (int)track_manager->getNumberOfTracks() )
{
const Track* TRACK = track_manager->getTrack( SELECTED_TRACK );
bool isAvailable = !unlock_manager->isLocked(TRACK->getIdent());
@@ -187,7 +187,7 @@ void TrackSel::select()
{
const int CLICKED_TOKEN = widget_manager->getSelectedWgt();
unsigned int track_number = CLICKED_TOKEN - WTOK_TRACK0;
if(track_number<0 || track_number >= track_manager->getTrackCount())
if(track_number<0 || track_number >= track_manager->getNumberOfTracks())
{
return; // not clicked on a track, ignore
}

View File

@@ -148,6 +148,7 @@ void Kart::createPhysics(ssgEntity *obj)
m_vehicle_raycaster =
new btDefaultVehicleRaycaster(world->getPhysics()->getPhysicsWorld());
m_tuning = new btRaycastVehicle::btVehicleTuning();
m_tuning->m_maxSuspensionTravelCm = m_kart_properties->getSuspensionTravelCM();
m_vehicle = new btRaycastVehicle(*m_tuning, m_body, m_vehicle_raycaster);
// never deactivate the vehicle

View File

@@ -1,252 +1,253 @@
// $Id$
//
// 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 3
// 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 <iostream>
#include <stdexcept>
#include <plib/ssg.h>
#include "material_manager.hpp"
#include "lisp/parser.hpp"
#include "lisp/lisp.hpp"
#include "loader.hpp"
#include "file_manager.hpp"
#include "string_utils.hpp"
#include "kart_properties.hpp"
#include "stk_config.hpp"
#include "translation.hpp"
#include "ssg_help.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
// This constructor would be a bit more useful, nicer, if we could call
// init_defaults() and load from here. Unfortunately, this object is used
// as a base class for STKConfig, which has to overwrite
// init_defaults() and getAllData(). But during the call of this constructor,
// the STKConfig object does not (yet) exist, so the overwriting
// functions do NOT get called, only the virtual functions here would be
// called. Therefore, a two step initialisation is necessary: the constructor
// doing not much, but then in load the overwriting functions can be used.
KartProperties::KartProperties() : m_icon_material(0), m_model(0)
{} // KartProperties
//-----------------------------------------------------------------------------
void KartProperties::load(const std::string filename, const std::string node,
bool dont_load_models, bool dont_load_materials)
{
init_defaults();
const lisp::Lisp* root = 0;
m_ident = StringUtils::basename(StringUtils::without_extension(filename));
try
{
lisp::Parser parser;
root = parser.parse(filename);
const lisp::Lisp* const LISP = root->getLisp(node);
if(!LISP)
{
char msg[MAX_ERROR_MESSAGE_LENGTH];
snprintf(msg, sizeof(msg), "No '%s' node found.", node.c_str());
throw std::runtime_error(msg);
}
getAllData(LISP);
}
catch(std::exception& err)
{
fprintf(stderr, "Error while parsing KartProperties '%s':\n",
filename.c_str());
fprintf(stderr, err.what());
fprintf(stderr, "\n");
}
delete root;
if(!dont_load_materials)
{
// Load material
// $Id$
//
// 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 3
// 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 <iostream>
#include <stdexcept>
#include <plib/ssg.h>
#include "material_manager.hpp"
#include "lisp/parser.hpp"
#include "lisp/lisp.hpp"
#include "loader.hpp"
#include "file_manager.hpp"
#include "string_utils.hpp"
#include "kart_properties.hpp"
#include "stk_config.hpp"
#include "translation.hpp"
#include "ssg_help.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
// This constructor would be a bit more useful, nicer, if we could call
// init_defaults() and load from here. Unfortunately, this object is used
// as a base class for STKConfig, which has to overwrite
// init_defaults() and getAllData(). But during the call of this constructor,
// the STKConfig object does not (yet) exist, so the overwriting
// functions do NOT get called, only the virtual functions here would be
// called. Therefore, a two step initialisation is necessary: the constructor
// doing not much, but then in load the overwriting functions can be used.
KartProperties::KartProperties() : m_icon_material(0), m_model(0)
{} // KartProperties
//-----------------------------------------------------------------------------
void KartProperties::load(const std::string filename, const std::string node,
bool dont_load_models, bool dont_load_materials)
{
init_defaults();
const lisp::Lisp* root = 0;
m_ident = StringUtils::basename(StringUtils::without_extension(filename));
try
{
lisp::Parser parser;
root = parser.parse(filename);
const lisp::Lisp* const LISP = root->getLisp(node);
if(!LISP)
{
char msg[MAX_ERROR_MESSAGE_LENGTH];
snprintf(msg, sizeof(msg), "No '%s' node found.", node.c_str());
throw std::runtime_error(msg);
}
getAllData(LISP);
}
catch(std::exception& err)
{
fprintf(stderr, "Error while parsing KartProperties '%s':\n",
filename.c_str());
fprintf(stderr, err.what());
fprintf(stderr, "\n");
}
delete root;
if(!dont_load_materials)
{
// Load material
std::string materials_file = file_manager->getKartFile("materials.dat",getIdent());
file_manager->pushModelSearchPath(file_manager->getKartFile("", getIdent()));
file_manager->pushTextureSearchPath(file_manager->getKartFile("", getIdent()));
// addShared makes sure that these textures/material infos stay in memory
material_manager->addSharedMaterial(materials_file);
m_icon_material = material_manager->getMaterial(m_icon_file);
}
// Load model, except when called as part of --list-karts
if(m_model_file.length()>0 && !dont_load_models)
{
m_model = loader->load(m_model_file, CB_KART, false);
if(!m_model)
{
fprintf(stderr, "Can't find kart model '%s'.\n",m_model_file.c_str());
file_manager->popTextureSearchPath();
file_manager->popModelSearchPath();
return;
}
ssgStripify(m_model);
float x_min, x_max, y_min, y_max, z_min, z_max;
MinMax(m_model, &x_min, &x_max, &y_min, &y_max, &z_min, &z_max);
if(getName()=="Hexley" || getName()=="Wilber")
{
// These kart models are too small, so we get problems with stability.
// Till we find either better (bigger) models or improve their physics
// parameters to become playable, we just adjust the size of their
// physical models to be the same as the tuxkart model
x_min=-0.473799f;
x_max= 0.486361f;
y_min=-0.772244f;
y_max= 0.739075f;
z_min= 0.002806f;
z_max= 0.701095f;
}
m_kart_width = x_max - x_min;
m_kart_length = y_max - y_min;
m_kart_height = z_max - z_min;
if(m_kart_length<1.2) m_kart_length=1.5f;
m_model->ref();
} // if
if(!dont_load_materials)
{
file_manager->popTextureSearchPath();
file_manager->popModelSearchPath();
}
} // load
//-----------------------------------------------------------------------------
KartProperties::~KartProperties()
{
ssgDeRefDelete(m_model);
} // ~KartProperties
//-----------------------------------------------------------------------------
void KartProperties::getAllData(const lisp::Lisp* lisp)
{
lisp->get("name", m_name);
lisp->get("model-file", m_model_file);
lisp->get("icon-file", m_icon_file);
lisp->get("shadow-file", m_shadow_file);
lisp->get("rgb", m_color);
lisp->get("wheel-base", m_wheel_base);
lisp->get("heightCOG", m_height_cog);
lisp->get("engine-power", m_engine_power);
lisp->get("time-full-steer", m_time_full_steer);
lisp->get("brake-factor", m_brake_factor);
lisp->get("mass", m_mass);
lisp->get("max-steer-angle", m_max_steer_angle);
lisp->get("wheelie-max-speed-ratio", m_wheelie_max_speed_ratio );
lisp->get("wheelie-max-pitch", m_wheelie_max_pitch );
lisp->get("wheelie-pitch-rate", m_wheelie_pitch_rate );
lisp->get("wheelie-restore-rate", m_wheelie_restore_rate );
lisp->get("wheelie-speed-boost", m_wheelie_speed_boost );
lisp->get("wheelie-lean-recovery", m_wheelie_lean_recovery );
lisp->get("wheelie-step", m_wheelie_step );
lisp->get("wheelie-balance-recovery",m_wheelie_balance_recovery);
lisp->get("wheelie-power-boost", m_wheelie_power_boost );
//bullet physics data
lisp->get("suspension-stiffness", m_suspension_stiffness );
lisp->get("wheel-damping-relaxation", m_wheel_damping_relaxation );
lisp->get("wheel-damping-compression", m_wheel_damping_compression);
lisp->get("friction-slip", m_friction_slip );
lisp->get("roll-influence", m_roll_influence );
lisp->get("wheel-radius", m_wheel_radius );
lisp->get("wheel-width", m_wheel_width );
lisp->get("chassis-linear-damping", m_chassis_linear_damping );
lisp->get("chassis-angular-damping", m_chassis_angular_damping );
lisp->get("max-speed-reverse-ratio", m_max_speed_reverse_ratio );
lisp->get("maximum-speed", m_maximum_speed );
lisp->get("gravity-center-shift", m_gravity_center_shift );
lisp->get("suspension-rest", m_suspension_rest );
lisp->get("jump-velocity", m_jump_velocity );
lisp->get("upright-tolerance", m_upright_tolerance );
lisp->get("upright-max-force", m_upright_max_force );
// getVector appends to existing vectors, so a new one must be used to load
std::vector<float> temp;
lisp->getVector("gear-switch-ratio", temp);
if(temp.size()>0) m_gear_switch_ratio = temp;
temp.clear();
lisp->getVector("gear-power-increase", temp);
if(temp.size()>0) m_gear_power_increase = temp;
// Camera
lisp->get("camera-max-accel", m_camera_max_accel);
lisp->get("camera-max-brake", m_camera_max_brake);
lisp->get("camera-distance", m_camera_distance );
} // getAllData
//-----------------------------------------------------------------------------
void KartProperties::init_defaults()
{
m_name = "Tux";
m_ident = "tux";
m_model_file = "tuxkart.ac";
m_icon_file = "tuxicon.png";
m_shadow_file = "tuxkartshadow.png";
m_color.setValue(1.0f, 0.0f, 0.0f);
m_kart_width = 1.0f;
m_kart_length = 1.5f;
m_wheel_base = stk_config->m_wheel_base;
m_height_cog = stk_config->m_height_cog;
m_engine_power = stk_config->m_engine_power;
m_time_full_steer = stk_config->m_time_full_steer;
m_brake_factor = stk_config->m_brake_factor;
m_mass = stk_config->m_mass;
m_max_steer_angle = stk_config->m_max_steer_angle;
m_wheelie_max_speed_ratio = stk_config->m_wheelie_max_speed_ratio;
m_wheelie_max_pitch = stk_config->m_wheelie_max_pitch;
m_wheelie_pitch_rate = stk_config->m_wheelie_pitch_rate;
m_wheelie_restore_rate = stk_config->m_wheelie_restore_rate;
m_wheelie_speed_boost = stk_config->m_wheelie_speed_boost;
m_wheelie_lean_recovery = stk_config->m_wheelie_lean_recovery;
m_wheelie_balance_recovery = stk_config->m_wheelie_balance_recovery;
m_wheelie_step = stk_config->m_wheelie_step;
m_wheelie_power_boost = stk_config->m_wheelie_power_boost;
//bullet physics data
m_suspension_stiffness = stk_config->m_suspension_stiffness;
m_wheel_damping_relaxation = stk_config->m_wheel_damping_relaxation;
m_wheel_damping_compression = stk_config->m_wheel_damping_compression;
m_friction_slip = stk_config->m_friction_slip;
m_roll_influence = stk_config->m_roll_influence;
m_wheel_radius = stk_config->m_wheel_radius;
m_wheel_width = stk_config->m_wheel_width;
m_chassis_linear_damping = stk_config->m_chassis_linear_damping;
m_chassis_angular_damping = stk_config->m_chassis_angular_damping;
m_maximum_speed = stk_config->m_maximum_speed;
m_max_speed_reverse_ratio = stk_config->m_max_speed_reverse_ratio;
m_gravity_center_shift = stk_config->m_gravity_center_shift;
m_suspension_rest = stk_config->m_suspension_rest;
m_jump_velocity = stk_config->m_jump_velocity;
m_gear_switch_ratio = stk_config->m_gear_switch_ratio;
m_gear_power_increase = stk_config->m_gear_power_increase;
m_upright_tolerance = stk_config->getUprightTolerance();
m_upright_max_force = stk_config->getUprightMaxForce();
m_camera_max_accel = stk_config->getCameraMaxAccel();
m_camera_max_brake = stk_config->getCameraMaxBrake();
m_camera_distance = stk_config->getCameraDistance();
} // init_defaults
/* EOF */
file_manager->pushModelSearchPath(file_manager->getKartFile("", getIdent()));
file_manager->pushTextureSearchPath(file_manager->getKartFile("", getIdent()));
// addShared makes sure that these textures/material infos stay in memory
material_manager->addSharedMaterial(materials_file);
m_icon_material = material_manager->getMaterial(m_icon_file);
}
// Load model, except when called as part of --list-karts
if(m_model_file.length()>0 && !dont_load_models)
{
m_model = loader->load(m_model_file, CB_KART, false);
if(!m_model)
{
fprintf(stderr, "Can't find kart model '%s'.\n",m_model_file.c_str());
file_manager->popTextureSearchPath();
file_manager->popModelSearchPath();
return;
}
ssgStripify(m_model);
float x_min, x_max, y_min, y_max, z_min, z_max;
MinMax(m_model, &x_min, &x_max, &y_min, &y_max, &z_min, &z_max);
if(getName()=="Hexley" || getName()=="Wilber")
{
// These kart models are too small, so we get problems with stability.
// Till we find either better (bigger) models or improve their physics
// parameters to become playable, we just adjust the size of their
// physical models to be the same as the tuxkart model
x_min=-0.473799f;
x_max= 0.486361f;
y_min=-0.772244f;
y_max= 0.739075f;
z_min= 0.002806f;
z_max= 0.701095f;
}
m_kart_width = x_max - x_min;
m_kart_length = y_max - y_min;
m_kart_height = z_max - z_min;
if(m_kart_length<1.2) m_kart_length=1.5f;
m_model->ref();
} // if
if(!dont_load_materials)
{
file_manager->popTextureSearchPath();
file_manager->popModelSearchPath();
}
} // load
//-----------------------------------------------------------------------------
KartProperties::~KartProperties()
{
ssgDeRefDelete(m_model);
} // ~KartProperties
//-----------------------------------------------------------------------------
void KartProperties::getAllData(const lisp::Lisp* lisp)
{
lisp->get("name", m_name);
lisp->get("model-file", m_model_file);
lisp->get("icon-file", m_icon_file);
lisp->get("shadow-file", m_shadow_file);
lisp->get("rgb", m_color);
lisp->get("wheel-base", m_wheel_base);
lisp->get("heightCOG", m_height_cog);
lisp->get("engine-power", m_engine_power);
lisp->get("time-full-steer", m_time_full_steer);
lisp->get("brake-factor", m_brake_factor);
lisp->get("mass", m_mass);
lisp->get("max-steer-angle", m_max_steer_angle);
lisp->get("wheelie-max-speed-ratio", m_wheelie_max_speed_ratio );
lisp->get("wheelie-max-pitch", m_wheelie_max_pitch );
lisp->get("wheelie-pitch-rate", m_wheelie_pitch_rate );
lisp->get("wheelie-restore-rate", m_wheelie_restore_rate );
lisp->get("wheelie-speed-boost", m_wheelie_speed_boost );
lisp->get("wheelie-power-boost", m_wheelie_power_boost );
//bullet physics data
lisp->get("suspension-stiffness", m_suspension_stiffness );
lisp->get("wheel-damping-relaxation", m_wheel_damping_relaxation );
lisp->get("wheel-damping-compression", m_wheel_damping_compression);
lisp->get("friction-slip", m_friction_slip );
lisp->get("roll-influence", m_roll_influence );
lisp->get("wheel-radius", m_wheel_radius );
lisp->get("wheel-width", m_wheel_width );
lisp->get("chassis-linear-damping", m_chassis_linear_damping );
lisp->get("chassis-angular-damping", m_chassis_angular_damping );
lisp->get("max-speed-reverse-ratio", m_max_speed_reverse_ratio );
lisp->get("maximum-speed", m_maximum_speed );
lisp->get("gravity-center-shift", m_gravity_center_shift );
lisp->get("suspension-rest", m_suspension_rest );
lisp->get("suspension-travel-cm", m_suspension_travel_cm );
lisp->get("jump-velocity", m_jump_velocity );
lisp->get("upright-tolerance", m_upright_tolerance );
lisp->get("upright-max-force", m_upright_max_force );
lisp->getVector("groups", m_groups );
if(m_groups.size()==0)
m_groups.push_back("standard");
// getVector appends to existing vectors, so a new one must be used to load
std::vector<float> temp;
lisp->getVector("gear-switch-ratio", temp);
if(temp.size()>0) m_gear_switch_ratio = temp;
temp.clear();
lisp->getVector("gear-power-increase", temp);
if(temp.size()>0) m_gear_power_increase = temp;
// Camera
lisp->get("camera-max-accel", m_camera_max_accel);
lisp->get("camera-max-brake", m_camera_max_brake);
lisp->get("camera-distance", m_camera_distance );
} // getAllData
//-----------------------------------------------------------------------------
void KartProperties::init_defaults()
{
m_name = "Tux";
m_ident = "tux";
m_model_file = "tuxkart.ac";
m_icon_file = "tuxicon.png";
m_shadow_file = "tuxkartshadow.png";
m_groups.clear();
m_color.setValue(1.0f, 0.0f, 0.0f);
m_kart_width = 1.0f;
m_kart_length = 1.5f;
m_wheel_base = stk_config->m_wheel_base;
m_height_cog = stk_config->m_height_cog;
m_engine_power = stk_config->m_engine_power;
m_time_full_steer = stk_config->m_time_full_steer;
m_brake_factor = stk_config->m_brake_factor;
m_mass = stk_config->m_mass;
m_max_steer_angle = stk_config->m_max_steer_angle;
m_wheelie_max_speed_ratio = stk_config->m_wheelie_max_speed_ratio;
m_wheelie_max_pitch = stk_config->m_wheelie_max_pitch;
m_wheelie_pitch_rate = stk_config->m_wheelie_pitch_rate;
m_wheelie_restore_rate = stk_config->m_wheelie_restore_rate;
m_wheelie_speed_boost = stk_config->m_wheelie_speed_boost;
m_wheelie_power_boost = stk_config->m_wheelie_power_boost;
//bullet physics data
m_suspension_stiffness = stk_config->m_suspension_stiffness;
m_wheel_damping_relaxation = stk_config->m_wheel_damping_relaxation;
m_wheel_damping_compression = stk_config->m_wheel_damping_compression;
m_friction_slip = stk_config->m_friction_slip;
m_roll_influence = stk_config->m_roll_influence;
m_wheel_radius = stk_config->m_wheel_radius;
m_wheel_width = stk_config->m_wheel_width;
m_chassis_linear_damping = stk_config->m_chassis_linear_damping;
m_chassis_angular_damping = stk_config->m_chassis_angular_damping;
m_maximum_speed = stk_config->m_maximum_speed;
m_max_speed_reverse_ratio = stk_config->m_max_speed_reverse_ratio;
m_gravity_center_shift = stk_config->m_gravity_center_shift;
m_suspension_rest = stk_config->m_suspension_rest;
m_suspension_travel_cm = stk_config->m_suspension_travel_cm;
m_jump_velocity = stk_config->m_jump_velocity;
m_gear_switch_ratio = stk_config->m_gear_switch_ratio;
m_gear_power_increase = stk_config->m_gear_power_increase;
m_upright_tolerance = stk_config->getUprightTolerance();
m_upright_max_force = stk_config->getUprightMaxForce();
m_camera_max_accel = stk_config->getCameraMaxAccel();
m_camera_max_brake = stk_config->getCameraMaxBrake();
m_camera_distance = stk_config->getCameraDistance();
} // init_defaults
/* EOF */

View File

@@ -1,174 +1,173 @@
// $Id$
//
// 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 3
// 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_KARTPROPERTIES_H
#define HEADER_KARTPROPERTIES_H
#include <string>
#include <vector>
#include "vec3.hpp"
#include "lisp/lisp.hpp"
#include "no_copy.hpp"
class Material;
class ssgEntity;
class KartProperties : public NoCopy
{
private:
Material* m_icon_material;
ssgEntity* m_model;
protected:
// Display and gui
// ---------------
std::string m_name; // The human readable Name of the karts driver
std::string m_ident; // The computer readable-name of the karts driver
std::string m_model_file; // Filename of 3d model that is used for kart
std::string m_icon_file; // Filename of icon that represents the kart in
// the statusbar and the character select screen
std::string m_shadow_file; // Filename of the image file that contains the
// shadow for this kart
Vec3 m_color; // Color the represents the kart in the status
// bar and on the track-view
// Physic properties
// -----------------
float m_kart_width; // width of kart
float m_kart_length; // length of kart
float m_kart_height; // height of kart
float m_mass; // weight of kart
float m_wheel_base; // distance between front and read wheels
float m_height_cog; // height of center of gravity
float m_engine_power; // maximum force from engine
float m_brake_factor; // braking factor * engine_power = braking force
float m_max_steer_angle; // maximum steering angle
float m_time_full_steer; // time for player karts to reach full steer angle
float m_wheelie_max_speed_ratio; // percentage of maximum speed for wheelies
float m_wheelie_max_pitch; // maximum pitch for wheelies
float m_wheelie_pitch_rate; // rate/sec with which kart goes up
float m_wheelie_restore_rate; // rate/sec with which kart does down
float m_wheelie_speed_boost; // speed boost while doing a wheelie
float m_wheelie_lean_recovery;
float m_wheelie_balance_recovery;
float m_wheelie_step;
float m_wheelie_power_boost; // increase in engine power
// bullet physics data
// -------------------
float m_suspension_stiffness;
float m_wheel_damping_relaxation;
float m_wheel_damping_compression;
float m_friction_slip;
float m_roll_influence;
float m_wheel_radius;
float m_wheel_width;
float m_chassis_linear_damping;
float m_chassis_angular_damping;
float m_maximum_speed;
float m_max_speed_reverse_ratio;
float m_gravity_center_shift;
float m_suspension_rest;
float m_jump_velocity; // z velocity set when jumping
float m_upright_tolerance;
float m_upright_max_force;
// Camera related setting
// ----------------------
float m_camera_max_accel; // maximum acceleration of camera
float m_camera_max_brake; // maximum braking of camera
float m_camera_distance; // distance of normal camera from kart
//
// The following two vectors define at what ratio of the maximum speed what
// gear is selected, e.g. 0.25 means: if speed <=0.25*maxSpeed --> gear 1,
// 0.5 means: if speed <=0.5 *maxSpeed --> gear 2
// The next vector contains the increase in max power (to simulate different
// gears), e.g. 2.5 as first entry means: 2.5*maxPower in gear 1
std::vector<float> m_gear_switch_ratio;
std::vector<float> m_gear_power_increase;
public:
KartProperties ();
virtual ~KartProperties ();
virtual void init_defaults ();
virtual void getAllData (const lisp::Lisp* lisp);
virtual void load (const std::string filename,
const std::string node="tuxkart-kart",
bool dont_load_models=false,
bool dont_load_materials=false);
Material* getIconMaterial () const {return m_icon_material; }
ssgEntity* getModel () const {return m_model; }
const std::string& getName () const {return m_name; }
const std::string& getIdent () const {return m_ident; }
const std::string& getShadowFile () const {return m_shadow_file; }
const std::string& getIconFile () const {return m_icon_file; }
const Vec3 &getColor () const {return m_color; }
float getMass () const {return m_mass; }
float getKartLength () const {return m_kart_length; }
float getKartWidth () const {return m_kart_width; }
float getKartHeight () const {return m_kart_height; }
float getMaxPower () const {return m_engine_power; }
float getTimeFullSteer () const {return m_time_full_steer; }
float getBrakeFactor () const {return m_brake_factor; }
float getWheelBase () const {return m_wheel_base; }
float getHeightCOG () const {return m_height_cog; }
float getMaxSteerAngle () const {return m_max_steer_angle; }
float getMaxSpeedReverseRatio() const {return m_max_speed_reverse_ratio;}
float getWheelieMaxSpeedRatio() const {return m_wheelie_max_speed_ratio;}
float getWheelieMaxPitch () const {return m_wheelie_max_pitch; }
float getWheeliePitchRate () const {return m_wheelie_pitch_rate; }
float getWheelieRestoreRate () const {return m_wheelie_restore_rate; }
float getWheelieSpeedBoost () const {return m_wheelie_speed_boost; }
float getWheelieLeanRecovery () const {return m_wheelie_lean_recovery; }
float getWheelieBalanceRecovery()const{return m_wheelie_balance_recovery;}
float getWheelieStep () const {return m_wheelie_step; }
float getWheeliePowerBoost () const {return m_wheelie_power_boost; }
//bullet physics get functions
float getSuspensionStiffness () const {return m_suspension_stiffness; }
float getWheelDampingRelaxation () const {return m_wheel_damping_relaxation; }
float getWheelDampingCompression() const {return m_wheel_damping_compression;}
float getFrictionSlip () const {return m_friction_slip; }
float getRollInfluence () const {return m_roll_influence; }
float getWheelRadius () const {return m_wheel_radius; }
float getWheelWidth () const {return m_wheel_width; }
float getChassisLinearDamping () const {return m_chassis_linear_damping; }
float getChassisAngularDamping () const {return m_chassis_angular_damping; }
float getMaximumSpeed () const {return m_maximum_speed; }
float getGravityCenterShift () const {return m_gravity_center_shift; }
float getSuspensionRest () const {return m_suspension_rest; }
float getJumpVelocity () const {return m_jump_velocity; }
float getUprightTolerance () const {return m_upright_tolerance; }
float getUprightMaxForce () const {return m_upright_max_force; }
const std::vector<float>&
getGearSwitchRatio () const {return m_gear_switch_ratio; }
const std::vector<float>&
getGearPowerIncrease () const {return m_gear_power_increase; }
float getCameraMaxAccel () const {return m_camera_max_accel; }
float getCameraMaxBrake () const {return m_camera_max_brake; }
float getCameraDistance () const {return m_camera_distance; }
};
#endif
/* EOF */
// $Id$
//
// 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 3
// 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_KARTPROPERTIES_H
#define HEADER_KARTPROPERTIES_H
#include <string>
#include <vector>
#include "vec3.hpp"
#include "lisp/lisp.hpp"
#include "no_copy.hpp"
class Material;
class ssgEntity;
class KartProperties : public NoCopy
{
private:
Material *m_icon_material;
ssgEntity *m_model;
std::vector<std::string> m_groups; // list of all groups the kart belongs to
protected:
// Display and gui
// ---------------
std::string m_name; // The human readable Name of the karts driver
std::string m_ident; // The computer readable-name of the karts driver
std::string m_model_file; // Filename of 3d model that is used for kart
std::string m_icon_file; // Filename of icon that represents the kart in
// the statusbar and the character select screen
std::string m_shadow_file; // Filename of the image file that contains the
// shadow for this kart
Vec3 m_color; // Color the represents the kart in the status
// bar and on the track-view
// Physic properties
// -----------------
float m_kart_width; // width of kart
float m_kart_length; // length of kart
float m_kart_height; // height of kart
float m_mass; // weight of kart
float m_wheel_base; // distance between front and read wheels
float m_height_cog; // height of center of gravity
float m_engine_power; // maximum force from engine
float m_brake_factor; // braking factor * engine_power = braking force
float m_max_steer_angle; // maximum steering angle
float m_time_full_steer; // time for player karts to reach full steer angle
float m_wheelie_max_speed_ratio; // percentage of maximum speed for wheelies
float m_wheelie_max_pitch; // maximum pitch for wheelies
float m_wheelie_pitch_rate; // rate/sec with which kart goes up
float m_wheelie_restore_rate; // rate/sec with which kart does down
float m_wheelie_speed_boost; // speed boost while doing a wheelie
float m_wheelie_power_boost; // increase in engine power
// bullet physics data
// -------------------
float m_suspension_stiffness;
float m_wheel_damping_relaxation;
float m_wheel_damping_compression;
float m_friction_slip;
float m_roll_influence;
float m_wheel_radius;
float m_wheel_width;
float m_chassis_linear_damping;
float m_chassis_angular_damping;
float m_maximum_speed;
float m_max_speed_reverse_ratio;
float m_gravity_center_shift;
float m_suspension_rest;
float m_suspension_travel_cm;
float m_jump_velocity; // z velocity set when jumping
float m_upright_tolerance;
float m_upright_max_force;
// Camera related setting
// ----------------------
float m_camera_max_accel; // maximum acceleration of camera
float m_camera_max_brake; // maximum braking of camera
float m_camera_distance; // distance of normal camera from kart
//
// The following two vectors define at what ratio of the maximum speed what
// gear is selected, e.g. 0.25 means: if speed <=0.25*maxSpeed --> gear 1,
// 0.5 means: if speed <=0.5 *maxSpeed --> gear 2
// The next vector contains the increase in max power (to simulate different
// gears), e.g. 2.5 as first entry means: 2.5*maxPower in gear 1
std::vector<float> m_gear_switch_ratio;
std::vector<float> m_gear_power_increase;
public:
KartProperties ();
virtual ~KartProperties ();
virtual void init_defaults ();
virtual void getAllData (const lisp::Lisp* lisp);
virtual void load (const std::string filename,
const std::string node="tuxkart-kart",
bool dont_load_models=false,
bool dont_load_materials=false);
Material* getIconMaterial () const {return m_icon_material; }
ssgEntity* getModel () const {return m_model; }
const std::string& getName () const {return m_name; }
const std::string& getIdent () const {return m_ident; }
const std::string& getShadowFile() const {return m_shadow_file; }
const std::string& getIconFile () const {return m_icon_file; }
const Vec3 &getColor () const {return m_color; }
const std::vector<std::string>&
getGroups () const {return m_groups; }
float getMass () const {return m_mass; }
float getKartLength () const {return m_kart_length; }
float getKartWidth () const {return m_kart_width; }
float getKartHeight () const {return m_kart_height; }
float getMaxPower () const {return m_engine_power; }
float getTimeFullSteer () const {return m_time_full_steer; }
float getBrakeFactor () const {return m_brake_factor; }
float getWheelBase () const {return m_wheel_base; }
float getHeightCOG () const {return m_height_cog; }
float getMaxSteerAngle () const {return m_max_steer_angle; }
float getMaxSpeedReverseRatio () const {return m_max_speed_reverse_ratio; }
float getWheelieMaxSpeedRatio () const {return m_wheelie_max_speed_ratio; }
float getWheelieMaxPitch () const {return m_wheelie_max_pitch; }
float getWheeliePitchRate () const {return m_wheelie_pitch_rate; }
float getWheelieRestoreRate () const {return m_wheelie_restore_rate; }
float getWheelieSpeedBoost () const {return m_wheelie_speed_boost; }
float getWheeliePowerBoost () const {return m_wheelie_power_boost; }
//bullet physics get functions
float getSuspensionStiffness () const {return m_suspension_stiffness; }
float getWheelDampingRelaxation () const {return m_wheel_damping_relaxation; }
float getWheelDampingCompression() const {return m_wheel_damping_compression;}
float getFrictionSlip () const {return m_friction_slip; }
float getRollInfluence () const {return m_roll_influence; }
float getWheelRadius () const {return m_wheel_radius; }
float getWheelWidth () const {return m_wheel_width; }
float getChassisLinearDamping () const {return m_chassis_linear_damping; }
float getChassisAngularDamping () const {return m_chassis_angular_damping; }
float getMaximumSpeed () const {return m_maximum_speed; }
float getGravityCenterShift () const {return m_gravity_center_shift; }
float getSuspensionRest () const {return m_suspension_rest; }
float getSuspensionTravelCM () const {return m_suspension_travel_cm; }
float getJumpVelocity () const {return m_jump_velocity; }
float getUprightTolerance () const {return m_upright_tolerance; }
float getUprightMaxForce () const {return m_upright_max_force; }
const std::vector<float>&
getGearSwitchRatio () const {return m_gear_switch_ratio; }
const std::vector<float>&
getGearPowerIncrease () const {return m_gear_power_increase; }
float getCameraMaxAccel () const {return m_camera_max_accel; }
float getCameraMaxBrake () const {return m_camera_max_brake; }
float getCameraDistance () const {return m_camera_distance; }
};
#endif
/* EOF */

View File

@@ -1,184 +1,215 @@
// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2006 Ingo Ruhnke <grumbel@gmx.de>
//
// 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 3
// 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 <stdexcept>
#include <algorithm>
#include <ctime>
#include "file_manager.hpp"
#include "string_utils.hpp"
#include "kart_properties_manager.hpp"
#include "kart_properties.hpp"
#include "translation.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
KartPropertiesManager *kart_properties_manager=0;
KartPropertiesManager::KartPropertiesManager()
{}
//-----------------------------------------------------------------------------
KartPropertiesManager::~KartPropertiesManager()
{
for(KartPropertiesVector::iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
delete *i;
} // ~KartPropertiesManager
//-----------------------------------------------------------------------------
void KartPropertiesManager::removeTextures()
{
for(KartPropertiesVector::iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
{
delete *i;
}
m_karts_properties.clear();
callback_manager->clear(CB_KART);
} // removeTextures
//-----------------------------------------------------------------------------
void KartPropertiesManager::loadKartData(bool dont_load_models)
{
m_max_steer_angle = -1.0f;
std::set<std::string> result;
file_manager->listFiles(result, file_manager->getKartDir(),
/*is_full_path*/ true);
// Find out which characters are available and load them
for(std::set<std::string>::iterator i = result.begin();
i != result.end(); ++i)
{
std::string kart_file;
try
{
kart_file = file_manager->getKartFile((*i)+".kart");
}
catch (std::exception& e)
{
(void)e; // remove warning about unused variable
continue;
}
FILE *f=fopen(kart_file.c_str(),"r");
if(!f) continue;
fclose(f);
KartProperties* kp = new KartProperties();
kp->load(kart_file, "tuxkart-kart", dont_load_models);
m_karts_properties.push_back(kp);
if(kp->getMaxSteerAngle() > m_max_steer_angle)
{
m_max_steer_angle = kp->getMaxSteerAngle();
}
} // for i
} // loadKartData
//-----------------------------------------------------------------------------
const int KartPropertiesManager::getKartId(const std::string IDENT)
{
int j = 0;
for(KartPropertiesVector::const_iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
{
if ((*i)->getIdent() == IDENT)
return j;
++j;
}
char msg[MAX_ERROR_MESSAGE_LENGTH];
snprintf(msg, sizeof(msg), "KartPropertiesManager: Couldn't find kart: '%s'",
IDENT.c_str());
throw std::runtime_error(msg);
} // getKartId
//-----------------------------------------------------------------------------
const KartProperties* KartPropertiesManager::getKart(const std::string IDENT)
{
for(KartPropertiesVector::const_iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
{
if ((*i)->getIdent() == IDENT)
return *i;
}
return NULL;
} // getKart
//-----------------------------------------------------------------------------
const KartProperties* KartPropertiesManager::getKartById(int i)
{
if (i < 0 || i >= int(m_karts_properties.size()))
return NULL;
return m_karts_properties[i];
}
/*FIXME: the next function is unused, if it is not useful, it should be
deleted.*/
//-----------------------------------------------------------------------------
std::vector<std::string> KartPropertiesManager::getRandomKarts(int len)
{
std::vector<std::string> all_karts;
for(KartPropertiesVector::const_iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
{
all_karts.push_back((*i)->getIdent());
}
std::random_shuffle(all_karts.begin(), all_karts.end());
all_karts.resize(len);
return all_karts;
} // getRandomKart
//-----------------------------------------------------------------------------
void KartPropertiesManager::fillWithRandomKarts(std::vector<std::string>& vec)
{
std::vector<std::string> all_karts;
for(KartPropertiesVector::const_iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
all_karts.push_back((*i)->getIdent());
std::srand((unsigned int)std::time(0));
std::random_shuffle(all_karts.begin(), all_karts.end());
int new_kart = 0;
for(int i = 0; i < int(vec.size()); ++i)
{
while(vec[i].empty())
{
if (std::find(vec.begin(), vec.end(), all_karts[new_kart]) == vec.end())
{ // Found a new kart, so use it
vec[i] = all_karts[new_kart];
}
else if (!(all_karts.size() >= vec.size()))
{ // We need to fill more karts than we have available, so don't care about dups
vec[i] = all_karts[new_kart];
}
new_kart += 1;
} // while
} // for i
}
/* EOF */
// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2006 Ingo Ruhnke <grumbel@gmx.de>
//
// 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 3
// 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 <stdexcept>
#include <algorithm>
#include <ctime>
#include "file_manager.hpp"
#include "string_utils.hpp"
#include "kart_properties_manager.hpp"
#include "kart_properties.hpp"
#include "translation.hpp"
#if defined(WIN32) && !defined(__CYGWIN__)
# define snprintf _snprintf
#endif
KartPropertiesManager *kart_properties_manager=0;
KartPropertiesManager::KartPropertiesManager()
{
m_all_groups.clear();
m_all_groups.push_back("standard");
}
//-----------------------------------------------------------------------------
KartPropertiesManager::~KartPropertiesManager()
{
for(KartPropertiesVector::iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
delete *i;
} // ~KartPropertiesManager
//-----------------------------------------------------------------------------
void KartPropertiesManager::removeTextures()
{
for(KartPropertiesVector::iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
{
delete *i;
}
m_karts_properties.clear();
callback_manager->clear(CB_KART);
} // removeTextures
//-----------------------------------------------------------------------------
void KartPropertiesManager::loadKartData(bool dont_load_models)
{
m_max_steer_angle = -1.0f;
std::set<std::string> result;
file_manager->listFiles(result, file_manager->getKartDir(),
/*is_full_path*/ true);
// Find out which characters are available and load them
for(std::set<std::string>::iterator i = result.begin();
i != result.end(); ++i)
{
std::string kart_file;
try
{
kart_file = file_manager->getKartFile((*i)+".kart");
}
catch (std::exception& e)
{
(void)e; // remove warning about unused variable
continue;
}
FILE *f=fopen(kart_file.c_str(),"r");
if(!f) continue;
fclose(f);
KartProperties* kp = new KartProperties();
kp->load(kart_file, "tuxkart-kart", dont_load_models);
m_karts_properties.push_back(kp);
if(kp->getMaxSteerAngle() > m_max_steer_angle)
{
m_max_steer_angle = kp->getMaxSteerAngle();
}
const std::vector<std::string>& groups=kp->getGroups();
for(unsigned int i=0; i<groups.size(); i++)
{
if(std::find(m_all_groups.begin(), m_all_groups.end(), groups[i])
== m_all_groups.end())
{
m_all_groups.push_back(groups[i]);
}
}
} // for i
} // loadKartData
//-----------------------------------------------------------------------------
const int KartPropertiesManager::getKartId(const std::string IDENT) const
{
int j = 0;
for(KartPropertiesVector::const_iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
{
if ((*i)->getIdent() == IDENT)
return j;
++j;
}
char msg[MAX_ERROR_MESSAGE_LENGTH];
snprintf(msg, sizeof(msg), "KartPropertiesManager: Couldn't find kart: '%s'",
IDENT.c_str());
throw std::runtime_error(msg);
} // getKartId
//-----------------------------------------------------------------------------
const KartProperties* KartPropertiesManager::getKart(const std::string IDENT) const
{
for(KartPropertiesVector::const_iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
{
if ((*i)->getIdent() == IDENT)
return *i;
}
return NULL;
} // getKart
//-----------------------------------------------------------------------------
const KartProperties* KartPropertiesManager::getKartById(int i) const
{
if (i < 0 || i >= int(m_karts_properties.size()))
return NULL;
return m_karts_properties[i];
}
//-----------------------------------------------------------------------------
/** Returns the (global) index of the n-th kart of a given group. If there is
* no such kart, -1 is returned
*/
int KartPropertiesManager::getKartByGroup(const std::string& group, int n) const
{
int count=0;
for(KartPropertiesVector::const_iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
{
std::vector<std::string> groups=(*i)->getGroups();
if (std::find(groups.begin(), groups.end(), group)==groups.end()) continue;
if(count==n) return (int)(i-m_karts_properties.begin());
count=count+1;
}
return -1;
} // getKartByGroup
/*FIXME: the next function is unused, if it is not useful, it should be
deleted.*/
//-----------------------------------------------------------------------------
std::vector<std::string> KartPropertiesManager::getRandomKarts(int len)
{
std::vector<std::string> all_karts;
for(KartPropertiesVector::const_iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
{
all_karts.push_back((*i)->getIdent());
}
std::random_shuffle(all_karts.begin(), all_karts.end());
all_karts.resize(len);
return all_karts;
} // getRandomKart
//-----------------------------------------------------------------------------
void KartPropertiesManager::fillWithRandomKarts(std::vector<std::string>& vec)
{
std::vector<std::string> all_karts;
for(KartPropertiesVector::const_iterator i = m_karts_properties.begin();
i != m_karts_properties.end(); ++i)
all_karts.push_back((*i)->getIdent());
std::srand((unsigned int)std::time(0));
std::random_shuffle(all_karts.begin(), all_karts.end());
int new_kart = 0;
for(int i = 0; i < int(vec.size()); ++i)
{
while(vec[i].empty())
{
if (std::find(vec.begin(), vec.end(), all_karts[new_kart]) == vec.end())
{ // Found a new kart, so use it
vec[i] = all_karts[new_kart];
}
else if (!(all_karts.size() >= vec.size()))
{ // We need to fill more karts than we have available, so don't care about dups
vec[i] = all_karts[new_kart];
}
new_kart += 1;
} // while
} // for i
}
/* EOF */

View File

@@ -1,64 +1,68 @@
// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2006 Ingo Ruhnke <grumbel@gmx.de>
//
// 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 3
// 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_KARTPROPERTIESMANAGER_H
#define HEADER_KARTPROPERTIESMANAGER_H
#include <vector>
//#include "kart_properties.hpp"
class KartProperties;
class KartPropertiesManager
{
protected:
float m_max_steer_angle;
typedef std::vector<KartProperties*> KartPropertiesVector;
/** All available kart configurations */
KartPropertiesVector m_karts_properties;
public:
KartPropertiesManager();
~KartPropertiesManager();
// vector containing kart numbers that have been selected in multiplayer
// games. This it used to ensure the same kart can not be selected more
// than once.
std::vector<int> m_selected_karts;
const KartProperties* getKartById (int i);
const KartProperties* getKart (const std::string IDENT);
const int getKartId (const std::string IDENT);
void loadKartData (bool dont_load_models=false);
const float getMaximumSteeringAngle() {return m_max_steer_angle;}
const unsigned int getNumberOfKarts () {return (unsigned int)m_karts_properties.size();}
/** Return len random karts */
std::vector<std::string> getRandomKarts (int len);
/** Fill the empty positions in the given vector with random karts */
void fillWithRandomKarts (std::vector<std::string>& vec);
void removeTextures ();
};
extern KartPropertiesManager *kart_properties_manager;
#endif
/* EOF */
// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2006 Ingo Ruhnke <grumbel@gmx.de>
//
// 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 3
// 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_KARTPROPERTIESMANAGER_H
#define HEADER_KARTPROPERTIESMANAGER_H
#include <vector>
//#include "kart_properties.hpp"
class KartProperties;
class KartPropertiesManager
{
private:
std::vector<std::string> m_all_groups;
protected:
float m_max_steer_angle;
typedef std::vector<KartProperties*> KartPropertiesVector;
/** All available kart configurations */
KartPropertiesVector m_karts_properties;
public:
KartPropertiesManager();
~KartPropertiesManager();
// vector containing kart numbers that have been selected in multiplayer
// games. This it used to ensure the same kart can not be selected more
// than once.
std::vector<int> m_selected_karts;
const KartProperties* getKartById (int i) const;
const KartProperties* getKart (const std::string IDENT) const;
const int getKartId (const std::string IDENT) const;
int getKartByGroup (const std::string& group, int i) const;
void loadKartData (bool dont_load_models=false);
const float getMaximumSteeringAngle() const {return m_max_steer_angle;}
const unsigned int getNumberOfKarts () const {return (unsigned int)m_karts_properties.size();}
const std::vector<std::string>& getAllGroups () const {return m_all_groups; }
/** Return len random karts */
std::vector<std::string> getRandomKarts (int len);
/** Fill the empty positions in the given vector with random karts */
void fillWithRandomKarts (std::vector<std::string>& vec);
void removeTextures ();
};
extern KartPropertiesManager *kart_properties_manager;
#endif
/* EOF */

View File

@@ -212,7 +212,7 @@ int handleCmdLine(int argc, char **argv)
{
fprintf ( stdout, " Available tracks:\n" );
for (size_t i = 0; i != track_manager->getTrackCount(); i++)
for (size_t i = 0; i != track_manager->getNumberOfTracks(); i++)
{
const Track *track = track_manager->getTrack(i);
if (!unlock_manager->isLocked(track->getIdent()))

View File

@@ -1,269 +1,269 @@
// $Id$
//
// 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 3
// 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 <iostream>
#include "track_manager.hpp"
#include "game_manager.hpp"
#include "kart_properties_manager.hpp"
#include "race_manager.hpp"
#include "unlock_manager.hpp"
#include "gui/menu_manager.hpp"
#include "world.hpp"
#include "scene.hpp"
#include "user_config.hpp"
#include "stk_config.hpp"
RaceManager* race_manager= NULL;
RaceManager::RaceManager()
{
m_num_karts = user_config->m_karts;
m_difficulty = RD_HARD;
m_race_mode = RM_QUICK_RACE;
m_track_number = 0;
m_active_race = false;
m_score_for_position = stk_config->m_scores;
setTrack("race");
setPlayerKart(0, "tuxkart");
m_coin_target = 0;
} // RaceManager
//-----------------------------------------------------------------------------
RaceManager::~RaceManager()
{
} // ~RaceManager
//-----------------------------------------------------------------------------
void RaceManager::reset()
{
m_num_finished_karts = 0;
m_num_finished_players = 0;
} // reset
//-----------------------------------------------------------------------------
void RaceManager::setPlayerKart(unsigned int player, const std::string& kart)
{
if (player >= 0 && player < 4)
{
if (player >= getNumPlayers())
setNumPlayers(player+1);
m_player_karts[player] = kart;
}
else
{
fprintf(stderr, "Warning: player '%d' does not exists.\n", player);
}
} // setPlayerKart
//-----------------------------------------------------------------------------
void RaceManager::setNumPlayers(int num)
{
m_player_karts.resize(num);
for(PlayerKarts::iterator i = m_player_karts.begin(); i != m_player_karts.end(); ++i)
{
if (i->empty())
{
*i = "tuxkart";
}
}
} // setNumPlayers
//-----------------------------------------------------------------------------
void RaceManager::setDifficulty(Difficulty diff)
{
if(diff==RD_SKIDDING)
{
m_difficulty = RD_HARD;
user_config->m_skidding = true;
}
else
{
m_difficulty = diff;
user_config->m_skidding = false;
}
} // setDifficulty
//-----------------------------------------------------------------------------
void RaceManager::setTrack(const std::string& track)
{
m_tracks.clear();
m_tracks.push_back(track);
} // setTrack
//-----------------------------------------------------------------------------
void RaceManager::startNew()
{
if(m_race_mode==RM_GRAND_PRIX) // GP: get tracks and laps from cup object
{
m_tracks = m_cup.getTracks();
m_num_laps = m_cup.getLaps();
}
assert(m_player_karts.size() > 0);
// command line parameters: negative numbers=all karts
if(m_num_karts < 0 ) m_num_karts = stk_config->m_max_karts;
if((size_t)m_num_karts < m_player_karts.size())
m_num_karts = (int)m_player_karts.size();
// Create the list of all kart names to use
// ========================================
std::vector<std::string> kart_names;
kart_names.resize(m_num_karts);
for(unsigned int i = 0; i < m_player_karts.size(); i++)
{
/*Players position is behind the AI in the first race*/
kart_names[m_num_karts-1 - i] = m_player_karts[m_player_karts.size() - 1 - i];
}
kart_properties_manager->fillWithRandomKarts(kart_names);
// Create the kart status data structure to keep track of scores, times, ...
// ==========================================================================
const int num_ai_karts = m_num_karts - (int)m_player_karts.size();
m_kart_status.clear();
for(int i=0; i<m_num_karts; i++)
{
// AI karts have -1 as player
bool is_player = i>=num_ai_karts; // players start at the back
m_kart_status.push_back(KartStatus(kart_names[i], i,
is_player ? i-num_ai_karts : -1 ) );
} // for i<m_num_karts
// Then start the race with the first track
// ========================================
m_track_number = 0;
startNextRace();
} // startNew
//-----------------------------------------------------------------------------
void RaceManager::startNextRace()
{
m_num_finished_karts = 0;
m_num_finished_players = 0;
// if subsequent race, sort kart status structure
// ==============================================
if (m_track_number > 0)
{
std::sort(m_kart_status.begin(), m_kart_status.end());//sort karts by increasing scor
//reverse kart order if flagged in stk_config
if (stk_config->m_grid_order)
{
std::reverse(m_kart_status.begin(), m_kart_status.end());
}
} // not first race
// the constructor assigns this object to the global
// variable world. Admittedly a bit ugly, but simplifies
// handling of objects which get created in the constructor
// and need world to be defined.
new World();
m_active_race = true;
} // startNextRace
//-----------------------------------------------------------------------------
void RaceManager::next()
{
m_num_finished_karts = 0;
m_num_finished_players = 0;
m_track_number++;
if(m_track_number<(int)m_tracks.size())
{
scene->clear();
startNextRace();
}
else
{
exit_race();
}
} // next
//-----------------------------------------------------------------------------
void RaceManager::exit_race()
{
// Only display the grand prix result screen if all tracks
// were finished, and not when a race is aborted.
if(m_race_mode==RM_GRAND_PRIX && m_track_number==(int)m_tracks.size())
{
unlock_manager->grandPrixFinished();
menu_manager->switchToGrandPrixEnding();
}
else
{
menu_manager->switchToMainMenu();
}
scene->clear();
delete world;
world = 0;
m_track_number = 0;
m_active_race = false;
} // exit_Race
//-----------------------------------------------------------------------------
// Kart kart has finished the race at the specified time (which can be different
// from world->getClock() in case of setting extrapolated arrival times).
void RaceManager::RaceFinished(const Kart *kart, float time)
{
unsigned i;
for(i=0; i<m_kart_status.size(); i++)
{
if(kart->getIdent()==m_kart_status[i].m_ident) break;
} // for i
if(i>=m_kart_status.size())
{
fprintf(stderr, "Kart '%s' not found. Ignored.\n",kart->getName().c_str());
return;
}
// In follow the leader mode, kart 0 does not get any points,
// so the position of each kart is actually one better --> decrease pos
int pos = kart->getPosition();
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[i].m_score += m_score_for_position[pos-1];
m_kart_status[i].m_last_score = m_score_for_position[pos-1];
m_kart_status[i].m_overall_time += time;
m_kart_status[i].m_last_time = time;
m_num_finished_karts ++;
if(kart->isPlayerKart()) m_num_finished_players++;
} // raceFinished
//-----------------------------------------------------------------------------
void RaceManager::restartRace()
{
// Subtract last score from all karts:
for(int i=0; i<m_num_karts; i++)
{
m_kart_status[i].m_score -= m_kart_status[i].m_last_score;
m_kart_status[i].m_overall_time -= m_kart_status[i].m_last_time;
}
world->restartRace();
} // restartRace
/* EOF */
// $Id$
//
// 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 3
// 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 <iostream>
#include "track_manager.hpp"
#include "game_manager.hpp"
#include "kart_properties_manager.hpp"
#include "race_manager.hpp"
#include "unlock_manager.hpp"
#include "gui/menu_manager.hpp"
#include "world.hpp"
#include "scene.hpp"
#include "user_config.hpp"
#include "stk_config.hpp"
RaceManager* race_manager= NULL;
RaceManager::RaceManager()
{
m_num_karts = user_config->m_karts;
m_difficulty = RD_HARD;
m_race_mode = RM_QUICK_RACE;
m_track_number = 0;
m_active_race = false;
m_score_for_position = stk_config->m_scores;
m_coin_target = 0;
setTrack("race");
setPlayerKart(0, "tuxkart");
} // RaceManager
//-----------------------------------------------------------------------------
RaceManager::~RaceManager()
{
} // ~RaceManager
//-----------------------------------------------------------------------------
void RaceManager::reset()
{
m_num_finished_karts = 0;
m_num_finished_players = 0;
} // reset
//-----------------------------------------------------------------------------
void RaceManager::setPlayerKart(unsigned int player, const std::string& kart)
{
if (player >= 0 && player < 4)
{
if (player >= getNumPlayers())
setNumPlayers(player+1);
m_player_karts[player] = kart;
}
else
{
fprintf(stderr, "Warning: player '%d' does not exists.\n", player);
}
} // setPlayerKart
//-----------------------------------------------------------------------------
void RaceManager::setNumPlayers(int num)
{
m_player_karts.resize(num);
for(PlayerKarts::iterator i = m_player_karts.begin(); i != m_player_karts.end(); ++i)
{
if (i->empty())
{
*i = "tuxkart";
}
}
} // setNumPlayers
//-----------------------------------------------------------------------------
void RaceManager::setDifficulty(Difficulty diff)
{
if(diff==RD_SKIDDING)
{
m_difficulty = RD_HARD;
user_config->m_skidding = true;
}
else
{
m_difficulty = diff;
user_config->m_skidding = false;
}
} // setDifficulty
//-----------------------------------------------------------------------------
void RaceManager::setTrack(const std::string& track)
{
m_tracks.clear();
m_tracks.push_back(track);
} // setTrack
//-----------------------------------------------------------------------------
void RaceManager::startNew()
{
if(m_race_mode==RM_GRAND_PRIX) // GP: get tracks and laps from cup object
{
m_tracks = m_cup.getTracks();
m_num_laps = m_cup.getLaps();
}
assert(m_player_karts.size() > 0);
// command line parameters: negative numbers=all karts
if(m_num_karts < 0 ) m_num_karts = stk_config->m_max_karts;
if((size_t)m_num_karts < m_player_karts.size())
m_num_karts = (int)m_player_karts.size();
// Create the list of all kart names to use
// ========================================
std::vector<std::string> kart_names;
kart_names.resize(m_num_karts);
for(unsigned int i = 0; i < m_player_karts.size(); i++)
{
/*Players position is behind the AI in the first race*/
kart_names[m_num_karts-1 - i] = m_player_karts[m_player_karts.size() - 1 - i];
}
kart_properties_manager->fillWithRandomKarts(kart_names);
// Create the kart status data structure to keep track of scores, times, ...
// ==========================================================================
const int num_ai_karts = m_num_karts - (int)m_player_karts.size();
m_kart_status.clear();
for(int i=0; i<m_num_karts; i++)
{
// AI karts have -1 as player
bool is_player = i>=num_ai_karts; // players start at the back
m_kart_status.push_back(KartStatus(kart_names[i], i,
is_player ? i-num_ai_karts : -1 ) );
} // for i<m_num_karts
// Then start the race with the first track
// ========================================
m_track_number = 0;
startNextRace();
} // startNew
//-----------------------------------------------------------------------------
void RaceManager::startNextRace()
{
m_num_finished_karts = 0;
m_num_finished_players = 0;
// if subsequent race, sort kart status structure
// ==============================================
if (m_track_number > 0)
{
std::sort(m_kart_status.begin(), m_kart_status.end());//sort karts by increasing scor
//reverse kart order if flagged in stk_config
if (stk_config->m_grid_order)
{
std::reverse(m_kart_status.begin(), m_kart_status.end());
}
} // not first race
// the constructor assigns this object to the global
// variable world. Admittedly a bit ugly, but simplifies
// handling of objects which get created in the constructor
// and need world to be defined.
new World();
m_active_race = true;
} // startNextRace
//-----------------------------------------------------------------------------
void RaceManager::next()
{
m_num_finished_karts = 0;
m_num_finished_players = 0;
m_track_number++;
if(m_track_number<(int)m_tracks.size())
{
scene->clear();
startNextRace();
}
else
{
exit_race();
}
} // next
//-----------------------------------------------------------------------------
void RaceManager::exit_race()
{
// Only display the grand prix result screen if all tracks
// were finished, and not when a race is aborted.
if(m_race_mode==RM_GRAND_PRIX && m_track_number==(int)m_tracks.size())
{
unlock_manager->grandPrixFinished();
menu_manager->switchToGrandPrixEnding();
}
else
{
menu_manager->switchToMainMenu();
}
scene->clear();
delete world;
world = 0;
m_track_number = 0;
m_active_race = false;
} // exit_Race
//-----------------------------------------------------------------------------
// Kart kart has finished the race at the specified time (which can be different
// from world->getClock() in case of setting extrapolated arrival times).
void RaceManager::RaceFinished(const Kart *kart, float time)
{
unsigned i;
for(i=0; i<m_kart_status.size(); i++)
{
if(kart->getIdent()==m_kart_status[i].m_ident) break;
} // for i
if(i>=m_kart_status.size())
{
fprintf(stderr, "Kart '%s' not found. Ignored.\n",kart->getName().c_str());
return;
}
// In follow the leader mode, kart 0 does not get any points,
// so the position of each kart is actually one better --> decrease pos
int pos = kart->getPosition();
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[i].m_score += m_score_for_position[pos-1];
m_kart_status[i].m_last_score = m_score_for_position[pos-1];
m_kart_status[i].m_overall_time += time;
m_kart_status[i].m_last_time = time;
m_num_finished_karts ++;
if(kart->isPlayerKart()) m_num_finished_players++;
} // raceFinished
//-----------------------------------------------------------------------------
void RaceManager::restartRace()
{
// Subtract last score from all karts:
for(int i=0; i<m_num_karts; i++)
{
m_kart_status[i].m_score -= m_kart_status[i].m_last_score;
m_kart_status[i].m_overall_time -= m_kart_status[i].m_last_time;
}
world->restartRace();
} // restartRace
/* EOF */

View File

@@ -1,156 +1,156 @@
// $Id$
//
// 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 3
// 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_RACEMANAGER_H
#define HEADER_RACEMANAGER_H
#include <vector>
#include <algorithm>
#include <string>
#include "cup_data.hpp"
/** The race manager has two functions:
1) it stores information about the race the user selected (e.g. number
of karts, track, race mode etc.)
2) when a race is started, it creates the world, and keeps track of
score during the race. When a race is finished, it deletes the world,
and (depending on race mode) starts the next race by creating a new
world).
Information in the race manager is considered to be more static, sometimes
the world has similar functions showing the current state. E.g.: the
race manager keeps track of the number of karts with which the race was
started, while world keeps track of the number of karts currently in the
race (consider a race mode like follow the leader where karts can get
eliminated).
The race manager handles all race types as a kind of grand prix. E.g.:
a quick race is basically a GP with only one track (so the race manager
keeps track of scores even though no scores are used in a quick race)
**/
class RaceManager
{
public:
enum RaceModeType { RM_TIME_TRIAL, RM_QUICK_RACE, RM_GRAND_PRIX,
RM_FOLLOW_LEADER };
enum Difficulty { RD_EASY, RD_MEDIUM, RD_HARD, RD_SKIDDING };
private:
struct KartStatus
{
std::string m_ident; // The .tkkf filename without the .tkkf
int m_score; // score for this kart
int m_last_score; // needed for restart race
double m_overall_time; // sum of times of all races
double m_last_time; // needed for restart
int m_prev_finish_pos; // previous finished position
int m_player_id; // player controling the kart, for AI: -1
bool m_is_eliminated; // for mini games which can eliminate karts
KartStatus(const std::string& ident, const int& prev_finish_pos,
const int& player_id) :
m_ident(ident), m_score(0), m_last_score(0),
m_overall_time(0.0f), m_last_time(0.0f),
m_prev_finish_pos(prev_finish_pos), m_player_id(player_id),
m_is_eliminated(false)
{}
}; // KartStatus
std::vector<KartStatus> m_kart_status;
Difficulty m_difficulty;
RaceModeType m_race_mode;
typedef std::vector<std::string> PlayerKarts;
PlayerKarts m_player_karts;
std::vector<std::string> m_tracks;
std::vector<int> m_num_laps;
std::vector<int> m_score_for_position;
int m_track_number;
CupData m_cup;
int m_num_karts;
unsigned int m_num_finished_karts;
unsigned int m_num_finished_players;
int m_coin_target;
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
public:
RaceManager();
~RaceManager();
void setPlayerKart(unsigned int player, const std::string& kart);
void setNumPlayers(int num);
void reset();
void RaceFinished(const Kart* kart, float time);
void setTrack(const std::string& track);
void setGrandPrix(const CupData &cup){ m_cup = cup; }
void setDifficulty(Difficulty diff);
void setNumLaps(int num) { m_num_laps.clear();
m_num_laps.push_back(num); }
void setRaceMode(RaceModeType mode) { m_race_mode = mode; }
void setNumKarts(int num) { m_num_karts = num; }
void setCoinTarget(int num) { m_coin_target = num; }
RaceModeType getRaceMode() const { return m_race_mode; }
unsigned int getNumKarts() const { return m_num_karts; }
unsigned int getNumPlayers() const { return (int)m_player_karts.size();}
int getNumLaps() const { return m_num_laps[m_track_number];}
Difficulty getDifficulty() const { return m_difficulty; }
const std::string&
getTrackName() const { return m_tracks[m_track_number]; }
const CupData
*getGrandPrix() const { return &m_cup; }
unsigned int getFinishedKarts() const { return m_num_finished_karts; }
unsigned int getFinishedPlayers() const { return m_num_finished_players; }
const std::string&
getKartName(int kart) const { return m_kart_status[kart].m_ident;}
const std::string&
getHerringStyle() const { return m_cup.getHerringStyle(); }
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;}
int getCoinTarget() const { return m_coin_target; }
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;}
int allPlayerFinished() const {return
m_num_finished_players==m_player_karts.size(); }
int raceIsActive() const { return m_active_race; }
bool isPlayer(int kart) const {return m_kart_status[kart].m_player_id>-1; }
void setMirror() {/*FIXME*/}
void setReverse(){/*FIXME*/}
void startNew(); // start new race/GP/...
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)
};
extern RaceManager *race_manager;
#endif
/* EOF */
// $Id$
//
// 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 3
// 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_RACEMANAGER_H
#define HEADER_RACEMANAGER_H
#include <vector>
#include <algorithm>
#include <string>
#include "cup_data.hpp"
/** The race manager has two functions:
1) it stores information about the race the user selected (e.g. number
of karts, track, race mode etc.)
2) when a race is started, it creates the world, and keeps track of
score during the race. When a race is finished, it deletes the world,
and (depending on race mode) starts the next race by creating a new
world).
Information in the race manager is considered to be more static, sometimes
the world has similar functions showing the current state. E.g.: the
race manager keeps track of the number of karts with which the race was
started, while world keeps track of the number of karts currently in the
race (consider a race mode like follow the leader where karts can get
eliminated).
The race manager handles all race types as a kind of grand prix. E.g.:
a quick race is basically a GP with only one track (so the race manager
keeps track of scores even though no scores are used in a quick race)
**/
class RaceManager
{
public:
enum RaceModeType { RM_TIME_TRIAL, RM_QUICK_RACE, RM_GRAND_PRIX,
RM_FOLLOW_LEADER };
enum Difficulty { RD_EASY, RD_MEDIUM, RD_HARD, RD_SKIDDING };
private:
struct KartStatus
{
std::string m_ident; // The .tkkf filename without the .tkkf
int m_score; // score for this kart
int m_last_score; // needed for restart race
double m_overall_time; // sum of times of all races
double m_last_time; // needed for restart
int m_prev_finish_pos; // previous finished position
int m_player_id; // player controling the kart, for AI: -1
bool m_is_eliminated; // for mini games which can eliminate karts
KartStatus(const std::string& ident, const int& prev_finish_pos,
const int& player_id) :
m_ident(ident), m_score(0), m_last_score(0),
m_overall_time(0.0f), m_last_time(0.0f),
m_prev_finish_pos(prev_finish_pos), m_player_id(player_id),
m_is_eliminated(false)
{}
}; // KartStatus
std::vector<KartStatus> m_kart_status;
Difficulty m_difficulty;
RaceModeType m_race_mode;
typedef std::vector<std::string> PlayerKarts;
PlayerKarts m_player_karts;
std::vector<std::string> m_tracks;
std::vector<int> m_num_laps;
std::vector<int> m_score_for_position;
int m_track_number;
CupData m_cup;
int m_num_karts;
unsigned int m_num_finished_karts;
unsigned int m_num_finished_players;
int m_coin_target;
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
public:
RaceManager();
~RaceManager();
void setPlayerKart(unsigned int player, const std::string& kart);
void setNumPlayers(int num);
void reset();
void RaceFinished(const Kart* kart, float time);
void setTrack(const std::string& track);
void setGrandPrix(const CupData &cup){ m_cup = cup; }
void setDifficulty(Difficulty diff);
void setNumLaps(int num) { m_num_laps.clear();
m_num_laps.push_back(num); }
void setRaceMode(RaceModeType mode) { m_race_mode = mode; }
void setNumKarts(int num) { m_num_karts = num; }
void setCoinTarget(int num) { m_coin_target = num; }
RaceModeType getRaceMode() const { return m_race_mode; }
unsigned int getNumKarts() const { return m_num_karts; }
unsigned int getNumPlayers() const { return (int)m_player_karts.size();}
int getNumLaps() const { return m_num_laps[m_track_number];}
Difficulty getDifficulty() const { return m_difficulty; }
const std::string&
getTrackName() const { return m_tracks[m_track_number]; }
const CupData
*getGrandPrix() const { return &m_cup; }
unsigned int getFinishedKarts() const { return m_num_finished_karts; }
unsigned int getFinishedPlayers() const { return m_num_finished_players; }
const std::string&
getKartName(int kart) const { return m_kart_status[kart].m_ident;}
const std::string&
getHerringStyle() const { return m_cup.getHerringStyle(); }
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;}
int getCoinTarget() const { return m_coin_target; }
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;}
int allPlayerFinished() const {return
m_num_finished_players==m_player_karts.size(); }
int raceIsActive() const { return m_active_race; }
bool isPlayer(int kart) const {return m_kart_status[kart].m_player_id>-1; }
void setMirror() {/*FIXME*/}
void setReverse(){/*FIXME*/}
void startNew(); // start new race/GP/...
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)
};
extern RaceManager *race_manager;
#endif
/* EOF */

View File

@@ -458,7 +458,7 @@ bool DefaultRobot::do_wheelie ( const int STEPS )
for( int i = WHEELIE_STEPS; i > STEPS - 1; --i )
{
step_coord = getXYZ()+vel_normal* m_kart_properties->getKartLength() * i ;
step_coord = getXYZ()+vel_normal* m_kart_properties->getKartLength() * float(i);
world->m_track->spatialToTrack(step_track_coord, step_coord,
m_future_sector );
@@ -601,7 +601,7 @@ void DefaultRobot::check_crashes( const int STEPS, const Vec3& pos )
for(int i = 1; STEPS > i; ++i)
{
step_coord = pos + vel_normal* m_kart_properties->getKartLength() * i;
step_coord = pos + vel_normal* m_kart_properties->getKartLength() * float(i);
/* Find if we crash with any kart, as long as we haven't found one
* yet
@@ -720,7 +720,7 @@ void DefaultRobot::find_non_crashing_point( sgVec2 result )
//Test if we crash if we drive towards the target sector
for( int i = 2; i < steps; ++i )
{
step_coord = getXYZ()+direction*m_kart_properties->getKartLength() * i ;
step_coord = getXYZ()+direction*m_kart_properties->getKartLength() * float(i);
world->m_track->spatialToTrack( step_track_coord, step_coord,
sector );

View File

@@ -20,6 +20,7 @@
#include "smoke.hpp"
#include "kart.hpp"
#include "constants.hpp"
Smoke::Smoke(Kart* kart_,
int num, float _create_rate, int _ttf,

View File

@@ -82,9 +82,6 @@ void STKConfig::load(const std::string filename)
CHECK_NEG(m_wheelie_pitch_rate, "wheelie-pitch-rate" );
CHECK_NEG(m_wheelie_restore_rate, "wheelie-restore-rate" );
CHECK_NEG(m_wheelie_speed_boost, "wheelie-speed-boost" );
CHECK_NEG(m_wheelie_lean_recovery, "wheelie-lean-recovery" );
CHECK_NEG(m_wheelie_balance_recovery,"wheelie-balance-recovery" );
CHECK_NEG(m_wheelie_step, "wheelie-step" );
CHECK_NEG(m_wheelie_power_boost, "wheelie-power-boost" );
CHECK_NEG(m_parachute_friction, "parachute-friction" );
@@ -116,6 +113,7 @@ void STKConfig::load(const std::string filename)
CHECK_NEG(m_zipper_speed_gain, "zipper-speed-gain" );
CHECK_NEG(m_shortcut_segments, "shortcut-skipped-segments" );
CHECK_NEG(m_suspension_rest, "suspension-rest" );
CHECK_NEG(m_suspension_travel_cm, "suspension-travel-cm" );
CHECK_NEG(m_jump_velocity, "jump-velocity" );
CHECK_NEG(m_explosion_impulse, "explosion-impulse" );
CHECK_NEG(m_explosion_impulse_objects, "explosion-impulse-objects" );
@@ -147,12 +145,12 @@ void STKConfig::init_defaults()
//bullet physics data
m_suspension_stiffness = m_wheel_damping_relaxation =
m_wheel_damping_compression = m_friction_slip = m_roll_influence =
m_wheel_radius = m_wheel_width = m_wheelie_lean_recovery =
m_wheelie_step = m_wheelie_balance_recovery =m_wheelie_power_boost =
m_wheel_radius = m_wheel_width = m_wheelie_power_boost =
m_chassis_linear_damping = m_chassis_angular_damping =
m_maximum_speed = m_gravity_center_shift = m_suspension_rest =
m_maximum_speed = m_gravity_center_shift = m_suspension_rest =
m_max_speed_reverse_ratio = m_explosion_impulse = m_jump_velocity =
m_explosion_impulse_objects = m_upright_tolerance = m_upright_max_force =
m_suspension_travel_cm =
// Camera
m_camera_max_accel = m_camera_max_brake = m_camera_distance = -99.9f;

View File

@@ -840,6 +840,9 @@ void Track::loadTrack(std::string filename_)
LISP->get ("gravity", m_gravity);
LISP->get ("AI-angle-adjust", m_AI_angle_adjustment);
LISP->get ("AI-curve-speed-adjust", m_AI_curve_speed_adjustment);
LISP->getVector("groups", m_groups);
if(m_groups.size()==0)
m_groups.push_back("standard");
// if both camera position and rotation are defined,
// set the flag that the track has final camera position
m_has_final_camera = LISP->get("camera-final-position", m_camera_final_position);

View File

@@ -50,6 +50,7 @@ private:
std::string m_description;
std::string m_designer;
std::string m_filename;
std::vector<std::string> m_groups;
ssgBranch* m_model;
TriangleMesh* m_track_mesh;
TriangleMesh* m_non_collision_mesh;
@@ -150,6 +151,8 @@ public:
float getTrackLength () const {return m_total_distance; }
const std::string& getIdent () const {return m_ident; }
const char* getName () const {return m_name.c_str(); }
const std::vector<std::string>
getGroups () const {return m_groups; }
void startMusic () const;
const std::string& getFilename () const {return m_filename; }
const sgVec3& getSunPos () const {return m_sun_position; }

View File

@@ -19,6 +19,7 @@
#include <stdio.h>
#include <stdexcept>
#include <algorithm>
#include "file_manager.hpp"
#include "string_utils.hpp"
#include "track_manager.hpp"
@@ -52,18 +53,6 @@ Track* TrackManager::getTrack(const std::string& ident) const
throw std::runtime_error(msg);
} // getTrack
//-----------------------------------------------------------------------------
Track* TrackManager::getTrack(size_t id) const
{
return m_tracks[id];
} // getTrack
//-----------------------------------------------------------------------------
size_t TrackManager::getTrackCount() const
{
return m_tracks.size();
} // getTrackCount
//-----------------------------------------------------------------------------
void TrackManager::loadTrackList ()
{
@@ -87,9 +76,37 @@ void TrackManager::loadTrackList ()
FILE *f=fopen(config_file.c_str(),"r");
if(!f) continue;
m_tracks.push_back(new Track(config_file));
Track *track = new Track(config_file);
m_tracks.push_back(track);
updateGroups(track);
// Read music files in that dir as well
sound_manager->loadMusicFromOneDir(*dir);
}
} // loadTrackList
// ----------------------------------------------------------------------------
void TrackManager::updateGroups(const Track* track)
{
const std::vector<std::string>& new_groups = track->getGroups();
for(unsigned int i=0; i<new_groups.size(); i++)
{
if(std::find(m_all_groups.begin(), m_all_groups.end(), new_groups[i])
== m_all_groups.end()) continue;
m_all_groups.push_back(new_groups[i]);
}
} // updateGroups
// ----------------------------------------------------------------------------
int TrackManager::getTrackByGroup(const std::string& group, int n) const
{
int count=0;
for(Tracks::const_iterator i = m_tracks.begin(); i != m_tracks.end(); i++)
{
std::vector<std::string> groups=(*i)->getGroups();
if (std::find(groups.begin(), groups.end(), group)==groups.end()) continue;
if(count==n) return (int)(i-m_tracks.begin());
count=count+1;
}
return -1;
} // getTrackByGroup

View File

@@ -29,23 +29,26 @@ class Track;
class TrackManager
{
private:
typedef std::vector<Track*> Tracks;
Tracks m_tracks;
typedef std::vector<Track*> Tracks;
Tracks m_tracks;
std::vector<std::string>
m_all_groups;
void updateGroups(const Track* track);
public:
TrackManager();
~TrackManager();
TrackManager();
~TrackManager();
/** get TrackData by the track ident (aka filename without
.track) */
Track* getTrack(const std::string& ident) const;
Track* getTrack(size_t id) const;
/** get TrackData by the track ident (aka filename without .track) */
Track *getTrack(const std::string& ident) const;
Track *getTrack(size_t id) const {return m_tracks[id]; }
int getTrackByGroup(const std::string& group, int n) const;
const std::vector<std::string>
getAllGroups();
size_t getNumberOfTracks() const {return m_tracks.size();}
size_t getTrackCount() const;
/** initialize the track list by searching through all directories
for .track files */
void loadTrackList ();
/** load all .track files from all directories */
void loadTrackList ();
};
extern TrackManager* track_manager;

View File

@@ -26,8 +26,8 @@
# define gettext_noop(String) String
# define N_(String) gettext_noop (String)
// libintl defines its own fprintf, which doesn't work for me :(
# if defined(WIN32) && !defined(__CYGWIN__)
# undef fprintf
# if defined(WIN32) && !defined(__CYGWIN__)
# undef fprintf
# endif
#else
# define _(String) (String)

View File

@@ -118,6 +118,8 @@ void UserConfig::setDefaults()
m_blacklist_res.clear();
m_karts = 4;
m_log_errors = false;
m_kart_group = "standard";
m_track_group = "standard";
if(getenv("USERNAME")!=NULL) // for windows
m_username=getenv("USERNAME");
@@ -131,6 +133,7 @@ void UserConfig::setDefaults()
for(int i=0; i<4; i++)
{
m_player[i].setName(m_username);
m_player[i].setLastKartId(0);
}
// Clear every entry.
@@ -304,7 +307,7 @@ void UserConfig::loadConfig()
int UserConfig::CheckAndCreateDir()
{
const std::string DIRNAME = file_manager->getHomeDir();
ulDir* u = ulOpenDir(DIRNAME.c_str());
ulDir* u = ulOpenDir(DIRNAME.c_str());
if(u)
{ // OK, directory exists
ulCloseDir(u);
@@ -436,7 +439,8 @@ void UserConfig::loadConfig(const std::string& filename)
//get whether to log errors to file
lisp->get("log-errors", m_log_errors);
lisp->get("kart-group", m_kart_group);
lisp->get("track-group", m_track_group);
// Handle loading the stick config in it own method.
readStickConfigs(lisp);
@@ -683,6 +687,10 @@ void UserConfig::saveConfig(const std::string& filename)
writer->writeComment("error logging to log (true) or stderr (false)");
writer->write("log-errors\t", m_log_errors);
writer->writeComment("Last selected kart group");
writer->write("kart-group", m_kart_group);
writer->writeComment("Last selected track group");
writer->write("track-group", m_track_group);
writeStickConfigs(writer);
// Write unlock information back

View File

@@ -175,6 +175,8 @@ public:
std::string m_herring_style;
std::string m_username;
std::string m_background_music;
std::string m_kart_group; // Kart group used last
std::string m_track_group; // Track group used last
bool m_replay_history;
bool m_use_kph;
int m_width;

View File

@@ -719,7 +719,7 @@ void Widget::draw()
if( m_enable_track )
{
if( m_track_num > (int)(track_manager->getTrackCount()) - 1)
if( m_track_num > (int)(track_manager->getNumberOfTracks()) - 1)
{
std::cerr << "Warning: widget tried to draw a track with a " <<
"number bigger than the amount of tracks available.\n";

View File

@@ -909,6 +909,7 @@ void WidgetManager::setSelectedWgt(const int TOKEN)
{
setSelectedWgtToken( TOKEN );
}
else std::cerr << "WARNING: tried to select unnamed widget with " <<
"token " << TOKEN << '\n';
}