1 /*
2  * Copyright (C) 2006-2019 Christopho, Solarus - http://www.solarus-games.org
3  *
4  * Solarus 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  * Solarus 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 along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #include "solarus/core/Debug.h"
18 #include "solarus/core/Game.h"
19 #include "solarus/core/Map.h"
20 #include "solarus/core/QuestFiles.h"
21 #include "solarus/core/ResourceProvider.h"
22 #include "solarus/entities/Camera.h"
23 #include "solarus/entities/DynamicTile.h"
24 #include "solarus/entities/Hero.h"
25 #include "solarus/entities/Tileset.h"
26 #include "solarus/entities/TilePattern.h"
27 
28 namespace Solarus {
29 
30 /**
31  * \brief Creates a new dynamic tile on the map.
32  * \param name A name to identify this entity.
33  * \param layer Layer of the tile.
34  * \param xy Coordinates of the tile on the map.
35  * \param size Size of the tile (the pattern can be repeated).
36  * \param tile_pattern_id Id of the tile pattern in the tileset.
37  * \param tile_pattern The tile pattern, or nullptr if it does not exist in the tileset.
38  * \param tileset The tileset to use (nullptr means the one of the map).
39  */
DynamicTile(const std::string & name,int layer,const Point & xy,const Size & size,const std::string & tile_pattern_id,const std::shared_ptr<TilePattern> & tile_pattern,const Tileset * tileset)40 DynamicTile::DynamicTile(
41     const std::string& name,
42     int layer,
43     const Point& xy,
44     const Size& size,
45     const std::string& tile_pattern_id,
46     const std::shared_ptr<TilePattern>& tile_pattern,
47     const Tileset* tileset
48 ) :
49   Entity(name, 0, layer, xy, size),
50   tile_pattern_id(tile_pattern_id),
51   tile_pattern(tile_pattern),
52   tileset(tileset) {
53 
54   set_tiled(true);
55 }
56 
57 /**
58  * \brief Returns the type of entity.
59  * \return the type of entity
60  */
get_type() const61 EntityType DynamicTile::get_type() const {
62   return ThisType;
63 }
64 
65 /**
66  * \brief Returns the id of the pattern of this dynamic tile.
67  * \return The tile pattern id.
68  */
get_tile_pattern_id() const69 const std::string& DynamicTile::get_tile_pattern_id() const {
70   return tile_pattern_id;
71 }
72 
73 /**
74  * \brief When is_ground_modifier() is \c true, returns the ground defined
75  * by this entity.
76  * \return The ground defined by this entity.
77  */
get_modified_ground() const78 Ground DynamicTile::get_modified_ground() const {
79 
80   if (tile_pattern == nullptr) {
81     return Ground::EMPTY;
82   }
83   return tile_pattern->get_ground();
84 }
85 
86 /**
87  * \brief Returns the tileset of this dynamic tile.
88  * \return The tileset used (\c nullptr if map's tileset is used).
89  */
get_tileset() const90 const Tileset* DynamicTile::get_tileset() const {
91   return this->tileset;
92 }
93 
94 /**
95  * \brief Set the tileset for this dynamic tile.
96  * \param tileset The tileset (\c nullptr to use the map's tileset).
97  */
set_tileset(const Tileset * tileset)98 void DynamicTile::set_tileset(const Tileset* tileset) {
99     this->tileset = tileset;
100 }
101 
102 /**
103  * \brief Set the tileset for this dynamic tile by tileset id.
104  * \param tileset_id Id of the tileset to use.
105  */
set_tileset(const std::string & tileset_id)106 void DynamicTile::set_tileset(const std::string& tileset_id) {
107     tileset = &get_game().get_resource_provider().get_tileset(tileset_id);
108 }
109 
110 /**
111  * \copydoc Entity::is_drawn_at_its_position()
112  */
is_drawn_at_its_position() const113 bool DynamicTile::is_drawn_at_its_position() const {
114 
115   if (tile_pattern == nullptr) {
116     return true;
117   }
118   return tile_pattern->is_drawn_at_its_position();
119 }
120 
121 /**
122  * \copydoc Entity::built_in_draw
123  */
built_in_draw(Camera & camera)124 void DynamicTile::built_in_draw(Camera& camera) {
125 
126   if (tile_pattern != nullptr) {
127     const Rectangle& camera_position = camera.get_bounding_box();
128 
129     Rectangle dst_position(get_top_left_x() - camera_position.get_x(),
130         get_top_left_y() - camera_position.get_y(),
131         get_width(), get_height());
132 
133     const Tileset* tileset = this->tileset != nullptr ? this->tileset : &get_map().get_tileset();
134     tile_pattern->fill_surface(
135         camera.get_surface(),
136         dst_position,
137         *tileset,
138         camera_position.get_xy()
139     );
140   }
141 
142   Entity::built_in_draw(camera);
143 }
144 
145 /**
146  * \copydoc Entity::notify_tileset_changed
147  */
notify_tileset_changed()148 void DynamicTile::notify_tileset_changed() {
149 
150   // The tileset of the map has changed.
151   // Update the pattern if we use that tileset.
152   if (tileset == nullptr) {
153     tile_pattern = get_map().get_tileset().get_tile_pattern(tile_pattern_id);
154   }
155 }
156 
157 }
158