1 // 2 // SuperTuxKart - a fun racing game with go-kart 3 // Copyright (C) 2010-2015 Joerg Henrichs 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_MAX_SPEED_HPP 20 #define HEADER_MAX_SPEED_HPP 21 22 #include "utils/types.hpp" 23 #include <limits> 24 25 /** \defgroup karts */ 26 27 class AbstractKart; 28 class BareNetworkString; 29 30 class MaxSpeed 31 { 32 friend class KartRewinder; 33 public: 34 /** The categories to use for increasing the speed of a kart: 35 * Increase due to zipper, slipstream, nitro, rubber band, 36 * skidding usage. */ 37 enum {MS_INCREASE_MIN, 38 MS_INCREASE_ZIPPER = MS_INCREASE_MIN, 39 MS_INCREASE_SLIPSTREAM, 40 MS_INCREASE_NITRO, 41 MS_INCREASE_RUBBER, 42 MS_INCREASE_SKIDDING, 43 MS_INCREASE_RED_SKIDDING, 44 MS_INCREASE_MAX}; 45 46 /** The categories to use for decreasing the speed of a kart: 47 * Decrease due to terrain, different AI levels and end controller. */ 48 enum {MS_DECREASE_MIN, 49 MS_DECREASE_TERRAIN = MS_DECREASE_MIN, 50 MS_DECREASE_AI, 51 MS_DECREASE_BUBBLE, 52 MS_DECREASE_SQUASH, 53 MS_DECREASE_MAX}; 54 55 private: 56 /** A pointer to the kart to which this speed handling object belongs. */ 57 AbstractKart *m_kart; 58 59 /** The current maximum speed. */ 60 float m_current_max_speed; 61 62 /** Additional engine force, summed from all SpeedIncrease engine forces. */ 63 float m_add_engine_force; 64 65 /** If >0 then the minimum speed a kart should have (used for zippers). */ 66 float m_min_speed; 67 68 // ------------------------------------------------------------------------ 69 /** An internal class to store and handle speed increase related data. */ 70 class SpeedIncrease 71 { 72 public: 73 /** The maximum additional speed allowed, 3 digits precision. */ 74 uint16_t m_max_add_speed; 75 /** How long this speed will apply. This is used as a timer internally, 76 * to the duration will be decreased. When the duration is <0, the 77 * fade out time starts, and duration will go down to 78 * -m_fade_out_time before this speed increase stops. */ 79 int16_t m_duration; 80 /** The fadeout time. */ 81 int16_t m_fade_out_time; 82 /** The current max speed increase value, updated with duration. */ 83 float m_current_speedup; 84 /** Additional engine force, 1 digit precision. */ 85 uint16_t m_engine_force; 86 /** The constructor initialised the values with a no-increase 87 * entry, i.e. an entry that does affect top speed at all. */ SpeedIncrease()88 SpeedIncrease() 89 { 90 reset(); 91 } // SpeedIncrease 92 // -------------------------------------------------------------------- 93 /** Resets this increase category to be not active. */ reset()94 void reset() 95 { 96 m_max_add_speed = 0; 97 m_duration = std::numeric_limits<int16_t>::min(); 98 m_fade_out_time = 0; 99 m_current_speedup = 0; 100 m_engine_force = 0; 101 } // reset 102 // -------------------------------------------------------------------- 103 void update(int ticks); 104 void saveState(BareNetworkString *buffer) const; 105 void rewindTo(BareNetworkString *buffer, bool is_active); 106 // -------------------------------------------------------------------- 107 /** Returns the current speedup for this category. */ getSpeedIncrease() const108 float getSpeedIncrease() const {return m_current_speedup;} 109 // -------------------------------------------------------------------- 110 /** Returns the remaining time till the fade out time starts. 111 * Note that this function will return a negative value if 112 * the fade_out time has started or this speed increase has 113 * expired. */ getTimeLeft() const114 int getTimeLeft() const {return m_duration; } 115 // -------------------------------------------------------------------- 116 /** Returns the additional engine force for this speed increase. */ getEngineForce() const117 float getEngineForce() const 118 { 119 return m_duration > 0 ? (float)m_engine_force / 10.0f : 0; 120 } // getEngineForce 121 // -------------------------------------------------------------------- 122 /** Returns if this speed increase is active atm. */ isActive() const123 bool isActive() const { return m_duration > -m_fade_out_time; } 124 }; // SpeedIncrease 125 126 // ------------------------------------------------------------------------ 127 /** An internal class to store and handle speed decrease related data. */ 128 class SpeedDecrease 129 { 130 public: 131 /** The maximum slowdown to apply, 3 digits precision. */ 132 uint16_t m_max_speed_fraction; 133 /** The current slowdown fraction, taking the fade-in time 134 * into account. */ 135 float m_current_fraction; 136 137 /** How long it should take for the full slowdown to take effect. */ 138 int16_t m_fade_in_ticks; 139 140 /** How long the effect should last. A -1 as value indicates 141 * that this effect stays active till it is changed back. */ 142 int16_t m_duration; 143 144 /** The constructor initialises the data with data that won't 145 * affect top speed at all. */ SpeedDecrease()146 SpeedDecrease() 147 { 148 reset(); 149 } // SpeedDecrease 150 // -------------------------------------------------------------------- 151 /** Resets the state to be inactive. */ reset()152 void reset() 153 { 154 m_max_speed_fraction = 1000; 155 m_current_fraction = 1.0f; 156 m_fade_in_ticks = 0; 157 m_duration = 0; 158 } //reset 159 // -------------------------------------------------------------------- 160 void update(int ticks); 161 void saveState(BareNetworkString *buffer) const; 162 void rewindTo(BareNetworkString *buffer, bool is_active); 163 // -------------------------------------------------------------------- 164 /** Returns the current slowdown fracftion, taking a 'fade in' 165 * into account. */ getSlowdownFraction() const166 float getSlowdownFraction() const { return m_current_fraction; } 167 // -------------------------------------------------------------------- getTimeLeft() const168 int getTimeLeft() const { return m_duration; } 169 // -------------------------------------------------------------------- 170 /** Returns if this speed decrease is active atm. A duration of 171 * -1 indicates an ongoing effect. */ isActive() const172 bool isActive() const { return m_duration > 0 || m_duration <= -1; } 173 }; // SpeedDecrease 174 175 // ------------------------------------------------------------------------ 176 /** Stores all speed decrease related information 177 * for each possible category. */ 178 SpeedDecrease m_speed_decrease[MS_DECREASE_MAX]; 179 180 /** Stores all speed increase related information 181 * for each possible category. */ 182 SpeedIncrease m_speed_increase[MS_INCREASE_MAX]; 183 184 185 public: 186 MaxSpeed(AbstractKart *kart); 187 188 void increaseMaxSpeed(unsigned int category, float add_speed, 189 float engine_force, int duration, 190 int fade_out_time); 191 void instantSpeedIncrease(unsigned int category, 192 float add_speed, float speed_boost, 193 float engine_force, int duration, 194 int fade_out_time); 195 void setSlowdown(unsigned int category, float max_speed_fraction, 196 int fade_in_time, int duration=-1); 197 int getSpeedIncreaseTicksLeft(unsigned int category); 198 int isSpeedIncreaseActive(unsigned int category); 199 int isSpeedDecreaseActive(unsigned int category); 200 void update(int ticks); 201 void reset(); 202 void saveState(BareNetworkString *buffer) const; 203 void rewindTo(BareNetworkString *buffer); 204 // ------------------------------------------------------------------------ 205 /** Sets the minimum speed a kart should have. This is used to guarantee 206 * that e.g. zippers on ramps will always fast enough for the karts to 207 * reach the other end. If set to a negative number, it will have 208 * no effect. */ setMinSpeed(float s)209 void setMinSpeed(float s) { m_min_speed = s; } 210 // ------------------------------------------------------------------------ 211 /** Returns the current maximum speed for this kart. */ getCurrentMaxSpeed() const212 float getCurrentMaxSpeed() const { return m_current_max_speed; } 213 // ------------------------------------------------------------------------ 214 /** Returns the additional engine force. */ getCurrentAdditionalEngineForce() const215 float getCurrentAdditionalEngineForce() const { return m_add_engine_force;} 216 }; // MaxSpeed 217 #endif 218