da17b5de1395b166cd45153e883bcf66d4e1f291
[supertux.git] / src / object / tilemap.hpp
1 //  SuperTux
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_OBJECT_TILEMAP_HPP
18 #define HEADER_SUPERTUX_OBJECT_TILEMAP_HPP
19
20 #include <boost/shared_ptr.hpp>
21
22 #include "object/path_walker.hpp"
23 #include "supertux/game_object.hpp"
24 #include "supertux/script_interface.hpp"
25 #include "video/drawing_context.hpp"
26
27 namespace lisp {
28 class Lisp;
29 }
30
31 class Level;
32 class TileManager;
33 class Tile;
34 class TileSet;
35
36 /**
37  * This class is responsible for drawing the level tiles
38  */
39 class TileMap : public GameObject,
40                 public ScriptInterface
41 {
42 public:
43   TileMap(const TileSet *tileset);
44   TileMap(const Reader& reader);
45   TileMap(const TileSet *tileset, std::string name, int z_pos, bool solid_,
46           size_t width_, size_t height_);
47   virtual ~TileMap();
48
49   virtual void update(float elapsed_time);
50   virtual void draw(DrawingContext& context);
51
52   /** Move tilemap until at given node, then stop */
53   void goto_node(int node_no);
54
55   /** Start moving tilemap */
56   void start_moving();
57
58   /** Stop tilemap at next node */
59   void stop_moving();
60
61   virtual void expose(HSQUIRRELVM vm, SQInteger table_idx);
62   virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx);
63
64   void set(int width, int height, const std::vector<unsigned int>& vec,
65            int z_pos, bool solid);
66
67   /** resizes the tilemap to a new width and height (tries to not destroy the
68    * existing map)
69    */
70   void resize(int newwidth, int newheight, int fill_id = 0);
71
72   size_t get_width() const
73   { return width; }
74
75   size_t get_height() const
76   { return height; }
77
78   Vector get_offset() const
79   { return offset; }
80
81   /** Get the movement of this tilemap. The collision detection code may need a
82    *  non-negative y-movement. Passing `false' as the `actual' argument will
83    *  provide that. Used exclusively in src/supertux/sector.cpp. */
84   Vector get_movement(bool actual) const
85   {
86     if(actual) {
87       return movement;
88     } else {
89       return Vector(movement.x, std::max(0.0f,movement.y));
90     }
91   }
92
93   boost::shared_ptr<Path> get_path()
94   { return path; }
95
96   boost::shared_ptr<PathWalker> get_walker()
97   { return walker; }
98
99   void set_offset(const Vector &offset_)
100   { this->offset = offset_; }
101
102   /* Returns the position of the upper-left corner of
103    * tile (x, y) in the sector. */
104   Vector get_tile_position(int x, int y) const
105   { return offset + Vector(x,y) * 32; }
106
107   Rectf get_bbox() const
108   { return Rectf(get_tile_position(0, 0), get_tile_position(width, height)); }
109
110   Rectf get_tile_bbox(int x, int y) const
111   { return Rectf(get_tile_position(x, y), get_tile_position(x+1, y+1)); }
112
113   /* Returns the half-open rectangle of (x, y) tile indices
114    * that overlap the given rectangle in the sector. */
115   Rect get_tiles_overlapping(const Rectf &rect) const;
116
117   int get_layer() const
118   { return z_pos; }
119
120   bool is_solid() const
121   { return real_solid && effective_solid; }
122
123   /**
124    * Changes Tilemap's solidity, i.e. whether to consider it when doing collision detection.
125    */
126   void set_solid(bool solid = true);
127
128   /// returns tile in row y and column y (of the tilemap)
129   const Tile* get_tile(int x, int y) const;
130   /// returns tile at position pos (in world coordinates)
131   const Tile* get_tile_at(const Vector& pos) const;
132   /// returns tile in row y and column y (of the tilemap)
133   uint32_t get_tile_id(int x, int y) const;
134   /// returns tile at position pos (in world coordinates)
135   uint32_t get_tile_id_at(const Vector& pos) const;
136
137   void change(int x, int y, uint32_t newtile);
138
139   void change_at(const Vector& pos, uint32_t newtile);
140
141   /// changes all tiles with the given ID
142   void change_all(uint32_t oldtile, uint32_t newtile);
143
144   void set_drawing_effect(DrawingEffect effect)
145   {
146     drawing_effect = effect;
147   }
148
149   DrawingEffect get_drawing_effect()
150   {
151     return drawing_effect;
152   }
153
154   /**
155    * Start fading the tilemap to opacity given by @c alpha.
156    * Destination opacity will be reached after @c seconds seconds. Also influences solidity.
157    */
158   void fade(float alpha, float seconds = 0);
159
160   /**
161    * Instantly switch tilemap's opacity to @c alpha. Also influences solidity.
162    */
163   void set_alpha(float alpha);
164
165   /**
166    * Return tilemap's opacity. Note that while the tilemap is fading in or out, this will return the current alpha value, not the target alpha.
167    */
168   float get_alpha();
169
170 private:
171   const TileSet *tileset;
172
173   typedef std::vector<uint32_t> Tiles;
174   Tiles tiles;
175
176   /* read solid: In *general*, is this a solid layer?
177    * effective solid: is the layer *currently* solid? A generally solid layer
178    * may be not solid when its alpha is low.
179    * See `is_solid' above. */
180   bool real_solid;
181   bool effective_solid;
182   void update_effective_solid (void);
183
184   float speed_x;
185   float speed_y;
186   int width, height;
187   int z_pos;
188   Vector offset;
189   Vector movement; /**< The movement that happened last frame */
190
191   DrawingEffect drawing_effect;
192   float alpha; /**< requested tilemap opacity */
193   float current_alpha; /**< current tilemap opacity */
194   float remaining_fade_time; /**< seconds until requested tilemap opacity is reached */
195
196   boost::shared_ptr<Path> path;
197   boost::shared_ptr<PathWalker> walker;
198
199   DrawingContext::Target draw_target; /**< set to LIGHTMAP to draw to lightmap */
200
201 private:
202   TileMap(const TileMap&);
203   TileMap& operator=(const TileMap&);
204 };
205
206 #endif /*SUPERTUX_TILEMAP_H*/
207
208 /* EOF */