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