From 43e3d37a2122ab40fe9df887d971eab80588ff10 Mon Sep 17 00:00:00 2001 From: Chris Beck Date: Tue, 4 Nov 2014 21:22:21 -0500 Subject: [PATCH] fix bug #22484 (fix random map generation in mp create) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As described in bug report, mp create had a bizarre implementation for random map vs scenario generation. Scenario generation was called map generation, and map generation was impossible. We fix it and make it work like it works in the rest of the game. At time of writing the wiki describes map generation wml as follows: ``` To use the default [generator] your [scenario] tag must contain one of the following keys: scenario_generation=default map_generation=default If ‘scenario_generation’ is used, the engine will expect for your entire [scenario] sub tags to be inside a [scenario] tag inside [generator]. Tags outside of this will be ignored. There may be value in this, but at this writing, it’s not clear. ‘map_generation=default’ is simpler and more commonly used. It is also necessary to use this key so that you can regenerate a map in MP game creation. In its use only generator data is in the [generator] tag, all other [scenario] data is placed outside of it. The exception is if you are making an initial MP scenario available in MP game creation, for this a [scenario] tag must appear inside of [generator], containing the [scenario] subtags you want to use. See “data/multiplayer/scenarios/Random_Scenario.cfg” for an example. ``` This commit essentially removes the "exception" pointed out above. After this, the mp create dialog treats map and scenario generation both in the "random maps" classification, and it handles them normally, scenario generation replacing the entire scenario, and map generation replacing only the map data of the scenario. --- .../multiplayer/scenarios/Random_Scenario.cfg | 2 +- .../scenarios/Random_Scenario_Desert.cfg | 2 +- .../scenarios/Random_Scenario_Marsh.cfg | 2 +- .../scenarios/Random_Scenario_Winter.cfg | 2 +- .../scenarios/Random_YAMG_Scenario.cfg | 2 +- src/game_initialization/create_engine.cpp | 99 +++++++++++++++---- src/game_initialization/create_engine.hpp | 10 +- src/tests/gui/test_gui2.cpp | 2 +- 8 files changed, 96 insertions(+), 25 deletions(-) diff --git a/data/multiplayer/scenarios/Random_Scenario.cfg b/data/multiplayer/scenarios/Random_Scenario.cfg index 3c7e6d27da111..bd18d72d1a66d 100644 --- a/data/multiplayer/scenarios/Random_Scenario.cfg +++ b/data/multiplayer/scenarios/Random_Scenario.cfg @@ -5,7 +5,7 @@ id=multiplayer_Random_Map name= _ "Random map" description= _ "Randomly generated map. Note: random maps are often unbalanced, but if you have time, you can regenerate them until you get a good one." - map_generation=default + scenario_generation=default [generator] [scenario] name= _ "Random map" diff --git a/data/multiplayer/scenarios/Random_Scenario_Desert.cfg b/data/multiplayer/scenarios/Random_Scenario_Desert.cfg index 003202a6fbb15..3384188894f34 100644 --- a/data/multiplayer/scenarios/Random_Scenario_Desert.cfg +++ b/data/multiplayer/scenarios/Random_Scenario_Desert.cfg @@ -4,7 +4,7 @@ id=multiplayer_Random_Map_Desert name= _ "Random map (Desert)" description= _ "A random map with sand as the primary terrain. Note: random maps are often unbalanced, but if you have time, you can regenerate them until you get a good one." - map_generation=default + scenario_generation=default [generator] [scenario] name= _ "Random map (Desert)" diff --git a/data/multiplayer/scenarios/Random_Scenario_Marsh.cfg b/data/multiplayer/scenarios/Random_Scenario_Marsh.cfg index fdf544f48d4ca..d51fbb9cb48d9 100644 --- a/data/multiplayer/scenarios/Random_Scenario_Marsh.cfg +++ b/data/multiplayer/scenarios/Random_Scenario_Marsh.cfg @@ -4,7 +4,7 @@ id=multiplayer_Random_Map_Marsh name= _ "Random map (Marsh)" description= _ "A random map with swamp as the primary terrain. Note: random maps are often unbalanced, but if you have time, you can regenerate them until you get a good one." - map_generation=default + scenario_generation=default [generator] [scenario] name= _ "Random map (Marsh)" diff --git a/data/multiplayer/scenarios/Random_Scenario_Winter.cfg b/data/multiplayer/scenarios/Random_Scenario_Winter.cfg index 5bb04eda5413e..8b41723c6984c 100644 --- a/data/multiplayer/scenarios/Random_Scenario_Winter.cfg +++ b/data/multiplayer/scenarios/Random_Scenario_Winter.cfg @@ -4,7 +4,7 @@ id=multiplayer_Random_Map_Winter name= _ "Random map (Winter)" description= _ "A random map set in the break between spring and winter, mainly with snowy terrains. Note: random maps are often unbalanced, but if you have time, you can regenerate them until you get a good one." - map_generation=default + scenario_generation=default [generator] [scenario] name= _ "Random map (Winter)" diff --git a/data/multiplayer/scenarios/Random_YAMG_Scenario.cfg b/data/multiplayer/scenarios/Random_YAMG_Scenario.cfg index 64e8ce4893181..fb343f4a6e72d 100644 --- a/data/multiplayer/scenarios/Random_YAMG_Scenario.cfg +++ b/data/multiplayer/scenarios/Random_YAMG_Scenario.cfg @@ -5,7 +5,7 @@ id=multiplayer_Random_YAMG_Map name= _ "Random map by YAMG" description= _ "Randomly generated map. Note: random maps are often unbalanced, but if you have time, you can regenerate them until you get a good one." - map_generation=yamg + scenario_generation=yamg [generator] [scenario] name= _ "Random map" diff --git a/src/game_initialization/create_engine.cpp b/src/game_initialization/create_engine.cpp index a60bee8390a8f..fc3dafcdf98e9 100644 --- a/src/game_initialization/create_engine.cpp +++ b/src/game_initialization/create_engine.cpp @@ -42,6 +42,7 @@ static lg::log_domain log_config("config"); #define ERR_CF LOG_STREAM(err, log_config) static lg::log_domain log_mp_create_engine("mp/create/engine"); +#define WRN_MP LOG_STREAM(warn, log_mp_create_engine) #define DBG_MP LOG_STREAM(debug, log_mp_create_engine) namespace { @@ -251,10 +252,27 @@ std::string user_map::id() const return name_; } -random_map::random_map(const config& generator_data) : - scenario(config()), - generator_data_(generator_data) -{ +random_map::random_map(const config& data) : + scenario(data), + generator_data_(), + generate_whole_scenario_(data_.has_attribute("scenario_generation")), + generator_name_(generate_whole_scenario_ ? data_["scenario_generation"] : data_["map_generation"]) +{ + if (!data.has_child("generator")) { + data_ = config(); + generator_data_= config(); + data_["description"] = "Error: Random map found with missing generator information. Scenario should have a [generator] child."; + data_["error_message"] = "missing [generator] tag"; + } else { + generator_data_ = data.child("generator"); + } + + if (!data.has_attribute("scenario_generation") && !data.has_attribute("map_generation")) { + data_ = config(); + generator_data_= config(); + data_["description"] = "Error: Random map found with missing generator information. Scenario should have a [generator] child."; + data_["error_message"] = "couldn't find 'scenario_generation' or 'map_generation' attribute"; + } } random_map::~random_map() @@ -268,17 +286,32 @@ const config& random_map::generator_data() const std::string random_map::name() const { - return generator_data_["name"]; + return data_["name"]; } std::string random_map::description() const { - return generator_data_["description"]; + return data_["description"]; } std::string random_map::id() const { - return generator_data_["id"]; + return data_["id"]; +} + +bool random_map::generate_whole_scenario() const +{ + return generate_whole_scenario_; +} + +std::string random_map::generator_name() const +{ + return generator_name_; +} + +map_generator * random_map::create_map_generator() const +{ + return ::create_map_generator(generator_name(), generator_data()); } campaign::campaign(const config& data) : @@ -427,16 +460,47 @@ void create_engine::init_generated_level_data() { DBG_MP << "initializing generated level data\n"; - config data = generator_->create_scenario(); + //DBG_MP << "current data:\n"; + //DBG_MP << current_level().data().debug(); + + random_map * cur_lev = dynamic_cast (¤t_level()); + + if (!cur_lev) { + WRN_MP << "Tried to initialized generated level data on a level that wasn't a random map\n"; + return; + } + + if (!cur_lev->generate_whole_scenario()) + { + DBG_MP << "** replacing map ** \n"; + + config data = cur_lev->data(); + + data["map_data"] = generator_->create_map(); - // Set the scenario to have placing of sides - // based on the terrain they prefer - data["modify_placing"] = "true"; + cur_lev->set_data(data); + + } else { //scenario generation + + DBG_MP << "** replacing scenario ** \n"; + + config data = generator_->create_scenario(); + + // Set the scenario to have placing of sides + // based on the terrain they prefer + if (!data.has_attribute("modify_placing")) { + data["modify_placing"] = "true"; + } + + const std::string& description = cur_lev->data()["description"]; + data["description"] = description; + + cur_lev->set_data(data); + } - const std::string& description = current_level().data()["description"]; - data["description"] = description; + //DBG_MP << "final data:\n"; + //DBG_MP << current_level().data().debug(); - current_level().set_data(data); } void create_engine::prepare_for_new_level() @@ -579,6 +643,7 @@ void create_engine::prepare_for_saved_game() void create_engine::prepare_for_other() { + DBG_MP << "prepare_for_other\n"; state_.set_scenario(current_level().data()); state_.mp_settings().hash = current_level().data().hash(); } @@ -735,9 +800,7 @@ void create_engine::set_current_level(const size_t index) random_map* current_random_map = dynamic_cast(¤t_level()); - generator_.reset(create_map_generator( - current_random_map->generator_data()["map_generation"], - current_random_map->generator_data().child("generator"))); + generator_.reset(current_random_map->create_map_generator()); } else { generator_.reset(NULL); } @@ -998,7 +1061,7 @@ void create_engine::init_all_levels() if (!data["allow_new_game"].to_bool(true)) continue; - if (!data["map_generation"].empty()) { + if (data.has_attribute("map_generation") || data.has_attribute("scenario_generation")) { random_map_ptr new_random_map(new random_map(data)); random_maps_.push_back(new_random_map); random_maps_.back()->set_metadata(); diff --git a/src/game_initialization/create_engine.hpp b/src/game_initialization/create_engine.hpp index c07abb2e9b27b..182722d256fd0 100644 --- a/src/game_initialization/create_engine.hpp +++ b/src/game_initialization/create_engine.hpp @@ -108,7 +108,7 @@ class user_map : public scenario class random_map : public scenario { public: - random_map(const config& generator_data); + random_map(const config& data); virtual ~random_map(); const config& generator_data() const; @@ -116,12 +116,20 @@ class random_map : public scenario std::string name() const; std::string description() const; std::string id() const; + std::string generator_name() const; + + map_generator * create_map_generator() const; + + bool generate_whole_scenario() const; private: random_map(const random_map&); void operator=(const random_map&); config generator_data_; + + bool generate_whole_scenario_; + std::string generator_name_; }; class campaign : public level diff --git a/src/tests/gui/test_gui2.cpp b/src/tests/gui/test_gui2.cpp index 19afb9694d95b..7155e07a4110c 100644 --- a/src/tests/gui/test_gui2.cpp +++ b/src/tests/gui/test_gui2.cpp @@ -820,7 +820,7 @@ struct twrapper std::vector map_generators; BOOST_FOREACH(const config &i, main_config.child_range("multiplayer")) { - if(i["map_generation"] == "default") { + if(i["scenario_generation"] == "default") { const config &generator_cfg = i.child("generator"); if (generator_cfg) { map_generators.push_back(