1 // 2 // SuperTuxKart - a fun racing game with go-kart 3 // Copyright (C) 2006-2015 SuperTuxKart-Team 4 // 5 // This program is free software; you can redistribute it and/or 6 // modify it under the terms of the GNU General Public License 7 // as published by the Free Software Foundation; either version 3 8 // of the License, or (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 #ifndef HEADER_RACEMANAGER_HPP 20 #define HEADER_RACEMANAGER_HPP 21 22 /** 23 * \defgroup race 24 * Contains the race information that is conceptually above what you can find 25 * in group Modes. Handles highscores, grands prix, number of karts, which 26 * track was selected, etc. 27 */ 28 29 #include <vector> 30 #include <algorithm> 31 #include <string> 32 33 #include "network/remote_kart_info.hpp" 34 #include "race/grand_prix_data.hpp" 35 #include "utils/vec3.hpp" 36 37 class AbstractKart; 38 class NetworkString; 39 class SavedGrandPrix; 40 class Track; 41 42 static const std::string IDENT_STD ("STANDARD" ); 43 static const std::string IDENT_TTRIAL ("STD_TIMETRIAL" ); 44 static const std::string IDENT_FTL ("FOLLOW_LEADER" ); 45 static const std::string IDENT_STRIKES ("BATTLE_3_STRIKES"); 46 static const std::string IDENT_FFA ("BATTLE_FFA" ); 47 static const std::string IDENT_CTF ("BATTLE_CTF" ); 48 static const std::string IDENT_EASTER ("EASTER_EGG_HUNT" ); 49 static const std::string IDENT_SOCCER ("SOCCER" ); 50 static const std::string IDENT_GHOST ("GHOST" ); 51 static const std::string IDENT_OVERWORLD("OVERWORLD" ); 52 static const std::string IDENT_CUTSCENE ("CUTSCENE" ); 53 54 /** 55 * The race manager has two functions: 56 * 1) it stores information about the race the user selected (e.g. number 57 * of karts, track, race mode etc.). Most of the values are just stored 58 * from the menus, and just read back, except for GP mode (the race 59 * manager stores the GP information, but World queries only track 60 * and number of laps, so in case of GP this information is taken from 61 * the GrandPrix object), and local player information (number of local 62 * players, and selected karts). 63 * Information about player karts (which player selected which kart, 64 * player ids) is stored in a RemoteKartInfo structure and used later 65 * to initialise the KartStatus array (startNew()). The KartStatus array 66 * stores information about all karts (player and AI), and is used to 67 * determine the order in which karts are started (see startNextRace()). 68 * 2) when a race is started, it creates the world, and keeps track of 69 * score during the race. When a race is finished, it deletes the world, 70 * and (depending on race mode) starts the next race by creating a new 71 * world. 72 * Information in the RaceManager is considered to be 'more static', sometimes 73 * the world has similar functions showing the current state. E.g.: the 74 * race manager keeps track of the number of karts with which the race was 75 * started, while world keeps track of the number of karts currently in the 76 * race (consider a race mode like follow the leader where karts can get 77 * eliminated, but still the RaceManager has to accumulate points for those 78 * karts). 79 * The race manager handles all race types as a kind of grand prix. E.g.: 80 * a quick race is basically a GP with only one track (so the race manager 81 * keeps track of scores even though no scores are used in a quick race). 82 * 83 * \ingroup race 84 */ 85 class RaceManager 86 { 87 public: 88 /** The major types or races supported in STK 89 */ 90 enum MajorRaceModeType 91 { 92 MAJOR_MODE_GRAND_PRIX = 0, 93 MAJOR_MODE_SINGLE 94 }; 95 96 // quick method to tell the difference between battle modes and race modes 97 // think of it like a bitmask, but done in decimal to avoid endianness 98 // issues 99 #define LINEAR_RACE(ID, COUNT_LAPSES) (1000+ID+100*COUNT_LAPSES) 100 #define BATTLE_ARENA(ID) (2000+ID) 101 #define EASTER_EGG(ID) (3000+ID) 102 #define MISC(ID) (4000+ID) 103 104 // ---------------------------------------------------------------------------------------- 105 /** Minor variants to the major types of race. 106 * Make sure to use the 'LINEAR_RACE/BATTLE_ARENA' macros. */ 107 enum MinorRaceModeType 108 { 109 MINOR_MODE_NONE = -1, 110 111 MINOR_MODE_NORMAL_RACE = LINEAR_RACE(0, true), 112 MINOR_MODE_TIME_TRIAL = LINEAR_RACE(1, true), 113 MINOR_MODE_FOLLOW_LEADER = LINEAR_RACE(2, false), 114 115 MINOR_MODE_3_STRIKES = BATTLE_ARENA(0), 116 MINOR_MODE_FREE_FOR_ALL = BATTLE_ARENA(1), 117 MINOR_MODE_CAPTURE_THE_FLAG = BATTLE_ARENA(2), 118 MINOR_MODE_SOCCER = BATTLE_ARENA(3), 119 120 MINOR_MODE_EASTER_EGG = EASTER_EGG(0), 121 122 MINOR_MODE_OVERWORLD = MISC(0), 123 MINOR_MODE_TUTORIAL = MISC(1), 124 MINOR_MODE_CUTSCENE = MISC(2) 125 }; 126 127 // ---------------------------------------------------------------------------------------- 128 /** True if the AI should have additional abbilities, e.g. 129 * nolok will get special bubble gums in the final challenge. */ 130 enum AISuperPower 131 { 132 SUPERPOWER_NONE = 0, 133 SUPERPOWER_NOLOK_BOSS = 1 134 }; 135 136 // ---------------------------------------------------------------------------------------- 137 /** Returns a string identifier for each minor race mode. 138 * \param mode Minor race mode. 139 */ getIdentOf(const MinorRaceModeType mode)140 static const std::string& getIdentOf(const MinorRaceModeType mode) 141 { 142 switch (mode) 143 { 144 case MINOR_MODE_NORMAL_RACE: return IDENT_STD; 145 case MINOR_MODE_TIME_TRIAL: return IDENT_TTRIAL; 146 case MINOR_MODE_FOLLOW_LEADER: return IDENT_FTL; 147 case MINOR_MODE_3_STRIKES: return IDENT_STRIKES; 148 case MINOR_MODE_FREE_FOR_ALL: return IDENT_FFA; 149 case MINOR_MODE_CAPTURE_THE_FLAG: return IDENT_CTF; 150 case MINOR_MODE_EASTER_EGG: return IDENT_EASTER; 151 case MINOR_MODE_SOCCER: return IDENT_SOCCER; 152 default: assert(false); 153 return IDENT_STD; // stop compiler warning 154 } 155 } // getIdentOf 156 157 // ---------------------------------------------------------------------------------------- 158 /** Returns the icon for a minor race mode. 159 * \param mode Minor race mode. 160 */ getIconOf(const MinorRaceModeType mode)161 static const char* getIconOf(const MinorRaceModeType mode) 162 { 163 switch (mode) 164 { 165 case MINOR_MODE_NORMAL_RACE: return "/gui/icons/mode_normal.png"; 166 case MINOR_MODE_TIME_TRIAL: return "/gui/icons/mode_tt.png"; 167 case MINOR_MODE_FOLLOW_LEADER: return "/gui/icons/mode_ftl.png"; 168 case MINOR_MODE_3_STRIKES: return "/gui/icons/mode_3strikes.png"; 169 case MINOR_MODE_FREE_FOR_ALL: return "/gui/icons/mode_weapons.png"; 170 case MINOR_MODE_CAPTURE_THE_FLAG: return "/gui/icons/mode_weapons.png"; 171 case MINOR_MODE_EASTER_EGG: return "/gui/icons/mode_easter.png"; 172 case MINOR_MODE_SOCCER: return "/gui/icons/mode_soccer.png"; 173 default: assert(false); return NULL; 174 } 175 } // getIconOf 176 177 // ---------------------------------------------------------------------------------------- 178 static const core::stringw getNameOf(const MinorRaceModeType mode); 179 // ---------------------------------------------------------------------------------------- 180 /** Returns if the currently set minor game mode can be used by the AI. */ hasAI()181 bool hasAI() 182 { 183 switch (m_minor_mode) 184 { 185 case MINOR_MODE_NORMAL_RACE: return true; 186 case MINOR_MODE_TIME_TRIAL: return true; 187 case MINOR_MODE_FOLLOW_LEADER: return true; 188 case MINOR_MODE_3_STRIKES: return true; 189 case MINOR_MODE_FREE_FOR_ALL: return false; 190 case MINOR_MODE_CAPTURE_THE_FLAG: return false; 191 case MINOR_MODE_EASTER_EGG: return false; 192 case MINOR_MODE_SOCCER: return true; 193 default: assert(false); return false; 194 } 195 } // hasAI 196 197 198 // ---------------------------------------------------------------------------------------- 199 /** Returns the minor mode id from a string identifier. This function is 200 * used from challenge_data, which reads the mode from a challenge file. 201 * \param name The name of the minor mode. 202 */ getModeIDFromInternalName(const std::string & name)203 static const MinorRaceModeType getModeIDFromInternalName( 204 const std::string &name) 205 { 206 if (name==IDENT_STD ) return MINOR_MODE_NORMAL_RACE; 207 else if (name==IDENT_TTRIAL ) return MINOR_MODE_TIME_TRIAL; 208 else if (name==IDENT_FTL ) return MINOR_MODE_FOLLOW_LEADER; 209 else if (name==IDENT_STRIKES) return MINOR_MODE_3_STRIKES; 210 else if (name==IDENT_FFA) return MINOR_MODE_FREE_FOR_ALL; 211 else if (name==IDENT_CTF) return MINOR_MODE_CAPTURE_THE_FLAG; 212 else if (name==IDENT_EASTER ) return MINOR_MODE_EASTER_EGG; 213 else if (name==IDENT_SOCCER) return MINOR_MODE_SOCCER; 214 215 assert(0); 216 return MINOR_MODE_NONE; 217 } 218 219 #undef LINEAR_RACE 220 #undef BATTLE_ARENA 221 #undef MISC 222 223 /** Game difficulty. */ 224 enum Difficulty { DIFFICULTY_EASY = 0, 225 DIFFICULTY_FIRST = DIFFICULTY_EASY, 226 DIFFICULTY_MEDIUM, 227 DIFFICULTY_HARD, 228 DIFFICULTY_BEST, 229 DIFFICULTY_LAST = DIFFICULTY_BEST, 230 DIFFICULTY_COUNT, 231 DIFFICULTY_NONE}; 232 233 /** Different kart types: A local player, a player connected via network, 234 * an AI kart, the leader kart (currently not used), a ghost kart and 235 * spare tire karts which allow gain life in battle mode */ 236 enum KartType { KT_PLAYER, KT_NETWORK_PLAYER, KT_AI, KT_LEADER, 237 KT_GHOST, KT_SPARE_TIRE }; 238 private: 239 240 bool m_started_from_overworld; 241 242 public: 243 244 /** This data structure accumulates kart data and race result data from 245 * each race. */ 246 struct KartStatus 247 { 248 /** The kart identifier. */ 249 std::string m_ident; 250 /** For networked karts. */ 251 std::string m_player_name; 252 // Score for this kart. */ 253 int m_score; 254 /** Needed for restart race, and for race results GUI. */ 255 int m_last_score; 256 /** Sum of times of all races. */ 257 float m_overall_time; 258 /** Needed for restart. */ 259 float m_last_time; 260 /** Kart type: AI, player, network player etc. */ 261 KartType m_kart_type; 262 /** Player controling the kart, for AI: -1 */ 263 int m_local_player_id; 264 /** Global ID of player. */ 265 int m_global_player_id; 266 /** In GPs, at the end, will hold the overall rank of this kart 267 * (0<=m_gp_rank < num_karts-1). */ 268 int m_gp_rank; 269 /** Boosted status (AI only). */ 270 bool m_boosted_ai; 271 /** The handicap for this player. */ 272 HandicapLevel m_handicap; 273 /** Kart color of player (used in gp win / lose screen). */ 274 float m_color; KartStatusRaceManager::KartStatus275 KartStatus(const std::string& ident, const int& prev_finish_pos, 276 int local_player_id, int global_player_id, 277 int init_gp_rank, KartType kt, 278 HandicapLevel handicap) : 279 m_ident(ident), m_score(0), m_last_score(0), 280 m_overall_time(0.0f), m_last_time(0.0f), 281 m_kart_type(kt), 282 m_local_player_id(local_player_id), 283 m_global_player_id(global_player_id), 284 m_gp_rank(init_gp_rank), m_handicap(handicap) 285 { m_boosted_ai = false; m_color = 0.0f; } 286 287 }; // KartStatus 288 private: 289 290 /** The kart status data for each kart. */ 291 std::vector<KartStatus> m_kart_status; 292 293 /** The selected difficulty. */ 294 Difficulty m_difficulty; 295 296 /** The major mode (single race, GP). */ 297 MajorRaceModeType m_major_mode; 298 299 /** The minor mode (race, time trial, ftl, battle mode). */ 300 MinorRaceModeType m_minor_mode; 301 /** Stores remote kart information about all player karts. */ 302 std::vector<RemoteKartInfo> m_player_karts; 303 std::vector<std::string> m_tracks; 304 305 /** Number of local players. */ 306 unsigned int m_num_local_players; 307 308 /** The number of laps for each track of a GP (only one element 309 * is used if only a single track is used. */ 310 std::vector<int> m_num_laps; 311 312 /** Whether a track should be reversed */ 313 std::vector<bool> m_reverse_track; 314 315 /** The list of default AI karts to use. This is from the command line. */ 316 std::vector<std::string> m_default_ai_list; 317 318 /** If set, specifies which kart to use for AI(s) */ 319 std::string m_ai_kart_override; 320 321 AISuperPower m_ai_superpower; 322 323 /** The list of AI karts to use. This is stored here so that the 324 * same list of AIs is used for all tracks of a GP. */ 325 std::vector<std::string> m_ai_kart_list; 326 int m_track_number; 327 GrandPrixData m_grand_prix; 328 SavedGrandPrix* m_saved_gp; 329 int m_num_karts; 330 unsigned int m_num_red_ai; 331 unsigned int m_num_blue_ai; 332 unsigned int m_num_ghost_karts; 333 unsigned int m_num_spare_tire_karts; 334 unsigned int m_num_finished_karts; 335 unsigned int m_num_finished_players; 336 unsigned m_flag_return_ticks; 337 unsigned m_flag_deactivated_ticks; 338 int m_coin_target; 339 float m_time_target; 340 int m_goal_target; 341 int m_hit_capture_limit; 342 void startNextRace(); // start a next race 343 operator <(const KartStatus & left,const KartStatus & right)344 friend bool operator< (const KartStatus& left, const KartStatus& right) 345 { 346 return (left.m_score < right.m_score) || 347 (left.m_score == right.m_score && 348 left.m_overall_time > right.m_overall_time); 349 } 350 351 bool m_have_kart_last_position_on_overworld; 352 Vec3 m_kart_last_position_on_overworld; 353 354 /** Determines if saved GP should be continued or not*/ 355 bool m_continue_saved_gp; 356 357 bool m_is_recording_race; 358 359 bool m_has_ghost_karts; 360 361 bool m_watching_replay; 362 public: 363 // ---------------------------------------------------------------------------------------- 364 static RaceManager* get(); 365 // ---------------------------------------------------------------------------------------- 366 static void create(); 367 // ---------------------------------------------------------------------------------------- 368 static void destroy(); 369 // ---------------------------------------------------------------------------------------- 370 static void clear(); 371 // ---------------------------------------------------------------------------------------- 372 RaceManager(); 373 ~RaceManager(); 374 375 void reset(); 376 void setPlayerKart(unsigned int player_id, const std::string &kart_name); 377 void setPlayerKart(unsigned int player_id, 378 const RemoteKartInfo& ki); 379 380 /** Sets additional information for a player to indicate which team it belong to 381 */ 382 void setKartTeam(unsigned int player_id, KartTeam team); 383 384 /** Sets the handicap for a player. 385 */ 386 void setPlayerHandicap(unsigned int player_id, HandicapLevel handicap); 387 388 /** In case of non GP mode set the track to use. 389 * \param track Pointer to the track to use. 390 */ 391 void setTrack(const std::string& track); 392 393 /** \brief Returns the kart with a given GP rank (or NULL if no such 394 * kart exists). 395 * \param n Rank (0<=n<num_karts) to look for. 396 */ 397 const AbstractKart* getKartWithGPRank(unsigned int n); 398 399 /** \return the GP rank of a local player, or -1 if the given player ID 400 * doesn't exist */ 401 int getLocalPlayerGPRank(const int playerID) const; 402 403 404 /** Sort karts and update the m_gp_rank KartStatus member, in preparation 405 * for future calls to RaceManager::getKartGPRank or 406 * RaceManager::getKartWithGPRank 407 */ 408 void computeGPRanks(); 409 410 /** \brief Sets the difficulty. 411 * \param diff Difficulty. 412 */ 413 void setDifficulty(Difficulty diff); 414 static Difficulty convertDifficulty(const std::string &difficulty); 415 void startNew(bool from_overworld); 416 void next(); 417 void rerunRace(); 418 void exitRace(bool delete_world=true); 419 void startGP(const GrandPrixData &gp, bool from_overworld, 420 bool continue_saved_gp); 421 void saveGP(); 422 void startSingleRace(const std::string &track_ident, const int num_laps, 423 bool from_overworld); 424 void startWatchingReplay(const std::string &track_ident, const int num_laps); 425 void setupPlayerKartInfo(); 426 void kartFinishedRace(const AbstractKart* kart, float time); 427 void setNumPlayers(int players, int local_players=-1); 428 void setDefaultAIKartList(const std::vector<std::string> &ai_list); 429 void computeRandomKartList(); 430 431 // ---------------------------------------------------------------------------------------- hasTimeTarget() const432 bool hasTimeTarget() const { return m_time_target > 0.0f; } 433 // ---------------------------------------------------------------------------------------- setMaxGoal(int max_goal)434 void setMaxGoal(int max_goal) 435 { 436 m_time_target = 0.0f; 437 m_goal_target = max_goal; 438 } // setMaxGoal 439 // ---------------------------------------------------------------------------------------- getMaxGoal()440 int getMaxGoal(){ return m_goal_target; } 441 // ---------------------------------------------------------------------------------------- setCoinTarget(int num)442 void setCoinTarget(int num) { m_coin_target = num; } 443 // ---------------------------------------------------------------------------------------- setGrandPrix(const GrandPrixData & gp)444 void setGrandPrix(const GrandPrixData &gp) 445 { 446 m_grand_prix = gp; 447 setCoinTarget(0); 448 } // setGrandPrix 449 // ---------------------------------------------------------------------------------------- setAIKartOverride(const std::string & kart)450 void setAIKartOverride(const std::string& kart) 451 { 452 m_ai_kart_override = kart; 453 } // setAIKartOverride 454 // ---------------------------------------------------------------------------------------- setAISuperPower(AISuperPower superpower)455 void setAISuperPower(AISuperPower superpower) 456 { 457 m_ai_superpower = superpower; 458 } // setAISuperPower 459 // ---------------------------------------------------------------------------------------- getAISuperPower() const460 AISuperPower getAISuperPower() const { return m_ai_superpower; } 461 // ---------------------------------------------------------------------------------------- setNumLaps(int num)462 void setNumLaps(int num) 463 { 464 m_num_laps.clear(); 465 m_num_laps.push_back(num); 466 } // setNumLaps 467 // ---------------------------------------------------------------------------------------- setReverseTrack(bool r_t)468 void setReverseTrack(bool r_t) 469 { 470 m_reverse_track.clear(); 471 m_reverse_track.push_back(r_t); 472 } // setReverseTrack 473 // ---------------------------------------------------------------------------------------- setMajorMode(MajorRaceModeType mode)474 void setMajorMode(MajorRaceModeType mode) { m_major_mode = mode; } 475 // ---------------------------------------------------------------------------------------- setMinorMode(MinorRaceModeType mode)476 void setMinorMode(MinorRaceModeType mode) 477 { 478 m_minor_mode = mode; 479 } // setMinorMode 480 // ---------------------------------------------------------------------------------------- setNumKarts(int num)481 void setNumKarts(int num) 482 { 483 m_num_karts = num; 484 m_ai_kart_override = ""; 485 m_ai_superpower = SUPERPOWER_NONE; 486 } // setNumKarts 487 // ---------------------------------------------------------------------------------------- setNumRedAI(unsigned int num)488 void setNumRedAI(unsigned int num) 489 { 490 m_num_red_ai = num; 491 } // setNumRedAI 492 // ---------------------------------------------------------------------------------------- setNumBlueAI(unsigned int num)493 void setNumBlueAI(unsigned int num) 494 { 495 m_num_blue_ai = num; 496 } // setNumBlueAI 497 // ---------------------------------------------------------------------------------------- setTimeTarget(float time)498 void setTimeTarget(float time) 499 { 500 m_goal_target = 0; 501 m_time_target = time; 502 } // setTimeTarget 503 // ---------------------------------------------------------------------------------------- getKartInfo(unsigned int n)504 RemoteKartInfo& getKartInfo(unsigned int n) 505 { 506 return m_player_karts[n]; 507 } // getKartInfo 508 // ---------------------------------------------------------------------------------------- getNumLocalPlayers() const509 unsigned int getNumLocalPlayers() const 510 { 511 return m_num_local_players; 512 } // getNumLocalPlayers 513 514 // ---------------------------------------------------------------------------------------- 515 /** Returns true if the split screen display leaves an empty space that 516 * can be used to display the minimap. 517 */ getIfEmptyScreenSpaceExists() const518 bool getIfEmptyScreenSpaceExists() const 519 { 520 const float sqrt_num_players = sqrtf((float)getNumLocalPlayers()); 521 const int rows = (int)ceil(sqrt_num_players); 522 const int cols = (int)round(sqrt_num_players); 523 const int total_spaces = rows * cols; 524 return (total_spaces - getNumLocalPlayers() > 0); 525 } // getIfEmptyScreenSpaceExists 526 // ---------------------------------------------------------------------------------------- 527 /** Returns the selected number of karts (selected number of players and 528 * AI karts. */ getNumberOfKarts() const529 unsigned int getNumberOfKarts() const { return m_num_karts; } 530 // ---------------------------------------------------------------------------------------- getNumberOfAIKarts() const531 unsigned int getNumberOfAIKarts() const 532 { 533 return (unsigned int)m_ai_kart_list.size(); 534 } // getNumberOfAIKarts 535 // ---------------------------------------------------------------------------------------- getNumberOfRedAIKarts() const536 unsigned int getNumberOfRedAIKarts() const { return m_num_red_ai; } 537 // ---------------------------------------------------------------------------------------- getNumberOfBlueAIKarts() const538 unsigned int getNumberOfBlueAIKarts() const { return m_num_blue_ai; } 539 // ---------------------------------------------------------------------------------------- getNumNonGhostKarts() const540 unsigned int getNumNonGhostKarts() const 541 { return m_num_karts - m_num_ghost_karts; } 542 // ---------------------------------------------------------------------------------------- getMajorMode() const543 MajorRaceModeType getMajorMode() const { return m_major_mode; } 544 // ---------------------------------------------------------------------------------------- getMinorMode() const545 MinorRaceModeType getMinorMode() const { return m_minor_mode; } 546 // ---------------------------------------------------------------------------------------- getMinorModeName() const547 std::string getMinorModeName() const 548 { 549 switch (m_minor_mode) 550 { 551 case MINOR_MODE_NORMAL_RACE: return "normal"; 552 case MINOR_MODE_TIME_TRIAL: return "time-trial"; 553 case MINOR_MODE_FOLLOW_LEADER: return "follow-the-leader"; 554 case MINOR_MODE_3_STRIKES: return "battle"; 555 case MINOR_MODE_FREE_FOR_ALL: return "ffa"; 556 case MINOR_MODE_CAPTURE_THE_FLAG: return "ctf"; 557 case MINOR_MODE_EASTER_EGG: return "egg-hunt"; 558 case MINOR_MODE_SOCCER: return "soccer"; 559 default: assert(false); return ""; 560 } 561 } 562 // ---------------------------------------------------------------------------------------- getNumPlayers() const563 unsigned int getNumPlayers() const 564 { 565 return (unsigned int) m_player_karts.size(); 566 } // getNumPlayers 567 // ---------------------------------------------------------------------------------------- 568 /** \brief Returns the number lf laps. 569 * In case of FTL or battle mode always return 9999, since they don't 570 * have laps. This avoids problems in FTL GP, since in this case no laps 571 * would be set (otherwise we would need many more tests in calls to 572 * getNumLaps). 573 */ getNumLaps() const574 int getNumLaps() const 575 { 576 if(modeHasLaps()) 577 return m_num_laps[m_track_number]; 578 // else 579 return 9999; 580 } // getNumLaps 581 // ---------------------------------------------------------------------------------------- 582 /** \return whether the track should be reversed */ getReverseTrack() const583 bool getReverseTrack() const { return m_reverse_track[m_track_number]; } 584 // ---------------------------------------------------------------------------------------- 585 /** Returns the difficulty. */ getDifficulty() const586 Difficulty getDifficulty() const { return m_difficulty; } 587 // ---------------------------------------------------------------------------------------- 588 /** Returns the specified difficulty as a string. */ getDifficultyAsString(Difficulty diff) const589 std::string getDifficultyAsString(Difficulty diff) const 590 { 591 switch(diff) 592 { 593 case RaceManager::DIFFICULTY_EASY: return "easy"; break; 594 case RaceManager::DIFFICULTY_MEDIUM: return "medium"; break; 595 case RaceManager::DIFFICULTY_HARD: return "hard"; break; 596 case RaceManager::DIFFICULTY_BEST: return "best"; break; 597 default: assert(false); 598 } 599 return ""; 600 } // getDifficultyAsString 601 602 // ---------------------------------------------------------------------------------------- 603 core::stringw getDifficultyName(Difficulty diff) const; 604 // ---------------------------------------------------------------------------------------- getTrackName() const605 const std::string& getTrackName() const { return m_tracks[m_track_number];} 606 // ---------------------------------------------------------------------------------------- getGrandPrix() const607 const GrandPrixData& getGrandPrix() const { return m_grand_prix; } 608 // ---------------------------------------------------------------------------------------- getFinishedKarts() const609 unsigned int getFinishedKarts() const { return m_num_finished_karts; } 610 // ---------------------------------------------------------------------------------------- getFinishedPlayers() const611 unsigned int getFinishedPlayers() const { return m_num_finished_players; } 612 // ---------------------------------------------------------------------------------------- getKartGPRank(const int kart_id) const613 int getKartGPRank(const int kart_id)const 614 { 615 return m_kart_status[kart_id].m_gp_rank; 616 } // getKartGPRank 617 // ---------------------------------------------------------------------------------------- getKartIdent(int kart) const618 const std::string& getKartIdent(int kart) const 619 { 620 return m_kart_status[kart].m_ident; 621 } // getKartIdent 622 // ---------------------------------------------------------------------------------------- getKartScore(int krt) const623 int getKartScore(int krt) const { return m_kart_status[krt].m_score; } 624 // ---------------------------------------------------------------------------------------- getKartPrevScore(int krt) const625 int getKartPrevScore(int krt) const 626 { 627 return m_kart_status[krt].m_last_score; 628 } // getKartPrevScore 629 // ---------------------------------------------------------------------------------------- getKartLocalPlayerId(int k) const630 int getKartLocalPlayerId(int k) const 631 { 632 return m_kart_status[k].m_local_player_id; 633 } // getKartLocalPlayerId 634 // ---------------------------------------------------------------------------------------- getKartGlobalPlayerId(int k) const635 int getKartGlobalPlayerId(int k) const 636 { 637 return m_kart_status[k].m_global_player_id; 638 } // getKartGlobalPlayerId 639 // ---------------------------------------------------------------------------------------- getOverallTime(int kart) const640 float getOverallTime(int kart) const 641 { 642 return m_kart_status[kart].m_overall_time; 643 } // getOverallTime 644 // ---------------------------------------------------------------------------------------- getKartRaceTime(int kart) const645 float getKartRaceTime(int kart) const 646 { 647 return m_kart_status[kart].m_last_time; 648 } // getKartRaceTime 649 // ---------------------------------------------------------------------------------------- getKartType(int kart) const650 KartType getKartType(int kart) const 651 { 652 return m_kart_status[kart].m_kart_type; 653 } // getKartType 654 // ---------------------------------------------------------------------------------------- getPlayerHandicap(int kart) const655 HandicapLevel getPlayerHandicap(int kart) const 656 { 657 return m_kart_status[kart].m_handicap; 658 } // getPlayerHandicap 659 // ---------------------------------------------------------------------------------------- hasBoostedAI(int kart) const660 bool hasBoostedAI(int kart) const 661 { 662 return m_kart_status[kart].m_boosted_ai; 663 } // getKartRaceTime 664 // ---------------------------------------------------------------------------------------- setKartColor(int kart,float color)665 void setKartColor(int kart, float color) 666 { 667 m_kart_status[kart].m_color = color; 668 } // setKartColor 669 // ---------------------------------------------------------------------------------------- getKartColor(int kart) const670 float getKartColor(int kart) const 671 { 672 return m_kart_status[kart].m_color; 673 } // getKartColor 674 // ---------------------------------------------------------------------------------------- getCoinTarget() const675 int getCoinTarget() const { return m_coin_target; } 676 // ---------------------------------------------------------------------------------------- getTimeTarget() const677 float getTimeTarget() const { return m_time_target; } 678 // ---------------------------------------------------------------------------------------- getTrackNumber() const679 int getTrackNumber() const { return m_track_number; } 680 // ---------------------------------------------------------------------------------------- getNumOfTracks() const681 int getNumOfTracks() const { return (int)m_tracks.size(); } 682 // ---------------------------------------------------------------------------------------- 683 /** Returns the list of AI karts to use. Used for networking, and for 684 * the --ai= command line option. */ getAIKartList() const685 const std::vector<std::string>& getAIKartList() const 686 { 687 return m_ai_kart_list; 688 } // getAIKartList 689 // ---------------------------------------------------------------------------------------- 690 /** \brief get information about current mode (returns true if 'mode' is of 691 * linear races type) */ isLinearRaceMode() const692 bool isLinearRaceMode() const 693 { 694 const int id = (int)m_minor_mode; 695 // info is stored in its ID for conveniance, see the macros LINEAR_RACE 696 // and BATTLE_ARENA above for exact meaning. 697 if(id > 999 && id < 2000) return true; 698 else return false; 699 } // isLinearRaceMode 700 701 // ---------------------------------------------------------------------------------------- 702 /** \brief get information about given mode (returns true if 'mode' is of 703 * linear races type) */ isLinearRaceMode(const MinorRaceModeType mode) const704 bool isLinearRaceMode(const MinorRaceModeType mode) const 705 { 706 const int id = (int)mode; 707 // info is stored in its ID for conveniance, see the macros LINEAR_RACE 708 // and BATTLE_ARENA above for exact meaning. 709 if(id > 999 && id < 2000) return true; 710 else return false; 711 } // isLinearRaceMode 712 713 // ---------------------------------------------------------------------------------------- 714 /** \brief Returns true if the current mode is a battle mode. */ isBattleMode() const715 bool isBattleMode() const 716 { 717 const int id = (int)m_minor_mode; 718 // This uses the numerical id of the mode, see the macros 719 // LINEAR_RACE and BATTLE_ARENA above for exact meaning. 720 if (id >= 2000 && id <= 2002) return true; 721 else return false; 722 } // isBattleMode 723 724 // ---------------------------------------------------------------------------------------- 725 /** \brief Returns true if the current mode is a soccer mode. */ isSoccerMode() const726 bool isSoccerMode() const 727 { 728 const int id = (int)m_minor_mode; 729 // This uses the numerical id of the mode, see the macros 730 // LINEAR_RACE and BATTLE_ARENA above for exact meaning. 731 if (id == 2003) return true; 732 else return false; 733 } // isSoccerMode 734 735 // ---------------------------------------------------------------------------------------- isTutorialMode() const736 bool isTutorialMode() const { return m_minor_mode == MINOR_MODE_TUTORIAL; } 737 738 // ---------------------------------------------------------------------------------------- isFollowMode() const739 bool isFollowMode() const { return m_minor_mode == MINOR_MODE_FOLLOW_LEADER; } 740 741 // ---------------------------------------------------------------------------------------- isCTFMode() const742 bool isCTFMode() const { return m_minor_mode == MINOR_MODE_CAPTURE_THE_FLAG; } 743 744 // ---------------------------------------------------------------------------------------- isEggHuntMode() const745 bool isEggHuntMode() const { return m_minor_mode == MINOR_MODE_EASTER_EGG; } 746 747 // ---------------------------------------------------------------------------------------- isTimeTrialMode() const748 bool isTimeTrialMode() const { return m_minor_mode == MINOR_MODE_TIME_TRIAL; } 749 // ---------------------------------------------------------------------------------------- 750 /** \brief Returns the number of second's decimals to display */ currentModeTimePrecision() const751 int currentModeTimePrecision() const 752 { 753 return 3; // display milliseconds 754 } // currentModeTimePrecision 755 // ---------------------------------------------------------------------------------------- 756 /** \brief Returns true if the current mode has laps. */ modeHasLaps() const757 bool modeHasLaps() const 758 { 759 if (!isLinearRaceMode()) return false; 760 const int id = (int)m_minor_mode; 761 // See meaning of IDs above 762 const int answer = (id-1000)/100; 763 return answer!=0; 764 } // modeHasLaps 765 // ---------------------------------------------------------------------------------------- 766 /** Returns true if the currently selected minor mode has highscores. */ modeHasHighscores()767 bool modeHasHighscores() 768 { 769 //FIXME: this information is duplicated. RaceManager knows about it, 770 // and each World may set m_use_highscores to true or false. 771 // The reason for this duplication is that we might want to know 772 // whether to display highscores without creating a World. 773 return !isBattleMode() && 774 !isSoccerMode() && 775 m_minor_mode != MINOR_MODE_FOLLOW_LEADER; 776 } // modeHasHighscore 777 // ---------------------------------------------------------------------------------------- raceWasStartedFromOverworld() const778 bool raceWasStartedFromOverworld() const 779 { 780 return m_started_from_overworld; 781 } // raceWasStartedFromOverworld 782 783 // ---------------------------------------------------------------------------------------- 784 /** \name Callbacks from the race classes 785 * These methods are to be used by the classes that manage the various 786 * races, to let the race manager know about current status 787 */ allPlayerFinished() const788 bool allPlayerFinished() const 789 { 790 return m_num_finished_players == m_player_karts.size(); 791 } // allPlayerFinished 792 // ---------------------------------------------------------------------------------------- 793 /** Sets the AI to use. This is used in networking mode to set the karts 794 * that will be used by the server to the client. It will take precedence 795 * over the random selection. */ setAIKartList(const std::vector<std::string> & rkl)796 void setAIKartList(const std::vector<std::string>& rkl) 797 { 798 m_ai_kart_list = rkl; 799 } // setAIKartList 800 // ---------------------------------------------------------------------------------------- haveKartLastPositionOnOverworld()801 bool haveKartLastPositionOnOverworld() 802 { 803 return m_have_kart_last_position_on_overworld; 804 } // haveKartLastPositionOnOverworld 805 // ---------------------------------------------------------------------------------------- setKartLastPositionOnOverworld(const Vec3 & pos)806 void setKartLastPositionOnOverworld(const Vec3 &pos) 807 { 808 m_have_kart_last_position_on_overworld = true; 809 m_kart_last_position_on_overworld = pos; 810 } // setKartLastPositionOnOverworld 811 // ---------------------------------------------------------------------------------------- clearKartLastPositionOnOverworld()812 void clearKartLastPositionOnOverworld() 813 { 814 m_have_kart_last_position_on_overworld = false; 815 } // clearKartLastPositionOnOverworld 816 // ---------------------------------------------------------------------------------------- getKartLastPositionOnOverworld()817 Vec3 getKartLastPositionOnOverworld() 818 { 819 return m_kart_last_position_on_overworld; 820 } // getKartLastPositionOnOverworld 821 // ---------------------------------------------------------------------------------------- setRecordRace(bool record)822 void setRecordRace(bool record) 823 { 824 m_is_recording_race = record; 825 } // setRecordRace 826 // ---------------------------------------------------------------------------------------- setRaceGhostKarts(bool ghost)827 void setRaceGhostKarts(bool ghost) 828 { 829 m_has_ghost_karts = ghost; 830 } // setRaceGhostKarts 831 // ---------------------------------------------------------------------------------------- setWatchingReplay(bool watch)832 void setWatchingReplay(bool watch) 833 { 834 m_watching_replay = watch; 835 } // setWatchingReplay 836 // ---------------------------------------------------------------------------------------- isRecordingRace() const837 bool isRecordingRace() const 838 { 839 return m_is_recording_race; 840 } // isRecordingRace 841 // ---------------------------------------------------------------------------------------- hasGhostKarts() const842 bool hasGhostKarts() const 843 { 844 return m_has_ghost_karts; 845 } // hasGhostKarts 846 // ---------------------------------------------------------------------------------------- isWatchingReplay() const847 bool isWatchingReplay() const 848 { 849 return m_watching_replay; 850 } // isWatchingReplay 851 // ---------------------------------------------------------------------------------------- addSpareTireKart(const std::string & name)852 void addSpareTireKart(const std::string& name) 853 { 854 m_kart_status.push_back(KartStatus(name, 0, -1, -1, 855 -1, KT_SPARE_TIRE, HANDICAP_NONE)); 856 m_num_spare_tire_karts++; 857 m_num_karts++; 858 } // addSpareTireKart 859 // ---------------------------------------------------------------------------------------- setSpareTireKartNum(unsigned int i)860 void setSpareTireKartNum(unsigned int i) 861 { 862 m_num_spare_tire_karts = i; 863 } // setSpareTireKartNum 864 // ---------------------------------------------------------------------------------------- getNumSpareTireKarts() const865 unsigned int getNumSpareTireKarts() const 866 { 867 return m_num_spare_tire_karts; 868 } // getNumSpareTireKarts 869 // ---------------------------------------------------------------------------------------- 870 void configGrandPrixResultFromNetwork(NetworkString& ns); 871 // ---------------------------------------------------------------------------------------- 872 void clearNetworkGrandPrixResult(); 873 // ---------------------------------------------------------------------------------------- setHitCaptureTime(int hc,float time)874 void setHitCaptureTime(int hc, float time) 875 { 876 m_hit_capture_limit = hc; 877 m_time_target = time; 878 } 879 // ---------------------------------------------------------------------------------------- getHitCaptureLimit() const880 int getHitCaptureLimit() const { return m_hit_capture_limit; } 881 // ---------------------------------------------------------------------------------------- teamEnabled() const882 bool teamEnabled() const 883 { 884 return m_minor_mode == MINOR_MODE_SOCCER || 885 m_minor_mode == MINOR_MODE_CAPTURE_THE_FLAG; 886 } 887 // ---------------------------------------------------------------------------------------- setFlagReturnTicks(unsigned ticks)888 void setFlagReturnTicks(unsigned ticks) { m_flag_return_ticks = ticks; } 889 // ---------------------------------------------------------------------------------------- getFlagReturnTicks() const890 unsigned getFlagReturnTicks() const { return m_flag_return_ticks; } 891 // ---------------------------------------------------------------------------------------- setFlagDeactivatedTicks(unsigned ticks)892 void setFlagDeactivatedTicks(unsigned ticks) 893 { m_flag_deactivated_ticks = ticks; } 894 // ---------------------------------------------------------------------------------------- getFlagDeactivatedTicks() const895 unsigned getFlagDeactivatedTicks() const 896 { return m_flag_deactivated_ticks; } 897 // ---------------------------------------------------------------------------------------- 898 /** Whether the current game mode allow live joining even the current game 899 *. started in network*/ supportsLiveJoining() const900 bool supportsLiveJoining() const 901 { 902 return m_minor_mode == MINOR_MODE_SOCCER || 903 m_minor_mode == MINOR_MODE_CAPTURE_THE_FLAG || 904 m_minor_mode == MINOR_MODE_FREE_FOR_ALL; 905 } 906 }; // RaceManager 907 908 #endif 909 910 /* EOF */ 911