The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
singleplayer.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2008 - 2025
3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY.
11
12 See the COPYING file for more details.
13*/
14
16
17#include "addon/manager_ui.hpp"
18#include "config.hpp"
21#include "game_launcher.hpp"
26#include "wml_exception.hpp"
27
28static lg::log_domain log_engine("engine");
29#define ERR_NG LOG_STREAM(err, log_engine)
30
31namespace sp
32{
33bool select_campaign(saved_game& state, jump_to_campaign_info jump_to_campaign)
34{
35 while(true) {
36 ng::create_engine create_eng(state);
37 create_eng.set_current_level_type(level_type::type::sp_campaign);
38
39 const std::vector<ng::create_engine::level_ptr> campaigns =
40 create_eng.get_levels_by_type_unfiltered(level_type::type::sp_campaign);
41
42 if(campaigns.empty()) {
43 gui2::show_error_message(_("No campaigns are available."));
44 return false;
45 }
46
47 std::string random_mode = "", difficulty = "";
48
49 // No campaign selected from command line
50 if(jump_to_campaign.campaign_id.empty()) {
52
53 try {
54 dlg.show();
55 } catch(const wml_exception& e) {
56 e.show();
57 return false;
58 }
59
60 if(dlg.get_retval() == gui2::retval::OK) {
61 switch(dlg.get_rng_mode()) {
63 random_mode = "";
64 break;
66 random_mode = "deterministic";
67 break;
69 random_mode = "biased";
70 break;
71 }
72 difficulty = dlg.get_difficulty();
73 } else {
76 }
77 return false;
78 }
79
80 } else {
81 // Don't reset the campaign_id_ so we can know
82 // if we should quit the game or return to the main menu
83
84 // Checking for valid campaign name
85 const auto campaign = utils::ranges::find(campaigns, jump_to_campaign.campaign_id,
86 [](const ng::create_engine::level_ptr& level) { return level->data()["id"]; });
87
88 // Didn't find a campaign with that id
89 if(campaign == campaigns.end()) {
90 ERR_NG << "No such campaign id to jump to: [" << jump_to_campaign.campaign_id << "]";
91 return false;
92 }
93
94 create_eng.set_current_level(std::distance(campaigns.begin(), campaign));
95 }
96
97 state.classification().random_mode = random_mode;
98
99 const auto selected_difficulty = difficulty;
100
101 if(selected_difficulty == "FAIL") return false;
102 if(selected_difficulty == "CANCEL") {
103 if(!jump_to_campaign.campaign_id.empty()) {
104 jump_to_campaign.campaign_id = "";
105 }
106
107 // Canceled difficulty dialog, relaunch the campaign selection dialog
108 return select_campaign(state, jump_to_campaign);
109 }
110
111 create_eng.prepare_for_era_and_mods();
112 create_eng.prepare_for_campaign(selected_difficulty);
113
114 if(!jump_to_campaign.scenario_id.empty()) {
116 config {"next_scenario", jump_to_campaign.scenario_id}
117 );
118 }
119
120 if(!state.valid()) {
121 ERR_NG << "Cannot load scenario with id=" << state.get_scenario_id();
122 return false;
123 }
124
125 if(configure_campaign(state, create_eng)) {
126 break;
127 }
128 }
129
130 return true;
131}
132
134{
135 create_eng.get_state().mp_settings().use_map_settings = true;
137 return false;
138 }
139
140 create_eng.get_parameters();
141 create_eng.prepare_for_new_level();
142
143 ng::connect_engine connect_eng(state, true, nullptr);
144 connect_eng.start_game();
145
146 return true;
147}
148
149} // end namespace sp
#define ERR_NG
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
const std::string & get_difficulty() const
bool show(const unsigned auto_close_time=0)
Shows the window.
static bool execute(ng::create_engine &create_engine)
Execute function.
int get_retval()
Definition window.hpp:394
std::shared_ptr< level > level_ptr
void set_current_level_type(const level_type::type type)
saved_game & get_state()
void prepare_for_campaign(const std::string &difficulty="")
std::vector< level_ptr > get_levels_by_type_unfiltered(level_type::type type) const
const mp_game_settings & get_parameters()
void set_current_level(const std::size_t index)
void set_carryover_sides_start(config carryover_sides_start)
std::string get_scenario_id() const
game_classification & classification()
mp_game_settings & mp_settings()
Multiplayer parameters for this game.
bool valid() const
Definitions for the interface to Wesnoth Markup Language (WML).
static std::string _(const char *str)
Definition gettext.hpp:100
bool manage_addons()
Shows the add-ons server connection dialog, for access to the various management front-ends.
void show_error_message(const std::string &msg, bool message_use_markup)
Shows an error message to the user.
Definition message.cpp:201
@ OK
Dialog was closed with the OK button.
Definition retval.hpp:35
bool select_campaign(saved_game &state, jump_to_campaign_info jump_to_campaign)
bool configure_campaign(saved_game &state, ng::create_engine &create_eng)
auto find(Container &container, const Value &value, const Projection &projection={})
Definition general.hpp:213
static lg::log_domain log_engine("engine")
std::string campaign_id
The ID of the campaign to launch.
std::string scenario_id
The ID of the scenario within the campaign to jump to.
Helper class, don't construct this directly.
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define e