84 #define ERR_NG LOG_STREAM(err, log_engine)
85 #define LOG_NG LOG_STREAM(info, log_engine)
92 std::string last_created_unit =
"";
93 std::string last_recruit =
"";
94 std::string last_variation =
"";
161 const auto& unit_dlg = units_dialog::build_unit_list_dialog(
unit_list);
163 if (unit_dlg->show() && unit_dlg->is_selected()) {
199 symbols[
"msg"] =
e.what();
200 const std::string
msg =
VGETTEXT(
"Could not save the map: $msg", symbols);
208 gui2::dialogs::preferences_dialog::display();
216 c[
"name"] =
"prototype of chat log";
228 ?
board().is_observer()
229 ?
_(
"Send to observers only")
230 :
_(
"Send to allies only")
248 if(
board().is_observer()) {
267 std::map<const unit_type*, t_string> err_msgs_map;
268 std::vector<const unit_type*> recruit_list;
270 std::vector<t_string> unknown_units;
275 for(
const auto&
recruit : recruits) {
279 unknown_units.emplace_back(
recruit);
286 if (!err_msg.
empty()) {
287 err_msgs_map[
type] = err_msg;
289 recruit_list.push_back(
type);
290 if (
type->id() == last_recruit) {
296 if(!unknown_units.empty()) {
301 const auto message =
VNGETTEXT(
"Error: there’s an unknown unit type on your recruit list: $unknown_ids",
302 "Error: there are several unknown unit types on your recruit list: $unknown_ids",
303 unknown_units.size(),
308 if(recruit_list.empty()) {
313 const auto& dlg = units_dialog::build_recruit_dialog(recruit_list, err_msgs_map, current_team);
316 const auto&
type = recruit_list[dlg->get_selected_index()];
317 last_recruit =
type->id();
321 do_recruit(
type->id(), side_num, recruit_hex);
325 void menu_handler::repeat_recruit(
int side_num,
const map_location& last_hex)
327 const std::string& last_recruit = board().get_team(side_num).last_recruit();
328 if(!last_recruit.empty()) {
330 do_recruit(last_recruit, side_num, recruit_hex);
334 bool menu_handler::do_recruit(
const std::string& name,
int side_num,
map_location&
loc)
337 team& current_team = board().get_team(side_num);
340 if(res.empty() && (!pc_.get_whiteboard() || !pc_.get_whiteboard()->save_recruit(name, side_num,
loc))) {
347 }
else if(res.empty()) {
358 if(pc_.get_disallow_recall()) {
363 team& current_team = board().get_team(side_num);
365 std::vector<unit_const_ptr> recall_list_team;
371 DBG_WB <<
"menu_handler::recall: Contents of wb-modified recall list:";
378 _(
"There are no troops available to recall.\n(You must have veteran survivors from a previous scenario.)"));
382 if(recall_list_team.empty()) {
387 const auto& dlg = units_dialog::build_recall_dialog(recall_list_team, current_team);
389 if(!dlg->show() || !dlg->is_selected()) {
393 int res = dlg->get_selected_index();
402 if(sel_unit->recall_cost() > -1) {
403 unit_cost = sel_unit->recall_cost();
406 int wb_gold = pc_.get_whiteboard() ? pc_.get_whiteboard()->get_spent_gold_for(side_num) : 0;
408 if(current_team.
gold() - wb_gold < unit_cost) {
410 i18n_symbols[
"cost"] = std::to_string(unit_cost);
411 std::string
msg =
VNGETTEXT(
"You must have at least 1 gold piece to recall a unit.",
412 "You must have at least $cost gold pieces to recall this unit.", unit_cost, i18n_symbols);
417 LOG_NG <<
"recall index: " << res;
434 if(!pc_.get_whiteboard()
435 || !pc_.get_whiteboard()->save_recall(*sel_unit, side_num, recall_location)) {
440 ERR_NG <<
"menu_handler::recall(): Unit does not exist in the recall list.";
446 void menu_handler::show_enemy_moves(
bool ignore_units,
int side_num)
453 gui_->unhighlight_reach();
456 for(
auto& u : pc_.get_units()) {
457 bool invisible = u.invisible(u.get_location());
459 if(board().get_team(side_num).is_enemy(u.side()) && !gui_->fogged(u.get_location()) && !u.incapacitated()
463 =
pathfind::paths(u,
false,
true, gui_->viewing_team(), 0,
false, ignore_units);
465 gui_->highlight_another_reach(
path, hex_under_mouse);
469 gui_->invalidate(u.get_location());
474 const bool selected_hex_has_unit = mh.
hex_hosts_unit(hex_under_mouse);
476 if(selected_hex_has_unit) {
485 void menu_handler::toggle_shroud_updates(
int side_num)
487 team& current_team = board().get_team(side_num);
491 update_shroud_now(side_num);
498 void menu_handler::update_shroud_now(
int )
507 bool units_alive(
int side_num,
const unit_map& units)
509 for(
auto&
unit : units) {
518 bool partmoved_units(
519 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
521 for(
auto&
unit : units) {
536 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
538 for(
auto&
unit : units) {
541 && (!whiteb || !whiteb->unit_has_actions(&
unit))) {
551 bool menu_handler::end_turn(
int side_num)
556 reason =
_(
"You cannot end your turn yet!");
562 std::size_t team_num =
static_cast<std::size_t
>(side_num - 1);
563 if(team_num < pc_.get_teams().size() && pc_.get_teams()[team_num].no_turn_confirmation()) {
568 && (!pc_.get_whiteboard() || !pc_.get_whiteboard()->current_side_has_actions())
569 && units_alive(side_num, pc_.get_units())) {
571 _(
"You have not started your turn yet. Do you really want to end your turn?"),
572 message::yes_no_buttons);
578 else if(
prefs::get().yellow_confirm() && partmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
580 _(
"Some units have movement left. Do you really want to end your turn?"),
581 message::yes_no_buttons);
587 else if(
prefs::get().green_confirm() && unmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
589 _(
"Some units have not moved. Do you really want to end your turn?"),
590 message::yes_no_buttons);
598 if(pc_.get_whiteboard() && !pc_.get_whiteboard()->allow_end_turn()) {
605 void menu_handler::goto_leader(
int side_num)
608 if(
i != pc_.get_units().end() &&
i->is_visible_to_team(gui_->viewing_team(),
false)) {
613 void menu_handler::unit_description()
616 if(un != pc_.get_units().end()) {
624 if(pc_.get_map().on_board(
loc) ==
false || gui_->shrouded(
loc)) {
633 void menu_handler::rename_unit()
636 if(un == pc_.get_units().end() || gui_->viewing_team().side() != un->side()) {
640 if(un->unrenamable()) {
644 std::string name = un->name();
645 const std::string title(
_(
"Rename Unit"));
646 const std::string
label(
_(
"Name:"));
648 if(edit_text::execute(title,
label, name)) {
651 gui_->invalidate_unit();
657 const mouse_handler& mousehandler = pc_.get_mouse_handler_base();
658 const bool see_all = gui_->show_everything() || (pc_.is_replay() && pc_.get_replay_controller()->see_all());
661 if(res != pc_.get_units().end()) {
672 typedef std::tuple<const unit_type*, unit_race::GENDER, std::string> type_gender_variation;
681 type_gender_variation choose_unit()
685 const auto& create_dlg = units_dialog::build_create_dialog(types_list);
687 for (
size_t i = 0;
i < types_list.size();
i++) {
688 if (types_list[
i]->
id() == last_created_unit) {
689 create_dlg->set_selected_index(
i);
690 create_dlg->set_gender(last_gender);
691 create_dlg->set_variation(last_variation);
698 const unit_type* ut = types_list[create_dlg->get_selected_index()];
699 last_created_unit = ut->
id();
700 last_gender = create_dlg->gender();
701 last_variation = create_dlg->variation();
704 if (create_dlg->is_selected()) {
705 info = type_gender_variation(ut, last_gender, last_variation);
707 ERR_NG <<
"Create unit dialog returned nonexistent or unusable unit_type id.";
718 void create_and_place(
725 const std::string& variation =
"")
733 "variation", variation,
748 assert(gui_ !=
nullptr);
751 if(
const auto& [
type, gender, variation] = choose_unit();
type !=
nullptr) {
753 create_and_place(*gui_, pc_.get_map(), pc_.get_units(), destination, *
type, gender, variation);
761 if(
i == pc_.get_units().end()) {
762 if(!pc_.get_map().is_village(
loc)) {
770 if(
team >
static_cast<int>(pc_.get_teams().size())) {
775 int side =
i->side();
777 if(side >
static_cast<int>(pc_.get_teams().size())) {
782 if(pc_.get_map().is_village(
loc)) {
794 void menu_handler::label_terrain(
mouse_handler& mousehandler,
bool team_only)
797 if(pc_.get_map().on_board(
loc) ==
false) {
802 std::string
label = old_label ? old_label->
text() :
"";
804 if(edit_label::execute(
label, team_only)) {
805 std::string team_name;
809 team_name = gui_->labels().team_name();
813 const terrain_label* res = gui_->labels().set_label(
loc,
label, gui_->viewing_team_index(), team_name, color);
820 void menu_handler::clear_labels()
822 if(!board().is_observer()) {
825 _(
"Are you sure you want to clear map labels?"),
826 message::yes_no_buttons
830 std::string viewing_team = gui_->viewing_team().team_name();
831 gui_->labels().clear(viewing_team,
false);
837 void menu_handler::label_settings()
839 if(label_settings::execute(board())) {
840 gui_->labels().recalculate_labels();
847 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
849 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
853 move_unit_to_loc(
i,
i->get_interrupted_move(),
true, side_num, mousehandler);
856 void menu_handler::move_unit_to_loc(
863 assert(ui != pc_.get_units().end());
867 if(route.
steps.empty()) {
871 assert(route.
steps.front() == ui->get_location());
873 gui_->set_route(&route);
874 gui_->unhighlight_reach();
877 LOG_NG <<
"move_unit_to_loc " << route.
steps.front() <<
" to " << route.
steps.back();
882 gui_->set_route(
nullptr);
883 gui_->invalidate_game_status();
892 bool wait_blocker_move =
true;
893 std::set<map_location> fully_moved;
896 bool blocked_unit =
false;
899 blocked_unit =
false;
900 for(
auto&
unit : pc_.get_units()) {
908 if(goto_loc == current_loc) {
913 if(!pc_.get_map().on_board(goto_loc)) {
918 if(fully_moved.count(current_loc)) {
924 if(route.
steps.size() <= 1) {
925 fully_moved.insert(current_loc);
931 pathfind::marked_route::mark_map::const_iterator
w = route.
marks.begin();
932 for(;
w != route.
marks.end(); ++
w) {
933 if(
w->second.turns == 1) {
934 next_stop =
w->first;
939 if(next_stop == current_loc) {
940 fully_moved.insert(current_loc);
946 if(pc_.get_units().count(next_stop)) {
948 if(wait_blocker_move)
952 gui_->set_route(&route);
955 LOG_NG <<
"execute goto from " << route.
steps.front() <<
" to " << route.
steps.back();
962 wait_blocker_move =
true;
966 if(!change && wait_blocker_move) {
968 wait_blocker_move =
false;
971 }
while(change && blocked_unit);
974 gui_->set_route(
nullptr);
975 gui_->invalidate_game_status();
978 void menu_handler::toggle_ellipses()
981 gui_->invalidate_all();
984 void menu_handler::toggle_grid()
987 gui_->invalidate_all();
990 void menu_handler::unit_hold_position(
mouse_handler& mousehandler,
int side_num)
993 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
994 un->toggle_hold_position();
999 if(un->hold_position()) {
1008 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1009 un->toggle_user_end_turn();
1014 if(un->user_end_turn()) {
1026 void menu_handler::search()
1028 std::ostringstream
msg;
1030 if(last_search_hit_.valid()) {
1031 msg <<
" [" << last_search_ <<
"]";
1037 bool menu_handler::do_speak()
1041 return chat_handler::do_speak(
1042 textbox_info_.box()->text(), textbox_info_.check() !=
nullptr ? textbox_info_.check()->checked() :
false);
1045 void menu_handler::add_chat_message(
const std::chrono::system_clock::time_point& time,
1046 const std::string& speaker,
1051 gui_->get_chat_manager().add_chat_message(time, speaker, side,
message,
type,
false);
1078 using chmap::get_commands_list;
1079 using chmap::command_failed;
1085 chat_command_handler::command_handler
h,
1086 const std::string&
help =
"",
1087 const std::string& usage =
"",
1088 const std::string& flags =
"")
1090 chmap::register_command(cmd,
h,
help, usage, flags +
"N");
1095 chmap::register_alias(to_cmd, cmd);
1100 return chmap::get_arg(
i);
1105 return chmap::get_cmd();
1110 return chmap::get_data(
n);
1114 using chmap::register_command;
1115 using chmap::register_alias;
1117 using chmap::is_enabled;
1118 using chmap::command_failed_need_arg;
1126 void do_controller();
1128 void do_foreground();
1131 void do_benchmark();
1133 void do_save_quit();
1135 void do_ignore_replay_errors();
1137 void do_next_level();
1138 void do_choose_level();
1140 void do_turn_limit();
1144 void do_unsafe_lua();
1146 void do_set_alias();
1150 void do_control_dialog();
1155 void do_undiscover();
1161 void do_toggle_draw_coordinates();
1162 void do_toggle_draw_terrain_codes();
1163 void do_toggle_draw_num_of_bitmaps();
1164 void do_toggle_whiteboard();
1165 void do_whiteboard_options();
1169 return _(
"(D) — debug only, (N) — network only, (A) — admin only");
1172 using chat_command_handler::get_command_flags_description;
1175 std::string space(
" ");
1176 return (
c.has_flag(
'D') ? space +
_(
"(debug command)") :
"")
1177 + (
c.has_flag(
'N') ? space +
_(
"(network only)") :
"")
1178 + (
c.has_flag(
'A') ? space +
_(
"(admin only)") :
"")
1179 + (
c.has_flag(
'S') ? space +
_(
"(not during other events)") :
"");
1182 using map::is_enabled;
1186 || (
c.has_flag(
'N') && !menu_handler_.pc_.is_networked_mp())
1193 menu_handler_.add_chat_message(std::chrono::system_clock::now(), title, 0,
message);
1198 chat_command_handler::init_map();
1200 chmap::get_command(
"log")->flags =
"";
1201 chmap::get_command(
"version")->flags =
"";
1202 chmap::get_command(
"ignore")->flags =
"";
1203 chmap::get_command(
"friend")->flags =
"";
1204 chmap::get_command(
"remove")->flags =
"";
1206 chmap::set_cmd_prefix(
":");
1207 chmap::set_cmd_flag(
true);
1209 register_command(
"refresh", &console_handler::do_refresh,
_(
"Refresh gui."));
1210 register_command(
"droid", &console_handler::do_droid,
_(
"Switch a side to/from AI control."),
1214 _(
"[<side> [on/off/full]]\n“on” = enable but retain vision, “full” = as if it’s controlled by another player"));
1215 register_command(
"terrain", &console_handler::do_terrain,
_(
"Change terrain type of current hex"),
1217 _(
"<terrain type> [both|base|overlay]"),
"DS");
1218 register_command(
"idle", &console_handler::do_idle,
_(
"Switch a side to/from idle state."),
1222 _(
"command_idle^[<side> [on/off]]"));
1223 register_command(
"theme", &console_handler::do_theme,
_(
"Change the in-game theme."));
1224 register_command(
"control", &console_handler::do_control,
1225 _(
"Assign control of a side to a different player or observer."),
_(
"<side> <nickname>"),
"N");
1226 register_command(
"controller", &console_handler::do_controller,
_(
"Query the controller status of a side."),
1228 register_command(
"clear", &console_handler::do_clear,
_(
"Clear chat history."));
1229 register_command(
"foreground", &console_handler::do_foreground,
_(
"Debug foreground terrain."),
"",
"D");
1231 "layers", &console_handler::do_layers,
_(
"Debug layers from terrain under the mouse."),
"",
"D");
1232 register_command(
"fps", &console_handler::do_fps,
_(
"Display and log fps (Frames Per Second)."));
1233 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."));
1234 register_command(
"save", &console_handler::do_save,
_(
"Save game."));
1235 register_alias(
"save",
"w");
1236 register_command(
"quit", &console_handler::do_quit,
_(
"Quit game."));
1238 register_alias(
"quit",
"q!");
1239 register_command(
"save_quit", &console_handler::do_save_quit,
_(
"Save and quit."));
1240 register_alias(
"save_quit",
"wq");
1241 register_command(
"ignore_replay_errors", &console_handler::do_ignore_replay_errors,
_(
"Ignore replay errors."));
1242 register_command(
"nosaves", &console_handler::do_nosaves,
_(
"Disable autosaves."));
1243 register_command(
"next_level", &console_handler::do_next_level,
1244 _(
"Advance to the next scenario, or scenario identified by ‘id’"),
_(
"<id>"),
"DS");
1245 register_alias(
"next_level",
"n");
1246 register_command(
"choose_level", &console_handler::do_choose_level,
_(
"Choose next scenario"),
"",
"DS");
1247 register_alias(
"choose_level",
"cl");
1248 register_command(
"turn", &console_handler::do_turn,
1249 _(
"Change turn number (and time of day), or increase by one if no number is specified."),
_(
"[turn]"),
1251 register_command(
"turn_limit", &console_handler::do_turn_limit,
1252 _(
"Change turn limit, or turn the turn limit off if no number is specified or it’s −1."),
_(
"[limit]"),
1254 register_command(
"debug", &console_handler::do_debug,
_(
"Turn debug mode on."));
1255 register_command(
"nodebug", &console_handler::do_nodebug,
_(
"Turn debug mode off."),
"",
"D");
1257 "lua", &console_handler::do_lua,
_(
"Execute a Lua statement."),
_(
"<command>[;<command>...]"),
"DS");
1259 "unsafe_lua", &console_handler::do_unsafe_lua,
_(
"Grant higher privileges to Lua scripts."),
"",
"D");
1260 register_command(
"custom", &console_handler::do_custom,
_(
"Set the command used by the custom command hotkey"),
1261 _(
"<command>[;<command>...]"));
1262 register_command(
"give_control", &console_handler::do_control_dialog,
1263 _(
"Invoke a dialog allowing changing control of MP sides."),
"",
"N");
1264 register_command(
"inspect", &console_handler::do_inspect,
_(
"Launch the gamestate inspector"),
"",
"D");
1266 "alias", &console_handler::do_set_alias,
_(
"Set or show alias to a command"),
_(
"<name>[=<command>]"));
1268 "set_var", &console_handler::do_set_var,
_(
"Set a scenario variable."),
_(
"<var>=<value>"),
"DS");
1269 register_command(
"show_var", &console_handler::do_show_var,
_(
"Show a scenario variable."),
_(
"<var>"),
"D");
1270 register_command(
"unit", &console_handler::do_unit,
1272 _(
"Modify a unit variable. (Only top level keys are supported, and advances=<number>.)"),
1273 _(
"<var>=<value>"),
"DS");
1279 register_command(
"discover", &console_handler::do_discover,
_(
"Discover all units in help."),
"");
1280 register_command(
"undiscover", &console_handler::do_undiscover,
_(
"‘Undiscover’ all units in help."),
"");
1281 register_command(
"create", &console_handler::do_create,
_(
"Create a unit."),
_(
"<unit type id>"),
"DS");
1282 register_command(
"fog", &console_handler::do_fog,
_(
"Toggle fog for the current player."),
"",
"DS");
1283 register_command(
"shroud", &console_handler::do_shroud,
_(
"Toggle shroud for the current player."),
"",
"DS");
1284 register_command(
"gold", &console_handler::do_gold,
_(
"Give gold to the current player."),
_(
"<amount>"),
"DS");
1285 register_command(
"throw", &console_handler::do_event,
_(
"Fire a game event."),
_(
"<event name>"),
"DS");
1286 register_alias(
"throw",
"fire");
1287 register_command(
"show_coordinates", &console_handler::do_toggle_draw_coordinates,
1288 _(
"Toggle overlaying of x,y coordinates on hexes."));
1289 register_alias(
"show_coordinates",
"sc");
1290 register_command(
"show_terrain_codes", &console_handler::do_toggle_draw_terrain_codes,
1291 _(
"Toggle overlaying of terrain codes on hexes."));
1292 register_alias(
"show_terrain_codes",
"tc");
1293 register_command(
"show_num_of_bitmaps", &console_handler::do_toggle_draw_num_of_bitmaps,
1294 _(
"Toggle overlaying of number of bitmaps on hexes."));
1295 register_alias(
"show_num_of_bitmaps",
"bn");
1296 register_command(
"whiteboard", &console_handler::do_toggle_whiteboard,
_(
"Toggle planning mode."));
1297 register_alias(
"whiteboard",
"wb");
1299 "whiteboard_options", &console_handler::do_whiteboard_options,
_(
"Access whiteboard options dialog."));
1300 register_alias(
"whiteboard_options",
"wbo");
1302 if(
auto alias_list =
prefs::get().get_alias()) {
1303 for(
const auto& [key, value] : alias_list->attribute_range()) {
1304 register_alias(value, key);
1314 void menu_handler::send_chat_message(
const std::string&
message,
bool allies_only)
1319 auto now = std::chrono::system_clock::now();
1322 const int side = board().
is_observer() ? 0 : gui_->viewing_team().side();
1323 if(!board().is_observer()) {
1330 if(board().is_observer()) {
1333 cfg[
"to_sides"] = gui_->viewing_team().allied_human_teams();
1339 add_chat_message(now, cfg[
"id"], side,
message,
1343 void menu_handler::do_search(
const std::string& new_search)
1345 if(new_search.empty() ==
false && new_search != last_search_)
1346 last_search_ = new_search;
1348 if(last_search_.empty())
1354 std::vector<std::string> args =
utils::split(last_search_,
',');
1355 if(args.size() == 2) {
1357 x = lexical_cast_default<int>(args[0], 0) - 1;
1358 y = lexical_cast_default<int>(args[1], 0) - 1;
1359 if(x >= 0 && x < pc_.get_map().w() && y >= 0 && y < pc_.get_map().h()) {
1372 loc.
x = (
loc.
x + 1) % pc_.get_map().w();
1374 loc.
y = (
loc.
y + 1) % pc_.get_map().h();
1377 if(!gui_->shrouded(
loc)) {
1380 const std::string& label_text =
label->text().str();
1386 if(!gui_->fogged(
loc)) {
1388 if(ui != pc_.get_units().end()) {
1389 const std::string&
unit_name = ui->name();
1391 if(!gui_->viewing_team().is_enemy(ui->side())
1392 || !ui->invisible(ui->get_location())) {
1404 last_search_hit_ =
loc;
1406 gui_->highlight_hex(
loc);
1411 symbols[
"search"] = last_search_;
1412 const std::string
msg =
VGETTEXT(
"Could not find label or unit "
1413 "containing the string ‘$search’.",
1419 void menu_handler::do_command(
const std::string& str)
1425 std::vector<std::string> menu_handler::get_commands_list()
1436 void console_handler::do_refresh()
1441 menu_handler_.gui_->create_buttons();
1442 menu_handler_.gui_->queue_rerender();
1445 void console_handler::do_droid()
1448 const std::string side_s = get_arg(1);
1449 std::string action = get_arg(2);
1450 std::transform(action.begin(), action.end(), action.begin(), tolower);
1452 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1453 const bool is_your_turn = menu_handler_.pc_.current_side() ==
static_cast<int>(menu_handler_.gui_->viewing_team().side());
1456 symbols[
"side"] = std::to_string(side);
1458 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1459 command_failed(
VGETTEXT(
"Can’t droid invalid side: ‘$side’.", symbols));
1461 }
else if(menu_handler_.board().get_team(side).is_network()) {
1462 command_failed(
VGETTEXT(
"Can’t droid networked side: ‘$side’.", symbols));
1464 }
else if(menu_handler_.board().get_team(side).is_local()) {
1465 bool changed =
false;
1467 const bool is_human = menu_handler_.board().get_team(side).is_human();
1468 const bool is_droid = menu_handler_.board().get_team(side).is_droid();
1469 const bool is_proxy_human = menu_handler_.board().get_team(side).is_proxy_human();
1470 const bool is_ai = menu_handler_.board().get_team(side).is_ai();
1472 if(action ==
"on") {
1473 if(is_ai && !is_your_turn) {
1474 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1477 if(!is_human || !is_droid) {
1478 menu_handler_.board().get_team(side).make_human();
1479 menu_handler_.board().get_team(side).make_droid();
1482 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1484 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: AI.", symbols));
1486 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already droided.", symbols));
1488 }
else if(action ==
"off") {
1489 if(is_ai && !is_your_turn) {
1490 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1493 if(!is_human || !is_proxy_human) {
1494 menu_handler_.board().get_team(side).make_human();
1495 menu_handler_.board().get_team(side).make_proxy_human();
1498 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1500 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: human.", symbols));
1502 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already not droided.", symbols));
1504 }
else if(action ==
"full") {
1506 command_failed(
_(
"It is not allowed to change a side from human to AI control when it’s not your turn."));
1509 if(!is_ai || !is_droid) {
1510 menu_handler_.board().get_team(side).make_ai();
1511 menu_handler_.board().get_team(side).make_droid();
1513 if(is_human || is_proxy_human) {
1514 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::ai}});
1516 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now fully controlled by: AI.", symbols));
1518 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already fully AI controlled.", symbols));
1520 }
else if(action ==
"") {
1521 if(is_ai && !is_your_turn) {
1522 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1525 if(is_ai || is_droid) {
1526 menu_handler_.board().get_team(side).make_human();
1527 menu_handler_.board().get_team(side).make_proxy_human();
1530 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1532 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: human.", symbols));
1534 menu_handler_.board().get_team(side).make_human();
1535 menu_handler_.board().get_team(side).make_droid();
1538 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1540 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: AI.", symbols));
1543 print(get_cmd(),
VGETTEXT(
"Invalid action provided for side ‘$side’. Valid actions are: on, off, full.", symbols));
1546 if(team_num_ == side && changed) {
1548 psc->set_player_type_changed();
1552 command_failed(
VGETTEXT(
"Side ‘$side’ is not a human or AI player.", symbols));
1555 menu_handler_.textbox_info_.close();
1558 void console_handler::do_terrain()
1562 const std::string mode_str = get_arg(2);
1572 "mode_str", mode_str,
1577 void console_handler::do_idle()
1580 const std::string side_s = get_arg(1);
1581 const std::string action = get_arg(2);
1583 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1585 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1587 symbols[
"side"] = side_s;
1588 command_failed(
VGETTEXT(
"Can’t idle invalid side: ‘$side’.", symbols));
1590 }
else if(menu_handler_.board().get_team(side).is_network()) {
1592 symbols[
"side"] = std::to_string(side);
1593 command_failed(
VGETTEXT(
"Can’t idle networked side: ‘$side’.", symbols));
1595 }
else if(menu_handler_.board().get_team(side).is_local_ai()) {
1597 symbols[
"side"] = std::to_string(side);
1598 command_failed(
VGETTEXT(
"Can’t idle local ai side: ‘$side’.", symbols));
1600 }
else if(menu_handler_.board().get_team(side).is_local_human()) {
1601 if(menu_handler_.board().get_team(side).is_idle() ? action ==
" on" : action ==
" off") {
1605 menu_handler_.board().get_team(side).toggle_idle();
1606 if(team_num_ == side) {
1608 psc->set_player_type_changed();
1612 menu_handler_.textbox_info_.close();
1615 void console_handler::do_theme()
1629 return t.save_id() == save_id_;
1635 void console_handler::do_control()
1638 if(!menu_handler_.pc_.is_networked_mp()) {
1642 const std::string side = get_arg(1);
1643 const std::string player = get_arg(2);
1644 if(player.empty()) {
1645 command_failed_need_arg(2);
1649 unsigned int side_num;
1651 side_num = lexical_cast<unsigned int>(side);
1653 const auto& teams = menu_handler_.pc_.get_teams();
1654 const auto it_t = std::find_if(teams.begin(), teams.end(),
save_id_matches(side));
1656 if(it_t == teams.end()) {
1658 symbols[
"side"] = side;
1659 command_failed(
VGETTEXT(
"Can’t change control of invalid side: ‘$side’.", symbols));
1662 side_num = it_t->side();
1666 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1668 symbols[
"side"] = side;
1669 command_failed(
VGETTEXT(
"Can’t change control of out-of-bounds side: ‘$side’.", symbols));
1673 menu_handler_.request_control_change(side_num, player);
1674 menu_handler_.textbox_info_.close();
1677 void console_handler::do_controller()
1679 const std::string side = get_arg(1);
1680 unsigned int side_num;
1682 side_num = lexical_cast<unsigned int>(side);
1685 symbols[
"side"] = side;
1686 command_failed(
VGETTEXT(
"Can’t query control of invalid side: ‘$side’.", symbols));
1690 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1692 symbols[
"side"] = side;
1693 command_failed(
VGETTEXT(
"Can’t query control of out-of-bounds side: ‘$side’.", symbols));
1698 if(!menu_handler_.board().get_team(side_num).is_proxy_human()) {
1702 if(menu_handler_.board().get_team(side_num).is_network()) {
1703 report +=
" (networked)";
1706 print(get_cmd(), report);
1709 void console_handler::do_clear()
1711 menu_handler_.gui_->get_chat_manager().clear_chat_messages();
1714 void console_handler::do_foreground()
1717 menu_handler_.gui_->invalidate_all();
1720 void console_handler::do_layers()
1722 display& disp = *(menu_handler_.gui_);
1736 if(menu_handler_.pc_.get_map().on_board_with_border(
loc)) {
1737 terrain_layers::display(disp,
loc);
1741 void console_handler::do_fps()
1746 void console_handler::do_benchmark()
1751 void console_handler::do_save()
1753 menu_handler_.pc_.do_consolesave(get_data());
1756 void console_handler::do_save_quit()
1762 void console_handler::do_quit()
1767 void console_handler::do_ignore_replay_errors()
1772 void console_handler::do_nosaves()
1777 void console_handler::do_next_level()
1782 void console_handler::do_choose_level()
1784 std::string
tag = menu_handler_.pc_.get_classification().get_tagname();
1785 std::vector<std::string> options;
1787 if(
tag !=
"multiplayer") {
1789 const std::string&
id = sc[
"id"];
1790 options.push_back(
id);
1791 if(
id == menu_handler_.gamedata().next_scenario()) {
1798 std::string scenario_id = menu_handler_.pc_.get_mp_settings().mp_scenario;
1799 if(
auto this_scenario = menu_handler_.game_config_.find_child(
tag,
"id", scenario_id)) {
1800 std::string addon_id = this_scenario[
"addon_id"].str();
1802 if(sc[
"addon_id"] == addon_id) {
1803 std::string
id = sc[
"id"];
1804 options.push_back(
id);
1805 if(
id == menu_handler_.gamedata().next_scenario()) {
1812 std::sort(options.begin(), options.end());
1813 int choice = std::distance(options.begin(), std::lower_bound(options.begin(), options.end(), next));
1825 if(std::size_t(choice) < options.size()) {
1830 void console_handler::do_turn()
1832 tod_manager& tod_man = menu_handler_.gamestate().tod_manager_;
1834 int turn = tod_man.
turn() + 1;
1835 const std::string&
data = get_data();
1837 turn = lexical_cast_default<int>(
data, 1);
1842 void console_handler::do_turn_limit()
1844 int limit = get_data().empty() ? -1 : lexical_cast_default<int>(get_data(), 1);
1848 void console_handler::do_debug()
1851 print(get_cmd(),
_(
"Debug mode activated!"));
1854 command_failed(
_(
"Debug mode not available in network games"));
1858 void console_handler::do_nodebug()
1861 print(get_cmd(),
_(
"Debug mode deactivated!"));
1866 void console_handler::do_lua()
1868 if(!menu_handler_.gamestate().lua_kernel_) {
1875 void console_handler::do_unsafe_lua()
1877 if(!menu_handler_.gamestate().lua_kernel_) {
1882 _(
"Executing Lua code in in this manner opens your computer to potential security breaches from any "
1883 "malicious add-ons or other programs you may have installed.\n\n"
1884 "Do not continue unless you really know what you are doing."), message::ok_cancel_buttons);
1887 print(get_cmd(),
_(
"Unsafe mode enabled!"));
1888 menu_handler_.gamestate().lua_kernel_->load_package();
1892 void console_handler::do_custom()
1897 void console_handler::do_set_alias()
1899 const std::string
data = get_data();
1901 const std::string alias(
data.begin(), j);
1902 if(j !=
data.end()) {
1903 const std::string command(j + 1,
data.end());
1904 if(!command.empty()) {
1905 register_alias(command, alias);
1909 register_alias(alias, alias);
1917 const std::string command = chmap::get_actual_cmd(alias);
1918 print(get_cmd(),
"'" + alias +
"'" +
" = " +
"'" + command +
"'");
1922 void console_handler::do_set_var()
1924 const std::string
data = get_data();
1926 command_failed_need_arg(1);
1931 if(j !=
data.end()) {
1932 const std::string name(
data.begin(), j);
1933 const std::string value(j + 1,
data.end());
1936 command_failed(
_(
"Variable not found"));
1940 void console_handler::do_show_var()
1945 void console_handler::do_inspect()
1948 gamestate_inspector::display(
1952 void console_handler::do_control_dialog()
1954 mp_change_control::display(menu_handler_);
1957 void console_handler::do_unit()
1965 if(
i == menu_handler_.pc_.get_units().end()) {
1967 symbols[
"unit"] = get_arg(1);
1969 "Debug command ‘unit: $unit’ failed: no unit selected or hovered over.",
1975 const std::string
data = get_data(1);
1977 if(parameters.size() < 2) {
1981 if(parameters[0] ==
"alignment") {
1985 symbols[
"alignment"] = get_arg(1);
1987 "Invalid alignment: ‘$alignment’, needs to be one of lawful, neutral, chaotic, or liminal.",
1997 "name", parameters[0],
1998 "value", parameters[1],
2003 void console_handler::do_discover()
2005 for(
const unit_type_data::unit_type_map::value_type&
i :
unit_types.
types()) {
2010 void console_handler::do_undiscover()
2013 _(
"Do you wish to clear all of your discovered units from help?"), message::yes_no_buttons);
2020 void console_handler::do_create()
2024 if(menu_handler_.pc_.get_map().on_board(
loc)) {
2027 command_failed(
_(
"Invalid unit type"));
2032 create_and_place(*menu_handler_.gui_, menu_handler_.pc_.get_map(), menu_handler_.pc_.get_units(),
loc, *ut);
2034 command_failed(
_(
"Invalid location"));
2038 void console_handler::do_fog()
2043 void console_handler::do_shroud()
2048 void console_handler::do_gold()
2053 void console_handler::do_event()
2058 void console_handler::do_toggle_draw_coordinates()
2061 menu_handler_.gui_->invalidate_all();
2063 void console_handler::do_toggle_draw_terrain_codes()
2066 menu_handler_.gui_->invalidate_all();
2069 void console_handler::do_toggle_draw_num_of_bitmaps()
2072 menu_handler_.gui_->invalidate_all();
2075 void console_handler::do_toggle_whiteboard()
2077 if(
const std::shared_ptr<wb::manager>& whiteb = menu_handler_.pc_.get_whiteboard()) {
2078 whiteb->set_active(!whiteb->is_active());
2079 if(whiteb->is_active()) {
2080 print(get_cmd(),
_(
"Planning mode activated!"));
2081 whiteb->print_help_once();
2083 print(get_cmd(),
_(
"Planning mode deactivated!"));
2088 void console_handler::do_whiteboard_options()
2090 if(menu_handler_.pc_.get_whiteboard()) {
2091 menu_handler_.pc_.get_whiteboard()->options_dlg();
2095 void menu_handler::do_ai_formula(
const std::string& str,
int side_num,
mouse_handler& )
2105 void menu_handler::user_command()
2110 void menu_handler::request_control_change(
int side_num,
const std::string& player)
2112 std::string side = std::to_string(side_num);
2113 if(board().get_team(side_num).is_local_human() && player ==
prefs::get().login()) {
2119 pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player", player}});
2123 void menu_handler::custom_command()
2126 do_command(command);
2130 void menu_handler::ai_formula()
2132 if(!pc_.is_networked_mp()) {
2137 void menu_handler::clear_messages()
2139 gui_->get_chat_manager().clear_chat_messages();
2144 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,...
virtual const unit_map & units() const =0
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 scroll_to_tile(const map_location &loc, SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true, bool force=true)
Scroll such that location loc is on-screen.
const display_context & context() const
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_
bool dispatch(std::string cmd)
std::vector< std::string > get_commands_list() const
game_board & board() const
gui::floating_textbox & get_textbox()
gui::floating_textbox textbox_info_
void show_statistics(int side_num)
void recruit(int side_num, const map_location &last_hex)
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
virtual void select_hex(map_location hex) override
Function to display a location as selected.
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.
Main class to show messages to the user.
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).
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()
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 std::vector< const unit_type * > types_list() const
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.
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).
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_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(std::string_view tag, Args &&... data)
Wraps the given data in the specified tag.
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)
Case-insensitive search.
static std::string sgettext(const char *str)
t_string recruit_message(const std::string &type_id, map_location &target_hex, map_location &recruited_from, team ¤t_team)
@ STRIP_SPACES
REMOVE_EMPTY: remove empty elements.
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.