83 #define ERR_NG LOG_STREAM(err, log_engine)
84 #define LOG_NG LOG_STREAM(info, log_engine)
134 gui2::dialogs::statistics_dialog::display(
pc_.
statistics(),
board().get_team(side_num));
171 symbols[
"msg"] =
e.what();
172 const std::string
msg =
VGETTEXT(
"Could not save the map: $msg", symbols);
179 gui2::dialogs::preferences_dialog::display();
187 c[
"name"] =
"prototype of chat log";
199 ?
board().is_observer()
200 ?
_(
"Send to observers only")
201 :
_(
"Send to allies only")
219 if(
board().is_observer()) {
238 std::map<const unit_type*, t_string> sample_units;
242 std::vector<t_string> unknown_units;
243 for(
const auto&
recruit : recruits) {
247 unknown_units.emplace_back(
recruit);
255 if(!unknown_units.empty()) {
260 const auto message =
VNGETTEXT(
"Error: there’s an unknown unit type on your recruit list: $unknown_ids",
261 "Error: there are several unknown unit types on your recruit list: $unknown_ids",
262 unknown_units.size(),
267 if(sample_units.empty()) {
281 do_recruit(
type->id(), side_num, recruit_hex);
285 void menu_handler::repeat_recruit(
int side_num,
const map_location& last_hex)
287 const std::string& last_recruit = board().get_team(side_num).last_recruit();
288 if(last_recruit.empty() ==
false) {
290 do_recruit(last_recruit, side_num, recruit_hex);
299 team& current_team = board().get_team(side_num);
302 if(u_type ==
nullptr) {
303 return _(
"Internal error. Please report this as a bug! Details:\n")
304 +
"menu_handler::can_recruit: u_type == nullptr for " + name;
309 return VGETTEXT(
"You cannot recruit a $unit_type_name at this time.",
317 wb_gold = (pc_.get_whiteboard() ? pc_.get_whiteboard()->get_spent_gold_for(side_num) : 0);
319 if(u_type->
cost() > current_team.
gold() - wb_gold)
323 return _(
"At this point in your plan, you will not have enough gold to recruit this unit.");
325 return _(
"You do not have enough gold to recruit this unit.");
342 bool menu_handler::do_recruit(
const std::string& name,
int side_num,
map_location&
loc)
345 const std::string res = can_recruit(name, side_num,
loc, recruited_from);
346 team& current_team = board().get_team(side_num);
348 if(res.empty() && (!pc_.get_whiteboard() || !pc_.get_whiteboard()->save_recruit(name, side_num,
loc))) {
356 }
else if(res.empty()) {
367 if(pc_.get_disallow_recall()) {
372 team& current_team = board().get_team(side_num);
374 std::vector<unit_const_ptr> recall_list_team;
382 DBG_WB <<
"menu_handler::recall: Contents of wb-modified recall list:";
389 _(
"There are no troops available to recall.\n(You must have veteran survivors from a previous scenario.)"));
392 if(recall_list_team.empty()) {
415 unit_cost = recall_list_team[res]->recall_cost();
418 int wb_gold = pc_.get_whiteboard() ? pc_.get_whiteboard()->get_spent_gold_for(side_num) : 0;
419 if(current_team.
gold() - wb_gold < unit_cost) {
421 i18n_symbols[
"cost"] = std::to_string(unit_cost);
422 std::string
msg =
VNGETTEXT(
"You must have at least 1 gold piece to recall a unit.",
423 "You must have at least $cost gold pieces to recall this unit.", unit_cost, i18n_symbols);
428 LOG_NG <<
"recall index: " << res;
445 if(!pc_.get_whiteboard()
446 || !pc_.get_whiteboard()->save_recall(*recall_list_team[res].get(), side_num, recall_location)) {
451 ERR_NG <<
"menu_handler::recall(): Unit does not exist in the recall list.";
457 void menu_handler::show_enemy_moves(
bool ignore_units,
int side_num)
464 gui_->unhighlight_reach();
467 for(
auto& u : pc_.get_units()) {
468 bool invisible = u.invisible(u.get_location());
470 if(board().get_team(side_num).is_enemy(u.side()) && !gui_->fogged(u.get_location()) && !u.incapacitated()
474 =
pathfind::paths(u,
false,
true, gui_->viewing_team(), 0,
false, ignore_units);
476 gui_->highlight_another_reach(
path, hex_under_mouse);
480 gui_->invalidate(u.get_location());
485 const bool selected_hex_has_unit = mh.
hex_hosts_unit(hex_under_mouse);
487 if(selected_hex_has_unit) {
496 void menu_handler::toggle_shroud_updates(
int side_num)
498 team& current_team = board().get_team(side_num);
502 update_shroud_now(side_num);
509 void menu_handler::update_shroud_now(
int )
518 bool units_alive(
int side_num,
const unit_map& units)
520 for(
auto&
unit : units) {
529 bool partmoved_units(
530 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
532 for(
auto&
unit : units) {
547 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
549 for(
auto&
unit : units) {
552 && (!whiteb || !whiteb->unit_has_actions(&
unit))) {
562 bool menu_handler::end_turn(
int side_num)
567 reason =
_(
"You cannot end your turn yet!");
573 std::size_t team_num =
static_cast<std::size_t
>(side_num - 1);
574 if(team_num < pc_.get_teams().size() && pc_.get_teams()[team_num].no_turn_confirmation()) {
579 && (!pc_.get_whiteboard() || !pc_.get_whiteboard()->current_side_has_actions())
580 && units_alive(side_num, pc_.get_units())) {
582 _(
"You have not started your turn yet. Do you really want to end your turn?"),
589 else if(
prefs::get().yellow_confirm() && partmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
591 _(
"Some units have movement left. Do you really want to end your turn?"),
598 else if(
prefs::get().green_confirm() && unmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
600 _(
"Some units have not moved. Do you really want to end your turn?"),
609 if(pc_.get_whiteboard() && !pc_.get_whiteboard()->allow_end_turn()) {
616 void menu_handler::goto_leader(
int side_num)
619 if(
i != pc_.get_units().end() &&
i->is_visible_to_team(gui_->viewing_team(),
false)) {
624 void menu_handler::unit_description()
627 if(un != pc_.get_units().end()) {
635 if(pc_.get_map().on_board(
loc) ==
false || gui_->shrouded(
loc)) {
644 void menu_handler::rename_unit()
647 if(un == pc_.get_units().end() || gui_->viewing_team().side() != un->side()) {
651 if(un->unrenamable()) {
655 std::string name = un->name();
656 const std::string title(
_(
"Rename Unit"));
657 const std::string
label(
_(
"Name:"));
659 if(gui2::dialogs::edit_text::execute(title,
label, name)) {
662 gui_->invalidate_unit();
668 const mouse_handler& mousehandler = pc_.get_mouse_handler_base();
669 const bool see_all = gui_->show_everything() || (pc_.is_replay() && pc_.get_replay_controller()->see_all());
672 if(res != pc_.get_units().end()) {
683 typedef std::tuple<const unit_type*, unit_race::GENDER, std::string> type_gender_variation;
692 type_gender_variation choose_unit()
705 const std::string& ut_id = create_dlg.
choice();
708 ERR_NG <<
"Create unit dialog returned nonexistent or unusable unit_type id '" << ut_id <<
"'.";
721 return type_gender_variation(utp, gender, create_dlg.
variation());
734 const std::string& variation =
"")
742 "variation", variation,
757 assert(gui_ !=
nullptr);
760 if(
const auto& [
type, gender, variation] = choose_unit();
type !=
nullptr) {
762 create_and_place(*gui_, pc_.get_map(), pc_.get_units(), destination, *
type, gender, variation);
770 if(
i == pc_.get_units().end()) {
771 if(!pc_.get_map().is_village(
loc)) {
779 if(
team >
static_cast<int>(pc_.get_teams().size())) {
784 int side =
i->side();
786 if(side >
static_cast<int>(pc_.get_teams().size())) {
791 if(pc_.get_map().is_village(
loc)) {
803 void menu_handler::label_terrain(
mouse_handler& mousehandler,
bool team_only)
806 if(pc_.get_map().on_board(
loc) ==
false) {
811 std::string
label = old_label ? old_label->
text() :
"";
813 if(gui2::dialogs::edit_label::execute(
label, team_only)) {
814 std::string team_name;
818 team_name = gui_->labels().team_name();
822 const terrain_label* res = gui_->labels().set_label(
loc,
label, gui_->viewing_team_index(), team_name, color);
829 void menu_handler::clear_labels()
831 if(!board().is_observer()) {
834 _(
"Are you sure you want to clear map labels?"),
839 std::string viewing_team = gui_->viewing_team().team_name();
840 gui_->labels().clear(viewing_team,
false);
846 void menu_handler::label_settings()
848 if(gui2::dialogs::label_settings::execute(board())) {
849 gui_->labels().recalculate_labels();
856 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
858 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
862 move_unit_to_loc(
i,
i->get_interrupted_move(),
true, side_num, mousehandler);
871 assert(ui != pc_.get_units().end());
875 if(route.
steps.empty()) {
879 assert(route.
steps.front() == ui->get_location());
881 gui_->set_route(&route);
882 gui_->unhighlight_reach();
885 LOG_NG <<
"move_unit_to_loc " << route.
steps.front() <<
" to " << route.
steps.back();
890 gui_->set_route(
nullptr);
891 gui_->invalidate_game_status();
900 bool wait_blocker_move =
true;
901 std::set<map_location> fully_moved;
904 bool blocked_unit =
false;
907 blocked_unit =
false;
908 for(
auto&
unit : pc_.get_units()) {
916 if(goto_loc == current_loc) {
921 if(!pc_.get_map().on_board(goto_loc)) {
926 if(fully_moved.count(current_loc)) {
932 if(route.
steps.size() <= 1) {
933 fully_moved.insert(current_loc);
939 pathfind::marked_route::mark_map::const_iterator
w = route.
marks.begin();
940 for(;
w != route.
marks.end(); ++
w) {
941 if(
w->second.turns == 1) {
942 next_stop =
w->first;
947 if(next_stop == current_loc) {
948 fully_moved.insert(current_loc);
954 if(pc_.get_units().count(next_stop)) {
956 if(wait_blocker_move)
960 gui_->set_route(&route);
963 LOG_NG <<
"execute goto from " << route.
steps.front() <<
" to " << route.
steps.back();
970 wait_blocker_move =
true;
974 if(!change && wait_blocker_move) {
976 wait_blocker_move =
false;
979 }
while(change && blocked_unit);
982 gui_->set_route(
nullptr);
983 gui_->invalidate_game_status();
986 void menu_handler::toggle_ellipses()
989 gui_->invalidate_all();
992 void menu_handler::toggle_grid()
995 gui_->invalidate_all();
998 void menu_handler::unit_hold_position(
mouse_handler& mousehandler,
int side_num)
1001 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1002 un->toggle_hold_position();
1007 if(un->hold_position()) {
1016 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1017 un->toggle_user_end_turn();
1022 if(un->user_end_turn()) {
1034 void menu_handler::search()
1036 std::ostringstream
msg;
1038 if(last_search_hit_.valid()) {
1039 msg <<
" [" << last_search_ <<
"]";
1045 void menu_handler::do_speak()
1049 chat_handler::do_speak(
1050 textbox_info_.box()->text(), textbox_info_.check() !=
nullptr ? textbox_info_.check()->checked() :
false);
1053 void menu_handler::add_chat_message(
const std::time_t& time,
1054 const std::string& speaker,
1056 const std::string& message,
1059 gui_->get_chat_manager().add_chat_message(time, speaker, side, message,
type,
false);
1086 using chmap::get_commands_list;
1087 using chmap::command_failed;
1093 chat_command_handler::command_handler
h,
1094 const std::string&
help =
"",
1095 const std::string& usage =
"",
1096 const std::string& flags =
"")
1098 chmap::register_command(cmd,
h,
help, usage, flags +
"N");
1103 chmap::register_alias(to_cmd, cmd);
1108 return chmap::get_arg(
i);
1113 return chmap::get_cmd();
1118 return chmap::get_data(
n);
1122 using chmap::register_command;
1123 using chmap::register_alias;
1125 using chmap::is_enabled;
1126 using chmap::command_failed_need_arg;
1134 void do_controller();
1136 void do_foreground();
1139 void do_benchmark();
1141 void do_save_quit();
1143 void do_ignore_replay_errors();
1145 void do_next_level();
1146 void do_choose_level();
1148 void do_turn_limit();
1152 void do_unsafe_lua();
1154 void do_set_alias();
1158 void do_control_dialog();
1163 void do_undiscover();
1169 void do_toggle_draw_coordinates();
1170 void do_toggle_draw_terrain_codes();
1171 void do_toggle_draw_num_of_bitmaps();
1172 void do_toggle_whiteboard();
1173 void do_whiteboard_options();
1177 return _(
"(D) — debug only, (N) — network only, (A) — admin only");
1180 using chat_command_handler::get_command_flags_description;
1183 std::string space(
" ");
1184 return (
c.has_flag(
'D') ? space +
_(
"(debug command)") :
"")
1185 + (
c.has_flag(
'N') ? space +
_(
"(network only)") :
"")
1186 + (
c.has_flag(
'A') ? space +
_(
"(admin only)") :
"")
1187 + (
c.has_flag(
'S') ? space +
_(
"(not during other events)") :
"");
1190 using map::is_enabled;
1194 || (
c.has_flag(
'N') && !menu_handler_.pc_.is_networked_mp())
1199 void print(
const std::string& title,
const std::string& message)
1201 menu_handler_.add_chat_message(std::time(
nullptr), title, 0, message);
1206 chat_command_handler::init_map();
1208 chmap::get_command(
"log")->flags =
"";
1209 chmap::get_command(
"version")->flags =
"";
1210 chmap::get_command(
"ignore")->flags =
"";
1211 chmap::get_command(
"friend")->flags =
"";
1212 chmap::get_command(
"remove")->flags =
"";
1214 chmap::set_cmd_prefix(
":");
1215 chmap::set_cmd_flag(
true);
1217 register_command(
"refresh", &console_handler::do_refresh,
_(
"Refresh gui."));
1218 register_command(
"droid", &console_handler::do_droid,
_(
"Switch a side to/from AI control."),
1222 _(
"[<side> [on/off/full]]\n“on” = enable but retain vision, “full” = as if it’s controlled by another player"));
1223 register_command(
"terrain", &console_handler::do_terrain,
_(
"Change terrain type of current hex"),
1225 _(
"<terrain type> [both|base|overlay]"),
"DS");
1226 register_command(
"idle", &console_handler::do_idle,
_(
"Switch a side to/from idle state."),
1230 _(
"command_idle^[<side> [on/off]]"));
1231 register_command(
"theme", &console_handler::do_theme,
_(
"Change the in-game theme."));
1232 register_command(
"control", &console_handler::do_control,
1233 _(
"Assign control of a side to a different player or observer."),
_(
"<side> <nickname>"),
"N");
1234 register_command(
"controller", &console_handler::do_controller,
_(
"Query the controller status of a side."),
1236 register_command(
"clear", &console_handler::do_clear,
_(
"Clear chat history."));
1237 register_command(
"foreground", &console_handler::do_foreground,
_(
"Debug foreground terrain."),
"",
"D");
1239 "layers", &console_handler::do_layers,
_(
"Debug layers from terrain under the mouse."),
"",
"D");
1240 register_command(
"fps", &console_handler::do_fps,
_(
"Display and log fps (Frames Per Second)."));
1241 register_command(
"benchmark", &console_handler::do_benchmark,
_(
"Similar to the ‘fps’ command, but also forces everything to redraw instead of only things that have changed."));
1242 register_command(
"save", &console_handler::do_save,
_(
"Save game."));
1243 register_alias(
"save",
"w");
1244 register_command(
"quit", &console_handler::do_quit,
_(
"Quit game."));
1246 register_alias(
"quit",
"q!");
1247 register_command(
"save_quit", &console_handler::do_save_quit,
_(
"Save and quit."));
1248 register_alias(
"save_quit",
"wq");
1249 register_command(
"ignore_replay_errors", &console_handler::do_ignore_replay_errors,
_(
"Ignore replay errors."));
1250 register_command(
"nosaves", &console_handler::do_nosaves,
_(
"Disable autosaves."));
1251 register_command(
"next_level", &console_handler::do_next_level,
1252 _(
"Advance to the next scenario, or scenario identified by ‘id’"),
_(
"<id>"),
"DS");
1253 register_alias(
"next_level",
"n");
1254 register_command(
"choose_level", &console_handler::do_choose_level,
_(
"Choose next scenario"),
"",
"DS");
1255 register_alias(
"choose_level",
"cl");
1256 register_command(
"turn", &console_handler::do_turn,
1257 _(
"Change turn number (and time of day), or increase by one if no number is specified."),
_(
"[turn]"),
1259 register_command(
"turn_limit", &console_handler::do_turn_limit,
1260 _(
"Change turn limit, or turn the turn limit off if no number is specified or it’s −1."),
_(
"[limit]"),
1262 register_command(
"debug", &console_handler::do_debug,
_(
"Turn debug mode on."));
1263 register_command(
"nodebug", &console_handler::do_nodebug,
_(
"Turn debug mode off."),
"",
"D");
1265 "lua", &console_handler::do_lua,
_(
"Execute a Lua statement."),
_(
"<command>[;<command>...]"),
"DS");
1267 "unsafe_lua", &console_handler::do_unsafe_lua,
_(
"Grant higher privileges to Lua scripts."),
"",
"D");
1268 register_command(
"custom", &console_handler::do_custom,
_(
"Set the command used by the custom command hotkey"),
1269 _(
"<command>[;<command>...]"));
1270 register_command(
"give_control", &console_handler::do_control_dialog,
1271 _(
"Invoke a dialog allowing changing control of MP sides."),
"",
"N");
1272 register_command(
"inspect", &console_handler::do_inspect,
_(
"Launch the gamestate inspector"),
"",
"D");
1274 "alias", &console_handler::do_set_alias,
_(
"Set or show alias to a command"),
_(
"<name>[=<command>]"));
1276 "set_var", &console_handler::do_set_var,
_(
"Set a scenario variable."),
_(
"<var>=<value>"),
"DS");
1277 register_command(
"show_var", &console_handler::do_show_var,
_(
"Show a scenario variable."),
_(
"<var>"),
"D");
1278 register_command(
"unit", &console_handler::do_unit,
1280 _(
"Modify a unit variable. (Only top level keys are supported, and advances=<number>.)"),
1281 _(
"<var>=<value>"),
"DS");
1287 register_command(
"discover", &console_handler::do_discover,
_(
"Discover all units in help."),
"");
1288 register_command(
"undiscover", &console_handler::do_undiscover,
_(
"‘Undiscover’ all units in help."),
"");
1289 register_command(
"create", &console_handler::do_create,
_(
"Create a unit."),
_(
"<unit type id>"),
"DS");
1290 register_command(
"fog", &console_handler::do_fog,
_(
"Toggle fog for the current player."),
"",
"DS");
1291 register_command(
"shroud", &console_handler::do_shroud,
_(
"Toggle shroud for the current player."),
"",
"DS");
1292 register_command(
"gold", &console_handler::do_gold,
_(
"Give gold to the current player."),
_(
"<amount>"),
"DS");
1293 register_command(
"throw", &console_handler::do_event,
_(
"Fire a game event."),
_(
"<event name>"),
"DS");
1294 register_alias(
"throw",
"fire");
1295 register_command(
"show_coordinates", &console_handler::do_toggle_draw_coordinates,
1296 _(
"Toggle overlaying of x,y coordinates on hexes."));
1297 register_alias(
"show_coordinates",
"sc");
1298 register_command(
"show_terrain_codes", &console_handler::do_toggle_draw_terrain_codes,
1299 _(
"Toggle overlaying of terrain codes on hexes."));
1300 register_alias(
"show_terrain_codes",
"tc");
1301 register_command(
"show_num_of_bitmaps", &console_handler::do_toggle_draw_num_of_bitmaps,
1302 _(
"Toggle overlaying of number of bitmaps on hexes."));
1303 register_alias(
"show_num_of_bitmaps",
"bn");
1304 register_command(
"whiteboard", &console_handler::do_toggle_whiteboard,
_(
"Toggle planning mode."));
1305 register_alias(
"whiteboard",
"wb");
1307 "whiteboard_options", &console_handler::do_whiteboard_options,
_(
"Access whiteboard options dialog."));
1308 register_alias(
"whiteboard_options",
"wbo");
1310 if(
auto alias_list =
prefs::get().get_alias()) {
1311 for(
const auto& [key, value] : alias_list->attribute_range()) {
1312 register_alias(value, key);
1322 void menu_handler::send_chat_message(
const std::string& message,
bool allies_only)
1326 cfg[
"message"] = message;
1327 auto now = std::chrono::system_clock::now();
1330 const int side = board().
is_observer() ? 0 : gui_->viewing_team().side();
1331 if(!board().is_observer()) {
1338 if(board().is_observer()) {
1341 cfg[
"to_sides"] = gui_->viewing_team().allied_human_teams();
1347 auto as_time_t = std::chrono::system_clock::to_time_t(now);
1348 add_chat_message(as_time_t, cfg[
"id"], side, message,
1352 void menu_handler::do_search(
const std::string& new_search)
1354 if(new_search.empty() ==
false && new_search != last_search_)
1355 last_search_ = new_search;
1357 if(last_search_.empty())
1363 std::vector<std::string> args =
utils::split(last_search_,
',');
1364 if(args.size() == 2) {
1366 x = lexical_cast_default<int>(args[0], 0) - 1;
1367 y = lexical_cast_default<int>(args[1], 0) - 1;
1368 if(x >= 0 && x < pc_.get_map().w() && y >= 0 && y < pc_.get_map().h()) {
1381 loc.
x = (
loc.
x + 1) % pc_.get_map().w();
1383 loc.
y = (
loc.
y + 1) % pc_.get_map().h();
1386 if(!gui_->shrouded(
loc)) {
1389 const std::string& label_text =
label->text().str();
1395 if(!gui_->fogged(
loc)) {
1397 if(ui != pc_.get_units().end()) {
1398 const std::string&
unit_name = ui->name();
1400 if(!gui_->viewing_team().is_enemy(ui->side())
1401 || !ui->invisible(ui->get_location())) {
1413 last_search_hit_ =
loc;
1415 gui_->highlight_hex(
loc);
1420 symbols[
"search"] = last_search_;
1421 const std::string
msg =
VGETTEXT(
"Could not find label or unit "
1422 "containing the string ‘$search’.",
1428 void menu_handler::do_command(
const std::string& str)
1434 std::vector<std::string> menu_handler::get_commands_list()
1445 void console_handler::do_refresh()
1450 menu_handler_.gui_->create_buttons();
1451 menu_handler_.gui_->queue_rerender();
1454 void console_handler::do_droid()
1457 const std::string side_s = get_arg(1);
1458 std::string action = get_arg(2);
1459 std::transform(action.begin(), action.end(), action.begin(), tolower);
1461 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1462 const bool is_your_turn = menu_handler_.pc_.current_side() ==
static_cast<int>(menu_handler_.gui_->viewing_team().side());
1465 symbols[
"side"] = std::to_string(side);
1467 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1468 command_failed(
VGETTEXT(
"Can’t droid invalid side: ‘$side’.", symbols));
1470 }
else if(menu_handler_.board().get_team(side).is_network()) {
1471 command_failed(
VGETTEXT(
"Can’t droid networked side: ‘$side’.", symbols));
1473 }
else if(menu_handler_.board().get_team(side).is_local()) {
1474 bool changed =
false;
1476 const bool is_human = menu_handler_.board().get_team(side).is_human();
1477 const bool is_droid = menu_handler_.board().get_team(side).is_droid();
1478 const bool is_proxy_human = menu_handler_.board().get_team(side).is_proxy_human();
1479 const bool is_ai = menu_handler_.board().get_team(side).is_ai();
1481 if(action ==
"on") {
1482 if(is_ai && !is_your_turn) {
1483 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1486 if(!is_human || !is_droid) {
1487 menu_handler_.board().get_team(side).make_human();
1488 menu_handler_.board().get_team(side).make_droid();
1491 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1493 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: AI.", symbols));
1495 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already droided.", symbols));
1497 }
else if(action ==
"off") {
1498 if(is_ai && !is_your_turn) {
1499 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1502 if(!is_human || !is_proxy_human) {
1503 menu_handler_.board().get_team(side).make_human();
1504 menu_handler_.board().get_team(side).make_proxy_human();
1507 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1509 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: human.", symbols));
1511 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already not droided.", symbols));
1513 }
else if(action ==
"full") {
1515 command_failed(
_(
"It is not allowed to change a side from human to AI control when it’s not your turn."));
1518 if(!is_ai || !is_droid) {
1519 menu_handler_.board().get_team(side).make_ai();
1520 menu_handler_.board().get_team(side).make_droid();
1522 if(is_human || is_proxy_human) {
1523 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::ai}});
1525 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now fully controlled by: AI.", symbols));
1527 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already fully AI controlled.", symbols));
1529 }
else if(action ==
"") {
1530 if(is_ai && !is_your_turn) {
1531 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1534 if(is_ai || is_droid) {
1535 menu_handler_.board().get_team(side).make_human();
1536 menu_handler_.board().get_team(side).make_proxy_human();
1539 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1541 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: human.", symbols));
1543 menu_handler_.board().get_team(side).make_human();
1544 menu_handler_.board().get_team(side).make_droid();
1547 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1549 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: AI.", symbols));
1552 print(get_cmd(),
VGETTEXT(
"Invalid action provided for side ‘$side’. Valid actions are: on, off, full.", symbols));
1555 if(team_num_ == side && changed) {
1557 psc->set_player_type_changed();
1561 command_failed(
VGETTEXT(
"Side ‘$side’ is not a human or AI player.", symbols));
1564 menu_handler_.textbox_info_.close();
1567 void console_handler::do_terrain()
1571 const std::string mode_str = get_arg(2);
1581 "mode_str", mode_str,
1586 void console_handler::do_idle()
1589 const std::string side_s = get_arg(1);
1590 const std::string action = get_arg(2);
1592 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1594 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1596 symbols[
"side"] = side_s;
1597 command_failed(
VGETTEXT(
"Can’t idle invalid side: ‘$side’.", symbols));
1599 }
else if(menu_handler_.board().get_team(side).is_network()) {
1601 symbols[
"side"] = std::to_string(side);
1602 command_failed(
VGETTEXT(
"Can’t idle networked side: ‘$side’.", symbols));
1604 }
else if(menu_handler_.board().get_team(side).is_local_ai()) {
1606 symbols[
"side"] = std::to_string(side);
1607 command_failed(
VGETTEXT(
"Can’t idle local ai side: ‘$side’.", symbols));
1609 }
else if(menu_handler_.board().get_team(side).is_local_human()) {
1610 if(menu_handler_.board().get_team(side).is_idle() ? action ==
" on" : action ==
" off") {
1614 menu_handler_.board().get_team(side).toggle_idle();
1615 if(team_num_ == side) {
1617 psc->set_player_type_changed();
1621 menu_handler_.textbox_info_.close();
1624 void console_handler::do_theme()
1638 return t.save_id() == save_id_;
1644 void console_handler::do_control()
1647 if(!menu_handler_.pc_.is_networked_mp()) {
1651 const std::string side = get_arg(1);
1652 const std::string player = get_arg(2);
1653 if(player.empty()) {
1654 command_failed_need_arg(2);
1658 unsigned int side_num;
1660 side_num = lexical_cast<unsigned int>(side);
1662 const auto& teams = menu_handler_.pc_.get_teams();
1663 const auto it_t = std::find_if(teams.begin(), teams.end(),
save_id_matches(side));
1665 if(it_t == teams.end()) {
1667 symbols[
"side"] = side;
1668 command_failed(
VGETTEXT(
"Can’t change control of invalid side: ‘$side’.", symbols));
1671 side_num = it_t->side();
1675 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1677 symbols[
"side"] = side;
1678 command_failed(
VGETTEXT(
"Can’t change control of out-of-bounds side: ‘$side’.", symbols));
1682 menu_handler_.request_control_change(side_num, player);
1683 menu_handler_.textbox_info_.close();
1686 void console_handler::do_controller()
1688 const std::string side = get_arg(1);
1689 unsigned int side_num;
1691 side_num = lexical_cast<unsigned int>(side);
1694 symbols[
"side"] = side;
1695 command_failed(
VGETTEXT(
"Can’t query control of invalid side: ‘$side’.", symbols));
1699 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1701 symbols[
"side"] = side;
1702 command_failed(
VGETTEXT(
"Can’t query control of out-of-bounds side: ‘$side’.", symbols));
1707 if(!menu_handler_.board().get_team(side_num).is_proxy_human()) {
1711 if(menu_handler_.board().get_team(side_num).is_network()) {
1712 report +=
" (networked)";
1715 print(get_cmd(), report);
1718 void console_handler::do_clear()
1720 menu_handler_.gui_->get_chat_manager().clear_chat_messages();
1723 void console_handler::do_foreground()
1726 menu_handler_.gui_->invalidate_all();
1729 void console_handler::do_layers()
1731 display& disp = *(menu_handler_.gui_);
1745 if(menu_handler_.pc_.get_map().on_board_with_border(
loc)) {
1746 gui2::dialogs::terrain_layers::display(disp,
loc);
1750 void console_handler::do_fps()
1755 void console_handler::do_benchmark()
1760 void console_handler::do_save()
1762 menu_handler_.pc_.do_consolesave(get_data());
1765 void console_handler::do_save_quit()
1771 void console_handler::do_quit()
1776 void console_handler::do_ignore_replay_errors()
1781 void console_handler::do_nosaves()
1786 void console_handler::do_next_level()
1791 void console_handler::do_choose_level()
1793 std::string
tag = menu_handler_.pc_.get_classification().get_tagname();
1794 std::vector<std::string> options;
1796 if(
tag !=
"multiplayer") {
1798 const std::string&
id = sc[
"id"];
1799 options.push_back(
id);
1800 if(
id == menu_handler_.gamedata().next_scenario()) {
1807 std::string scenario_id = menu_handler_.pc_.get_mp_settings().mp_scenario;
1808 if(
auto this_scenario = menu_handler_.game_config_.find_child(
tag,
"id", scenario_id)) {
1809 std::string addon_id = this_scenario[
"addon_id"].str();
1811 if(sc[
"addon_id"] == addon_id) {
1812 std::string
id = sc[
"id"];
1813 options.push_back(
id);
1814 if(
id == menu_handler_.gamedata().next_scenario()) {
1821 std::sort(options.begin(), options.end());
1822 int choice = std::distance(options.begin(), std::lower_bound(options.begin(), options.end(), next));
1834 if(std::size_t(choice) < options.size()) {
1839 void console_handler::do_turn()
1841 tod_manager& tod_man = menu_handler_.gamestate().tod_manager_;
1843 int turn = tod_man.
turn() + 1;
1844 const std::string&
data = get_data();
1846 turn = lexical_cast_default<int>(
data, 1);
1851 void console_handler::do_turn_limit()
1853 int limit = get_data().empty() ? -1 : lexical_cast_default<int>(get_data(), 1);
1857 void console_handler::do_debug()
1860 print(get_cmd(),
_(
"Debug mode activated!"));
1863 command_failed(
_(
"Debug mode not available in network games"));
1867 void console_handler::do_nodebug()
1870 print(get_cmd(),
_(
"Debug mode deactivated!"));
1875 void console_handler::do_lua()
1877 if(!menu_handler_.gamestate().lua_kernel_) {
1884 void console_handler::do_unsafe_lua()
1886 if(!menu_handler_.gamestate().lua_kernel_) {
1891 _(
"Executing Lua code in in this manner opens your computer to potential security breaches from any "
1892 "malicious add-ons or other programs you may have installed.\n\n"
1896 print(get_cmd(),
_(
"Unsafe mode enabled!"));
1897 menu_handler_.gamestate().lua_kernel_->load_package();
1901 void console_handler::do_custom()
1906 void console_handler::do_set_alias()
1908 const std::string
data = get_data();
1910 const std::string alias(
data.begin(), j);
1911 if(j !=
data.end()) {
1912 const std::string command(j + 1,
data.end());
1913 if(!command.empty()) {
1914 register_alias(command, alias);
1918 register_alias(alias, alias);
1926 const std::string command = chmap::get_actual_cmd(alias);
1927 print(get_cmd(),
"'" + alias +
"'" +
" = " +
"'" + command +
"'");
1931 void console_handler::do_set_var()
1933 const std::string
data = get_data();
1935 command_failed_need_arg(1);
1940 if(j !=
data.end()) {
1941 const std::string name(
data.begin(), j);
1942 const std::string value(j + 1,
data.end());
1945 command_failed(
_(
"Variable not found"));
1949 void console_handler::do_show_var()
1954 void console_handler::do_inspect()
1957 gui2::dialogs::gamestate_inspector::display(
1961 void console_handler::do_control_dialog()
1963 gui2::dialogs::mp_change_control::display(menu_handler_);
1966 void console_handler::do_unit()
1974 if(
i == menu_handler_.pc_.get_units().end()) {
1976 symbols[
"unit"] = get_arg(1);
1978 "Debug command ‘unit: $unit’ failed: no unit selected or hovered over.",
1984 const std::string
data = get_data(1);
1986 if(parameters.size() < 2) {
1990 if(parameters[0] ==
"alignment") {
1994 symbols[
"alignment"] = get_arg(1);
1996 "Invalid alignment: ‘$alignment’, needs to be one of lawful, neutral, chaotic, or liminal.",
2006 "name", parameters[0],
2007 "value", parameters[1],
2012 void console_handler::do_discover()
2014 for(
const unit_type_data::unit_type_map::value_type&
i :
unit_types.
types()) {
2019 void console_handler::do_undiscover()
2029 void console_handler::do_create()
2033 if(menu_handler_.pc_.get_map().on_board(
loc)) {
2036 command_failed(
_(
"Invalid unit type"));
2041 create_and_place(*menu_handler_.gui_, menu_handler_.pc_.get_map(), menu_handler_.pc_.get_units(),
loc, *ut);
2043 command_failed(
_(
"Invalid location"));
2047 void console_handler::do_fog()
2052 void console_handler::do_shroud()
2057 void console_handler::do_gold()
2062 void console_handler::do_event()
2067 void console_handler::do_toggle_draw_coordinates()
2070 menu_handler_.gui_->invalidate_all();
2072 void console_handler::do_toggle_draw_terrain_codes()
2075 menu_handler_.gui_->invalidate_all();
2078 void console_handler::do_toggle_draw_num_of_bitmaps()
2081 menu_handler_.gui_->invalidate_all();
2084 void console_handler::do_toggle_whiteboard()
2086 if(
const std::shared_ptr<wb::manager>& whiteb = menu_handler_.pc_.get_whiteboard()) {
2087 whiteb->set_active(!whiteb->is_active());
2088 if(whiteb->is_active()) {
2089 print(get_cmd(),
_(
"Planning mode activated!"));
2090 whiteb->print_help_once();
2092 print(get_cmd(),
_(
"Planning mode deactivated!"));
2097 void console_handler::do_whiteboard_options()
2099 if(menu_handler_.pc_.get_whiteboard()) {
2100 menu_handler_.pc_.get_whiteboard()->options_dlg();
2104 void menu_handler::do_ai_formula(
const std::string& str,
int side_num,
mouse_handler& )
2114 void menu_handler::user_command()
2119 void menu_handler::request_control_change(
int side_num,
const std::string& player)
2121 std::string side = std::to_string(side_num);
2122 if(board().get_team(side_num).is_local_human() && player ==
prefs::get().login()) {
2128 pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player", player}});
2132 void menu_handler::custom_command()
2135 do_command(command);
2139 void menu_handler::ai_formula()
2141 if(!pc_.is_networked_mp()) {
2146 void menu_handler::clear_messages()
2148 gui_->get_chat_manager().clear_chat_messages();
2153 pc_.send_to_wesnothd(cfg);
Various functions related to moving units.
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
static manager & get_singleton()
A config object defines a single node in a WML file, with access to child nodes.
child_itors child_range(config_key_type key)
int village_owner(const map_location &loc) const
Given the location of a village, will return the 1-based number of the team that currently owns it,...
bool is_observer() const
Check if we are an observer in this game.
can_move_result unit_can_move(const unit &u) const
Work out what u can do - this does not check which player's turn is currently active,...
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
const team & viewing_team() const
@ DEBUG_COORDINATES
Overlays x,y coords on tiles.
@ DEBUG_BENCHMARK
Toggle to continuously redraw the whole map.
@ DEBUG_NUM_BITMAPS
Overlays number of bitmaps on tiles.
@ DEBUG_FOREGROUND
Separates background and foreground terrain layers.
@ DEBUG_TERRAIN_CODES
Overlays terrain codes on tiles.
void queue_rerender()
Marks everything for rendering including all tiles and sidebar.
virtual std::string get_arg(unsigned i) const
std::string get_flags_description() const
virtual std::string get_cmd() const
console_handler(menu_handler &menu_handler)
void print(const std::string &title, const std::string &message)
virtual void register_alias(const std::string &to_cmd, const std::string &cmd)
bool is_enabled(const chmap::command &c) const
virtual std::string get_data(unsigned n=1) const
menu_handler & menu_handler_
std::string get_command_flags_description(const chmap::command &c) const
virtual void register_command(const std::string &cmd, chat_command_handler::command_handler h, const std::string &help="", const std::string &usage="", const std::string &flags="")
map_command_handler< console_handler > chmap
const unsigned int team_num_
std::vector< std::string > get_commands_list() const
void dispatch(std::string cmd)
game_board & board() const
gui::floating_textbox & get_textbox()
menu_handler(game_display *gui, play_controller &pc)
gui::floating_textbox textbox_info_
void show_statistics(int side_num)
void recruit(int side_num, const map_location &last_hex)
t_string can_recruit(const std::string &name, int side_num, map_location &target_hex, map_location &recruited_from)
game_state & gamestate() const
void disable_units_highlight()
Use this to disable hovering an unit from highlighting its movement range.
void set_current_paths(const pathfind::paths &new_paths)
pathfind::marked_route get_route(const unit *un, map_location go_to, const team &team) const
map_location get_selected_hex() const
const map_location hovered_hex() const
Uses SDL and game_display::hex_clicked_on to fetch the hex the mouse is hovering, if applicable.
const map_location & get_last_hex() const
bool hex_hosts_unit(const map_location &hex) const
Unit exists on the hex, no matter if friend or foe.
void cycle_units(const bool browse, const bool reverse=false)
unit_map::iterator find_visible_unit(const map_location &loc, const team ¤t_team, bool see_all=false)
void scroll_to_leader(int side, SCROLL_TYPE scroll_type=ONSCREEN, bool force=true)
Scrolls to the leader of a certain side.
virtual const std::set< std::string > & observers() const override
Encapsulates the map of the game.
std::string write() const
file_dialog & set_extension(const std::string &value)
Sets allowed file extensions for file names in save mode.
file_dialog & set_path(const std::string &value)
Sets the initial file selection.
file_dialog & set_title(const std::string &value)
Sets the current dialog title text.
file_dialog & set_save_mode(bool value)
Sets the dialog's behavior on non-existent file name inputs.
std::string path() const
Gets the current file selection.
static bool execute(game_board &board, const team viewing_team, int &selected_side_number)
@ yes_no_buttons
Shows a yes and no button.
@ ok_cancel_buttons
Shows an ok and cancel button.
@ auto_close
Enables auto close.
bool show(const unsigned auto_close_time=0)
Shows the window.
int selected_index() const
Returns the selected item index after displaying.
void set_selected_index(int index)
Sets the initially selected item index (-1 by default).
unit_race::GENDER gender()
Gender choice from the user.
bool no_choice() const
Whether the user actually chose a unit type or not.
std::string variation() const
Variation choice from the user.
const std::string & choice() const
Unit type choice from the user.
int get_selected_index() const
void show(gui::TEXTBOX_MODE mode, const std::string &label, const std::string &check_label, bool checked, game_display &gui)
std::vector< team > & get_teams()
void show_objectives() const
statistics_t & statistics()
events::mouse_handler & get_mouse_handler_base() override
Get a reference to a mouse handler member a derived class uses.
const gamemap & get_map() const
void refresh_objectives() const
Reevaluate [show_if] conditions and build a new objectives string.
void notify_event(const std::string &name, const config &data)
static plugins_manager * get()
std::set< std::string > & encountered_units()
void add_alias(const std::string &alias, const std::string &command)
void set_message_private(bool value)
void set_show_fps(bool value)
bool empty() const
Is it empty?
static config get_recall(const std::string &unit_id, const map_location &loc, const map_location &from)
static config get_auto_shroud(bool turned_on)
Records that the player has toggled automatic shroud updates.
static config get_recruit(const std::string &type_id, const map_location &loc, const map_location &from)
static config get_update_shroud()
Records that the player has manually updated fog/shroud.
void add_rename(const std::string &name, const map_location &loc)
void add_label(const terrain_label *)
void speak(const config &cfg)
void clear_labels(const std::string &, bool)
static synced_state get_synced_state()
static bool run_and_throw(const std::string &commandname, const config &data, action_spectator &spectator=get_default_spectator())
This class stores all the data for a single 'side' (in game nomenclature).
void set_action_bonus_count(const int count)
bool auto_shroud_updates() const
const std::string & team_name() const
int action_bonus_count() const
static color_t get_side_color(int side)
recall_list_manager & recall_list()
const std::string & last_recruit() const
To store label data Class implements logic for rendering.
const t_string & text() const
Container associating units to locations.
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
const unit_type_map & types() const
A single unit type that the player may recruit.
const std::string & id() const
The id for this unit_type.
const std::vector< unit_race::GENDER > & genders() const
The returned vector will not be empty, provided this has been built to the HELP_INDEXED status.
const t_string & type_name() const
The name of the unit in the current language setting.
This class represents a single unit of a specific type.
A variable-expanding proxy for the config class.
static vconfig empty_vconfig()
Various functions related to the creation of units (recruits, recalls, and placed units).
static void print(std::stringstream &sstr, const std::string &queue, const std::string &id)
Contains the exception interfaces used to signal completion of a scenario, campaign or turn.
void throw_quit_game_exception()
int dispatch(lua_State *L)
static std::string _(const char *str)
bool user_end_turn() const
Check whether the user ended their turn.
const std::string & id() const
Gets this unit's id.
int side() const
The side this unit belongs to.
const t_string & name() const
Gets this unit's translatable display name.
const map_location & get_location() const
The current map location this unit is at.
bool has_moved() const
Checks if this unit has moved.
void set_goto(const map_location &new_goto)
Sets this unit's long term destination.
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
const map_location & get_goto() const
The map location to which this unit is moving over multiple turns, if any.
std::string label
What to show in the filter's drop-down list.
std::string id
Text to match against addon_info.tags()
Standard logging facilities (interface).
std::string find_recruit_location(const int side, map_location &recruit_location, map_location &recruited_from, const std::string &unit_type)
Finds a location on which to place a unit.
const std::set< std::string > get_recruits(int side, const map_location &recruit_loc)
Gets the recruitable units from a side's leaders' personal recruit lists who can recruit on or from a...
game_events::pump_result_t get_village(const map_location &loc, int side, bool *action_timebonus, bool fire_event)
Makes it so the village at the given location is owned by the given side.
std::vector< unit_const_ptr > get_recalls(int side, const map_location &recall_loc)
Gets the recallable units for a side, restricted by that side's leaders' personal abilities to recall...
std::size_t move_unit_and_record(const std::vector< map_location > &steps, bool continued_move, bool *interrupted)
Wrapper around the other overload.
std::string find_recall_location(const int side, map_location &recall_location, map_location &recall_from, const unit &unit_recall)
Finds a location on which to recall unit_recall.
auto serialize_timestamp(const std::chrono::system_clock::time_point &time)
EXIT_STATUS start(bool clear_id, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
Handling of system events.
std::string get_legacy_editor_dir()
const std::string map_extension
void write_file(const std::string &fname, const std::string &data, std::ios_base::openmode mode)
Throws io_exception if an error occurs.
const color_t LABEL_COLOR
std::string private_message
Game configuration data as global variables.
bool ignore_replay_errors
const std::string observer_team_name
observer team name used for observer team chat
void set_debug(bool new_debug)
void show_unit_list(display &gui)
void show_transient_error_message(const std::string &message, const std::string &image, const bool message_use_markup)
Shows a transient error message to the user.
void show_transient_message(const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup)
Shows a transient message to the user.
void show_message(const std::string &title, const std::string &msg, const std::string &button_caption, const bool auto_close, const bool message_use_markup, const bool title_use_markup)
Shows a message to the user.
retval
Default window/dialog return values.
@ OK
Dialog was closed with the OK button.
@ CANCEL
Dialog was closed with the CANCEL button.
void show_help(const std::string &show_topic)
Open the help browser, show topic with id show_topic.
void show_terrain_description(const terrain_type &t)
void show_unit_description(const unit &u)
void flush_cache()
Purges all image caches.
std::string tag(const std::string &tag_name, Args &&... contents)
void send_to_server(const config &data)
Attempts to send given data to server if a connection is open.
bool logged_in_as_moderator()
Gets whether the currently logged-in user is a moderator.
game_events::manager * game_events
bool ci_search(const std::string &s1, const std::string &s2)
static std::string sgettext(const char *str)
@ STRIP_SPACES
REMOVE_EMPTY: remove empty elements.
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
std::string format_conjunct_list(const t_string &empty, const std::vector< t_string > &elems)
Format a conjunctive list.
std::map< std::string, t_string > string_map
std::vector< std::string > split(const config_attribute_value &val)
auto * find(Container &container, const Value &value)
Convenience wrapper for using find on a container without needing to comare to end()
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
std::shared_ptr< const unit > unit_const_ptr
const std::string & gender_string(unit_race::GENDER gender)
static config unit_name(const unit *u)
Thrown when a lexical_cast fails.
The basic class for representing 8-bit RGB or RGBA colour values.
save_id_matches(const std::string &save_id)
bool operator()(const team &t) const
An exception object used when an IO error occurs.
Encapsulates the map of the game.
static const map_location & null_location()
Structure which holds a single route and marks for special events.
std::vector< map_location > & steps
Object which contains all the possible locations a unit can move to, with associated best routes to t...
static std::string get_string(enum_type key)
Converts a enum to its string equivalent.
static constexpr utils::optional< enum_type > get_enum(const std::string_view value)
Converts a string into its enum equivalent.
Object which temporarily resets a unit's movement.
ONLY IF whiteboard is currently active, applies the planned unit map for the duration of the struct's...
Applies the planned unit map for the duration of the struct's life.
const std::string & gamedata
static map_location::direction n
unit_type_data unit_types
Various functions that implement the undoing (and redoing) of in-game commands.