First iteration of battle mode! It's playable, and the rack selection works. Warning, if you select AI players it won't work. Lives are shown but don't decrease with hits yet.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2339 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
bac6c98e9f
commit
ed2f52bee6
@ -149,6 +149,7 @@ supertuxkart_SOURCES = main.cpp \
|
||||
modes/clock.cpp modes/clock.hpp \
|
||||
modes/world.cpp modes/world.hpp \
|
||||
modes/linear_world.cpp modes/linear_world.hpp \
|
||||
modes/three_strikes_battle.cpp modes/three_strikes_battle.hpp \
|
||||
replay_buffer_tpl.hpp \
|
||||
replay_buffers.hpp replay_buffers.cpp \
|
||||
replay_base.hpp replay_base.cpp \
|
||||
|
@ -32,12 +32,13 @@ enum WidgetTokens
|
||||
WTOK_QUICK_RACE_SINGLE,
|
||||
WTOK_TIMETRIAL_SINGLE,
|
||||
WTOK_FOLLOW_LEADER_SINGLE,
|
||||
|
||||
WTOK_3_STRIKES_SINGLE,
|
||||
|
||||
WTOK_TITLE_GP,
|
||||
WTOK_QUICK_RACE_GP,
|
||||
WTOK_TIMETRIAL_GP,
|
||||
WTOK_FOLLOW_LEADER_GP,
|
||||
|
||||
|
||||
WTOK_HELP,
|
||||
WTOK_QUIT
|
||||
};
|
||||
@ -47,51 +48,63 @@ GameMode::GameMode()
|
||||
const int HEIGHT = 7;
|
||||
const int WIDTH = 5;
|
||||
|
||||
const WidgetDirection column_1_dir = WGT_DIR_FROM_LEFT;
|
||||
const float column_1_loc = 0.1f;
|
||||
|
||||
const WidgetDirection column_2_dir = WGT_DIR_FROM_RIGHT;
|
||||
const float column_2_loc = 0.1f;
|
||||
|
||||
// First the single race events
|
||||
// ============================
|
||||
Widget *w=widget_manager->addTextWgt(WTOK_TITLE_SINGLE, WIDTH,
|
||||
HEIGHT, _("Single Race"));
|
||||
widget_manager->hideWgtRect(WTOK_TITLE_SINGLE);
|
||||
w->setPosition(WGT_DIR_FROM_LEFT, 0.1f, NULL,
|
||||
w->setPosition(column_1_dir, column_1_loc, NULL,
|
||||
WGT_DIR_FROM_TOP, 0.2f, NULL);
|
||||
Widget *w_prev=w;
|
||||
w=widget_manager->addTextButtonWgt(WTOK_QUICK_RACE_SINGLE, WIDTH, HEIGHT,
|
||||
_("Quick Race"));
|
||||
w->setPosition(WGT_DIR_FROM_LEFT, 0.1f, NULL,
|
||||
w->setPosition(column_1_dir, column_1_loc, NULL,
|
||||
WGT_DIR_UNDER_WIDGET, 0.0f, w_prev);
|
||||
w_prev=w;
|
||||
w=widget_manager->addTextButtonWgt(WTOK_TIMETRIAL_SINGLE, WIDTH, HEIGHT,
|
||||
_("Time Trial"));
|
||||
w->setPosition(WGT_DIR_FROM_LEFT, 0.1f, NULL,
|
||||
w->setPosition(column_1_dir, column_1_loc, NULL,
|
||||
WGT_DIR_UNDER_WIDGET, 0.0f, w_prev);
|
||||
w_prev=w;
|
||||
w=widget_manager->addTextButtonWgt(WTOK_FOLLOW_LEADER_SINGLE, WIDTH, HEIGHT,
|
||||
_("Follow the Leader"));
|
||||
w->setPosition(WGT_DIR_FROM_LEFT, 0.1f, NULL,
|
||||
w->setPosition(column_1_dir, column_1_loc, NULL,
|
||||
WGT_DIR_UNDER_WIDGET, 0.0f, w_prev);
|
||||
widget_manager->sameWidth(WTOK_TITLE_SINGLE, WTOK_FOLLOW_LEADER_SINGLE);
|
||||
w_prev=w;
|
||||
w=widget_manager->addTextButtonWgt(WTOK_3_STRIKES_SINGLE, WIDTH, HEIGHT,
|
||||
_("3 Strikes Battle"));
|
||||
w->setPosition(column_1_dir, column_1_loc, NULL,
|
||||
WGT_DIR_UNDER_WIDGET, 0.0f, w_prev);
|
||||
w_prev=w;
|
||||
widget_manager->sameWidth(WTOK_TITLE_SINGLE, WTOK_3_STRIKES_SINGLE);
|
||||
|
||||
// Then the GPs
|
||||
// ============
|
||||
w=widget_manager->addTextWgt(WTOK_TITLE_GP, WIDTH,
|
||||
HEIGHT, _("Grand Prix"));
|
||||
widget_manager->hideWgtRect(WTOK_TITLE_GP);
|
||||
w->setPosition(WGT_DIR_FROM_RIGHT, 0.1f, NULL,
|
||||
w->setPosition(column_2_dir, column_2_loc, NULL,
|
||||
WGT_DIR_FROM_TOP, 0.2f, NULL);
|
||||
w_prev=w;
|
||||
w=widget_manager->addTextButtonWgt(WTOK_QUICK_RACE_GP, WIDTH, HEIGHT,
|
||||
_("Quick Race"));
|
||||
w->setPosition(WGT_DIR_FROM_RIGHT, 0.1f, NULL,
|
||||
w->setPosition(column_2_dir, column_2_loc, NULL,
|
||||
WGT_DIR_UNDER_WIDGET, 0.0f, w_prev);
|
||||
w_prev=w;
|
||||
w=widget_manager->addTextButtonWgt(WTOK_TIMETRIAL_GP, WIDTH, HEIGHT,
|
||||
_("Time Trial"));
|
||||
w->setPosition(WGT_DIR_FROM_RIGHT, 0.1f, NULL,
|
||||
w->setPosition(column_2_dir, column_2_loc, NULL,
|
||||
WGT_DIR_UNDER_WIDGET, 0.0f, w_prev);
|
||||
w_prev=w;
|
||||
w=widget_manager->addTextButtonWgt(WTOK_FOLLOW_LEADER_GP, WIDTH, HEIGHT,
|
||||
_("Follow the Leader"));
|
||||
w->setPosition(WGT_DIR_FROM_RIGHT, 0.1f, NULL,
|
||||
w->setPosition(column_2_dir, column_2_loc, NULL,
|
||||
WGT_DIR_UNDER_WIDGET, 0.0f, w_prev);
|
||||
w_prev=w;
|
||||
widget_manager->sameWidth(WTOK_TITLE_GP, WTOK_FOLLOW_LEADER_GP);
|
||||
@ -125,11 +138,14 @@ GameMode::GameMode()
|
||||
// _("Fulfil challenge to unlock"));
|
||||
}
|
||||
|
||||
|
||||
// help
|
||||
w=widget_manager->addTextButtonWgt( WTOK_HELP, WIDTH, HEIGHT, _("Game mode help"));
|
||||
widget_manager->setWgtTextSize( WTOK_HELP, WGT_FNT_SML );
|
||||
w->setPosition(WGT_DIR_CENTER, 0.0f, NULL, WGT_DIR_UNDER_WIDGET, 0.1f, w_prev);
|
||||
w_prev=w;
|
||||
|
||||
// return button
|
||||
w=widget_manager->addTextButtonWgt(WTOK_QUIT, WIDTH, HEIGHT, _("Press <ESC> to go back"));
|
||||
widget_manager->setWgtTextSize( WTOK_QUIT, WGT_FNT_SML );
|
||||
w->setPosition(WGT_DIR_CENTER, 0.0f, NULL, WGT_DIR_FROM_BOTTOM, 0.0f, w_prev);
|
||||
@ -161,6 +177,10 @@ void GameMode::select()
|
||||
race_manager->setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
|
||||
race_manager->setMinorMode(RaceManager::MINOR_MODE_FOLLOW_LEADER);
|
||||
break;
|
||||
case WTOK_3_STRIKES_SINGLE:
|
||||
race_manager->setMajorMode(RaceManager::MAJOR_MODE_SINGLE);
|
||||
race_manager->setMinorMode(RaceManager::MINOR_MODE_3_STRIKES);
|
||||
break;
|
||||
case WTOK_QUICK_RACE_GP:
|
||||
race_manager->setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX);
|
||||
race_manager->setMinorMode(RaceManager::MINOR_MODE_QUICK_RACE);
|
||||
|
@ -279,6 +279,9 @@ void RaceGUI::drawTimer ()
|
||||
|
||||
void RaceGUI::drawMap ()
|
||||
{
|
||||
// arenas currently don't have a map.
|
||||
if(RaceManager::getTrack()->isArena()) return;
|
||||
|
||||
glDisable ( GL_TEXTURE_2D ) ;
|
||||
assert(RaceManager::getWorld() != NULL);
|
||||
int xLeft = 10;
|
||||
@ -338,9 +341,9 @@ void RaceGUI::drawPlayerIcons (const KartIconDisplayInfo* info)
|
||||
{
|
||||
Kart* kart = RaceManager::getKart(i);
|
||||
if(kart->isEliminated()) continue;
|
||||
int position = kart->getPosition();
|
||||
const int position = kart->getPosition();
|
||||
|
||||
y = user_config->m_height*3/4-20 - ((position-1)*(ICON_PLAYER_WIDHT+2));
|
||||
y = user_config->m_height*3/4-20 - ( (position == -1 ? i : position-1)*(ICON_PLAYER_WIDHT+2));
|
||||
|
||||
GLfloat COLOR[] = {info[i].r, info[i].g, info[i].b, 1.0f};
|
||||
font_race->PrintShadow(info[i].time.c_str(), 30, ICON_PLAYER_WIDHT+x, y+5, COLOR);
|
||||
@ -390,19 +393,21 @@ void RaceGUI::drawPlayerIcons (const KartIconDisplayInfo* info)
|
||||
glDisable(GL_CULL_FACE);
|
||||
char str[256];
|
||||
|
||||
sprintf(str, "%d", kart->getPosition());
|
||||
font_race->PrintShadow(str, 33, x-7, y-4);
|
||||
|
||||
// FIXME: translation
|
||||
if (kart->getPosition() == 1)
|
||||
font_race->PrintShadow("st", 13, x-7+17, y-4+17);
|
||||
else if (kart->getPosition() == 2)
|
||||
font_race->PrintShadow("nd", 13, x-7+17, y-4+17);
|
||||
else if (kart->getPosition() == 3)
|
||||
font_race->PrintShadow("rd", 13, x-7+17, y-4+17);
|
||||
else
|
||||
font_race->PrintShadow("th", 13, x-7+17, y-4+17);
|
||||
|
||||
if(position != -1)
|
||||
{
|
||||
sprintf(str, "%d", position);
|
||||
font_race->PrintShadow(str, 33, x-7, y-4);
|
||||
|
||||
// FIXME: translation
|
||||
if (kart->getPosition() == 1)
|
||||
font_race->PrintShadow("st", 13, x-7+17, y-4+17);
|
||||
else if (kart->getPosition() == 2)
|
||||
font_race->PrintShadow("nd", 13, x-7+17, y-4+17);
|
||||
else if (kart->getPosition() == 3)
|
||||
font_race->PrintShadow("rd", 13, x-7+17, y-4+17);
|
||||
else
|
||||
font_race->PrintShadow("th", 13, x-7+17, y-4+17);
|
||||
}
|
||||
} // next kart
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
@ -633,7 +638,11 @@ void RaceGUI::drawSteering(Kart* kart, int offset_x, int offset_y,
|
||||
void RaceGUI::drawPosition(Kart* kart, int offset_x, int offset_y,
|
||||
float ratio_x, float ratio_y )
|
||||
{
|
||||
|
||||
// arenas don't have a position (rank)
|
||||
if(RaceManager::getTrack()->isArena()) return;
|
||||
|
||||
if(kart->getPosition() == -1) return;
|
||||
|
||||
char str[256];
|
||||
offset_x += (int)((user_config->m_width-110)*ratio_x);
|
||||
offset_y += (int)(140*ratio_y);
|
||||
|
@ -42,7 +42,6 @@ class RaceSetup;
|
||||
struct KartIconDisplayInfo
|
||||
{
|
||||
std::string time;
|
||||
// int rank;
|
||||
float r, g, b;
|
||||
std::string special_title;
|
||||
/** Current lap of this kart, or -1 if irrelevant
|
||||
|
@ -150,6 +150,8 @@ void TrackSel::switchGroup()
|
||||
m_index_avail_tracks.clear();
|
||||
|
||||
const std::vector<int> &tracks =
|
||||
RaceManager::isBattleMode( race_manager->getMinorMode() ) ?
|
||||
track_manager->getArenasInGroup(user_config->m_track_group) :
|
||||
track_manager->getTracksInGroup(user_config->m_track_group);
|
||||
|
||||
for(unsigned int i=0; i<tracks.size(); i++)
|
||||
@ -163,7 +165,8 @@ void TrackSel::switchGroup()
|
||||
// Now add the groups, indicated by a negative number as kart index
|
||||
// ----------------------------------------------------------------
|
||||
const std::vector<std::string>& groups=track_manager->getAllGroups();
|
||||
for(int i =0; i<(int)groups.size(); i++)
|
||||
const int group_size = (int)groups.size();
|
||||
for(int i =0; i<group_size; i++)
|
||||
{
|
||||
// Only add groups other than the current one
|
||||
if(groups[i]!=user_config->m_track_group) m_index_avail_tracks.push_back(-i-1);
|
||||
|
@ -10,6 +10,8 @@
|
||||
95065F6A0E9127B800B2C509 /* race_result_message.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95065F690E9127B700B2C509 /* race_result_message.cpp */; };
|
||||
9519653D0E8C592F001BB888 /* linear_world.hpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9519653B0E8C592F001BB888 /* linear_world.hpp */; };
|
||||
9519653E0E8C592F001BB888 /* linear_world.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9519653C0E8C592F001BB888 /* linear_world.cpp */; };
|
||||
957A12BE0EA4271500E46BFD /* three_strikes_battle.hpp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 957A12BC0EA4271500E46BFD /* three_strikes_battle.hpp */; };
|
||||
957A12BF0EA4271500E46BFD /* three_strikes_battle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 957A12BD0EA4271500E46BFD /* three_strikes_battle.cpp */; };
|
||||
95F0F25A0E85C054005F6693 /* callbacks.c in Sources */ = {isa = PBXBuildFile; fileRef = 95923F8B0E808EDC00388BDC /* callbacks.c */; };
|
||||
95F0F25B0E85C054005F6693 /* list.c in Sources */ = {isa = PBXBuildFile; fileRef = 95923FAF0E808EDC00388BDC /* list.c */; };
|
||||
95F0F25C0E85C054005F6693 /* host.c in Sources */ = {isa = PBXBuildFile; fileRef = 95923F9B0E808EDC00388BDC /* host.c */; };
|
||||
@ -252,6 +254,7 @@
|
||||
95F0F36E0E85C6A6005F6693 /* clock.hpp in CopyFiles */,
|
||||
95F0F3830E85C76B005F6693 /* world.hpp in CopyFiles */,
|
||||
9519653D0E8C592F001BB888 /* linear_world.hpp in CopyFiles */,
|
||||
957A12BE0EA4271500E46BFD /* three_strikes_battle.hpp in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
};
|
||||
@ -265,6 +268,8 @@
|
||||
956F3FAC0E85BE0E006F93B0 /* random_generator.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = random_generator.hpp; sourceTree = "<group>"; };
|
||||
956F3FAD0E85BE0E006F93B0 /* ssg_help.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ssg_help.cpp; sourceTree = "<group>"; };
|
||||
956F3FAE0E85BE0E006F93B0 /* ssg_help.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = ssg_help.hpp; sourceTree = "<group>"; };
|
||||
957A12BC0EA4271500E46BFD /* three_strikes_battle.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = three_strikes_battle.hpp; path = modes/three_strikes_battle.hpp; sourceTree = "<group>"; };
|
||||
957A12BD0EA4271500E46BFD /* three_strikes_battle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = three_strikes_battle.cpp; path = modes/three_strikes_battle.cpp; sourceTree = "<group>"; };
|
||||
957B11B30E831DA8002A69EA /* standard_race.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = standard_race.hpp; path = modes/standard_race.hpp; sourceTree = "<group>"; };
|
||||
957B11B40E831DA8002A69EA /* standard_race.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = standard_race.cpp; path = modes/standard_race.cpp; sourceTree = "<group>"; };
|
||||
957B11D70E8320CD002A69EA /* follow_the_leader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = follow_the_leader.hpp; path = modes/follow_the_leader.hpp; sourceTree = "<group>"; };
|
||||
@ -2066,6 +2071,8 @@
|
||||
9519653B0E8C592F001BB888 /* linear_world.hpp */,
|
||||
9519653C0E8C592F001BB888 /* linear_world.cpp */,
|
||||
957B11B40E831DA8002A69EA /* standard_race.cpp */,
|
||||
957A12BC0EA4271500E46BFD /* three_strikes_battle.hpp */,
|
||||
957A12BD0EA4271500E46BFD /* three_strikes_battle.cpp */,
|
||||
);
|
||||
name = modes;
|
||||
sourceTree = "<group>";
|
||||
@ -2335,6 +2342,7 @@
|
||||
95F0F3840E85C76B005F6693 /* world.cpp in Sources */,
|
||||
9519653E0E8C592F001BB888 /* linear_world.cpp in Sources */,
|
||||
95065F6A0E9127B800B2C509 /* race_result_message.cpp in Sources */,
|
||||
957A12BF0EA4271500E46BFD /* three_strikes_battle.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -58,7 +58,8 @@ protected:
|
||||
void forceRescue(Kart* kart, KartInfo& kart_info, bool shortcut);
|
||||
|
||||
void doLapCounting ( KartInfo& kart_info, Kart* kart );
|
||||
|
||||
float estimateFinishTimeForKart (Kart* kart, KartInfo& kart_info);
|
||||
void updateRacePosition ( Kart* kart, KartInfo& kart_info );
|
||||
public:
|
||||
LinearWorld();
|
||||
virtual ~LinearWorld();
|
||||
@ -84,8 +85,6 @@ public:
|
||||
virtual void terminateRace();
|
||||
virtual void restartRace();
|
||||
|
||||
float estimateFinishTimeForKart (Kart* kart, KartInfo& kart_info);
|
||||
void updateRacePosition ( Kart* kart, KartInfo& kart_info );
|
||||
|
||||
virtual bool raceHasLaps(){ return true; }
|
||||
};
|
||||
|
170
src/modes/three_strikes_battle.cpp
Normal file
170
src/modes/three_strikes_battle.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
// 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 "modes/three_strikes_battle.hpp"
|
||||
#include "gui/race_gui.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
ThreeStrikesBattle::ThreeStrikesBattle() : World()
|
||||
{
|
||||
TimedRace::setClockMode(CHRONO);
|
||||
|
||||
// FIXME - disable AI karts in the GUI
|
||||
if(race_manager->getNumKarts() > race_manager->getNumPlayers())
|
||||
{
|
||||
fprintf(stderr, "No AI exists for this game mode");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
const unsigned int kart_amount = m_kart.size();
|
||||
m_kart_display_info = new KartIconDisplayInfo[kart_amount];
|
||||
|
||||
for(unsigned int n=0; n<kart_amount; n++)
|
||||
{
|
||||
// create the struct that ill hold each player's lives
|
||||
BattleInfo info;
|
||||
info.m_lives = 3;
|
||||
m_kart_info.push_back(info);
|
||||
|
||||
// no positions in this mode
|
||||
m_kart[n]->setPosition(-1);
|
||||
}// next kart
|
||||
|
||||
// TODO - implement
|
||||
}
|
||||
ThreeStrikesBattle::~ThreeStrikesBattle()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ThreeStrikesBattle::onGo()
|
||||
{
|
||||
// Reset the brakes now that the prestart
|
||||
// phase is over (braking prevents the karts
|
||||
// from sliding downhill)
|
||||
for(unsigned int i=0; i<m_kart.size(); i++)
|
||||
{
|
||||
m_kart[i]->resetBrakes();
|
||||
}
|
||||
}
|
||||
void ThreeStrikesBattle::terminateRace()
|
||||
{
|
||||
// TODO - implement
|
||||
}
|
||||
|
||||
std::string ThreeStrikesBattle::getInternalCode() const
|
||||
{
|
||||
return "BATTLE_3_STRIKES";
|
||||
}
|
||||
void ThreeStrikesBattle::update(float delta)
|
||||
{
|
||||
World::update(delta);
|
||||
}
|
||||
void ThreeStrikesBattle::restartRace()
|
||||
{
|
||||
}
|
||||
//void ThreeStrikesBattle::getDefaultCollectibles(int& collectible_type, int& amount)
|
||||
|
||||
KartIconDisplayInfo* ThreeStrikesBattle::getKartsDisplayInfo(const RaceGUI* caller)
|
||||
{
|
||||
const unsigned int kart_amount = race_manager->getNumKarts();
|
||||
for(unsigned int i = 0; i < kart_amount ; i++)
|
||||
{
|
||||
KartIconDisplayInfo& rank_info = m_kart_display_info[i];
|
||||
|
||||
// reset color
|
||||
rank_info.lap = -1;
|
||||
|
||||
switch(m_kart_info[i].m_lives)
|
||||
{
|
||||
case 3:
|
||||
rank_info.r = 0.0;
|
||||
rank_info.g = 1.0;
|
||||
rank_info.b = 0.0;
|
||||
break;
|
||||
case 2:
|
||||
rank_info.r = 1.0;
|
||||
rank_info.g = 0.9;
|
||||
rank_info.b = 0.0;
|
||||
break;
|
||||
case 1:
|
||||
rank_info.r = 1.0;
|
||||
rank_info.g = 0.0;
|
||||
rank_info.b = 0.0;
|
||||
break;
|
||||
case 0:
|
||||
rank_info.r = 0.5;
|
||||
rank_info.g = 0.5;
|
||||
rank_info.b = 0.5;
|
||||
break;
|
||||
}
|
||||
|
||||
char lives[4];
|
||||
sprintf(lives, "%i", m_kart_info[i].m_lives);
|
||||
|
||||
rank_info.time = lives; // FIXME - rename 'time' to something more generic
|
||||
}
|
||||
|
||||
return m_kart_display_info;
|
||||
}
|
||||
|
||||
void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
|
||||
{
|
||||
// find closest point to drop kart on
|
||||
const int start_spots_amount = RaceManager::getTrack()->m_start_positions.size();
|
||||
assert(start_spots_amount > 0);
|
||||
|
||||
int smallest_distance_found = -1, closest_id_found = -1;
|
||||
|
||||
const int kart_x = kart->getXYZ()[0];
|
||||
const int kart_y = kart->getXYZ()[1];
|
||||
|
||||
for(int n=0; n<start_spots_amount; n++)
|
||||
{
|
||||
// no need for the overhead to compute exact distance with sqrt(), so using the
|
||||
// 'manhattan' heuristic which will do fine enough.
|
||||
const int dist_n = abs(kart_x - RaceManager::getTrack()->m_start_positions[n][0]) +
|
||||
abs(kart_y - RaceManager::getTrack()->m_start_positions[n][1]);
|
||||
if(dist_n < smallest_distance_found || closest_id_found == -1)
|
||||
{
|
||||
closest_id_found = n;
|
||||
smallest_distance_found = dist_n;
|
||||
}
|
||||
}
|
||||
|
||||
assert(closest_id_found != -1);
|
||||
|
||||
kart->setXYZ( Vec3(RaceManager::getTrack()->m_start_positions[closest_id_found]) );
|
||||
|
||||
// FIXME - implement heading
|
||||
// btQuaternion heading(btVector3(0.0f, 0.0f, 1.0f),
|
||||
// DEGREE_TO_RAD(RaceManager::getTrack()->m_angle[info.m_track_sector]) );
|
||||
// kart->setRotation(heading);
|
||||
|
||||
// A certain epsilon is added here to the Z coordinate (0.1), in case
|
||||
// that the points are somewhat under the track. Otherwise, the
|
||||
// kart will be placed a little bit under the track, triggering
|
||||
// a rescue, ...
|
||||
btTransform pos;
|
||||
pos.setOrigin(kart->getXYZ()+btVector3(0, 0, 0.5f*kart->getKartHeight()+0.1f));
|
||||
//pos.setRotation(btQuaternion(btVector3(0.0f, 0.0f, 1.0f),
|
||||
// DEGREE_TO_RAD(RaceManager::getTrack()->m_angle[info.m_track_sector])));
|
||||
|
||||
body->setCenterOfMassTransform(pos);
|
||||
|
||||
}
|
63
src/modes/three_strikes_battle.hpp
Normal file
63
src/modes/three_strikes_battle.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
// $Id: world.hpp 2326 2008-10-04 18:50:45Z auria $
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004 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 THREE_STRIKES_HPP
|
||||
#define THREE_STRIKES_HPP
|
||||
|
||||
#include "modes/world.hpp"
|
||||
#include <string>
|
||||
|
||||
class KartIconDisplayInfo;
|
||||
|
||||
struct BattleInfo
|
||||
{
|
||||
int m_lives;
|
||||
};
|
||||
|
||||
class ThreeStrikesBattle : public World
|
||||
{
|
||||
KartIconDisplayInfo* m_kart_display_info;
|
||||
|
||||
/** This vector contains an 'BattleInfo' struct for every kart in the race.
|
||||
*/
|
||||
std::vector<BattleInfo> m_kart_info;
|
||||
|
||||
public:
|
||||
ThreeStrikesBattle();
|
||||
virtual ~ThreeStrikesBattle();
|
||||
|
||||
// clock events
|
||||
virtual void onGo();
|
||||
virtual void terminateRace();
|
||||
|
||||
// overriding World methods
|
||||
virtual void update(float delta);
|
||||
virtual void restartRace();
|
||||
//virtual void getDefaultCollectibles(int& collectible_type, int& amount);
|
||||
//virtual bool useRedHerring();
|
||||
virtual bool useFastMusicNearEnd() const { return false; }
|
||||
virtual KartIconDisplayInfo* getKartsDisplayInfo(const RaceGUI* caller);
|
||||
virtual bool raceHasLaps(){ return false; }
|
||||
virtual void moveKartAfterRescue(Kart* kart, btRigidBody* body);
|
||||
|
||||
virtual std::string getInternalCode() const;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -98,7 +98,7 @@ World::World() : TimedRace()
|
||||
for(unsigned int i=0; i<race_manager->getNumKarts(); i++)
|
||||
{
|
||||
int position = i+1; // position start with 1
|
||||
btTransform init_pos=m_track->getStartTransform(position);
|
||||
btTransform init_pos=m_track->getStartTransform(i);
|
||||
Kart* newkart;
|
||||
const std::string& kart_name = race_manager->getKartName(i);
|
||||
int local_player_id = race_manager->getKartLocalPlayerId(i);
|
||||
|
@ -104,7 +104,6 @@ protected:
|
||||
*/
|
||||
bool m_use_highscores;
|
||||
|
||||
//void updateRacePosition(int k);
|
||||
void updateHighscores ();
|
||||
void loadTrack ();
|
||||
void resetAllKarts ();
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "network/network_manager.hpp"
|
||||
#include "modes/standard_race.hpp"
|
||||
#include "modes/follow_the_leader.hpp"
|
||||
#include "modes/three_strikes_battle.hpp"
|
||||
|
||||
RaceManager* race_manager= NULL;
|
||||
|
||||
@ -262,6 +263,7 @@ void RaceManager::startNextRace()
|
||||
// and need world to be defined.
|
||||
if(m_minor_mode==MINOR_MODE_FOLLOW_LEADER) new FollowTheLeaderRace();
|
||||
else if(m_minor_mode==MINOR_MODE_QUICK_RACE || m_minor_mode==MINOR_MODE_TIME_TRIAL) new StandardRace();
|
||||
else if(m_minor_mode==MINOR_MODE_3_STRIKES) new ThreeStrikesBattle();
|
||||
else{ fprintf(stderr,"Could not create given race mode\n"); assert(0); }
|
||||
|
||||
m_active_race = true;
|
||||
|
@ -84,7 +84,7 @@ public:
|
||||
MINOR_MODE_TIME_TRIAL = LINEAR_RACE(1, true),
|
||||
MINOR_MODE_FOLLOW_LEADER = LINEAR_RACE(2, false),
|
||||
|
||||
MINOR_MODE_LAST_ALIVE = BATTLE_ARENA(0)
|
||||
MINOR_MODE_3_STRIKES = BATTLE_ARENA(0)
|
||||
};
|
||||
#undef LINEAR_RACE
|
||||
#undef BATTLE_ARENA
|
||||
|
@ -67,7 +67,7 @@ Track::Track( std::string filename_, float w, float h, bool stretch )
|
||||
m_screenshot = "";
|
||||
m_top_view = "";
|
||||
m_has_final_camera = false;
|
||||
|
||||
m_is_arena = false;
|
||||
loadTrack(m_filename);
|
||||
loadDriveline();
|
||||
|
||||
@ -419,26 +419,38 @@ const Vec3& Track::trackToSpatial(const int SECTOR ) const
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Returns the start coordinates for a kart on a given position pos
|
||||
(with 0<=pos).
|
||||
*/
|
||||
btTransform Track::getStartTransform(unsigned int pos) const {
|
||||
// Bug fix/workaround: sometimes the first kart would be too close
|
||||
// to the first driveline point and not to the last one -->
|
||||
// This kart would not get any lap counting done in the first
|
||||
// lap! Therefor -1.5 is subtracted from the y position - which
|
||||
// is a somewhat arbitrary value.
|
||||
Vec3 orig;
|
||||
pos--; // adjust from "1 to n" index to "0 to n-1"
|
||||
orig.setX( pos<m_start_x.size() ? m_start_x[pos] : ((pos%2==0)?1.5f:-1.5f) );
|
||||
orig.setY( pos<m_start_y.size() ? m_start_y[pos] : -1.5f*pos-1.5f );
|
||||
orig.setZ( pos<m_start_z.size() ? m_start_z[pos] : 1.0f );
|
||||
btTransform start;
|
||||
start.setOrigin(orig);
|
||||
start.setRotation(btQuaternion(btVector3(0, 0, 1),
|
||||
pos<m_start_heading.size()
|
||||
? DEGREE_TO_RAD(m_start_heading[pos])
|
||||
: 0.0f ));
|
||||
return start;
|
||||
(with pos ranging from 0 to kart_num-1).
|
||||
*/
|
||||
btTransform Track::getStartTransform(unsigned int pos) const
|
||||
{
|
||||
|
||||
Vec3 orig;
|
||||
|
||||
if(isArena())
|
||||
{
|
||||
assert(pos < m_start_positions.size());
|
||||
orig.setX( m_start_positions[pos][0] );
|
||||
orig.setY( m_start_positions[pos][1] );
|
||||
orig.setZ( m_start_positions[pos][2] );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bug fix/workaround: sometimes the first kart would be too close
|
||||
// to the first driveline point and not to the last one -->
|
||||
// This kart would not get any lap counting done in the first
|
||||
// lap! Therefor -1.5 is subtracted from the y position - which
|
||||
// is a somewhat arbitrary value.
|
||||
orig.setX( pos<m_start_x.size() ? m_start_x[pos] : ((pos%2==0)?1.5f:-1.5f) );
|
||||
orig.setY( pos<m_start_y.size() ? m_start_y[pos] : -1.5f*pos-1.5f );
|
||||
orig.setZ( pos<m_start_z.size() ? m_start_z[pos] : 1.0f );
|
||||
}
|
||||
btTransform start;
|
||||
start.setOrigin(orig);
|
||||
start.setRotation(btQuaternion(btVector3(0, 0, 1),
|
||||
pos<m_start_heading.size()
|
||||
? DEGREE_TO_RAD(m_start_heading[pos])
|
||||
: 0.0f ));
|
||||
return start;
|
||||
} // getStartTransform
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -845,6 +857,7 @@ void Track::loadTrack(std::string filename_)
|
||||
LISP->get ("sun-specular", m_specular_col);
|
||||
LISP->get ("sun-diffuse", m_diffuse_col);
|
||||
LISP->get ("gravity", m_gravity);
|
||||
LISP->get ("arena", m_is_arena);
|
||||
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);
|
||||
@ -1164,7 +1177,7 @@ void Track::loadTrackModel()
|
||||
int need_hat = false ;
|
||||
int fit_skin = false ;
|
||||
char fname [ 1024 ] ;
|
||||
sgCoord loc ;
|
||||
sgCoord loc;
|
||||
sgZeroVec3 ( loc.xyz ) ;
|
||||
sgZeroVec3 ( loc.hpr ) ;
|
||||
|
||||
@ -1180,6 +1193,11 @@ void Track::loadTrackModel()
|
||||
{
|
||||
herring_command (&loc.xyz, htype, true) ;
|
||||
}
|
||||
else if ( sscanf ( s, "START,%f,%f,%f",
|
||||
&(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]) ) == 3 )
|
||||
{
|
||||
m_start_positions.push_back(Vec3(loc.xyz[0], loc.xyz[1], loc.xyz[2]));
|
||||
}
|
||||
else if ( s[0] == '\"' )
|
||||
{
|
||||
if ( sscanf ( s, "\"%[^\"]\",%f,%f,%f,%f,%f,%f",
|
||||
|
@ -62,6 +62,8 @@ private:
|
||||
bool m_has_final_camera;
|
||||
Vec3 m_camera_final_position;
|
||||
Vec3 m_camera_final_hpr;
|
||||
bool m_is_arena;
|
||||
|
||||
public:
|
||||
enum RoadSide{ RS_DONT_KNOW = -1, RS_LEFT = 0, RS_RIGHT = 1 };
|
||||
|
||||
@ -104,7 +106,10 @@ public:
|
||||
std::vector<SGfloat> m_distance_from_start;
|
||||
std::vector<SGfloat> m_path_width;
|
||||
std::vector<SGfloat> m_angle;
|
||||
|
||||
|
||||
/** Start positions for arenas (unused in linear races) */
|
||||
std::vector<Vec3> m_start_positions;
|
||||
|
||||
//Left and Right drivelines for overhead map rendering.
|
||||
//(Should probably be private as they are only use internally right now)
|
||||
std::vector<Vec3> m_left_driveline;
|
||||
@ -126,6 +131,7 @@ public:
|
||||
Track (std::string filename,float w=100,
|
||||
float h=100, bool stretch=1);
|
||||
~Track ();
|
||||
bool isArena () const { return m_is_arena; }
|
||||
void cleanup ();
|
||||
void addDebugToScene (int type ) const;
|
||||
void draw2Dview (float x_offset,
|
||||
|
@ -115,7 +115,7 @@ std::vector<std::string> TrackManager::getAllTrackIdentifiers()
|
||||
} // getAllTrackNames
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Loads all track from the track directory (data/track).
|
||||
/** Loads all tracks from the track directory (data/track).
|
||||
*/
|
||||
void TrackManager::loadTrackList ()
|
||||
{
|
||||
@ -155,11 +155,19 @@ void TrackManager::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++)
|
||||
const bool isArena = track->isArena();
|
||||
|
||||
const unsigned int groups_amount = new_groups.size();
|
||||
for(unsigned int i=0; i<groups_amount; i++)
|
||||
{
|
||||
if(m_groups.find(new_groups[i])==m_groups.end())
|
||||
// if we didn't yet have this group in memory, add it to the global list
|
||||
if(m_groups.find(new_groups[i])==m_groups.end() &&
|
||||
m_arena_groups.find(new_groups[i])==m_arena_groups.end())
|
||||
m_all_groups.push_back(new_groups[i]);
|
||||
m_groups[new_groups[i]].push_back(m_tracks.size()-1);
|
||||
|
||||
// add this track to its group
|
||||
if(isArena) m_arena_groups[new_groups[i]].push_back(m_tracks.size()-1);
|
||||
else m_groups[new_groups[i]].push_back(m_tracks.size()-1);
|
||||
}
|
||||
} // updateGroups
|
||||
|
||||
|
@ -34,6 +34,7 @@ private:
|
||||
typedef std::vector<Track*> Tracks;
|
||||
Tracks m_tracks;
|
||||
std::map<std::string, std::vector<int> > m_groups;
|
||||
std::map<std::string, std::vector<int> > m_arena_groups;
|
||||
std::vector<std::string> m_all_groups;
|
||||
/** Flag if this track is available or not. Tracks are set unavailable
|
||||
* if they are not available on all clients (applies only to network mode)
|
||||
@ -56,6 +57,8 @@ public:
|
||||
bool isAvailable(unsigned int n) const {return m_track_avail[n];}
|
||||
const std::vector<int>&
|
||||
getTracksInGroup(const std::string& g) {return m_groups[g];}
|
||||
const std::vector<int>&
|
||||
getArenasInGroup(const std::string& g) {return m_arena_groups[g];}
|
||||
std::vector<std::string> getAllTrackIdentifiers();
|
||||
/** load all .track files from all directories */
|
||||
void loadTrackList ();
|
||||
|
Loading…
Reference in New Issue
Block a user