#ifndef SUPERTUX_WORLDMAP_H
#define SUPERTUX_WORLDMAP_H
#include <vector>
#include <string>
#include "musicref.h"
namespace WorldMapNS {
struct Point
{
Point() : x(0), y(0) {}
Point(const Point& pos)
: x(pos.x), y(pos.y) {}
Point& operator=(const Point& pos)
{ x = pos.x;
y = pos.y;
return *this; }
Point(int x_, int y_)
: x(x_), y(y_) {}
int x;
int y;
};
enum {
BOTH_WAYS,
NORTH_SOUTH_WAY,
SOUTH_NORTH_WAY,
EAST_WEST_WAY,
WEST_EAST_WAY
};
class Tile
{
public:
Tile();
~Tile();
Surface* sprite;
bool north;
bool east;
bool south;
bool west;
int one_way;
bool stop;
bool auto_walk;
};
class TileManager
{
private:
typedef std::vector<Tile*> Tiles;
Tiles tiles;
public:
TileManager();
~TileManager();
Tile* get(int i);
};
enum Direction { D_NONE, D_WEST, D_EAST, D_NORTH, D_SOUTH };
std::string direction_to_string(Direction d);
Direction string_to_direction(const std::string& d);
Direction reverse_dir(Direction d);
class WorldMap;
class Tux
{
public:
Direction back_direction;
private:
WorldMap* worldmap;
Surface* largetux_sprite;
Surface* firetux_sprite;
Surface* smalltux_sprite;
Direction input_direction;
Direction direction;
Point tile_pos;
float offset;
bool moving;
void stop();
public:
Tux(WorldMap* worldmap_);
~Tux();
void draw(const Point& offset);
void update(float delta);
void set_direction(Direction d) { input_direction = d; }
bool is_moving() const { return moving; }
Point get_pos();
Point get_tile_pos() const { return tile_pos; }
void set_tile_pos(Point p) { tile_pos = p; }
};
class WorldMap
{
private:
Tux* tux;
bool quit;
Surface* level_sprite;
Surface* leveldot_green;
Surface* leveldot_red;
Surface* leveldot_teleporter;
std::string name;
std::string music;
std::vector<int> tilemap;
int width;
int height;
int start_x;
int start_y;
TileManager* tile_manager;
public:
struct Level
{
int x;
int y;
std::string name;
std::string title;
bool solved;
std::string extro_filename;
std::string display_map_message;
bool passive_message;
int teleport_dest_x;
int teleport_dest_y;
std::string teleport_message;
bool invisible_teleporter;
bool auto_path;
bool apply_action_north;
bool apply_action_east;
bool apply_action_south;
bool apply_action_west;
bool north;
bool east;
bool south;
bool west;
};
Timer passive_message_timer;
std::string passive_message;
private:
typedef std::vector<Level> Levels;
Levels levels;
MusicRef song;
Direction input_direction;
bool enter_level;
Point offset;
std::string savegame_file;
std::string map_file;
void get_level_title(Level* level);
void draw_status();
public:
WorldMap();
~WorldMap();
void set_map_file(std::string mapfile);
void display();
void load_map();
void get_input();
void update(float delta);
void draw(const Point& offset);
Point get_next_tile(Point pos, Direction direction);
Tile* at(Point pos);
WorldMap::Level* at_level();
bool path_ok(Direction direction, Point pos, Point* new_pos);
void savegame(const std::string& filename);
void loadgame(const std::string& filename);
void loadmap(const std::string& filename);
const std::string& get_world_title() const
{ return name; }
const int& get_start_x() const
{ return start_x; }
const int& get_start_y() const
{ return start_y; }
void set_levels_as_solved()
{ for(Levels::iterator i = levels.begin(); i != levels.end(); ++i)
i->solved = true; }
private:
void on_escape_press();
};
}
#endif