1 //
2 //  SuperTuxKart - a fun racing game with go-kart
3 //  Copyright (C) 2004-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_WORLD_HPP
20 #define HEADER_WORLD_HPP
21 
22 /**
23   * \defgroup modes
24   * Contains the logic for the various game modes (race, follow the leader,
25   * battle, etc.)
26   */
27 
28 #include <cstring>
29 #include <limits>
30 #include <map>
31 #include <memory>
32 #include <vector>
33 #include <stdexcept>
34 
35 #include "graphics/weather.hpp"
36 #include "modes/world_status.hpp"
37 #include "race/highscores.hpp"
38 #include "states_screens/race_gui_base.hpp"
39 #include "states_screens/state_manager.hpp"
40 #include "utils/random_generator.hpp"
41 #include "utils/stk_process.hpp"
42 
43 #include "LinearMath/btTransform.h"
44 
45 class AbstractKart;
46 class BareNetworkString;
47 class btRigidBody;
48 class Controller;
49 class ItemState;
50 class PhysicalObject;
51 class STKPeer;
52 
53 namespace Scripting
54 {
55     class ScriptEngine;
56 }
57 
58 namespace irr
59 {
60     namespace scene { class ISceneNode; }
61 }
62 
63 class AbortWorldUpdateException : public std::runtime_error
64 {
65 public:
AbortWorldUpdateException()66     AbortWorldUpdateException() : std::runtime_error("race abort") { };
67 };
68 
69 /**
70  *  \brief base class for all game modes
71  *  This class is responsible for running the actual race. A world is created
72  *  by the race manager on the start of each race (so a new world is created
73  *  for each race of a Grand Prix). It creates the
74  *  physics, loads the track, creates all karts, and initialises the race
75  *  specific managers (ItemManager, ProjectilManager, highscores, ...).
76  *  It uses the information from the race manager to get information like
77  *  what and how many karts, track to load etc. This class does not really
78  *  know about Grand Prixs, a GP is created
79  *  It maintains the race clock, and updates all karts, herings etc. during
80  *  the race.
81  *  Special game modes (e.g. follow the leader) are currently integrated in
82  *  this world, see e.g. updateRaceStatus where the world clock behaviour
83  *  is handled differently to create the count down.
84  * \ingroup modes
85  */
86 
87 class World : public WorldStatus
88 {
89 public:
90     typedef std::vector<std::shared_ptr<AbstractKart> > KartList;
91 private:
92     /** A pointer to the global world object for a race. */
93     static World *m_world[PT_COUNT];
94     // ------------------------------------------------------------------------
95     void setAITeam();
96     // ------------------------------------------------------------------------
97     std::shared_ptr<AbstractKart> createKartWithTeam
98         (const std::string &kart_ident, int index, int local_player_id,
99         int global_player_id, RaceManager::KartType type,
100         HandicapLevel handicap);
101 
102 protected:
103 
104 #ifdef DEBUG
105     unsigned int m_magic_number;
106 #endif
107 
108     /* Team related variables. */
109     int m_red_ai;
110     int m_blue_ai;
111     std::map<int, KartTeam> m_kart_team_map;
112     std::map<int, unsigned int> m_kart_position_map;
113 
114     /** The list of all karts. */
115     KartList                  m_karts;
116     RandomGenerator           m_random;
117 
118     AbstractKart* m_fastest_kart;
119     /** Number of eliminated karts. */
120     int         m_eliminated_karts;
121     /** Number of eliminated players. */
122     int         m_eliminated_players;
123     /** OVerall number of players. */
124     int         m_num_players;
125 
126     bool        m_faster_music_active; // true if faster music was activated
127 
128     bool        m_stop_music_when_dialog_open;
129 
130     bool        m_unfair_team;
131 
132     /** Whether highscores should be used for this kind of race.
133      *  True by default, change to false in a child class to disable.
134     */
135     bool        m_use_highscores;
136 
137     void  updateHighscores  (int* best_highscore_rank);
138     void  resetAllKarts     ();
139     Controller*
140           loadAIController  (AbstractKart *kart);
141 
142     virtual std::shared_ptr<AbstractKart> createKart
143         (const std::string &kart_ident, int index, int local_player_id,
144         int global_player_id, RaceManager::KartType type,
145         HandicapLevel handicap);
146 
147     /** Pointer to the race GUI. The race GUI is handled by world. */
148     RaceGUIBase *m_race_gui;
149 
150     /** The actual race gui needs to be saved when the race result gui is
151         displayed since it is still needed in case of a restart, and it
152         can't simply be created again (since it assumes that it can render
153         to texture without having any scene nodes, but in case of a restart
154         there are scene nodes). */
155     RaceGUIBase *m_saved_race_gui;
156 
157     /** Pausing/unpausing are not done immediately, but at next udpdate. The
158      *  use of this is when switching between screens : if we leave a screen
159      *  that paused the game, only to go to another screen that pauses back
160      *  the game, this mechanism prevents the game from moving on between
161      *  the switch. */
162     bool m_schedule_pause;
163 
164     /** Pausing/unpausing are not done immediately, but at next udpdate. The
165      *  use of this is when switching between screens : if we leave a screen
166      *  that paused the game, only to go to another screen that pauses back
167      *  the game, this mechanism prevents the game from moving on between the
168      *  switch. */
169     bool m_schedule_unpause;
170 
171     bool m_schedule_exit_race;
172 
173     bool m_schedule_tutorial;
174 
175     Phase m_scheduled_pause_phase;
176 
177     /** Set when the world needs to be deleted but you can't do it immediately
178      * because you are e.g. within World::update()
179      */
180     bool m_self_destruct;
181 
182     /** Set when the world is online and counts network players. */
183     bool m_is_network_world;
184 
185     bool m_ended_early;
186 
187     virtual void  onGo() OVERRIDE;
188     /** Returns true if the race is over. Must be defined by all modes. */
189     virtual bool  isRaceOver() = 0;
190     virtual void  update(int ticks) OVERRIDE;
191     virtual void  createRaceGUI();
192             void  updateTrack(int ticks);
193     // ------------------------------------------------------------------------
194     /** Used for AI karts that are still racing when all player kart finished.
195      *  Generally it should estimate the arrival time for those karts, but as
196      *  a default (useful for battle mode and ftl races) we just use the
197      *  current time for this (since this is a good value for karts still
198      *  around at the end of a race, and other criteria (number of lives,
199      *  race position) will be used to determine the final order.
200      */
estimateFinishTimeForKart(AbstractKart * kart)201     virtual float estimateFinishTimeForKart(AbstractKart* kart)
202                                         {return getTime(); }
203     void updateAchievementDataEndRace();
204     void updateAchievementModeCounters(bool start);
205 
206 public:
207                     World();
208     virtual        ~World();
209     // Static functions to access world:
210     // =================================
211     // ------------------------------------------------------------------------
212     /** Returns a pointer to the (singleton) world object. */
getWorld()213     static World*   getWorld()
214     {
215         ProcessType type = STKProcess::getType();
216         return m_world[type];
217     }
218     // ------------------------------------------------------------------------
219     /** Delete the )singleton) world object, if it exists, and sets the
220       * singleton pointer to NULL. It's harmless to call this if the world
221       *  has been deleted already. */
deleteWorld()222     static void     deleteWorld()
223     {
224         ProcessType type = STKProcess::getType();
225         delete m_world[type];
226         m_world[type] = NULL;
227     }
228     // ------------------------------------------------------------------------
229     /** Sets the pointer to the world object. This is only used by
230      *  the race_manager.*/
setWorld(World * world)231     static void     setWorld(World *world)
232     {
233         ProcessType type = STKProcess::getType();
234         m_world[type] = world;
235     }
236     // ------------------------------------------------------------------------
clear()237     static void     clear() { memset(m_world, 0, sizeof(m_world)); }
238     // ------------------------------------------------------------------------
239 
240     // Pure virtual functions
241     // ======================
242 
243     /** Each game mode should have a unique identifier. Override
244       * this method in child classes to provide it. */
245     virtual const std::string& getIdent() const = 0;
246     // ------------------------------------------------------------------------
247     /** Returns the number of rescue positions on a given track and game
248      *  mode. */
249     virtual unsigned int getNumberOfRescuePositions() const;
250     // ------------------------------------------------------------------------
251     /** Determines the rescue position index of the specified kart. */
252     virtual unsigned int getRescuePositionIndex(AbstractKart *kart) = 0;
253     // ------------------------------------------------------------------------
254     /** Returns the bullet transformation for the specified rescue index. */
255     virtual btTransform getRescueTransform(unsigned int index) const;
256     // ------------------------------------------------------------------------
257     virtual void moveKartAfterRescue(AbstractKart* kart);
258     // ------------------------------------------------------------------------
259     /** Called when it is needed to know whether this kind of race involves
260      *  counting laps. */
261     virtual bool raceHasLaps() = 0;
262     // ------------------------------------------------------------------------
263     /** Returns the number of laps for a given kart. Only valid when
264      *  raceHasLaps() - otherwise STK will abort. */
getFinishedLapsOfKart(unsigned int kart_index) const265     virtual int getFinishedLapsOfKart(unsigned int kart_index) const
266     {
267         assert(false); return -1; // remove compiler warning
268     }   // getFinishedLapsOfKart
269     // ------------------------------------------------------------------------
270     /** Called by the code that draws the list of karts on the race GUI
271       * to know what needs to be drawn in the current mode. */
272     virtual void getKartsDisplayInfo(
273                        std::vector<RaceGUIBase::KartIconDisplayInfo> *info)= 0;
274     // ------------------------------------------------------------------------
275 
276     // Virtual functions
277     // =================
278     virtual void    init();
279     virtual void    updateGraphics(float dt);
280     virtual void    terminateRace() OVERRIDE;
281     virtual void    reset(bool restart=false) OVERRIDE;
282     virtual void    pause(Phase phase) OVERRIDE;
283     virtual void    unpause() OVERRIDE;
284     virtual void    getDefaultCollectibles(int *collectible_type,
285                                            int *amount );
286     // ------------------------------------------------------------------------
287     /** Receives notification if an item is collected. Used for easter eggs. */
collectedItem(const AbstractKart * kart,const ItemState * item)288     virtual void collectedItem(const AbstractKart *kart,
289                                const ItemState *item    ) {}
290     // ------------------------------------------------------------------------
endRaceEarly()291     virtual void endRaceEarly() { return; }
292     // ------------------------------------------------------------------------
hasRaceEndedEarly() const293     virtual bool hasRaceEndedEarly() const { return m_ended_early; }
294     // ------------------------------------------------------------------------
295     /** Called to determine whether this race mode uses bonus boxes. */
haveBonusBoxes()296     virtual bool haveBonusBoxes() { return true; }
297     // ------------------------------------------------------------------------
298     /** Returns if this mode should use fast music (if available). */
useFastMusicNearEnd() const299     virtual bool useFastMusicNearEnd() const { return true; }
300     // ------------------------------------------------------------------------
301     /** If you want to do something to karts or their graphics at the start
302      *  of the race, override this. */
kartAdded(AbstractKart * kart,scene::ISceneNode * node)303     virtual void kartAdded(AbstractKart* kart, scene::ISceneNode* node) {}
304     // ------------------------------------------------------------------------
305     /** Called whenever a kart starts a new lap. Meaningless (and won't be
306      *  called) in non-laped races.
307      */
newLap(unsigned int kart_index)308     virtual void newLap(unsigned int kart_index) {}
309     // ------------------------------------------------------------------------
310     /** Called when a kart was hit by a projectile. */
kartHit(int kart_id,int hitter=-1)311     virtual bool kartHit(int kart_id, int hitter = -1) { return false; }
312     // ------------------------------------------------------------------------
onMouseClick(int x,int y)313     virtual void onMouseClick(int x, int y) {};
314 
315     // Other functions
316     // ===============
317     Highscores     *getHighscores() const;
318     void            schedulePause(Phase phase);
319     void            scheduleUnpause();
scheduleExitRace()320     void            scheduleExitRace() { m_schedule_exit_race = true; }
321     void            scheduleTutorial();
322     void            updateWorld(int ticks);
323     void            handleExplosion(const Vec3 &xyz, AbstractKart *kart_hit,
324                                     PhysicalObject *object);
325     AbstractKart*   getPlayerKart(unsigned int player) const;
326     AbstractKart*   getLocalPlayerKart(unsigned int n) const;
327     virtual const btTransform &getStartTransform(int index);
328     void moveKartTo(AbstractKart* kart, const btTransform &t);
329     // ------------------------------------------------------------------------
330     /** Returns a pointer to the race gui. */
getRaceGUI() const331     RaceGUIBase    *getRaceGUI() const { return m_race_gui;}
332     // ------------------------------------------------------------------------
333     /** Returns the number of karts in the race. */
getNumKarts() const334     unsigned int    getNumKarts() const { return (unsigned int) m_karts.size(); }
335     // ------------------------------------------------------------------------
336     /** Returns the kart with a given world id. */
getKart(int kartId) const337     AbstractKart       *getKart(int kartId) const {
338                         assert(kartId >= 0 && kartId < int(m_karts.size()));
339                         return m_karts[kartId].get();                              }
340     // ------------------------------------------------------------------------
341     /** Returns all karts. */
getKarts() const342     const KartList & getKarts() const { return m_karts; }
343     // ------------------------------------------------------------------------
344     /** Returns the number of currently active (i.e.non-elikminated) karts. */
getCurrentNumKarts() const345     unsigned int    getCurrentNumKarts() const { return (int)m_karts.size() -
346                                                          m_eliminated_karts; }
347     // ------------------------------------------------------------------------
348     /** Returns the number of currently active (i.e. non-eliminated) players.*/
getCurrentNumPlayers() const349     unsigned int    getCurrentNumPlayers() const { return m_num_players -
350                                                          m_eliminated_players;}
351     // ------------------------------------------------------------------------
resetElimination()352     void resetElimination()
353     {
354         m_eliminated_karts = 0;
355         m_eliminated_players = 0;
356     }
357     // ------------------------------------------------------------------------
addReservedKart(int kart_id)358     virtual void addReservedKart(int kart_id)
359     {
360         if (m_eliminated_karts > 0)
361             m_eliminated_karts--;
362     }
363     // ------------------------------------------------------------------------
saveCompleteState(BareNetworkString * bns,STKPeer * peer)364     virtual void saveCompleteState(BareNetworkString* bns, STKPeer* peer) {}
365     // ------------------------------------------------------------------------
restoreCompleteState(const BareNetworkString & buffer)366     virtual void restoreCompleteState(const BareNetworkString& buffer) {}
367     // ------------------------------------------------------------------------
368     /** The code that draws the timer should call this first to know
369      *  whether the game mode wants a timer drawn. */
shouldDrawTimer() const370     virtual bool shouldDrawTimer() const
371                     { return isActiveRacePhase() && getClockMode() != CLOCK_NONE; }
372     // ------------------------------------------------------------------------
373     /** \return whether this world can generate/have highscores */
useHighScores() const374     bool useHighScores() const { return m_use_highscores; }
375     // ------------------------------------------------------------------------
376     /** Override if you want to know when a kart presses fire */
onFirePressed(Controller * who)377     virtual void onFirePressed(Controller* who) {}
378     // ------------------------------------------------------------------------
379     /** Whether to compute checkline requirements for each world on the
380       * quadgraph. Override to change value. */
useChecklineRequirements() const381     virtual bool useChecklineRequirements() const { return false; }
382     // ------------------------------------------------------------------------
383     virtual void escapePressed();
384     // ------------------------------------------------------------------------
loadCustomModels()385     virtual void loadCustomModels() {}
386     // ------------------------------------------------------------------------
387     void eliminateKart(int kart_number, bool notify_of_elimination = true);
388     // ------------------------------------------------------------------------
setUnfairTeam(bool val)389     void setUnfairTeam(bool val)                       { m_unfair_team = val; }
390     // ------------------------------------------------------------------------
hasTeam() const391     virtual bool hasTeam() const                              { return false; }
392     // ------------------------------------------------------------------------
393     /** Get the team of kart in world (including AIs) */
394     KartTeam getKartTeam(unsigned int kart_id) const;
395     // ------------------------------------------------------------------------
396     int getTeamNum(KartTeam team) const;
397     // ------------------------------------------------------------------------
398     /** Set the network mode (true if networked) */
setNetworkWorld(bool is_networked)399     void setNetworkWorld(bool is_networked) { m_is_network_world = is_networked; }
400     // ------------------------------------------------------------------------
isNetworkWorld() const401     bool isNetworkWorld() const { return m_is_network_world; }
402     // ------------------------------------------------------------------------
403     /** Set the team arrow on karts if necessary*/
404     void initTeamArrows(AbstractKart* k);
405     // ------------------------------------------------------------------------
406     /** Used by server to get the current started game progress in either or
407      *  both remaining time or progress in percent. uint32_t max for either or
408      *  both if not available.  */
getGameStartedProgress() const409     virtual std::pair<uint32_t, uint32_t> getGameStartedProgress() const
410     {
411         return std::make_pair(std::numeric_limits<uint32_t>::max(),
412             std::numeric_limits<uint32_t>::max());
413     }
414     // ------------------------------------------------------------------------
isGoalPhase() const415     virtual bool isGoalPhase() const { return false; }
416 };   // World
417 
418 #endif
419 
420 /* EOF */
421