fix require_scenario=yes not working with map_generation

this fixes require_scenario=yes for scenarios that use map_generation or
scenario_generation, the problem was that create_engine does not call
saved_game::expand_scenario for random maps, (which is the function that
checks require_scenario=yes)

fixes #3105
This commit is contained in:
gfgtdf 2018-05-19 20:50:50 +02:00
parent b8ceaf637f
commit 0e483441d8
3 changed files with 56 additions and 20 deletions

View file

@ -330,8 +330,7 @@ void create_engine::init_generated_level_data()
const std::string& description = cur_lev->data()["description"];
data["description"] = description;
// TODO: should we also carryover [story] from the outer scenario as we do in saved_game.cpp
data["id"] = cur_lev->data()["id"];
saved_game::post_scenario_generation(cur_lev->data(), data);
cur_lev->set_data(data);
}
@ -483,6 +482,7 @@ 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();
state_.check_require_scenario();
}
void create_engine::apply_level_filter(const std::string& name)

View file

@ -236,18 +236,8 @@ void saved_game::expand_scenario()
// A hash has to be generated using an unmodified scenario data.
mp_settings_.hash = scenario.hash();
// Add addon_id information if it exists.
if(!scenario["addon_id"].empty() && scenario["require_scenario"].to_bool(false)) {
config required_scenario;
required_scenario["id"] = scenario["addon_id"];
required_scenario["name"] = scenario["addon_title"];
required_scenario["version"] = scenario["addon_version"];
required_scenario["min_version"] = scenario["addon_min_version"];
mp_settings_.update_addon_requirements(required_scenario);
}
check_require_scenario();
update_label();
set_defaults();
@ -258,6 +248,26 @@ void saved_game::expand_scenario()
}
}
void saved_game::check_require_scenario()
{
if(!starting_pos_["require_scenario"].to_bool(false)) {
return;
}
if(starting_pos_["addon_id"].empty()) {
ERR_NG << "cannot handle require_scenario=yes because we don't know from which addon that scenario came from\n";
return;
}
config required_scenario;
required_scenario["id"] = starting_pos_["addon_id"];
required_scenario["name"] = starting_pos_["addon_title"];
required_scenario["version"] = starting_pos_["addon_version"];
required_scenario["min_version"] = starting_pos_["addon_min_version"];
mp_settings_.update_addon_requirements(required_scenario);
}
namespace
{
bool variable_to_bool(const config& vars, const std::string& expression)
@ -417,12 +427,7 @@ void saved_game::expand_random_scenario()
config scenario_new =
random_generate_scenario(starting_pos_["scenario_generation"], starting_pos_.child("generator"));
// Preserve "story" form the scenario toplevel.
for(config& story : starting_pos_.child_range("story")) {
scenario_new.add_child("story", story);
}
scenario_new["id"] = starting_pos_["id"];
post_scenario_generation(starting_pos_, scenario_new);
starting_pos_ = scenario_new;
update_label();
@ -446,6 +451,33 @@ void saved_game::expand_random_scenario()
}
}
void saved_game::post_scenario_generation(const config& old_scenario, config& generated_scenario)
{
static const std::vector<std::string> attributes_to_copy {
"id",
"addon_id",
"addon_title",
"addon_version",
"addon_min_version",
"require_scenario",
};
// TODO: should we add "description" to this list?
// TODO: in theory it is possible that whether the scenario is required depends on the generated scenario, so maybe remove require_scenario from this list.
for(const auto& str : attributes_to_copy) {
generated_scenario[str] = old_scenario[str];
}
// Preserve "story" form the scenario toplevel.
// Note that it does not delete [story] tags in generated_scenario, so you can still have your story
// dependent on the generated scenario.
for(const config& story : old_scenario.child_range("story")) {
generated_scenario.add_child("story", story);
}
}
void saved_game::expand_carryover()
{
expand_scenario();

View file

@ -80,6 +80,10 @@ public:
/// takes care of generate_map=, generate_scenario=, map= attributes
/// This should be called before expanding carryover or mp_events because this might completely replace starting_pos_.
void expand_random_scenario();
/// copies attributes & tags from the 'outer' [scenario] to the scenario that is generated by scenario_generation=
static void post_scenario_generation(const config& old_scenario, config& generated_scenario);
/// Add addon_id information if needed.
void check_require_scenario();
bool valid() const;
/// @return the snapshot in the savefile (get_starting_pos)
config& set_snapshot(config snapshot);