1 // Copyright 2015-2016 the openage authors. See copying.md for legal info.
2 
3 #pragma once
4 
5 #include <unordered_set>
6 
7 #include "../coord/tile.h"
8 #include "../gui/guisys/public/gui_property_map.h"
9 
10 namespace qtsdl {
11 class GuiItemLink;
12 } // qtsdl
13 
14 namespace openage {
15 
16 class GameSpec;
17 class Terrain;
18 class GameMain;
19 
20 namespace rng {
21 class RNG;
22 } // openage::rng
23 
24 /**
25  * the type to store a set of tiles
26  */
27 using tileset_t = std::unordered_set<coord::tile>;
28 
29 /**
30  * picks a random tile from a set
31  */
32 coord::tile random_tile(rng::RNG &rng, tileset_t tiles);
33 
34 /**
35  * the four directions available for 2d tiles
36  */
37 constexpr coord::tile_delta const neigh_tiles[] = {
38 	{ 1,  0},
39 	{-1,  0},
40 	{ 0,  1},
41 	{ 0, -1}
42 };
43 
44 /**
45  * A region is a set of tiles around a starting point,
46  * including functions to create child regions
47  */
48 class Region {
49 public:
50 	/**
51 	 * a square of tiles ranging from
52 	 * {-size, -size} to {size, size}
53 	 */
54 	Region(int size);
55 
56 	/**
57 	 * a specified set of tiles
58 	 */
59 	Region(coord::tile center, tileset_t tiles);
60 
61 	/**
62 	 * all tiles in this region
63 	 */
64 	tileset_t get_tiles() const;
65 
66 	/**
67 	 * the center point of the region
68 	 */
69 	coord::tile get_center() const;
70 
71 	/**
72 	 * picks a random tile from this subset
73 	 */
74 	coord::tile get_tile(rng::RNG &rng) const;
75 
76 	/**
77 	 * find a group of tiles inside this region, number is the number of tiles to be contained
78 	 * in the subset, p is a probability between 0.0 and 1.0 which produces various shapes. a value
79 	 * of 1.0 produces circular shapes, where as a low value produces more scattered shapes. a value
80 	 * of 0.0 should not be used, and will always return no tiles
81 	 */
82 	tileset_t subset(rng::RNG &rng, coord::tile start_tile, unsigned int number, double p) const;
83 
84 	/**
85 	 * removes the given set of tiles from this region, which get split of as a new child region
86 	 */
87 	Region take_tiles(rng::RNG &rng, coord::tile start_tile, unsigned int number, double p);
88 
89 	/**
90 	 * similiar to take_tiles, but takes a random group of tiles
91 	 */
92 	Region take_random(rng::RNG &rng, unsigned int number, double p);
93 
94 	/**
95 	 * player id of the owner, 0 for none
96 	 */
97 	int owner;
98 
99 	/**
100 	 * the object to be placed on each tile of this region
101 	 * 0 for placing no object
102 	 */
103 	int object_id;
104 
105 	/**
106 	 * the base terrain for this region
107 	 */
108 	int terrain_id;
109 
110 private:
111 
112 	/**
113 	 * the center tile of this region
114 	 */
115 	coord::tile center;
116 
117 	/**
118 	 * tiles in this region
119 	 */
120 	tileset_t tiles;
121 };
122 
123 
124 /**
125  * Manages creation and setup of new games
126  *
127  * required values used to construct a game
128  * this includes game spec and players
129  *
130  * this will be identical for each networked
131  * player in a game
132  */
133 class Generator : public qtsdl::GuiPropertyMap {
134 public:
135 	explicit Generator(qtsdl::GuiItemLink *gui_link);
136 
137 	/**
138 	 * game spec used by this generator
139 	 */
140 	std::shared_ptr<GameSpec> get_spec() const;
141 
142 	/**
143 	 * return the list of player names
144 	 */
145 	std::vector<std::string> player_names() const;
146 
147 	/**
148 	 * returns the generated terrain
149 	 */
150 	std::shared_ptr<Terrain> terrain() const;
151 
152 	/**
153 	 * places all initial objects
154 	 */
155 	void add_units(GameMain &m) const;
156 
157 	/**
158 	 * Create a game from a specification.
159 	 */
160 	std::unique_ptr<GameMain> create(std::shared_ptr<GameSpec> spec);
161 
162 private:
163 	void create_regions();
164 
165 	/**
166 	 * data version used to create a game
167 	 */
168 	std::shared_ptr<GameSpec> spec;
169 
170 	/**
171 	 * the generated data
172 	 */
173 	std::vector<Region> regions;
174 
175 public:
176 	qtsdl::GuiItemLink *gui_link;
177 };
178 
179 } // namespace openage
180