hopefully fixed the crash on exit, keep sectors script bundled in the sector and...
[supertux.git] / src / sector.hpp
1 //  $Id$
2 //
3 //  SuperTux -  A Jump'n Run
4 //  Copyright (C) 2004 Matthias Braun <matze@braunis.de
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 #ifndef SUPERTUX_SECTOR_H
20 #define SUPERTUX_SECTOR_H
21
22 #include <string>
23 #include <vector>
24 #include <memory>
25 #include <squirrel.h>
26
27 #include "direction.hpp"
28 #include "script_manager.hpp"
29 #include "math/vector.hpp"
30 #include "video/drawing_context.hpp"
31
32 namespace lisp {
33 class Lisp;
34 class Writer;
35 }
36
37 class Rect;
38 class Sprite;
39 class GameObject;
40 class Player;
41 class Camera;
42 class TileMap;
43 class Bullet;
44 class CollisionGrid;
45 class ScriptInterpreter;
46 class SpawnPoint;
47 class MovingObject;
48 class CollisionHit;
49
50 enum MusicType {
51   LEVEL_MUSIC,
52   HERRING_MUSIC
53 };
54
55 /**
56  * This class holds a sector (a part of a level) and all the game objects in
57  * the sector
58  */
59 class Sector
60 {
61 public:
62   Sector();
63   ~Sector();
64
65   /// read sector from lisp file
66   void parse(const lisp::Lisp& lisp);
67   void parse_old_format(const lisp::Lisp& lisp);
68   /// write sector to lisp file
69   void write(lisp::Writer& writer);
70
71   /// activates this sector (change music, intialize player class, ...)
72   void activate(const std::string& spawnpoint);
73   void activate(const Vector& player_pos);
74   void deactivate();
75
76   void update(float elapsed_time);
77   void update_game_objects();
78
79   void draw(DrawingContext& context);
80
81   /**
82    * runs a script in the context of the sector (sector_table will be the
83    * roottable of this squirrel VM)
84    */
85   HSQUIRRELVM run_script(std::istream& in, const std::string& sourcename);
86
87   /// adds a gameobject
88   void add_object(GameObject* object);
89
90   void set_name(const std::string& name)
91   { this->name = name; }
92   const std::string& get_name() const
93   { return name; }
94
95   /// tests if a given rectangle is inside the sector
96   bool inside(const Rect& rectangle) const;
97
98   void play_music(MusicType musictype);
99   MusicType get_music_type();
100   
101   bool add_bullet(const Vector& pos, float xm, Direction dir);
102   bool add_smoke_cloud(const Vector& pos);
103   void add_floating_text(const Vector& pos, const std::string& text);
104                                                                                 
105   /** get currently activated sector. */
106   static Sector* current()
107   { return _current; }
108
109   /** Get total number of badguys */
110   int get_total_badguys();
111
112   void collision_tilemap(const Rect& dest, const Vector& movement, CollisionHit& hit) const;
113
114   /** Checks if at the specified rectangle are gameobjects with STATIC flag set
115    * (or solid tiles from the tilemap)
116    */
117   bool is_free_space(const Rect& rect) const;
118
119   /**
120    * returns a list of players currently in the sector
121    */
122   std::vector<Player*> get_players() {
123     return std::vector<Player*>(1, this->player);
124   }
125
126   Rect get_active_region();
127
128 private:
129   uint32_t collision_tile_attributes(const Rect& dest) const;
130
131   void before_object_remove(GameObject* object);
132   bool before_object_add(GameObject* object);
133
134   void try_expose(GameObject* object);
135   void try_unexpose(GameObject* object);
136   
137   bool collision_static(MovingObject* object, const Vector& movement);
138   
139   /** Checks for all possible collisions. And calls the
140       collision_handlers, which the collision_objects provide for this
141       case (or not). */
142   void handle_collisions();
143   
144   void collision_object(MovingObject* object1, MovingObject* object2) const;
145   GameObject* parse_object(const std::string& name, const lisp::Lisp& lisp);
146
147   void fix_old_tiles();
148
149   typedef std::vector<GameObject*> GameObjects;
150   typedef std::vector<MovingObject*> MovingObjects;
151   typedef std::vector<SpawnPoint*> SpawnPoints;
152
153   static Sector* _current;
154   
155   std::string name;
156
157   std::vector<Bullet*> bullets;
158
159   std::string init_script;
160
161   /// container for newly created objects, they'll be added in Sector::update
162   GameObjects gameobjects_new;
163  
164   MusicType currentmusic;
165
166   std::auto_ptr<CollisionGrid> grid;
167
168   HSQOBJECT sector_table;
169   /// sector scripts
170   std::auto_ptr<ScriptManager> script_manager;
171
172 public: // TODO make this private again
173   GameObjects gameobjects;
174   MovingObjects moving_objects;
175   SpawnPoints spawnpoints;                       
176
177   std::string music;
178   float gravity;
179
180   // some special objects, where we need direct access
181   // (try to avoid accessing them directly)
182   Player* player;
183   TileMap* solids;
184   Camera* camera;
185 };
186
187 #endif
188