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_KART_PROPERTIES_HPP
20 #define HEADER_KART_PROPERTIES_HPP
21 
22 #include <memory>
23 #include <string>
24 #include <vector>
25 
26 #include <SColor.h>
27 #include <irrString.h>
28 namespace irr
29 {
30     namespace video { class ITexture; }
31 }
32 using namespace irr;
33 
34 #include "io/xml_node.hpp"
35 #include "race/race_manager.hpp"
36 #include "utils/interpolation_array.hpp"
37 #include "utils/vec3.hpp"
38 
39 class AbstractCharacteristic;
40 class AIProperties;
41 class CachedCharacteristic;
42 class CombinedCharacteristic;
43 class KartModel;
44 class Material;
45 class RenderInfo;
46 class XMLNode;
47 
48 
49 /**
50  *  \brief This class stores the properties of a kart.
51  *  This includes size, name, identifier, physical properties etc.
52  *  It is atm also the base class for STKConfig, which stores the default values
53  *  for all physics constants.
54  *  Note that KartProperties is copied (when setting the default values from
55  *  stk_config.
56  *
57  * \ingroup karts
58  */
59 class KartProperties
60 {
61 private:
62     /** Base directory for this kart. */
63     std::string              m_root;
64 
65     /** AI Properties for this kart, as a separate object in order to
66      *  reduce dependencies (and therefore compile time) when changing
67      *  any AI property. There is one separate object for each
68      *  difficulty. */
69     std::shared_ptr<AIProperties> m_ai_properties[RaceManager::DIFFICULTY_COUNT];
70 
71     /** The absolute path of the icon texture to use. */
72     Material                *m_icon_material;
73 
74     /** The minimap icon file. */
75     std::string              m_minimap_icon_file;
76 
77     /** The texture to use in the minimap. If not defined, a simple
78      *  color dot is used. */
79     video::ITexture         *m_minimap_icon;
80 
81     /** The kart model and wheels. It is mutable since the wheels of the
82      *  KartModel can rotate and turn, and animations are played, but otherwise
83      *  the kart_properties object is const. */
84     mutable std::shared_ptr<KartModel> m_kart_model;
85 
86     /** List of all groups the kart belongs to. */
87     std::vector<std::string> m_groups;
88 
89     /** Dummy value to detect unset properties. */
90     static float UNDEFINED;
91 
92     /** Version of the .kart file. */
93     int   m_version;
94 
95     // SFX files
96     // ---------------
97     std::vector<int> m_custom_sfx_id;     /**< Vector of custom SFX ids */
98 
99     // Display and gui
100     // ---------------
101     std::string m_name;               /**< The human readable Name of the kart
102                                        *   driver. */
103     std::string m_ident;              /**< The computer readable-name of the
104                                        *   kart driver. */
105     std::string m_icon_file;          /**< Filename of icon that represents the
106                                        *   kart in the statusbar and the
107                                        *   character select screen. */
108     std::string m_shadow_file;        /**< Filename of the image file that
109                                        *   contains the shadow for this kart.*/
110     float m_shadow_scale;             /**< Scale of the shadow plane
111                                        *   for this kart.*/
112     float m_shadow_x_offset;          /**< X offset of the shadow plane
113                                        *   for this kart.*/
114     float m_shadow_z_offset;          /**< Z offset of the shadow plane
115                                        *   for this kart.*/
116     Material* m_shadow_material;      /**< The texture with the shadow. */
117     video::SColor m_color;            /**< Color the represents the kart in the
118                                        *   status bar and on the track-view. */
119     int  m_shape;                     /**< Number of vertices in polygon when
120                                        *   drawing the dot on the mini map. */
121 
122     /** The physical, item, etc. characteristics of this kart that are loaded
123      *  from the xml file.
124      */
125     std::shared_ptr<AbstractCharacteristic> m_characteristic;
126     /** The base characteristics combined with the characteristics of this kart. */
127     std::shared_ptr<CombinedCharacteristic> m_combined_characteristic;
128     /** The cached combined characteristics. */
129     std::shared_ptr<CachedCharacteristic> m_cached_characteristic;
130 
131     // Physic properties
132     // -----------------
133     /** If != 0 a bevelled box shape is used by using a point cloud as a
134      *  collision shape. */
135     Vec3  m_bevel_factor;
136 
137     /** The position of the physical wheel is a weighted average of the
138      *  two ends of the beveled shape. This determines the weight: 0 =
139      *  a the widest end, 1 = at the narrowest front end. If the value is
140      *  < 0, the old physics settings are used which places the raycast
141      *  wheels outside of the chassis - but result in a more stable
142      *  physics behaviour (which is therefore atm still the default).
143      */
144     float m_physical_wheel_position;
145 
146     /** Minimum time during which nitro is consumed when pressing
147      *  the nitro key (to prevent using in very small bursts)
148      */
149     int8_t m_nitro_min_consumption;
150 
151     bool m_is_addon;
152 
153     /** Type of the kart (for the properties) */
154     std::string m_kart_type;
155 
156     /** Filename of the wheel models. */
157     std::string m_wheel_filename[4];
158 
159     /** Wheel base of the kart. */
160     float       m_wheel_base;
161 
162     /** The maximum roll a kart graphics should show when driving in a fast
163      *  curve. This is read in as degrees, but stored in radians. */
164      float      m_max_lean;
165 
166      /** The speed with which the roll (when leaning in a curve) changes
167       *  (in radians/second). */
168      float      m_lean_speed;
169 
170     /** Engine sound effect. */
171     std::string m_engine_sfx_type;
172 
173     // bullet physics data
174     // -------------------
175     float m_friction_slip;
176 
177     /** Shift of center of gravity. */
178     Vec3  m_gravity_center_shift;
179 
180 public:
181     /** STK can add an impulse to push karts away from the track in case
182      *  of a kart-track collision. This can be done in two ways: either
183      *  apply the impulse in the direction of the normal, or towards the
184      *  driveline. The later works nice as long as the kart is driving
185      *  on the main track, but can work very bad if the kart is drivling
186      *  off-track (and a wrong driveline is selected). */
187     enum TerrainImpulseType {IMPULSE_NONE, IMPULSE_NORMAL,
188                              IMPULSE_TO_DRIVELINE};
189 private:
190     TerrainImpulseType m_terrain_impulse_type;
191 
192     /** An additional impulse to push a kart away if it hits terrain */
193     float m_collision_terrain_impulse;
194 
195     /** An additiojnal artificial impulse that pushes two karts in a
196      *  side-side collision away from each other. */
197     float m_collision_impulse;
198 
199     /** How long the collision impulse should be applied. */
200     float m_collision_impulse_time;
201 
202     /** Restitution depending on speed. */
203     InterpolationArray m_restitution;
204 
205     void  load              (const std::string &filename,
206                              const std::string &node);
207     void combineCharacteristics(HandicapLevel h);
208 
209 public:
210     /** Returns the string representation of a handicap level. */
211     static std::string      getHandicapAsString(HandicapLevel h);
212 
213           KartProperties    (const std::string &filename="");
214          ~KartProperties    ();
215     void  copyForPlayer     (const KartProperties *source,
216                              HandicapLevel h = HANDICAP_NONE);
217     void  adjustForOnlineAddonKart(const KartProperties* source);
218     void  copyFrom          (const KartProperties *source);
219     void  getAllData        (const XMLNode * root);
220     void  checkAllSet       (const std::string &filename);
221     bool  isInGroup         (const std::string &group) const;
222     bool operator<(const KartProperties &other) const;
223 
224     // ------------------------------------------------------------------------
225     /** Returns the characteristics for this kart. */
226     const AbstractCharacteristic* getCharacteristic() const;
227     // ------------------------------------------------------------------------
228     /** Returns the characteristics for this kart combined with the base
229      *  characteristic. This value isn't used for the race, because the
230      *  difficulty is missing, but it can be used e.g. for the kart stats widget.
231      */
232     const AbstractCharacteristic* getCombinedCharacteristic() const;
233 
234     // ------------------------------------------------------------------------
235     /** Returns the material for the kart icons. */
getIconMaterial() const236     Material*     getIconMaterial    () const {return m_icon_material;        }
237 
238     // ------------------------------------------------------------------------
239     /** Returns the texture to use in the minimap, or NULL if not defined. */
getMinimapIcon() const240     video::ITexture *getMinimapIcon  () const {return m_minimap_icon;         }
241 
242     // ------------------------------------------------------------------------
243     KartModel* getKartModelCopy(std::shared_ptr<RenderInfo> ri=nullptr) const;
244     // ------------------------------------------------------------------------
245     /** Returns a pointer to the main KartModel object. This copy
246      *  should not be modified, not attachModel be called on it. */
getMasterKartModel() const247     const KartModel& getMasterKartModel() const {return *m_kart_model;        }
248     // ------------------------------------------------------------------------
249     void setHatMeshName(const std::string &hat_name);
250     // ------------------------------------------------------------------------
251     core::stringw getName() const;
252     // ------------------------------------------------------------------------
getNonTranslatedName() const253     const std::string getNonTranslatedName() const {return m_name;}
254 
255     // ------------------------------------------------------------------------
256     /** Returns the internal identifier of this kart. */
getIdent() const257     const std::string& getIdent      () const {return m_ident;                }
258 
259     // ------------------------------------------------------------------------
260     /** Returns the type of this kart. */
getKartType() const261     const std::string& getKartType   () const { return m_kart_type;           }
262 
263     // ------------------------------------------------------------------------
264     /** Returns the shadow texture to use. */
getShadowMaterial() const265     Material* getShadowMaterial() const           { return m_shadow_material; }
266 
267     // ------------------------------------------------------------------------
268     /** Returns the absolute path of the icon file of this kart. */
getAbsoluteIconFile() const269     const std::string& getAbsoluteIconFile() const      { return m_icon_file; }
270 
271     // ------------------------------------------------------------------------
272     /** Returns custom sound effects for this kart. */
getCustomSfxId(int type) const273     const int          getCustomSfxId (int type)
274                                        const  {return m_custom_sfx_id[type];  }
275 
276     // ------------------------------------------------------------------------
277     /** Returns the version of the .kart file. */
getVersion() const278     int   getVersion                () const {return m_version;               }
279 
280     // ------------------------------------------------------------------------
281     /** Returns the dot color to use for this kart in the race gui. */
getColor() const282     const video::SColor &getColor   () const {return m_color;                 }
283 
284     // ------------------------------------------------------------------------
285     /** Returns the number of edges for the polygon used to draw the dot of
286      *  this kart on the mini map of the race gui. */
getShape() const287     int   getShape                  () const {return m_shape;                 }
288 
289     // ------------------------------------------------------------------------
290     /** Returns the list of groups this kart belongs to. */
291     const std::vector<std::string>&
getGroups() const292                   getGroups         () const {return m_groups;                }
293 
294     // ------------------------------------------------------------------------
295     /** Returns the engine type (used to change sfx depending on kart size). */
getEngineSfxType() const296     const std::string& getEngineSfxType    () const {return m_engine_sfx_type;}
297 
298     // Bullet physics get functions
299     //-----------------------------
300     /** Returns friction slip. */
getFrictionSlip() const301     float getFrictionSlip           () const {return m_friction_slip;         }
302 
303     // ------------------------------------------------------------------------
304     /** Returns the wheel base (distance front to rear axis). */
getWheelBase() const305     float getWheelBase              () const {return m_wheel_base;            }
306 
307     // ------------------------------------------------------------------------
308     /** Returns a shift of the center of mass (lowering the center of mass
309      *  makes the karts more stable. */
getGravityCenterShift() const310     const Vec3&getGravityCenterShift() const {return m_gravity_center_shift;  }
311 
312     // ------------------------------------------------------------------------
313     /** Returns an artificial impulse to push karts away from the terrain
314      *  it hits. */
getCollisionTerrainImpulse() const315     float getCollisionTerrainImpulse() const
316                                           {return m_collision_terrain_impulse;}
317 
318     // ------------------------------------------------------------------------
319     /** Returns what kind of impulse STK should use in case of a kart-track
320      *  collision. */
getTerrainImpulseType() const321     TerrainImpulseType getTerrainImpulseType() const
322                                              { return m_terrain_impulse_type; }
323     // ------------------------------------------------------------------------
324     /** Returns the (artificial) collision impulse this kart will apply
325      *  to another kart in case of a non-frontal collision. */
getCollisionImpulse() const326     float getCollisionImpulse       () const {return m_collision_impulse;}
327 
328     // ------------------------------------------------------------------------
329     /** Returns how long the collision impulse should be applied. */
getCollisionImpulseTime() const330     float getCollisionImpulseTime() const { return m_collision_impulse_time;}
331 
332     // ------------------------------------------------------------------------
333     /** Returns the restitution factor for this kart. */
getRestitution(float speed) const334     float getRestitution(float speed) const { return m_restitution.get(speed);}
335 
336     // ------------------------------------------------------------------------
337     /** Returns a pointer to the AI properties. */
getAIPropertiesForDifficulty() const338     const AIProperties *getAIPropertiesForDifficulty() const
339     {
340         return m_ai_properties[RaceManager::get()->getDifficulty()].get();
341     }   // getAIProperties
342 
343     // ------------------------------------------------------------------------
344     /** Returns the full path where the files for this kart are stored. */
getKartDir() const345     const std::string& getKartDir   () const {return m_root;                  }
346 
347     // ------------------------------------------------------------------------
348     /** Returns the bevel factor (!=0 indicates to use a bevelled box). */
getBevelFactor() const349     const Vec3 &getBevelFactor() const { return m_bevel_factor; }
350     // ------------------------------------------------------------------------
351     /** Returns position of the physical wheel is a weighted average of the
352      *  two ends of the beveled shape. This determines the weight: 0 =
353      *  a the widest end, 1 = at the narrowest, front end. If the value is <0,
354      *  the old physics position is picked, which placed the raycast wheels
355      *  outside of the chassis, but gives more stable physics. */
getPhysicalWheelPosition() const356     const float getPhysicalWheelPosition() const
357     {
358         return m_physical_wheel_position;
359     }   // getPhysicalWheelPosition
360 
361     // ------------------------------------------------------------------------
362     float getAccelerationEfficiency() const;
363     // ------------------------------------------------------------------------
364     /** Returns minimum time during which nitro is consumed when pressing nitro
365     *  key, to prevent using nitro in very short bursts
366     */
getNitroMinConsumptionTicks() const367     int8_t getNitroMinConsumptionTicks() const
368                                             { return m_nitro_min_consumption; }
369     // ------------------------------------------------------------------------
isAddon() const370     bool isAddon() const                                 { return m_is_addon; }
371 
372     // Script-generated content generated by tools/create_kart_properties.py defs
373     // Please don't change the following tag. It will be automatically detected
374     // by the script and replace the contained content.
375     // To update the code, use tools/update_characteristics.py
376     /* <characteristics-start kpdefs> */
377 
378     float getSuspensionStiffness() const;
379     float getSuspensionRest() const;
380     float getSuspensionTravel() const;
381     bool getSuspensionExpSpringResponse() const;
382     float getSuspensionMaxForce() const;
383 
384     float getStabilityRollInfluence() const;
385     float getStabilityChassisLinearDamping() const;
386     float getStabilityChassisAngularDamping() const;
387     float getStabilityDownwardImpulseFactor() const;
388     float getStabilityTrackConnectionAccel() const;
389     std::vector<float> getStabilityAngularFactor() const;
390     float getStabilitySmoothFlyingImpulse() const;
391 
392     InterpolationArray getTurnRadius() const;
393     float getTurnTimeResetSteer() const;
394     InterpolationArray getTurnTimeFullSteer() const;
395 
396     float getEnginePower() const;
397     float getEngineMaxSpeed() const;
398     float getEngineGenericMaxSpeed() const;
399     float getEngineBrakeFactor() const;
400     float getEngineBrakeTimeIncrease() const;
401     float getEngineMaxSpeedReverseRatio() const;
402 
403     std::vector<float> getGearSwitchRatio() const;
404     std::vector<float> getGearPowerIncrease() const;
405 
406     float getMass() const;
407 
408     float getWheelsDampingRelaxation() const;
409     float getWheelsDampingCompression() const;
410 
411     float getJumpAnimationTime() const;
412 
413     float getLeanMax() const;
414     float getLeanSpeed() const;
415 
416     float getAnvilDuration() const;
417     float getAnvilWeight() const;
418     float getAnvilSpeedFactor() const;
419 
420     float getParachuteFriction() const;
421     float getParachuteDuration() const;
422     float getParachuteDurationOther() const;
423     float getParachuteDurationRankMult() const;
424     float getParachuteDurationSpeedMult() const;
425     float getParachuteLboundFraction() const;
426     float getParachuteUboundFraction() const;
427     float getParachuteMaxSpeed() const;
428 
429     float getFrictionKartFriction() const;
430 
431     float getBubblegumDuration() const;
432     float getBubblegumSpeedFraction() const;
433     float getBubblegumTorque() const;
434     float getBubblegumFadeInTime() const;
435     float getBubblegumShieldDuration() const;
436 
437     float getZipperDuration() const;
438     float getZipperForce() const;
439     float getZipperSpeedGain() const;
440     float getZipperMaxSpeedIncrease() const;
441     float getZipperFadeOutTime() const;
442 
443     float getSwatterDuration() const;
444     float getSwatterDistance() const;
445     float getSwatterSquashDuration() const;
446     float getSwatterSquashSlowdown() const;
447 
448     float getPlungerBandMaxLength() const;
449     float getPlungerBandForce() const;
450     float getPlungerBandDuration() const;
451     float getPlungerBandSpeedIncrease() const;
452     float getPlungerBandFadeOutTime() const;
453     float getPlungerInFaceTime() const;
454 
455     std::vector<float> getStartupTime() const;
456     std::vector<float> getStartupBoost() const;
457 
458     float getRescueDuration() const;
459     float getRescueVertOffset() const;
460     float getRescueHeight() const;
461 
462     float getExplosionDuration() const;
463     float getExplosionRadius() const;
464     float getExplosionInvulnerabilityTime() const;
465 
466     float getNitroDuration() const;
467     float getNitroEngineForce() const;
468     float getNitroEngineMult() const;
469     float getNitroConsumption() const;
470     float getNitroSmallContainer() const;
471     float getNitroBigContainer() const;
472     float getNitroMaxSpeedIncrease() const;
473     float getNitroFadeOutTime() const;
474     float getNitroMax() const;
475 
476     float getSlipstreamDurationFactor() const;
477     float getSlipstreamBaseSpeed() const;
478     float getSlipstreamLength() const;
479     float getSlipstreamWidth() const;
480     float getSlipstreamInnerFactor() const;
481     float getSlipstreamMinCollectTime() const;
482     float getSlipstreamMaxCollectTime() const;
483     float getSlipstreamAddPower() const;
484     float getSlipstreamMinSpeed() const;
485     float getSlipstreamMaxSpeedIncrease() const;
486     float getSlipstreamFadeOutTime() const;
487 
488     float getSkidIncrease() const;
489     float getSkidDecrease() const;
490     float getSkidMax() const;
491     float getSkidTimeTillMax() const;
492     float getSkidVisual() const;
493     float getSkidVisualTime() const;
494     float getSkidRevertVisualTime() const;
495     float getSkidMinSpeed() const;
496     std::vector<float> getSkidTimeTillBonus() const;
497     std::vector<float> getSkidBonusSpeed() const;
498     std::vector<float> getSkidBonusTime() const;
499     std::vector<float> getSkidBonusForce() const;
500     float getSkidPhysicalJumpTime() const;
501     float getSkidGraphicalJumpTime() const;
502     float getSkidPostSkidRotateFactor() const;
503     float getSkidReduceTurnMin() const;
504     float getSkidReduceTurnMax() const;
505     bool getSkidEnabled() const;
506 
507     /* <characteristics-end kpdefs> */
508 
509     LEAK_CHECK()
510 };   // KartProperties
511 
512 #endif
513 
514