diff --git a/src/Makefile.am b/src/Makefile.am index 9d3fbf61a..0008172bb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/gui/game_mode.cpp b/src/gui/game_mode.cpp index 7a84d84dd..76ce09dd9 100644 --- a/src/gui/game_mode.cpp +++ b/src/gui/game_mode.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 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); diff --git a/src/gui/race_gui.cpp b/src/gui/race_gui.cpp index 047c0e45e..78c9f6634 100644 --- a/src/gui/race_gui.cpp +++ b/src/gui/race_gui.cpp @@ -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); diff --git a/src/gui/race_gui.hpp b/src/gui/race_gui.hpp index b19abcb9d..85a65a3d7 100644 --- a/src/gui/race_gui.hpp +++ b/src/gui/race_gui.hpp @@ -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 diff --git a/src/gui/track_sel.cpp b/src/gui/track_sel.cpp index 2e12703aa..95a9ee1b2 100644 --- a/src/gui/track_sel.cpp +++ b/src/gui/track_sel.cpp @@ -150,6 +150,8 @@ void TrackSel::switchGroup() m_index_avail_tracks.clear(); const std::vector &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& groups=track_manager->getAllGroups(); - for(int i =0; i<(int)groups.size(); i++) + const int group_size = (int)groups.size(); + for(int i =0; im_track_group) m_index_avail_tracks.push_back(-i-1); diff --git a/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj b/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj index 5fbfbacf4..1c5fdcabd 100644 --- a/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj +++ b/src/ide/Xcode/STK_XCode.xcodeproj/project.pbxproj @@ -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 = ""; }; 956F3FAD0E85BE0E006F93B0 /* ssg_help.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ssg_help.cpp; sourceTree = ""; }; 956F3FAE0E85BE0E006F93B0 /* ssg_help.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; path = ssg_help.hpp; sourceTree = ""; }; + 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 = ""; }; + 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 = ""; }; 957B11B30E831DA8002A69EA /* standard_race.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = standard_race.hpp; path = modes/standard_race.hpp; sourceTree = ""; }; 957B11B40E831DA8002A69EA /* standard_race.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = standard_race.cpp; path = modes/standard_race.cpp; sourceTree = ""; }; 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 = ""; }; @@ -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 = ""; @@ -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; }; diff --git a/src/modes/linear_world.hpp b/src/modes/linear_world.hpp index a7eb92f3b..10b17b4ee 100644 --- a/src/modes/linear_world.hpp +++ b/src/modes/linear_world.hpp @@ -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; } }; diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp new file mode 100644 index 000000000..4e6d04bc8 --- /dev/null +++ b/src/modes/three_strikes_battle.cpp @@ -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 + +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; nsetPosition(-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; iresetBrakes(); + } +} +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; nm_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); + +} \ No newline at end of file diff --git a/src/modes/three_strikes_battle.hpp b/src/modes/three_strikes_battle.hpp new file mode 100644 index 000000000..239b30c66 --- /dev/null +++ b/src/modes/three_strikes_battle.hpp @@ -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 + +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 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 \ No newline at end of file diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 6a9084f6b..433aba83b 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -98,7 +98,7 @@ World::World() : TimedRace() for(unsigned int i=0; igetNumKarts(); 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); diff --git a/src/modes/world.hpp b/src/modes/world.hpp index 9937169cb..c133290e1 100644 --- a/src/modes/world.hpp +++ b/src/modes/world.hpp @@ -104,7 +104,6 @@ protected: */ bool m_use_highscores; - //void updateRacePosition(int k); void updateHighscores (); void loadTrack (); void resetAllKarts (); diff --git a/src/race_manager.cpp b/src/race_manager.cpp index 26f8bc11d..fe8f823e5 100644 --- a/src/race_manager.cpp +++ b/src/race_manager.cpp @@ -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; diff --git a/src/race_manager.hpp b/src/race_manager.hpp index cfd5a26e1..d0d7c1993 100644 --- a/src/race_manager.hpp +++ b/src/race_manager.hpp @@ -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 diff --git a/src/track.cpp b/src/track.cpp index 01d843174..c83c9813b 100644 --- a/src/track.cpp +++ b/src/track.cpp @@ -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 + // 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( posget ("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", diff --git a/src/track.hpp b/src/track.hpp index 63ee884e9..90f3b54dd 100644 --- a/src/track.hpp +++ b/src/track.hpp @@ -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 m_distance_from_start; std::vector m_path_width; std::vector m_angle; - + + /** Start positions for arenas (unused in linear races) */ + std::vector 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 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, diff --git a/src/track_manager.cpp b/src/track_manager.cpp index a60e7d9eb..2cf61e143 100644 --- a/src/track_manager.cpp +++ b/src/track_manager.cpp @@ -115,7 +115,7 @@ std::vector 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& new_groups = track->getGroups(); - for(unsigned int i=0; iisArena(); + + const unsigned int groups_amount = new_groups.size(); + for(unsigned int i=0; i Tracks; Tracks m_tracks; std::map > m_groups; + std::map > m_arena_groups; std::vector 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& getTracksInGroup(const std::string& g) {return m_groups[g];} + const std::vector& + getArenasInGroup(const std::string& g) {return m_arena_groups[g];} std::vector getAllTrackIdentifiers(); /** load all .track files from all directories */ void loadTrackList ();