82 #define ERR_NG LOG_STREAM(err, log_engine)
83 #define LOG_NG LOG_STREAM(info, log_engine)
133 gui2::dialogs::statistics_dialog::display(
pc_.
statistics(),
board().get_team(side_num));
170 symbols[
"msg"] =
e.what();
171 const std::string
msg =
VGETTEXT(
"Could not save the map: $msg", symbols);
178 gui2::dialogs::preferences_dialog::display();
186 c[
"name"] =
"prototype of chat log";
200 ?
board().is_observer()
201 ?
_(
"Send to observers only")
202 :
_(
"Send to allies only")
220 if(
board().is_observer()) {
239 std::map<const unit_type*, t_string> sample_units;
243 std::vector<t_string> unknown_units;
244 for(
const auto&
recruit : recruits) {
248 unknown_units.emplace_back(
recruit);
256 if(!unknown_units.empty()) {
261 const auto message =
VNGETTEXT(
"Error: there’s an unknown unit type on your recruit list: $unknown_ids",
262 "Error: there are several unknown unit types on your recruit list: $unknown_ids",
263 unknown_units.size(),
268 if(sample_units.empty()) {
282 do_recruit(
type->id(), side_num, recruit_hex);
286 void menu_handler::repeat_recruit(
int side_num,
const map_location& last_hex)
288 const std::string& last_recruit = board().get_team(side_num).last_recruit();
289 if(last_recruit.empty() ==
false) {
291 do_recruit(last_recruit, side_num, recruit_hex);
300 team& current_team = board().get_team(side_num);
303 if(u_type ==
nullptr) {
304 return _(
"Internal error. Please report this as a bug! Details:\n")
305 +
"menu_handler::can_recruit: u_type == nullptr for " + name;
310 return VGETTEXT(
"You cannot recruit a $unit_type_name at this time.",
318 wb_gold = (pc_.get_whiteboard() ? pc_.get_whiteboard()->get_spent_gold_for(side_num) : 0);
320 if(u_type->
cost() > current_team.
gold() - wb_gold)
324 return _(
"At this point in your plan, you will not have enough gold to recruit this unit.");
326 return _(
"You do not have enough gold to recruit this unit.");
343 bool menu_handler::do_recruit(
const std::string& name,
int side_num,
map_location& loc)
346 const std::string res = can_recruit(name, side_num, loc, recruited_from);
347 team& current_team = board().get_team(side_num);
349 if(res.empty() && (!pc_.get_whiteboard() || !pc_.get_whiteboard()->save_recruit(name, side_num, loc))) {
357 }
else if(res.empty()) {
368 if(pc_.get_disallow_recall()) {
373 team& current_team = board().get_team(side_num);
375 std::vector<unit_const_ptr> recall_list_team;
383 DBG_WB <<
"menu_handler::recall: Contents of wb-modified recall list:";
390 _(
"There are no troops available to recall.\n(You must have veteran survivors from a previous scenario.)"));
393 if(recall_list_team.empty()) {
416 unit_cost = recall_list_team[res]->recall_cost();
419 int wb_gold = pc_.get_whiteboard() ? pc_.get_whiteboard()->get_spent_gold_for(side_num) : 0;
420 if(current_team.
gold() - wb_gold < unit_cost) {
422 i18n_symbols[
"cost"] = std::to_string(unit_cost);
423 std::string
msg =
VNGETTEXT(
"You must have at least 1 gold piece to recall a unit.",
424 "You must have at least $cost gold pieces to recall this unit.", unit_cost, i18n_symbols);
429 LOG_NG <<
"recall index: " << res;
446 if(!pc_.get_whiteboard()
447 || !pc_.get_whiteboard()->save_recall(*recall_list_team[res].get(), side_num, recall_location)) {
452 ERR_NG <<
"menu_handler::recall(): Unit does not exist in the recall list.";
458 void menu_handler::show_enemy_moves(
bool ignore_units,
int side_num)
465 gui_->unhighlight_reach();
468 for(
auto& u : pc_.get_units()) {
469 bool invisible = u.invisible(u.get_location());
471 if(board().get_team(side_num).is_enemy(u.side()) && !gui_->fogged(u.get_location()) && !u.incapacitated()
475 =
pathfind::paths(u,
false,
true, gui_->viewing_team(), 0,
false, ignore_units);
477 gui_->highlight_another_reach(
path, hex_under_mouse);
481 gui_->invalidate(u.get_location());
486 const bool selected_hex_has_unit = mh.
hex_hosts_unit(hex_under_mouse);
488 if(selected_hex_has_unit) {
497 void menu_handler::toggle_shroud_updates(
int side_num)
499 team& current_team = board().get_team(side_num);
503 update_shroud_now(side_num);
510 void menu_handler::update_shroud_now(
int )
519 bool units_alive(
int side_num,
const unit_map& units)
521 for(
auto&
unit : units) {
530 bool partmoved_units(
531 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
533 for(
auto&
unit : units) {
548 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
550 for(
auto&
unit : units) {
553 && (!whiteb || !whiteb->unit_has_actions(&
unit))) {
563 bool menu_handler::end_turn(
int side_num)
568 reason =
_(
"You cannot end your turn yet!");
574 std::size_t team_num =
static_cast<std::size_t
>(side_num - 1);
575 if(team_num < pc_.get_teams().size() && pc_.get_teams()[team_num].no_turn_confirmation()) {
580 && (!pc_.get_whiteboard() || !pc_.get_whiteboard()->current_side_has_actions())
581 && units_alive(side_num, pc_.get_units())) {
583 _(
"You have not started your turn yet. Do you really want to end your turn?"),
590 else if(
prefs::get().yellow_confirm() && partmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
592 _(
"Some units have movement left. Do you really want to end your turn?"),
599 else if(
prefs::get().green_confirm() && unmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
601 _(
"Some units have not moved. Do you really want to end your turn?"),
610 if(pc_.get_whiteboard() && !pc_.get_whiteboard()->allow_end_turn()) {
617 void menu_handler::goto_leader(
int side_num)
620 if(
i != pc_.get_units().end() &&
i->is_visible_to_team(gui_->viewing_team(),
false)) {
625 void menu_handler::unit_description()
628 if(un != pc_.get_units().end()) {
636 if(pc_.get_map().on_board(loc) ==
false || gui_->shrouded(loc)) {
645 void menu_handler::rename_unit()
648 if(un == pc_.get_units().end() || gui_->viewing_team().side() != un->side()) {
652 if(un->unrenamable()) {
656 std::string name = un->name();
657 const std::string title(
_(
"Rename Unit"));
658 const std::string
label(
_(
"Name:"));
660 if(gui2::dialogs::edit_text::execute(title,
label, name)) {
663 gui_->invalidate_unit();
669 const mouse_handler& mousehandler = pc_.get_mouse_handler_base();
670 const bool see_all = gui_->show_everything() || (pc_.is_replay() && pc_.get_replay_controller()->see_all());
673 if(res != pc_.get_units().end()) {
684 typedef std::tuple<const unit_type*, unit_race::GENDER, std::string> type_gender_variation;
693 type_gender_variation choose_unit()
706 const std::string& ut_id = create_dlg.
choice();
709 ERR_NG <<
"Create unit dialog returned nonexistent or unusable unit_type id '" << ut_id <<
"'.";
722 return type_gender_variation(utp, gender, create_dlg.
variation());
735 const std::string& variation =
"")
743 "variation", variation,
758 assert(gui_ !=
nullptr);
761 if(
const auto& [
type, gender, variation] = choose_unit();
type !=
nullptr) {
763 create_and_place(*gui_, pc_.get_map(), pc_.get_units(), destination, *
type, gender, variation);
771 if(
i == pc_.get_units().end()) {
772 if(!pc_.get_map().is_village(loc)) {
780 if(
team >
static_cast<int>(pc_.get_teams().size())) {
785 int side =
i->side();
787 if(side >
static_cast<int>(pc_.get_teams().size())) {
792 if(pc_.get_map().is_village(loc)) {
804 void menu_handler::label_terrain(
mouse_handler& mousehandler,
bool team_only)
807 if(pc_.get_map().on_board(loc) ==
false) {
811 const terrain_label* old_label = gui_->labels().get_label(loc);
812 std::string
label = old_label ? old_label->
text() :
"";
814 if(gui2::dialogs::edit_label::execute(
label, team_only)) {
815 std::string team_name;
819 team_name = gui_->labels().team_name();
823 const terrain_label* res = gui_->labels().set_label(loc,
label, gui_->viewing_team_index(), team_name, color);
830 void menu_handler::clear_labels()
832 if(!board().is_observer()) {
835 _(
"Are you sure you want to clear map labels?"),
840 std::string viewing_team = gui_->viewing_team().team_name();
841 gui_->labels().clear(viewing_team,
false);
847 void menu_handler::label_settings()
849 if(gui2::dialogs::label_settings::execute(board())) {
850 gui_->labels().recalculate_labels();
857 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
859 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
863 move_unit_to_loc(
i,
i->get_interrupted_move(),
true, side_num, mousehandler);
872 assert(ui != pc_.get_units().end());
876 if(route.
steps.empty()) {
880 assert(route.
steps.front() == ui->get_location());
882 gui_->set_route(&route);
883 gui_->unhighlight_reach();
886 LOG_NG <<
"move_unit_to_loc " << route.
steps.front() <<
" to " << route.
steps.back();
891 gui_->set_route(
nullptr);
892 gui_->invalidate_game_status();
901 bool wait_blocker_move =
true;
902 std::set<map_location> fully_moved;
905 bool blocked_unit =
false;
908 blocked_unit =
false;
909 for(
auto&
unit : pc_.get_units()) {
917 if(goto_loc == current_loc) {
922 if(!pc_.get_map().on_board(goto_loc)) {
927 if(fully_moved.count(current_loc)) {
933 if(route.
steps.size() <= 1) {
934 fully_moved.insert(current_loc);
940 pathfind::marked_route::mark_map::const_iterator
w = route.
marks.begin();
941 for(;
w != route.
marks.end(); ++
w) {
942 if(
w->second.turns == 1) {
943 next_stop =
w->first;
948 if(next_stop == current_loc) {
949 fully_moved.insert(current_loc);
955 if(pc_.get_units().count(next_stop)) {
957 if(wait_blocker_move)
961 gui_->set_route(&route);
964 LOG_NG <<
"execute goto from " << route.
steps.front() <<
" to " << route.
steps.back();
971 wait_blocker_move =
true;
975 if(!change && wait_blocker_move) {
977 wait_blocker_move =
false;
980 }
while(change && blocked_unit);
983 gui_->set_route(
nullptr);
984 gui_->invalidate_game_status();
987 void menu_handler::toggle_ellipses()
990 gui_->invalidate_all();
993 void menu_handler::toggle_grid()
996 gui_->invalidate_all();
999 void menu_handler::unit_hold_position(
mouse_handler& mousehandler,
int side_num)
1002 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1003 un->toggle_hold_position();
1008 if(un->hold_position()) {
1017 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1018 un->toggle_user_end_turn();
1023 if(un->user_end_turn()) {
1035 void menu_handler::search()
1037 std::ostringstream
msg;
1039 if(last_search_hit_.valid()) {
1040 msg <<
" [" << last_search_ <<
"]";
1046 void menu_handler::do_speak()
1050 chat_handler::do_speak(
1051 textbox_info_.box()->text(), textbox_info_.check() !=
nullptr ? textbox_info_.check()->checked() :
false);
1054 void menu_handler::add_chat_message(
const std::time_t& time,
1055 const std::string& speaker,
1057 const std::string& message,
1060 gui_->get_chat_manager().add_chat_message(time, speaker, side, message,
type,
false);
1087 using chmap::get_commands_list;
1088 using chmap::command_failed;
1094 chat_command_handler::command_handler
h,
1095 const std::string&
help =
"",
1096 const std::string& usage =
"",
1097 const std::string& flags =
"")
1099 chmap::register_command(cmd,
h,
help, usage, flags +
"N");
1104 chmap::register_alias(to_cmd, cmd);
1109 return chmap::get_arg(
i);
1114 return chmap::get_cmd();
1119 return chmap::get_data(
n);
1123 using chmap::register_command;
1124 using chmap::register_alias;
1126 using chmap::is_enabled;
1127 using chmap::command_failed_need_arg;
1135 void do_controller();
1137 void do_foreground();
1140 void do_benchmark();
1142 void do_save_quit();
1144 void do_ignore_replay_errors();
1146 void do_next_level();
1147 void do_choose_level();
1149 void do_turn_limit();
1153 void do_unsafe_lua();
1155 void do_set_alias();
1159 void do_control_dialog();
1164 void do_undiscover();
1170 void do_toggle_draw_coordinates();
1171 void do_toggle_draw_terrain_codes();
1172 void do_toggle_draw_num_of_bitmaps();
1173 void do_toggle_whiteboard();
1174 void do_whiteboard_options();
1178 return _(
"(D) — debug only, (N) — network only, (A) — admin only");
1181 using chat_command_handler::get_command_flags_description;
1184 std::string space(
" ");
1185 return (
c.has_flag(
'D') ? space +
_(
"(debug command)") :
"")
1186 + (
c.has_flag(
'N') ? space +
_(
"(network only)") :
"")
1187 + (
c.has_flag(
'A') ? space +
_(
"(admin only)") :
"")
1188 + (
c.has_flag(
'S') ? space +
_(
"(not during other events)") :
"");
1191 using map::is_enabled;
1195 || (
c.has_flag(
'N') && !menu_handler_.pc_.is_networked_mp())
1200 void print(
const std::string& title,
const std::string& message)
1202 menu_handler_.add_chat_message(std::time(
nullptr), title, 0, message);
1207 chat_command_handler::init_map();
1209 chmap::get_command(
"log")->flags =
"";
1210 chmap::get_command(
"version")->flags =
"";
1211 chmap::get_command(
"ignore")->flags =
"";
1212 chmap::get_command(
"friend")->flags =
"";
1213 chmap::get_command(
"remove")->flags =
"";
1215 chmap::set_cmd_prefix(
":");
1216 chmap::set_cmd_flag(
true);
1218 register_command(
"refresh", &console_handler::do_refresh,
_(
"Refresh gui."));
1219 register_command(
"droid", &console_handler::do_droid,
_(
"Switch a side to/from AI control."),
1223 _(
"[<side> [on/off/full]]\n“on” = enable but retain vision, “full” = as if it’s controlled by another player"));
1224 register_command(
"terrain", &console_handler::do_terrain,
_(
"Change terrain type of current hex"),
1226 _(
"<terrain type> [both|base|overlay]"),
"DS");
1227 register_command(
"idle", &console_handler::do_idle,
_(
"Switch a side to/from idle state."),
1231 _(
"command_idle^[<side> [on/off]]"));
1232 register_command(
"theme", &console_handler::do_theme,
_(
"Change the in-game theme."));
1233 register_command(
"control", &console_handler::do_control,
1234 _(
"Assign control of a side to a different player or observer."),
_(
"<side> <nickname>"),
"N");
1235 register_command(
"controller", &console_handler::do_controller,
_(
"Query the controller status of a side."),
1237 register_command(
"clear", &console_handler::do_clear,
_(
"Clear chat history."));
1238 register_command(
"foreground", &console_handler::do_foreground,
_(
"Debug foreground terrain."),
"",
"D");
1240 "layers", &console_handler::do_layers,
_(
"Debug layers from terrain under the mouse."),
"",
"D");
1241 register_command(
"fps", &console_handler::do_fps,
_(
"Display and log fps (Frames Per Second)."));
1242 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."));
1243 register_command(
"save", &console_handler::do_save,
_(
"Save game."));
1244 register_alias(
"save",
"w");
1245 register_command(
"quit", &console_handler::do_quit,
_(
"Quit game."));
1247 register_alias(
"quit",
"q!");
1248 register_command(
"save_quit", &console_handler::do_save_quit,
_(
"Save and quit."));
1249 register_alias(
"save_quit",
"wq");
1250 register_command(
"ignore_replay_errors", &console_handler::do_ignore_replay_errors,
_(
"Ignore replay errors."));
1251 register_command(
"nosaves", &console_handler::do_nosaves,
_(
"Disable autosaves."));
1252 register_command(
"next_level", &console_handler::do_next_level,
1253 _(
"Advance to the next scenario, or scenario identified by ‘id’"),
_(
"<id>"),
"DS");
1254 register_alias(
"next_level",
"n");
1255 register_command(
"choose_level", &console_handler::do_choose_level,
_(
"Choose next scenario"),
"",
"DS");
1256 register_alias(
"choose_level",
"cl");
1257 register_command(
"turn", &console_handler::do_turn,
1258 _(
"Change turn number (and time of day), or increase by one if no number is specified."),
_(
"[turn]"),
1260 register_command(
"turn_limit", &console_handler::do_turn_limit,
1261 _(
"Change turn limit, or turn the turn limit off if no number is specified or it’s −1."),
_(
"[limit]"),
1263 register_command(
"debug", &console_handler::do_debug,
_(
"Turn debug mode on."));
1264 register_command(
"nodebug", &console_handler::do_nodebug,
_(
"Turn debug mode off."),
"",
"D");
1266 "lua", &console_handler::do_lua,
_(
"Execute a Lua statement."),
_(
"<command>[;<command>...]"),
"DS");
1268 "unsafe_lua", &console_handler::do_unsafe_lua,
_(
"Grant higher privileges to Lua scripts."),
"",
"D");
1269 register_command(
"custom", &console_handler::do_custom,
_(
"Set the command used by the custom command hotkey"),
1270 _(
"<command>[;<command>...]"));
1271 register_command(
"give_control", &console_handler::do_control_dialog,
1272 _(
"Invoke a dialog allowing changing control of MP sides."),
"",
"N");
1273 register_command(
"inspect", &console_handler::do_inspect,
_(
"Launch the gamestate inspector"),
"",
"D");
1275 "alias", &console_handler::do_set_alias,
_(
"Set or show alias to a command"),
_(
"<name>[=<command>]"));
1277 "set_var", &console_handler::do_set_var,
_(
"Set a scenario variable."),
_(
"<var>=<value>"),
"DS");
1278 register_command(
"show_var", &console_handler::do_show_var,
_(
"Show a scenario variable."),
_(
"<var>"),
"D");
1279 register_command(
"unit", &console_handler::do_unit,
1281 _(
"Modify a unit variable. (Only top level keys are supported, and advances=<number>.)"),
1282 _(
"<var>=<value>"),
"DS");
1288 register_command(
"discover", &console_handler::do_discover,
_(
"Discover all units in help."),
"");
1289 register_command(
"undiscover", &console_handler::do_undiscover,
_(
"‘Undiscover’ all units in help."),
"");
1290 register_command(
"create", &console_handler::do_create,
_(
"Create a unit."),
_(
"<unit type id>"),
"DS");
1291 register_command(
"fog", &console_handler::do_fog,
_(
"Toggle fog for the current player."),
"",
"DS");
1292 register_command(
"shroud", &console_handler::do_shroud,
_(
"Toggle shroud for the current player."),
"",
"DS");
1293 register_command(
"gold", &console_handler::do_gold,
_(
"Give gold to the current player."),
_(
"<amount>"),
"DS");
1294 register_command(
"throw", &console_handler::do_event,
_(
"Fire a game event."),
_(
"<event name>"),
"DS");
1295 register_alias(
"throw",
"fire");
1296 register_command(
"show_coordinates", &console_handler::do_toggle_draw_coordinates,
1297 _(
"Toggle overlaying of x,y coordinates on hexes."));
1298 register_alias(
"show_coordinates",
"sc");
1299 register_command(
"show_terrain_codes", &console_handler::do_toggle_draw_terrain_codes,
1300 _(
"Toggle overlaying of terrain codes on hexes."));
1301 register_alias(
"show_terrain_codes",
"tc");
1302 register_command(
"show_num_of_bitmaps", &console_handler::do_toggle_draw_num_of_bitmaps,
1303 _(
"Toggle overlaying of number of bitmaps on hexes."));
1304 register_alias(
"show_num_of_bitmaps",
"bn");
1305 register_command(
"whiteboard", &console_handler::do_toggle_whiteboard,
_(
"Toggle planning mode."));
1306 register_alias(
"whiteboard",
"wb");
1308 "whiteboard_options", &console_handler::do_whiteboard_options,
_(
"Access whiteboard options dialog."));
1309 register_alias(
"whiteboard_options",
"wbo");
1311 if(
auto alias_list =
prefs::get().get_alias()) {
1312 for(
const auto& [key, value] : alias_list->attribute_range()) {
1313 register_alias(value, key);
1323 void menu_handler::send_chat_message(
const std::string& message,
bool allies_only)
1327 cfg[
"message"] = message;
1328 const std::time_t time = ::std::time(
nullptr);
1329 std::stringstream ss;
1331 cfg[
"time"] = ss.str();
1333 const int side = board().
is_observer() ? 0 : gui_->viewing_team().side();
1334 if(!board().is_observer()) {
1341 if(board().is_observer()) {
1344 cfg[
"to_sides"] = gui_->viewing_team().allied_human_teams();
1350 add_chat_message(time, cfg[
"id"], side, message,
1354 void menu_handler::do_search(
const std::string& new_search)
1356 if(new_search.empty() ==
false && new_search != last_search_)
1357 last_search_ = new_search;
1359 if(last_search_.empty())
1365 std::vector<std::string> args =
utils::split(last_search_,
',');
1366 if(args.size() == 2) {
1368 x = lexical_cast_default<int>(args[0], 0) - 1;
1369 y = lexical_cast_default<int>(args[1], 0) - 1;
1370 if(x >= 0 && x < pc_.get_map().w() && y >= 0 && y < pc_.get_map().h()) {
1376 if(loc.
valid() ==
false) {
1377 loc =
map_location(pc_.get_map().w() - 1, pc_.get_map().h() - 1);
1383 loc.
x = (loc.
x + 1) % pc_.get_map().w();
1385 loc.
y = (loc.
y + 1) % pc_.get_map().h();
1388 if(!gui_->shrouded(loc)) {
1391 const std::string& label_text =
label->text().str();
1397 if(!gui_->fogged(loc)) {
1399 if(ui != pc_.get_units().end()) {
1400 const std::string&
unit_name = ui->name();
1402 if(!gui_->viewing_team().is_enemy(ui->side())
1403 || !ui->invisible(ui->get_location())) {
1415 last_search_hit_ = loc;
1417 gui_->highlight_hex(loc);
1422 symbols[
"search"] = last_search_;
1423 const std::string
msg =
VGETTEXT(
"Could not find label or unit "
1424 "containing the string ‘$search’.",
1430 void menu_handler::do_command(
const std::string& str)
1436 std::vector<std::string> menu_handler::get_commands_list()
1447 void console_handler::do_refresh()
1452 menu_handler_.gui_->create_buttons();
1453 menu_handler_.gui_->queue_rerender();
1456 void console_handler::do_droid()
1459 const std::string side_s = get_arg(1);
1460 std::string action = get_arg(2);
1461 std::transform(action.begin(), action.end(), action.begin(), tolower);
1463 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1464 const bool is_your_turn = menu_handler_.pc_.current_side() ==
static_cast<int>(menu_handler_.gui_->viewing_team().side());
1467 symbols[
"side"] = std::to_string(side);
1469 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1470 command_failed(
VGETTEXT(
"Can’t droid invalid side: ‘$side’.", symbols));
1472 }
else if(menu_handler_.board().get_team(side).is_network()) {
1473 command_failed(
VGETTEXT(
"Can’t droid networked side: ‘$side’.", symbols));
1475 }
else if(menu_handler_.board().get_team(side).is_local()) {
1476 bool changed =
false;
1478 const bool is_human = menu_handler_.board().get_team(side).is_human();
1479 const bool is_droid = menu_handler_.board().get_team(side).is_droid();
1480 const bool is_proxy_human = menu_handler_.board().get_team(side).is_proxy_human();
1481 const bool is_ai = menu_handler_.board().get_team(side).is_ai();
1483 if(action ==
"on") {
1484 if(is_ai && !is_your_turn) {
1485 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1488 if(!is_human || !is_droid) {
1489 menu_handler_.board().get_team(side).make_human();
1490 menu_handler_.board().get_team(side).make_droid();
1493 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1495 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: AI.", symbols));
1497 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already droided.", symbols));
1499 }
else if(action ==
"off") {
1500 if(is_ai && !is_your_turn) {
1501 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1504 if(!is_human || !is_proxy_human) {
1505 menu_handler_.board().get_team(side).make_human();
1506 menu_handler_.board().get_team(side).make_proxy_human();
1509 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1511 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: human.", symbols));
1513 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already not droided.", symbols));
1515 }
else if(action ==
"full") {
1517 command_failed(
_(
"It is not allowed to change a side from human to AI control when it’s not your turn."));
1520 if(!is_ai || !is_droid) {
1521 menu_handler_.board().get_team(side).make_ai();
1522 menu_handler_.board().get_team(side).make_droid();
1524 if(is_human || is_proxy_human) {
1525 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::ai}});
1527 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now fully controlled by: AI.", symbols));
1529 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already fully AI controlled.", symbols));
1531 }
else if(action ==
"") {
1532 if(is_ai && !is_your_turn) {
1533 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1536 if(is_ai || is_droid) {
1537 menu_handler_.board().get_team(side).make_human();
1538 menu_handler_.board().get_team(side).make_proxy_human();
1541 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1543 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: human.", symbols));
1545 menu_handler_.board().get_team(side).make_human();
1546 menu_handler_.board().get_team(side).make_droid();
1549 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1551 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: AI.", symbols));
1554 print(get_cmd(),
VGETTEXT(
"Invalid action provided for side ‘$side’. Valid actions are: on, off, full.", symbols));
1557 if(team_num_ == side && changed) {
1559 psc->set_player_type_changed();
1563 command_failed(
VGETTEXT(
"Side ‘$side’ is not a human or AI player.", symbols));
1566 menu_handler_.textbox_info_.close();
1569 void console_handler::do_terrain()
1573 const std::string mode_str = get_arg(2);
1583 "mode_str", mode_str,
1588 void console_handler::do_idle()
1591 const std::string side_s = get_arg(1);
1592 const std::string action = get_arg(2);
1594 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1596 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1598 symbols[
"side"] = side_s;
1599 command_failed(
VGETTEXT(
"Can’t idle invalid side: ‘$side’.", symbols));
1601 }
else if(menu_handler_.board().get_team(side).is_network()) {
1603 symbols[
"side"] = std::to_string(side);
1604 command_failed(
VGETTEXT(
"Can’t idle networked side: ‘$side’.", symbols));
1606 }
else if(menu_handler_.board().get_team(side).is_local_ai()) {
1608 symbols[
"side"] = std::to_string(side);
1609 command_failed(
VGETTEXT(
"Can’t idle local ai side: ‘$side’.", symbols));
1611 }
else if(menu_handler_.board().get_team(side).is_local_human()) {
1612 if(menu_handler_.board().get_team(side).is_idle() ? action ==
" on" : action ==
" off") {
1616 menu_handler_.board().get_team(side).toggle_idle();
1617 if(team_num_ == side) {
1619 psc->set_player_type_changed();
1623 menu_handler_.textbox_info_.close();
1626 void console_handler::do_theme()
1640 return t.save_id() == save_id_;
1646 void console_handler::do_control()
1649 if(!menu_handler_.pc_.is_networked_mp()) {
1653 const std::string side = get_arg(1);
1654 const std::string player = get_arg(2);
1655 if(player.empty()) {
1656 command_failed_need_arg(2);
1660 unsigned int side_num;
1662 side_num = lexical_cast<unsigned int>(side);
1664 const auto& teams = menu_handler_.pc_.get_teams();
1665 const auto it_t = std::find_if(teams.begin(), teams.end(),
save_id_matches(side));
1667 if(it_t == teams.end()) {
1669 symbols[
"side"] = side;
1670 command_failed(
VGETTEXT(
"Can’t change control of invalid side: ‘$side’.", symbols));
1673 side_num = it_t->side();
1677 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1679 symbols[
"side"] = side;
1680 command_failed(
VGETTEXT(
"Can’t change control of out-of-bounds side: ‘$side’.", symbols));
1684 menu_handler_.request_control_change(side_num, player);
1685 menu_handler_.textbox_info_.close();
1688 void console_handler::do_controller()
1690 const std::string side = get_arg(1);
1691 unsigned int side_num;
1693 side_num = lexical_cast<unsigned int>(side);
1696 symbols[
"side"] = side;
1697 command_failed(
VGETTEXT(
"Can’t query control of invalid side: ‘$side’.", symbols));
1701 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1703 symbols[
"side"] = side;
1704 command_failed(
VGETTEXT(
"Can’t query control of out-of-bounds side: ‘$side’.", symbols));
1709 if(!menu_handler_.board().get_team(side_num).is_proxy_human()) {
1713 if(menu_handler_.board().get_team(side_num).is_network()) {
1714 report +=
" (networked)";
1717 print(get_cmd(), report);
1720 void console_handler::do_clear()
1722 menu_handler_.gui_->get_chat_manager().clear_chat_messages();
1725 void console_handler::do_foreground()
1728 menu_handler_.gui_->invalidate_all();
1731 void console_handler::do_layers()
1733 display& disp = *(menu_handler_.gui_);
1747 if(menu_handler_.pc_.get_map().on_board_with_border(loc)) {
1748 gui2::dialogs::terrain_layers::display(disp, loc);
1752 void console_handler::do_fps()
1757 void console_handler::do_benchmark()
1762 void console_handler::do_save()
1764 menu_handler_.pc_.do_consolesave(get_data());
1767 void console_handler::do_save_quit()
1773 void console_handler::do_quit()
1778 void console_handler::do_ignore_replay_errors()
1783 void console_handler::do_nosaves()
1788 void console_handler::do_next_level()
1793 void console_handler::do_choose_level()
1795 std::string
tag = menu_handler_.pc_.get_classification().get_tagname();
1796 std::vector<std::string> options;
1798 if(
tag !=
"multiplayer") {
1800 const std::string&
id = sc[
"id"];
1801 options.push_back(
id);
1802 if(
id == menu_handler_.gamedata().next_scenario()) {
1809 std::string scenario_id = menu_handler_.pc_.get_mp_settings().mp_scenario;
1810 if(
auto this_scenario = menu_handler_.game_config_.find_child(
tag,
"id", scenario_id)) {
1811 std::string addon_id = this_scenario[
"addon_id"].str();
1813 if(sc[
"addon_id"] == addon_id) {
1814 std::string
id = sc[
"id"];
1815 options.push_back(
id);
1816 if(
id == menu_handler_.gamedata().next_scenario()) {
1823 std::sort(options.begin(), options.end());
1824 int choice = std::distance(options.begin(), std::lower_bound(options.begin(), options.end(), next));
1836 if(std::size_t(choice) < options.size()) {
1841 void console_handler::do_turn()
1843 tod_manager& tod_man = menu_handler_.gamestate().tod_manager_;
1845 int turn = tod_man.
turn() + 1;
1846 const std::string&
data = get_data();
1848 turn = lexical_cast_default<int>(
data, 1);
1853 void console_handler::do_turn_limit()
1855 int limit = get_data().empty() ? -1 : lexical_cast_default<int>(get_data(), 1);
1859 void console_handler::do_debug()
1862 print(get_cmd(),
_(
"Debug mode activated!"));
1865 command_failed(
_(
"Debug mode not available in network games"));
1869 void console_handler::do_nodebug()
1872 print(get_cmd(),
_(
"Debug mode deactivated!"));
1877 void console_handler::do_lua()
1879 if(!menu_handler_.gamestate().lua_kernel_) {
1886 void console_handler::do_unsafe_lua()
1888 if(!menu_handler_.gamestate().lua_kernel_) {
1893 _(
"Executing Lua code in in this manner opens your computer to potential security breaches from any "
1894 "malicious add-ons or other programs you may have installed.\n\n"
1898 print(get_cmd(),
_(
"Unsafe mode enabled!"));
1899 menu_handler_.gamestate().lua_kernel_->load_package();
1903 void console_handler::do_custom()
1908 void console_handler::do_set_alias()
1910 const std::string
data = get_data();
1911 const std::string::const_iterator j = std::find(
data.begin(),
data.end(),
'=');
1912 const std::string alias(
data.begin(), j);
1913 if(j !=
data.end()) {
1914 const std::string command(j + 1,
data.end());
1915 if(!command.empty()) {
1916 register_alias(command, alias);
1920 register_alias(alias, alias);
1928 const std::string command = chmap::get_actual_cmd(alias);
1929 print(get_cmd(),
"'" + alias +
"'" +
" = " +
"'" + command +
"'");
1933 void console_handler::do_set_var()
1935 const std::string
data = get_data();
1937 command_failed_need_arg(1);
1941 const std::string::const_iterator j = std::find(
data.begin(),
data.end(),
'=');
1942 if(j !=
data.end()) {
1943 const std::string name(
data.begin(), j);
1944 const std::string value(j + 1,
data.end());
1947 command_failed(
_(
"Variable not found"));
1951 void console_handler::do_show_var()
1956 void console_handler::do_inspect()
1959 gui2::dialogs::gamestate_inspector::display(
1963 void console_handler::do_control_dialog()
1965 gui2::dialogs::mp_change_control::display(menu_handler_);
1968 void console_handler::do_unit()
1976 if(
i == menu_handler_.pc_.get_units().end()) {
1978 symbols[
"unit"] = get_arg(1);
1980 "Debug command ‘unit: $unit’ failed: no unit selected or hovered over.",
1986 const std::string
data = get_data(1);
1988 if(parameters.size() < 2) {
1992 if(parameters[0] ==
"alignment") {
1996 symbols[
"alignment"] = get_arg(1);
1998 "Invalid alignment: ‘$alignment’, needs to be one of lawful, neutral, chaotic, or liminal.",
2008 "name", parameters[0],
2009 "value", parameters[1],
2014 void console_handler::do_discover()
2016 for(
const unit_type_data::unit_type_map::value_type&
i :
unit_types.
types()) {
2021 void console_handler::do_undiscover()
2031 void console_handler::do_create()
2035 if(menu_handler_.pc_.get_map().on_board(loc)) {
2038 command_failed(
_(
"Invalid unit type"));
2043 create_and_place(*menu_handler_.gui_, menu_handler_.pc_.get_map(), menu_handler_.pc_.get_units(), loc, *ut);
2045 command_failed(
_(
"Invalid location"));
2049 void console_handler::do_fog()
2054 void console_handler::do_shroud()
2059 void console_handler::do_gold()
2064 void console_handler::do_event()
2069 void console_handler::do_toggle_draw_coordinates()
2072 menu_handler_.gui_->invalidate_all();
2074 void console_handler::do_toggle_draw_terrain_codes()
2077 menu_handler_.gui_->invalidate_all();
2080 void console_handler::do_toggle_draw_num_of_bitmaps()
2083 menu_handler_.gui_->invalidate_all();
2086 void console_handler::do_toggle_whiteboard()
2088 if(
const std::shared_ptr<wb::manager>& whiteb = menu_handler_.pc_.get_whiteboard()) {
2089 whiteb->set_active(!whiteb->is_active());
2090 if(whiteb->is_active()) {
2091 print(get_cmd(),
_(
"Planning mode activated!"));
2092 whiteb->print_help_once();
2094 print(get_cmd(),
_(
"Planning mode deactivated!"));
2099 void console_handler::do_whiteboard_options()
2101 if(menu_handler_.pc_.get_whiteboard()) {
2102 menu_handler_.pc_.get_whiteboard()->options_dlg();
2106 void menu_handler::do_ai_formula(
const std::string& str,
int side_num,
mouse_handler& )
2116 void menu_handler::user_command()
2121 void menu_handler::request_control_change(
int side_num,
const std::string& player)
2123 std::string side = std::to_string(side_num);
2124 if(board().get_team(side_num).is_local_human() && player ==
prefs::get().login()) {
2130 pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player", player}});
2134 void menu_handler::custom_command()
2137 do_command(command);
2141 void menu_handler::ai_formula()
2143 if(!pc_.is_networked_mp()) {
2148 void menu_handler::clear_messages()
2150 gui_->get_chat_manager().clear_chat_messages();
2155 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.
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)
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.