1 //  $Id: worldmap.h 1746 2004-08-11 11:09:42Z wansti $
2 //
3 //  SuperTux
4 //  Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 
20 #ifndef SUPERTUX_WORLDMAP_H
21 #define SUPERTUX_WORLDMAP_H
22 
23 #include <vector>
24 #include <string>
25 
26 #include "musicref.h"
27 
28 namespace WorldMapNS {
29 
30 struct Point
31 {
PointPoint32   Point() : x(0), y(0) {}
33 
PointPoint34   Point(const Point& pos)
35     : x(pos.x), y(pos.y) {}
36 
37   Point& operator=(const Point& pos)
38   { x = pos.x;
39     y = pos.y;
40     return *this; }
41 
PointPoint42   Point(int x_, int y_)
43     : x(x_), y(y_) {}
44 
45   int x;
46   int y;
47 };
48 
49 // For one way tiles
50 enum {
51   BOTH_WAYS,
52   NORTH_SOUTH_WAY,
53   SOUTH_NORTH_WAY,
54   EAST_WEST_WAY,
55   WEST_EAST_WAY
56   };
57 
58 class Tile
59 {
60 public:
61   Tile();
62   ~Tile();
63 
64   Surface* sprite;
65 
66   // Directions in which Tux is allowed to walk from this tile
67   bool north;
68   bool east;
69   bool south;
70   bool west;
71 
72   /** One way tile */
73   int one_way;
74 
75   /** Stop on this tile or walk over it? */
76   bool stop;
77 
78   /** When set automatically turn directions when walked over such a
79       tile (ie. walk smoothly a curve) */
80   bool auto_walk;
81 };
82 
83 class TileManager
84 {
85 private:
86   typedef std::vector<Tile*> Tiles;
87   Tiles tiles;
88 
89 public:
90   TileManager();
91   ~TileManager();
92 
93   Tile* get(int i);
94 };
95 
96 enum Direction { D_NONE, D_WEST, D_EAST, D_NORTH, D_SOUTH };
97 
98 std::string direction_to_string(Direction d);
99 Direction   string_to_direction(const std::string& d);
100 Direction reverse_dir(Direction d);
101 
102 class WorldMap;
103 
104 class Tux
105 {
106 public:
107   Direction back_direction;
108 private:
109   WorldMap* worldmap;
110   Surface* largetux_sprite;
111   Surface* firetux_sprite;
112   Surface* smalltux_sprite;
113 
114   Direction input_direction;
115   Direction direction;
116   Point tile_pos;
117   /** Length by which tux is away from its current tile, length is in
118       input_direction direction */
119   float offset;
120   bool  moving;
121 
122   void stop();
123 public:
124   Tux(WorldMap* worldmap_);
125   ~Tux();
126 
127   void draw(const Point& offset);
128   void update(float delta);
129 
set_direction(Direction d)130   void set_direction(Direction d) { input_direction = d; }
131 
is_moving()132   bool is_moving() const { return moving; }
133   Point get_pos();
get_tile_pos()134   Point get_tile_pos() const { return tile_pos; }
set_tile_pos(Point p)135   void  set_tile_pos(Point p) { tile_pos = p; }
136 };
137 
138 /** */
139 class WorldMap
140 {
141 private:
142   Tux* tux;
143 
144   bool quit;
145 
146   Surface* level_sprite;
147   Surface* leveldot_green;
148   Surface* leveldot_red;
149   Surface* leveldot_teleporter;
150 
151   std::string name;
152   std::string music;
153 
154   std::vector<int> tilemap;
155   int width;
156   int height;
157 
158   int start_x;
159   int start_y;
160 
161   TileManager* tile_manager;
162 
163 public:
164   struct Level
165   {
166     int x;
167     int y;
168     std::string name;
169     std::string title;
170     bool solved;
171 
172     /** Filename of the extro text to show once the level is
173         successfully completed */
174     std::string extro_filename;
175 
176     /** Message to show in the Map during a certain time */
177     std::string display_map_message;
178     bool passive_message;
179 
180 	 /** Teleporters */
181 	 int teleport_dest_x;
182 	 int teleport_dest_y;
183 	 std::string teleport_message;
184 	 bool invisible_teleporter;
185 
186     /** If false, disables the auto walking after finishing a level */
187     bool auto_path;
188 
189     /** Only applies actions (ie. map messages) when going to that direction */
190     bool apply_action_north;
191     bool apply_action_east;
192     bool apply_action_south;
193     bool apply_action_west;
194 
195     // Directions which are walkable from this level
196     bool north;
197     bool east;
198     bool south;
199     bool west;
200   };
201 
202   /** Variables to deal with the passive map messages */
203   Timer passive_message_timer;
204   std::string passive_message;
205 
206 private:
207   typedef std::vector<Level> Levels;
208   Levels levels;
209 
210   MusicRef song;
211 
212   Direction input_direction;
213   bool enter_level;
214 
215   Point offset;
216   std::string savegame_file;
217   std::string map_file;
218 
219   void get_level_title(Levels::pointer level);
220 
221   void draw_status();
222 public:
223   WorldMap();
224   ~WorldMap();
225 
226   void set_map_file(std::string mapfile);
227 
228   /** Busy loop */
229   void display();
230 
231   void load_map();
232 
233   void get_input();
234 
235   /** Update Tux position */
236   void update(float delta);
237 
238   /** Draw one frame */
239   void draw(const Point& offset);
240 
241   Point get_next_tile(Point pos, Direction direction);
242   Tile* at(Point pos);
243   WorldMap::Level* at_level();
244 
245   /** Check if it is possible to walk from \a pos into \a direction,
246       if possible, write the new position to \a new_pos */
247   bool path_ok(Direction direction, Point pos, Point* new_pos);
248 
249   void savegame(const std::string& filename);
250   void loadgame(const std::string& filename);
251   void loadmap(const std::string& filename);
252 
get_world_title()253   const std::string& get_world_title() const
254     { return name; }
255 
get_start_x()256   const int& get_start_x() const
257     { return start_x; }
258 
get_start_y()259   const int& get_start_y() const
260     { return start_y; }
261 
262   /** This functions should be call by contrib menu to set
263      all levels as played, since their state is not saved. */
set_levels_as_solved()264   void set_levels_as_solved()
265     { for(Levels::iterator i = levels.begin(); i != levels.end(); ++i)
266         i->solved = true;  }
267 
268 private:
269   void on_escape_press();
270 };
271 
272 } // namespace WorldMapNS
273 
274 #endif
275 
276 /* Local Variables: */
277 /* mode:c++ */
278 /* End: */
279