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);
317 if (!dlg->show() && !dlg->is_selected()) {
321 const unit_type*
type = recruit_list[dlg->get_selected_index()];
322 last_recruit =
type->id();
325 if(err_msgs_map[
type].empty()) {
326 do_recruit(
type->id(), side_num, last_hex);
333 void menu_handler::repeat_recruit(
int side_num,
const map_location& last_hex)
335 team& current_team = board().get_team(side_num);
336 const std::string& last_recruit = current_team.
last_recruit();
337 if(last_recruit.empty())
return;
339 const auto validation = std::array
350 for(
const std::string&
err : validation) {
357 do_recruit(last_recruit, side_num, last_hex);
360 bool menu_handler::do_recruit(
const std::string&
type,
int side_num,
const map_location& target_hex)
373 if(
auto wb = pc_.get_whiteboard()) {
374 if(
wb->save_recruit(
type, side_num,
dst)) {
380 team& current_team = board().get_team(side_num);
391 if(pc_.get_disallow_recall()) {
396 team& current_team = board().get_team(side_num);
398 std::vector<unit_const_ptr> recall_list_team;
404 DBG_WB <<
"menu_handler::recall: Contents of wb-modified recall list:";
411 _(
"There are no troops available to recall.\n(You must have veteran survivors from a previous scenario.)"));
415 if(recall_list_team.empty()) {
420 const auto& dlg = units_dialog::build_recall_dialog(recall_list_team, current_team);
422 if(!dlg->show() || !dlg->is_selected()) {
426 int res = dlg->get_selected_index();
435 if(sel_unit->recall_cost() > -1) {
436 unit_cost = sel_unit->recall_cost();
439 int wb_gold = pc_.get_whiteboard() ? pc_.get_whiteboard()->get_spent_gold_for(side_num) : 0;
441 if(current_team.
gold() - wb_gold < unit_cost) {
443 i18n_symbols[
"cost"] = std::to_string(unit_cost);
444 std::string
msg =
VNGETTEXT(
"You must have at least 1 gold piece to recall a unit.",
445 "You must have at least $cost gold pieces to recall this unit.", unit_cost, i18n_symbols);
450 LOG_NG <<
"recall index: " << res;
467 if(!pc_.get_whiteboard()
468 || !pc_.get_whiteboard()->save_recall(*sel_unit, side_num, recall_location)) {
473 ERR_NG <<
"menu_handler::recall(): Unit does not exist in the recall list.";
479 void menu_handler::show_enemy_moves(
bool ignore_units,
int side_num)
486 gui_->unhighlight_reach();
489 for(
auto& u : pc_.get_units()) {
490 bool invisible = u.invisible(u.get_location());
492 if(board().get_team(side_num).is_enemy(u.side()) && !gui_->fogged(u.get_location()) && !u.incapacitated()
496 =
pathfind::paths(u,
false,
true, gui_->viewing_team(), 0,
false, ignore_units);
498 gui_->highlight_another_reach(
path, hex_under_mouse);
502 gui_->invalidate(u.get_location());
507 const bool selected_hex_has_unit = mh.
hex_hosts_unit(hex_under_mouse);
509 if(selected_hex_has_unit) {
518 void menu_handler::toggle_shroud_updates(
int side_num)
520 team& current_team = board().get_team(side_num);
524 update_shroud_now(side_num);
531 void menu_handler::update_shroud_now(
int )
540 bool units_alive(
int side_num,
const unit_map& units)
542 for(
auto&
unit : units) {
551 bool partmoved_units(
552 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
554 for(
auto&
unit : units) {
569 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
571 for(
auto&
unit : units) {
574 && (!whiteb || !whiteb->unit_has_actions(&
unit))) {
584 bool menu_handler::end_turn(
int side_num)
589 reason =
_(
"You cannot end your turn yet!");
595 std::size_t team_num =
static_cast<std::size_t
>(side_num - 1);
596 if(team_num < pc_.get_teams().size() && pc_.get_teams()[team_num].no_turn_confirmation()) {
601 && (!pc_.get_whiteboard() || !pc_.get_whiteboard()->current_side_has_actions())
602 && units_alive(side_num, pc_.get_units())) {
604 _(
"You have not started your turn yet. Do you really want to end your turn?"),
605 message::yes_no_buttons);
611 else if(
prefs::get().yellow_confirm() && partmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
613 _(
"Some units have movement left. Do you really want to end your turn?"),
614 message::yes_no_buttons);
620 else if(
prefs::get().green_confirm() && unmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
622 _(
"Some units have not moved. Do you really want to end your turn?"),
623 message::yes_no_buttons);
631 if(pc_.get_whiteboard() && !pc_.get_whiteboard()->allow_end_turn()) {
638 void menu_handler::goto_leader(
int side_num)
641 if(
i != pc_.get_units().end() &&
i->is_visible_to_team(gui_->viewing_team(),
false)) {
646 void menu_handler::unit_description()
649 if(un != pc_.get_units().end()) {
657 if(pc_.get_map().on_board(
loc) ==
false || gui_->shrouded(
loc)) {
666 void menu_handler::rename_unit()
669 if(un == pc_.get_units().end() || gui_->viewing_team().side() != un->side()) {
673 if(un->unrenamable()) {
677 std::string name = un->name();
678 const std::string title(
_(
"Rename Unit"));
679 const std::string
label(
_(
"Name:"));
681 if(edit_text::execute(title,
label, name)) {
684 gui_->invalidate_unit();
690 const mouse_handler& mousehandler = pc_.get_mouse_handler_base();
691 const bool see_all = gui_->show_everything() || (pc_.is_replay() && pc_.get_replay_controller()->see_all());
694 if(res != pc_.get_units().end()) {
705 typedef std::tuple<const unit_type*, unit_race::GENDER, std::string> type_gender_variation;
714 type_gender_variation choose_unit()
718 const auto& create_dlg = units_dialog::build_create_dialog(types_list);
720 for (std::size_t
i = 0;
i < types_list.size();
i++) {
721 if (types_list[
i]->
id() == last_created_unit) {
722 create_dlg->set_selected_index(
i);
723 create_dlg->set_gender(last_gender);
724 create_dlg->set_variation(last_variation);
730 if (!create_dlg->show() && !create_dlg->is_selected()) {
734 const unit_type* ut = types_list[create_dlg->get_selected_index()];
735 last_created_unit = ut->
id();
736 last_gender = create_dlg->gender();
737 last_variation = create_dlg->variation();
740 if (create_dlg->is_selected()) {
741 info = type_gender_variation(ut, last_gender, last_variation);
743 ERR_NG <<
"Create unit dialog returned nonexistent or unusable unit_type id.";
754 void create_and_place(
758 const std::string& variation =
"")
766 "variation", variation,
783 if(
const auto& [
type, gender, variation] = choose_unit();
type !=
nullptr) {
784 create_and_place(destination, *
type, gender, variation);
792 if(
i == pc_.get_units().end()) {
793 if(!pc_.get_map().is_village(
loc)) {
801 if(
team >
static_cast<int>(pc_.get_teams().size())) {
806 int side =
i->side();
808 if(side >
static_cast<int>(pc_.get_teams().size())) {
813 if(pc_.get_map().is_village(
loc)) {
825 void menu_handler::label_terrain(
mouse_handler& mousehandler,
bool team_only)
828 if(pc_.get_map().on_board(
loc) ==
false) {
833 std::string
label = old_label ? old_label->
text() :
"";
835 if(edit_label::execute(
label, team_only)) {
836 std::string team_name;
840 team_name = gui_->labels().team_name();
844 const terrain_label* res = gui_->labels().set_label(
loc,
label, gui_->viewing_team_index(), team_name, color);
851 void menu_handler::clear_labels()
853 if(!board().is_observer()) {
856 _(
"Are you sure you want to clear map labels?"),
857 message::yes_no_buttons
861 std::string viewing_team = gui_->viewing_team().team_name();
862 gui_->labels().clear(viewing_team,
false);
868 void menu_handler::label_settings()
870 if(label_settings::execute(board())) {
871 gui_->labels().recalculate_labels();
878 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
880 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
884 move_unit_to_loc(
i,
i->get_interrupted_move(),
true, side_num, mousehandler);
887 void menu_handler::move_unit_to_loc(
894 assert(ui != pc_.get_units().end());
898 if(route.
steps.empty()) {
902 assert(route.
steps.front() == ui->get_location());
904 gui_->set_route(&route);
905 gui_->unhighlight_reach();
908 LOG_NG <<
"move_unit_to_loc " << route.
steps.front() <<
" to " << route.
steps.back();
913 gui_->set_route(
nullptr);
914 gui_->invalidate_game_status();
923 bool wait_blocker_move =
true;
924 std::set<map_location> fully_moved;
927 bool blocked_unit =
false;
930 blocked_unit =
false;
931 for(
auto&
unit : pc_.get_units()) {
939 if(goto_loc == current_loc) {
944 if(!pc_.get_map().on_board(goto_loc)) {
949 if(fully_moved.count(current_loc)) {
955 if(route.
steps.size() <= 1) {
956 fully_moved.insert(current_loc);
962 pathfind::marked_route::mark_map::const_iterator
w = route.
marks.begin();
963 for(;
w != route.
marks.end(); ++
w) {
964 if(
w->second.turns == 1) {
965 next_stop =
w->first;
970 if(next_stop == current_loc) {
971 fully_moved.insert(current_loc);
977 if(pc_.get_units().count(next_stop)) {
979 if(wait_blocker_move)
983 gui_->set_route(&route);
986 LOG_NG <<
"execute goto from " << route.
steps.front() <<
" to " << route.
steps.back();
993 wait_blocker_move =
true;
997 if(!change && wait_blocker_move) {
999 wait_blocker_move =
false;
1002 }
while(change && blocked_unit);
1005 gui_->set_route(
nullptr);
1006 gui_->invalidate_game_status();
1009 void menu_handler::toggle_ellipses()
1012 gui_->invalidate_all();
1015 void menu_handler::toggle_grid()
1018 gui_->invalidate_all();
1021 void menu_handler::unit_hold_position(
mouse_handler& mousehandler,
int side_num)
1024 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1025 un->toggle_hold_position();
1030 if(un->hold_position()) {
1039 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1040 un->toggle_user_end_turn();
1045 if(un->user_end_turn()) {
1057 void menu_handler::search()
1059 std::ostringstream
msg;
1061 if(last_search_hit_.valid()) {
1062 msg <<
" [" << last_search_ <<
"]";
1068 bool menu_handler::do_speak()
1072 return chat_handler::do_speak(
1073 textbox_info_.box()->text(), textbox_info_.check() !=
nullptr ? textbox_info_.check()->checked() :
false);
1076 void menu_handler::add_chat_message(
const std::chrono::system_clock::time_point& time,
1077 const std::string& speaker,
1082 gui_->get_chat_manager().add_chat_message(time, speaker, side,
message,
type,
false);
1109 using chmap::get_commands_list;
1110 using chmap::command_failed;
1116 chat_command_handler::command_handler
h,
1117 const std::string&
help =
"",
1118 const std::string& usage =
"",
1119 const std::string& flags =
"")
1121 chmap::register_command(cmd,
h,
help, usage, flags +
"N");
1126 chmap::register_alias(to_cmd, cmd);
1131 return chmap::get_arg(
i);
1136 return chmap::get_cmd();
1141 return chmap::get_data(
n);
1145 using chmap::register_command;
1146 using chmap::register_alias;
1148 using chmap::is_enabled;
1149 using chmap::command_failed_need_arg;
1157 void do_controller();
1159 void do_foreground();
1162 void do_benchmark();
1164 void do_save_quit();
1166 void do_ignore_replay_errors();
1168 void do_next_level();
1169 void do_choose_level();
1171 void do_turn_limit();
1175 void do_unsafe_lua();
1177 void do_set_alias();
1181 void do_control_dialog();
1186 void do_undiscover();
1192 void do_toggle_draw_coordinates();
1193 void do_toggle_draw_terrain_codes();
1194 void do_toggle_draw_num_of_bitmaps();
1195 void do_toggle_whiteboard();
1196 void do_whiteboard_options();
1200 return _(
"(D) — debug only, (N) — network only, (A) — admin only");
1203 using chat_command_handler::get_command_flags_description;
1206 std::string space(
" ");
1207 return (
c.has_flag(
'D') ? space +
_(
"(debug command)") :
"")
1208 + (
c.has_flag(
'N') ? space +
_(
"(network only)") :
"")
1209 + (
c.has_flag(
'A') ? space +
_(
"(admin only)") :
"")
1210 + (
c.has_flag(
'S') ? space +
_(
"(not during other events)") :
"");
1213 using map::is_enabled;
1217 || (
c.has_flag(
'N') && !menu_handler_.pc_.is_networked_mp())
1224 menu_handler_.add_chat_message(std::chrono::system_clock::now(), title, 0,
message);
1229 chat_command_handler::init_map();
1231 chmap::get_command(
"log")->flags =
"";
1232 chmap::get_command(
"version")->flags =
"";
1233 chmap::get_command(
"ignore")->flags =
"";
1234 chmap::get_command(
"friend")->flags =
"";
1235 chmap::get_command(
"remove")->flags =
"";
1237 chmap::set_cmd_prefix(
":");
1238 chmap::set_cmd_flag(
true);
1240 register_command(
"refresh", &console_handler::do_refresh,
_(
"Refresh gui."));
1241 register_command(
"droid", &console_handler::do_droid,
_(
"Switch a side to/from AI control."),
1245 _(
"[<side> [on/off/full]]\n“on” = enable but retain vision, “full” = as if it’s controlled by another player"));
1246 register_command(
"terrain", &console_handler::do_terrain,
_(
"Change terrain type of current hex"),
1248 _(
"<terrain type> [both|base|overlay]"),
"DS");
1249 register_command(
"idle", &console_handler::do_idle,
_(
"Switch a side to/from idle state."),
1253 _(
"command_idle^[<side> [on/off]]"));
1254 register_command(
"theme", &console_handler::do_theme,
_(
"Change the in-game theme."));
1255 register_command(
"control", &console_handler::do_control,
1256 _(
"Assign control of a side to a different player or observer."),
_(
"<side> <nickname>"),
"N");
1257 register_command(
"controller", &console_handler::do_controller,
_(
"Query the controller status of a side."),
1259 register_command(
"clear", &console_handler::do_clear,
_(
"Clear chat history."));
1260 register_command(
"foreground", &console_handler::do_foreground,
_(
"Debug foreground terrain."),
"",
"D");
1262 "layers", &console_handler::do_layers,
_(
"Debug layers from terrain under the mouse."),
"",
"D");
1263 register_command(
"fps", &console_handler::do_fps,
_(
"Display and log fps (Frames Per Second)."));
1264 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."));
1265 register_command(
"save", &console_handler::do_save,
_(
"Save game."));
1266 register_alias(
"save",
"w");
1267 register_command(
"quit", &console_handler::do_quit,
_(
"Quit game."));
1269 register_alias(
"quit",
"q!");
1270 register_command(
"save_quit", &console_handler::do_save_quit,
_(
"Save and quit."));
1271 register_alias(
"save_quit",
"wq");
1272 register_command(
"ignore_replay_errors", &console_handler::do_ignore_replay_errors,
_(
"Ignore replay errors."));
1273 register_command(
"nosaves", &console_handler::do_nosaves,
_(
"Disable autosaves."));
1274 register_command(
"next_level", &console_handler::do_next_level,
1275 _(
"Advance to the next scenario, or scenario identified by ‘id’"),
_(
"<id>"),
"DS");
1276 register_alias(
"next_level",
"n");
1277 register_command(
"choose_level", &console_handler::do_choose_level,
_(
"Choose next scenario"),
"",
"DS");
1278 register_alias(
"choose_level",
"cl");
1279 register_command(
"turn", &console_handler::do_turn,
1280 _(
"Change turn number (and time of day), or increase by one if no number is specified."),
_(
"[turn]"),
1282 register_command(
"turn_limit", &console_handler::do_turn_limit,
1283 _(
"Change turn limit, or turn the turn limit off if no number is specified or it’s −1."),
_(
"[limit]"),
1285 register_command(
"debug", &console_handler::do_debug,
_(
"Turn debug mode on."));
1286 register_command(
"nodebug", &console_handler::do_nodebug,
_(
"Turn debug mode off."),
"",
"D");
1288 "lua", &console_handler::do_lua,
_(
"Execute a Lua statement."),
_(
"<command>[;<command>...]"),
"DS");
1290 "unsafe_lua", &console_handler::do_unsafe_lua,
_(
"Grant higher privileges to Lua scripts."),
"",
"D");
1291 register_command(
"custom", &console_handler::do_custom,
_(
"Set the command used by the custom command hotkey"),
1292 _(
"<command>[;<command>...]"));
1293 register_command(
"give_control", &console_handler::do_control_dialog,
1294 _(
"Invoke a dialog allowing changing control of MP sides."),
"",
"N");
1295 register_command(
"inspect", &console_handler::do_inspect,
_(
"Launch the gamestate inspector"),
"",
"D");
1297 "alias", &console_handler::do_set_alias,
_(
"Set or show alias to a command"),
_(
"<name>[=<command>]"));
1299 "set_var", &console_handler::do_set_var,
_(
"Set a scenario variable."),
_(
"<var>=<value>"),
"DS");
1300 register_command(
"show_var", &console_handler::do_show_var,
_(
"Show a scenario variable."),
_(
"<var>"),
"D");
1301 register_command(
"unit", &console_handler::do_unit,
1303 _(
"Modify a unit variable. (Only top level keys are supported, and advances=<number>.)"),
1304 _(
"<var>=<value>"),
"DS");
1310 register_command(
"discover", &console_handler::do_discover,
_(
"Discover all units in help."),
"");
1311 register_command(
"undiscover", &console_handler::do_undiscover,
_(
"‘Undiscover’ all units in help."),
"");
1312 register_command(
"create", &console_handler::do_create,
_(
"Create a unit."),
_(
"<unit type id>"),
"DS");
1313 register_command(
"fog", &console_handler::do_fog,
_(
"Toggle fog for the current player."),
"",
"DS");
1314 register_command(
"shroud", &console_handler::do_shroud,
_(
"Toggle shroud for the current player."),
"",
"DS");
1315 register_command(
"gold", &console_handler::do_gold,
_(
"Give gold to the current player."),
_(
"<amount>"),
"DS");
1316 register_command(
"throw", &console_handler::do_event,
_(
"Fire a game event."),
_(
"<event name>"),
"DS");
1317 register_alias(
"throw",
"fire");
1318 register_command(
"show_coordinates", &console_handler::do_toggle_draw_coordinates,
1319 _(
"Toggle overlaying of x,y coordinates on hexes."));
1320 register_alias(
"show_coordinates",
"sc");
1321 register_command(
"show_terrain_codes", &console_handler::do_toggle_draw_terrain_codes,
1322 _(
"Toggle overlaying of terrain codes on hexes."));
1323 register_alias(
"show_terrain_codes",
"tc");
1324 register_command(
"show_num_of_bitmaps", &console_handler::do_toggle_draw_num_of_bitmaps,
1325 _(
"Toggle overlaying of number of bitmaps on hexes."));
1326 register_alias(
"show_num_of_bitmaps",
"bn");
1327 register_command(
"whiteboard", &console_handler::do_toggle_whiteboard,
_(
"Toggle planning mode."));
1328 register_alias(
"whiteboard",
"wb");
1330 "whiteboard_options", &console_handler::do_whiteboard_options,
_(
"Access whiteboard options dialog."));
1331 register_alias(
"whiteboard_options",
"wbo");
1333 if(
auto alias_list =
prefs::get().get_alias()) {
1334 for(
const auto& [key, value] : alias_list->attribute_range()) {
1335 register_alias(value, key);
1345 void menu_handler::send_chat_message(
const std::string&
message,
bool allies_only)
1350 auto now = std::chrono::system_clock::now();
1353 const int side = board().
is_observer() ? 0 : gui_->viewing_team().side();
1354 if(!board().is_observer()) {
1361 if(board().is_observer()) {
1364 cfg[
"to_sides"] = gui_->viewing_team().allied_human_teams();
1370 add_chat_message(now,
cfg[
"id"], side,
message,
1374 void menu_handler::do_search(
const std::string& new_search)
1376 if(new_search.empty() ==
false && new_search != last_search_)
1377 last_search_ = new_search;
1379 if(last_search_.empty())
1385 std::vector<std::string> args =
utils::split(last_search_,
',');
1386 if(args.size() == 2) {
1388 x = lexical_cast_default<int>(args[0], 0) - 1;
1389 y = lexical_cast_default<int>(args[1], 0) - 1;
1390 if(x >= 0 && x < pc_.get_map().w() && y >= 0 && y < pc_.get_map().h()) {
1403 loc.
x = (
loc.
x + 1) % pc_.get_map().w();
1405 loc.
y = (
loc.
y + 1) % pc_.get_map().h();
1408 if(!gui_->shrouded(
loc)) {
1411 const std::string& label_text =
label->text().str();
1417 if(!gui_->fogged(
loc)) {
1419 if(ui != pc_.get_units().end()) {
1420 const std::string&
unit_name = ui->name();
1422 if(!gui_->viewing_team().is_enemy(ui->side())
1423 || !ui->invisible(ui->get_location())) {
1435 last_search_hit_ =
loc;
1437 gui_->highlight_hex(
loc);
1442 symbols[
"search"] = last_search_;
1443 const std::string
msg =
VGETTEXT(
"Could not find label or unit "
1444 "containing the string ‘$search’.",
1450 void menu_handler::do_command(
const std::string& str)
1456 std::vector<std::string> menu_handler::get_commands_list()
1467 void console_handler::do_refresh()
1472 menu_handler_.gui_->create_buttons();
1473 menu_handler_.gui_->queue_rerender();
1476 void console_handler::do_droid()
1479 const std::string side_s = get_arg(1);
1480 std::string action = get_arg(2);
1481 std::transform(action.begin(), action.end(), action.begin(), tolower);
1483 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1484 const bool is_your_turn = menu_handler_.pc_.current_side() ==
static_cast<int>(menu_handler_.gui_->viewing_team().side());
1487 symbols[
"side"] = std::to_string(side);
1489 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1490 command_failed(
VGETTEXT(
"Can’t droid invalid side: ‘$side’.", symbols));
1492 }
else if(menu_handler_.board().get_team(side).is_network()) {
1493 command_failed(
VGETTEXT(
"Can’t droid networked side: ‘$side’.", symbols));
1495 }
else if(menu_handler_.board().get_team(side).is_local()) {
1496 bool changed =
false;
1498 const bool is_human = menu_handler_.board().get_team(side).is_human();
1499 const bool is_droid = menu_handler_.board().get_team(side).is_droid();
1500 const bool is_proxy_human = menu_handler_.board().get_team(side).is_proxy_human();
1501 const bool is_ai = menu_handler_.board().get_team(side).is_ai();
1503 if(action ==
"on") {
1504 if(is_ai && !is_your_turn) {
1505 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1508 if(!is_human || !is_droid) {
1509 menu_handler_.board().get_team(side).make_human();
1510 menu_handler_.board().get_team(side).make_droid();
1513 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1515 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: AI.", symbols));
1517 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already droided.", symbols));
1519 }
else if(action ==
"off") {
1520 if(is_ai && !is_your_turn) {
1521 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1524 if(!is_human || !is_proxy_human) {
1525 menu_handler_.board().get_team(side).make_human();
1526 menu_handler_.board().get_team(side).make_proxy_human();
1529 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1531 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: human.", symbols));
1533 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already not droided.", symbols));
1535 }
else if(action ==
"full") {
1537 command_failed(
_(
"It is not allowed to change a side from human to AI control when it’s not your turn."));
1540 if(!is_ai || !is_droid) {
1541 menu_handler_.board().get_team(side).make_ai();
1542 menu_handler_.board().get_team(side).make_droid();
1544 if(is_human || is_proxy_human) {
1545 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::ai}});
1547 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now fully controlled by: AI.", symbols));
1549 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ is already fully AI controlled.", symbols));
1551 }
else if(action ==
"") {
1552 if(is_ai && !is_your_turn) {
1553 command_failed(
_(
"It is not allowed to change a side from AI to human control when it’s not your turn."));
1556 if(is_ai || is_droid) {
1557 menu_handler_.board().get_team(side).make_human();
1558 menu_handler_.board().get_team(side).make_proxy_human();
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: human.", symbols));
1565 menu_handler_.board().get_team(side).make_human();
1566 menu_handler_.board().get_team(side).make_droid();
1569 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1571 print(get_cmd(),
VGETTEXT(
"Side ‘$side’ controller is now controlled by: AI.", symbols));
1574 print(get_cmd(),
VGETTEXT(
"Invalid action provided for side ‘$side’. Valid actions are: on, off, full.", symbols));
1577 if(team_num_ == side && changed) {
1579 psc->set_player_type_changed();
1583 command_failed(
VGETTEXT(
"Side ‘$side’ is not a human or AI player.", symbols));
1586 menu_handler_.textbox_info_.close();
1589 void console_handler::do_terrain()
1593 const std::string mode_str = get_arg(2);
1603 "mode_str", mode_str,
1608 void console_handler::do_idle()
1611 const std::string side_s = get_arg(1);
1612 const std::string action = get_arg(2);
1614 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1616 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1618 symbols[
"side"] = side_s;
1619 command_failed(
VGETTEXT(
"Can’t idle invalid side: ‘$side’.", symbols));
1621 }
else if(menu_handler_.board().get_team(side).is_network()) {
1623 symbols[
"side"] = std::to_string(side);
1624 command_failed(
VGETTEXT(
"Can’t idle networked side: ‘$side’.", symbols));
1626 }
else if(menu_handler_.board().get_team(side).is_local_ai()) {
1628 symbols[
"side"] = std::to_string(side);
1629 command_failed(
VGETTEXT(
"Can’t idle local ai side: ‘$side’.", symbols));
1631 }
else if(menu_handler_.board().get_team(side).is_local_human()) {
1632 if(menu_handler_.board().get_team(side).is_idle() ? action ==
" on" : action ==
" off") {
1636 menu_handler_.board().get_team(side).toggle_idle();
1637 if(team_num_ == side) {
1639 psc->set_player_type_changed();
1643 menu_handler_.textbox_info_.close();
1646 void console_handler::do_theme()
1651 void console_handler::do_control()
1654 if(!menu_handler_.pc_.is_networked_mp()) {
1658 const std::string side = get_arg(1);
1659 const std::string player = get_arg(2);
1660 if(player.empty()) {
1661 command_failed_need_arg(2);
1665 unsigned int side_num;
1667 side_num = lexical_cast<unsigned int>(side);
1669 const auto& teams = menu_handler_.pc_.get_teams();
1672 if(it_t == teams.end()) {
1674 symbols[
"side"] = side;
1675 command_failed(
VGETTEXT(
"Can’t change control of invalid side: ‘$side’.", symbols));
1678 side_num = it_t->side();
1682 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1684 symbols[
"side"] = side;
1685 command_failed(
VGETTEXT(
"Can’t change control of out-of-bounds side: ‘$side’.", symbols));
1689 menu_handler_.request_control_change(side_num, player);
1690 menu_handler_.textbox_info_.close();
1693 void console_handler::do_controller()
1695 const std::string side = get_arg(1);
1696 unsigned int side_num;
1698 side_num = lexical_cast<unsigned int>(side);
1701 symbols[
"side"] = side;
1702 command_failed(
VGETTEXT(
"Can’t query control of invalid side: ‘$side’.", symbols));
1706 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1708 symbols[
"side"] = side;
1709 command_failed(
VGETTEXT(
"Can’t query control of out-of-bounds side: ‘$side’.", symbols));
1714 if(!menu_handler_.board().get_team(side_num).is_proxy_human()) {
1718 if(menu_handler_.board().get_team(side_num).is_network()) {
1719 report +=
" (networked)";
1722 print(get_cmd(), report);
1725 void console_handler::do_clear()
1727 menu_handler_.gui_->get_chat_manager().clear_chat_messages();
1730 void console_handler::do_foreground()
1733 menu_handler_.gui_->invalidate_all();
1736 void console_handler::do_layers()
1738 display& disp = *(menu_handler_.gui_);
1752 if(menu_handler_.pc_.get_map().on_board_with_border(
loc)) {
1753 terrain_layers::display(disp,
loc);
1757 void console_handler::do_fps()
1762 void console_handler::do_benchmark()
1767 void console_handler::do_save()
1769 menu_handler_.pc_.do_consolesave(get_data());
1772 void console_handler::do_save_quit()
1778 void console_handler::do_quit()
1783 void console_handler::do_ignore_replay_errors()
1788 void console_handler::do_nosaves()
1793 void console_handler::do_next_level()
1798 void console_handler::do_choose_level()
1800 std::string
tag = menu_handler_.pc_.get_classification().get_tagname();
1801 std::vector<std::string> options;
1803 if(
tag !=
"multiplayer") {
1805 const std::string&
id = sc[
"id"];
1806 options.push_back(
id);
1807 if(
id == menu_handler_.gamedata().next_scenario()) {
1814 std::string scenario_id = menu_handler_.pc_.get_mp_settings().mp_scenario;
1815 if(
auto this_scenario = menu_handler_.game_config_.find_child(
tag,
"id", scenario_id)) {
1816 std::string addon_id = this_scenario[
"addon_id"].str();
1818 if(sc[
"addon_id"] == addon_id) {
1819 std::string
id = sc[
"id"];
1820 options.push_back(
id);
1821 if(
id == menu_handler_.gamedata().next_scenario()) {
1828 std::sort(options.begin(), options.end());
1829 int choice = std::distance(options.begin(), std::lower_bound(options.begin(), options.end(), next));
1841 if(std::size_t(choice) < options.size()) {
1846 void console_handler::do_turn()
1848 tod_manager& tod_man = menu_handler_.gamestate().tod_manager_;
1850 int turn = tod_man.
turn() + 1;
1851 const std::string&
data = get_data();
1853 turn = lexical_cast_default<int>(
data, 1);
1858 void console_handler::do_turn_limit()
1860 int limit = get_data().empty() ? -1 : lexical_cast_default<int>(get_data(), 1);
1864 void console_handler::do_debug()
1867 print(get_cmd(),
_(
"Debug mode activated!"));
1870 command_failed(
_(
"Debug mode not available in network games"));
1874 void console_handler::do_nodebug()
1877 print(get_cmd(),
_(
"Debug mode deactivated!"));
1882 void console_handler::do_lua()
1884 if(!menu_handler_.gamestate().lua_kernel_) {
1891 void console_handler::do_unsafe_lua()
1893 if(!menu_handler_.gamestate().lua_kernel_) {
1898 _(
"Executing Lua code in in this manner opens your computer to potential security breaches from any "
1899 "malicious add-ons or other programs you may have installed.\n\n"
1900 "Do not continue unless you really know what you are doing."), message::ok_cancel_buttons);
1903 print(get_cmd(),
_(
"Unsafe mode enabled!"));
1904 menu_handler_.gamestate().lua_kernel_->load_package();
1908 void console_handler::do_custom()
1913 void console_handler::do_set_alias()
1915 const std::string
data = get_data();
1917 const std::string alias(
data.begin(), j);
1918 if(j !=
data.end()) {
1919 const std::string command(j + 1,
data.end());
1920 if(!command.empty()) {
1921 register_alias(command, alias);
1925 register_alias(alias, alias);
1933 const std::string command = chmap::get_actual_cmd(alias);
1934 print(get_cmd(),
"'" + alias +
"'" +
" = " +
"'" + command +
"'");
1938 void console_handler::do_set_var()
1940 const std::string
data = get_data();
1942 command_failed_need_arg(1);
1947 if(j !=
data.end()) {
1948 const std::string name(
data.begin(), j);
1949 const std::string value(j + 1,
data.end());
1952 command_failed(
_(
"Variable not found"));
1956 void console_handler::do_show_var()
1961 void console_handler::do_inspect()
1964 gamestate_inspector::display(
1968 void console_handler::do_control_dialog()
1970 mp_change_control::display(menu_handler_);
1973 void console_handler::do_unit()
1981 if(
i == menu_handler_.pc_.get_units().end()) {
1983 symbols[
"unit"] = get_arg(1);
1985 "Debug command ‘unit: $unit’ failed: no unit selected or hovered over.",
1991 const std::string
data = get_data(1);
1993 if(parameters.size() < 2) {
1997 if(parameters[0] ==
"alignment") {
2001 symbols[
"alignment"] = get_arg(1);
2003 "Invalid alignment: ‘$alignment’, needs to be one of lawful, neutral, chaotic, or liminal.",
2013 "name", parameters[0],
2014 "value", parameters[1],
2019 void console_handler::do_discover()
2021 for(
const unit_type_data::unit_type_map::value_type&
i :
unit_types.
types()) {
2026 void console_handler::do_undiscover()
2029 _(
"Do you wish to clear all of your discovered units from help?"), message::yes_no_buttons);
2036 void console_handler::do_create()
2040 if(menu_handler_.pc_.get_map().on_board(
loc)) {
2043 command_failed(
_(
"Invalid unit type"));
2048 create_and_place(
loc, *ut);
2050 command_failed(
_(
"Invalid location"));
2054 void console_handler::do_fog()
2059 void console_handler::do_shroud()
2064 void console_handler::do_gold()
2069 void console_handler::do_event()
2074 void console_handler::do_toggle_draw_coordinates()
2077 menu_handler_.gui_->invalidate_all();
2079 void console_handler::do_toggle_draw_terrain_codes()
2082 menu_handler_.gui_->invalidate_all();
2085 void console_handler::do_toggle_draw_num_of_bitmaps()
2088 menu_handler_.gui_->invalidate_all();
2091 void console_handler::do_toggle_whiteboard()
2093 if(
const std::shared_ptr<wb::manager>& whiteb = menu_handler_.pc_.get_whiteboard()) {
2094 whiteb->set_active(!whiteb->is_active());
2095 if(whiteb->is_active()) {
2096 print(get_cmd(),
_(
"Planning mode activated!"));
2097 whiteb->print_help_once();
2099 print(get_cmd(),
_(
"Planning mode deactivated!"));
2104 void console_handler::do_whiteboard_options()
2106 if(menu_handler_.pc_.get_whiteboard()) {
2107 menu_handler_.pc_.get_whiteboard()->options_dlg();
2116 add_chat_message(std::chrono::system_clock::now(),
"wfl", 0, result.
to_debug_string());
2123 void menu_handler::user_command()
2128 void menu_handler::request_control_change(
int side_num,
const std::string& player)
2130 std::string side = std::to_string(side_num);
2131 if(board().get_team(side_num).is_local_human() && player ==
prefs::get().login()) {
2137 pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player", player}});
2141 void menu_handler::custom_command()
2144 do_command(command);
2148 void menu_handler::ai_formula()
2150 if(!pc_.is_networked_mp()) {
2155 void menu_handler::clear_messages()
2157 gui_->get_chat_manager().clear_chat_messages();
2162 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)
const std::string & save_id() const
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.
auto find(Container &container, const Value &value, const Projection &projection={})
@ 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.
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.