--- /dev/null
+#ifndef LIBR2C2_TERRAIN_H_
+#define LIBR2C2_TERRAIN_H_
+
+#include "object.h"
+#include "terraintype.h"
+
+namespace R2C2 {
+
+class Terrain: public Object
+{
+public:
+ class Loader: public Msp::DataFile::ObjectLoader<Terrain>
+ {
+ private:
+ unsigned next_tile;
+
+ public:
+ Loader(Terrain &);
+
+ private:
+ void position(float, float, float);
+ void rotation(float);
+ void size(unsigned, unsigned);
+ void tile();
+ void tile_coords(unsigned, unsigned);
+ };
+
+ struct Node
+ {
+ class Loader: public Msp::DataFile::ObjectLoader<Node>
+ {
+ private:
+ Terrain &terrain;
+
+ public:
+ Loader(Terrain &, Node &);
+
+ private:
+ void ground(unsigned);
+ };
+
+ float elevation;
+ unsigned ground;
+ unsigned wall;
+
+ Node();
+
+ void save(std::list<Msp::DataFile::Statement> &) const;
+ };
+
+ struct Tile
+ {
+ class Loader: public Msp::DataFile::ObjectLoader<Tile>
+ {
+ private:
+ Terrain &terrain;
+
+ public:
+ Loader(Terrain &, Tile &);
+
+ private:
+ void ground(unsigned);
+ void elevation(float);
+ void node(unsigned);
+ };
+
+ Node nodes[4];
+ bool secondary_axis;
+
+ Tile();
+
+ void save(std::list<Msp::DataFile::Statement> &) const;
+ };
+
+ struct NodeCoordinates
+ {
+ unsigned x, y;
+ unsigned i;
+
+ NodeCoordinates();
+ NodeCoordinates(unsigned, unsigned, unsigned);
+ };
+
+ sigc::signal<void, unsigned, unsigned> signal_size_changed;
+ sigc::signal<void, unsigned, unsigned> signal_tile_changed;
+
+private:
+ const TerrainType &type;
+ unsigned width;
+ unsigned height;
+ std::vector<Tile> tiles;
+
+public:
+ Terrain(Layout &, const TerrainType &);
+ virtual ~Terrain();
+
+ virtual Terrain *clone(Layout *) const;
+
+ virtual const TerrainType &get_type() const { return type; }
+ virtual void set_position(const Vector &);
+ virtual void set_rotation(const Angle &);
+ virtual void set_tilt(const Angle &) { }
+
+ void set_size(unsigned, unsigned);
+ unsigned get_width() const { return width; }
+ unsigned get_height() const { return height; }
+ const Tile &get_tile(unsigned, unsigned) const;
+ void set_node_elevation(const NodeCoordinates &, float, bool = false);
+ float get_node_elevation(const NodeCoordinates &) const;
+ Vector get_node_position(const NodeCoordinates &) const;
+ NodeCoordinates get_closest_node(const Ray &) const;
+
+ void save(std::list<Msp::DataFile::Statement> &) const;
+};
+
+} // namespace R2C2
+
+#endif