29 #define LOG_NG LOG_STREAM(info, log_engine)
32 #define ERR_WML LOG_STREAM(err, log_wml)
44 flipx_chance_(cfg_[
"flipx_chance"]),
45 flipy_chance_(cfg_[
"flipy_chance"])
70 y = params.height_ - y - 1;
79 return res[
"map_data"];
93 , starting_positions_()
97 , res_(params.
cfg_.child_or_empty(
"settings"))
102 "deprecated_message",
config {
103 "what",
"scenario_generation=cave",
105 "message",
"Use the Lua cave generator instead, with scenario_generation=lua and create_scenario= (see wiki for details).",
110 LOG_NG <<
"creating random cave with seed: " << seed;
114 LOG_NG <<
"creating scenario....";
117 LOG_NG <<
"placing chambers...";
122 LOG_NG <<
"placing passages...";
127 LOG_NG <<
"outputting map....";
134 if(
size == 0 || locs.count(loc) != 0 || !params.on_board(loc))
140 if(
static_cast<int>(rng_() % 100) < (100l -
static_cast<long>(jagged))) {
141 build_chamber(adj,locs,
size-1,jagged);
151 if (ch.has_attribute(
"chance") &&
static_cast<int>(rng_() % 100) < ch[
"chance"].to_int()) {
155 const std::string &xpos = ch[
"x"];
156 const std::string &ypos = ch[
"y"];
158 std::size_t min_xpos = 0, min_ypos = 0, max_xpos = params.width_, max_ypos = params.height_;
162 if(
items.empty() ==
false) {
164 min_xpos = std::stoi(
items.front()) - 1;
165 max_xpos = std::stoi(
items.back());
166 }
catch(
const std::invalid_argument&) {
167 lg::log_to_chat() <<
"Invalid min/max coordinates in cave_map_generator: " <<
items.front() <<
", " <<
items.back() <<
"\n";
168 ERR_WML <<
"Invalid min/max coordinates in cave_map_generator: " <<
items.front() <<
", " <<
items.back();
176 if(
items.empty() ==
false) {
178 min_ypos = std::stoi(
items.front()) - 1;
179 max_ypos = std::stoi(
items.back());
180 }
catch(
const std::invalid_argument&) {
181 lg::log_to_chat() <<
"Invalid min/max coordinates in cave_map_generator: " <<
items.front() <<
", " <<
items.back() <<
"\n";
182 ERR_WML <<
"Invalid min/max coordinates in cave_map_generator: " <<
items.front() <<
", " <<
items.back();
186 const std::size_t x = translate_x(min_xpos + (rng_()%(max_xpos-min_xpos)));
187 const std::size_t y = translate_y(min_ypos + (rng_()%(max_ypos-min_ypos)));
189 int chamber_size = ch[
"size"].to_int(3);
190 int jagged_edges = ch[
"jagged"];
194 build_chamber(new_chamber.
center,new_chamber.
locs,chamber_size,jagged_edges);
196 auto items = ch.optional_child(
"items");
199 const std::string &
id = ch[
"id"];
201 chamber_ids_[
id] = chambers_.size();
204 chambers_.push_back(new_chamber);
206 for(
const config &
p : ch.child_range(
"passage"))
208 const std::string &dst =
p[
"destination"];
211 const std::map<std::string,std::size_t>::const_iterator itor = chamber_ids_.find(dst);
212 if(itor == chamber_ids_.end())
215 assert(itor->second < chambers_.size());
217 passages_.emplace_back(new_chamber.
center, chambers_[itor->second].center,
p);
224 for(std::set<map_location>::const_iterator
i =
c.locs.begin();
i !=
c.locs.end(); ++
i) {
225 set_terrain(*
i,params.clear_);
228 if (
c.items ==
nullptr ||
c.locs.empty())
return;
230 std::size_t
index = 0;
235 config* object_filter =
nullptr;
237 if (
auto of = object->optional_child(
"filter")) {
238 object_filter = &*of;
242 if (!it.cfg[
"same_location_as_previous"].to_bool()) {
243 index = rng_()%
c.locs.size();
245 std::string loc_var = it.cfg[
"store_location_as"];
247 std::set<map_location>::const_iterator loc =
c.locs.begin();
248 std::advance(loc,
index);
250 cfg[
"x"] = loc->x + 1;
251 cfg[
"y"] = loc->y + 1;
254 filter[
"x"] = loc->x + 1;
255 filter[
"y"] = loc->y + 1;
259 (*object_filter)[
"x"] = loc->x + 1;
260 (*object_filter)[
"y"] = loc->y + 1;
264 if (it.key ==
"side" && !it.cfg[
"no_castle"].to_bool()) {
265 place_castle(it.cfg[
"side"].to_int(-1), *loc);
268 res_.add_child(it.key, cfg);
270 if(!loc_var.empty()) {
272 temp[
"name"] =
"prestart";
274 xcfg[
"name"] = loc_var +
"_x";
275 xcfg[
"value"] = loc->x + 1;
277 ycfg[
"name"] = loc_var +
"_y";
278 ycfg[
"value"] = loc->y + 1;
287 double laziness, std::size_t windiness,
289 map_(mapdata),
wall_(wall), laziness_(laziness), windiness_(windiness), rng_(rng)
292 virtual double cost(
const map_location& loc,
const double so_far)
const;
309 res *=
static_cast<double>(rng_()%windiness_);
317 const std::string& chance =
p.cfg[
"chance"];
318 if(!chance.empty() &&
static_cast<int>(rng_()%100) < std::stoi(chance)) {
323 int windiness =
p.cfg[
"windiness"];
324 double laziness = std::max<double>(1.0,
p.cfg[
"laziness"].to_double());
330 int width = std::max<int>(1,
p.cfg[
"width"].to_int());
331 int jagged =
p.cfg[
"jagged"];
333 for(std::vector<map_location>::const_iterator
i = rt.
steps.begin();
i != rt.
steps.end(); ++
i) {
334 std::set<map_location> locs;
335 build_chamber(*
i,locs,width,jagged);
336 for(std::set<map_location>::const_iterator j = locs.begin(); j != locs.end(); ++j) {
337 set_terrain(*j, params.clear_);
344 if (params.on_board(loc)) {
347 if(
c == params.clear_ ||
c == params.wall_ ||
c == params.village_) {
349 if (
t == params.clear_ &&
static_cast<int>(rng_() % 1000) < params.village_density_ )
360 if (starting_position != -1) {
361 set_terrain(loc, params.keep_);
366 starting_positions_.insert(t_translation::starting_positions::value_type(std::to_string(starting_position), coord));
370 set_terrain(adj, params.castle_);
static lg::log_domain log_engine("engine")
static lg::log_domain log_wml("wml")
cave_map_generator(const config &game_config)
std::string create_map(std::optional< uint32_t > randomseed={})
Creates a new map and returns it.
config create_scenario(std::optional< uint32_t > randomseed={})
std::string config_name() const
Return a friendly name for the generator used to differentiate between different configs of the same ...
t_translation::terrain_code wall_
A config object defines a single node in a WML file, with access to child nodes.
child_itors child_range(config_key_type key)
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Euivalent to mandatory_child, but returns an empty optional if the nth child was not found.
config & add_child(config_key_type key)
static const int default_border
The default border style for a map.
Encapsulates the map of the game.
std::string id
Text to match against addon_info.tags()
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Standard logging facilities (interface).
std::stringstream & log_to_chat()
Use this to show WML errors in the ingame chat.
const std::vector< std::string > items
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator &calc, const std::size_t width, const std::size_t height, const teleport_map *teleports, bool border)
const terrain_code CAVE_WALL
std::string write_game_map(const ter_map &map, const starting_positions &starting_positions, coordinate border_offset)
Write a gamemap in to a vector string.
const terrain_code DWARVEN_KEEP
const terrain_code UNDERGROUND_VILLAGE
const terrain_code DWARVEN_CASTLE
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
std::vector< std::string > split(const config_attribute_value &val)
This module contains various pathfinding functions and utilities.
std::set< map_location > locs
void set_terrain(map_location loc, const t_translation::terrain_code &t)
cave_map_generator_job(const cave_map_generator ¶ms, std::optional< uint32_t > randomseed={})
std::vector< chamber > chambers_
void place_chamber(const chamber &c)
const cave_map_generator & params
void build_chamber(map_location loc, std::set< map_location > &locs, std::size_t size, std::size_t jagged)
std::size_t translate_x(std::size_t x) const
void place_passage(const passage &p)
t_translation::starting_positions starting_positions_
std::size_t translate_y(std::size_t y) const
t_translation::ter_map map_
std::vector< passage > passages_
void place_castle(int starting_position, const map_location &loc)
Encapsulates the map of the game.
const t_translation::ter_map & map_
virtual double cost(const map_location &loc, const double so_far) const
t_translation::terrain_code wall_
passage_path_calculator(const t_translation::ter_map &mapdata, const t_translation::terrain_code &wall, double laziness, std::size_t windiness, std::mt19937 &rng)
Structure which holds a single route between one location and another.
std::vector< map_location > steps
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...