1 //
2 //  Copyright (C) 2009  Nick Gasson
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 
18 #ifndef INC_IMAP_HPP
19 #define INC_IMAP_HPP
20 
21 #include "IGraphics.hpp"
22 #include "ITrackSegment.hpp"
23 #include "IStation.hpp"
24 #include "IResource.hpp"
25 #include "IScenery.hpp"
26 #include "Colour.hpp"
27 
28 #include <memory>
29 #include <string>
30 
31 // A map is a MxN array of floating point height values
32 // It also contains the track layout and any scenery items
33 class IMap {
34 public:
35    virtual int width() const = 0;
36    virtual int depth() const = 0;
37 
38    // Return the track segment at the given position
39    // It is invalid to call this with a position that doesn't
40    // contain the *origin* of a track segment -- call is_valid_track
41    // first
42    virtual ITrackSegmentPtr track_at(const Point<int>& a_point) const = 0;
43 
44    // True if the given position is the origin of a track segment
45    virtual bool is_valid_track(const Point<int>& a_point) const = 0;
46 
47    // Change the track segment at the given position
48    // Set rebuild to true to update the display lists used to render
49    // the map
50    virtual void set_track_at(const Point<int>& a_point,
51       ITrackSegmentPtr a_track) = 0;
52 
53    // Return the station at this track location or a null pointer
54    virtual IStationPtr station_at(Point<int> a_point) const = 0;
55 
56    // Delete the contents of a tile
57    virtual void erase_tile(int x, int y) = 0;
58 
59    // False if this tile has something in it (track, scenery, etc.)
60    virtual bool empty_tile(Point<int> point) const = 0;
61 
62    // The start location consists of both a position and
63    // a direction vector
64    virtual track::Connection start() const = 0;
65 
66    virtual void render(IGraphicsPtr a_context) const = 0;
67 
68    // Draw a coloured highlight over the given tile
69    virtual void highlight_tile(Point<int> point, Colour colour) const = 0;
70 
71    // Given a pick name return the (x, y) co-ordinate
72    virtual Point<int> pick_position(unsigned a_name) const = 0;
73 
74    // True if this names a valid tile
75    virtual bool is_valid_tileName(unsigned a_name) const = 0;
76 
77    // Save the map to its resource
78    virtual void save() = 0;
79 
80    // Return the name of the map resource
81    virtual string name() const = 0;
82 
83    // Change the start location
84    // The second variant allows setting the direction as well
85    virtual void set_start(int x, int y) = 0;
86    virtual void set_start(int x, int y, int dirX, int dirY) = 0;
87 
88    // Toggle display of grid lines
89    virtual void set_grid(bool on_off) = 0;
90 
91    // Toggle pick mode on and off
92    // This turns of display of everything but the terrain
93    // and things that can be clicked on
94    virtual void set_pick_mode(bool on_off) = 0;
95 
96    // Make a hill or valley in the given area
97    virtual void raise_area(const Point<int>& a_start_pos,
98       const Point<int>& a_finish_pos) = 0;
99    virtual void lower_area(const Point<int>& a_start_pos,
100       const Point<int>& a_finish_pos) = 0;
101 
102    // Make all tiles in the area the same height
103    virtual void level_area(Point<int> a_start_pos, Point<int> a_finish_pos) = 0;
104 
105    // Smooth the gradient along a strip
106    virtual void smooth_area(Point<int> start, Point<int> finish) = 0;
107 
108    // Create a new station covering this area or extend an existing station
109    virtual IStationPtr extend_station(Point<int> a_start_pos,
110       Point<int> a_finish_pos) = 0;
111 
112    // Get the height above ground at a particular point
113    virtual float height_at(float x, float y) const = 0;
114    virtual float height_at(Point<int> where) const = 0;
115 
116    // Given a tile and an axis, return a vector indicating the slope
117    // along that axis. `level' is set if the slope is the same across
118    // the tile
119    virtual Vector<float> slope_at(Point<int> where,
120       track::Direction axis, bool& level) const = 0;
121 
122    // Similar to slope_at, but calculates slope of tile before and
123    // after along `axis'
124    virtual Vector<float> slope_before(Point<int> where,
125       track::Direction axis, bool &valid) const = 0;
126    virtual Vector<float> slope_after(Point<int> where,
127       track::Direction axis, bool &valid) const = 0;
128 
129    // Place a tree, building, etc. at a location
130    virtual void add_scenery(Point<int> where, ISceneryPtr s) = 0;
131 
132 };
133 
134 typedef shared_ptr<IMap> IMapPtr;
135 
136 // Make an empty map inside a resource
137 IMapPtr make_empty_map(const string& a_res_id, int a_width, int a_height);
138 
139 // Load a map from a resource
140 IMapPtr load_map(const string& a_res_id);
141 
142 #endif
143