Integrate create_engine into sp campaign selection

After campaign selection, the mp codepath is followed starting with
enter_configure_mode().
Code for sorting and marking completed campaigns, as well as for difficulty selection, has been moved to create_engine.
Also, [scenario] tags are now converted to [multiplayer] for sp as in mp.

Conflicts:
	src/game_controller.cpp
	src/multiplayer.cpp
This commit is contained in:
Nathan Walker 2014-06-23 20:10:30 -05:00
parent c119584895
commit 5a9da1aeaf
10 changed files with 148 additions and 120 deletions

View file

@ -17,6 +17,8 @@
{core/}
{multiplayer/eras.cfg}
#ifdef MULTIPLAYER
{multiplayer/}
#endif

View file

@ -144,7 +144,8 @@ void game_config_manager::load_game_config(FORCE_RELOAD_CONFIG force_reload,
// become [multiplayer] tags and campaign's id should be added to them
// to allow to recognize which scenarios belongs to a loaded campaign.
if (classification != NULL) {
if (classification->campaign_type == game_classification::MULTIPLAYER &&
if ((classification->campaign_type == game_classification::MULTIPLAYER ||
classification->campaign_type == game_classification::SCENARIO) &&
!classification->campaign_define.empty()) {
const config& campaign = game_config().find_child("campaign",

View file

@ -43,6 +43,7 @@
#include "log.hpp" // for LOG_STREAM, logger, general, etc
#include "map_exception.hpp"
#include "multiplayer.hpp" // for start_client, etc
#include "multiplayer_create_engine.hpp"
#include "network.hpp"
#include "playcampaign.hpp" // for play_game, etc
#include "preferences.hpp" // for disable_preferences_save, etc
@ -96,10 +97,6 @@ static lg::log_domain log_network("network");
static lg::log_domain log_enginerefac("enginerefac");
#define LOG_RG LOG_STREAM(info, log_enginerefac)
static bool less_campaigns_rank(const config &a, const config &b) {
return a["rank"].to_int(1000) < b["rank"].to_int(1000);
}
game_launcher::game_launcher(const commandline_options& cmdline_opts, const char *appname) :
cmdline_opts_(cmdline_opts),
disp_(NULL),
@ -694,19 +691,13 @@ bool game_launcher::new_campaign()
state_ = saved_game();
state_.classification().campaign_type = game_classification::SCENARIO;
std::vector<config> campaigns;
BOOST_FOREACH(const config& campaign,
resources::config_manager->game_config().child_range("campaign")) {
mp::create_engine create_eng(disp(), state_);
create_eng.set_current_level_type(mp::level::SP_CAMPAIGN);
if (campaign["type"] != "mp") {
campaigns.push_back(campaign);
}
}
mark_completed_campaigns(campaigns);
std::stable_sort(campaigns.begin(),campaigns.end(),less_campaigns_rank);
if(campaigns.begin() == campaigns.end()) {
std::vector<mp::create_engine::level_ptr> campaigns(
create_eng.get_levels_by_type_unfiltered(mp::level::SP_CAMPAIGN));
if (campaigns.empty()) {
gui2::show_error_message(disp().video(),
_("No campaigns are available.\n"));
return false;
@ -743,7 +734,7 @@ bool game_launcher::new_campaign()
// checking for valid campaign name
for(size_t i = 0; i < campaigns.size(); ++i)
{
if (campaigns[i]["id"] == jump_to_campaign_.campaign_id_)
if (campaigns[i]->data()["id"] == jump_to_campaign_.campaign_id_)
{
campaign_num = i;
break;
@ -758,78 +749,41 @@ bool game_launcher::new_campaign()
}
}
const config &campaign = campaigns[campaign_num];
state_.classification().campaign = campaign["id"].str();
state_.classification().abbrev = campaign["abbrev"].str();
create_eng.set_current_level(campaign_num);
std::string random_mode = use_deterministic_mode ? "deterministic" : "";
state_.carryover_sides_start["random_mode"] = random_mode;
state_.classification().random_mode = random_mode;
// we didn't specify in the command line the scenario to be started
if (jump_to_campaign_.scenario_id_.empty())
state_.carryover_sides_start["next_scenario"] = campaign["first_scenario"].str();
else
state_.carryover_sides_start["next_scenario"] = jump_to_campaign_.scenario_id_;
std::string selected_difficulty = create_eng.select_campaign_difficulty(jump_to_campaign_.difficulty_);
state_.classification().end_text = campaign["end_text"].str();
state_.classification().end_text_duration = campaign["end_text_duration"];
const std::string difficulty_descriptions = campaign["difficulty_descriptions"];
std::vector<std::string> difficulty_options = utils::split(difficulty_descriptions, ';');
const std::vector<std::string> difficulties = utils::split(campaign["difficulties"]);
if(difficulties.empty() == false) {
int difficulty = 0;
if (jump_to_campaign_.difficulty_ == -1){
if(difficulty_options.size() != difficulties.size()) {
difficulty_options.resize(difficulties.size());
std::copy(difficulties.begin(),difficulties.end(),difficulty_options.begin());
}
gui2::tcampaign_difficulty dlg(difficulty_options);
dlg.show(disp().video());
if(dlg.selected_index() == -1) {
if (jump_to_campaign_.campaign_id_.empty() == false)
{
jump_to_campaign_.campaign_id_ = "";
}
// canceled difficulty dialog, relaunch the campaign selection dialog
return new_campaign();
}
difficulty = dlg.selected_index();
}
else
if (selected_difficulty == "FAIL") return false;
if (selected_difficulty == "CANCEL") {
if (jump_to_campaign_.campaign_id_.empty() == false)
{
if (jump_to_campaign_.difficulty_
> static_cast<int>(difficulties.size()))
{
std::cerr << "incorrect difficulty number: [" <<
jump_to_campaign_.difficulty_ << "]. maximum is [" <<
difficulties.size() << "].\n";
return false;
}
else if (jump_to_campaign_.difficulty_ < 1)
{
std::cerr << "incorrect difficulty number: [" <<
jump_to_campaign_.difficulty_ << "]. minimum is [1].\n";
return false;
}
else
{
difficulty = jump_to_campaign_.difficulty_ - 1;
}
jump_to_campaign_.campaign_id_ = "";
}
state_.classification().difficulty = difficulties[difficulty];
// canceled difficulty dialog, relaunch the campaign selection dialog
return new_campaign();
}
state_.classification().campaign_define = campaign["define"].str();
state_.classification().campaign_xtra_defines = utils::split(campaign["extra_defines"]);
create_eng.prepare_for_campaign(selected_difficulty);
return true;
create_eng.prepare_for_new_level();
if (jump_to_campaign_.scenario_id_.empty())
state_.carryover_sides_start["next_scenario"] = create_eng.current_level().data()["id"].str();
else {
state_.carryover_sides_start["next_scenario"] = jump_to_campaign_.scenario_id_;
create_eng.current_level().set_data(
resources::config_manager->game_config().find_child(
lexical_cast<std::string> (game_classification::MULTIPLAYER),
"id", jump_to_campaign_.scenario_id_));
}
state_.mp_settings().mp_era = "era_blank";
return enter_configure_mode(disp(), resources::config_manager->game_config(), state_, true);
}
std::string game_launcher::jump_to_campaign_id() const
@ -842,7 +796,7 @@ bool game_launcher::goto_campaign()
if(jump_to_campaign_.jump_){
if(new_campaign()) {
jump_to_campaign_.jump_ = false;
launch_game(game_launcher::RELOAD_DATA);
launch_game(NO_RELOAD_DATA);
}else{
jump_to_campaign_.jump_ = false;
return false;

View file

@ -140,8 +140,9 @@ void tcampaign_selection::pre_show(CVideo& /*video*/, twindow& window)
= find_widget<tmulti_page>(&window, "campaign_details", false);
unsigned id = 0;
FOREACH(const AUTO & campaign, campaigns_)
FOREACH(const AUTO & level, campaigns_)
{
const config& campaign = level->data();
/*** Add tree item ***/
tree_group_field["label"] = campaign["icon"];
@ -207,8 +208,9 @@ void tcampaign_selection::pre_show(CVideo& /*video*/, twindow& window)
tmulti_page& multi_page
= find_widget<tmulti_page>(&window, "campaign_details", false);
FOREACH(const AUTO & campaign, campaigns_)
FOREACH(const AUTO & level, campaigns_)
{
const config& campaign = level->data();
/*** Add list item ***/
string_map list_item;

View file

@ -18,6 +18,7 @@
#include "gui/dialogs/dialog.hpp"
#include "config.hpp"
#include "multiplayer_create_engine.hpp"
namespace gui2
{
@ -25,7 +26,7 @@ namespace gui2
class tcampaign_selection : public tdialog
{
public:
explicit tcampaign_selection(const std::vector<config>& campaigns)
explicit tcampaign_selection(const std::vector<mp::create_engine::level_ptr>& campaigns)
: campaigns_(campaigns), choice_(-1), deterministic_(false)
{
@ -57,7 +58,7 @@ private:
void post_show(twindow& window);
/** Contains the config objects for all campaigns. */
const std::vector<config>& campaigns_;
const std::vector<mp::create_engine::level_ptr>& campaigns_;
/** The chosen campaign. */
int choice_;

View file

@ -522,10 +522,6 @@ static bool enter_connect_mode(game_display& disp, const config& game_config,
return true;
}
static bool enter_configure_mode(game_display& disp, const config& game_config,
saved_game& state,
bool local_players_only = false);
static void enter_create_mode(game_display& disp, const config& game_config,
saved_game& state, bool local_players_only)
{
@ -575,7 +571,7 @@ static void enter_create_mode(game_display& disp, const config& game_config,
} while(configure_canceled || connect_canceled);
}
static bool enter_configure_mode(game_display& disp, const config& game_config,
bool enter_configure_mode(game_display& disp, const config& game_config,
saved_game& state, bool local_players_only)
{
DBG_MP << "entering configure mode" << std::endl;

View file

@ -71,4 +71,8 @@ mp::ui::result goto_mp_wait(saved_game& state, game_display& disp,
const config& game_config, bool observe);
}
bool enter_configure_mode(game_display& disp, const config& game_config,
saved_game& state, bool local_players_only = false);
#endif

View file

@ -229,7 +229,7 @@ void create::process_event()
if (engine_.current_level_type() == level::CAMPAIGN ||
engine_.current_level_type() == level::SP_CAMPAIGN) {
std::string difficulty = select_campaign_difficulty();
std::string difficulty = engine_.select_campaign_difficulty();
if (difficulty == "CANCEL") {
return;
}
@ -521,35 +521,6 @@ void create::update_mod_menu_images()
}
}
std::string create::select_campaign_difficulty()
{
const std::string difficulty_descriptions =
engine_.current_level().data()["difficulty_descriptions"];
std::vector<std::string> difficulty_options =
utils::split(difficulty_descriptions, ';');
const std::vector<std::string> difficulties =
utils::split(engine_.current_level().data()["difficulties"]);
if(!difficulties.empty()) {
int difficulty = 0;
if(difficulty_options.size() != difficulties.size()) {
difficulty_options = difficulties;
}
gui2::tcampaign_difficulty dlg(difficulty_options);
dlg.show(disp().video());
if(dlg.selected_index() == -1) {
return "CANCEL";
}
difficulty = dlg.selected_index();
return difficulties[difficulty];
}
return "";
}
void create::hide_children(bool hide)
{
DBG_MP << (hide ? "hiding" : "showing" ) << " children widgets" << std::endl;

View file

@ -14,8 +14,10 @@
#include "multiplayer_create_engine.hpp"
#include "game_config_manager.hpp"
#include "game_launcher.hpp"
#include "game_display.hpp"
#include "game_preferences.hpp"
#include "gui/dialogs/campaign_difficulty.hpp"
#include "filesystem.hpp"
#include "formula_string_utils.hpp"
#include "log.hpp"
@ -67,6 +69,11 @@ bool contains_ignore_case(const std::string& str1, const std::string& str2)
namespace mp {
static bool less_campaigns_rank(const create_engine::level_ptr& a, const create_engine::level_ptr& b) {
return a->data()["rank"].to_int(1000) < b->data()["rank"].to_int(1000);
}
level::level(const config& data) :
data_(data)
{
@ -102,6 +109,11 @@ const config& level::data() const
return data_;
}
config& level::data()
{
return data_;
}
scenario::scenario(const config& data) :
level(data),
map_(),
@ -306,6 +318,11 @@ void campaign::set_metadata()
}
}
void campaign::mark_if_completed()
{
data_["completed"] = preferences::is_campaign_completed(data_["id"]);
}
std::string campaign::id() const
{
return id_;
@ -344,14 +361,16 @@ create_engine::create_engine(game_display& disp, saved_game& state) :
eras_(),
mods_(),
state_(state),
disp_(disp),
dependency_manager_(resources::config_manager->game_config(), disp.video()),
generator_(NULL)
{
DBG_MP << "restoring game config\n";
// Restore game config for multiplayer.
game_classification::CAMPAIGN_TYPE type = state_.classification().campaign_type;
state_ = saved_game();
state_.classification().campaign_type = game_classification::MULTIPLAYER;
state_.classification().campaign_type = type;
resources::config_manager->
load_game_config_for_game(state_.classification());
@ -469,6 +488,74 @@ void create_engine::prepare_for_campaign(const std::string& difficulty)
"id", current_level().data()["first_scenario"]));
}
/**
* select_campaign_difficulty
*
* Launches difficulty selection gui and returns selected difficulty name.
*
* The gui can be bypassed by supplying a number
* from 1 to the number of difficulties available,
* corresponding to a choice of difficulty.
* This is useful for specifying difficulty via command line.
*
* @param set_value Preselected difficulty number. The default -1 launches the gui.
* @return Selected difficulty. Returns "FAIL" if set_value is invalid,
* and "CANCEL" if the gui is cancelled.
*/
std::string create_engine::select_campaign_difficulty(int set_value)
{
const std::string difficulty_descriptions =
current_level().data()["difficulty_descriptions"];
std::vector<std::string> difficulty_options =
utils::split(difficulty_descriptions, ';');
const std::vector<std::string> difficulties =
utils::split(current_level().data()["difficulties"]);
if(difficulties.empty()) return "";
int difficulty = 0;
if (set_value != -1)
{
// user-specified campaign to jump to. con
if (set_value
> static_cast<int>(difficulties.size()))
{
std::cerr << "incorrect difficulty number: [" <<
set_value << "]. maximum is [" <<
difficulties.size() << "].\n";
return "FAIL";
}
else if (set_value < 1)
{
std::cerr << "incorrect difficulty number: [" <<
set_value << "]. minimum is [1].\n";
return "FAIL";
}
else
{
difficulty = set_value - 1;
}
}
else
{
if(difficulty_options.size() != difficulties.size())
{
difficulty_options = difficulties;
}
// show gui
gui2::tcampaign_difficulty dlg(difficulty_options);
dlg.show(disp_.video());
if(dlg.selected_index() == -1)
{
return "CANCEL";
}
difficulty = dlg.selected_index();
}
return difficulties[difficulty];
}
void create_engine::prepare_for_saved_game()
{
DBG_MP << "preparing mp_game_settings for saved game\n";
@ -913,8 +1000,10 @@ void create_engine::init_all_levels()
campaign_ptr new_sp_campaign(new campaign(data));
sp_campaigns_.push_back(new_sp_campaign);
sp_campaigns_.back()->set_metadata();
sp_campaigns_.back()->mark_if_completed();
}
}
std::stable_sort(sp_campaigns_.begin(),sp_campaigns_.end(),less_campaigns_rank);
}
void create_engine::init_extras(const MP_EXTRA extra_type)

View file

@ -50,6 +50,7 @@ public:
void set_data(const config& data);
const config& data() const;
config& data();
protected:
config data_;
@ -136,6 +137,8 @@ public:
void set_metadata();
void mark_if_completed();
std::string id() const;
bool allow_era_choice() const;
@ -184,6 +187,8 @@ public:
void prepare_for_scenario();
void prepare_for_campaign(const std::string& difficulty);
void prepare_for_saved_game();
std::string select_campaign_difficulty(int set_value = -1);
void apply_level_filter(const std::string& name);
void apply_level_filter(int players);
@ -226,6 +231,7 @@ public:
const mp_game_settings& get_parameters();
saved_game& get_state();
private:
create_engine(const create_engine&);
void operator=(const create_engine&);
@ -272,6 +278,8 @@ private:
saved_game& state_;
game_display& disp_;
depcheck::manager dependency_manager_;
util::scoped_ptr<map_generator> generator_;