1 // SuperTuxKart - a fun racing game with go-kart 2 // Copyright (C) 2004-2015 SuperTuxKart-Team 3 // 4 // This program is free software; you can redistribute it and/or 5 // modify it under the terms of the GNU General Public License 6 // as published by the Free Software Foundation; either version 3 7 // of the License, or (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18 #ifndef HEADER_LINEAR_WORLD_HPP 19 #define HEADER_LINEAR_WORLD_HPP 20 21 #include "modes/world_with_rank.hpp" 22 #include "utils/aligned_array.hpp" 23 24 #include <climits> 25 #include <vector> 26 27 class SFXBase; 28 29 /* 30 * A 'linear world' is a subcategory of world used in 'standard' races, i.e. 31 * with a start line and a road that loops. This includes management of drivelines 32 * and lap counting. 33 * \ingroup modes 34 */ 35 class LinearWorld : public WorldWithRank 36 { 37 private: 38 /** Sfx for the final lap. */ 39 SFXBase *m_last_lap_sfx; 40 41 /** Last lap sfx should only be played once. */ 42 bool m_last_lap_sfx_played; 43 44 bool m_last_lap_sfx_playing; 45 46 /** True if clients and server has the same check structure. */ 47 bool m_check_structure_compatible; 48 49 /** The fastest lap time, in ticks of physics dt. */ 50 int m_fastest_lap_ticks; 51 52 core::stringw m_fastest_lap_kart_name; 53 54 /** The track length returned by Track::getLength() only covers the 55 * distance from start line to finish line, i.e. it does not include 56 * the distance the karts actually start behind the start line (the 57 * karts would have a negative distance till they reach the start line 58 * for the first time). This values stores the additional distance by 59 * which the track length must be increased, which is important to 60 * get valid finish times estimates. */ 61 float m_distance_increase; 62 63 /** This stores the live time difference between a ghost kart 64 * and a second kart racing against it (normal or ghost). 65 */ 66 float m_live_time_difference; 67 68 /** True if the live_time_difference is invalid */ 69 bool m_valid_reference_time; 70 71 /* if set then the game will auto end after this time for networking */ 72 float m_finish_timeout; 73 74 /** This calculate the time difference between the second kart in the race 75 * (there must be at least two) and the first kart in the race 76 * (who must be a ghost). 77 */ 78 void updateLiveDifference(); 79 80 // ------------------------------------------------------------------------ 81 /** Some additional info that needs to be kept for each kart 82 * in this kind of race. 83 */ 84 class KartInfo 85 { 86 public: 87 /** Number of finished laps. */ 88 int m_finished_laps; 89 90 /** Time at finishing last lap. */ 91 int m_ticks_at_last_lap; 92 93 /** Time at start of a new lap. */ 94 int m_lap_start_ticks; 95 96 /** During last lap only: estimated finishing time! */ 97 float m_estimated_finish; 98 99 /** How far the kart has travelled (this is (number-of-laps-1) times 100 * track-length plus distance-along-track). */ 101 float m_overall_distance; 102 103 /** Accumulates the time a kart has been driving in the wrong 104 * direction so that a message can be displayed. */ 105 float m_wrong_way_timer; 106 107 /** Initialises all fields. */ KartInfo()108 KartInfo() { reset(); } 109 // -------------------------------------------------------------------- 110 /** Re-initialises all data. */ reset()111 void reset() 112 { 113 m_finished_laps = -1; 114 m_lap_start_ticks = 0; 115 m_ticks_at_last_lap = INT_MAX; 116 m_estimated_finish = -1.0f; 117 m_overall_distance = 0.0f; 118 m_wrong_way_timer = 0.0f; 119 } // reset 120 // -------------------------------------------------------------------- 121 void saveCompleteState(BareNetworkString* bns); 122 // -------------------------------------------------------------------- 123 void restoreCompleteState(const BareNetworkString& b); 124 }; 125 // ------------------------------------------------------------------------ 126 127 protected: 128 129 /** This vector contains an 'KartInfo' struct for every kart in the race. 130 * This member is not strictly private but try not to use it directly outside 131 * tightly related classes (e.g. AI) 132 */ 133 std::vector<KartInfo> m_kart_info; 134 135 virtual void checkForWrongDirection(unsigned int i, float dt); 136 virtual float estimateFinishTimeForKart(AbstractKart* kart) OVERRIDE; 137 138 public: 139 LinearWorld(); 140 /** call just after instanciating. can't be moved to the contructor as child 141 classes must be instanciated, otherwise polymorphism will fail and the 142 results will be incorrect */ 143 virtual void init() OVERRIDE; 144 virtual ~LinearWorld(); 145 146 virtual void update(int ticks) OVERRIDE; 147 virtual void updateGraphics(float dt) OVERRIDE; 148 float getDistanceDownTrackForKart(const int kart_id, 149 bool account_for_checklines) const; 150 void updateTrackSectors(); 151 void updateRacePosition(); 152 float getDistanceToCenterForKart(const int kart_id) const; 153 float getEstimatedFinishTime(const int kart_id) const; 154 int getLapForKart(const int kart_id) const; 155 int getTicksAtLapForKart(const int kart_id) const; getLiveTimeDifference() const156 float getLiveTimeDifference() const { return m_live_time_difference; } hasValidTimeDifference() const157 bool hasValidTimeDifference() const { return m_valid_reference_time; } 158 159 virtual void getKartsDisplayInfo( 160 std::vector<RaceGUIBase::KartIconDisplayInfo> *info) OVERRIDE; 161 162 virtual unsigned int getNumberOfRescuePositions() const OVERRIDE; 163 virtual unsigned int getRescuePositionIndex(AbstractKart *kart) OVERRIDE; 164 virtual btTransform getRescueTransform(unsigned int index) const OVERRIDE; 165 virtual void reset(bool restart=false) OVERRIDE; 166 virtual void newLap(unsigned int kart_index) OVERRIDE; 167 168 // ------------------------------------------------------------------------ 169 /** Returns if this race mode has laps. */ raceHasLaps()170 virtual bool raceHasLaps() OVERRIDE { return true; } 171 // ------------------------------------------------------------------------ 172 /** Returns if this race mode has bonus items. */ haveBonusBoxes()173 virtual bool haveBonusBoxes() OVERRIDE { return true; } 174 // ------------------------------------------------------------------------ 175 /** Override settings from base class */ useChecklineRequirements() const176 virtual bool useChecklineRequirements() const OVERRIDE { return true; } 177 // ------------------------------------------------------------------------ 178 /** Returns the number of laps a kart has completed. 179 * \param kart_index World index of the kart. */ getFinishedLapsOfKart(unsigned int kart_index) const180 int getFinishedLapsOfKart(unsigned int kart_index) const OVERRIDE 181 { 182 assert(kart_index < m_kart_info.size()); 183 return m_kart_info[kart_index].m_finished_laps; 184 } // getkartLap 185 // ------------------------------------------------------------------------ 186 void setLastTriggeredCheckline(unsigned int kart_index, int index); 187 // ------------------------------------------------------------------------ 188 /** Returns how far the kart has driven so far (i.e. 189 * number-of-laps-finished times track-length plus distance-on-track. 190 * \param kart_index World kart id of the kart. */ getOverallDistance(unsigned int kart_index) const191 float getOverallDistance(unsigned int kart_index) const 192 { 193 return m_kart_info[kart_index].m_overall_distance; 194 } // getOverallDistance 195 // ------------------------------------------------------------------------ 196 /** Returns time for the fastest laps */ getFastestLap() const197 float getFastestLap() const 198 { 199 return stk_config->ticks2Time(m_fastest_lap_ticks); 200 } 201 // ------------------------------------------------------------------------ 202 /** Returns the kart name that made the fastest lap time */ getFastestLapKartName() const203 stringw getFastestLapKartName() const 204 { 205 return m_fastest_lap_kart_name; 206 } 207 // ------------------------------------------------------------------------ 208 /** Network use: get fastest lap in ticks */ getFastestLapTicks() const209 int getFastestLapTicks() const 210 { 211 return m_fastest_lap_ticks; 212 } 213 // ------------------------------------------------------------------------ 214 /** Network use: set fastest lap in ticks */ setFastestLapTicks(int ticks)215 void setFastestLapTicks(int ticks) 216 { 217 m_fastest_lap_ticks = ticks; 218 } 219 // ------------------------------------------------------------------------ 220 /** Network use: set fastest kart name */ setFastestKartName(const stringw & name)221 void setFastestKartName(const stringw& name) 222 { 223 m_fastest_lap_kart_name = name; 224 } 225 // ------------------------------------------------------------------------ 226 virtual std::pair<uint32_t, uint32_t> getGameStartedProgress() const 227 OVERRIDE; 228 // ------------------------------------------------------------------------ 229 virtual void saveCompleteState(BareNetworkString* bns, 230 STKPeer* peer) OVERRIDE; 231 // ------------------------------------------------------------------------ 232 virtual void restoreCompleteState(const BareNetworkString& b) OVERRIDE; 233 // ------------------------------------------------------------------------ 234 void updateCheckLinesServer(int check_id, int kart_id); 235 // ------------------------------------------------------------------------ 236 void updateCheckLinesClient(const BareNetworkString& b); 237 // ------------------------------------------------------------------------ 238 void handleServerCheckStructureCount(unsigned count); 239 }; // LinearWorld 240 241 #endif 242