116 #include <functional>
135 #define DBG_LUA LOG_STREAM(debug, log_scripting_lua)
136 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
137 #define WRN_LUA LOG_STREAM(warn, log_scripting_lua)
138 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
141 #define ERR_WML LOG_STREAM(err, log_wml)
149 template <member_callback method>
151 return ((lua_kernel_base::get_lua_kernel<game_lua_kernel>(L)).*method)(L);
157 template <member_callback2 method,
bool b>
159 return ((lua_kernel_base::get_lua_kernel<game_lua_kernel>(L)).*method)(L,
b);
209 if(!sides.
empty()) {
WRN_LUA <<
"ignoring duplicate side filter information (inline side=)"; }
222 struct queued_event_context
225 std::stack<qe const *> & stack_;
227 queued_event_context(qe
const *new_qe, std::stack<qe const*> & stack)
233 ~queued_event_context()
248 lua_pushinteger(L, disp->viewing_team().side());
249 lua_pushboolean(L, disp->show_everything());
267 anim.~unit_animator();
276 std::string which = luaL_checkstring(L, 3);
278 std::string hits_str = luaL_checkstring(L, 4);
288 if(lua_istable(L, 5)) {
289 lua_getfield(L, 5,
"target");
292 return luaL_argerror(L, 5,
"target location must be different from animated unit's location");
294 return luaL_argerror(L, 5,
"target location must be adjacent to the animated unit");
299 if(!lua_isnoneornil(L, -1)) {
305 lua_getfield(L, 5,
"value");
306 if(lua_isnumber(L, -1)) {
307 v1 = lua_tointeger(L, -1);
308 }
else if(lua_istable(L, -1)) {
309 lua_rawgeti(L, -1, 1);
310 v1 = lua_tointeger(L, -1);
312 lua_rawgeti(L, -1, 2);
313 v2 = lua_tointeger(L, -1);
315 }
else if(!lua_isnoneornil(L, -1)) {
316 return luaW_type_error(L, 5,
"value",
"number or array of two numbers");
320 lua_getfield(L, 5,
"with_bars");
321 if(lua_isboolean(L, -1)) {
323 }
else if(!lua_isnoneornil(L, -1)) {
324 return luaW_type_error(L, 5,
"with_bars", lua_typename(L, LUA_TBOOLEAN));
328 lua_getfield(L, 5,
"text");
329 if(lua_isstring(L, -1)) {
330 text = lua_tostring(L, -1);
333 }
else if(!lua_isnoneornil(L, -1)) {
338 lua_getfield(L, 5,
"color");
339 if(lua_istable(L, -1) && lua_rawlen(L, -1) == 3) {
340 int idx = lua_absindex(L, -1);
341 lua_rawgeti(L, idx, 1);
342 lua_rawgeti(L, idx, 2);
343 lua_rawgeti(L, idx, 3);
344 color =
color_t(lua_tointeger(L, -3), lua_tointeger(L, -2), lua_tointeger(L, -1));
346 }
else if(!lua_isnoneornil(L, -1)) {
351 lua_getfield(L, 5,
"primary");
353 if(!primary && !lua_isnoneornil(L, -1)) {
358 lua_getfield(L, 5,
"secondary");
360 if(!secondary && !lua_isnoneornil(L, -1)) {
364 }
else if(!lua_isnoneornil(L, 5)) {
368 anim.
add_animation(up, which, u.
get_location(), dest, v1, bars, text, color, hits, primary, secondary, v2);
396 const char* m = lua_tostring(L, 2);
404 luaL_Reg metafuncs[] {
408 {
"run", &dispatch<&game_lua_kernel::impl_run_animation>},
412 luaL_setfuncs(L, metafuncs, 0);
413 lua_pushstring(L,
"__metatable");
416 lua_setmetatable(L, -2);
426 name = cfg[
"name"].str();
429 name = luaL_optstring(L, 1,
"");
447 if(lua_isstring(L, 1) && !lua_isnumber(L, 1)) {
448 std::string
id = luaL_checkstring(L, 1);
458 return luaL_argerror(L, 1,
"expected string or location");
462 if (!ui.
valid())
return 0;
483 if (!ui.
valid())
return 0;
501 std::vector<const unit*>
units;
505 return luaL_argerror(L, 2,
"unit not found");
508 }
else if(!lua_isnoneornil(L, 2)) {
512 return luaL_argerror(L, 2,
"invalid location");
527 lua_rawseti(L, 1,
i);
547 lua_pushboolean(L,
true);
553 WRN_LUA <<
"wesnoth.units.matches called with a secondary unit (3rd argument), ";
554 WRN_LUA <<
"but unit to match was on recall list. ";
555 WRN_LUA <<
"Thus the 3rd argument is ignored.";
562 return luaL_argerror(L, 3,
"unit not found");
564 lua_pushboolean(L,
unit_filter(filter).matches(*u, *u_adj));
570 lua_pushboolean(L,
unit_filter(filter).matches(*u, loc));
575 lua_pushboolean(L,
unit_filter(filter).matches(*u, loc));
600 if (!filter.
null()) {
602 t.save_id_or_number(),
t.recall_list().find_index(u->id()));
607 lua_rawseti(L, 1,
i);
626 char const *m = luaL_checkstring(L, 1);
643 if(
data.has_child(
"primary_attack")) {
644 data.add_child(
"first",
data.mandatory_child(
"primary_attack"));
645 data.remove_children(
"primary_attack");
647 if(
data.has_child(
"secondary_attack")) {
648 data.add_child(
"second",
data.mandatory_child(
"secondary_attack"));
649 data.remove_children(
"secondary_attack");
660 lua_pushboolean(L,
b);
678 char const *m = luaL_checkstring(L, 1);
683 lua_pushboolean(L,
b);
695 char const *m = luaL_checkstring(L, 1);
707 const std::string m = luaL_checkstring(L, 1);
708 if(m.empty())
return luaL_argerror(L, 1,
"empty variable name");
709 if (lua_isnoneornil(L, 2)) {
722 cfg[
"side"] =
teams().size() + 1;
737 std::string ids(luaL_checkstring(L, 1));
740 WRN_LUA <<
"[clear_menu_item] has been given an empty id=, ignoring";
757 if(lua_istable(L, 2)) {
769 return luaL_argerror(L, 2,
"expected list of locations");
788 if(lua_istable(L, 2)) {
816 if(!
map().on_board(loc))
return luaL_argerror(L, 1,
"not on board");
830 unsigned side_1, side_2;
834 side_1 = luaL_checkinteger(L, 1);
839 side_2 = luaL_checkinteger(L, 2);
842 lua_pushboolean(L,
board().get_team(side_1).is_enemy(side_2));
876 lua_pushstring(L, tod.
id.c_str());
877 lua_setfield(L, -2,
"id");
879 lua_setfield(L, -2,
"lawful_bonus");
881 lua_setfield(L, -2,
"bonus_modified");
882 lua_pushstring(L, tod.
image.c_str());
883 lua_setfield(L, -2,
"image");
885 lua_setfield(L, -2,
"name");
886 lua_pushstring(L, tod.
sounds.c_str());
887 lua_setfield(L, -2,
"sound");
889 lua_setfield(L, -2,
"mask");
891 lua_pushinteger(L, tod.
color.
r);
892 lua_setfield(L, -2,
"red");
893 lua_pushinteger(L, tod.
color.
g);
894 lua_setfield(L, -2,
"green");
895 lua_pushinteger(L, tod.
color.
b);
896 lua_setfield(L, -2,
"blue");
903 lua_newuserdatauv(L, 0, 1);
904 lua_pushinteger(L, area_index);
905 lua_setiuservalue(L, -2, 1);
906 if(luaL_newmetatable(L,
"schedule")) {
907 static luaL_Reg
const schedule_meta[] {
908 {
"__index", &dispatch<&game_lua_kernel::impl_schedule_get>},
909 {
"__newindex", &dispatch<&game_lua_kernel::impl_schedule_set>},
910 {
"__dir", &dispatch<&game_lua_kernel::impl_schedule_dir>},
911 {
"__len", &dispatch<&game_lua_kernel::impl_schedule_len>},
914 luaL_setfuncs(L, schedule_meta, 0);
916 lua_setmetatable(L, -2);
921 int save_top = lua_gettop(L);
922 luaL_checkudata(L, idx,
"schedule");
923 lua_getiuservalue(L, idx, 1);
924 int i = luaL_checkinteger(L, -1);
925 lua_settop(L, save_top);
935 #define SCHEDULE_GETTER(name, type) LATTR_GETTER(name, type, schedule_tag, sched)
936 #define SCHEDULE_SETTER(name, type) LATTR_SETTER(name, type, schedule_tag, sched)
937 #define SCHEDULE_VALID(name) LATTR_VALID(name, schedule_tag, sched)
941 inline static auto metatable =
"schedule";
943 schedule_tag sched{lua_kernel_base::get_lua_kernel<game_lua_kernel>(L)};
952 if(lua_isnumber(L, 2)) {
954 int i = lua_tointeger(L, 2) - 1;
955 if(i < 0 || i >=
static_cast<int>(times.size())) {
956 return luaL_argerror(L, 2,
"invalid time of day index");
968 lua_pushinteger(L, times.size());
975 if(lua_isnumber(L, 2)) {
977 int i = lua_tointeger(L, 2) - 1;
978 if(i < 0 || i >=
static_cast<int>(times.size())) {
979 return luaL_argerror(L, 2,
"invalid time of day index");
998 if(sched.area_index >= 0) {
999 return sched.tod_man().get_area_time_of_day(sched.area_index).id;
1001 return sched.tod_man().get_time_of_day().id;
1005 const auto& times = sched.area_index < 0 ? sched.tod_man().times() : sched.tod_man().times(sched.area_index);
1006 auto iter = std::find_if(times.begin(), times.end(), [&value](
const time_of_day& tod) {
1007 return tod.id == value;
1009 if(iter == times.end()) {
1010 std::ostringstream
err;
1011 err <<
"invalid time of day ID for ";
1012 if(sched.area_index < 0) {
1013 err <<
"global schedule";
1015 const std::string&
id = sched.tod_man().get_area_id(sched.area_index);
1017 const auto& hexes = sched.tod_man().get_area_by_index(sched.area_index);
1019 err <<
"anonymous empty time area";
1021 err <<
"anonymous time area at (" << hexes.begin()->wml_x() <<
',' << hexes.begin()->wml_y() <<
")";
1024 err <<
"time area with id=" <<
id;
1030 int n = std::distance(times.begin(), iter);
1031 if(sched.area_index < 0) {
1032 sched.tod_man().set_current_time(
n);
1034 sched.tod_man().set_current_time(
n, sched.area_index);
1039 return sched.area_index < 0;
1043 if(sched.area_index >= 0)
return utils::nullopt;
1044 return sched.tod_man().get_max_liminal_bonus();
1048 if(sched.area_index >= 0) {
1049 throw luaL_error(L,
"liminal_bonus can only be set on the global schedule");
1052 sched.tod_man().set_max_liminal_bonus(*value);
1054 sched.tod_man().reset_max_liminal_bonus();
1059 return sched.area_index >= 0;
1063 if(sched.area_index < 0)
return utils::nullopt;
1064 return sched.tod_man().get_area_id(sched.area_index);
1068 if(sched.area_index < 0) {
1069 throw luaL_error(L,
"can't set id of global schedule");
1071 sched.tod_man().set_area_id(sched.area_index, value);
1075 return sched.area_index >= 0;
1079 if(sched.area_index < 0)
return utils::nullopt;
1080 return sched.tod_man().get_area_by_index(sched.area_index);
1084 if(sched.area_index < 0) {
1085 throw luaL_error(L,
"can't set hexes of global schedule");
1087 sched.tod_man().replace_area_locations(sched.area_index, value);
1098 char const *m = luaL_checkstring(L, 2);
1104 lua_pushstring(L,
info.id().c_str());
1105 lua_setfield(L, -2,
"id");
1107 lua_setfield(L, -2,
"name");
1109 lua_setfield(L, -2,
"editor_name");
1111 lua_setfield(L, -2,
"description");
1113 lua_setfield(L, -2,
"icon");
1115 lua_setfield(L, -2,
"editor_image");
1116 lua_pushinteger(L,
info.light_bonus(0));
1117 lua_setfield(L, -2,
"light");
1118 lua_pushboolean(L,
info.is_village());
1119 lua_setfield(L, -2,
"village");
1120 lua_pushboolean(L,
info.is_castle());
1121 lua_setfield(L, -2,
"castle");
1122 lua_pushboolean(L,
info.is_keep());
1123 lua_setfield(L, -2,
"keep");
1124 lua_pushinteger(L,
info.gives_healing());
1125 lua_setfield(L, -2,
"healing");
1137 std::vector<std::string> terrains;
1138 terrains.reserve(codes.size());
1139 for(
auto code : codes) {
1152 template<
bool cons
ider_illuminates>
1159 if(!
board().
map().on_board_with_border(loc)) {
1160 return luaL_argerror(L, 1,
"coordinates are not on board");
1162 }
else if(lua_isstring(L, 1)) {
1165 return luaL_error(L,
"invalid or empty time_area ID");
1168 loc = *area.begin();
1169 }
else if(!lua_isnil(L, 1)) {
1172 return luaL_error(L,
"empty time_area");
1175 loc = *area.begin();
1178 if(lua_isnumber(L, 2)) {
1179 for_turn = luaL_checkinteger(L, 2);
1181 if(for_turn < 1 || (number_of_turns != -1 && for_turn > number_of_turns)) {
1182 return luaL_argerror(L, 2,
"turn number out of range");
1203 if (!
board().
map().is_village(loc))
1207 if (!side)
return 0;
1208 lua_pushinteger(L, side);
1220 if(!
board().
map().is_village(loc)) {
1225 const int new_side_num = lua_isnoneornil(L, 2) ? 0 : luaL_checkinteger(L, 2);
1227 team* old_side =
nullptr;
1228 team* new_side =
nullptr;
1230 if(old_side_num == new_side_num) {
1236 }
catch(
const std::out_of_range&) {
1243 }
catch(
const std::out_of_range&) {
1249 if(new_side &&
board().team_is_defeated(*new_side)) {
1282 if (!
board().
map().on_board(loc))
return 0;
1283 lua_pushinteger(L, loc.
wml_x());
1284 lua_pushinteger(L, loc.
wml_y());
1300 if (!
board().
map().on_board(loc))
return 0;
1301 lua_pushinteger(L, loc.
wml_x());
1302 lua_pushinteger(L, loc.
wml_y());
1315 std::string m = luaL_checkstring(L, 1);
1321 return luaL_argerror(L, 1, (
"Cannot find resource with id '" + m +
"'").c_str());
1333 std::string m = luaL_checkstring(L, 1);
1339 return luaL_argerror(L, 1, (
"Cannot find era with id '" + m +
"'").c_str());
1354 #define GAME_CONFIG_SIMPLE_SETTER(name) \
1355 GAME_CONFIG_SETTER(#name, decltype(game_config::name), game_lua_kernel) { \
1357 game_config::name = value; \
1363 return k2.pc().gamestate().do_healing_;
1368 k2.pc().gamestate().do_healing_ = value;}
1378 k2.disp()->set_theme(value);
1381 using traits_map = std::map<std::string, config>;
1384 std::map<std::string, config> result;
1389 result.emplace(trait[
"id"], trait);
1405 static config find_addon(
const std::string&
type,
const std::string&
id)
1414 const char* m = luaL_checkstring(L, 2);
1432 struct end_level_committer {
1434 ~end_level_committer() {
1435 pc_.set_end_level_data(data_);
1446 const char* m = luaL_checkstring(L, 2);
1462 data->~end_level_data();
1468 void*
p = lua_touserdata(L, lua_upvalueindex(1));
1470 if(lua_type(L, 2) == LUA_TNUMBER) {
1473 size_t i = luaL_checkinteger(L, 2);
1475 lua_createtable(L, 2, 0);
1476 lua_pushstring(L,
"options");
1484 auto iter =
settings.addons.begin();
1485 std::advance(iter,
i);
1487 iter->second.write(cfg);
1488 cfg[
"id"] = iter->first;
1490 lua_createtable(L, 2, 0);
1491 lua_pushstring(L,
"addon");
1499 char const *m = luaL_checkstring(L, 2);
1527 if(strcmp(m,
"savegame") == 0) {
1529 if(
savegame == saved_game_mode::type::no) {
1530 lua_pushboolean(L,
false);
1536 if(strcmp(m,
"side_players") == 0) {
1540 if(strcmp(m,
"addons") == 0) {
1541 for(
const auto& [
id, addon] :
settings.addons) {
1542 lua_createtable(L, 0, 4);
1544 lua_setfield(L, -2,
"id");
1546 lua_setfield(L, -2,
"name");
1547 lua_pushboolean(L, addon.required);
1548 lua_setfield(L, -2,
"required");
1549 if(addon.min_version) {
1551 lua_push(L, addon.min_version->str());
1553 lua_setfield(L, -2,
"min_version");
1559 lua_setfield(L, -2,
"version");
1561 lua_createtable(L, addon.content.size(), 0);
1562 for(
const auto& content : addon.content) {
1563 lua_createtable(L, 0, 3);
1565 lua_setfield(L, -2,
"id");
1567 lua_setfield(L, -2,
"name");
1569 lua_setfield(L, -2,
"type");
1570 lua_seti(L, -2, lua_rawlen(L, -2) + 1);
1572 lua_setfield(L, -2,
"content");
1588 void*
p = lua_touserdata(L, lua_upvalueindex(1));
1590 lua_pushinteger(L,
settings.addons.size() + 1);
1601 auto end_level_set()
const {
return &dispatch<&game_lua_kernel::impl_end_level_data_set>; }
1603 #define SCENARIO_GETTER(name, type) LATTR_GETTER(name, type, scenario_tag, k)
1604 #define SCENARIO_SETTER(name, type) LATTR_SETTER(name, type, scenario_tag, k)
1605 #define SCENARIO_VALID(name) LATTR_VALID(name, scenario_tag, k)
1609 inline static auto metatable =
"scenario";
1611 return lua_kernel_base::get_lua_kernel<game_lua_kernel>(L);
1617 return k.tod_man().number_of_turns();
1621 k.tod_man().set_number_of_turns_by_wml(value);
1625 return k.gamedata().next_scenario();
1629 k.gamedata().set_next_scenario(value);
1633 return k.gamedata().get_id();
1637 return k.pc().get_scenario_name();
1641 return k.gamedata().get_defeat_music();
1645 k.gamedata().set_defeat_music(value);
1649 return k.gamedata().get_victory_music();
1653 k.gamedata().set_victory_music(value);
1658 for(
const std::string& rsrc :
utils::split(k.pc().get_loaded_resources())) {
1659 resources.push_back(find_addon(
"resource", rsrc));
1669 return k.cls().difficulty;
1673 return k.cls().end_credits;
1677 k.cls().end_credits = value;
1681 return k.cls().end_text;
1685 k.cls().end_text = value;
1689 return k.cls().end_text_duration.count();
1693 k.cls().end_text_duration = std::chrono::milliseconds{value};
1697 return !k.cls().campaign.empty();
1701 if(k.cls().campaign.empty())
return utils::nullopt;
1702 return find_addon(
"campaign", k.cls().campaign);
1706 std::vector<config> mods;
1707 for(
const std::string& mod : k.cls().active_mods) {
1708 mods.push_back(find_addon(
"modification", mod));
1714 if (!k.pc().is_regular_game_end()) {
1718 auto data = k.pc().get_end_level_data();
1720 if(luaL_newmetatable(L,
"end level data")) {
1721 static luaL_Reg
const callbacks[] {
1723 {
"__newindex", k.end_level_set()},
1725 {
nullptr,
nullptr }
1727 luaL_setfuncs(L, callbacks, 0);
1729 lua_setmetatable(L, -2);
1736 data.proceed_to_next_level = value[
"proceed_to_next_level"].to_bool(
true);
1737 data.transient.carryover_report = value[
"carryover_report"].to_bool(
true);
1738 data.prescenario_save = value[
"save"].to_bool(
true);
1739 data.replay_save = value[
"replay_save"].to_bool(
true);
1740 data.transient.linger_mode = value[
"linger_mode"].to_bool(
true) && !k.ref.teams().empty();
1741 data.transient.reveal_map = value[
"reveal_map"].to_bool(k.pc().reveal_map_default());
1742 data.is_victory = value[
"result"] == level_result::victory;
1743 data.test_result = value[
"test_result"].str();
1744 k.pc().set_end_level_data(
data);
1748 return k.cls().is_multiplayer();
1752 if(!k.cls().is_multiplayer()) {
1756 lua_newuserdatauv(L, 0, 0);
1757 if(luaL_newmetatable(L,
"mp settings")) {
1758 lua_pushlightuserdata(L, &k.pc());
1760 lua_setfield(L, -2,
"__index");
1761 lua_pushlightuserdata(L, &k.pc());
1763 lua_setfield(L, -2,
"__len");
1764 lua_pushstring(L,
"mp settings");
1765 lua_setfield(L, -2,
"__metatable");
1767 lua_setmetatable(L, -2);
1772 return k.cls().is_multiplayer();
1776 if(!k.cls().is_multiplayer())
return utils::nullopt;
1777 return find_addon(
"era", k.cls().era_id);
1789 DBG_LUA <<
"impl_scenario_get";
1801 DBG_LUA <<
"impl_scenario_set";
1810 DBG_LUA <<
"impl_scenario_dir";
1827 return "local_choice";
1846 #define CURRENT_GETTER(name, type) LATTR_GETTER(name, type, current_tag, k)
1850 inline static auto metatable =
"current";
1852 return lua_kernel_base::get_lua_kernel<game_lua_kernel>(L);
1858 return k.pc().current_side();
1862 return k.pc().turn();
1887 cfg[
"name"] = ev.
name;
1894 cfg.
add_child(
"second_weapon", *weapon);
1899 cfg[
"damage_inflicted"] = di;
1945 if (lua_isnone(L, 2)) {
1951 LOG_LUA <<
"Script says: \"" << m <<
"\"";
1960 double factor = luaL_checknumber(L, 1);
1987 if (!lua_isnoneornil(L, 1)) {
1988 int max = 2 *
teams().size();
1989 int npn = luaL_checkinteger(L, 1);
1990 if (npn <= 0 || npn > max) {
1991 return luaL_argerror(L, 1,
"side number out of range");
2008 lua_pushboolean(L,
b);
2026 const unit* u =
nullptr;
2027 int viewing_side = 0;
2029 if (lua_isuserdata(L, arg))
2033 viewing_side = u->
side();
2042 viewing_side = u->
side();
2050 return luaL_argerror(L, 1,
"invalid location");
2052 return luaL_argerror(L, arg,
"invalid location");
2056 bool ignore_units =
false, see_all =
false, ignore_teleport =
false;
2057 double stop_at = 10000;
2058 std::unique_ptr<pathfind::cost_calculator> calc;
2060 if (lua_istable(L, arg))
2062 ignore_units = luaW_table_get_def<bool>(L, arg,
"ignore_units",
false);
2063 see_all = luaW_table_get_def<bool>(L, arg,
"ignore_visibility",
false);
2064 ignore_teleport = luaW_table_get_def<bool>(L, arg,
"ignore_teleport",
false);
2066 stop_at = luaW_table_get_def<double>(L, arg,
"max_cost", stop_at);
2069 lua_pushstring(L,
"viewing_side");
2071 if (!lua_isnil(L, -1)) {
2072 int i = luaL_checkinteger(L, -1);
2073 if (
i >= 1 &&
i <=
static_cast<int>(
teams().
size())) viewing_side =
i;
2077 if(u) see_all =
true;
2078 deprecated_message(
"wesnoth.paths.find_path with viewing_side=0 (or an invalid side)",
DEP_LEVEL::FOR_REMOVAL, {1, 17, 0},
"To consider fogged and hidden units, use ignore_visibility=true instead.");
2083 lua_pushstring(L,
"calculate");
2085 if(lua_isfunction(L, -1)) {
2090 else if (lua_isfunction(L, arg))
2098 if(!ignore_teleport) {
2099 if(viewing_side == 0) {
2100 lua_warning(L,
"wesnoth.paths.find_path: ignore_teleport=false requires a valid viewing_side; continuing with ignore_teleport=true",
false);
2101 ignore_teleport =
true;
2109 return luaL_argerror(L, 1,
"unit not found OR custom cost function not provided");
2113 teams(),
map, ignore_units,
false, see_all));
2117 &teleport_locations);
2119 int nb = res.
steps.size();
2120 lua_createtable(L, nb, 0);
2121 for (
int i = 0;
i < nb; ++
i)
2124 lua_rawseti(L, -2,
i + 1);
2140 const unit* u =
nullptr;
2142 if (lua_isuserdata(L, arg))
2152 return luaL_argerror(L, 1,
"unit not found");
2157 int viewing_side = u->
side();
2158 bool ignore_units =
false, see_all =
false, ignore_teleport =
false;
2159 int additional_turns = 0;
2161 if (lua_istable(L, arg))
2163 ignore_units = luaW_table_get_def<bool>(L, arg,
"ignore_units",
false);
2164 see_all = luaW_table_get_def<bool>(L, arg,
"ignore_visibility",
false);
2165 ignore_teleport = luaW_table_get_def<bool>(L, arg,
"ignore_teleport",
false);
2166 additional_turns = luaW_table_get_def<int>(L, arg,
"max_cost", additional_turns);
2168 lua_pushstring(L,
"viewing_side");
2170 if (!lua_isnil(L, -1)) {
2171 int i = luaL_checkinteger(L, -1);
2172 if (
i >= 1 &&
i <=
static_cast<int>(
teams().
size())) viewing_side =
i;
2176 if(u) see_all =
true;
2186 viewing_team, additional_turns, see_all, ignore_units);
2189 lua_createtable(L, nb, 0);
2190 for (
int i = 0;
i < nb; ++
i)
2194 lua_pushinteger(L,
s.curr.wml_x());
2195 lua_rawseti(L, -2, 1);
2196 lua_pushinteger(L,
s.curr.wml_y());
2197 lua_rawseti(L, -2, 2);
2198 lua_pushinteger(L,
s.move_left);
2199 lua_rawseti(L, -2, 3);
2200 lua_rawseti(L, -2,
i + 1);
2215 const unit* u =
nullptr;
2217 if (lua_isuserdata(L, arg))
2227 return luaL_argerror(L, 1,
"unit not found");
2234 return luaL_error(L,
"wesnoth.find_vision_range: requires a valid unit");
2237 std::map<map_location, int> jamming_map;
2244 lua_pushinteger(L,
d.curr.wml_x());
2245 lua_rawseti(L, -2, 1);
2246 lua_pushinteger(L,
d.curr.wml_y());
2247 lua_rawseti(L, -2, 2);
2248 lua_pushinteger(L,
d.move_left);
2249 lua_rawseti(L, -2, 3);
2250 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
2252 for(
const auto&
e : res.
edges) {
2254 lua_pushinteger(L,
e.wml_x());
2255 lua_rawseti(L, -2, 1);
2256 lua_pushinteger(L,
e.wml_y());
2257 lua_rawseti(L, -2, 2);
2258 lua_pushinteger(L, -1);
2259 lua_rawseti(L, -2, 3);
2260 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
2265 template<
typename T>
2268 for (
int i = 1, i_end = lua_rawlen(L, arg);
i <= i_end; ++
i)
2271 lua_rawgeti(L, arg,
i);
2272 int entry = lua_gettop(L);
2273 if (!lua_istable(L, entry)) {
2281 lua_rawgeti(L, entry, 3);
2282 if (!lua_isnumber(L, -1)) {
2283 lua_getfield(L, entry,
"side");
2284 if (!lua_isnumber(L, -1)) {
2288 int side = lua_tointeger(L, -1);
2290 lua_rawgeti(L, entry, 4);
2291 if (!lua_isstring(L, -1)) {
2292 lua_getfield(L, entry,
"type");
2293 if (!lua_isstring(L, -1)) {
2297 std::string
unit_type = lua_tostring(L, -1);
2301 lua_settop(L, entry - 1);
2305 return luaL_argerror(L, arg,
"unit type table malformed - each entry should be either array of 4 elements or table with keys x, y, side, type");
2323 std::vector<const ::unit*> real_units;
2324 typedef std::vector<std::tuple<map_location, int, std::string>> unit_type_vector;
2330 real_units.push_back(
unit);
2332 else if (!filter.
null())
2334 for(const ::unit* match :
unit_filter(filter).all_matches_on_map()) {
2335 if(match->get_location().valid()) {
2336 real_units.push_back(match);
2346 real_units.push_back(&(*ui));
2351 if (lua_istable(L, arg))
2359 return luaL_argerror(L, 1,
"unit(s) not found");
2362 int viewing_side = 0;
2363 bool ignore_units =
true, see_all =
true, ignore_teleport =
false,
debug =
false, use_max_moves =
false;
2365 if (lua_istable(L, arg))
2367 lua_pushstring(L,
"ignore_units");
2369 if (!lua_isnil(L, -1))
2375 lua_pushstring(L,
"ignore_teleport");
2377 if (!lua_isnil(L, -1))
2383 lua_pushstring(L,
"viewing_side");
2385 if (!lua_isnil(L, -1))
2387 int i = luaL_checkinteger(L, -1);
2388 if (
i >= 1 &&
i <=
static_cast<int>(
teams().
size()))
2395 lua_pushstring(L,
"debug");
2397 if (!lua_isnil(L, -1))
2403 lua_pushstring(L,
"use_max_moves");
2405 if (!lua_isnil(L, -1))
2427 const team& viewing_team = viewing_side
2432 ignore_units, !ignore_teleport, viewing_team, see_all, ignore_units);
2434 for (const ::unit*
const u : real_units)
2436 cost_map.
add_unit(*u, use_max_moves);
2438 for (
const unit_type_vector::value_type& fu :
fake_units)
2441 cost_map.
add_unit(std::get<0>(fu), ut, std::get<1>(fu));
2450 std::stringstream
s;
2466 lua_pushinteger(L, loc.wml_x());
2467 lua_rawseti(L, -2, 1);
2469 lua_pushinteger(L, loc.wml_y());
2470 lua_rawseti(L, -2, 2);
2472 lua_pushinteger(L, cost_map.
get_pair_at(loc).first);
2473 lua_rawseti(L, -2, 3);
2475 lua_pushinteger(L, cost_map.
get_pair_at(loc).second);
2476 lua_rawseti(L, -2, 4);
2478 lua_rawseti(L, -2, counter);
2488 return reinterpret_cast<int*
>(luaL_checkudata(L, idx,
labelKey));
2493 const char* m = luaL_checkstring(L, 2);
2501 std::chrono::milliseconds fade{luaL_optinteger(L, 2, -1)};
2539 double width_ratio = 0;
2541 int lifetime = 2'000, fadeout = 100;
2547 if(lua_istable(L, 2)) {
2549 size = luaL_checkinteger(L, -1);
2553 width = lua_tointegerx(L, -1, &found_number);
2557 if(!value.empty() && value.back() ==
'%') {
2558 value.remove_suffix(1);
2559 width_ratio = std::stoi(std::string(value)) / 100.0;
2560 }
else throw std::invalid_argument(value.data());
2561 }
catch(std::invalid_argument&) {
2562 return luaL_argerror(L, -1,
"max_width should be integer or percentage");
2568 if(lua_isstring(L, -1)) {
2571 auto vec = lua_check<std::vector<int>>(L, -1);
2572 if(vec.size() != 3) {
2573 int idx = lua_absindex(L, -1);
2575 color.r = luaL_checkinteger(L, -3);
2576 color.g = luaL_checkinteger(L, -2);
2577 color.b = luaL_checkinteger(L, -1);
2579 return luaL_error(L,
"floating label text color should be a hex string, an array of 3 integers, or a table with r,g,b keys");
2589 if(lua_isstring(L, -1)) {
2592 auto vec = lua_check<std::vector<int>>(L, -1);
2593 if(vec.size() != 3) {
2594 int idx = lua_absindex(L, -1);
2596 bgcolor.r = luaL_checkinteger(L, -3);
2597 bgcolor.g = luaL_checkinteger(L, -2);
2598 bgcolor.b = luaL_checkinteger(L, -1);
2600 return luaL_error(L,
"floating label background color should be a hex string, an array of 3 integers, or a table with r,g,b keys");
2610 bgcolor.a = luaL_checkinteger(L, -1);
2615 lifetime = lua_tointegerx(L, -1, &found_number);
2618 if(value ==
"unlimited") {
2621 return luaL_argerror(L, -1,
"duration should be integer or 'unlimited'");
2626 fadeout = lua_tointeger(L, -1);
2632 static const char* options[] = {
"left",
"center",
"right"};
2633 alignment =
font::ALIGN(luaL_checkoption(L, -1,
nullptr, options));
2636 static const char* options[] = {
"top",
"center",
"bottom"};
2637 vertical_alignment =
font::ALIGN(luaL_checkoption(L, -1,
nullptr, options));
2649 int handle_idx = lua_gettop(L);
2656 if(width_ratio > 0) {
2657 width =
static_cast<int>(std::round(
rect.w * width_ratio));
2662 x =
rect.x + loc.wml_x();
2668 x =
rect.x +
rect.w / 2 + loc.wml_x();
2682 switch(vertical_alignment) {
2684 y =
rect.y + loc.wml_y();
2687 y =
rect.y +
rect.h / 2 + loc.wml_y();
2694 y =
rect.y +
rect.h - loc.wml_y() -
static_cast<int>(
size * 1.5);
2698 using std::chrono::milliseconds;
2705 flabel.
set_lifetime(milliseconds{lifetime}, milliseconds{fadeout});
2709 lua_settop(L, handle_idx);
2710 if(luaL_newmetatable(L,
labelKey)) {
2712 static const luaL_Reg methods[] = {
2713 {
"remove", &dispatch<&game_lua_kernel::intf_remove_floating_label>},
2714 {
"move", &dispatch<&game_lua_kernel::intf_move_floating_label>},
2715 {
"replace", &dispatch2<&game_lua_kernel::intf_set_floating_label, false>},
2717 {
nullptr,
nullptr }
2719 luaL_setfuncs(L, methods, 0);
2722 lua_setmetatable(L, handle_idx);
2723 lua_settop(L, handle_idx);
2748 return luaL_error(L,
"Attempted to move a unit while the map is locked");
2753 if (!
map().on_board(loc)) {
2754 return luaL_argerror(L, 2,
"invalid location");
2765 if (!
map().on_board(loc))
2766 return luaL_argerror(L, 1,
"invalid location");
2772 }
else if(!lua_isnoneornil(L, 1)) {
2773 const vconfig* vcfg =
nullptr;
2775 if (!
map().on_board(loc)) {
2778 if (!
map().on_board(loc))
2779 return luaL_argerror(L, 2,
"invalid location");
2785 u->set_location(loc);
2804 return luaL_error(L,
"Attempted to remove a unit while the map is locked");
2812 if (!
map().on_board(loc)) {
2813 return luaL_argerror(L, 1,
"invalid location");
2818 t.recall_list().erase_if_matches_id(u->
id());
2820 return luaL_argerror(L, 1,
"can't erase private units");
2823 if (!
map().on_board(loc)) {
2824 return luaL_argerror(L, 1,
"invalid location");
2827 return luaL_argerror(L, 1,
"expected unit or location");
2843 return luaL_error(L,
"Attempted to move a unit while the map is locked");
2847 int side = lua_tointeger(L, 2);
2848 if (
static_cast<unsigned>(side) >
teams().
size()) side = 0;
2852 u = lu->get_shared();
2853 if(lu->on_recall_list() && lu->on_recall_list() == side) {
2854 return luaL_argerror(L, 1,
"unit already on recall list");
2857 const vconfig* vcfg =
nullptr;
2869 std::size_t uid = u->underlying_id();
2870 t.recall_list().erase_by_underlying_id(uid);
2871 t.recall_list().add(u);
2876 u->anim_comp().clear_haloes();
2878 lu->lua_unit::~lua_unit();
2892 return luaL_error(L,
"Attempted to remove a unit while the map is locked");
2900 u->anim_comp().clear_haloes();
2901 }
else if (
int side = lu->on_recall_list()) {
2904 t.recall_list().erase_if_matches_id(u->id());
2910 lu->lua_unit::~lua_unit();
2926 if (!lua_isnoneornil(L, 2)) {
2930 const vconfig* vcfg =
nullptr;
2938 if (!res.
valid())
return 0;
2939 lua_pushinteger(L, res.
wml_x());
2940 lua_pushinteger(L, res.
wml_y());
2956 if (!lua_isnoneornil(L, 3)) {
2973 const vconfig* vcfg =
nullptr;
3003 char const *m = luaL_checkstring(L, 2);
3007 if(lua_isboolean(L, 3)) {
3009 if(!lua_isnoneornil(L, 4)) {
3012 }
else if(!lua_isnoneornil(L, 3)) {
3033 }
else if(lua_isstring(L, 2)) {
3034 char const *m = luaL_checkstring(L, 2);
3054 }
else if(lua_isstring(L, 2)) {
3055 char const *m = luaL_checkstring(L, 2);
3075 }
else if(lua_isstring(L, 2)) {
3076 char const *m = luaL_checkstring(L, 2);
3096 }
else if(lua_isstring(L, 2)) {
3097 char const *m = luaL_checkstring(L, 2);
3113 char const *m = luaL_checkstring(L, 2);
3127 char const *m = luaL_checkstring(L, 2);
3129 if (!utp)
return luaL_argerror(L, 2,
"unknown unit type");
3130 if(lua_isstring(L, 3)) {
3131 const std::string& m2 = lua_tostring(L, 3);
3132 if(!utp->
has_variation(m2))
return luaL_argerror(L, 2,
"unknown unit variation");
3146 lua_createtable(L, 0, 4);
3148 lua_setfield(L, -2,
"poisoned");
3149 lua_pushnumber(L, cmb.
slowed);
3150 lua_setfield(L, -2,
"slowed");
3152 lua_setfield(L, -2,
"untouched");
3154 lua_setfield(L, -2,
"average_hp");
3155 lua_createtable(L,
n, 0);
3156 for (
int i = 0;
i <
n; ++
i) {
3158 lua_rawseti(L, -2,
i);
3160 lua_setfield(L, -2,
"hp_chance");
3169 lua_createtable(L, 0, 16);
3172 lua_setfield(L, -2,
"num_blows");
3173 lua_pushnumber(L, bcustats.
damage);
3174 lua_setfield(L, -2,
"damage");
3176 lua_setfield(L, -2,
"chance_to_hit");
3177 lua_pushboolean(L, bcustats.
poisons);
3178 lua_setfield(L, -2,
"poisons");
3179 lua_pushboolean(L, bcustats.
slows);
3180 lua_setfield(L, -2,
"slows");
3182 lua_setfield(L, -2,
"petrifies");
3183 lua_pushboolean(L, bcustats.
plagues);
3184 lua_setfield(L, -2,
"plagues");
3186 lua_setfield(L, -2,
"plague_type");
3187 lua_pushnumber(L, bcustats.
rounds);
3188 lua_setfield(L, -2,
"rounds");
3190 lua_setfield(L, -2,
"firststrike");
3191 lua_pushboolean(L, bcustats.
drains);
3192 lua_setfield(L, -2,
"drains");
3194 lua_setfield(L, -2,
"drain_constant");
3196 lua_setfield(L, -2,
"drain_percent");
3201 lua_setfield(L, -2,
"attack_num");
3203 lua_setfield(L, -2,
"number");
3205 if(bcustats.
weapon !=
nullptr)
3207 lua_pushstring(L, bcustats.
weapon->id().c_str());
3208 lua_setfield(L, -2,
"name");
3210 lua_setfield(L, -2,
"weapon");
3229 int arg_num = 1, att_w = -1, def_w = -1;
3233 if (lua_isnumber(L, arg_num)) {
3234 att_w = lua_tointeger(L, arg_num) - 1;
3235 if (att_w < 0 || att_w >=
static_cast<int>(att->attacks().size()))
3236 return luaL_argerror(L, arg_num,
"weapon index out of bounds");
3242 if (lua_isnumber(L, arg_num)) {
3243 def_w = lua_tointeger(L, arg_num) - 1;
3244 if (def_w < 0 || def_w >=
static_cast<int>(def->attacks().size()))
3245 return luaL_argerror(L, arg_num,
"weapon index out of bounds");
3250 def->get_location(), att_w, def_w, 0.0,
nullptr, att, def);
3267 char const *m = luaL_checkstring(L, 1);
3268 int repeats = luaL_optinteger(L, 2, 0);
3280 const char* content_for = luaL_checkstring(L, 1);
3281 const char*
id = luaL_checkstring(L, 2);
3284 if(group.content_for_ == content_for) {
3286 if(achieve.
id_ ==
id) {
3313 ERR_LUA <<
"Achievement " <<
id <<
" not found for achievement group " << content_for;
3319 ERR_LUA <<
"Achievement group " << content_for <<
" not found";
3331 const char* content_for = luaL_checkstring(L, 1);
3332 const char*
id = luaL_checkstring(L, 2);
3335 ERR_LUA <<
"Returning false for whether a player has completed an achievement due to being networked multiplayer.";
3336 lua_pushboolean(L,
false);
3352 const char* content_for = luaL_checkstring(L, 1);
3353 const char*
id = luaL_checkstring(L, 2);
3357 if(group.content_for_ == content_for) {
3358 for(
const auto& achieve : group.achievements_) {
3359 if(achieve.id_ ==
id) {
3361 cfg[
"id"] = achieve.id_;
3362 cfg[
"name"] = achieve.name_;
3363 cfg[
"name_completed"] = achieve.name_completed_;
3364 cfg[
"description"] = achieve.description_;
3365 cfg[
"description_completed"] = achieve.description_completed_;
3366 cfg[
"icon"] = achieve.icon_;
3367 cfg[
"icon_completed"] = achieve.icon_completed_;
3368 cfg[
"hidden"] = achieve.hidden_;
3369 cfg[
"achieved"] = achieve.achieved_;
3370 cfg[
"max_progress"] = achieve.max_progress_;
3371 cfg[
"current_progress"] = achieve.current_progress_;
3373 for(
const auto& sub_ach : achieve.sub_achievements_) {
3375 sub[
"id"] = sub_ach.id_;
3376 sub[
"description"] = sub_ach.description_;
3377 sub[
"icon"] = sub_ach.icon_;
3378 sub[
"achieved"] = sub_ach.achieved_;
3386 ERR_LUA <<
"Achievement " <<
id <<
" not found for achievement group " << content_for;
3392 ERR_LUA <<
"Achievement group " << content_for <<
" not found";
3408 const char* content_for = luaL_checkstring(L, 1);
3409 const char*
id = luaL_checkstring(L, 2);
3410 int amount = luaL_checkinteger(L, 3);
3411 int limit = luaL_optinteger(L, 4, 999999999);
3414 if(group.content_for_ == content_for) {
3416 if(achieve.
id_ ==
id) {
3419 ERR_LUA <<
"Attempted to progress achievement " <<
id <<
" for achievement group " << content_for <<
", is not a progressible achievement.";
3420 lua_pushinteger(L, -1);
3421 lua_pushinteger(L, -1);
3436 lua_pushinteger(L, progress);
3438 lua_pushinteger(L, -1);
3446 lua_push(L,
"Achievement " + std::string(
id) +
" not found for achievement group " + content_for);
3447 return lua_error(L);
3452 lua_push(L,
"Achievement group " + std::string(content_for) +
" not found");
3453 return lua_error(L);
3465 const char* content_for = luaL_checkstring(L, 1);
3466 const char*
id = luaL_checkstring(L, 2);
3467 const char* sub_id = luaL_checkstring(L, 3);
3470 ERR_LUA <<
"Returning false for whether a player has completed an achievement due to being networked multiplayer.";
3471 lua_pushboolean(L,
false);
3487 const char* content_for = luaL_checkstring(L, 1);
3488 const char*
id = luaL_checkstring(L, 2);
3489 const char* sub_id = luaL_checkstring(L, 3);
3492 if(group.content_for_ == content_for) {
3494 if(achieve.
id_ ==
id) {
3501 if(sub_ach.
id_ == sub_id) {
3519 lua_push(L,
"Sub-achievement " + std::string(
id) +
" not found for achievement" +
id +
" in achievement group " + content_for);
3520 return lua_error(L);
3524 lua_push(L,
"Achievement " + std::string(
id) +
" not found for achievement group " + content_for);
3525 return lua_error(L);
3530 lua_push(L,
"Achievement group " + std::string(content_for) +
" not found");
3531 return lua_error(L);
3567 if(lua_isnoneornil(L, 1)) {
3572 if(!
map().on_board(loc))
return luaL_argerror(L, 1,
"not on board");
3573 bool highlight =
true;
3574 if(!lua_isnoneornil(L, 2))
3604 lua_pushboolean(L, skipping);
3615 if (!lua_isnone(L, 1)) {
3627 int user_choice_index;
3628 int random_choice_index;
3629 int ai_choice_index;
3631 lua_synchronize(lua_State *l,
const std::string& descr,
int user_index,
int random_index = 0,
int ai_index = 0)
3633 , user_choice_index(user_index)
3634 , random_choice_index(random_index)
3635 , ai_choice_index(ai_index != 0 ? ai_index : user_index)
3641 bool is_local_ai = lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).board().get_team(side).is_local_ai();
3643 query_lua(side, is_local_ai ? ai_choice_index : user_choice_index, cfg);
3650 if(random_choice_index != 0 && lua_isfunction(L, random_choice_index)) {
3651 query_lua(side, random_choice_index, cfg);
3661 void query_lua(
int side,
int function_index,
config& cfg)
const
3663 lua_pushvalue(L, function_index);
3664 lua_pushnumber(L, side);
3667 static const char*
msg =
"function returned to wesnoth.sync.[multi_]evaluate a table which was partially invalid";
3668 lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).log_error(
msg);
3669 lua_warning(L,
msg,
false);
3676 virtual bool is_visible()
const override {
return false; }
3690 std::string tagname =
"input";
3697 if(!lua_isfunction(L, nextarg) &&
luaW_totstring(L, nextarg, desc) ) {
3700 if(lua_isfunction(L, nextarg)) {
3701 human_func = nextarg++;
3704 return luaL_argerror(L, nextarg,
"expected a function");
3706 if(lua_isfunction(L, nextarg)) {
3707 ai_func = nextarg++;
3709 side_for = lua_tointeger(L, nextarg);
3725 std::string tagname =
"input";
3729 std::vector<int> sides_for;
3732 if(!lua_isfunction(L, nextarg) &&
luaW_totstring(L, nextarg, desc) ) {
3735 if(lua_isfunction(L, nextarg)) {
3736 human_func = nextarg++;
3739 return luaL_argerror(L, nextarg,
"expected a function");
3741 if(lua_isfunction(L, nextarg)) {
3742 null_func = nextarg++;
3744 sides_for = lua_check<std::vector<int>>(L, nextarg++);
3759 lua_pushvalue(L, 1);
3774 std::set<map_location> res;
3799 if (filter.
null()) {
3800 lua_pushboolean(L,
true);
3809 lua_pushboolean(L, t_filter.
match(loc));
3826 if (filter.
null()) {
3827 lua_pushboolean(L,
true);
3835 lua_pushboolean(L, s_filter.
match(*
t));
3837 unsigned side = luaL_checkinteger(L, 1) - 1;
3839 lua_pushboolean(L, s_filter.
match(side + 1));
3850 team_i = luaL_checkinteger(L, 1);
3852 std::string
flag = luaL_optlstring(L, 2,
"",
nullptr);
3853 std::string color = luaL_optlstring(L, 3,
"",
nullptr);
3855 if(
flag.empty() && color.empty()) {
3858 if(team_i < 1 ||
static_cast<std::size_t
>(team_i) >
teams().
size()) {
3859 return luaL_error(L,
"set_side_id: side number %d out of range", team_i);
3863 if(!color.empty()) {
3878 side_num =
t->side();
3880 side_num = luaL_checkinteger(L, 1);
3882 std::string
path = luaL_checkstring(L, 2);
3887 if(strcmp(action,
"delete") == 0) {
3892 std::size_t len = std::string::npos, open_brak =
path.find_last_of(
'[');
3893 std::size_t dot =
path.find_last_of(
'.');
3894 if(open_brak != len) {
3895 len = open_brak - dot - 1;
3906 side_num =
t->side();
3908 side_num = luaL_checkinteger(L, 1);
3910 if(lua_isstring(L, 2)) {
3911 std::string file = luaL_checkstring(L, 2);
3913 std::string
err =
formatter() <<
"Could not load AI for side " << side_num <<
" from file " << file;
3914 lua_pushlstring(L,
err.c_str(),
err.length());
3915 return lua_error(L);
3927 side_num =
t->side();
3929 side_num = luaL_checkinteger(L, 1);
3933 cfg =
config {
"ai", cfg};
3935 bool added_dummy_stage =
false;
3937 added_dummy_stage =
true;
3941 if(added_dummy_stage) {
3950 unsigned i = luaL_checkinteger(L, 1);
3951 if(i < 1 || i >
teams().
size())
return 0;
3963 LOG_LUA <<
"intf_get_sides called: this = " << std::hex <<
this << std::dec <<
" myname = " <<
my_name();
3964 std::vector<int> sides;
3968 sides.push_back(
t.side());
3978 lua_createtable(L, sides.size(), 0);
3980 for(
int side : sides) {
3982 lua_rawseti(L, -2,
index);
3999 char const *m = luaL_checkstring(L, 2);
4001 if (sm ==
"advance") {
4005 if (sm !=
"advancement" && sm !=
"object" && sm !=
"trait") {
4006 return luaL_argerror(L, 2,
"unknown modification type");
4008 bool write_to_mods =
true;
4009 if (!lua_isnone(L, 4)) {
4013 write_to_mods =
false;
4031 std::vector<std::string> tags;
4032 if(lua_isstring(L, 3)) {
4033 tags.push_back(lua_check<std::string>(L, 3));
4034 }
else if (lua_istable(L, 3)){
4035 tags = lua_check<std::vector<std::string>>(L, 3);
4037 tags.push_back(
"object");
4043 for(
const std::string&
tag : tags) {
4045 if(obj.matches(filter)) {
4046 obj[
"duration"] =
"now";
4066 if(lua_isboolean(L, 2)) {
4069 if(lua_isboolean(L, 3)) {
4083 char const *ty = luaL_checkstring(L, 1);
4086 std::stringstream ss;
4087 ss <<
"unknown unit type: '" << ty <<
"'";
4088 return luaL_argerror(L, 1, ss.str().c_str());
4105 std::string team_name;
4108 std::vector<std::string> team_names;
4109 std::transform(
teams.begin(),
teams.end(), std::back_inserter(team_names),
4110 [&](
int team) { return game_state_.get_disp_context().get_team(team).team_name(); });
4113 team_name = cfg[
"team_name"].str();
4122 cfg[
"visible_in_fog"].to_bool(
true),
4123 cfg[
"submerge"].to_double(0),
4124 cfg[
"z_order"].to_double(0)
4138 char const *m = lua_tostring(L, 2);
4155 const int nargs = lua_gettop(L);
4156 if(nargs < 2 || nargs > 3) {
4157 return luaL_error(L,
"Wrong number of arguments to ai.log_replay() - should be 2 or 3 arguments.");
4159 const std::string key = nargs == 2 ? luaL_checkstring(L, 1) : luaL_checkstring(L, 2);
4165 }
else if(!lua_isstring(L, 3)) {
4166 return luaL_argerror(L, 3,
"accepts only string or config");
4189 cfg.
add_child(
"filter_lua")[
"code"] =
"<function>";
4199 if(lua_isstring(L, idx)) {
4200 return lua_tostring(L, idx);
4240 using namespace std::literals;
4246 }
else if(is_menu_item) {
4248 return luaL_argerror(L, 1,
"non-empty id is required for a menu item");
4250 name =
"menu item " +
id;
4252 if(
id.empty() && name.empty()) {
4253 return luaL_argerror(L, 1,
"either a name or id is required");
4256 if(new_handler.valid()) {
4257 bool has_lua_filter =
false;
4261 int filterIdx = lua_gettop(L);
4264 if(lua_isfunction(L, filterIdx)) {
4265 int fcnIdx = lua_absindex(L, -1);
4266 new_handler->add_filter(std::make_unique<lua_event_filter>(*
this, fcnIdx,
luaW_table_get_def(L, 1,
"filter_args",
config())));
4267 has_lua_filter =
true;
4269 #define READ_ONE_FILTER(key, tag) \
4271 if(luaW_tableget(L, filterIdx, key)) { \
4272 if(lua_isstring(L, -1)) { \
4273 filters.add_child("insert_tag", config{ \
4275 "variable", luaL_checkstring(L, -1) \
4278 filters.add_child(tag, luaW_checkconfig(L, -1)); \
4288 #undef READ_ONE_FILTER
4290 filters[
"filter_formula"] = luaL_checkstring(L, -1);
4294 new_handler->read_filters(filters);
4300 if(has_lua_filter) {
4305 new_handler->register_wml_event(*
this);
4318 lua_pushvalue(L, lua_upvalueindex(1));
4335 template<
bool is_menu_item>
4341 double priority = luaL_optnumber(L, 3, 0.);
4343 return luaL_argerror(L, 1,
"must not be empty");
4347 name =
"menu item " + name;
4348 }
else if(lua_absindex(L, -1) > 2 && lua_isfunction(L, -1)) {
4351 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_undoable_event>, 2);
4354 if(new_handler.valid()) {
4371 bool delayed_variable_substitution = cfg[
"delayed_variable_substitution"].to_bool(
true);
4372 if(delayed_variable_substitution) {
4399 lua_pushinteger(L, color.r);
4400 lua_pushinteger(L, color.g);
4401 lua_pushinteger(L, color.b);
4410 auto vec = lua_check<std::vector<uint8_t>>(L, 1);
4411 if(vec.size() != 4) {
4414 color_t fade{vec[0], vec[1], vec[2], vec[3]};
4432 using namespace std::chrono_literals;
4433 std::chrono::milliseconds delay{luaL_checkinteger(L, 1)};
4441 const auto end_time = std::chrono::steady_clock::now() + delay;
4444 std::this_thread::sleep_for(10ms);
4445 }
while (std::chrono::steady_clock::now() < end_time);
4469 std::string team_name;
4472 if(lua_gettop(L) == 1 && lua_istable(L, 1)) {
4473 using namespace std::literals;
4476 team_name = luaL_optstring(L, 2,
"");
4490 switch(lua_type(L, 2)) {
4492 case LUA_TNONE:
case LUA_TNIL:
4497 if(
size_t n = luaL_checkinteger(L, 2);
n > 0 &&
n <=
teams().size()) {
4537 for (
const int side : filter.
get_teams()){
4559 int side = cfg[
"side"].to_int();
4569 lua_getfield(L, -1,
"ca_ptr");
4583 lua_getfield(L, -1,
"stg_ptr");
4592 lua_createtable(L, 0, 0);
4594 lua_pushstring(L,
"name");
4595 lua_pushstring(L,
c->get_name().c_str());
4598 lua_pushstring(L,
"engine");
4599 lua_pushstring(L,
c->get_engine().c_str());
4602 lua_pushstring(L,
"id");
4603 lua_pushstring(L,
c->get_id().c_str());
4606 if (ct ==
"candidate_action") {
4607 lua_pushstring(L,
"ca_ptr");
4608 lua_pushlightuserdata(L,
c);
4611 lua_pushstring(L,
"exec");
4616 if (ct ==
"stage") {
4617 lua_pushstring(L,
"stg_ptr");
4618 lua_pushlightuserdata(L,
c);
4621 lua_pushstring(L,
"exec");
4627 std::vector<std::string> c_types =
c->get_children_types();
4629 for (std::vector<std::string>::const_iterator
t = c_types.begin();
t != c_types.end(); ++
t)
4631 std::vector<ai::component*> children =
c->get_children(*
t);
4632 std::string
type = *
t;
4633 if (
type ==
"aspect" ||
type ==
"goal" ||
type ==
"engine")
4638 lua_pushstring(L,
type.c_str());
4639 lua_createtable(L, 0, 0);
4641 for (std::vector<ai::component*>::const_iterator
i = children.begin();
i != children.end(); ++
i)
4643 lua_pushstring(L, (*i)->get_name().c_str());
4674 side = luaL_checkinteger(L, 1);
4681 std::vector<ai::component*> engines =
c->get_children(
"engine");
4683 for (std::vector<ai::component*>::const_iterator
i = engines.begin();
i != engines.end(); ++
i)
4685 if ((*i)->get_name() ==
"lua")
4695 if (lua_engine ==
nullptr)
4708 LOG_LUA <<
"Created new dummy lua-engine for debug_ai().";
4718 lua_pushstring(L,
"components");
4744 if(lua_isboolean(L, 1)) {
4769 std::set<map_location> locs;
4772 if(lua_gettop(L) == 1) {
4775 id = cfg[
"id"].str();
4780 id = luaL_checkstring(L, 1);
4781 if(!lua_isnoneornil(L, 3))
4795 LOG_LUA <<
"Lua inserted time_area '" <<
id <<
"'";
4804 const char *
id = luaL_checkstring(L, 1);
4806 LOG_LUA <<
"Lua removed time_area '" <<
id <<
"'";
4816 if(area_index < 0) {
4823 std::string area_id = luaL_checkstring(L, 1);
4825 if(
auto iter = std::find(area_ids.begin(), area_ids.end(), area_id); iter == area_ids.end()) {
4839 if(luaL_testudata(L, 1,
"schedule")) {
4849 ERR_LUA <<
"attempted to to replace ToD schedule with empty schedule";
4855 LOG_LUA <<
"replaced ToD schedule";
4864 point scroll_to(luaL_checkinteger(L, 1), luaL_checkinteger(L, 2));
4881 lua_report_generator(lua_State *L,
const std::string &
n)
4890 if (!
luaW_getglobal(L,
"wesnoth",
"interface",
"game_display", name))
4914 char const *m = luaL_checkstring(L, 2);
4916 lua_pushvalue(L, 2);
4917 lua_pushvalue(L, -2);
4928 char const *m = luaL_checkstring(L, 2);
4929 lua_pushvalue(L, 2);
4930 lua_pushvalue(L, 3);
4971 if (
dst == u->get_location() || !
map().on_board(
dst)) {
4975 if (!
map().on_board(vacant_dst)) {
4986 std::vector<map_location> teleport_path;
4987 teleport_path.push_back(src_loc);
4988 teleport_path.push_back(vacant_dst);
4995 u->anim_comp().set_standing();
5002 if (
map().is_village(vacant_dst)) {
5021 const std::string& logger = lua_isstring(L, 2) ? luaL_checkstring(L, 1) :
"";
5022 const std::string&
msg = lua_isstring(L, 2) ? luaL_checkstring(L, 2) : luaL_checkstring(L, 1);
5024 if(logger ==
"wml" || logger ==
"WML") {
5038 lua_pushboolean(L, fog ?
t.fogged(loc) :
t.shrouded(loc));
5056 bool affect_normal_fog =
false;
5057 if(lua_isboolean(L, -1)) {
5060 std::set<int> sides;
5062 sides.insert(
t->side());
5063 }
else if(lua_isnumber(L, 1)) {
5064 sides.insert(lua_tointeger(L, 1));
5065 }
else if(lua_istable(L, 1) && lua_istable(L, 2)) {
5066 const auto& v = lua_check<std::vector<int>>(L, 1);
5067 sides.insert(v.begin(), v.end());
5070 sides.insert(
t.side()+1);
5075 for(
const int &side_num : sides) {
5076 if(side_num < 1 ||
static_cast<std::size_t
>(side_num) >
teams().
size()) {
5082 t.remove_fog_override(locs);
5083 if(affect_normal_fog) {
5086 }
else if(!affect_normal_fog) {
5088 t.add_fog_override(locs);
5106 const std::string name = luaL_checkstring(L, 1);
5111 if(!
luaW_getglobal(L,
"wesnoth",
"custom_synced_commands", name)) {
5112 return luaL_argerror(L, 1,
"Unknown synced command");
5115 cmd_tag[
"name"] = name;
5116 if(!lua_isnoneornil(L, 2)) {
5134 #define CALLBACK_GETTER(name, type) LATTR_GETTER(name, lua_index_raw, callbacks_tag, ) { lua_pushcfunction(L, &impl_null_callback<type>); return lua_index_raw(L); }
5137 template<
typename Ret>
5139 if constexpr(std::is_same_v<Ret, void>)
return 0;
5145 inline static auto metatable =
"game_events";
5147 return lua_kernel_base::get_lua_kernel<game_lua_kernel>(L);
5168 template<
typename Ret =
void>
5170 int top = lua_gettop(L);
5174 lua_getfield(L, -1, name.c_str());
5175 lua_pushcfunction(L, &impl_null_callback<Ret>);
5176 if(lua_rawequal(L, -1, -2)) {
5232 cmd_log_ <<
"Registering game-specific wesnoth lib functions...\n";
5235 static luaL_Reg
const callbacks[] {
5240 {
"cancel_action", &dispatch<&game_lua_kernel::intf_cancel_action > },
5241 {
"log_replay", &dispatch<&game_lua_kernel::intf_log_replay > },
5242 {
"log", &dispatch<&game_lua_kernel::intf_log > },
5243 {
"redraw", &dispatch<&game_lua_kernel::intf_redraw > },
5244 {
"simulate_combat", &dispatch<&game_lua_kernel::intf_simulate_combat > },
5245 {
nullptr,
nullptr }
5246 };lua_getglobal(L,
"wesnoth");
5247 if (!lua_istable(L,-1)) {
5250 luaL_setfuncs(L, callbacks, 0);
5252 lua_setglobal(L,
"wesnoth");
5254 lua_getglobal(L,
"gui");
5255 lua_pushcfunction(L, &dispatch<&game_lua_kernel::intf_gamestate_inspector>);
5256 lua_setfield(L, -2,
"show_inspector");
5262 static luaL_Reg
const test_callbacks[] {
5263 {
"fire_wml_menu_item", &dispatch<&game_lua_kernel::intf_fire_wml_menu_item> },
5264 {
nullptr,
nullptr }
5266 luaL_setfuncs(L, test_callbacks, 0);
5267 lua_setglobal(L,
"unit_test");
5293 cmd_log_ <<
"Adding terrain_types table...\n";
5294 lua_getglobal(L,
"wesnoth");
5295 lua_newuserdatauv(L, 0, 0);
5296 lua_createtable(L, 0, 2);
5297 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_get_terrain_info>);
5298 lua_setfield(L, -2,
"__index");
5299 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_get_terrain_list>);
5300 lua_setfield(L, -2,
"__dir");
5301 lua_pushstring(L,
"terrain types");
5302 lua_setfield(L, -2,
"__metatable");
5303 lua_setmetatable(L, -2);
5304 lua_setfield(L, -2,
"terrain_types");
5308 cmd_log_ <<
"Adding ai elements table...\n";
5313 cmd_log_ <<
"Adding wesnoth current table...\n";
5315 lua_getglobal(L,
"wesnoth");
5316 lua_newuserdatauv(L, 0, 0);
5317 lua_createtable(L, 0, 2);
5318 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_current_get>);
5319 lua_setfield(L, -2,
"__index");
5320 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_current_dir>);
5321 lua_setfield(L, -2,
"__dir");
5322 lua_pushboolean(L,
true);
5323 lua_setfield(L, -2,
"__dir_tablelike");
5324 lua_pushstring(L,
"current config");
5325 lua_setfield(L, -2,
"__metatable");
5326 lua_setmetatable(L, -2);
5327 lua_setfield(L, -2,
"current");
5331 lua_getglobal(L,
"wml");
5332 static luaL_Reg
const wml_callbacks[] {
5336 {
"get_variable", &dispatch<&game_lua_kernel::intf_get_variable>},
5337 {
"set_variable", &dispatch<&game_lua_kernel::intf_set_variable>},
5338 {
"get_all_vars", &dispatch<&game_lua_kernel::intf_get_all_vars>},
5339 {
nullptr,
nullptr }
5341 luaL_setfuncs(L, wml_callbacks, 0);
5346 static luaL_Reg
const map_callbacks[] {
5353 {
"get_owner", &dispatch<&game_lua_kernel::intf_get_village_owner>},
5354 {
"set_owner", &dispatch<&game_lua_kernel::intf_set_village_owner>},
5356 {
"add_label", &dispatch<&game_lua_kernel::intf_add_label>},
5357 {
"remove_label", &dispatch<&game_lua_kernel::intf_remove_label>},
5358 {
"get_label", &dispatch<&game_lua_kernel::intf_get_label>},
5360 {
"place_area", &dispatch<&game_lua_kernel::intf_add_time_area>},
5361 {
"remove_area", &dispatch<&game_lua_kernel::intf_remove_time_area>},
5362 {
"get_area", &dispatch<&game_lua_kernel::intf_get_time_area>},
5364 {
"find", &dispatch<&game_lua_kernel::intf_get_locations>},
5365 {
"matches", &dispatch<&game_lua_kernel::intf_match_location>},
5367 {
nullptr,
nullptr }
5369 luaL_setfuncs(L, map_callbacks, 0);
5373 cmd_log_ <<
"Adding units module...\n";
5374 static luaL_Reg
const unit_callbacks[] {
5377 {
"erase", &dispatch<&game_lua_kernel::intf_erase_unit>},
5378 {
"extract", &dispatch<&game_lua_kernel::intf_extract_unit>},
5379 {
"matches", &dispatch<&game_lua_kernel::intf_match_unit>},
5380 {
"select", &dispatch<&game_lua_kernel::intf_select_unit>},
5381 {
"to_map", &dispatch<&game_lua_kernel::intf_put_unit>},
5382 {
"to_recall", &dispatch<&game_lua_kernel::intf_put_recall_unit>},
5384 {
"teleport", &dispatch<&game_lua_kernel::intf_teleport>},
5386 {
"ability", &dispatch<&game_lua_kernel::intf_unit_ability>},
5397 {
"find_on_map", &dispatch<&game_lua_kernel::intf_get_units>},
5398 {
"find_on_recall", &dispatch<&game_lua_kernel::intf_get_recall_units>},
5399 {
"get", &dispatch<&game_lua_kernel::intf_get_unit>},
5400 {
"get_hovered", &dispatch<&game_lua_kernel::intf_get_displayed_unit>},
5401 {
"create_animator", &dispatch<&game_lua_kernel::intf_create_animator>},
5404 {
nullptr,
nullptr }
5406 lua_getglobal(L,
"wesnoth");
5408 luaL_setfuncs(L, unit_callbacks, 0);
5409 lua_setfield(L, -2,
"units");
5413 cmd_log_ <<
"Adding sides module...\n";
5414 static luaL_Reg
const side_callbacks[] {
5415 {
"is_enemy", &dispatch<&game_lua_kernel::intf_is_enemy> },
5416 {
"matches", &dispatch<&game_lua_kernel::intf_match_side> },
5417 {
"set_id", &dispatch<&game_lua_kernel::intf_set_side_id> },
5422 {
"find", &dispatch<&game_lua_kernel::intf_get_sides> },
5423 {
"get", &dispatch<&game_lua_kernel::intf_get_side> },
5424 {
"create", &dispatch<&game_lua_kernel::intf_create_side> },
5426 {
"place_shroud", &dispatch2<&game_lua_kernel::intf_toggle_shroud, true>},
5427 {
"remove_shroud", &dispatch2<&game_lua_kernel::intf_toggle_shroud, false>},
5428 {
"override_shroud", &dispatch<&game_lua_kernel::intf_override_shroud>},
5429 {
"is_shrouded", &dispatch2<&game_lua_kernel::intf_get_fog_or_shroud, false>},
5431 {
"place_fog", &dispatch2<&game_lua_kernel::intf_toggle_fog, false>},
5432 {
"remove_fog", &dispatch2<&game_lua_kernel::intf_toggle_fog, true>},
5433 {
"is_fogged", &dispatch2<&game_lua_kernel::intf_get_fog_or_shroud, true>},
5434 {
nullptr,
nullptr }
5436 std::vector<lua_cpp::Reg>
const cpp_side_callbacks {
5437 {
"add_ai_component", std::bind(
intf_modify_ai, std::placeholders::_1,
"add")},
5438 {
"delete_ai_component", std::bind(
intf_modify_ai, std::placeholders::_1,
"delete")},
5439 {
"change_ai_component", std::bind(
intf_modify_ai, std::placeholders::_1,
"change")},
5443 lua_getglobal(L,
"wesnoth");
5445 luaL_setfuncs(L, side_callbacks, 0);
5447 lua_setfield(L, -2,
"sides");
5451 cmd_log_ <<
"Adding interface module...\n";
5452 static luaL_Reg
const intf_callbacks[] {
5453 {
"add_hex_overlay", &dispatch<&game_lua_kernel::intf_add_tile_overlay>},
5454 {
"remove_hex_overlay", &dispatch<&game_lua_kernel::intf_remove_tile_overlay>},
5455 {
"get_color_adjust", &dispatch<&game_lua_kernel::intf_get_color_adjust>},
5456 {
"color_adjust", &dispatch<&game_lua_kernel::intf_color_adjust>},
5457 {
"screen_fade", &dispatch<&game_lua_kernel::intf_screen_fade>},
5458 {
"delay", &dispatch<&game_lua_kernel::intf_delay>},
5459 {
"deselect_hex", &dispatch<&game_lua_kernel::intf_deselect_hex>},
5460 {
"highlight_hex", &dispatch<&game_lua_kernel::intf_highlight_hex>},
5461 {
"float_label", &dispatch<&game_lua_kernel::intf_float_label>},
5462 {
"get_displayed_unit", &dispatch<&game_lua_kernel::intf_get_displayed_unit>},
5463 {
"get_hovered_hex", &dispatch<&game_lua_kernel::intf_get_mouseover_tile>},
5464 {
"get_selected_hex", &dispatch<&game_lua_kernel::intf_get_selected_tile>},
5465 {
"lock", &dispatch<&game_lua_kernel::intf_lock_view>},
5466 {
"is_locked", &dispatch<&game_lua_kernel::intf_view_locked>},
5467 {
"scroll", &dispatch<&game_lua_kernel::intf_scroll>},
5468 {
"scroll_to_hex", &dispatch<&game_lua_kernel::intf_scroll_to_tile>},
5469 {
"skip_messages", &dispatch<&game_lua_kernel::intf_skip_messages>},
5470 {
"is_skipping_messages", &dispatch<&game_lua_kernel::intf_is_skipping_messages>},
5471 {
"zoom", &dispatch<&game_lua_kernel::intf_zoom>},
5472 {
"clear_menu_item", &dispatch<&game_lua_kernel::intf_clear_menu_item>},
5473 {
"set_menu_item", &dispatch<&game_lua_kernel::intf_set_menu_item>},
5474 {
"allow_end_turn", &dispatch<&game_lua_kernel::intf_allow_end_turn>},
5475 {
"clear_chat_messages", &dispatch<&game_lua_kernel::intf_clear_messages>},
5476 {
"end_turn", &dispatch<&game_lua_kernel::intf_end_turn>},
5478 {
"add_chat_message", &dispatch<&game_lua_kernel::intf_message>},
5479 {
"add_overlay_text", &dispatch2<&game_lua_kernel::intf_set_floating_label, true>},
5481 {
nullptr,
nullptr }
5483 lua_getglobal(L,
"wesnoth");
5485 luaL_setfuncs(L, intf_callbacks, 0);
5486 lua_setfield(L, -2,
"interface");
5490 cmd_log_ <<
"Adding achievements module...\n";
5491 static luaL_Reg
const achievement_callbacks[] {
5492 {
"set", &dispatch<&game_lua_kernel::intf_set_achievement> },
5493 {
"has", &dispatch<&game_lua_kernel::intf_has_achievement> },
5494 {
"get", &dispatch<&game_lua_kernel::intf_get_achievement> },
5495 {
"progress", &dispatch<&game_lua_kernel::intf_progress_achievement> },
5496 {
"has_sub_achievement", &dispatch<&game_lua_kernel::intf_has_sub_achievement> },
5497 {
"set_sub_achievement", &dispatch<&game_lua_kernel::intf_set_sub_achievement> },
5498 {
nullptr,
nullptr }
5500 lua_getglobal(L,
"wesnoth");
5502 luaL_setfuncs(L, achievement_callbacks, 0);
5503 lua_setfield(L, -2,
"achievements");
5507 cmd_log_ <<
"Adding audio module...\n";
5508 static luaL_Reg
const audio_callbacks[] {
5509 {
"play", &dispatch<&game_lua_kernel::intf_play_sound > },
5510 {
nullptr,
nullptr }
5512 lua_getglobal(L,
"wesnoth");
5514 luaL_setfuncs(L, audio_callbacks, 0);
5515 lua_setfield(L, -2,
"audio");
5519 cmd_log_ <<
"Adding paths module...\n";
5520 static luaL_Reg
const path_callbacks[] {
5521 {
"find_cost_map", &dispatch<&game_lua_kernel::intf_find_cost_map > },
5522 {
"find_path", &dispatch<&game_lua_kernel::intf_find_path > },
5523 {
"find_reach", &dispatch<&game_lua_kernel::intf_find_reach > },
5524 {
"find_vacant_hex", &dispatch<&game_lua_kernel::intf_find_vacant_tile > },
5525 {
"find_vision_range", &dispatch<&game_lua_kernel::intf_find_vision_range > },
5526 {
nullptr,
nullptr }
5528 lua_getglobal(L,
"wesnoth");
5530 luaL_setfuncs(L, path_callbacks, 0);
5531 lua_setfield(L, -2,
"paths");
5535 cmd_log_ <<
"Adding sync module...\n";
5536 static luaL_Reg
const sync_callbacks[] {
5541 {
nullptr,
nullptr }
5543 lua_getglobal(L,
"wesnoth");
5545 luaL_setfuncs(L, sync_callbacks, 0);
5546 lua_setfield(L, -2,
"sync");
5550 cmd_log_ <<
"Adding schedule module...\n";
5551 static luaL_Reg
const schedule_callbacks[] {
5552 {
"get_time_of_day", &dispatch<&game_lua_kernel::intf_get_time_of_day<false>>},
5553 {
"get_illumination", &dispatch<&game_lua_kernel::intf_get_time_of_day<true>>},
5554 {
"replace", &dispatch<&game_lua_kernel::intf_replace_schedule>},
5555 {
nullptr,
nullptr }
5557 lua_getglobal(L,
"wesnoth");
5559 luaL_setfuncs(L, schedule_callbacks, 0);
5560 lua_createtable(L, 0, 2);
5561 lua_setmetatable(L, -2);
5562 lua_setfield(L, -2,
"schedule");
5569 cmd_log_ <<
"Adding wml_actions table...\n";
5571 lua_getglobal(L,
"wesnoth");
5573 lua_setfield(L, -2,
"wml_actions");
5577 cmd_log_ <<
"Adding wml_conditionals table...\n";
5579 lua_getglobal(L,
"wesnoth");
5581 lua_setfield(L, -2,
"wml_conditionals");
5588 cmd_log_ <<
"Adding effects table...\n";
5590 lua_getglobal(L,
"wesnoth");
5592 lua_setfield(L, -2,
"effects");
5596 cmd_log_ <<
"Adding custom_synced_commands table...\n";
5598 lua_getglobal(L,
"wesnoth");
5600 lua_setfield(L, -2,
"custom_synced_commands");
5604 cmd_log_ <<
"Adding game_events module...\n";
5605 static luaL_Reg
const event_callbacks[] {
5606 {
"add", &dispatch<&game_lua_kernel::intf_add_event> },
5607 {
"add_repeating", &dispatch<&game_lua_kernel::intf_add_event_simple<false>> },
5608 {
"add_menu", &dispatch<&game_lua_kernel::intf_add_event_simple<true>> },
5609 {
"add_wml", &dispatch<&game_lua_kernel::intf_add_event_wml> },
5610 {
"remove", &dispatch<&game_lua_kernel::intf_remove_event> },
5611 {
"fire", &dispatch2<&game_lua_kernel::intf_fire_event, false> },
5612 {
"fire_by_id", &dispatch2<&game_lua_kernel::intf_fire_event, true> },
5613 {
"add_undo_actions", &dispatch<&game_lua_kernel::intf_add_undo_actions> },
5614 {
"set_undoable", &dispatch<&game_lua_kernel::intf_allow_undo > },
5615 {
nullptr,
nullptr }
5617 lua_getglobal(L,
"wesnoth");
5619 luaL_setfuncs(L, event_callbacks, 0);
5620 lua_createtable(L, 0, 2);
5622 lua_setfield(L, -2,
"__dir");
5624 lua_setfield(L, -2,
"__index");
5625 lua_pushstring(L,
"game_events");
5626 lua_setfield(L, -2,
"__metatable");
5627 lua_setmetatable(L, -2);
5628 lua_setfield(L, -2,
"game_events");
5632 cmd_log_ <<
"Adding game_display table...\n";
5636 lua_createtable(L, 0, 2);
5637 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_theme_items_get>);
5638 lua_setfield(L, -2,
"__index");
5639 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_theme_items_set>);
5640 lua_setfield(L, -2,
"__newindex");
5641 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_theme_items_dir>);
5642 lua_setfield(L, -2,
"__dir");
5643 lua_setmetatable(L, -2);
5644 lua_setfield(L, -2,
"game_display");
5648 cmd_log_ <<
"Adding scenario table...\n";
5652 lua_createtable(L, 0, 2);
5653 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_scenario_get>);
5654 lua_setfield(L, -2,
"__index");
5655 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_scenario_set>);
5656 lua_setfield(L, -2,
"__newindex");
5657 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_scenario_dir>);
5658 lua_setfield(L, -2,
"__dir");
5659 lua_setmetatable(L, -2);
5660 lua_setfield(L, -2,
"scenario");
5671 lua_pushstring(L, effect.c_str());
5689 cmd_log_ <<
"Adding races table...\n";
5692 lua_getglobal(L,
"wesnoth");
5694 lua_setfield(L, -2,
"races");
5698 cmd_log_ <<
"Running preload scripts...\n";
5721 using namespace std::literals::string_view_literals;
5722 static constexpr std::array handled_file_tags {
5735 "modify_unit_type"sv,
5741 "terrain_graphics"sv,
5749 return std::binary_search(handled_file_tags.begin(), handled_file_tags.end(),
s);
5765 for(
const auto [child_key, child_cfg] :
level.all_children_view())
5768 lua_createtable(L, 2, 0);
5769 lua_pushstring(L, child_key.c_str());
5770 lua_rawseti(L, -2, 1);
5772 lua_rawseti(L, -2, 2);
5773 lua_rawseti(L, -2, k++);
5787 if(!impl_get_callback<config>(L,
"on_save"))
5800 const std::vector<std::string> src_tags(temp.begin(), temp.end());
5802 for(
const auto& key : src_tags) {
5809 const std::string m =
"Tag is already used: [" + key +
"]";
5830 lua_pushstring(L, ev.
name.c_str());
5839 if (!
luaW_getglobal(L,
"wesnoth",
"custom_synced_commands", name)) {
5855 std::string which_effect = lua_tostring(L, lua_upvalueindex(1));
5870 lua_pushstring(L, description.c_str());
5883 int str_i = lua_gettop(L);
5886 lua_pushstring(L,
"__call");
5887 lua_pushvalue(L, str_i);
5888 lua_pushboolean(L,
true);
5889 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_builtin_effect>, 2);
5891 lua_pushstring(L,
"__descr");
5892 lua_pushvalue(L, str_i);
5893 lua_pushboolean(L,
false);
5894 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_builtin_effect>, 2);
5896 lua_setmetatable(L, -2);
5906 (lua_touserdata(L, lua_upvalueindex(1)));
5920 lua_getglobal(L,
"wesnoth");
5921 lua_pushstring(L,
"wml_actions");
5923 lua_pushstring(L, cmd.c_str());
5924 lua_pushlightuserdata(L,
reinterpret_cast<void *
>(
h));
5925 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_wml_action>, 1);
5938 (lua_touserdata(L, lua_upvalueindex(1)));
5941 lua_pushboolean(L,
h(vcfg));
5952 lua_getglobal(L,
"wesnoth");
5953 lua_pushstring(L,
"wml_conditionals");
5955 lua_pushstring(L, cmd.c_str());
5956 lua_pushlightuserdata(L,
reinterpret_cast<void *
>(
h));
5998 ERR_WML <<
"unknown conditional wml: [" << cmd <<
"]";
6017 int argIdx = lua_gettop(L);
6019 return luaL_error(L,
"wesnoth.wml_actions.command is missing");
6021 lua_pushvalue(L, argIdx);
6030 int evtIdx = lua_gettop(L);
6035 return luaL_ref(L, evtIdx);
6042 int evtIdx = lua_gettop(L);
6046 std::ostringstream lua_name;
6047 lua_name <<
"event ";
6049 lua_name <<
"<anon>";
6054 lua_name <<
"[id=" <<
id <<
"]";
6057 ERR_LUA <<
"Failed to register WML event: " << lua_name.str();
6060 return luaL_ref(L, evtIdx);
6066 idx = lua_absindex(L, idx);
6068 int evtIdx = lua_gettop(L);
6072 lua_pushvalue(L, idx);
6073 return luaL_ref(L, evtIdx);
6080 luaL_unref(L, -1, ref);
6091 lua_geti(L, -1, ref);
6092 if(lua_isnil(L, -1))
return false;
6138 lua_pushvalue(L, -1);
6158 std::string message = std::string() +
"function " + name +
" not found";
6159 log_error(message.c_str(),
"Lua SUF Error");
6163 lua_insert(L, -nArgs - 1);
6175 int top = lua_gettop(L);
6186 if(lua_istable(L, -1)) {
6189 lua_pushvalue(L, -1);
6191 lua_pushvalue(L, top + 1);
6193 lua_pushvalue(L, top + 2);
6198 if(luaL_getmetafield(L, -1,
"__descr")) {
6200 if(lua_isstring(L, -1)) {
6202 descr = lua_tostring(L, -1);
6204 lua_pushvalue(L, -2);
6206 lua_pushvalue(L, top + 1);
6208 lua_pushvalue(L, top + 2);
6211 if(lua_isstring(L, -1) && !lua_isnumber(L, -1)) {
6212 descr = lua_tostring(L, -1);
6214 ERR_LUA <<
"Effect __descr metafunction should have returned a string, but instead returned ";
6215 if(lua_isnone(L, -1)) {
6218 ERR_LUA << lua_typename(L, lua_type(L, -1));
6223 }
else if(need_apply) {
6225 lua_pushvalue(L, top + 1);
6227 lua_pushvalue(L, top + 2);
6265 if(!impl_get_callback<bool>(L,
"on_mouse_button")) {
Various functions that implement attacks and attack calculations.
Various functions related to moving units.
void advance_unit_at(const advance_unit_params ¶ms)
Various functions that implement advancements of units.
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
Class to encapsulate fog/shroud clearing and the resultant sighted events.
bool clear_dest(const map_location &dest, const unit &viewer)
Clears shroud (and fog) at the provided location and its immediate neighbors.
game_events::pump_result_t fire_events()
Fires the sighted events that were earlier recorded by fog/shroud clearing.
bool clear_unit(const map_location &view_loc, team &view_team, std::size_t viewer_id, int sight_range, bool slowed, const movetype::terrain_costs &costs, const map_location &real_loc, const std::set< map_location > *known_units=nullptr, std::size_t *enemy_count=nullptr, std::size_t *friend_count=nullptr, move_unit_spectator *spectator=nullptr, bool instant=true)
Clears shroud (and fog) around the provided location for view_team based on sight_range,...
virtual ai_context & get_ai_context()
unwrap
virtual double evaluate()=0
Evaluate the candidate action, resetting the internal state of the action.
virtual void execute()=0
Execute the candidate action.
static bool add_component(component *root, const std::string &path, const config &cfg)
static void expand_simplified_aspects(side_number side, config &cfg)
Expand simplified aspects, similar to the change from 1.7.2 to 1.7.3 but with some additional syntax ...
static const config & get_default_ai_parameters()
get default AI parameters
virtual config to_config() const
Serialize to config.
virtual void push_ai_table()
Method that pushes the AI table of the lua_context on the stack for debugging purposes.
component * get_component(component *root, const std::string &path)
Proxy class for calling AI action handlers defined in Lua.
static lua_ai_action_handler * create(lua_State *L, char const *code, lua_ai_context &context)
Proxy table for the AI context.
static void init(lua_State *L)
static lua_ai_context * create(lua_State *L, char const *code, engine_lua *engine)
bool add_ai_for_side_from_config(side_number side, const config &cfg, bool replace=true)
Adds active AI for specified side from cfg.
void append_active_ai_for_side(ai::side_number side, const config &cfg)
Appends AI parameters to active AI of the given side.
void raise_user_interact()
Notifies all observers of 'ai_user_interact' event.
static manager & get_singleton()
void modify_active_ai_for_side(ai::side_number side, const config &cfg)
Modifies AI parameters for active AI of the given side.
ai::holder & get_active_ai_holder_for_side_dbg(side_number side)
Gets the active AI holder for debug purposes.
bool play_stage()
Play the turn - strategy.
Computes the statistics of a battle between an attacker and a defender unit.
const battle_context_unit_stats & get_defender_stats() const
This method returns the statistics of the defender.
const combatant & get_attacker_combatant(const combatant *prev_def=nullptr)
Get the simulation results.
const battle_context_unit_stats & get_attacker_stats() const
This method returns the statistics of the attacker.
const combatant & get_defender_combatant(const combatant *prev_def=nullptr)
Variant for storing WML attributes.
std::string str(const std::string &fallback="") const
bool empty() const
Tests for an attribute that either was never set or was set to "".
A config object defines a single node in a WML file, with access to child nodes.
std::size_t attribute_count() const
Count the number of non-blank attributes.
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
const_attr_itors attribute_range() const
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
child_itors child_range(config_key_type key)
config & child_or_add(config_key_type key)
Returns a reference to the first child with the given key.
std::size_t all_children_count() const
void remove_children(config_key_type key, std::function< bool(const config &)> p={})
Removes all children with tag key for which p returns true.
auto child_name_view() const
A non-owning view over all child tag names.
void append_children(const config &cfg)
Adds children from cfg.
void splice_children(config &src, config_key_type key)
Moves all the children with tag key from src to this.
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
config & add_child(config_key_type key)
virtual void play_slice()
void clear_chat_messages()
void add_chat_message(const std::time_t &time, const std::string &speaker, int side, const std::string &msg, events::chat_handler::MESSAGE_TYPE type, bool bell)
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,...
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
const team & viewing_team() const
void remove_overlay(const map_location &loc)
remove_overlay will remove all overlays on a tile.
void recalculate_minimap()
Schedule the minimap for recalculation.
void remove_single_overlay(const map_location &loc, const std::string &toDelete)
remove_single_overlay will remove a single overlay from a tile
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
double turbo_speed() const
void adjust_color_overlay(int r, int g, int b)
Add r,g,b to the colors for all images displayed on the map.
static double get_zoom_factor()
Returns the current zoom factor.
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.
bool set_zoom(bool increase)
Zooms the display in (true) or out (false).
tod_color get_color_overlay() const
void invalidate_all()
Function to invalidate all tiles.
rect map_outside_area() const
Returns the available area for a map, this may differ from the above.
void fade_to(const color_t &color, const std::chrono::milliseconds &duration)
Screen fade.
void add_overlay(const map_location &loc, overlay &&ov)
Functions to add and remove overlays from locations.
const map_location & selected_hex() const
bool show_everything() const
static display * get_singleton()
Returns the display object if a display object exists.
void reinit_flags_for_team(const team &)
Rebuild the flag list (not team colors) for a single side.
const map_location & mouseover_hex() const
void set_view_locked(bool value)
Sets whether the map view is locked (e.g.
bool scroll(const point &amount, bool force=false)
Scrolls the display by amount pixels.
void select_hex(const map_location &hex, const bool browse, const bool highlight=true, const bool fire_event=true, const bool force_unhighlight=false)
void set_position(double xpos, double ypos)
void set_alignment(ALIGN align)
void set_lifetime(const std::chrono::milliseconds &lifetime, const std::chrono::milliseconds &fadeout=std::chrono::milliseconds{100})
void set_color(const color_t &color)
void set_clip_rect(const SDL_Rect &r)
void set_bg_color(const color_t &bg_color)
void set_font_size(int font_size)
virtual const std::vector< team > & teams() const override
unit_map::iterator find_visible_unit(const map_location &loc, const team ¤t_team, bool see_all=false)
virtual const unit_map & units() const override
virtual const gamemap & map() const override
static game_config_manager * get()
const game_config_view & game_config() const
A class grating read only view to a vector of config objects, viewed as one config with all children ...
const config & find_mandatory_child(config_key_type key, const std::string &name, const std::string &value) const
void clear_variable(const std::string &varname)
Clears attributes config children does nothing if varname is no valid variable name.
@ PRELOAD
the preload [event] is fired next phase: PRESTART (normal game), TURN_STARTING_WAITING (reloaded game...
@ INITIAL
creating intitial [unit]s, executing toplevel [lua] etc.
@ PRESTART
the prestart [event] is fired next phase: START (default), GAME_ENDING
@ TURN_PLAYING
The User is controlling the game and invoking actions The game can be saved here.
const std::string & get_theme() const
variable_access_create get_variable_access_write(const std::string &varname)
returns a variable_access that can be used to change the game variables
void set_theme(const std::string &value)
void set_allow_end_turn(bool value, const t_string &reason="")
variable_access_const get_variable_access_read(const std::string &varname) const
returns a variable_access that cannot be used to change the game variables
void display_unit_hex(map_location hex)
Change the unit to be displayed in the sidebar.
void invalidate_unit_after_move(const map_location &src, const map_location &dst)
Same as invalidate_unit() if moving the displayed unit.
virtual void highlight_hex(map_location hex) override
Function to highlight a location.
virtual const map_location & displayed_unit_hex() const override
Virtual functions shadowed in game_display.
void new_turn()
Update lighting settings.
bool maybe_rebuild()
Rebuilds the screen if needs_rebuild(true) was previously called, and resets the flag.
display_chat_manager & get_chat_manager()
void float_label(const map_location &loc, const std::string &text, const color_t &color)
Function to float a label above a tile.
void set_arguments(const config &cfg)
The game event manager loads the scenario configuration object, and ensures that events are handled a...
void add_event_handler_from_wml(const config &handler, game_lua_kernel &lk, bool is_menu_item=false)
Create an event handler from an [event] tag.
pending_event_handler add_event_handler_from_lua(const std::string &name, const std::string &id, bool repeat=false, double priority=0., bool is_menu_item=false)
Create an empty event handler.
bool fire_item(const std::string &id, const map_location &hex, game_data &gamedata, filter_context &fc, unit_map &units, bool is_key_hold_repeat=false) const
Fires the menu item with the given id.
bool erase(const std::string &id)
Erases the item with the provided id.
void set_item(const std::string &id, const vconfig &menu_item)
Updates or creates (as appropriate) the menu item with the given id.
void(* handler)(const queued_event &, const vconfig &)
static const map & registry()
void set_action_canceled()
Sets whether or not wml wants to abort the currently executed user action.
pump_result_t fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
void set_undo_disabled(bool mutated)
[allow_undo] implementation
int intf_get_mouseover_tile(lua_State *L)
Returns the currently overed tile.
void custom_command(const std::string &, const config &)
int intf_put_unit(lua_State *L)
Places a unit on the map.
int intf_get_label(lua_State *L)
int intf_cancel_action(lua_State *)
int intf_set_floating_label(lua_State *L, bool spawn)
Arg 1: text - string Arg 2: options table.
int intf_replace_schedule(lua_State *l)
Replacing the current time of day schedule.
int intf_select_unit(lua_State *L)
Selects and highlights the given location on the map.
int intf_deselect_hex(lua_State *L)
Deselects any highlighted hex on the map.
std::stack< game_events::queued_event const * > queued_events_
int intf_get_all_vars(lua_State *L)
Gets all the WML variables currently set.
int intf_remove_tile_overlay(lua_State *L)
Removes an overlay from a tile.
int intf_screen_fade(lua_State *L)
int intf_erase_unit(lua_State *L)
Erases a unit from the map.
int intf_get_fog_or_shroud(lua_State *L, bool fog)
int intf_override_shroud(lua_State *L)
Overrides the shroud entirely.
int intf_get_variable(lua_State *L)
Gets a WML variable.
int intf_scroll(lua_State *L)
game_lua_kernel(game_state &, play_controller &, reports &)
int intf_set_sub_achievement(lua_State *L)
Marks a single sub-achievement as completed.
int intf_lock_view(lua_State *L)
Sets whether gamemap scrolling is disabled for the user.
void put_unit_helper(const map_location &loc)
int intf_toggle_shroud(lua_State *L, bool place_shroud)
Toggle shroud on some locations Arg 1: Side number Arg 2: List of locations on which to place/remove ...
int intf_match_side(lua_State *L)
Matches a side against the given filter.
int intf_get_selected_tile(lua_State *L)
Returns the currently selected tile.
int cfun_wml_action(lua_State *L)
Executes its upvalue as a wml action.
virtual void log_error(char const *msg, char const *context="Lua error") override
Error reporting mechanisms, used by virtual methods protected_call and load_string.
int cfun_builtin_effect(lua_State *L)
Applies its upvalue as an effect Arg 1: The unit to apply to Arg 3: The [effect] tag contents Arg 3: ...
ai::lua_ai_context * create_lua_ai_context(char const *code, ai::engine_lua *engine)
int intf_has_achievement(lua_State *L)
Returns whether an achievement has been completed.
int intf_gamestate_inspector(lua_State *)
int intf_float_label(lua_State *L)
Floats some text on the map.
int intf_find_reach(lua_State *L)
Finds all the locations reachable by a unit.
bool run_event(const game_events::queued_event &)
Executes the game_events.on_event function.
int intf_end_turn(lua_State *)
int save_wml_event()
Store a WML event in the Lua registry, as a function.
int impl_scenario_dir(lua_State *L)
Get a list of scenario data (__dir metamethod).
int intf_set_achievement(lua_State *L)
Sets an achievement as being completed.
int intf_get_units(lua_State *)
Gets all the units matching a given filter.
int intf_color_adjust(lua_State *L)
int intf_redraw(lua_State *L)
int intf_set_village_owner(lua_State *L)
Sets the owner of a village.
int impl_current_dir(lua_State *L)
Gets a list of date about current point of game (__dir metamethod).
static config preload_config
int intf_find_cost_map(lua_State *L)
Is called with one or more units and builds a cost map.
int intf_get_time_area(lua_State *)
int intf_highlight_hex(lua_State *L)
Highlights the given location on the map.
bool run_wml_event(int ref, const vconfig &args, const game_events::queued_event &ev, bool *out=nullptr)
Run a WML stored in the Lua registry.
int intf_scroll_to_tile(lua_State *L)
Scrolls to given tile.
int intf_get_side(lua_State *L)
int intf_remove_event(lua_State *L)
int intf_is_enemy(lua_State *L)
Returns whether the first side is an enemy of the second one.
static void extract_preload_scripts(const game_config_view &game_config)
int impl_get_terrain_info(lua_State *L)
Gets details about a terrain.
virtual std::string my_name() override
User-visible name of the lua kernel that they are talking to.
int intf_remove_label(lua_State *L)
bool run_wml_action(const std::string &, const vconfig &, const game_events::queued_event &)
Runs a command from an event handler.
int intf_move_floating_label(lua_State *L)
int intf_match_unit(lua_State *L)
Matches a unit against the given filter.
int intf_add_time_area(lua_State *)
Adding new time_areas dynamically with Standard Location Filters.
void clear_wml_event(int ref)
Clear a WML event store in the Lua registry.
int intf_create_animator(lua_State *)
int impl_theme_items_dir(lua_State *L)
Get all available theme_items (__dir metamethod).
int intf_add_event_wml(lua_State *L)
Add a new event handler Arg: A full event specification as a WML config.
int impl_scenario_set(lua_State *L)
Sets some scenario data (__newindex metamethod).
int intf_message(lua_State *L)
Displays a message in the chat window and in the logs.
int intf_set_side_id(lua_State *L)
int intf_view_locked(lua_State *L)
Gets whether gamemap scrolling is disabled for the user.
int intf_get_displayed_unit(lua_State *)
Gets the unit displayed in the sidebar.
bool run_wml_conditional(const std::string &, const vconfig &)
Evaluates a WML conidition.
int intf_get_recall_units(lua_State *L)
Gets the numeric ids of all the units matching a given filter on the recall lists.
int intf_add_label(lua_State *L)
int intf_zoom(lua_State *L)
int intf_log_replay(lua_State *L)
const game_events::queued_event & get_event_info()
int intf_unit_ability(lua_State *L)
Returns true if the unit has the given ability enabled.
void push_builtin_effect()
Registers a function for use as an effect handler.
int impl_run_animation(lua_State *)
std::string apply_effect(const std::string &name, unit &u, const config &cfg, bool need_apply)
int intf_fire_wml_menu_item(lua_State *L)
Fires a wml menu item.
int intf_clear_menu_item(lua_State *L)
void mouse_over_hex_callback(const map_location &loc)
int impl_theme_items_get(lua_State *L)
Creates a field of the theme_items table and returns it (__index metamethod).
int intf_find_vacant_tile(lua_State *L)
Finds a vacant tile.
play_controller & play_controller_
int impl_schedule_dir(lua_State *L)
const gamemap & map() const
int map_locked_
A value != 0 means that the shouldn't remove any units from the map, usually because we are currently...
static std::vector< config > preload_scripts
int intf_get_unit(lua_State *)
Gets the unit at the given location or with the given id.
int impl_current_get(lua_State *L)
Gets some data about current point of game (__index metamethod).
int impl_schedule_set(lua_State *L)
void select_hex_callback(const map_location &loc)
void set_wml_condition(const std::string &, bool(*)(const vconfig &))
Registers a function for use as a conditional handler.
int impl_end_level_data_set(lua_State *)
std::string synced_state()
converts synced_context::get_synced_state() to a string.
int intf_find_path(lua_State *L)
Finds a path between two locations.
int intf_remove_floating_label(lua_State *L)
void set_wml_action(const std::string &, game_events::wml_action::handler)
Registers a function for use as an action handler.
int intf_put_recall_unit(lua_State *L)
Puts a unit on a recall list.
int intf_teleport(lua_State *L)
Teeleports a unit to a location.
void luaW_push_schedule(lua_State *L, int area_index)
int intf_add_tile_overlay(lua_State *L)
Adds an overlay on a tile.
int intf_play_sound(lua_State *L)
Plays a sound, possibly repeated.
void lua_chat(const std::string &caption, const std::string &msg)
int intf_allow_end_turn(lua_State *)
Allow undo sets the flag saying whether the event has mutated the game to false.
int intf_get_village_owner(lua_State *L)
Gets the side of a village owner.
int intf_get_sides(lua_State *L)
Returns a proxy table array for all sides matching the given SSF.
int intf_has_sub_achievement(lua_State *L)
Returns whether an achievement has been completed.
int intf_create_side(lua_State *L)
void initialize(const config &level)
int intf_add_undo_actions(lua_State *L)
Add undo actions for the current active event Arg 1: Either a table of ActionWML or a function to cal...
void save_game(config &level)
Executes the game_events.on_save function and adds to cfg the returned tags.
int impl_scenario_get(lua_State *L)
Gets some scenario data (__index metamethod).
int intf_remove_time_area(lua_State *)
Removing new time_areas dynamically with Standard Location Filters.
int impl_schedule_len(lua_State *L)
int intf_get_locations(lua_State *L)
Gets all the locations matching a given filter.
int intf_add_event(lua_State *L)
Add a new event handler Arg 1: Table of options.
int intf_simulate_combat(lua_State *L)
Simulates a combat between two units.
int impl_get_terrain_list(lua_State *L)
Gets a list of known terrain codes.
std::vector< team > & teams()
int intf_progress_achievement(lua_State *L)
Progresses the provided achievement.
int intf_match_location(lua_State *L)
Matches a location against the given filter.
int intf_toggle_fog(lua_State *L, const bool clear)
Implements the lifting and resetting of fog via WML.
int intf_extract_unit(lua_State *L)
Extracts a unit from the map or a recall list and gives it to Lua.
int intf_log(lua_State *L)
Logs a message Arg 1: (optional) Logger; "wml" for WML errors or deprecations Arg 2: Message Arg 3: W...
int intf_clear_messages(lua_State *)
Removes all messages from the chat window.
int intf_allow_undo(lua_State *)
Allow undo sets the flag saying whether the event has mutated the game to false.
int impl_schedule_get(lua_State *L)
int intf_set_variable(lua_State *L)
Sets a WML variable.
int impl_theme_items_set(lua_State *L)
Sets a field of the theme_items table (__newindex metamethod).
void set_game_display(game_display *gd)
int intf_set_menu_item(lua_State *L)
ai::lua_ai_action_handler * create_lua_ai_action_handler(char const *code, ai::lua_ai_context &context)
int impl_theme_item(lua_State *L, std::string name)
Executes its upvalue as a theme item generator.
bool mouse_button_callback(const map_location &loc, const std::string &button, const std::string &event)
int intf_get_achievement(lua_State *L)
Returns information on a single achievement, or no data if the achievement is not found.
std::vector< int > get_sides_vector(const vconfig &cfg)
Gets a vector of sides from side= attribute in a given config node.
int intf_fire_event(lua_State *L, const bool by_id)
Fires an event.
int intf_delay(lua_State *L)
Delays engine for a while.
int intf_add_event_simple(lua_State *L)
Add a new event handler Arg 1: Event to handle, as a string or list of strings; or menu item ID if th...
bool run_filter(char const *name, const unit &u)
Runs a script from a unit filter.
int intf_find_vision_range(lua_State *L)
Finds all the locations for which a given unit would remove the fog (if there was fog on the map).
int intf_skip_messages(lua_State *L)
Set whether to skip messages Arg 1 (optional) - boolean.
game_display * game_display_
int cfun_undoable_event(lua_State *L)
Upvalue 1: The event function Upvalue 2: The undo function Arg 1: The event content.
void load_game(const config &level)
Executes the game_events.on_load function and passes to it all the scenario tags not yet handled.
int intf_get_time_of_day(lua_State *L)
Gets time of day information.
int intf_get_color_adjust(lua_State *L)
int intf_is_skipping_messages(lua_State *L)
Return true if a replay is in progress but the player has chosen to skip it.
void add_side_wml(config cfg)
creates a new side during a game.
const std::unique_ptr< game_events::manager > events_manager_
game_events::wmi_manager & get_wml_menu_items()
int w() const
Effective map width.
int h() const
Effective map height.
Encapsulates the map of the game.
const std::shared_ptr< terrain_type_data > & tdata() const
virtual void log_error(char const *msg, char const *context="Lua error")
Error reporting mechanisms, used by virtual methods protected_call and load_string.
bool load_string(char const *prog, const std::string &name, error_handler)
void run_lua_tag(const config &cfg)
Runs a [lua] tag.
Storage for a unit, either owned by the Lua code (ptr != 0), a local variable unit (c_ptr !...
bool put_map(const map_location &loc)
int on_recall_list() const
unit_ptr get_shared() const
const terrain_label * set_label(const map_location &loc, const t_string &text, const int creator=-1, const std::string &team="", const color_t color=font::NORMAL_COLOR, const bool visible_in_fog=true, const bool visible_in_shroud=false, const bool immutable=false, const std::string &category="", const t_string &tooltip="")
const terrain_label * get_label(const map_location &loc, const std::string &team_name) const
void recalculate_shroud()
game_classification & get_classification()
events::mouse_handler & get_mouse_handler_base() override
Get a reference to a mouse handler member a derived class uses.
bool is_skipping_story() const
bool is_skipping_replay() const
std::shared_ptr< wb::manager > get_whiteboard() const
virtual void force_end_turn()=0
game_events::wml_event_pump & pump()
std::set< std::string > & encountered_units()
int progress_achievement(const std::string &content_for, const std::string &id, int limit=999999, int max_progress=999999, int amount=0)
Increments the achievement's current progress by amount if it hasn't already been completed.
void set_achievement(const std::string &content_for, const std::string &id)
Marks the specified achievement as completed.
void set_sub_achievement(const std::string &content_for, const std::string &id, const std::string &sub_id)
Marks the specified sub-achievement as completed.
void add_log_data(const std::string &key, const std::string &var)
config generate_report(const std::string &name, const context &ct, bool only_static=false)
void register_generator(const std::string &name, generator *)
const std::set< std::string > & report_list()
An object to leave the synced context during draw or unsynced wml items when we don’t know whether we...
std::vector< int > get_teams() const
bool match(const team &t) const
static map & registry()
using static function variable instead of static member variable to prevent static initialization fia...
static void add_undo_commands(const config &commands, const game_events::queued_event &ctx)
static synced_state get_synced_state()
This class stores all the data for a single 'side' (in game nomenclature).
game_events::pump_result_t get_village(const map_location &, const int owner_side, game_data *fire_event)
Acquires a village from owner_side.
const std::string & team_name() const
void set_color(const std::string &color)
void set_flag(const std::string &flag)
void lose_village(const map_location &)
bool match(const map_location &loc) const
void get_locations(std::set< map_location > &locs, bool with_border=false) const
gets all locations on the map that match this filter
To store label data Class implements logic for rendering.
void replace_schedule(const config &time_cfg)
Replace the time of day schedule.
int number_of_turns() const
const time_of_day get_illuminated_time_of_day(const unit_map &units, const gamemap &map, const map_location &loc, int for_turn=0) const
Returns time of day object for the passed turn at a location.
const std::vector< time_of_day > & times(const map_location &loc=map_location::null_location()) const
std::vector< std::string > get_area_ids() const
const std::set< map_location > & get_area_by_index(int index) const
void remove_time_area(const std::string &id)
Removes a time area from config, making it follow the scenario's normal time-of-day sequence.
void add_time_area(const gamemap &map, const config &cfg)
Adds a new local time area from config, making it follow its own time-of-day sequence.
void replace_local_schedule(const std::vector< time_of_day > &schedule, int area_index, int initial_time=0)
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
const std::set< map_location > & get_area_by_id(const std::string &id) const
std::pair< int, std::string > get_area_on_hex(const map_location &loc) const
void wait_for_end() const
void add_animation(unit_const_ptr animated_unit, const unit_animation *animation, const map_location &src=map_location::null_location(), bool with_bars=false, const std::string &text="", const color_t text_color={0, 0, 0})
std::vector< const unit * > all_matches_with_unit(const unit &u) const
std::vector< const unit * > all_matches_at(const map_location &loc) const
std::vector< const unit * > all_matches_on_map(const map_location *loc=nullptr, const unit *other_unit=nullptr) const
Container associating units to locations.
unit_ptr extract(const map_location &loc)
Extracts a unit from the map.
unit_iterator find(std::size_t id)
std::size_t erase(const map_location &l)
Erases the unit at location l, if any.
umap_retval_pair_t insert(unit_ptr p)
Inserts the unit pointed to by p into the map.
umap_retval_pair_t move(const map_location &src, const map_location &dst)
Moves a unit from location src to location dst.
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.
config_array_view traits() const
A single unit type that the player may recruit.
const unit_type & get_variation(const std::string &id) const
bool has_variation(const std::string &variation_id) const
This class represents a single unit of a specific type.
static void clear_status_caches()
Clear this unit status cache for all units.
static unit_ptr create(const config &cfg, bool use_traits=false, const vconfig *vcfg=nullptr)
Initializes a unit from a config.
Additional functionality for a non-const variable_info.
Information on a WML variable.
A variable-expanding proxy for the config class.
static vconfig unconstructed_vconfig()
This is just a wrapper for the default constructor; it exists for historical reasons and to make it c...
vconfig child(const std::string &key) const
Returns a child of *this whose key is key.
const config & get_config() const
config get_parsed_config() const
child_list get_children(const std::string &key) const
constexpr uint8_t ALPHA_OPAQUE
A component of the AI framework.
Composite AI with turn sequence which is a vector of stages.
Define conditionals for the game's events mechanism, a.k.a.
Definitions for the interface to Wesnoth Markup Language (WML).
Managing the AIs configuration - headers.
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
LUA AI Support engine - creating specific ai components from config.
Define locations as used by the game's events mechanism.
static int intf_modify_ai(lua_State *L, const char *action)
int dispatch(lua_State *L)
static int load_fake_units(lua_State *L, int arg, T &fake_units)
static int impl_animator_get(lua_State *L)
#define SCENARIO_SETTER(name, type)
static int impl_null_callback(lua_State *L)
static int impl_animator_collect(lua_State *L)
#define SCENARIO_GETTER(name, type)
static int intf_unit_resistance(lua_State *L)
Returns unit resistance against a given attack type.
static int intf_synchronize_choice(lua_State *L)
Ensures a value is synchronized among all the clients.
static int luaW_check_schedule(lua_State *L, int idx)
#define SCENARIO_VALID(name)
static lg::log_domain log_scripting_lua("scripting/lua")
static int intf_add_known_unit(lua_State *L)
Adds a new known unit type to the help system.
static int intf_append_ai(lua_State *L)
static int impl_end_level_data_collect(lua_State *L)
static int impl_mp_settings_len(lua_State *L)
#define CURRENT_GETTER(name, type)
#define READ_ONE_FILTER(key, tag)
#define SCHEDULE_SETTER(name, type)
luaW_Registry scenarioReg
bool(*)(const vconfig &) wml_conditional_handler
static int cfun_exec_candidate_action(lua_State *L)
static int intf_run_event_wml(lua_State *L)
static int intf_eval_conditional(lua_State *L)
Evaluates a boolean WML conditional.
static int impl_clear_animation(lua_State *L)
static int intf_advance_unit(lua_State *L)
Advances a unit if the unit has enough xp.
static int impl_add_animation(lua_State *L)
static int intf_debug_ai(lua_State *L)
Debug access to the ai tables.
#define GAME_CONFIG_SIMPLE_SETTER(name)
static int intf_unit_movement_cost(lua_State *L)
Returns unit movement cost on a given terrain.
static int intf_add_modification(lua_State *L)
Adds a modification to a unit.
#define SCHEDULE_GETTER(name, type)
static void luaW_pushsimdata(lua_State *L, const combatant &cmb)
Puts a table at the top of the stack with some combat result.
#define CALLBACK_GETTER(name, type)
static std::string read_event_name(lua_State *L, int idx)
static int intf_remove_modifications(lua_State *L)
Removes modifications from a unit.
int dispatch2(lua_State *L)
static int intf_copy_unit(lua_State *L)
Copies a unit.
static void push_component(lua_State *L, ai::component *c, const std::string &ct="")
static int impl_mp_settings_get(lua_State *L)
static int cfun_exec_stage(lua_State *L)
static int impl_game_events_get(lua_State *L)
static int intf_modify_ai_old(lua_State *L)
Lua frontend to the modify_ai functionality.
static int intf_get_resource(lua_State *L)
Gets a table for an resource tag.
static const char animatorKey[]
static bool is_handled_file_tag(std::string_view s)
These are the child tags of [scenario] (and the like) that are handled elsewhere (in the C++ code).
static int intf_synchronize_choices(lua_State *L)
Ensures a value is synchronized among all the clients.
static int intf_switch_ai(lua_State *L)
static int intf_create_unit(lua_State *L)
Creates a unit from its WML description.
static int intf_transform_unit(lua_State *L)
Changes a unit to the given unit type.
static int impl_floating_label_getmethod(lua_State *L)
static int intf_get_viewing_side(lua_State *L)
Gets currently viewing side.
int(game_lua_kernel::* member_callback)(lua_State *)
int(game_lua_kernel::* member_callback2)(lua_State *, bool)
static int intf_invoke_synced_command(lua_State *L)
static void luaW_push_tod(lua_State *L, const time_of_day &tod)
static int intf_do_unsynced(lua_State *L)
Calls a function in an unsynced context (this specially means that all random calls used by that func...
luaW_Registry scheduleReg
static void luaW_pushsimweapon(lua_State *L, const battle_context_unit_stats &bcustats)
Puts a table at the top of the stack with information about the combatants' weapons.
static int intf_handle_user_interact(lua_State *)
static int intf_unit_jamming_cost(lua_State *L)
Returns unit jamming cost on a given terrain.
static int impl_end_level_data_get(lua_State *L)
static lg::log_domain log_wml("wml")
static int intf_unit_defense(lua_State *L)
Returns unit defense on a given terrain.
static int intf_get_era(lua_State *L)
Gets a table for an era tag.
luaW_Registry & gameConfigReg()
static bool impl_get_callback(lua_State *L, const std::string &name)
#define SCHEDULE_VALID(name)
static int cfun_wml_condition(lua_State *L)
Executes its upvalue as a wml condition and returns the result.
luaW_Registry callbacksReg
static int * luaW_check_floating_label(lua_State *L, int idx)
static int impl_game_events_dir(lua_State *L)
static int intf_unit_vision_cost(lua_State *L)
Returns unit vision cost on a given terrain.
static std::string _(const char *str)
bool get_ability_bool(const std::string &tag_name, const map_location &loc) const
Checks whether this unit currently possesses or is affected by a given ability.
const std::string & id() const
Gets this unit's id.
int side() const
The side this unit belongs to.
void advance_to(const unit_type &t, bool use_traits=false)
Advances this unit to another type.
int defense_modifier(const t_translation::terrain_code &terrain) const
The unit's defense on a given terrain.
int resistance_against(const std::string &damage_name, bool attacker, const map_location &loc, const_attack_ptr weapon=nullptr, const_attack_ptr opp_weapon=nullptr) const
The unit's resistance against a given damage type.
void apply_builtin_effect(std::string type, const config &effect)
Apply a builtin effect to the unit.
void add_modification(const std::string &type, const config &modification, bool no_add=false)
Add a new modification to the unit.
static const std::set< std::string > builtin_effects
std::string describe_builtin_effect(std::string type, const config &effect)
Construct a string describing a built-in effect.
config & get_modifications()
Get the raw modifications.
void expire_modifications(const std::string &duration)
Clears those modifications whose duration has expired.
const map_location & get_location() const
The current map location this unit is at.
int movement_cost(const t_translation::terrain_code &terrain) const
Get the unit's movement cost on a particular terrain.
int vision_cost(const t_translation::terrain_code &terrain) const
Get the unit's vision cost on a particular terrain.
int jamming_cost(const t_translation::terrain_code &terrain) const
Get the unit's jamming cost on a particular terrain.
std::string label
What to show in the filter's drop-down list.
std::string id
Text to match against addon_info.tags()
Define the handlers for the game's events mechanism.
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Standard logging facilities (interface).
#define log_scope(description)
std::decay_t< T > lua_check(lua_State *L, int n)
void luaW_pushconfig(lua_State *L, const config &cfg)
Converts a config object to a Lua table pushed at the top of the stack.
bool luaW_iststring(lua_State *L, int index)
void luaW_push_namedtuple(lua_State *L, const std::vector< std::string > &names)
Push an empty "named tuple" onto the stack.
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
void luaW_pushlocation(lua_State *L, const map_location &ml)
Converts a map location object to a Lua table pushed at the top of the stack.
std::set< map_location > luaW_check_locationset(lua_State *L, int idx)
Converts a table of integer pairs to a set of map location objects.
void luaW_pushtstring(lua_State *L, const t_string &v)
Pushes a t_string on the top of the stack.
bool luaW_pushvariable(lua_State *L, variable_access_const &v)
bool luaW_tovconfig(lua_State *L, int index, vconfig &vcfg)
Gets an optional vconfig from either a table or a userdata.
void luaW_pushvconfig(lua_State *L, const vconfig &cfg)
Pushes a vconfig on the top of the stack.
bool luaW_toboolean(lua_State *L, int n)
int luaW_type_error(lua_State *L, int narg, const char *tname)
std::string_view luaW_tostring(lua_State *L, int index)
bool luaW_getmetafield(lua_State *L, int idx, const char *key)
Like luaL_getmetafield, but returns false if key is an empty string or begins with two underscores.
bool luaW_totstring(lua_State *L, int index, t_string &str)
Converts a scalar to a translatable string.
bool luaW_tableget(lua_State *L, int index, const char *key)
bool luaW_checkvariable(lua_State *L, variable_access_create &v, int n)
bool luaW_pcall(lua_State *L, int nArgs, int nRets, bool allow_wml_error)
Calls a Lua function stored below its nArgs arguments at the top of the stack.
bool luaW_toconfig(lua_State *L, int index, config &cfg)
Converts an optional table or vconfig to a config object.
int luaW_push_locationset(lua_State *L, const std::set< map_location > &locs)
Converts a set of map locations to a Lua table pushed at the top of the stack.
vconfig luaW_checkvconfig(lua_State *L, int index, bool allow_missing)
Gets an optional vconfig from either a table or a userdata.
bool luaW_tolocation(lua_State *L, int index, map_location &loc)
Converts an optional table or pair of integers to a map location object.
map_location luaW_checklocation(lua_State *L, int index)
Converts an optional table or pair of integers to a map location object.
bool luaW_getglobal(lua_State *L, const std::vector< std::string > &path)
Pushes the value found by following the variadic names (char *), if the value is not nil.
t_string luaW_checktstring(lua_State *L, int index)
Converts a scalar to a translatable string.
#define return_cstring_attrib(name, accessor)
#define return_string_attrib(name, accessor)
#define return_cfgref_attrib(name, accessor)
#define return_int_attrib(name, accessor)
#define modify_bool_attrib(name, accessor)
#define return_bool_attrib(name, accessor)
#define return_cfg_attrib(name, accessor)
#define modify_string_attrib(name, accessor)
#define return_string_attrib_deprecated(name, prefix, level, version, msg, accessor)
#define GAME_CONFIG_SETTER(name, type, kernel_type)
#define GAME_CONFIG_GETTER(name, type, kernel_type)
void luaW_pushracetable(lua_State *L)
void luaW_pushteam(lua_State *L, team &tm)
Create a full userdata containing a pointer to the team.
team * luaW_toteam(lua_State *L, int idx)
Test if the top stack element is a team, and if so, return it.
team & luaW_checkteam(lua_State *L, int idx)
Test if the top stack element is a team, and if not, error.
std::set< map_location > location_set
int intf_terrain_mask(lua_State *L)
Replaces part of the map.
int intf_on_border(lua_State *L)
int intf_on_board(lua_State *L)
int intf_terrainmap_iter(lua_State *L)
int intf_terrainmap_get(lua_State *L)
int intf_replace_if_failed(lua_State *L)
lua_unit * luaW_checkunit_ref(lua_State *L, int index)
Similar to luaW_checkunit but returns a lua_unit; use this if you need to handle map and recall units...
unit & luaW_checkunit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
bool luaW_isunit(lua_State *L, int index)
Test if a Lua value is a unit.
unit_ptr luaW_checkunit_ptr(lua_State *L, int index, bool only_on_map)
Similar to luaW_checkunit but returns a unit_ptr; use this instead of luaW_checkunit when using an ap...
lua_unit * luaW_pushlocalunit(lua_State *L, unit &u)
Pushes a private unit on the stack.
unit * luaW_tounit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
lua_unit * luaW_pushunit(lua_State *L, Args... args)
int intf_create_attack(lua_State *L)
const_attack_ptr luaW_toweapon(lua_State *L, int idx)
void luaW_pushweapon(lua_State *L, attack_ptr weapon)
std::map< std::string, config > traits_map
bool clear_shroud(int side, bool reset_fog, bool fire_events)
Function that will clear shroud (and fog) based on current unit positions.
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.
void create_jamming_map(std::map< map_location, int > &jamming, const team &view_team)
Helper function that creates the map of enemy anti-vision that's needed when creating a pathfinding::...
void clear()
Clear the current render target.
const color_t LABEL_COLOR
int add_floating_label(const floating_label &flabel)
add a label floating on the screen above everything else.
void remove_floating_label(int handle, const std::chrono::milliseconds &fadeout)
removes the floating label given by 'handle' from the screen
void move_floating_label(int handle, double xmove, double ymove)
moves the floating label given by 'handle' by (xmove,ymove)
Game configuration data as global variables.
void load_config(const config &v)
bool variable_matches(const vconfig &values)
bool have_location(const vconfig &cfg)
bool have_unit(const vconfig &cfg)
bool conditional_passed(const vconfig &cond)
bool fire_event(const ui_event event, const std::vector< std::pair< widget *, ui_event >> &event_chain, widget *dispatcher, widget *w, F &&... params)
Helper function for fire_event.
std::shared_ptr< halo_record > handle
std::stringstream & log_to_chat()
Use this to show WML errors in the ingame chat.
std::string register_table(lua_State *L)
std::string register_vconfig_metatable(lua_State *L)
Adds the vconfig metatable.
int intf_tovconfig(lua_State *L)
Creates a vconfig containing the WML table.
void set_functions(lua_State *L, const std::vector< lua_cpp::Reg > &functions)
Analogous to lua_setfuncs, it registers a collection of function wrapper objects into a table,...
void push_closure(lua_State *L, const lua_function &f, int nup)
Pushes a closure which retains a std::function object as its first up-value.
int show_gamestate_inspector(const std::string &name, const game_data &data, const game_state &state)
std::string register_metatable(lua_State *L)
std::string register_metatable(lua_State *L)
std::string register_metatables(lua_State *L)
std::string register_metatable(lua_State *L)
std::string register_table(lua_State *L)
std::string register_metatables(lua_State *L)
std::string register_attacks_metatables(lua_State *L)
std::string tag(const std::string &tag_name, Args &&... contents)
config get_user_choice(const std::string &name, const user_choice &uch, int side=0)
std::map< int, config > get_user_choice_multiple_sides(const std::string &name, const user_choice &uch, std::set< int > sides)
Performs a choice for multiple sides for WML events.
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator &calc, const std::size_t width, const std::size_t height, const teleport_map *teleports, bool border)
const teleport_map get_teleport_locations(const unit &u, const team &viewing_team, bool see_all, bool ignore_units, bool check_vision)
map_location find_vacant_tile(const map_location &loc, VACANT_TILE_TYPE vacancy, const unit *pass_check, const team *shroud_check, const game_board *board)
Function that will find a location on the board that is as near to loc as possible,...
Unit and team statistics.
fake_unit_manager * fake_units
play_controller * controller
std::shared_ptr< wb::manager > whiteboard
Contains the general settings which have a default.
void play_sound(const std::string &files, channel_group group, unsigned int repeats)
terrain_code read_terrain_code(std::string_view str, const ter_layer filler)
Reads a single terrain from a string.
std::string write_terrain_code(const terrain_code &tcode)
Writes a single terrain code to a string.
const terrain_code NONE_TERRAIN
void move_unit(const std::vector< map_location > &path, unit_ptr u, bool animate, map_location::direction dir, bool force_scroll)
Display a unit moving along a given path.
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
@ STRIP_SPACES
REMOVE_EMPTY: remove empty elements.
std::string join_map(const T &v, const std::string &major=",", const std::string &minor=":")
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::vector< std::string > split(const config_attribute_value &val)
bool headless()
The game is running headless.
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
This module contains various pathfinding functions and utilities.
std::shared_ptr< const unit > unit_const_ptr
std::shared_ptr< const attack_type > const_attack_ptr
std::shared_ptr< unit > unit_ptr
Define the game's event mechanism.
void lua_push(lua_State *L, const T &val)
std::decay_t< T > luaW_table_get_def(lua_State *L, int index, std::string_view k, const T &def)
returns t[k] where k is the table at index index and k is k or def if it is not convertible to the co...
void luaW_table_set(lua_State *L, int index, std::string_view k, const T &value)
candidate action framework
#define ON_SCOPE_EXIT(...)
Run some arbitrary code (a lambda) when the current scope exits The lambda body follows this header,...
rect dst
Location on the final composed sheet.
rect src
Non-transparent portion of the surface to compose.
A set of achievements tied to a particular content.
Represents a single achievement and its data.
std::string icon_completed_
The icon of the achievement to show on the UI if the achievement is completed.
t_string name_completed_
The name of the achievement to show on the UI if the achievement is completed.
t_string description_completed_
The name of the achievement to show on the UI if the achievement is completed.
bool achieved_
Whether the achievement has been completed.
std::string id_
The ID of the achievement.
int max_progress_
When the achievement's current progress matches or equals this value, then it should be marked as com...
std::string sound_path_
The path to a sound to play when an achievement is completed.
int current_progress_
The current progress value of the achievement.
std::vector< sub_achievement > sub_achievements_
The list of distinct sub-achievements for this achievement.
advances the unit at loc if it has enough experience, maximum 20 times.
advance_unit_params & animate(bool value)
advance_unit_params & fire_events(bool value)
Structure describing the statistics of a unit involved in the battle.
bool slows
Attack slows opponent when it hits.
unsigned int num_blows
Effective number of blows, takes swarm into account.
std::string plague_type
The plague type used by the attack, if any.
bool petrifies
Attack petrifies opponent when it hits.
int drain_percent
Percentage of damage recovered as health.
bool drains
Attack drains opponent when it hits.
const_attack_ptr weapon
The weapon used by the unit to attack the opponent, or nullptr if there is none.
unsigned int rounds
Berserk special can force us to fight more than one round.
int damage
Effective damage of the weapon (all factors accounted for).
bool poisons
Attack poisons opponent when it hits.
unsigned int chance_to_hit
Effective chance to hit as a percentage (all factors accounted for).
int drain_constant
Base HP drained regardless of damage dealt.
bool firststrike
Attack has firststrike special.
int attack_num
Index into unit->attacks() or -1 for none.
bool plagues
Attack turns opponent into a zombie when fatal.
callbacks_tag(game_lua_kernel &k)
The basic class for representing 8-bit RGB or RGBA colour values.
static color_t from_hex_string(std::string_view c)
Creates a new color_t object from a string variable in hex format.
static color_t from_rgb_string(std::string_view c)
Creates a new opaque color_t object from a string variable in "R,G,B" format.
double slowed
Resulting chance we are slowed.
std::vector< double > hp_dist
Resulting probability distribution (might be not as large as max_hp)
double poisoned
Resulting chance we are poisoned.
double average_hp(unsigned int healing=0) const
What's the average hp (weighted average of hp_dist).
double untouched
Resulting chance we were not hit by this opponent (important if it poisons)
void push_schedule(lua_State *L) const
current_tag(game_lua_kernel &k)
Additional information on the game outcome which can be provided by WML.
Error used for any general game error, e.g.
game_config_glk_tag(lua_kernel_base &k)
const map_location & filter_loc() const
Represents a single filter condition on an event.
Holds a lookup table for members of one type of object.
int dir(lua_State *L)
Implement __dir metamethod.
int set(lua_State *L)
Implement __newindex metamethod.
int get(lua_State *L)
Implement __index metamethod.
void serialize(config &cfg) const override
Serializes the filter into a config, if possible.
lua_event_filter(game_lua_kernel &lk, int idx, const config &args)
bool operator()(const game_events::queued_event &event_info) const override
Runs the filter and returns whether it passes on the given event.
static game_lua_kernel & get(lua_State *L, int)
static game_lua_kernel & get(lua_State *L, int)
static scenario_tag get(lua_State *L, int)
static schedule_tag get(lua_State *L, int n)
Cost function object relying on a Lua function.
Encapsulates the map of the game.
static const map_location & null_location()
game_lua_kernel * kernel_
map_locker(game_lua_kernel *kernel)
Interface for querying local choices.
virtual config query_user(int side) const =0
virtual std::string description() const
virtual bool is_visible() const
whether the choice is visible for the user like an advancement choice a non-visible choice is for exa...
virtual config random_choice(int side) const =0
Structure which uses find_routes() to build a cost map This maps each hex to a the movements a unit w...
void add_unit(const unit &u, bool use_max_moves=true)
Adds a units cost map to cost_map (increments the elements in cost_map)
std::pair< int, int > get_pair_at(map_location loc) const
Accessor for the cost/reach-amount pairs.
Object which contains all the possible locations a unit can move to, with associated best routes to t...
Structure which holds a single route between one location and another.
std::vector< map_location > steps
int move_cost
Movement cost for reaching the end of the route.
A refinement of paths for use when calculating vision.
std::set< map_location > edges
The edges are the non-destination hexes bordering the destinations.
An abstract description of a rectangle with integer coordinates.
scenario_tag(game_lua_kernel &k)
auto end_level_set() const
schedule_tag(game_lua_kernel &k)
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.
Represents a distinct sub-achievement within another achievement.
std::string id_
The ID of the sub-achievement.
bool achieved_
Whether the sub-achievement has been completed.
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Object which defines a time of day with associated bonuses, image, sounds etc.
tod_color color
The color modifications that should be made to the game board to reflect the time of day.
int lawful_bonus
The % bonus lawful units receive.
std::string image
The image to be displayed in the game status.
std::string sounds
List of "ambient" sounds associated with this time_of_day, Played at the beginning of turn.
std::string image_mask
The image that is to be laid over all images while this time of day lasts.
pointer get_shared_ptr() const
This is exactly the same as operator-> but it's slightly more readable, and can replace &*iter syntax...
static map_location::direction n
static map_location::direction s
unit_type_data unit_types
Display units performing various actions: moving, attacking, and dying.
Various functions implementing vision (through fog of war and shroud).