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;
269 std::vector<t_string> unknown_units;
275 int selected_index = -1,
i = 0;
280 recruit_list.push_back(
type);
283 unknown_units.emplace_back(
recruit);
291 if(
type->id() == last_recruit) {
298 if(!unknown_units.empty()) {
303 "Error: there’s an unknown unit type on your recruit list: $unknown_ids",
304 "Error: there are several unknown unit types on your recruit list: $unknown_ids",
305 unknown_units.size(),
306 {{
"unknown_ids", utils::format_conjunct_list(
"", unknown_units) }}
310 if(recruit_list.empty()) {
315 auto dlg = units_dialog::build_recruit_dialog(recruit_list, err_msgs_map, current_team);
316 dlg->set_selected_index(selected_index);
319 const unit_type*
type = recruit_list[dlg->get_selected_index()];
320 last_recruit =
type->id();
323 do_recruit(
type->id(), side_num, last_hex);
327 void menu_handler::repeat_recruit(
int side_num,
const map_location& last_hex)
329 team& current_team = board().get_team(side_num);
330 const std::string& last_recruit = current_team.
last_recruit();
331 if(last_recruit.empty())
return;
333 const auto validation = std::array
344 for(
const std::string&
err : validation) {
351 do_recruit(last_recruit, side_num, last_hex);
354 bool menu_handler::do_recruit(
const std::string&
type,
int side_num,
const map_location& target_hex)
367 if(
auto wb = pc_.get_whiteboard()) {
368 if(
wb->save_recruit(
type, side_num,
dst)) {
374 team& current_team = board().get_team(side_num);
385 if(pc_.get_disallow_recall()) {
390 team& current_team = board().get_team(side_num);
392 std::vector<unit_const_ptr> recall_list_team;
398 DBG_WB <<
"menu_handler::recall: Contents of wb-modified recall list:";
405 _(
"There are no troops available to recall.\n(You must have veteran survivors from a previous scenario.)"));
409 if(recall_list_team.empty()) {
414 const auto& dlg = units_dialog::build_recall_dialog(recall_list_team, current_team);
416 if(!dlg->show() || !dlg->is_selected()) {
420 int res = dlg->get_selected_index();
429 if(sel_unit->recall_cost() > -1) {
430 unit_cost = sel_unit->recall_cost();
433 int wb_gold = pc_.get_whiteboard() ? pc_.get_whiteboard()->get_spent_gold_for(side_num) : 0;
435 if(current_team.
gold() - wb_gold < unit_cost) {
437 i18n_symbols[
"cost"] = std::to_string(unit_cost);
438 std::string
msg =
VNGETTEXT(
"You must have at least 1 gold piece to recall a unit.",
439 "You must have at least $cost gold pieces to recall this unit.", unit_cost, i18n_symbols);
444 LOG_NG <<
"recall index: " << res;
461 if(!pc_.get_whiteboard()
462 || !pc_.get_whiteboard()->save_recall(*sel_unit, side_num, recall_location)) {
467 ERR_NG <<
"menu_handler::recall(): Unit does not exist in the recall list.";
473 void menu_handler::show_enemy_moves(
bool ignore_units,
int side_num)
480 gui_->unhighlight_reach();
483 for(
auto& u : pc_.get_units()) {
484 bool invisible = u.invisible(u.get_location());
486 if(board().get_team(side_num).is_enemy(u.side()) && !gui_->fogged(u.get_location()) && !u.incapacitated()
490 =
pathfind::paths(u,
false,
true, gui_->viewing_team(), 0,
false, ignore_units);
492 gui_->highlight_another_reach(
path, hex_under_mouse);
496 gui_->invalidate(u.get_location());
501 const bool selected_hex_has_unit = mh.
hex_hosts_unit(hex_under_mouse);
503 if(selected_hex_has_unit) {
512 void menu_handler::toggle_shroud_updates(
int side_num)
514 team& current_team = board().get_team(side_num);
518 update_shroud_now(side_num);
525 void menu_handler::update_shroud_now(
int )
534 bool units_alive(
int side_num,
const unit_map& units)
536 for(
auto&
unit : units) {
545 bool partmoved_units(
546 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
548 for(
auto&
unit : units) {
563 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
565 for(
auto&
unit : units) {
568 && (!whiteb || !whiteb->unit_has_actions(&
unit))) {
578 bool menu_handler::end_turn(
int side_num)
583 reason =
_(
"You cannot end your turn yet!");
589 std::size_t team_num =
static_cast<std::size_t
>(side_num - 1);
590 if(team_num < pc_.get_teams().size() && pc_.get_teams()[team_num].no_turn_confirmation()) {
595 && (!pc_.get_whiteboard() || !pc_.get_whiteboard()->current_side_has_actions())
596 && units_alive(side_num, pc_.get_units())) {
598 _(
"You have not started your turn yet. Do you really want to end your turn?"),
599 message::yes_no_buttons);
605 else if(
prefs::get().yellow_confirm() && partmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
607 _(
"Some units have movement left. Do you really want to end your turn?"),
608 message::yes_no_buttons);
614 else if(
prefs::get().green_confirm() && unmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
616 _(
"Some units have not moved. Do you really want to end your turn?"),
617 message::yes_no_buttons);
625 if(pc_.get_whiteboard() && !pc_.get_whiteboard()->allow_end_turn()) {
632 void menu_handler::goto_leader(
int side_num)
635 if(
i != pc_.get_units().end() &&
i->is_visible_to_team(gui_->viewing_team(),
false)) {
640 void menu_handler::unit_description()
643 if(un != pc_.get_units().end()) {
651 if(pc_.get_map().on_board(
loc) ==
false || gui_->shrouded(
loc)) {
660 void menu_handler::rename_unit()
663 if(un == pc_.get_units().end() || gui_->viewing_team().side() != un->side()) {
667 if(un->unrenamable()) {
671 std::string name = un->name();
672 const std::string title(
_(
"Rename Unit"));
673 const std::string
label(
_(
"Name:"));
675 if(edit_text::execute(title,
label, name)) {
678 gui_->invalidate_unit();
684 const mouse_handler& mousehandler = pc_.get_mouse_handler_base();
685 const bool see_all = gui_->show_everything() || (pc_.is_replay() && pc_.get_replay_controller()->see_all());
688 if(res != pc_.get_units().end()) {
699 typedef std::tuple<const unit_type*, unit_race::GENDER, std::string> type_gender_variation;
708 type_gender_variation choose_unit()
712 const auto& create_dlg = units_dialog::build_create_dialog(types_list);
714 for (std::size_t
i = 0;
i < types_list.size();
i++) {
715 if (types_list[
i]->
id() == last_created_unit) {
716 create_dlg->set_selected_index(
i);
717 create_dlg->set_gender(last_gender);
718 create_dlg->set_variation(last_variation);
725 const unit_type* ut = types_list[create_dlg->get_selected_index()];
726 last_created_unit = ut->
id();
727 last_gender = create_dlg->gender();
728 last_variation = create_dlg->variation();
731 if (create_dlg->is_selected()) {
732 info = type_gender_variation(ut, last_gender, last_variation);
734 ERR_NG <<
"Create unit dialog returned nonexistent or unusable unit_type id.";
745 void create_and_place(
749 const std::string& variation =
"")
757 "variation", variation,
774 if(
const auto& [
type, gender, variation] = choose_unit();
type !=
nullptr) {
776 create_and_place(destination, *
type, gender, variation);
784 if(
i == pc_.get_units().end()) {
785 if(!pc_.get_map().is_village(
loc)) {
793 if(
team >
static_cast<int>(pc_.get_teams().size())) {
798 int side =
i->side();
800 if(side >
static_cast<int>(pc_.get_teams().size())) {
805 if(pc_.get_map().is_village(
loc)) {
817 void menu_handler::label_terrain(
mouse_handler& mousehandler,
bool team_only)
820 if(pc_.get_map().on_board(
loc) ==
false) {
825 std::string
label = old_label ? old_label->
text() :
"";
827 if(edit_label::execute(
label, team_only)) {
828 std::string team_name;
832 team_name = gui_->labels().team_name();
836 const terrain_label* res = gui_->labels().set_label(
loc,
label, gui_->viewing_team_index(), team_name, color);
843 void menu_handler::clear_labels()
845 if(!board().is_observer()) {
848 _(
"Are you sure you want to clear map labels?"),
849 message::yes_no_buttons
853 std::string viewing_team = gui_->viewing_team().team_name();
854 gui_->labels().clear(viewing_team,
false);
860 void menu_handler::label_settings()
862 if(label_settings::execute(board())) {
863 gui_->labels().recalculate_labels();
870 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
872 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
876 move_unit_to_loc(
i,
i->get_interrupted_move(),
true, side_num, mousehandler);
879 void menu_handler::move_unit_to_loc(
886 assert(ui != pc_.get_units().end());
890 if(route.
steps.empty()) {
894 assert(route.
steps.front() == ui->get_location());
896 gui_->set_route(&route);
897 gui_->unhighlight_reach();
900 LOG_NG <<
"move_unit_to_loc " << route.
steps.front() <<
" to " << route.
steps.back();
905 gui_->set_route(
nullptr);
906 gui_->invalidate_game_status();
915 bool wait_blocker_move =
true;
916 std::set<map_location> fully_moved;
919 bool blocked_unit =
false;
922 blocked_unit =
false;
923 for(
auto&
unit : pc_.get_units()) {
931 if(goto_loc == current_loc) {
936 if(!pc_.get_map().on_board(goto_loc)) {
941 if(fully_moved.count(current_loc)) {
947 if(route.
steps.size() <= 1) {
948 fully_moved.insert(current_loc);
954 pathfind::marked_route::mark_map::const_iterator
w = route.
marks.begin();
955 for(;
w != route.
marks.end(); ++
w) {
956 if(
w->second.turns == 1) {
957 next_stop =
w->first;
962 if(next_stop == current_loc) {
963 fully_moved.insert(current_loc);
969 if(pc_.get_units().count(next_stop)) {
971 if(wait_blocker_move)
975 gui_->set_route(&route);
978 LOG_NG <<
"execute goto from " << route.
steps.front() <<
" to " << route.
steps.back();
985 wait_blocker_move =
true;
989 if(!change && wait_blocker_move) {
991 wait_blocker_move =
false;
994 }
while(change && blocked_unit);
997 gui_->set_route(
nullptr);
998 gui_->invalidate_game_status();
1001 void menu_handler::toggle_ellipses()
1004 gui_->invalidate_all();
1007 void menu_handler::toggle_grid()
1010 gui_->invalidate_all();
1013 void menu_handler::unit_hold_position(
mouse_handler& mousehandler,
int side_num)
1016 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1017 un->toggle_hold_position();
1022 if(un->hold_position()) {
1031 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1032 un->toggle_user_end_turn();
1037 if(un->user_end_turn()) {
1049 void menu_handler::search()
1051 std::ostringstream
msg;
1053 if(last_search_hit_.valid()) {
1054 msg <<
" [" << last_search_ <<
"]";
1060 bool menu_handler::do_speak()
1064 return chat_handler::do_speak(
1065 textbox_info_.box()->text(), textbox_info_.check() !=
nullptr ? textbox_info_.check()->checked() :
false);
1068 void menu_handler::add_chat_message(
const std::chrono::system_clock::time_point& time,
1069 const std::string& speaker,
1074 gui_->get_chat_manager().add_chat_message(time, speaker, side,
message,
type,
false);
1101 using chmap::get_commands_list;
1102 using chmap::command_failed;
1108 chat_command_handler::command_handler
h,
1109 const std::string&
help =
"",
1110 const std::string& usage =
"",
1111 const std::string& flags =
"")
1113 chmap::register_command(cmd,
h,
help, usage, flags +
"N");
1118 chmap::register_alias(to_cmd, cmd);
1123 return chmap::get_arg(
i);
1128 return chmap::get_cmd();
1133 return chmap::get_data(
n);
1137 using chmap::register_command;
1138 using chmap::register_alias;
1140 using chmap::is_enabled;
1141 using chmap::command_failed_need_arg;
1149 void do_controller();
1151 void do_foreground();
1154 void do_benchmark();
1156 void do_save_quit();
1158 void do_ignore_replay_errors();
1160 void do_next_level();
1161 void do_choose_level();
1163 void do_turn_limit();
1167 void do_unsafe_lua();
1169 void do_set_alias();
1173 void do_control_dialog();
1178 void do_undiscover();
1184 void do_toggle_draw_coordinates();
1185 void do_toggle_draw_terrain_codes();
1186 void do_toggle_draw_num_of_bitmaps();
1187 void do_toggle_whiteboard();
1188 void do_whiteboard_options();
1192 return _(
"(D) — debug only, (N) — network only, (A) — admin only");
1195 using chat_command_handler::get_command_flags_description;
1198 std::string space(
" ");
1199 return (
c.has_flag(
'D') ? space +
_(
"(debug command)") :
"")
1200 + (
c.has_flag(
'N') ? space +
_(
"(network only)") :
"")
1201 + (
c.has_flag(
'A') ? space +
_(
"(admin only)") :
"")
1202 + (
c.has_flag(
'S') ? space +
_(
"(not during other events)") :
"");
1205 using map::is_enabled;
1209 || (
c.has_flag(
'N') && !menu_handler_.pc_.is_networked_mp())
1216 menu_handler_.add_chat_message(std::chrono::system_clock::now(), title, 0,
message);
1221 chat_command_handler::init_map();
1223 chmap::get_command(
"log")->flags =
"";
1224 chmap::get_command(
"version")->flags =
"";
1225 chmap::get_command(
"ignore")->flags =
"";
1226 chmap::get_command(
"friend")->flags =
"";
1227 chmap::get_command(
"remove")->flags =
"";
1229 chmap::set_cmd_prefix(
":");
1230 chmap::set_cmd_flag(
true);
1232 register_command(
"refresh", &console_handler::do_refresh,
_(
"Refresh gui."));
1233 register_command(
"droid", &console_handler::do_droid,
_(
"Switch a side to/from AI control."),
1237 _(
"[<side> [on/off/full]]\n“on” = enable but retain vision, “full” = as if it’s controlled by another player"));
1238 register_command(
"terrain", &console_handler::do_terrain,
_(
"Change terrain type of current hex"),
1240 _(
"<terrain type> [both|base|overlay]"),
"DS");
1241 register_command(
"idle", &console_handler::do_idle,
_(
"Switch a side to/from idle state."),
1245 _(
"command_idle^[<side> [on/off]]"));
1246 register_command(
"theme", &console_handler::do_theme,
_(
"Change the in-game theme."));
1247 register_command(
"control", &console_handler::do_control,
1248 _(
"Assign control of a side to a different player or observer."),
_(
"<side> <nickname>"),
"N");
1249 register_command(
"controller", &console_handler::do_controller,
_(
"Query the controller status of a side."),
1251 register_command(
"clear", &console_handler::do_clear,
_(
"Clear chat history."));
1252 register_command(
"foreground", &console_handler::do_foreground,
_(
"Debug foreground terrain."),
"",
"D");
1254 "layers", &console_handler::do_layers,
_(
"Debug layers from terrain under the mouse."),
"",
"D");
1255 register_command(
"fps", &console_handler::do_fps,
_(
"Display and log fps (Frames Per Second)."));
1256 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."));
1257 register_command(
"save", &console_handler::do_save,
_(
"Save game."));
1258 register_alias(
"save",
"w");
1259 register_command(
"quit", &console_handler::do_quit,
_(
"Quit game."));
1261 register_alias(
"quit",
"q!");
1262 register_command(
"save_quit", &console_handler::do_save_quit,
_(
"Save and quit."));
1263 register_alias(
"save_quit",
"wq");
1264 register_command(
"ignore_replay_errors", &console_handler::do_ignore_replay_errors,
_(
"Ignore replay errors."));
1265 register_command(
"nosaves", &console_handler::do_nosaves,
_(
"Disable autosaves."));
1266 register_command(
"next_level", &console_handler::do_next_level,
1267 _(
"Advance to the next scenario, or scenario identified by ‘id’"),
_(
"<id>"),
"DS");
1268 register_alias(
"next_level",
"n");
1269 register_command(
"choose_level", &console_handler::do_choose_level,
_(
"Choose next scenario"),
"",
"DS");
1270 register_alias(
"choose_level",
"cl");
1271 register_command(
"turn", &console_handler::do_turn,
1272 _(
"Change turn number (and time of day), or increase by one if no number is specified."),
_(
"[turn]"),
1274 register_command(
"turn_limit", &console_handler::do_turn_limit,
1275 _(
"Change turn limit, or turn the turn limit off if no number is specified or it’s −1."),
_(
"[limit]"),
1277 register_command(
"debug", &console_handler::do_debug,
_(
"Turn debug mode on."));
1278 register_command(
"nodebug", &console_handler::do_nodebug,
_(
"Turn debug mode off."),
"",
"D");
1280 "lua", &console_handler::do_lua,
_(
"Execute a Lua statement."),
_(
"<command>[;<command>...]"),
"DS");
1282 "unsafe_lua", &console_handler::do_unsafe_lua,
_(
"Grant higher privileges to Lua scripts."),
"",
"D");
1283 register_command(
"custom", &console_handler::do_custom,
_(
"Set the command used by the custom command hotkey"),
1284 _(
"<command>[;<command>...]"));
1285 register_command(
"give_control", &console_handler::do_control_dialog,
1286 _(
"Invoke a dialog allowing changing control of MP sides."),
"",
"N");
1287 register_command(
"inspect", &console_handler::do_inspect,
_(
"Launch the gamestate inspector"),
"",
"D");
1289 "alias", &console_handler::do_set_alias,
_(
"Set or show alias to a command"),
_(
"<name>[=<command>]"));
1291 "set_var", &console_handler::do_set_var,
_(
"Set a scenario variable."),
_(
"<var>=<value>"),
"DS");
1292 register_command(
"show_var", &console_handler::do_show_var,
_(
"Show a scenario variable."),
_(
"<var>"),
"D");
1293 register_command(
"unit", &console_handler::do_unit,
1295 _(
"Modify a unit variable. (Only top level keys are supported, and advances=<number>.)"),
1296 _(
"<var>=<value>"),
"DS");
1302 register_command(
"discover", &console_handler::do_discover,
_(
"Discover all units in help."),
"");
1303 register_command(
"undiscover", &console_handler::do_undiscover,
_(
"‘Undiscover’ all units in help."),
"");
1304 register_command(
"create", &console_handler::do_create,
_(
"Create a unit."),
_(
"<unit type id>"),
"DS");
1305 register_command(
"fog", &console_handler::do_fog,
_(
"Toggle fog for the current player."),
"",
"DS");
1306 register_command(
"shroud", &console_handler::do_shroud,
_(
"Toggle shroud for the current player."),
"",
"DS");
1307 register_command(
"gold", &console_handler::do_gold,
_(
"Give gold to the current player."),
_(
"<amount>"),
"DS");
1308 register_command(
"throw", &console_handler::do_event,
_(
"Fire a game event."),
_(
"<event name>"),
"DS");
1309 register_alias(
"throw",
"fire");
1310 register_command(
"show_coordinates", &console_handler::do_toggle_draw_coordinates,
1311 _(
"Toggle overlaying of x,y coordinates on hexes."));
1312 register_alias(
"show_coordinates",
"sc");
1313 register_command(
"show_terrain_codes", &console_handler::do_toggle_draw_terrain_codes,
1314 _(
"Toggle overlaying of terrain codes on hexes."));
1315 register_alias(
"show_terrain_codes",
"tc");
1316 register_command(
"show_num_of_bitmaps", &console_handler::do_toggle_draw_num_of_bitmaps,
1317 _(
"Toggle overlaying of number of bitmaps on hexes."));
1318 register_alias(
"show_num_of_bitmaps",
"bn");
1319 register_command(
"whiteboard", &console_handler::do_toggle_whiteboard,
_(
"Toggle planning mode."));
1320 register_alias(
"whiteboard",
"wb");
1322 "whiteboard_options", &console_handler::do_whiteboard_options,
_(
"Access whiteboard options dialog."));
1323 register_alias(
"whiteboard_options",
"wbo");
1325 if(
auto alias_list =
prefs::get().get_alias()) {
1326 for(
const auto& [key, value] : alias_list->attribute_range()) {
1327 register_alias(value, key);
1337 void menu_handler::send_chat_message(
const std::string&
message,
bool allies_only)
1342 auto now = std::chrono::system_clock::now();
1345 const int side = board().
is_observer() ? 0 : gui_->viewing_team().side();
1346 if(!board().is_observer()) {
1353 if(board().is_observer()) {
1356 cfg[
"to_sides"] = gui_->viewing_team().allied_human_teams();
1362 add_chat_message(now,
cfg[
"id"], side,
message,
1366 void menu_handler::do_search(
const std::string& new_search)
1368 if(new_search.empty() ==
false && new_search != last_search_)
1369 last_search_ = new_search;
1371 if(last_search_.empty())
1377 std::vector<std::string> args =
utils::split(last_search_,
',');
1378 if(args.size() == 2) {
1380 x = lexical_cast_default<int>(args[0], 0) - 1;
1381 y = lexical_cast_default<int>(args[1], 0) - 1;
1382 if(x >= 0 && x < pc_.get_map().w() && y >= 0 && y < pc_.get_map().h()) {
1395 loc.
x = (
loc.
x + 1) % pc_.get_map().w();
1397 loc.
y = (
loc.
y + 1) % pc_.get_map().h();
1400 if(!gui_->shrouded(
loc)) {
1403 const std::string& label_text =
label->text().str();
1409 if(!gui_->fogged(
loc)) {
1411 if(ui != pc_.get_units().end()) {
1412 const std::string&
unit_name = ui->name();
1414 if(!gui_->viewing_team().is_enemy(ui->side())
1415 || !ui->invisible(ui->get_location())) {
1427 last_search_hit_ =
loc;
1429 gui_->highlight_hex(
loc);
1434 symbols[
"search"] = last_search_;
1435 const std::string
msg =
VGETTEXT(
"Could not find label or unit "
1436 "containing the string ‘$search’.",
1442 void menu_handler::do_command(
const std::string& str)
1448 std::vector<std::string> menu_handler::get_commands_list()
1459 void console_handler::do_refresh()
1464 menu_handler_.gui_->create_buttons();
1465 menu_handler_.gui_->queue_rerender();
1468 void console_handler::do_droid()
1471 const std::string side_s = get_arg(1);
1472 std::string action = get_arg(2);
1473 std::transform(action.begin(), action.end(), action.begin(), tolower);
1475 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1476 const bool is_your_turn = menu_handler_.pc_.current_side() ==
static_cast<int>(menu_handler_.gui_->viewing_team().side());
1479 symbols[
"side"] = std::to_string(side);
1481 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1482 command_failed(
VGETTEXT(
"Can’t droid invalid side: ‘$side’.", symbols));
1484 }
else if(menu_handler_.board().get_team(side).is_network()) {
1485 command_failed(
VGETTEXT(
"Can’t droid networked side: ‘$side’.", symbols));
1487 }
else if(menu_handler_.board().get_team(side).is_local()) {
1488 bool changed =
false;
1490 const bool is_human = menu_handler_.board().get_team(side).is_human();
1491 const bool is_droid = menu_handler_.board().get_team(side).is_droid();
1492 const bool is_proxy_human = menu_handler_.board().get_team(side).is_proxy_human();
1493 const bool is_ai = menu_handler_.board().get_team(side).is_ai();
1495 if(action ==
"on") {
1496 if(is_ai && !is_your_turn) {
1497 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1500 if(!is_human || !is_droid) {
1501 menu_handler_.board().get_team(side).make_human();
1502 menu_handler_.board().get_team(side).make_droid();
1505 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1507 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: AI.", symbols));
1509 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already droided.", symbols));
1511 }
else if(action ==
"off") {
1512 if(is_ai && !is_your_turn) {
1513 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1516 if(!is_human || !is_proxy_human) {
1517 menu_handler_.board().get_team(side).make_human();
1518 menu_handler_.board().get_team(side).make_proxy_human();
1521 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1523 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: human.", symbols));
1525 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already not droided.", symbols));
1527 }
else if(action ==
"full") {
1529 command_failed(
_(
"It is not allowed to change a side from human to AI control when it’s not your turn."));
1532 if(!is_ai || !is_droid) {
1533 menu_handler_.board().get_team(side).make_ai();
1534 menu_handler_.board().get_team(side).make_droid();
1536 if(is_human || is_proxy_human) {
1537 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::ai}});
1539 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now fully controlled by: AI.", symbols));
1541 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already fully AI controlled.", symbols));
1543 }
else if(action ==
"") {
1544 if(is_ai && !is_your_turn) {
1545 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1548 if(is_ai || is_droid) {
1549 menu_handler_.board().get_team(side).make_human();
1550 menu_handler_.board().get_team(side).make_proxy_human();
1553 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1555 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: human.", symbols));
1557 menu_handler_.board().get_team(side).make_human();
1558 menu_handler_.board().get_team(side).make_droid();
1561 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1563 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: AI.", symbols));
1566 print(get_cmd(),
VGETTEXT(
"Invalid action provided for side ‘$side’. Valid actions are: on, off, full.", symbols));
1569 if(team_num_ == side && changed) {
1571 psc->set_player_type_changed();
1575 command_failed(
VGETTEXT(
"Side ‘$side’ is not a human or AI player.", symbols));
1578 menu_handler_.textbox_info_.close();
1581 void console_handler::do_terrain()
1585 const std::string mode_str = get_arg(2);
1595 "mode_str", mode_str,
1600 void console_handler::do_idle()
1603 const std::string side_s = get_arg(1);
1604 const std::string action = get_arg(2);
1606 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1608 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1610 symbols[
"side"] = side_s;
1611 command_failed(
VGETTEXT(
"Can’t idle invalid side: ‘$side’.", symbols));
1613 }
else if(menu_handler_.board().get_team(side).is_network()) {
1615 symbols[
"side"] = std::to_string(side);
1616 command_failed(
VGETTEXT(
"Can’t idle networked side: ‘$side’.", symbols));
1618 }
else if(menu_handler_.board().get_team(side).is_local_ai()) {
1620 symbols[
"side"] = std::to_string(side);
1621 command_failed(
VGETTEXT(
"Can’t idle local ai side: ‘$side’.", symbols));
1623 }
else if(menu_handler_.board().get_team(side).is_local_human()) {
1624 if(menu_handler_.board().get_team(side).is_idle() ? action ==
" on" : action ==
" off") {
1628 menu_handler_.board().get_team(side).toggle_idle();
1629 if(team_num_ == side) {
1631 psc->set_player_type_changed();
1635 menu_handler_.textbox_info_.close();
1638 void console_handler::do_theme()
1652 return t.save_id() == save_id_;
1658 void console_handler::do_control()
1661 if(!menu_handler_.pc_.is_networked_mp()) {
1665 const std::string side = get_arg(1);
1666 const std::string player = get_arg(2);
1667 if(player.empty()) {
1668 command_failed_need_arg(2);
1672 unsigned int side_num;
1674 side_num = lexical_cast<unsigned int>(side);
1676 const auto& teams = menu_handler_.pc_.get_teams();
1677 const auto it_t = std::find_if(teams.begin(), teams.end(),
save_id_matches(side));
1679 if(it_t == teams.end()) {
1681 symbols[
"side"] = side;
1682 command_failed(
VGETTEXT(
"Can’t change control of invalid side: ‘$side’.", symbols));
1685 side_num = it_t->side();
1689 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1691 symbols[
"side"] = side;
1692 command_failed(
VGETTEXT(
"Can’t change control of out-of-bounds side: ‘$side’.", symbols));
1696 menu_handler_.request_control_change(side_num, player);
1697 menu_handler_.textbox_info_.close();
1700 void console_handler::do_controller()
1702 const std::string side = get_arg(1);
1703 unsigned int side_num;
1705 side_num = lexical_cast<unsigned int>(side);
1708 symbols[
"side"] = side;
1709 command_failed(
VGETTEXT(
"Can’t query control of invalid side: ‘$side’.", symbols));
1713 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1715 symbols[
"side"] = side;
1716 command_failed(
VGETTEXT(
"Can’t query control of out-of-bounds side: ‘$side’.", symbols));
1721 if(!menu_handler_.board().get_team(side_num).is_proxy_human()) {
1725 if(menu_handler_.board().get_team(side_num).is_network()) {
1726 report +=
" (networked)";
1729 print(get_cmd(), report);
1732 void console_handler::do_clear()
1734 menu_handler_.gui_->get_chat_manager().clear_chat_messages();
1737 void console_handler::do_foreground()
1740 menu_handler_.gui_->invalidate_all();
1743 void console_handler::do_layers()
1745 display& disp = *(menu_handler_.gui_);
1759 if(menu_handler_.pc_.get_map().on_board_with_border(
loc)) {
1760 terrain_layers::display(disp,
loc);
1764 void console_handler::do_fps()
1769 void console_handler::do_benchmark()
1774 void console_handler::do_save()
1776 menu_handler_.pc_.do_consolesave(get_data());
1779 void console_handler::do_save_quit()
1785 void console_handler::do_quit()
1790 void console_handler::do_ignore_replay_errors()
1795 void console_handler::do_nosaves()
1800 void console_handler::do_next_level()
1805 void console_handler::do_choose_level()
1807 std::string
tag = menu_handler_.pc_.get_classification().get_tagname();
1808 std::vector<std::string> options;
1810 if(
tag !=
"multiplayer") {
1812 const std::string&
id = sc[
"id"];
1813 options.push_back(
id);
1814 if(
id == menu_handler_.gamedata().next_scenario()) {
1821 std::string scenario_id = menu_handler_.pc_.get_mp_settings().mp_scenario;
1822 if(
auto this_scenario = menu_handler_.game_config_.find_child(
tag,
"id", scenario_id)) {
1823 std::string addon_id = this_scenario[
"addon_id"].str();
1825 if(sc[
"addon_id"] == addon_id) {
1826 std::string
id = sc[
"id"];
1827 options.push_back(
id);
1828 if(
id == menu_handler_.gamedata().next_scenario()) {
1835 std::sort(options.begin(), options.end());
1836 int choice = std::distance(options.begin(), std::lower_bound(options.begin(), options.end(), next));
1848 if(std::size_t(choice) < options.size()) {
1853 void console_handler::do_turn()
1855 tod_manager& tod_man = menu_handler_.gamestate().tod_manager_;
1857 int turn = tod_man.
turn() + 1;
1858 const std::string&
data = get_data();
1860 turn = lexical_cast_default<int>(
data, 1);
1865 void console_handler::do_turn_limit()
1867 int limit = get_data().empty() ? -1 : lexical_cast_default<int>(get_data(), 1);
1871 void console_handler::do_debug()
1874 print(get_cmd(),
_(
"Debug mode activated!"));
1877 command_failed(
_(
"Debug mode not available in network games"));
1881 void console_handler::do_nodebug()
1884 print(get_cmd(),
_(
"Debug mode deactivated!"));
1889 void console_handler::do_lua()
1891 if(!menu_handler_.gamestate().lua_kernel_) {
1898 void console_handler::do_unsafe_lua()
1900 if(!menu_handler_.gamestate().lua_kernel_) {
1905 _(
"Executing Lua code in in this manner opens your computer to potential security breaches from any "
1906 "malicious add-ons or other programs you may have installed.\n\n"
1907 "Do not continue unless you really know what you are doing."), message::ok_cancel_buttons);
1910 print(get_cmd(),
_(
"Unsafe mode enabled!"));
1911 menu_handler_.gamestate().lua_kernel_->load_package();
1915 void console_handler::do_custom()
1920 void console_handler::do_set_alias()
1922 const std::string
data = get_data();
1924 const std::string alias(
data.begin(), j);
1925 if(j !=
data.end()) {
1926 const std::string command(j + 1,
data.end());
1927 if(!command.empty()) {
1928 register_alias(command, alias);
1932 register_alias(alias, alias);
1940 const std::string command = chmap::get_actual_cmd(alias);
1941 print(get_cmd(),
"'" + alias +
"'" +
" = " +
"'" + command +
"'");
1945 void console_handler::do_set_var()
1947 const std::string
data = get_data();
1949 command_failed_need_arg(1);
1954 if(j !=
data.end()) {
1955 const std::string name(
data.begin(), j);
1956 const std::string value(j + 1,
data.end());
1959 command_failed(
_(
"Variable not found"));
1963 void console_handler::do_show_var()
1968 void console_handler::do_inspect()
1971 gamestate_inspector::display(
1975 void console_handler::do_control_dialog()
1977 mp_change_control::display(menu_handler_);
1980 void console_handler::do_unit()
1988 if(
i == menu_handler_.pc_.get_units().end()) {
1990 symbols[
"unit"] = get_arg(1);
1992 "Debug command ‘unit: $unit’ failed: no unit selected or hovered over.",
1998 const std::string
data = get_data(1);
2000 if(parameters.size() < 2) {
2004 if(parameters[0] ==
"alignment") {
2008 symbols[
"alignment"] = get_arg(1);
2010 "Invalid alignment: ‘$alignment’, needs to be one of lawful, neutral, chaotic, or liminal.",
2020 "name", parameters[0],
2021 "value", parameters[1],
2026 void console_handler::do_discover()
2028 for(
const unit_type_data::unit_type_map::value_type&
i :
unit_types.
types()) {
2033 void console_handler::do_undiscover()
2036 _(
"Do you wish to clear all of your discovered units from help?"), message::yes_no_buttons);
2043 void console_handler::do_create()
2047 if(menu_handler_.pc_.get_map().on_board(
loc)) {
2050 command_failed(
_(
"Invalid unit type"));
2055 create_and_place(
loc, *ut);
2057 command_failed(
_(
"Invalid location"));
2061 void console_handler::do_fog()
2066 void console_handler::do_shroud()
2071 void console_handler::do_gold()
2076 void console_handler::do_event()
2081 void console_handler::do_toggle_draw_coordinates()
2084 menu_handler_.gui_->invalidate_all();
2086 void console_handler::do_toggle_draw_terrain_codes()
2089 menu_handler_.gui_->invalidate_all();
2092 void console_handler::do_toggle_draw_num_of_bitmaps()
2095 menu_handler_.gui_->invalidate_all();
2098 void console_handler::do_toggle_whiteboard()
2100 if(
const std::shared_ptr<wb::manager>& whiteb = menu_handler_.pc_.get_whiteboard()) {
2101 whiteb->set_active(!whiteb->is_active());
2102 if(whiteb->is_active()) {
2103 print(get_cmd(),
_(
"Planning mode activated!"));
2104 whiteb->print_help_once();
2106 print(get_cmd(),
_(
"Planning mode deactivated!"));
2111 void console_handler::do_whiteboard_options()
2113 if(menu_handler_.pc_.get_whiteboard()) {
2114 menu_handler_.pc_.get_whiteboard()->options_dlg();
2123 add_chat_message(std::chrono::system_clock::now(),
"wfl", 0, result.
to_debug_string());
2130 void menu_handler::user_command()
2135 void menu_handler::request_control_change(
int side_num,
const std::string& player)
2137 std::string side = std::to_string(side_num);
2138 if(board().get_team(side_num).is_local_human() && player ==
prefs::get().login()) {
2144 pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player", player}});
2148 void menu_handler::custom_command()
2151 do_command(command);
2155 void menu_handler::ai_formula()
2157 if(!pc_.is_networked_mp()) {
2162 void menu_handler::clear_messages()
2164 gui_->get_chat_manager().clear_chat_messages();
2169 pc_.send_to_wesnothd(
cfg);
Various functions related to moving units.
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.
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).
bool auto_shroud_updates() const
const std::string & team_name() const
void set_last_recruit(const std::string &u_type)
static color_t get_side_color(int side)
void increment_action_bonus_count()
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 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()
An object representing the state of the game, providing access to the map and basic information.
std::string to_debug_string(bool verbose=false, formula_seen_stack *seen=nullptr) const
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::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)
std::string check_recruit_list(const std::string &type, int side_number, const map_location &target_hex)
std::string check_recruit_purse(int unit_cost, int current_purse, int investments)
int planned_gold_spent(int side_number)
std::tuple< std::string, map_location, map_location > validate_recruit_target(const std::string &type, int side_number, const map_location &target_hex)
Verifies that target_hex is a valid recruit location for the given side.
@ 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::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)
rect dst
Location on the final composed sheet.
rect src
Non-transparent portion of the surface to compose.
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.