Skip to content

Commit

Permalink
fix require_scenario=yes not working with map_generation
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gfgtdf authored and Vultraz committed May 19, 2018
1 parent 16bfab0 commit a10287c
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/game_initialization/create_engine.cpp
Expand Up @@ -329,8 +329,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);
}
Expand Down Expand Up @@ -478,6 +477,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)
Expand Down
69 changes: 51 additions & 18 deletions src/saved_game.cpp
Expand Up @@ -188,7 +188,7 @@ void saved_game::set_defaults()
for(config& side : starting_point_.child_range("side")) {
// Set save_id default value directly after loading to its default to prevent different default behaviour in
// mp_connect code and sp code.

if(side["no_leader"].to_bool()) {
side["leader_lock"] = true;
side.remove_attribute("type");
Expand Down Expand Up @@ -237,17 +237,7 @@ 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();
Expand All @@ -258,6 +248,27 @@ void saved_game::expand_scenario()
}
}

void saved_game::check_require_scenario()
{
if(!starting_point_["require_scenario"].to_bool(false)) {
return;
}

if(starting_point_["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_point_["addon_id"];
required_scenario["name"] = starting_point_["addon_title"];
required_scenario["version"] = starting_point_["addon_version"];
required_scenario["min_version"] = starting_point_["addon_min_version"];

mp_settings_.update_addon_requirements(required_scenario);
}

namespace
{
bool variable_to_bool(const config& vars, const std::string& expression)
Expand Down Expand Up @@ -417,12 +428,7 @@ void saved_game::expand_random_scenario()
config scenario_new =
random_generate_scenario(starting_point_["scenario_generation"], starting_point_.child("generator"));

// Preserve "story" form the scenario toplevel.
for(config& story : starting_point_.child_range("story")) {
scenario_new.add_child("story", story);
}

scenario_new["id"] = starting_point_["id"];
post_scenario_generation(starting_point_, scenario_new);
starting_point_ = scenario_new;

update_label();
Expand All @@ -446,6 +452,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();
Expand Down
4 changes: 4 additions & 0 deletions src/saved_game.hpp
Expand Up @@ -80,6 +80,10 @@ class saved_game
/// 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_point_.
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_point)
config& set_snapshot(config snapshot);
Expand Down

0 comments on commit a10287c

Please sign in to comment.