1 //  SuperTux -  A Jump'n Run
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (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, see <http://www.gnu.org/licenses/>.
16 
17 #ifndef HEADER_SUPERTUX_SUPERTUX_SECTOR_HPP
18 #define HEADER_SUPERTUX_SUPERTUX_SECTOR_HPP
19 
20 #include <vector>
21 #include <stdint.h>
22 
23 #include "math/anchor_point.hpp"
24 #include "math/easing.hpp"
25 #include "math/fwd.hpp"
26 #include "squirrel/squirrel_environment.hpp"
27 #include "supertux/d_scope.hpp"
28 #include "supertux/game_object_manager.hpp"
29 #include "supertux/tile.hpp"
30 #include "video/color.hpp"
31 
32 namespace collision {
33 class Constraints;
34 }
35 
36 class Camera;
37 class CollisionSystem;
38 class CollisionGroundMovementManager;
39 class DisplayEffect;
40 class DrawingContext;
41 class Level;
42 class MovingObject;
43 class Player;
44 class ReaderMapping;
45 class Rectf;
46 class Size;
47 class TileMap;
48 class Writer;
49 
50 /** Represents one of (potentially) multiple, separate parts of a Level.
51     Sectors contain GameObjects, e.g. Badguys and Players. */
52 class Sector final : public GameObjectManager
53 {
54 public:
55   friend class CollisionSystem;
56   friend class EditorSectorMenu;
57 
58 private:
59   static Sector* s_current;
60 
61 public:
62   /** get currently activated sector. */
get()63   static Sector& get() { assert(s_current != nullptr); return *s_current; }
current()64   static Sector* current() { return s_current; }
65 
66 public:
67   Sector(Level& parent);
68   ~Sector() override;
69 
70   /** Needs to be called after parsing to finish the construction of
71       the Sector before using it. */
72   void finish_construction(bool editable);
73 
74   Level& get_level() const;
75 
76   /** activates this sector (change music, initialize player class, ...) */
77   void activate(const std::string& spawnpoint);
78   void activate(const Vector& player_pos);
79   void deactivate();
80 
81   void update(float dt_sec);
82 
83   void draw(DrawingContext& context);
84 
85   void save(Writer &writer);
86 
87   /** stops all looping sounds in whole sector. */
88   void stop_looping_sounds();
89 
90   /** continues the looping sounds in whole sector. */
91   void play_looping_sounds();
92 
set_name(const std::string & name_)93   void set_name(const std::string& name_) { m_name = name_; }
get_name() const94   const std::string& get_name() const { return m_name; }
95 
96   /** tests if a given rectangle is inside the sector
97       (a rectangle that is on top of the sector is considered inside) */
98   bool inside(const Rectf& rectangle) const;
99 
100   /** Checks if the specified rectangle is free of (solid) tiles.
101       Note that this does not include static objects, e.g. bonus blocks. */
102   bool is_free_of_tiles(const Rectf& rect, const bool ignoreUnisolid = false, uint32_t tiletype = Tile::SOLID) const;
103 
104   /** Checks if the specified rectangle is free of both
105       1.) solid tiles and
106       2.) MovingObjects in COLGROUP_STATIC.
107       Note that this does not include badguys or players. */
108   bool is_free_of_statics(const Rectf& rect, const MovingObject* ignore_object = nullptr, const bool ignoreUnisolid = false) const;
109 
110   /** Checks if the specified rectangle is free of both
111       1.) solid tiles and
112       2.) MovingObjects in COLGROUP_STATIC, COLGROUP_MOVINGSTATIC or COLGROUP_MOVING.
113       This includes badguys and players. */
114   bool is_free_of_movingstatics(const Rectf& rect, const MovingObject* ignore_object = nullptr) const;
115 
116   bool free_line_of_sight(const Vector& line_start, const Vector& line_end, bool ignore_objects = false, const MovingObject* ignore_object = nullptr) const;
117   bool can_see_player(const Vector& eye) const;
118 
119   Player* get_nearest_player (const Vector& pos) const;
get_nearest_player(const Rectf & pos) const120   Player* get_nearest_player (const Rectf& pos) const {
121     return (get_nearest_player (get_anchor_pos (pos, ANCHOR_MIDDLE)));
122   }
123 
124   std::vector<MovingObject*> get_nearby_objects (const Vector& center, float max_distance) const;
125 
126   Rectf get_active_region() const;
127 
128   int get_foremost_layer() const;
129 
130   /** returns the editor size (in tiles) of a sector */
131   Size get_editor_size() const;
132 
133   /** resize all tilemaps with given size */
134   void resize_sector(const Size& old_size, const Size& new_size, const Size& resize_offset);
135 
136   /** globally changes solid tilemaps' tile ids */
137   void change_solid_tiles(uint32_t old_tile_id, uint32_t new_tile_id);
138 
139   /** set gravity throughout sector */
140   void set_gravity(float gravity);
141   float get_gravity() const;
142 
set_init_script(const std::string & init_script)143   void set_init_script(const std::string& init_script) {
144     m_init_script = init_script;
145   }
146 
147   void run_script(const std::string& script, const std::string& sourcename);
148 
149   Camera& get_camera() const;
150   Player& get_player() const;
151   DisplayEffect& get_effect() const;
152 
153 private:
154   uint32_t collision_tile_attributes(const Rectf& dest, const Vector& mov) const;
155 
156   virtual bool before_object_add(GameObject& object) override;
157   virtual void before_object_remove(GameObject& object) override;
158 
159   int calculate_foremost_layer() const;
160 
161   /** Convert tiles into their corresponding GameObjects (e.g.
162       bonusblocks, add light to lava tiles) */
163   void convert_tiles2gameobject();
164 
165 private:
166   /** Parent level containing this sector */
167   Level& m_level;
168 
169   std::string m_name;
170 
171   bool m_fully_constructed;
172 
173   std::string m_init_script;
174 
175   int m_foremost_layer;
176 
177   std::unique_ptr<SquirrelEnvironment> m_squirrel_environment;
178   std::unique_ptr<CollisionSystem> m_collision_system;
179 
180   float m_gravity;
181 
182 private:
183   Sector(const Sector&) = delete;
184   Sector& operator=(const Sector&) = delete;
185 };
186 
187 #endif
188 
189 /* EOF */
190