82 #define ERR_NG LOG_STREAM(err, log_engine)
83 #define LOG_NG LOG_STREAM(info, log_engine)
133 gui2::dialogs::statistics_dialog::display(
pc_.
statistics(),
board().get_team(side_num));
152 const std::string& input_name
171 symbols[
"msg"] =
e.what();
172 const std::string
msg =
VGETTEXT(
"Could not save the map: $msg", symbols);
179 gui2::dialogs::preferences_dialog::display();
187 c[
"name"] =
"prototype of chat log";
201 ?
board().is_observer()
202 ?
_(
"Send to observers only")
203 :
_(
"Send to allies only")
221 if(
board().is_observer()) {
240 std::map<const unit_type*, t_string> sample_units;
244 std::vector<t_string> unknown_units;
245 for(
const auto&
recruit : recruits) {
249 unknown_units.emplace_back(
recruit);
257 if(!unknown_units.empty()) {
262 const auto message =
VNGETTEXT(
"Error: there’s an unknown unit type on your recruit list: $unknown_ids",
263 "Error: there are several unknown unit types on your recruit list: $unknown_ids",
264 unknown_units.size(),
269 if(sample_units.empty()) {
283 do_recruit(
type->id(), side_num, recruit_hex);
287 void menu_handler::repeat_recruit(
int side_num,
const map_location& last_hex)
289 const std::string& last_recruit = board().get_team(side_num).last_recruit();
290 if(last_recruit.empty() ==
false) {
292 do_recruit(last_recruit, side_num, recruit_hex);
301 team& current_team = board().get_team(side_num);
304 if(u_type ==
nullptr) {
305 return _(
"Internal error. Please report this as a bug! Details:\n")
306 +
"menu_handler::can_recruit: u_type == nullptr for " + name;
311 return VGETTEXT(
"You cannot recruit a $unit_type_name at this time.",
319 wb_gold = (pc_.get_whiteboard() ? pc_.get_whiteboard()->get_spent_gold_for(side_num) : 0);
321 if(u_type->
cost() > current_team.
gold() - wb_gold)
325 return _(
"At this point in your plan, you will not have enough gold to recruit this unit.");
327 return _(
"You do not have enough gold to recruit this unit.");
344 bool menu_handler::do_recruit(
const std::string& name,
int side_num,
map_location& loc)
347 const std::string res = can_recruit(name, side_num, loc, recruited_from);
348 team& current_team = board().get_team(side_num);
350 if(res.empty() && (!pc_.get_whiteboard() || !pc_.get_whiteboard()->save_recruit(name, side_num, loc))) {
358 }
else if(res.empty()) {
369 if(pc_.get_disallow_recall()) {
374 team& current_team = board().get_team(side_num);
376 std::vector<unit_const_ptr> recall_list_team;
384 DBG_WB <<
"menu_handler::recall: Contents of wb-modified recall list:";
391 _(
"There are no troops available to recall.\n(You must have veteran survivors from a previous scenario.)"));
394 if(recall_list_team.empty()) {
417 unit_cost = recall_list_team[res]->recall_cost();
420 int wb_gold = pc_.get_whiteboard() ? pc_.get_whiteboard()->get_spent_gold_for(side_num) : 0;
421 if(current_team.
gold() - wb_gold < unit_cost) {
423 i18n_symbols[
"cost"] = std::to_string(unit_cost);
424 std::string
msg =
VNGETTEXT(
"You must have at least 1 gold piece to recall a unit.",
425 "You must have at least $cost gold pieces to recall this unit.", unit_cost, i18n_symbols);
430 LOG_NG <<
"recall index: " << res;
447 if(!pc_.get_whiteboard()
448 || !pc_.get_whiteboard()->save_recall(*recall_list_team[res].get(), side_num, recall_location)) {
454 ERR_NG <<
"menu_handler::recall(): Unit does not exist in the recall list.";
460 void menu_handler::show_enemy_moves(
bool ignore_units,
int side_num)
467 gui_->unhighlight_reach();
470 for(
auto& u : pc_.get_units()) {
471 bool invisible = u.invisible(u.get_location());
473 if(board().get_team(side_num).is_enemy(u.side()) && !gui_->fogged(u.get_location()) && !u.incapacitated()
477 =
pathfind::paths(u,
false,
true, gui_->viewing_team(), 0,
false, ignore_units);
479 gui_->highlight_another_reach(
path, hex_under_mouse);
483 gui_->invalidate(u.get_location());
488 const bool selected_hex_has_unit = mh.
hex_hosts_unit(hex_under_mouse);
490 if(selected_hex_has_unit) {
499 void menu_handler::toggle_shroud_updates(
int side_num)
501 team& current_team = board().get_team(side_num);
505 update_shroud_now(side_num);
512 void menu_handler::update_shroud_now(
int )
521 bool units_alive(
int side_num,
const unit_map& units)
523 for(
auto&
unit : units) {
532 bool partmoved_units(
533 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
535 for(
auto&
unit : units) {
550 int side_num,
const unit_map& units,
const game_board& board,
const std::shared_ptr<wb::manager>& whiteb)
552 for(
auto&
unit : units) {
555 && (!whiteb || !whiteb->unit_has_actions(&
unit))) {
565 bool menu_handler::end_turn(
int side_num)
570 reason =
_(
"You cannot end your turn yet!");
576 std::size_t team_num =
static_cast<std::size_t
>(side_num - 1);
577 if(team_num < pc_.get_teams().size() && pc_.get_teams()[team_num].no_turn_confirmation()) {
582 && (!pc_.get_whiteboard() || !pc_.get_whiteboard()->current_side_has_actions())
583 && units_alive(side_num, pc_.get_units())) {
585 _(
"You have not started your turn yet. Do you really want to end your turn?"),
592 else if(
prefs::get().yellow_confirm() && partmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
594 _(
"Some units have movement left. Do you really want to end your turn?"),
601 else if(
prefs::get().green_confirm() && unmoved_units(side_num, pc_.get_units(), board(), pc_.get_whiteboard())) {
603 _(
"Some units have not moved. Do you really want to end your turn?"),
612 if(pc_.get_whiteboard() && !pc_.get_whiteboard()->allow_end_turn()) {
619 void menu_handler::goto_leader(
int side_num)
622 if(
i != pc_.get_units().end() &&
i->is_visible_to_team(gui_->viewing_team(),
false)) {
627 void menu_handler::unit_description()
630 if(un != pc_.get_units().end()) {
638 if(pc_.get_map().on_board(loc) ==
false || gui_->shrouded(loc)) {
647 void menu_handler::rename_unit()
650 if(un == pc_.get_units().end() || gui_->viewing_team().side() != un->side()) {
654 if(un->unrenamable()) {
658 std::string name = un->name();
659 const std::string title(
_(
"Rename Unit"));
660 const std::string
label(
_(
"Name:"));
662 if(gui2::dialogs::edit_text::execute(title,
label, name)) {
665 gui_->invalidate_unit();
671 const mouse_handler& mousehandler = pc_.get_mouse_handler_base();
672 const bool see_all = gui_->show_everything() || (pc_.is_replay() && pc_.get_replay_controller()->see_all());
675 if(res != pc_.get_units().end()) {
686 typedef std::tuple<const unit_type*, unit_race::GENDER, std::string> type_gender_variation;
695 type_gender_variation choose_unit()
708 const std::string& ut_id = create_dlg.
choice();
711 ERR_NG <<
"Create unit dialog returned nonexistent or unusable unit_type id '" << ut_id <<
"'.";
724 return type_gender_variation(utp, gender, create_dlg.
variation());
737 const std::string& variation =
"")
745 "variation", variation,
760 assert(gui_ !=
nullptr);
763 if(
const auto& [
type, gender, variation] = choose_unit();
type !=
nullptr) {
765 create_and_place(*gui_, pc_.get_map(), pc_.get_units(), destination, *
type, gender, variation);
773 if(
i == pc_.get_units().end()) {
774 if(!pc_.get_map().is_village(loc)) {
782 if(
team >
static_cast<int>(pc_.get_teams().size())) {
787 int side =
i->side();
789 if(side >
static_cast<int>(pc_.get_teams().size())) {
794 if(pc_.get_map().is_village(loc)) {
806 void menu_handler::label_terrain(
mouse_handler& mousehandler,
bool team_only)
809 if(pc_.get_map().on_board(loc) ==
false) {
813 const terrain_label* old_label = gui_->labels().get_label(loc);
814 std::string
label = old_label ? old_label->
text() :
"";
816 if(gui2::dialogs::edit_label::execute(
label, team_only)) {
817 std::string team_name;
821 team_name = gui_->labels().team_name();
825 const terrain_label* res = gui_->labels().set_label(loc,
label, gui_->viewing_team_index(), team_name, color);
832 void menu_handler::clear_labels()
834 if(!board().is_observer()) {
837 _(
"Are you sure you want to clear map labels?"),
842 gui_->labels().clear(gui_->current_team_name(),
false);
848 void menu_handler::label_settings()
850 if(gui2::dialogs::label_settings::execute(board())) {
851 gui_->labels().recalculate_labels();
858 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
860 if(
i == pc_.get_units().end() || !
i->move_interrupted()) {
864 move_unit_to_loc(
i,
i->get_interrupted_move(),
true, side_num, mousehandler);
873 assert(ui != pc_.get_units().end());
877 if(route.
steps.empty()) {
881 assert(route.
steps.front() == ui->get_location());
883 gui_->set_route(&route);
884 gui_->unhighlight_reach();
887 LOG_NG <<
"move_unit_to_loc " << route.
steps.front() <<
" to " << route.
steps.back();
892 gui_->set_route(
nullptr);
893 gui_->invalidate_game_status();
902 bool wait_blocker_move =
true;
903 std::set<map_location> fully_moved;
906 bool blocked_unit =
false;
909 blocked_unit =
false;
910 for(
auto&
unit : pc_.get_units()) {
918 if(goto_loc == current_loc) {
923 if(!pc_.get_map().on_board(goto_loc)) {
928 if(fully_moved.count(current_loc)) {
934 if(route.
steps.size() <= 1) {
935 fully_moved.insert(current_loc);
941 pathfind::marked_route::mark_map::const_iterator
w = route.
marks.begin();
942 for(;
w != route.
marks.end(); ++
w) {
943 if(
w->second.turns == 1) {
944 next_stop =
w->first;
949 if(next_stop == current_loc) {
950 fully_moved.insert(current_loc);
956 if(pc_.get_units().count(next_stop)) {
958 if(wait_blocker_move)
962 gui_->set_route(&route);
965 LOG_NG <<
"execute goto from " << route.
steps.front() <<
" to " << route.
steps.back();
972 wait_blocker_move =
true;
976 if(!change && wait_blocker_move) {
978 wait_blocker_move =
false;
981 }
while(change && blocked_unit);
984 gui_->set_route(
nullptr);
985 gui_->invalidate_game_status();
988 void menu_handler::toggle_ellipses()
991 gui_->invalidate_all();
994 void menu_handler::toggle_grid()
997 gui_->invalidate_all();
1000 void menu_handler::unit_hold_position(
mouse_handler& mousehandler,
int side_num)
1003 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1004 un->toggle_hold_position();
1009 if(un->hold_position()) {
1018 if(un != pc_.get_units().end() && un->side() == side_num && un->movement_left() >= 0) {
1019 un->toggle_user_end_turn();
1024 if(un->user_end_turn()) {
1036 void menu_handler::search()
1038 std::ostringstream
msg;
1040 if(last_search_hit_.valid()) {
1041 msg <<
" [" << last_search_ <<
"]";
1047 void menu_handler::do_speak()
1051 chat_handler::do_speak(
1052 textbox_info_.box()->text(), textbox_info_.check() !=
nullptr ? textbox_info_.check()->checked() :
false);
1055 void menu_handler::add_chat_message(
const std::time_t& time,
1056 const std::string& speaker,
1058 const std::string& message,
1061 gui_->get_chat_manager().add_chat_message(time, speaker, side, message,
type,
false);
1088 using chmap::get_commands_list;
1089 using chmap::command_failed;
1095 chat_command_handler::command_handler
h,
1096 const std::string&
help =
"",
1097 const std::string& usage =
"",
1098 const std::string& flags =
"")
1100 chmap::register_command(cmd,
h,
help, usage, flags +
"N");
1105 chmap::register_alias(to_cmd, cmd);
1110 return chmap::get_arg(
i);
1115 return chmap::get_cmd();
1120 return chmap::get_data(
n);
1124 using chmap::register_command;
1125 using chmap::register_alias;
1127 using chmap::is_enabled;
1128 using chmap::command_failed_need_arg;
1136 void do_controller();
1138 void do_foreground();
1141 void do_benchmark();
1143 void do_save_quit();
1145 void do_ignore_replay_errors();
1147 void do_next_level();
1148 void do_choose_level();
1150 void do_turn_limit();
1154 void do_unsafe_lua();
1156 void do_set_alias();
1160 void do_control_dialog();
1165 void do_undiscover();
1171 void do_toggle_draw_coordinates();
1172 void do_toggle_draw_terrain_codes();
1173 void do_toggle_draw_num_of_bitmaps();
1174 void do_toggle_whiteboard();
1175 void do_whiteboard_options();
1179 return _(
"(D) — debug only, (N) — network only, (A) — admin only");
1182 using chat_command_handler::get_command_flags_description;
1185 std::string space(
" ");
1186 return (
c.has_flag(
'D') ? space +
_(
"(debug command)") :
"")
1187 + (
c.has_flag(
'N') ? space +
_(
"(network only)") :
"")
1188 + (
c.has_flag(
'A') ? space +
_(
"(admin only)") :
"")
1189 + (
c.has_flag(
'S') ? space +
_(
"(not during other events)") :
"");
1192 using map::is_enabled;
1196 || (
c.has_flag(
'N') && !menu_handler_.pc_.is_networked_mp())
1201 void print(
const std::string& title,
const std::string& message)
1203 menu_handler_.add_chat_message(std::time(
nullptr), title, 0, message);
1208 chat_command_handler::init_map();
1210 chmap::get_command(
"log")->flags =
"";
1211 chmap::get_command(
"version")->flags =
"";
1212 chmap::get_command(
"ignore")->flags =
"";
1213 chmap::get_command(
"friend")->flags =
"";
1214 chmap::get_command(
"remove")->flags =
"";
1216 chmap::set_cmd_prefix(
":");
1217 chmap::set_cmd_flag(
true);
1219 register_command(
"refresh", &console_handler::do_refresh,
_(
"Refresh gui."));
1220 register_command(
"droid", &console_handler::do_droid,
_(
"Switch a side to/from AI control."),
1224 _(
"[<side> [on/off/full]]\n“on” = enable but retain vision, “full” = as if it’s controlled by another player"));
1225 register_command(
"terrain", &console_handler::do_terrain,
_(
"Change terrain type of current hex"),
1227 _(
"<terrain type> [both|base|overlay]"),
"DS");
1228 register_command(
"idle", &console_handler::do_idle,
_(
"Switch a side to/from idle state."),
1232 _(
"command_idle^[<side> [on/off]]"));
1233 register_command(
"theme", &console_handler::do_theme,
_(
"Change the in-game theme."));
1234 register_command(
"control", &console_handler::do_control,
1235 _(
"Assign control of a side to a different player or observer."),
_(
"<side> <nickname>"),
"N");
1236 register_command(
"controller", &console_handler::do_controller,
_(
"Query the controller status of a side."),
1238 register_command(
"clear", &console_handler::do_clear,
_(
"Clear chat history."));
1239 register_command(
"foreground", &console_handler::do_foreground,
_(
"Debug foreground terrain."),
"",
"D");
1241 "layers", &console_handler::do_layers,
_(
"Debug layers from terrain under the mouse."),
"",
"D");
1242 register_command(
"fps", &console_handler::do_fps,
_(
"Display and log fps (Frames Per Second)."));
1243 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."));
1244 register_command(
"save", &console_handler::do_save,
_(
"Save game."));
1245 register_alias(
"save",
"w");
1246 register_command(
"quit", &console_handler::do_quit,
_(
"Quit game."));
1248 register_alias(
"quit",
"q!");
1249 register_command(
"save_quit", &console_handler::do_save_quit,
_(
"Save and quit."));
1250 register_alias(
"save_quit",
"wq");
1251 register_command(
"ignore_replay_errors", &console_handler::do_ignore_replay_errors,
_(
"Ignore replay errors."));
1252 register_command(
"nosaves", &console_handler::do_nosaves,
_(
"Disable autosaves."));
1253 register_command(
"next_level", &console_handler::do_next_level,
1254 _(
"Advance to the next scenario, or scenario identified by 'id'"),
_(
"<id>"),
"DS");
1255 register_alias(
"next_level",
"n");
1256 register_command(
"choose_level", &console_handler::do_choose_level,
_(
"Choose next scenario"),
"",
"DS");
1257 register_alias(
"choose_level",
"cl");
1258 register_command(
"turn", &console_handler::do_turn,
1259 _(
"Change turn number (and time of day), or increase by one if no number is specified."),
_(
"[turn]"),
1261 register_command(
"turn_limit", &console_handler::do_turn_limit,
1262 _(
"Change turn limit, or turn the turn limit off if no number is specified or it’s −1."),
_(
"[limit]"),
1264 register_command(
"debug", &console_handler::do_debug,
_(
"Turn debug mode on."));
1265 register_command(
"nodebug", &console_handler::do_nodebug,
_(
"Turn debug mode off."),
"",
"D");
1267 "lua", &console_handler::do_lua,
_(
"Execute a Lua statement."),
_(
"<command>[;<command>...]"),
"DS");
1269 "unsafe_lua", &console_handler::do_unsafe_lua,
_(
"Grant higher privileges to Lua scripts."),
"",
"D");
1270 register_command(
"custom", &console_handler::do_custom,
_(
"Set the command used by the custom command hotkey"),
1271 _(
"<command>[;<command>...]"));
1272 register_command(
"give_control", &console_handler::do_control_dialog,
1273 _(
"Invoke a dialog allowing changing control of MP sides."),
"",
"N");
1274 register_command(
"inspect", &console_handler::do_inspect,
_(
"Launch the gamestate inspector"),
"",
"D");
1276 "alias", &console_handler::do_set_alias,
_(
"Set or show alias to a command"),
_(
"<name>[=<command>]"));
1278 "set_var", &console_handler::do_set_var,
_(
"Set a scenario variable."),
_(
"<var>=<value>"),
"DS");
1279 register_command(
"show_var", &console_handler::do_show_var,
_(
"Show a scenario variable."),
_(
"<var>"),
"D");
1280 register_command(
"unit", &console_handler::do_unit,
1282 _(
"Modify a unit variable. (Only top level keys are supported, and advances=<number>.)"),
1283 _(
"<var>=<value>"),
"DS");
1289 register_command(
"discover", &console_handler::do_discover,
_(
"Discover all units in help."),
"");
1290 register_command(
"undiscover", &console_handler::do_undiscover,
_(
"'Undiscover' all units in help."),
"");
1291 register_command(
"create", &console_handler::do_create,
_(
"Create a unit."),
_(
"<unit type id>"),
"DS");
1292 register_command(
"fog", &console_handler::do_fog,
_(
"Toggle fog for the current player."),
"",
"DS");
1293 register_command(
"shroud", &console_handler::do_shroud,
_(
"Toggle shroud for the current player."),
"",
"DS");
1294 register_command(
"gold", &console_handler::do_gold,
_(
"Give gold to the current player."),
_(
"<amount>"),
"DS");
1295 register_command(
"throw", &console_handler::do_event,
_(
"Fire a game event."),
_(
"<event name>"),
"DS");
1296 register_alias(
"throw",
"fire");
1297 register_command(
"show_coordinates", &console_handler::do_toggle_draw_coordinates,
1298 _(
"Toggle overlaying of x,y coordinates on hexes."));
1299 register_alias(
"show_coordinates",
"sc");
1300 register_command(
"show_terrain_codes", &console_handler::do_toggle_draw_terrain_codes,
1301 _(
"Toggle overlaying of terrain codes on hexes."));
1302 register_alias(
"show_terrain_codes",
"tc");
1303 register_command(
"show_num_of_bitmaps", &console_handler::do_toggle_draw_num_of_bitmaps,
1304 _(
"Toggle overlaying of number of bitmaps on hexes."));
1305 register_alias(
"show_num_of_bitmaps",
"bn");
1306 register_command(
"whiteboard", &console_handler::do_toggle_whiteboard,
_(
"Toggle planning mode."));
1307 register_alias(
"whiteboard",
"wb");
1309 "whiteboard_options", &console_handler::do_whiteboard_options,
_(
"Access whiteboard options dialog."));
1310 register_alias(
"whiteboard_options",
"wbo");
1312 if(
auto alias_list =
prefs::get().get_alias()) {
1314 register_alias(a.second, a.first);
1324 void menu_handler::send_chat_message(
const std::string& message,
bool allies_only)
1328 cfg[
"message"] = message;
1329 const std::time_t time = ::std::time(
nullptr);
1330 std::stringstream ss;
1332 cfg[
"time"] = ss.str();
1334 const int side = board().
is_observer() ? 0 : gui_->viewing_team().side();
1335 if(!board().is_observer()) {
1342 if(board().is_observer()) {
1345 cfg[
"to_sides"] = gui_->viewing_team().allied_human_teams();
1351 add_chat_message(time, cfg[
"id"], side, message,
1355 void menu_handler::do_search(
const std::string& new_search)
1357 if(new_search.empty() ==
false && new_search != last_search_)
1358 last_search_ = new_search;
1360 if(last_search_.empty())
1366 std::vector<std::string> args =
utils::split(last_search_,
',');
1367 if(args.size() == 2) {
1369 x = lexical_cast_default<int>(args[0], 0) - 1;
1370 y = lexical_cast_default<int>(args[1], 0) - 1;
1371 if(x >= 0 && x < pc_.get_map().w() && y >= 0 && y < pc_.get_map().h()) {
1377 if(loc.
valid() ==
false) {
1378 loc =
map_location(pc_.get_map().w() - 1, pc_.get_map().h() - 1);
1384 loc.
x = (loc.
x + 1) % pc_.get_map().w();
1386 loc.
y = (loc.
y + 1) % pc_.get_map().h();
1389 if(!gui_->shrouded(loc)) {
1392 std::string label_text =
label->text().str();
1393 if(std::search(label_text.begin(), label_text.end(), last_search_.begin(), last_search_.end(),
1395 != label_text.end()) {
1401 if(!gui_->fogged(loc)) {
1403 if(ui != pc_.get_units().end()) {
1404 const std::string name = ui->name();
1408 if(!gui_->viewing_team().is_enemy(ui->side())
1409 || !ui->invisible(ui->get_location())) {
1421 last_search_hit_ = loc;
1423 gui_->highlight_hex(loc);
1428 symbols[
"search"] = last_search_;
1429 const std::string
msg =
VGETTEXT(
"Could not find label or unit "
1430 "containing the string ‘$search’.",
1436 void menu_handler::do_command(
const std::string& str)
1442 std::vector<std::string> menu_handler::get_commands_list()
1453 void console_handler::do_refresh()
1458 menu_handler_.gui_->create_buttons();
1459 menu_handler_.gui_->queue_rerender();
1462 void console_handler::do_droid()
1465 const std::string side_s = get_arg(1);
1466 std::string action = get_arg(2);
1467 std::transform(action.begin(), action.end(), action.begin(), tolower);
1469 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1470 const bool is_your_turn = menu_handler_.pc_.current_side() ==
static_cast<int>(menu_handler_.gui_->viewing_team().side());
1473 symbols[
"side"] = std::to_string(side);
1475 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1476 command_failed(
VGETTEXT(
"Can't droid invalid side: '$side'.", symbols));
1478 }
else if(menu_handler_.board().get_team(side).is_network()) {
1479 command_failed(
VGETTEXT(
"Can't droid networked side: '$side'.", symbols));
1481 }
else if(menu_handler_.board().get_team(side).is_local()) {
1482 bool changed =
false;
1484 const bool is_human = menu_handler_.board().get_team(side).is_human();
1485 const bool is_droid = menu_handler_.board().get_team(side).is_droid();
1486 const bool is_proxy_human = menu_handler_.board().get_team(side).is_proxy_human();
1487 const bool is_ai = menu_handler_.board().get_team(side).is_ai();
1489 if(action ==
"on") {
1490 if(is_ai && !is_your_turn) {
1491 command_failed(
_(
"It is not allowed to change a side from AI to human control when it's not your turn."));
1494 if(!is_human || !is_droid) {
1495 menu_handler_.board().get_team(side).make_human();
1496 menu_handler_.board().get_team(side).make_droid();
1499 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1501 print(get_cmd(),
VGETTEXT(
"Side '$side' controller is now controlled by: AI.", symbols));
1503 print(get_cmd(),
VGETTEXT(
"Side '$side' is already droided.", symbols));
1505 }
else if(action ==
"off") {
1506 if(is_ai && !is_your_turn) {
1507 command_failed(
_(
"It is not allowed to change a side from AI to human control when it's not your turn."));
1510 if(!is_human || !is_proxy_human) {
1511 menu_handler_.board().get_team(side).make_human();
1512 menu_handler_.board().get_team(side).make_proxy_human();
1515 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1517 print(get_cmd(),
VGETTEXT(
"Side '$side' controller is now controlled by: human.", symbols));
1519 print(get_cmd(),
VGETTEXT(
"Side '$side' is already not droided.", symbols));
1521 }
else if(action ==
"full") {
1523 command_failed(
_(
"It is not allowed to change a side from human to AI control when it's not your turn."));
1526 if(!is_ai || !is_droid) {
1527 menu_handler_.board().get_team(side).make_ai();
1528 menu_handler_.board().get_team(side).make_droid();
1530 if(is_human || is_proxy_human) {
1531 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::ai}});
1533 print(get_cmd(),
VGETTEXT(
"Side '$side' controller is now fully controlled by: AI.", symbols));
1535 print(get_cmd(),
VGETTEXT(
"Side '$side' is already fully AI controlled.", symbols));
1537 }
else if(action ==
"") {
1538 if(is_ai && !is_your_turn) {
1539 command_failed(
_(
"It is not allowed to change a side from AI to human control when it's not your turn."));
1542 if(is_ai || is_droid) {
1543 menu_handler_.board().get_team(side).make_human();
1544 menu_handler_.board().get_team(side).make_proxy_human();
1547 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1549 print(get_cmd(),
VGETTEXT(
"Side '$side' controller is now controlled by: human.", symbols));
1551 menu_handler_.board().get_team(side).make_human();
1552 menu_handler_.board().get_team(side).make_droid();
1555 menu_handler_.pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player",
prefs::get().
login(),
"to", side_controller::human}});
1557 print(get_cmd(),
VGETTEXT(
"Side '$side' controller is now controlled by: AI.", symbols));
1560 print(get_cmd(),
VGETTEXT(
"Invalid action provided for side '$side'. Valid actions are: on, off, full.", symbols));
1563 if(team_num_ == side && changed) {
1565 psc->set_player_type_changed();
1569 command_failed(
VGETTEXT(
"Side '$side' is not a human or AI player.", symbols));
1572 menu_handler_.textbox_info_.close();
1575 void console_handler::do_terrain()
1579 const std::string mode_str = get_arg(2);
1589 "mode_str", mode_str,
1594 void console_handler::do_idle()
1597 const std::string side_s = get_arg(1);
1598 const std::string action = get_arg(2);
1600 const unsigned int side = side_s.empty() ? team_num_ : lexical_cast_default<unsigned int>(side_s);
1602 if(side < 1 || side > menu_handler_.pc_.get_teams().size()) {
1604 symbols[
"side"] = side_s;
1605 command_failed(
VGETTEXT(
"Can't idle invalid side: '$side'.", symbols));
1607 }
else if(menu_handler_.board().get_team(side).is_network()) {
1609 symbols[
"side"] = std::to_string(side);
1610 command_failed(
VGETTEXT(
"Can't idle networked side: '$side'.", symbols));
1612 }
else if(menu_handler_.board().get_team(side).is_local_ai()) {
1614 symbols[
"side"] = std::to_string(side);
1615 command_failed(
VGETTEXT(
"Can't idle local ai side: '$side'.", symbols));
1617 }
else if(menu_handler_.board().get_team(side).is_local_human()) {
1618 if(menu_handler_.board().get_team(side).is_idle() ? action ==
" on" : action ==
" off") {
1622 menu_handler_.board().get_team(side).toggle_idle();
1623 if(team_num_ == side) {
1625 psc->set_player_type_changed();
1629 menu_handler_.textbox_info_.close();
1632 void console_handler::do_theme()
1646 return t.save_id() == save_id_;
1652 void console_handler::do_control()
1655 if(!menu_handler_.pc_.is_networked_mp()) {
1659 const std::string side = get_arg(1);
1660 const std::string player = get_arg(2);
1661 if(player.empty()) {
1662 command_failed_need_arg(2);
1666 unsigned int side_num;
1668 side_num = lexical_cast<unsigned int>(side);
1670 const auto& teams = menu_handler_.pc_.get_teams();
1671 const auto it_t = std::find_if(teams.begin(), teams.end(),
save_id_matches(side));
1673 if(it_t == teams.end()) {
1675 symbols[
"side"] = side;
1676 command_failed(
VGETTEXT(
"Can't change control of invalid side: '$side'.", symbols));
1679 side_num = it_t->side();
1683 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1685 symbols[
"side"] = side;
1686 command_failed(
VGETTEXT(
"Can't change control of out-of-bounds side: '$side'.", symbols));
1690 menu_handler_.request_control_change(side_num, player);
1691 menu_handler_.textbox_info_.close();
1694 void console_handler::do_controller()
1696 const std::string side = get_arg(1);
1697 unsigned int side_num;
1699 side_num = lexical_cast<unsigned int>(side);
1702 symbols[
"side"] = side;
1703 command_failed(
VGETTEXT(
"Can't query control of invalid side: '$side'.", symbols));
1707 if(side_num < 1 || side_num > menu_handler_.pc_.get_teams().size()) {
1709 symbols[
"side"] = side;
1710 command_failed(
VGETTEXT(
"Can't query control of out-of-bounds side: '$side'.", symbols));
1715 if(!menu_handler_.board().get_team(side_num).is_proxy_human()) {
1719 if(menu_handler_.board().get_team(side_num).is_network()) {
1720 report +=
" (networked)";
1723 print(get_cmd(), report);
1726 void console_handler::do_clear()
1728 menu_handler_.gui_->get_chat_manager().clear_chat_messages();
1731 void console_handler::do_foreground()
1734 menu_handler_.gui_->invalidate_all();
1737 void console_handler::do_layers()
1739 display& disp = *(menu_handler_.gui_);
1754 gui2::dialogs::terrain_layers::display(disp, loc);
1758 void console_handler::do_fps()
1763 void console_handler::do_benchmark()
1768 void console_handler::do_save()
1770 menu_handler_.pc_.do_consolesave(get_data());
1773 void console_handler::do_save_quit()
1779 void console_handler::do_quit()
1784 void console_handler::do_ignore_replay_errors()
1789 void console_handler::do_nosaves()
1794 void console_handler::do_next_level()
1799 void console_handler::do_choose_level()
1801 std::string tag = menu_handler_.pc_.get_classification().get_tagname();
1802 std::vector<std::string> options;
1804 if(tag !=
"multiplayer") {
1806 const std::string&
id = sc[
"id"];
1807 options.push_back(
id);
1808 if(
id == menu_handler_.gamedata().next_scenario()) {
1815 std::string scenario_id = menu_handler_.pc_.get_mp_settings().mp_scenario;
1816 if(
auto this_scenario = menu_handler_.game_config_.find_child(tag,
"id", scenario_id)) {
1817 std::string addon_id = this_scenario[
"addon_id"].str();
1819 if(sc[
"addon_id"] == addon_id) {
1820 std::string
id = sc[
"id"];
1821 options.push_back(
id);
1822 if(
id == menu_handler_.gamedata().next_scenario()) {
1829 std::sort(options.begin(), options.end());
1830 int choice = std::distance(options.begin(), std::lower_bound(options.begin(), options.end(), next));
1842 if(std::size_t(choice) < options.size()) {
1847 void console_handler::do_turn()
1849 tod_manager& tod_man = menu_handler_.gamestate().tod_manager_;
1851 int turn = tod_man.
turn() + 1;
1852 const std::string&
data = get_data();
1854 turn = lexical_cast_default<int>(
data, 1);
1859 void console_handler::do_turn_limit()
1861 int limit = get_data().empty() ? -1 : lexical_cast_default<int>(get_data(), 1);
1865 void console_handler::do_debug()
1868 print(get_cmd(),
_(
"Debug mode activated!"));
1871 command_failed(
_(
"Debug mode not available in network games"));
1875 void console_handler::do_nodebug()
1878 print(get_cmd(),
_(
"Debug mode deactivated!"));
1883 void console_handler::do_lua()
1885 if(!menu_handler_.gamestate().lua_kernel_) {
1892 void console_handler::do_unsafe_lua()
1894 if(!menu_handler_.gamestate().lua_kernel_) {
1899 _(
"Executing Lua code in in this manner opens your computer to potential security breaches from any "
1900 "malicious add-ons or other programs you may have installed.\n\n"
1904 print(get_cmd(),
_(
"Unsafe mode enabled!"));
1905 menu_handler_.gamestate().lua_kernel_->load_package();
1909 void console_handler::do_custom()
1914 void console_handler::do_set_alias()
1916 const std::string
data = get_data();
1917 const std::string::const_iterator j = std::find(
data.begin(),
data.end(),
'=');
1918 const std::string alias(
data.begin(), j);
1919 if(j !=
data.end()) {
1920 const std::string command(j + 1,
data.end());
1921 if(!command.empty()) {
1922 register_alias(command, alias);
1926 register_alias(alias, alias);
1934 const std::string command = chmap::get_actual_cmd(alias);
1935 print(get_cmd(),
"'" + alias +
"'" +
" = " +
"'" + command +
"'");
1939 void console_handler::do_set_var()
1941 const std::string
data = get_data();
1943 command_failed_need_arg(1);
1947 const std::string::const_iterator j = std::find(
data.begin(),
data.end(),
'=');
1948 if(j !=
data.end()) {
1949 const std::string name(
data.begin(), j);
1950 const std::string value(j + 1,
data.end());
1953 command_failed(
_(
"Variable not found"));
1957 void console_handler::do_show_var()
1962 void console_handler::do_inspect()
1965 gui2::dialogs::gamestate_inspector::display(
1969 void console_handler::do_control_dialog()
1971 gui2::dialogs::mp_change_control::display(menu_handler_);
1974 void console_handler::do_unit()
1982 if(
i == menu_handler_.pc_.get_units().end()) {
1984 symbols[
"unit"] = get_arg(1);
1986 "Debug command 'unit: $unit' failed: no unit selected or hovered over.",
1992 const std::string
data = get_data(1);
1994 if(parameters.size() < 2) {
1998 if(parameters[0] ==
"alignment") {
2002 symbols[
"alignment"] = get_arg(1);
2004 "Invalid alignment: '$alignment', needs to be one of lawful, neutral, chaotic, or liminal.",
2014 "name", parameters[0],
2015 "value", parameters[1],
2020 void console_handler::do_discover()
2022 for(
const unit_type_data::unit_type_map::value_type&
i :
unit_types.
types()) {
2027 void console_handler::do_undiscover()
2037 void console_handler::do_create()
2041 if(menu_handler_.pc_.get_map().on_board(loc)) {
2044 command_failed(
_(
"Invalid unit type"));
2049 create_and_place(*menu_handler_.gui_, menu_handler_.pc_.get_map(), menu_handler_.pc_.get_units(), loc, *ut);
2051 command_failed(
_(
"Invalid location"));
2055 void console_handler::do_fog()
2060 void console_handler::do_shroud()
2065 void console_handler::do_gold()
2070 void console_handler::do_event()
2075 void console_handler::do_toggle_draw_coordinates()
2078 menu_handler_.gui_->invalidate_all();
2080 void console_handler::do_toggle_draw_terrain_codes()
2083 menu_handler_.gui_->invalidate_all();
2086 void console_handler::do_toggle_draw_num_of_bitmaps()
2089 menu_handler_.gui_->invalidate_all();
2092 void console_handler::do_toggle_whiteboard()
2094 if(
const std::shared_ptr<wb::manager>& whiteb = menu_handler_.pc_.get_whiteboard()) {
2095 whiteb->set_active(!whiteb->is_active());
2096 if(whiteb->is_active()) {
2097 print(get_cmd(),
_(
"Planning mode activated!"));
2098 whiteb->print_help_once();
2100 print(get_cmd(),
_(
"Planning mode deactivated!"));
2105 void console_handler::do_whiteboard_options()
2107 if(menu_handler_.pc_.get_whiteboard()) {
2108 menu_handler_.pc_.get_whiteboard()->options_dlg();
2112 void menu_handler::do_ai_formula(
const std::string& str,
int side_num,
mouse_handler& )
2122 void menu_handler::user_command()
2127 void menu_handler::request_control_change(
int side_num,
const std::string& player)
2129 std::string side = std::to_string(side_num);
2130 if(board().get_team(side_num).is_local_human() && player ==
prefs::get().login()) {
2136 pc_.send_to_wesnothd(
config {
"change_controller",
config {
"side", side,
"player", player}});
2140 void menu_handler::custom_command()
2143 do_command(command);
2147 void menu_handler::ai_formula()
2149 if(!pc_.is_networked_mp()) {
2154 void menu_handler::clear_messages()
2156 gui_->get_chat_manager().clear_chat_messages();
2161 pc_.send_to_wesnothd(cfg);
Various functions related to moving units.
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
static manager & get_singleton()
A config object defines a single node in a WML file, with access to child nodes.
child_itors child_range(config_key_type key)
attribute_map::value_type attribute
int village_owner(const map_location &loc) const
Given the location of a village, will return the 1-based number of the team that currently owns it,...
bool is_observer() const
Check if we are an observer in this game.
can_move_result unit_can_move(const unit &u) const
Work out what u can do - this does not check which player's turn is currently active,...
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
const team & viewing_team() const
@ DEBUG_COORDINATES
Overlays x,y coords on tiles.
@ DEBUG_BENCHMARK
Toggle to continuously redraw the whole map.
@ DEBUG_NUM_BITMAPS
Overlays number of bitmaps on tiles.
@ DEBUG_FOREGROUND
Separates background and foreground terrain layers.
@ DEBUG_TERRAIN_CODES
Overlays terrain codes on tiles.
const gamemap & get_map() const
void queue_rerender()
Marks everything for rendering including all tiles and sidebar.
std::size_t viewing_team_index() const
The viewing team is the team currently viewing the game.
virtual std::string get_arg(unsigned i) const
std::string get_flags_description() const
virtual std::string get_cmd() const
console_handler(menu_handler &menu_handler)
void print(const std::string &title, const std::string &message)
virtual void register_alias(const std::string &to_cmd, const std::string &cmd)
bool is_enabled(const chmap::command &c) const
virtual std::string get_data(unsigned n=1) const
menu_handler & menu_handler_
std::string get_command_flags_description(const chmap::command &c) const
virtual void register_command(const std::string &cmd, chat_command_handler::command_handler h, const std::string &help="", const std::string &usage="", const std::string &flags="")
map_command_handler< console_handler > chmap
const unsigned int team_num_
std::vector< std::string > get_commands_list() const
void dispatch(std::string cmd)
game_board & board() const
gui::floating_textbox & get_textbox()
menu_handler(game_display *gui, play_controller &pc)
gui::floating_textbox textbox_info_
void show_statistics(int side_num)
void recruit(int side_num, const map_location &last_hex)
t_string can_recruit(const std::string &name, int side_num, map_location &target_hex, map_location &recruited_from)
game_state & gamestate() const
void disable_units_highlight()
Use this to disable hovering an unit from highlighting its movement range.
void set_current_paths(const pathfind::paths &new_paths)
pathfind::marked_route get_route(const unit *un, map_location go_to, const team &team) const
map_location get_selected_hex() const
const map_location hovered_hex() const
Uses SDL and game_display::hex_clicked_on to fetch the hex the mouse is hovering, if applicable.
const map_location & get_last_hex() const
bool hex_hosts_unit(const map_location &hex) const
Unit exists on the hex, no matter if friend or foe.
void cycle_units(const bool browse, const bool reverse=false)
unit_map::iterator find_visible_unit(const map_location &loc, const team ¤t_team, bool see_all=false)
void scroll_to_leader(int side, SCROLL_TYPE scroll_type=ONSCREEN, bool force=true)
Scrolls to the leader of a certain side.
virtual const std::set< std::string > & observers() const override
bool on_board_with_border(const map_location &loc) const
Encapsulates the map of the game.
std::string write() const
file_dialog & set_extension(const std::string &value)
Sets allowed file extensions for file names in save mode.
file_dialog & set_path(const std::string &value)
Sets the initial file selection.
file_dialog & set_title(const std::string &value)
Sets the current dialog title text.
file_dialog & set_save_mode(bool value)
Sets the dialog's behavior on non-existent file name inputs.
std::string path() const
Gets the current file selection.
static bool execute(game_board &board, const int viewing_team, int &selected_side_number)
@ yes_no_buttons
Shows a yes and no button.
@ ok_cancel_buttons
Shows an ok and cancel button.
@ auto_close
Enables auto close.
bool show(const unsigned auto_close_time=0)
Shows the window.
int selected_index() const
Returns the selected item index after displaying.
void set_selected_index(int index)
Sets the initially selected item index (-1 by default).
unit_race::GENDER gender()
Gender choice from the user.
bool no_choice() const
Whether the user actually chose a unit type or not.
std::string variation() const
Variation choice from the user.
const std::string & choice() const
Unit type choice from the user.
int get_selected_index() const
void show(gui::TEXTBOX_MODE mode, const std::string &label, const std::string &check_label, bool checked, game_display &gui)
std::vector< team > & get_teams()
void show_objectives() const
statistics_t & statistics()
events::mouse_handler & get_mouse_handler_base() override
Get a reference to a mouse handler member a derived class uses.
const gamemap & get_map() const
void refresh_objectives() const
Reevaluate [show_if] conditions and build a new objectives string.
void notify_event(const std::string &name, const config &data)
static plugins_manager * get()
std::set< std::string > & encountered_units()
void add_alias(const std::string &alias, const std::string &command)
void set_message_private(bool value)
void set_show_fps(bool value)
bool empty() const
Is it empty?
static config get_recall(const std::string &unit_id, const map_location &loc, const map_location &from)
static config get_auto_shroud(bool turned_on)
Records that the player has toggled automatic shroud updates.
static config get_recruit(const std::string &type_id, const map_location &loc, const map_location &from)
static config get_update_shroud()
Records that the player has manually updated fog/shroud.
void add_rename(const std::string &name, const map_location &loc)
void add_label(const terrain_label *)
void speak(const config &cfg)
void clear_labels(const std::string &, bool)
static void ignore_error_function(const std::string &message)
A function to be passed to run_in_synced_context to ignore the error.
static bool run_and_throw(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
static synced_state get_synced_state()
This class stores all the data for a single 'side' (in game nomenclature).
void set_action_bonus_count(const int count)
bool auto_shroud_updates() const
const std::string & team_name() const
int action_bonus_count() const
static color_t get_side_color(int side)
recall_list_manager & recall_list()
const std::string & last_recruit() const
To store label data Class implements logic for rendering.
const t_string & text() const
Container associating units to locations.
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
const unit_type_map & types() const
A single unit type that the player may recruit.
const std::string & id() const
The id for this unit_type.
const std::vector< unit_race::GENDER > & genders() const
The returned vector will not be empty, provided this has been built to the HELP_INDEXED status.
const t_string & type_name() const
The name of the unit in the current language setting.
This class represents a single unit of a specific type.
A variable-expanding proxy for the config class.
static vconfig empty_vconfig()
Various functions related to the creation of units (recruits, recalls, and placed units).
static void print(std::stringstream &sstr, const std::string &queue, const std::string &id)
Contains the exception interfaces used to signal completion of a scenario, campaign or turn.
void throw_quit_game_exception()
int dispatch(lua_State *L)
static std::string _(const char *str)
bool user_end_turn() const
Check whether the user ended their turn.
const std::string & id() const
Gets this unit's id.
int side() const
The side this unit belongs to.
const t_string & name() const
Gets this unit's translatable display name.
const map_location & get_location() const
The current map location this unit is at.
bool has_moved() const
Checks if this unit has moved.
void set_goto(const map_location &new_goto)
Sets this unit's long term destination.
int movement_left() const
Gets how far a unit can move, considering the incapacitated flag.
const map_location & get_goto() const
The map location to which this unit is moving over multiple turns, if any.
std::string label
What to show in the filter's drop-down list.
std::string id
Text to match against addon_info.tags()
Standard logging facilities (interface).
std::string find_recruit_location(const int side, map_location &recruit_location, map_location &recruited_from, const std::string &unit_type)
Finds a location on which to place a unit.
const std::set< std::string > get_recruits(int side, const map_location &recruit_loc)
Gets the recruitable units from a side's leaders' personal recruit lists who can recruit on or from a...
std::size_t move_unit_and_record(const std::vector< map_location > &steps, undo_list *undo_stack, bool continued_move, bool show_move, bool *interrupted, move_unit_spectator *move_spectator)
Moves a unit across the board.
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::string find_recall_location(const int side, map_location &recall_location, map_location &recall_from, const unit &unit_recall)
Finds a location on which to recall unit_recall.
EXIT_STATUS start(bool clear_id, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
Handling of system events.
static bfs::path get_dir(const bfs::path &dirpath)
std::string get_user_data_dir()
const std::string map_extension
void write_file(const std::string &fname, const std::string &data, std::ios_base::openmode mode)
Throws io_exception if an error occurs.
const color_t LABEL_COLOR
std::string private_message
Game configuration data as global variables.
bool ignore_replay_errors
const std::string observer_team_name
observer team name used for observer team chat
void set_debug(bool new_debug)
void show_unit_list(display &gui)
void show_transient_error_message(const std::string &message, const std::string &image, const bool message_use_markup)
Shows a transient error message to the user.
void show_transient_message(const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup)
Shows a transient message to the user.
void show_message(const std::string &title, const std::string &msg, const std::string &button_caption, const bool auto_close, const bool message_use_markup, const bool title_use_markup)
Shows a message to the user.
retval
Default window/dialog return values.
@ OK
Dialog was closed with the OK button.
@ CANCEL
Dialog was closed with the CANCEL button.
void show_help(const std::string &show_topic, int xloc, int yloc)
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.
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
static std::string sgettext(const char *str)
@ STRIP_SPACES
REMOVE_EMPTY: remove empty elements.
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
bool chars_equal_insensitive(char a, char b)
std::string format_conjunct_list(const t_string &empty, const std::vector< t_string > &elems)
Format a conjunctive list.
std::map< std::string, t_string > string_map
std::vector< std::string > split(const config_attribute_value &val)
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
std::shared_ptr< const unit > unit_const_ptr
const std::string & gender_string(unit_race::GENDER gender)
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.