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