118 #include <functional>
136 #define DBG_LUA LOG_STREAM(debug, log_scripting_lua)
137 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
138 #define WRN_LUA LOG_STREAM(warn, log_scripting_lua)
139 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
142 #define ERR_WML LOG_STREAM(err, log_wml)
150 template <member_callback method>
152 return ((lua_kernel_base::get_lua_kernel<game_lua_kernel>(L)).*method)(L);
158 template <member_callback2 method,
bool b>
160 return ((lua_kernel_base::get_lua_kernel<game_lua_kernel>(L)).*method)(L,
b);
207 const vconfig &ssf =
cfg.child(
"filter_side");
210 if(!sides.
empty()) {
WRN_LUA <<
"ignoring duplicate side filter information (inline side=)"; }
212 return filter.get_teams();
216 return filter.get_teams();
228 struct queued_event_context
231 std::stack<qe const *> & stack_;
233 queued_event_context(qe
const *new_qe, std::stack<qe const*> & stack)
239 ~queued_event_context()
254 lua_pushinteger(L, disp->viewing_team().side());
255 lua_pushboolean(L, disp->show_everything());
273 anim.~unit_animator();
282 std::string which = luaL_checkstring(L, 3);
284 std::string hits_str = luaL_checkstring(L, 4);
294 if(lua_istable(L, 5)) {
295 lua_getfield(L, 5,
"target");
298 return luaL_argerror(L, 5,
"target location must be different from animated unit's location");
300 return luaL_argerror(L, 5,
"target location must be adjacent to the animated unit");
305 if(!lua_isnoneornil(L, -1)) {
311 lua_getfield(L, 5,
"value");
312 if(lua_isnumber(L, -1)) {
313 v1 = lua_tointeger(L, -1);
314 }
else if(lua_istable(L, -1)) {
315 lua_rawgeti(L, -1, 1);
316 v1 = lua_tointeger(L, -1);
318 lua_rawgeti(L, -1, 2);
319 v2 = lua_tointeger(L, -1);
321 }
else if(!lua_isnoneornil(L, -1)) {
322 return luaW_type_error(L, 5,
"value",
"number or array of two numbers");
326 lua_getfield(L, 5,
"with_bars");
327 if(lua_isboolean(L, -1)) {
329 }
else if(!lua_isnoneornil(L, -1)) {
330 return luaW_type_error(L, 5,
"with_bars", lua_typename(L, LUA_TBOOLEAN));
334 lua_getfield(L, 5,
"text");
335 if(lua_isstring(L, -1)) {
336 text = lua_tostring(L, -1);
339 }
else if(!lua_isnoneornil(L, -1)) {
344 lua_getfield(L, 5,
"color");
345 if(lua_istable(L, -1) && lua_rawlen(L, -1) == 3) {
346 int idx = lua_absindex(L, -1);
347 lua_rawgeti(L, idx, 1);
348 lua_rawgeti(L, idx, 2);
349 lua_rawgeti(L, idx, 3);
350 color =
color_t(lua_tointeger(L, -3), lua_tointeger(L, -2), lua_tointeger(L, -1));
352 }
else if(!lua_isnoneornil(L, -1)) {
357 lua_getfield(L, 5,
"primary");
359 if(!primary && !lua_isnoneornil(L, -1)) {
364 lua_getfield(L, 5,
"secondary");
366 if(!secondary && !lua_isnoneornil(L, -1)) {
370 }
else if(!lua_isnoneornil(L, 5)) {
374 anim.
add_animation(up, which, u.
get_location(), dest, v1, bars, text, color, hits, primary, secondary, v2);
402 const char* m = lua_tostring(L, 2);
410 luaL_Reg metafuncs[] {
414 {
"run", &dispatch<&game_lua_kernel::impl_run_animation>},
418 luaL_setfuncs(L, metafuncs, 0);
420 lua_setfield(L, -2,
"__metatable");
422 lua_setmetatable(L, -2);
432 name =
cfg[
"name"].str();
435 name = luaL_optstring(L, 1,
"");
453 if(lua_isstring(L, 1) && !lua_isnumber(L, 1)) {
454 std::string
id = luaL_checkstring(L, 1);
464 return luaL_argerror(L, 1,
"expected string or location");
468 if (!ui.
valid())
return 0;
489 if (!ui.
valid())
return 0;
507 std::vector<const unit*>
units;
511 return luaL_argerror(L, 2,
"unit not found");
514 }
else if(!lua_isnoneornil(L, 2)) {
518 return luaL_argerror(L, 2,
"invalid location");
533 lua_rawseti(L, 1,
i);
553 lua_pushboolean(L,
true);
559 WRN_LUA <<
"wesnoth.units.matches called with a secondary unit (3rd argument), ";
560 WRN_LUA <<
"but unit to match was on recall list. ";
561 WRN_LUA <<
"Thus the 3rd argument is ignored.";
568 return luaL_argerror(L, 3,
"unit not found");
608 t.save_id_or_number(),
t.recall_list().find_index(u->id()));
613 lua_rawseti(L, 1,
i);
632 char const *m = luaL_checkstring(L, 1);
649 if(
data.has_child(
"primary_attack")) {
650 data.add_child(
"first",
data.mandatory_child(
"primary_attack"));
651 data.remove_children(
"primary_attack");
653 if(
data.has_child(
"secondary_attack")) {
654 data.add_child(
"second",
data.mandatory_child(
"secondary_attack"));
655 data.remove_children(
"secondary_attack");
666 lua_pushboolean(L,
b);
684 char const *m = luaL_checkstring(L, 1);
689 lua_pushboolean(L,
b);
701 char const *m = luaL_checkstring(L, 1);
713 const std::string m = luaL_checkstring(L, 1);
714 if(m.empty())
return luaL_argerror(L, 1,
"empty variable name");
715 if (lua_isnoneornil(L, 2)) {
743 std::string ids(luaL_checkstring(L, 1));
746 WRN_LUA <<
"[clear_menu_item] has been given an empty id=, ignoring";
763 if(lua_istable(L, 2)) {
775 return luaL_argerror(L, 2,
"expected list of locations");
794 if(lua_istable(L, 2)) {
822 if(!
map().on_board(
loc))
return luaL_argerror(L, 1,
"not on board");
836 unsigned side_1, side_2;
840 side_1 = luaL_checkinteger(L, 1);
845 side_2 = luaL_checkinteger(L, 2);
848 lua_pushboolean(L,
board().get_team(side_1).
is_enemy(side_2));
882 lua_pushstring(L, tod.
id.c_str());
883 lua_setfield(L, -2,
"id");
885 lua_setfield(L, -2,
"lawful_bonus");
887 lua_setfield(L, -2,
"bonus_modified");
888 lua_pushstring(L, tod.
image.c_str());
889 lua_setfield(L, -2,
"image");
891 lua_setfield(L, -2,
"name");
892 lua_pushstring(L, tod.
sounds.c_str());
893 lua_setfield(L, -2,
"sound");
895 lua_setfield(L, -2,
"mask");
897 lua_pushinteger(L, tod.
color.
r);
898 lua_setfield(L, -2,
"red");
899 lua_pushinteger(L, tod.
color.
g);
900 lua_setfield(L, -2,
"green");
901 lua_pushinteger(L, tod.
color.
b);
902 lua_setfield(L, -2,
"blue");
909 lua_newuserdatauv(L, 0, 1);
910 lua_pushinteger(L, area_index);
911 lua_setiuservalue(L, -2, 1);
912 if(luaL_newmetatable(L,
"schedule")) {
913 static luaL_Reg
const schedule_meta[] {
914 {
"__index", &dispatch<&game_lua_kernel::impl_schedule_get>},
915 {
"__newindex", &dispatch<&game_lua_kernel::impl_schedule_set>},
916 {
"__dir", &dispatch<&game_lua_kernel::impl_schedule_dir>},
917 {
"__len", &dispatch<&game_lua_kernel::impl_schedule_len>},
920 luaL_setfuncs(L, schedule_meta, 0);
921 lua_pushstring(L,
"schedule");
922 lua_setfield(L, -2,
"__metatable");
924 lua_setmetatable(L, -2);
929 int save_top = lua_gettop(L);
930 luaL_checkudata(L, idx,
"schedule");
931 lua_getiuservalue(L, idx, 1);
932 int i = luaL_checkinteger(L, -1);
933 lua_settop(L, save_top);
943 #define SCHEDULE_GETTER(name, type) LATTR_GETTER(name, type, schedule_tag, sched)
944 #define SCHEDULE_SETTER(name, type) LATTR_SETTER(name, type, schedule_tag, sched)
945 #define SCHEDULE_VALID(name) LATTR_VALID(name, schedule_tag, sched)
949 inline static auto metatable =
"schedule";
951 schedule_tag sched{lua_kernel_base::get_lua_kernel<game_lua_kernel>(L)};
960 if(lua_isnumber(L, 2)) {
962 int i = lua_tointeger(L, 2) - 1;
963 if(i < 0 || i >=
static_cast<int>(times.size())) {
964 return luaL_argerror(L, 2,
"invalid time of day index");
976 lua_pushinteger(L, times.size());
983 if(lua_isnumber(L, 2)) {
985 int i = lua_tointeger(L, 2) - 1;
986 if(i < 0 || i >=
static_cast<int>(times.size())) {
987 return luaL_argerror(L, 2,
"invalid time of day index");
1006 if(sched.area_index >= 0) {
1007 return sched.tod_man().get_area_time_of_day(sched.area_index).id;
1009 return sched.tod_man().get_time_of_day().id;
1013 const auto& times = sched.area_index < 0 ? sched.tod_man().times() : sched.tod_man().times(sched.area_index);
1015 if(iter == times.end()) {
1016 std::ostringstream
err;
1017 err <<
"invalid time of day ID for ";
1018 if(sched.area_index < 0) {
1019 err <<
"global schedule";
1021 const std::string&
id = sched.tod_man().get_area_id(sched.area_index);
1023 const auto& hexes = sched.tod_man().get_area_by_index(sched.area_index);
1025 err <<
"anonymous empty time area";
1027 err <<
"anonymous time area at (" << hexes.begin()->wml_x() <<
',' << hexes.begin()->wml_y() <<
")";
1030 err <<
"time area with id=" <<
id;
1036 int n = std::distance(times.begin(), iter);
1037 if(sched.area_index < 0) {
1038 sched.tod_man().set_current_time(
n);
1040 sched.tod_man().set_current_time(
n, sched.area_index);
1045 return sched.area_index < 0;
1049 if(sched.area_index >= 0)
return utils::nullopt;
1050 return sched.tod_man().get_max_liminal_bonus();
1054 if(sched.area_index >= 0) {
1055 throw luaL_error(L,
"liminal_bonus can only be set on the global schedule");
1058 sched.tod_man().set_max_liminal_bonus(*
value);
1060 sched.tod_man().reset_max_liminal_bonus();
1065 return sched.area_index >= 0;
1069 if(sched.area_index < 0)
return utils::nullopt;
1070 return sched.tod_man().get_area_id(sched.area_index);
1074 if(sched.area_index < 0) {
1075 throw luaL_error(L,
"can't set id of global schedule");
1077 sched.tod_man().set_area_id(sched.area_index,
value);
1081 return sched.area_index >= 0;
1085 if(sched.area_index < 0)
return utils::nullopt;
1086 return sched.tod_man().get_area_by_index(sched.area_index);
1090 if(sched.area_index < 0) {
1091 throw luaL_error(L,
"can't set hexes of global schedule");
1093 sched.tod_man().replace_area_locations(sched.area_index,
value);
1104 char const *m = luaL_checkstring(L, 2);
1108 if (!
info.is_nonnull())
return 0;
1111 lua_pushstring(L,
info.id().c_str());
1112 lua_setfield(L, -2,
"id");
1114 lua_setfield(L, -2,
"name");
1116 lua_setfield(L, -2,
"editor_name");
1118 lua_setfield(L, -2,
"description");
1120 lua_setfield(L, -2,
"icon");
1122 lua_setfield(L, -2,
"editor_image");
1123 lua_pushinteger(L,
info.light_bonus(0));
1124 lua_setfield(L, -2,
"light");
1125 lua_pushboolean(L,
info.is_village());
1126 lua_setfield(L, -2,
"village");
1127 lua_pushboolean(L,
info.is_castle());
1128 lua_setfield(L, -2,
"castle");
1129 lua_pushboolean(L,
info.is_keep());
1130 lua_setfield(L, -2,
"keep");
1131 lua_pushinteger(L,
info.gives_healing());
1132 lua_setfield(L, -2,
"healing");
1137 for (
const auto& terrain :
info.mvt_type()) {
1139 if (!base.
id().empty()) {
1141 lua_rawseti(L, -2, idx++);
1144 lua_setfield(L, -2,
"mvt_alias");
1149 for (
const auto& terrain :
info.def_type()) {
1151 if (!base.
id().empty()) {
1153 lua_rawseti(L, -2, idx++);
1156 lua_setfield(L, -2,
"def_alias");
1168 std::vector<std::string> terrains;
1169 terrains.reserve(codes.size());
1170 for(
auto code : codes) {
1183 template<
bool cons
ider_illuminates>
1190 if(!
map().on_board_with_border(
loc)) {
1191 return luaL_argerror(L, 1,
"coordinates are not on board");
1193 }
else if(lua_isstring(L, 1)) {
1196 return luaL_error(L,
"invalid or empty time_area ID");
1199 loc = *area.begin();
1200 }
else if(!lua_isnil(L, 1)) {
1203 return luaL_error(L,
"empty time_area");
1206 loc = *area.begin();
1209 if(lua_isnumber(L, 2)) {
1210 for_turn = luaL_checkinteger(L, 2);
1212 if(for_turn < 1 || (number_of_turns != -1 && for_turn > number_of_turns)) {
1213 return luaL_argerror(L, 2,
"turn number out of range");
1234 if (!
map().is_village(
loc))
1238 if (!side)
return 0;
1239 lua_pushinteger(L, side);
1251 if(!
map().is_village(
loc)) {
1256 const int new_side_num = lua_isnoneornil(L, 2) ? 0 : luaL_checkinteger(L, 2);
1258 team* old_side =
nullptr;
1259 team* new_side =
nullptr;
1261 if(old_side_num == new_side_num) {
1267 }
catch(
const std::out_of_range&) {
1274 }
catch(
const std::out_of_range&) {
1280 if(new_side &&
board().team_is_defeated(*new_side)) {
1313 if (!
map().on_board(
loc))
return 0;
1331 if (!
map().on_board(
loc))
return 0;
1346 std::string m = luaL_checkstring(L, 1);
1352 return luaL_argerror(L, 1, (
"Cannot find resource with id '" + m +
"'").c_str());
1364 std::string m = luaL_checkstring(L, 1);
1370 return luaL_argerror(L, 1, (
"Cannot find era with id '" + m +
"'").c_str());
1385 #define GAME_CONFIG_SIMPLE_SETTER(name) \
1386 GAME_CONFIG_SETTER(#name, decltype(game_config::name), game_lua_kernel) { \
1388 game_config::name = value; \
1394 return k2.pc().gamestate().do_healing_;
1399 k2.pc().gamestate().do_healing_ =
value;}
1403 return k2.pc().get_classification().random_mode;
1414 k2.disp()->set_theme(
value);
1417 using traits_map = std::map<std::string, config>;
1420 std::map<std::string, config> result;
1425 result.emplace(trait[
"id"], trait);
1441 static config find_addon(
const std::string&
type,
const std::string&
id)
1451 const char* m = luaL_checkstring(L, 2);
1469 struct end_level_committer {
1471 ~end_level_committer() {
1472 pc_.set_end_level_data(data_);
1483 const char* m = luaL_checkstring(L, 2);
1499 data->~end_level_data();
1508 if(lua_type(L, 2) == LUA_TNUMBER) {
1511 std::size_t
i = luaL_checkinteger(L, 2);
1513 lua_createtable(L, 2, 0);
1514 lua_pushstring(L,
"options");
1522 auto iter =
settings.addons.begin();
1523 std::advance(iter,
i);
1525 iter->second.write(
cfg);
1526 cfg[
"id"] = iter->first;
1528 lua_createtable(L, 2, 0);
1529 lua_pushstring(L,
"addon");
1537 char const *m = luaL_checkstring(L, 2);
1565 if(strcmp(m,
"savegame") == 0) {
1567 if(
savegame == saved_game_mode::type::no) {
1568 lua_pushboolean(L,
false);
1574 if(strcmp(m,
"side_players") == 0) {
1578 if(strcmp(m,
"addons") == 0) {
1579 for(
const auto& [
id, addon] :
settings.addons) {
1580 lua_createtable(L, 0, 4);
1582 lua_setfield(L, -2,
"id");
1584 lua_setfield(L, -2,
"name");
1585 lua_pushboolean(L, addon.required);
1586 lua_setfield(L, -2,
"required");
1587 if(addon.min_version) {
1589 lua_push(L, addon.min_version->str());
1591 lua_setfield(L, -2,
"min_version");
1597 lua_setfield(L, -2,
"version");
1599 lua_createtable(L, addon.content.size(), 0);
1600 for(
const auto& content : addon.content) {
1601 lua_createtable(L, 0, 3);
1603 lua_setfield(L, -2,
"id");
1605 lua_setfield(L, -2,
"name");
1607 lua_setfield(L, -2,
"type");
1608 lua_seti(L, -2, lua_rawlen(L, -2) + 1);
1610 lua_setfield(L, -2,
"content");
1628 lua_pushinteger(L,
settings.addons.size() + 1);
1639 auto end_level_set()
const {
return &dispatch<&game_lua_kernel::impl_end_level_data_set>; }
1641 #define SCENARIO_GETTER(name, type) LATTR_GETTER(name, type, scenario_tag, k)
1642 #define SCENARIO_SETTER(name, type) LATTR_SETTER(name, type, scenario_tag, k)
1643 #define SCENARIO_VALID(name) LATTR_VALID(name, scenario_tag, k)
1647 inline static auto metatable =
"scenario";
1649 return lua_kernel_base::get_lua_kernel<game_lua_kernel>(L);
1655 return k.tod_man().number_of_turns();
1659 k.tod_man().set_number_of_turns_by_wml(
value);
1663 return k.gamedata().next_scenario();
1667 k.gamedata().set_next_scenario(
value);
1671 return k.gamedata().get_id();
1675 return k.pc().get_scenario_name();
1679 return k.gamedata().get_defeat_music();
1683 k.gamedata().set_defeat_music(
value);
1687 return k.gamedata().get_victory_music();
1691 k.gamedata().set_victory_music(
value);
1696 for(
const std::string& rsrc :
utils::split(k.pc().get_loaded_resources())) {
1697 resources.push_back(find_addon(
"resource", rsrc));
1707 return k.cls().difficulty;
1711 return k.cls().end_credits;
1715 k.cls().end_credits =
value;
1719 return k.cls().end_text;
1723 k.cls().end_text =
value;
1727 return k.cls().end_text_duration.count();
1731 k.cls().end_text_duration = std::chrono::milliseconds{
value};
1735 return !k.cls().campaign.empty();
1739 if(k.cls().campaign.empty())
return utils::nullopt;
1740 return find_addon(
"campaign", k.cls().campaign);
1744 std::vector<config> mods;
1745 for(
const std::string& mod : k.cls().active_mods) {
1746 mods.push_back(find_addon(
"modification", mod));
1752 if (!k.pc().is_regular_game_end()) {
1756 auto data = k.pc().get_end_level_data();
1759 static luaL_Reg
const callbacks[] {
1761 {
"__newindex", k.end_level_set()},
1763 {
nullptr,
nullptr }
1766 lua_setfield(L, -2,
"__metatable");
1767 luaL_setfuncs(L, callbacks, 0);
1769 lua_setmetatable(L, -2);
1776 data.proceed_to_next_level =
value[
"proceed_to_next_level"].to_bool(
true);
1777 data.transient.carryover_report =
value[
"carryover_report"].to_bool(
true);
1778 data.prescenario_save =
value[
"save"].to_bool(
true);
1779 data.replay_save =
value[
"replay_save"].to_bool(
true);
1780 data.transient.linger_mode =
value[
"linger_mode"].to_bool(
true) && !k.ref.teams().empty();
1781 data.transient.reveal_map =
value[
"reveal_map"].to_bool(k.pc().reveal_map_default());
1782 data.is_victory =
value[
"result"] == level_result::victory;
1783 data.test_result =
value[
"test_result"].str();
1784 k.pc().set_end_level_data(
data);
1788 return k.cls().is_multiplayer();
1792 if(!k.cls().is_multiplayer()) {
1797 new(L)
type(&k.pc());
1798 if(luaL_newmetatable(L,
"mp settings")) {
1800 lua_setfield(L, -2,
"__index");
1802 lua_setfield(L, -2,
"__len");
1804 lua_setfield(L, -2,
"__metatable");
1806 lua_setmetatable(L, -2);
1811 return k.cls().is_multiplayer();
1815 if(!k.cls().is_multiplayer())
return utils::nullopt;
1816 return find_addon(
"era", k.cls().era_id);
1828 DBG_LUA <<
"impl_scenario_get";
1840 DBG_LUA <<
"impl_scenario_set";
1849 DBG_LUA <<
"impl_scenario_dir";
1866 return "local_choice";
1885 #define CURRENT_GETTER(name, type) LATTR_GETTER(name, type, current_tag, k)
1889 inline static auto metatable =
"current";
1891 return lua_kernel_base::get_lua_kernel<game_lua_kernel>(L);
1897 return k.pc().current_side();
1901 return k.pc().turn();
1924 return k.pc().is_replay();
1942 cfg[
"damage_inflicted"] = di;
1988 if (lua_isnone(L, 2)) {
1994 LOG_LUA <<
"Script says: \"" << m <<
"\"";
2003 double factor = luaL_checknumber(L, 1);
2030 if (!lua_isnoneornil(L, 1)) {
2031 int max = 2 *
teams().size();
2032 int npn = luaL_checkinteger(L, 1);
2033 if (npn <= 0 || npn > max) {
2034 return luaL_argerror(L, 1,
"side number out of range");
2051 lua_pushboolean(L,
b);
2068 const unit* u =
nullptr;
2069 int viewing_side = 0;
2071 if (lua_isuserdata(L, arg))
2075 viewing_side = u->
side();
2084 viewing_side = u->
side();
2091 if (!
map().on_board(
src))
2092 return luaL_argerror(L, 1,
"invalid location");
2093 if (!
map().on_board(
dst))
2094 return luaL_argerror(L, arg,
"invalid location");
2097 bool ignore_units =
false, see_all =
false, ignore_teleport =
false;
2098 double stop_at = 10000;
2099 std::unique_ptr<pathfind::cost_calculator> calc;
2101 if (lua_istable(L, arg))
2103 ignore_units = luaW_table_get_def<bool>(L, arg,
"ignore_units",
false);
2104 see_all = luaW_table_get_def<bool>(L, arg,
"ignore_visibility",
false);
2105 ignore_teleport = luaW_table_get_def<bool>(L, arg,
"ignore_teleport",
false);
2107 stop_at = luaW_table_get_def<double>(L, arg,
"max_cost", stop_at);
2109 lua_pushstring(L,
"viewing_side");
2111 if (!lua_isnil(L, -1)) {
2112 int i = luaL_checkinteger(L, -1);
2113 if(
board().has_team(
i)) {
2116 return luaL_argerror(L, -1,
"invalid viewing side");
2121 lua_pushstring(L,
"calculate");
2123 if(lua_isfunction(L, -1)) {
2127 }
else if(!lua_isnoneornil(L, arg)) {
2128 return luaL_argerror(L, arg,
"table expected");
2133 if(!ignore_teleport) {
2134 if(viewing_side == 0) {
2135 lua_warning(L,
"wesnoth.paths.find_path: ignore_teleport=false requires a valid viewing_side; continuing with ignore_teleport=true",
false);
2136 ignore_teleport =
true;
2144 return luaL_argerror(L, 1,
"unit not found OR custom cost function not provided");
2148 teams(),
map(), ignore_units,
false, see_all));
2152 &teleport_locations);
2154 int nb = res.
steps.size();
2155 lua_createtable(L, nb, 0);
2156 for (
int i = 0;
i < nb; ++
i)
2159 lua_rawseti(L, -2,
i + 1);
2175 const unit* u =
nullptr;
2177 if (lua_isuserdata(L, arg))
2187 return luaL_argerror(L, 1,
"unit not found");
2192 int viewing_side = u->
side();
2193 bool ignore_units =
false, see_all =
false, ignore_teleport =
false;
2194 int additional_turns = 0;
2196 if (lua_istable(L, arg))
2198 ignore_units = luaW_table_get_def<bool>(L, arg,
"ignore_units",
false);
2199 see_all = luaW_table_get_def<bool>(L, arg,
"ignore_visibility",
false);
2200 ignore_teleport = luaW_table_get_def<bool>(L, arg,
"ignore_teleport",
false);
2201 additional_turns = luaW_table_get_def<int>(L, arg,
"max_cost", additional_turns);
2203 lua_pushstring(L,
"viewing_side");
2205 if (!lua_isnil(L, -1)) {
2206 int i = luaL_checkinteger(L, -1);
2207 if(
board().has_team(
i)) {
2210 return luaL_argerror(L, -1,
"invalid viewing side");
2214 }
else if(!lua_isnoneornil(L, arg)) {
2215 return luaL_argerror(L, arg,
"table expected");
2221 viewing_team, additional_turns, see_all, ignore_units);
2226 lua_createtable(L, nb, 0);
2227 for (
int i = 0;
i < nb; ++
i)
2230 tuple_builder.push(L);
2231 lua_pushinteger(L,
s.curr.wml_x());
2232 lua_rawseti(L, -2, 1);
2233 lua_pushinteger(L,
s.curr.wml_y());
2234 lua_rawseti(L, -2, 2);
2235 lua_pushinteger(L,
s.move_left);
2236 lua_rawseti(L, -2, 3);
2237 lua_rawseti(L, -2,
i + 1);
2252 const unit* u =
nullptr;
2254 if (lua_isuserdata(L, arg))
2264 return luaL_argerror(L, 1,
"unit not found");
2271 return luaL_error(L,
"wesnoth.find_vision_range: requires a valid unit");
2274 std::map<map_location, int> jamming_map;
2282 tuple_builder.push(L);
2283 lua_pushinteger(L,
d.curr.wml_x());
2284 lua_rawseti(L, -2, 1);
2285 lua_pushinteger(L,
d.curr.wml_y());
2286 lua_rawseti(L, -2, 2);
2287 lua_pushinteger(L,
d.move_left);
2288 lua_rawseti(L, -2, 3);
2289 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
2291 for(
const auto&
e : res.
edges) {
2292 tuple_builder.push(L);
2293 lua_pushinteger(L,
e.wml_x());
2294 lua_rawseti(L, -2, 1);
2295 lua_pushinteger(L,
e.wml_y());
2296 lua_rawseti(L, -2, 2);
2297 lua_pushinteger(L, -1);
2298 lua_rawseti(L, -2, 3);
2299 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
2304 template<
typename T>
2307 for (
int i = 1, i_end = lua_rawlen(L, arg);
i <= i_end; ++
i)
2310 lua_rawgeti(L, arg,
i);
2311 int entry = lua_gettop(L);
2312 if (!lua_istable(L, entry)) {
2320 lua_rawgeti(L, entry, 3);
2321 if (!lua_isnumber(L, -1)) {
2322 lua_getfield(L, entry,
"side");
2323 if (!lua_isnumber(L, -1)) {
2327 int side = lua_tointeger(L, -1);
2329 lua_rawgeti(L, entry, 4);
2330 if (!lua_isstring(L, -1)) {
2331 lua_getfield(L, entry,
"type");
2332 if (!lua_isstring(L, -1)) {
2336 std::string
unit_type = lua_tostring(L, -1);
2340 lua_settop(L, entry - 1);
2344 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");
2362 std::vector<const ::unit*> real_units;
2363 typedef std::vector<std::tuple<map_location, int, std::string>> unit_type_vector;
2369 real_units.push_back(
unit);
2374 if(match->get_location().valid()) {
2375 real_units.push_back(match);
2385 real_units.push_back(&(*ui));
2390 if (lua_istable(L, arg))
2398 return luaL_argerror(L, 1,
"unit(s) not found");
2401 int viewing_side = 0;
2402 bool ignore_units =
true, see_all =
true, ignore_teleport =
false,
debug =
false, use_max_moves =
false;
2404 if (lua_istable(L, arg))
2406 lua_pushstring(L,
"ignore_units");
2408 if (!lua_isnil(L, -1))
2414 lua_pushstring(L,
"ignore_teleport");
2416 if (!lua_isnil(L, -1))
2422 lua_pushstring(L,
"viewing_side");
2424 if (!lua_isnil(L, -1))
2426 int i = luaL_checkinteger(L, -1);
2427 if (
i >= 1 &&
i <=
static_cast<int>(
teams().
size()))
2434 lua_pushstring(L,
"debug");
2436 if (!lua_isnil(L, -1))
2442 lua_pushstring(L,
"use_max_moves");
2444 if (!lua_isnil(L, -1))
2466 const team& viewing_team = viewing_side
2471 ignore_units, !ignore_teleport, viewing_team, see_all, ignore_units);
2473 for (const ::unit*
const u : real_units)
2475 cost_map.
add_unit(*u, use_max_moves);
2477 for (
const unit_type_vector::value_type& fu :
fake_units)
2480 cost_map.
add_unit(std::get<0>(fu), ut, std::get<1>(fu));
2489 std::stringstream
s;
2505 tuple_builder.push(L);
2508 lua_rawseti(L, -2, 1);
2511 lua_rawseti(L, -2, 2);
2514 lua_rawseti(L, -2, 3);
2517 lua_rawseti(L, -2, 4);
2519 lua_rawseti(L, -2, counter);
2529 return reinterpret_cast<int*
>(luaL_checkudata(L, idx,
labelKey));
2534 const char* m = luaL_checkstring(L, 2);
2542 std::chrono::milliseconds fade{luaL_optinteger(L, 2, -1)};
2590 int handle_idx = lua_gettop(L);
2595 double width_ratio = 0;
2597 int lifetime = 2'000, fadeout = 100;
2604 if(lua_istable(L, idx+1)) {
2606 size = luaL_checkinteger(L, -1);
2610 width = lua_tointegerx(L, -1, &found_number);
2615 value.remove_suffix(1);
2617 }
else throw std::invalid_argument(
value.data());
2618 }
catch(std::invalid_argument&) {
2619 return luaL_argerror(L, -1,
"max_width should be integer or percentage");
2625 if(lua_isstring(L, -1)) {
2628 auto vec = lua_check<std::vector<int>>(L, -1);
2629 if(vec.size() != 3) {
2630 int idx = lua_absindex(L, -1);
2632 color.r = luaL_checkinteger(L, -3);
2633 color.g = luaL_checkinteger(L, -2);
2634 color.b = luaL_checkinteger(L, -1);
2636 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");
2646 if(lua_isstring(L, -1)) {
2649 auto vec = lua_check<std::vector<int>>(L, -1);
2650 if(vec.size() != 3) {
2651 int idx = lua_absindex(L, -1);
2653 bgcolor.r = luaL_checkinteger(L, -3);
2654 bgcolor.g = luaL_checkinteger(L, -2);
2655 bgcolor.b = luaL_checkinteger(L, -1);
2657 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");
2667 bgcolor.a = luaL_checkinteger(L, -1);
2672 lifetime = lua_tointegerx(L, -1, &found_number);
2675 if(
value ==
"unlimited") {
2678 return luaL_argerror(L, -1,
"duration should be integer or 'unlimited'");
2683 fadeout = lua_tointeger(L, -1);
2689 border = std::max<int>(0, lua_tointeger(L, -1));
2692 static const char* options[] = {
"left",
"center",
"right"};
2693 alignment =
font::ALIGN(luaL_checkoption(L, -1,
nullptr, options));
2696 static const char* options[] = {
"top",
"center",
"bottom"};
2697 vertical_alignment =
font::ALIGN(luaL_checkoption(L, -1,
nullptr, options));
2706 if(width_ratio > 0) {
2707 width =
static_cast<int>(std::round(
rect.w * width_ratio));
2721 switch(vertical_alignment) {
2737 using std::chrono::milliseconds;
2745 flabel.
set_lifetime(milliseconds{lifetime}, milliseconds{fadeout});
2756 lua_settop(L, handle_idx);
2757 if(luaL_newmetatable(L,
labelKey)) {
2759 static const luaL_Reg methods[] = {
2760 {
"remove", &dispatch<&game_lua_kernel::intf_remove_floating_label>},
2761 {
"move", &dispatch<&game_lua_kernel::intf_move_floating_label>},
2762 {
"replace", &dispatch2<&game_lua_kernel::intf_set_floating_label, false>},
2764 {
nullptr,
nullptr }
2766 luaL_setfuncs(L, methods, 0);
2769 lua_setmetatable(L, handle_idx);
2770 lua_settop(L, handle_idx);
2795 return luaL_error(L,
"Attempted to move a unit while the map is locked");
2800 if (!
map().on_board(
loc)) {
2801 return luaL_argerror(L, 2,
"invalid location");
2812 if (!
map().on_board(
loc))
2813 return luaL_argerror(L, 1,
"invalid location");
2820 }
else if(!lua_isnoneornil(L, 1)) {
2821 const vconfig* vcfg =
nullptr;
2823 if (!
map().on_board(
loc)) {
2826 if (!
map().on_board(
loc))
2827 return luaL_argerror(L, 2,
"invalid location");
2833 u->set_location(
loc);
2835 u->anim_comp().reset_affect_adjacent(
units());
2853 return luaL_error(L,
"Attempted to remove a unit while the map is locked");
2861 if (!
map().on_board(
loc)) {
2862 return luaL_argerror(L, 1,
"invalid location");
2868 t.recall_list().erase_if_matches_id(u->
id());
2870 return luaL_argerror(L, 1,
"can't erase private units");
2873 if (!
map().on_board(
loc)) {
2874 return luaL_argerror(L, 1,
"invalid location");
2877 return luaL_argerror(L, 1,
"expected unit or location");
2893 return luaL_error(L,
"Attempted to move a unit while the map is locked");
2897 int side = lua_tointeger(L, 2);
2898 if (
static_cast<unsigned>(side) >
teams().
size()) side = 0;
2902 u = lu->get_shared();
2903 if(lu->on_recall_list() && lu->on_recall_list() == side) {
2904 return luaL_argerror(L, 1,
"unit already on recall list");
2907 const vconfig* vcfg =
nullptr;
2919 std::size_t uid = u->underlying_id();
2920 t.recall_list().erase_by_underlying_id(uid);
2921 t.recall_list().add(u);
2926 u->anim_comp().clear_haloes();
2927 u->anim_comp().reset_affect_adjacent(
units());
2929 lu->lua_unit::~lua_unit();
2943 return luaL_error(L,
"Attempted to remove a unit while the map is locked");
2951 u->anim_comp().clear_haloes();
2952 u->anim_comp().reset_affect_adjacent(
units());
2953 }
else if (
int side = lu->on_recall_list()) {
2956 t.recall_list().erase_if_matches_id(u->id());
2962 lu->lua_unit::~lua_unit();
2978 if (!lua_isnoneornil(L, 2)) {
2982 const vconfig* vcfg =
nullptr;
2985 if (u->get_location().valid()) {
2986 u->anim_comp().reset_affect_adjacent(
units());
2993 if (!res.
valid())
return 0;
2994 lua_pushinteger(L, res.
wml_x());
2995 lua_pushinteger(L, res.
wml_y());
3011 if (!lua_isnoneornil(L, 3)) {
3034 void reset_affect_adjacent(
const unit&
unit)
3047 const vconfig* vcfg =
nullptr;
3051 if (u->get_location().valid()) {
3052 reset_affect_adjacent(*u);
3080 char const *m = luaL_checkstring(L, 2);
3084 if(lua_isboolean(L, 3)) {
3086 if(!lua_isnoneornil(L, 4)) {
3089 }
else if(!lua_isnoneornil(L, 3)) {
3110 }
else if(lua_isstring(L, 2)) {
3111 char const *m = luaL_checkstring(L, 2);
3131 }
else if(lua_isstring(L, 2)) {
3132 char const *m = luaL_checkstring(L, 2);
3152 }
else if(lua_isstring(L, 2)) {
3153 char const *m = luaL_checkstring(L, 2);
3173 }
else if(lua_isstring(L, 2)) {
3174 char const *m = luaL_checkstring(L, 2);
3190 char const *m = luaL_checkstring(L, 2);
3204 char const *m = luaL_checkstring(L, 2);
3206 if (!utp)
return luaL_argerror(L, 2,
"unknown unit type");
3207 if(lua_isstring(L, 3)) {
3208 const std::string& m2 = lua_tostring(L, 3);
3209 if(!utp->
has_variation(m2))
return luaL_argerror(L, 2,
"unknown unit variation");
3214 reset_affect_adjacent(u);
3226 lua_createtable(L, 0, 4);
3228 lua_setfield(L, -2,
"poisoned");
3229 lua_pushnumber(L, cmb.
slowed);
3230 lua_setfield(L, -2,
"slowed");
3232 lua_setfield(L, -2,
"untouched");
3234 lua_setfield(L, -2,
"average_hp");
3235 lua_createtable(L,
n, 0);
3236 for (
int i = 0;
i <
n; ++
i) {
3238 lua_rawseti(L, -2,
i);
3240 lua_setfield(L, -2,
"hp_chance");
3249 lua_createtable(L, 0, 16);
3252 lua_setfield(L, -2,
"num_blows");
3253 lua_pushnumber(L, bcustats.
damage);
3254 lua_setfield(L, -2,
"damage");
3256 lua_setfield(L, -2,
"chance_to_hit");
3257 lua_pushboolean(L, bcustats.
poisons);
3258 lua_setfield(L, -2,
"poisons");
3259 lua_pushboolean(L, bcustats.
slows);
3260 lua_setfield(L, -2,
"slows");
3262 lua_setfield(L, -2,
"petrifies");
3263 lua_pushboolean(L, bcustats.
plagues);
3264 lua_setfield(L, -2,
"plagues");
3266 lua_setfield(L, -2,
"plague_type");
3267 lua_pushnumber(L, bcustats.
rounds);
3268 lua_setfield(L, -2,
"rounds");
3270 lua_setfield(L, -2,
"firststrike");
3271 lua_pushboolean(L, bcustats.
drains);
3272 lua_setfield(L, -2,
"drains");
3274 lua_setfield(L, -2,
"drain_constant");
3276 lua_setfield(L, -2,
"drain_percent");
3281 lua_setfield(L, -2,
"attack_num");
3283 lua_setfield(L, -2,
"number");
3285 if(bcustats.
weapon !=
nullptr)
3287 lua_pushstring(L, bcustats.
weapon->id().c_str());
3288 lua_setfield(L, -2,
"name");
3290 lua_setfield(L, -2,
"weapon");
3309 int arg_num = 1, att_w = -1, def_w = -1;
3313 if (lua_isnumber(L, arg_num)) {
3314 att_w = lua_tointeger(L, arg_num) - 1;
3315 if (att_w < 0 || att_w >=
static_cast<int>(att->attacks().size()))
3316 return luaL_argerror(L, arg_num,
"weapon index out of bounds");
3322 if (lua_isnumber(L, arg_num)) {
3323 def_w = lua_tointeger(L, arg_num) - 1;
3324 if (def_w < 0 || def_w >=
static_cast<int>(def->attacks().size()))
3325 return luaL_argerror(L, arg_num,
"weapon index out of bounds");
3330 def->get_location(), att_w, def_w, 0.0,
nullptr, att, def);
3347 char const *m = luaL_checkstring(L, 1);
3348 int repeats = luaL_optinteger(L, 2, 0);
3360 const char* content_for = luaL_checkstring(L, 1);
3361 const char*
id = luaL_checkstring(L, 2);
3364 if(group.content_for_ == content_for) {
3366 if(achieve.
id_ ==
id) {
3393 ERR_LUA <<
"Achievement " <<
id <<
" not found for achievement group " << content_for;
3399 ERR_LUA <<
"Achievement group " << content_for <<
" not found";
3411 const char* content_for = luaL_checkstring(L, 1);
3412 const char*
id = luaL_checkstring(L, 2);
3415 ERR_LUA <<
"Returning false for whether a player has completed an achievement due to being networked multiplayer.";
3416 lua_pushboolean(L,
false);
3432 const char* content_for = luaL_checkstring(L, 1);
3433 const char*
id = luaL_checkstring(L, 2);
3437 if(group.content_for_ == content_for) {
3438 for(
const auto& achieve : group.achievements_) {
3439 if(achieve.id_ ==
id) {
3441 cfg[
"id"] = achieve.id_;
3442 cfg[
"name"] = achieve.name_;
3443 cfg[
"name_completed"] = achieve.name_completed_;
3444 cfg[
"description"] = achieve.description_;
3445 cfg[
"description_completed"] = achieve.description_completed_;
3446 cfg[
"icon"] = achieve.icon_;
3447 cfg[
"icon_completed"] = achieve.icon_completed_;
3448 cfg[
"hidden"] = achieve.hidden_;
3449 cfg[
"achieved"] = achieve.achieved_;
3450 cfg[
"max_progress"] = achieve.max_progress_;
3451 cfg[
"current_progress"] = achieve.current_progress_;
3453 for(
const auto& sub_ach : achieve.sub_achievements_) {
3455 sub[
"id"] = sub_ach.id_;
3456 sub[
"description"] = sub_ach.description_;
3457 sub[
"icon"] = sub_ach.icon_;
3458 sub[
"achieved"] = sub_ach.achieved_;
3466 ERR_LUA <<
"Achievement " <<
id <<
" not found for achievement group " << content_for;
3472 ERR_LUA <<
"Achievement group " << content_for <<
" not found";
3488 const char* content_for = luaL_checkstring(L, 1);
3489 const char*
id = luaL_checkstring(L, 2);
3490 int amount = luaL_checkinteger(L, 3);
3491 int limit = luaL_optinteger(L, 4, 999999999);
3494 if(group.content_for_ == content_for) {
3496 if(achieve.
id_ ==
id) {
3499 ERR_LUA <<
"Attempted to progress achievement " <<
id <<
" for achievement group " << content_for <<
", is not a progressible achievement.";
3500 lua_pushinteger(L, -1);
3501 lua_pushinteger(L, -1);
3516 lua_pushinteger(L, progress);
3518 lua_pushinteger(L, -1);
3526 lua_push(L,
"Achievement " + std::string(
id) +
" not found for achievement group " + content_for);
3527 return lua_error(L);
3532 lua_push(L,
"Achievement group " + std::string(content_for) +
" not found");
3533 return lua_error(L);
3545 const char* content_for = luaL_checkstring(L, 1);
3546 const char*
id = luaL_checkstring(L, 2);
3547 const char* sub_id = luaL_checkstring(L, 3);
3550 ERR_LUA <<
"Returning false for whether a player has completed an achievement due to being networked multiplayer.";
3551 lua_pushboolean(L,
false);
3567 const char* content_for = luaL_checkstring(L, 1);
3568 const char*
id = luaL_checkstring(L, 2);
3569 const char* sub_id = luaL_checkstring(L, 3);
3572 if(group.content_for_ == content_for) {
3574 if(achieve.
id_ ==
id) {
3581 if(sub_ach.
id_ == sub_id) {
3599 lua_push(L,
"Sub-achievement " + std::string(
id) +
" not found for achievement" +
id +
" in achievement group " + content_for);
3600 return lua_error(L);
3604 lua_push(L,
"Achievement " + std::string(
id) +
" not found for achievement group " + content_for);
3605 return lua_error(L);
3610 lua_push(L,
"Achievement group " + std::string(content_for) +
" not found");
3611 return lua_error(L);
3647 if(lua_isnoneornil(L, 1)) {
3652 if(!
map().on_board(
loc))
return luaL_argerror(L, 1,
"not on board");
3653 bool highlight =
true;
3654 if(!lua_isnoneornil(L, 2))
3684 lua_pushboolean(L, skipping);
3695 if (!lua_isnone(L, 1)) {
3707 int user_choice_index;
3708 int random_choice_index;
3709 int ai_choice_index;
3711 lua_synchronize(lua_State *l,
const std::string& descr,
int user_index,
int random_index = 0,
int ai_index = 0)
3713 , user_choice_index(user_index)
3714 , random_choice_index(random_index)
3715 , ai_choice_index(ai_index != 0 ? ai_index : user_index)
3721 bool is_local_ai = lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).board().get_team(side).is_local_ai();
3723 query_lua(side, is_local_ai ? ai_choice_index : user_choice_index,
cfg);
3730 if(random_choice_index != 0 && lua_isfunction(L, random_choice_index)) {
3731 query_lua(side, random_choice_index,
cfg);
3741 void query_lua(
int side,
int function_index,
config&
cfg)
const
3743 lua_pushvalue(L, function_index);
3744 lua_pushnumber(L, side);
3747 static const char*
msg =
"function returned to wesnoth.sync.[multi_]evaluate a table which was partially invalid";
3748 lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).log_error(
msg);
3749 lua_warning(L,
msg,
false);
3756 virtual bool is_visible()
const override {
return false; }
3770 std::string tagname =
"input";
3777 if(!lua_isfunction(L, nextarg) &&
luaW_totstring(L, nextarg, desc) ) {
3780 if(lua_isfunction(L, nextarg)) {
3781 human_func = nextarg++;
3784 return luaL_argerror(L, nextarg,
"expected a function");
3786 if(lua_isfunction(L, nextarg)) {
3787 ai_func = nextarg++;
3789 side_for = lua_tointeger(L, nextarg);
3805 std::string tagname =
"input";
3809 std::vector<int> sides_for;
3812 if(!lua_isfunction(L, nextarg) &&
luaW_totstring(L, nextarg, desc) ) {
3815 if(lua_isfunction(L, nextarg)) {
3816 human_func = nextarg++;
3819 return luaL_argerror(L, nextarg,
"expected a function");
3821 if(lua_isfunction(L, nextarg)) {
3822 null_func = nextarg++;
3824 sides_for = lua_check<std::vector<int>>(L, nextarg++);
3839 lua_pushvalue(L, 1);
3854 std::set<map_location> res;
3880 lua_pushboolean(L,
true);
3889 lua_pushboolean(L, t_filter.
match(
loc));
3907 lua_pushboolean(L,
true);
3915 lua_pushboolean(L, s_filter.
match(*
t));
3917 unsigned side = luaL_checkinteger(L, 1) - 1;
3919 lua_pushboolean(L, s_filter.
match(side + 1));
3930 team_i = luaL_checkinteger(L, 1);
3932 std::string
flag = luaL_optlstring(L, 2,
"",
nullptr);
3933 std::string color = luaL_optlstring(L, 3,
"",
nullptr);
3935 if(
flag.empty() && color.empty()) {
3938 if(team_i < 1 ||
static_cast<std::size_t
>(team_i) >
teams().
size()) {
3939 return luaL_error(L,
"set_side_id: side number %d out of range", team_i);
3943 if(!color.empty()) {
3958 side_num =
t->side();
3960 side_num = luaL_checkinteger(L, 1);
3962 std::string
path = luaL_checkstring(L, 2);
3967 if(strcmp(action,
"delete") == 0) {
3972 std::size_t len = std::string::npos, open_brak =
path.find_last_of(
'[');
3973 std::size_t dot =
path.find_last_of(
'.');
3974 if(open_brak != len) {
3975 len = open_brak - dot - 1;
3986 side_num =
t->side();
3988 side_num = luaL_checkinteger(L, 1);
3990 if(lua_isstring(L, 2)) {
3991 std::string file = luaL_checkstring(L, 2);
3993 std::string
err =
formatter() <<
"Could not load AI for side " << side_num <<
" from file " << file;
3994 lua_pushlstring(L,
err.c_str(),
err.length());
3995 return lua_error(L);
4007 side_num =
t->side();
4009 side_num = luaL_checkinteger(L, 1);
4015 bool added_dummy_stage =
false;
4017 added_dummy_stage =
true;
4021 if(added_dummy_stage) {
4030 unsigned i = luaL_checkinteger(L, 1);
4031 if(i < 1 || i >
teams().
size())
return 0;
4043 LOG_LUA <<
"intf_get_sides called: this = " << std::hex <<
this << std::dec <<
" myname = " <<
my_name();
4044 std::vector<int> sides;
4048 sides.push_back(
t.side());
4054 sides =
filter.get_teams();
4058 lua_createtable(L, sides.size(), 0);
4060 for(
int side : sides) {
4062 lua_rawseti(L, -2,
index);
4079 char const *m = luaL_checkstring(L, 2);
4081 if (sm ==
"advance") {
4085 if (sm !=
"advancement" && sm !=
"object" && sm !=
"trait") {
4086 return luaL_argerror(L, 2,
"unknown modification type");
4088 bool write_to_mods =
true;
4089 if (!lua_isnone(L, 4)) {
4093 write_to_mods =
false;
4111 std::vector<std::string> tags;
4112 if(lua_isstring(L, 3)) {
4113 tags.push_back(lua_check<std::string>(L, 3));
4114 }
else if (lua_istable(L, 3)){
4115 tags = lua_check<std::vector<std::string>>(L, 3);
4117 tags.push_back(
"object");
4120 if(
filter.attribute_count() == 1 &&
filter.all_children_count() == 0 &&
filter.attribute_range().front().first ==
"duration") {
4123 for(
const std::string&
tag : tags) {
4125 if(obj.matches(
filter)) {
4126 obj[
"duration"] =
"now";
4146 if(lua_isboolean(L, 2)) {
4149 if(lua_isboolean(L, 3)) {
4163 char const *ty = luaL_checkstring(L, 1);
4166 std::stringstream ss;
4167 ss <<
"unknown unit type: '" << ty <<
"'";
4168 return luaL_argerror(L, 1, ss.str().c_str());
4183 const vconfig &ssf =
cfg.child(
"filter_team");
4185 std::string team_name;
4188 std::vector<std::string> team_names;
4190 [&](
int team) { return game_state_.get_disp_context().get_team(team).team_name(); });
4193 team_name =
cfg[
"team_name"].str();
4202 cfg[
"visible_in_fog"].to_bool(
true),
4203 cfg[
"submerge"].to_double(0),
4204 cfg[
"z_order"].to_double(0)
4218 char const *m = lua_tostring(L, 2);
4235 const int nargs = lua_gettop(L);
4236 if(nargs < 2 || nargs > 3) {
4237 return luaL_error(L,
"Wrong number of arguments to ai.log_replay() - should be 2 or 3 arguments.");
4239 const std::string key = nargs == 2 ? luaL_checkstring(L, 1) : luaL_checkstring(L, 2);
4245 }
else if(!lua_isstring(L, 3)) {
4246 return luaL_argerror(L, 3,
"accepts only string or config");
4279 if(lua_isstring(L, idx)) {
4280 return lua_tostring(L, idx);
4320 using namespace std::literals;
4326 }
else if(is_menu_item) {
4328 return luaL_argerror(L, 1,
"non-empty id is required for a menu item");
4330 name =
"menu item " +
id;
4332 if(
id.empty() && name.empty()) {
4333 return luaL_argerror(L, 1,
"either a name or id is required");
4336 if(new_handler.valid()) {
4337 bool has_lua_filter =
false;
4341 int filterIdx = lua_gettop(L);
4344 if(lua_isfunction(L, filterIdx)) {
4345 int fcnIdx = lua_absindex(L, -1);
4346 new_handler->add_filter(std::make_unique<lua_event_filter>(*
this, fcnIdx,
luaW_table_get_def(L, 1,
"filter_args",
config())));
4347 has_lua_filter =
true;
4349 #define READ_ONE_FILTER(key, tag) \
4351 if(luaW_tableget(L, filterIdx, key)) { \
4352 if(lua_isstring(L, -1)) { \
4353 filters.add_child("insert_tag", config{ \
4355 "variable", luaL_checkstring(L, -1) \
4358 filters.add_child(tag, luaW_checkconfig(L, -1)); \
4368 #undef READ_ONE_FILTER
4370 filters[
"filter_formula"] = luaL_checkstring(L, -1);
4374 new_handler->read_filters(filters);
4380 if(has_lua_filter) {
4385 new_handler->register_wml_event(*
this);
4398 lua_pushvalue(L, lua_upvalueindex(1));
4415 template<
bool is_menu_item>
4421 double priority = luaL_optnumber(L, 3, 0.);
4423 return luaL_argerror(L, 1,
"must not be empty");
4427 name =
"menu item " + name;
4428 }
else if(lua_absindex(L, -1) > 2 && lua_isfunction(L, -1)) {
4431 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_undoable_event>, 2);
4434 if(new_handler.valid()) {
4451 bool delayed_variable_substitution =
cfg[
"delayed_variable_substitution"].to_bool(
true);
4452 if(delayed_variable_substitution) {
4479 lua_pushinteger(L, color.r);
4480 lua_pushinteger(L, color.g);
4481 lua_pushinteger(L, color.b);
4490 auto vec = lua_check<std::vector<uint8_t>>(L, 1);
4491 if(vec.size() != 4) {
4494 color_t fade{vec[0], vec[1], vec[2], vec[3]};
4512 using namespace std::chrono_literals;
4513 std::chrono::milliseconds delay{luaL_checkinteger(L, 1)};
4521 const auto end_time = std::chrono::steady_clock::now() + delay;
4524 std::this_thread::sleep_for(10ms);
4525 }
while (std::chrono::steady_clock::now() < end_time);
4549 std::string team_name;
4552 if(lua_gettop(L) == 1 && lua_istable(L, 1)) {
4553 using namespace std::literals;
4556 team_name = luaL_optstring(L, 2,
"");
4570 switch(lua_type(L, 2)) {
4572 case LUA_TNONE:
case LUA_TNIL:
4577 if(std::size_t
n = luaL_checkinteger(L, 2);
n > 0 &&
n <=
teams().size()) {
4617 for (
const int side :
filter.get_teams()){
4639 int side =
cfg[
"side"].to_int();
4649 lua_getfield(L, -1,
"ca_ptr");
4650 if(!lua_islightuserdata(L, -1)) {
4651 lua_pushstring(L,
"Could not execute candidate action - invalid pointer");
4652 return lua_error(L);
4667 lua_getfield(L, -1,
"stg_ptr");
4668 if(!lua_islightuserdata(L, -1)) {
4669 lua_pushstring(L,
"Could not execute stage - invalid pointer");
4670 return lua_error(L);
4680 lua_createtable(L, 0, 0);
4682 lua_pushstring(L,
"name");
4683 lua_pushstring(L,
c->get_name().c_str());
4686 lua_pushstring(L,
"engine");
4687 lua_pushstring(L,
c->get_engine().c_str());
4690 lua_pushstring(L,
"id");
4691 lua_pushstring(L,
c->get_id().c_str());
4694 if (ct ==
"candidate_action") {
4695 lua_pushstring(L,
"ca_ptr");
4696 lua_pushlightuserdata(L,
c);
4699 lua_pushstring(L,
"exec");
4704 if (ct ==
"stage") {
4705 lua_pushstring(L,
"stg_ptr");
4706 lua_pushlightuserdata(L,
c);
4709 lua_pushstring(L,
"exec");
4714 for(
const std::string&
type :
c->get_children_types()) {
4715 if (
type ==
"aspect" ||
type ==
"goal" ||
type ==
"engine")
4720 lua_pushstring(L,
type.c_str());
4721 lua_createtable(L, 0, 0);
4724 lua_pushstring(L, child->get_name().c_str());
4753 side = luaL_checkinteger(L, 1);
4762 if(engine->get_name() ==
"lua") {
4771 if (lua_engine ==
nullptr)
4784 LOG_LUA <<
"Created new dummy lua-engine for debug_ai().";
4794 lua_pushstring(L,
"components");
4820 if(lua_isboolean(L, 1)) {
4845 std::set<map_location> locs;
4848 if(lua_gettop(L) == 1) {
4851 id =
cfg[
"id"].str();
4853 filter.get_locations(locs,
true);
4854 times =
cfg.get_parsed_config();
4856 id = luaL_checkstring(L, 1);
4857 if(!lua_isnoneornil(L, 3))
4863 filter.get_locations(locs,
true);
4871 LOG_LUA <<
"Lua inserted time_area '" <<
id <<
"'";
4880 const char *
id = luaL_checkstring(L, 1);
4882 LOG_LUA <<
"Lua removed time_area '" <<
id <<
"'";
4892 if(area_index < 0) {
4899 std::string area_id = luaL_checkstring(L, 1);
4901 if(
auto iter =
std::find(area_ids.begin(), area_ids.end(), area_id); iter == area_ids.end()) {
4915 if(luaL_testudata(L, 1,
"schedule")) {
4924 if(
cfg.get_children(
"time").
empty()) {
4925 ERR_LUA <<
"attempted to to replace ToD schedule with empty schedule";
4931 LOG_LUA <<
"replaced ToD schedule";
4940 point scroll_to(luaL_checkinteger(L, 1), luaL_checkinteger(L, 2));
4957 lua_report_generator(lua_State *L,
const std::string &
n)
4966 if (!
luaW_getglobal(L,
"wesnoth",
"interface",
"game_display", name))
4990 char const *m = luaL_checkstring(L, 2);
4992 lua_pushvalue(L, 2);
4993 lua_pushvalue(L, -2);
5004 char const *m = luaL_checkstring(L, 2);
5005 lua_pushvalue(L, 2);
5006 lua_pushvalue(L, 3);
5047 if (
dst == u->get_location() || !
map().on_board(
dst)) {
5051 if (!
map().on_board(vacant_dst)) {
5062 std::vector<map_location> teleport_path;
5063 teleport_path.push_back(src_loc);
5064 teleport_path.push_back(vacant_dst);
5071 u->anim_comp().set_standing();
5078 if (
map().is_village(vacant_dst)) {
5097 const std::string& logger = lua_isstring(L, 2) ? luaL_checkstring(L, 1) :
"";
5098 const std::string&
msg = lua_isstring(L, 2) ? luaL_checkstring(L, 2) : luaL_checkstring(L, 1);
5100 if(logger ==
"wml" || logger ==
"WML") {
5114 lua_pushboolean(L, fog ?
t.fogged(
loc) :
t.shrouded(
loc));
5132 bool affect_normal_fog =
false;
5133 if(lua_isboolean(L, -1)) {
5136 std::set<int> sides;
5138 sides.insert(
t->side());
5139 }
else if(lua_isnumber(L, 1)) {
5140 sides.insert(lua_tointeger(L, 1));
5141 }
else if(lua_istable(L, 1) && lua_istable(L, 2)) {
5142 const auto& v = lua_check<std::vector<int>>(L, 1);
5143 sides.insert(v.begin(), v.end());
5146 sides.insert(
t.side()+1);
5151 for(
const int &side_num : sides) {
5152 if(side_num < 1 ||
static_cast<std::size_t
>(side_num) >
teams().
size()) {
5158 t.remove_fog_override(locs);
5159 if(affect_normal_fog) {
5162 }
else if(!affect_normal_fog) {
5164 t.add_fog_override(locs);
5182 const std::string name = luaL_checkstring(L, 1);
5187 if(!
luaW_getglobal(L,
"wesnoth",
"custom_synced_commands", name)) {
5188 return luaL_argerror(L, 1,
"Unknown synced command");
5191 cmd_tag[
"name"] = name;
5192 if(!lua_isnoneornil(L, 2)) {
5210 #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); }
5213 template<
typename Ret>
5215 if constexpr(std::is_same_v<Ret, void>)
return 0;
5221 inline static auto metatable =
"game_events";
5223 return lua_kernel_base::get_lua_kernel<game_lua_kernel>(L);
5244 template<
typename Ret =
void>
5246 int top = lua_gettop(L);
5250 lua_getfield(L, -1, name.c_str());
5251 lua_pushcfunction(L, &impl_null_callback<Ret>);
5252 if(lua_rawequal(L, -1, -2)) {
5307 cmd_log_ <<
"Registering game-specific wesnoth lib functions...\n";
5310 static luaL_Reg
const callbacks[] {
5315 {
"cancel_action", &dispatch<&game_lua_kernel::intf_cancel_action > },
5316 {
"log_replay", &dispatch<&game_lua_kernel::intf_log_replay > },
5317 {
"log", &dispatch<&game_lua_kernel::intf_log > },
5318 {
"redraw", &dispatch<&game_lua_kernel::intf_redraw > },
5319 {
"simulate_combat", &dispatch<&game_lua_kernel::intf_simulate_combat > },
5320 {
nullptr,
nullptr }
5321 };lua_getglobal(L,
"wesnoth");
5322 if (!lua_istable(L,-1)) {
5325 luaL_setfuncs(L, callbacks, 0);
5327 lua_setglobal(L,
"wesnoth");
5329 lua_getglobal(L,
"gui");
5330 lua_pushcfunction(L, &dispatch<&game_lua_kernel::intf_gamestate_inspector>);
5331 lua_setfield(L, -2,
"show_inspector");
5333 lua_setfield(L, -2,
"show_recruit_dialog");
5335 lua_setfield(L, -2,
"show_recall_dialog");
5341 static luaL_Reg
const test_callbacks[] {
5342 {
"fire_wml_menu_item", &dispatch<&game_lua_kernel::intf_fire_wml_menu_item> },
5343 {
nullptr,
nullptr }
5345 luaL_setfuncs(L, test_callbacks, 0);
5346 lua_setglobal(L,
"unit_test");
5372 cmd_log_ <<
"Adding terrain_types table...\n";
5373 lua_getglobal(L,
"wesnoth");
5374 lua_newuserdatauv(L, 0, 0);
5375 lua_createtable(L, 0, 2);
5376 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_get_terrain_info>);
5377 lua_setfield(L, -2,
"__index");
5378 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_get_terrain_list>);
5379 lua_setfield(L, -2,
"__dir");
5380 lua_pushstring(L,
"terrain types");
5381 lua_setfield(L, -2,
"__metatable");
5382 lua_setmetatable(L, -2);
5383 lua_setfield(L, -2,
"terrain_types");
5387 cmd_log_ <<
"Adding ai elements table...\n";
5392 cmd_log_ <<
"Adding wesnoth current table...\n";
5394 lua_getglobal(L,
"wesnoth");
5395 lua_newuserdatauv(L, 0, 0);
5396 lua_createtable(L, 0, 2);
5397 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_current_get>);
5398 lua_setfield(L, -2,
"__index");
5399 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_current_dir>);
5400 lua_setfield(L, -2,
"__dir");
5401 lua_pushboolean(L,
true);
5402 lua_setfield(L, -2,
"__dir_tablelike");
5403 lua_pushstring(L,
"current config");
5404 lua_setfield(L, -2,
"__metatable");
5405 lua_setmetatable(L, -2);
5406 lua_setfield(L, -2,
"current");
5410 lua_getglobal(L,
"wml");
5411 static luaL_Reg
const wml_callbacks[] {
5415 {
"get_variable", &dispatch<&game_lua_kernel::intf_get_variable>},
5416 {
"set_variable", &dispatch<&game_lua_kernel::intf_set_variable>},
5417 {
"get_all_vars", &dispatch<&game_lua_kernel::intf_get_all_vars>},
5418 {
nullptr,
nullptr }
5420 luaL_setfuncs(L, wml_callbacks, 0);
5425 static luaL_Reg
const map_callbacks[] {
5432 {
"get_owner", &dispatch<&game_lua_kernel::intf_get_village_owner>},
5433 {
"set_owner", &dispatch<&game_lua_kernel::intf_set_village_owner>},
5435 {
"add_label", &dispatch<&game_lua_kernel::intf_add_label>},
5436 {
"remove_label", &dispatch<&game_lua_kernel::intf_remove_label>},
5437 {
"get_label", &dispatch<&game_lua_kernel::intf_get_label>},
5439 {
"place_area", &dispatch<&game_lua_kernel::intf_add_time_area>},
5440 {
"remove_area", &dispatch<&game_lua_kernel::intf_remove_time_area>},
5441 {
"get_area", &dispatch<&game_lua_kernel::intf_get_time_area>},
5443 {
"find", &dispatch<&game_lua_kernel::intf_get_locations>},
5444 {
"matches", &dispatch<&game_lua_kernel::intf_match_location>},
5446 {
nullptr,
nullptr }
5448 luaL_setfuncs(L, map_callbacks, 0);
5452 cmd_log_ <<
"Adding units module...\n";
5453 static luaL_Reg
const unit_callbacks[] {
5456 {
"erase", &dispatch<&game_lua_kernel::intf_erase_unit>},
5457 {
"extract", &dispatch<&game_lua_kernel::intf_extract_unit>},
5458 {
"matches", &dispatch<&game_lua_kernel::intf_match_unit>},
5459 {
"select", &dispatch<&game_lua_kernel::intf_select_unit>},
5460 {
"to_map", &dispatch<&game_lua_kernel::intf_put_unit>},
5461 {
"to_recall", &dispatch<&game_lua_kernel::intf_put_recall_unit>},
5463 {
"teleport", &dispatch<&game_lua_kernel::intf_teleport>},
5465 {
"ability", &dispatch<&game_lua_kernel::intf_unit_ability>},
5476 {
"find_on_map", &dispatch<&game_lua_kernel::intf_get_units>},
5477 {
"find_on_recall", &dispatch<&game_lua_kernel::intf_get_recall_units>},
5478 {
"get", &dispatch<&game_lua_kernel::intf_get_unit>},
5479 {
"get_hovered", &dispatch<&game_lua_kernel::intf_get_displayed_unit>},
5480 {
"create_animator", &dispatch<&game_lua_kernel::intf_create_animator>},
5483 {
nullptr,
nullptr }
5485 lua_getglobal(L,
"wesnoth");
5487 luaL_setfuncs(L, unit_callbacks, 0);
5488 lua_setfield(L, -2,
"units");
5492 cmd_log_ <<
"Adding sides module...\n";
5493 static luaL_Reg
const side_callbacks[] {
5494 {
"is_enemy", &dispatch<&game_lua_kernel::intf_is_enemy> },
5495 {
"matches", &dispatch<&game_lua_kernel::intf_match_side> },
5496 {
"set_id", &dispatch<&game_lua_kernel::intf_set_side_id> },
5501 {
"find", &dispatch<&game_lua_kernel::intf_get_sides> },
5502 {
"get", &dispatch<&game_lua_kernel::intf_get_side> },
5503 {
"create", &dispatch<&game_lua_kernel::intf_create_side> },
5505 {
"place_shroud", &dispatch2<&game_lua_kernel::intf_toggle_shroud, true>},
5506 {
"remove_shroud", &dispatch2<&game_lua_kernel::intf_toggle_shroud, false>},
5507 {
"override_shroud", &dispatch<&game_lua_kernel::intf_override_shroud>},
5508 {
"is_shrouded", &dispatch2<&game_lua_kernel::intf_get_fog_or_shroud, false>},
5510 {
"place_fog", &dispatch2<&game_lua_kernel::intf_toggle_fog, false>},
5511 {
"remove_fog", &dispatch2<&game_lua_kernel::intf_toggle_fog, true>},
5512 {
"is_fogged", &dispatch2<&game_lua_kernel::intf_get_fog_or_shroud, true>},
5513 {
nullptr,
nullptr }
5515 std::vector<lua_cpp::Reg>
const cpp_side_callbacks {
5516 {
"add_ai_component", std::bind(
intf_modify_ai, std::placeholders::_1,
"add")},
5517 {
"delete_ai_component", std::bind(
intf_modify_ai, std::placeholders::_1,
"delete")},
5518 {
"change_ai_component", std::bind(
intf_modify_ai, std::placeholders::_1,
"change")},
5522 lua_getglobal(L,
"wesnoth");
5524 luaL_setfuncs(L, side_callbacks, 0);
5526 lua_setfield(L, -2,
"sides");
5530 cmd_log_ <<
"Adding interface module...\n";
5531 static luaL_Reg
const intf_callbacks[] {
5532 {
"add_hex_overlay", &dispatch<&game_lua_kernel::intf_add_tile_overlay>},
5533 {
"remove_hex_overlay", &dispatch<&game_lua_kernel::intf_remove_tile_overlay>},
5534 {
"get_color_adjust", &dispatch<&game_lua_kernel::intf_get_color_adjust>},
5535 {
"color_adjust", &dispatch<&game_lua_kernel::intf_color_adjust>},
5536 {
"screen_fade", &dispatch<&game_lua_kernel::intf_screen_fade>},
5537 {
"delay", &dispatch<&game_lua_kernel::intf_delay>},
5538 {
"deselect_hex", &dispatch<&game_lua_kernel::intf_deselect_hex>},
5539 {
"highlight_hex", &dispatch<&game_lua_kernel::intf_highlight_hex>},
5540 {
"float_label", &dispatch<&game_lua_kernel::intf_float_label>},
5541 {
"get_displayed_unit", &dispatch<&game_lua_kernel::intf_get_displayed_unit>},
5542 {
"get_hovered_hex", &dispatch<&game_lua_kernel::intf_get_mouseover_tile>},
5543 {
"get_selected_hex", &dispatch<&game_lua_kernel::intf_get_selected_tile>},
5544 {
"lock", &dispatch<&game_lua_kernel::intf_lock_view>},
5545 {
"is_locked", &dispatch<&game_lua_kernel::intf_view_locked>},
5546 {
"scroll", &dispatch<&game_lua_kernel::intf_scroll>},
5547 {
"scroll_to_hex", &dispatch<&game_lua_kernel::intf_scroll_to_tile>},
5548 {
"skip_messages", &dispatch<&game_lua_kernel::intf_skip_messages>},
5549 {
"is_skipping_messages", &dispatch<&game_lua_kernel::intf_is_skipping_messages>},
5550 {
"zoom", &dispatch<&game_lua_kernel::intf_zoom>},
5551 {
"clear_menu_item", &dispatch<&game_lua_kernel::intf_clear_menu_item>},
5552 {
"set_menu_item", &dispatch<&game_lua_kernel::intf_set_menu_item>},
5553 {
"allow_end_turn", &dispatch<&game_lua_kernel::intf_allow_end_turn>},
5554 {
"clear_chat_messages", &dispatch<&game_lua_kernel::intf_clear_messages>},
5555 {
"end_turn", &dispatch<&game_lua_kernel::intf_end_turn>},
5557 {
"add_chat_message", &dispatch<&game_lua_kernel::intf_message>},
5558 {
"add_overlay_text", &dispatch2<&game_lua_kernel::intf_set_floating_label, true>},
5560 {
nullptr,
nullptr }
5562 lua_getglobal(L,
"wesnoth");
5564 luaL_setfuncs(L, intf_callbacks, 0);
5565 lua_setfield(L, -2,
"interface");
5569 cmd_log_ <<
"Adding achievements module...\n";
5570 static luaL_Reg
const achievement_callbacks[] {
5571 {
"set", &dispatch<&game_lua_kernel::intf_set_achievement> },
5572 {
"has", &dispatch<&game_lua_kernel::intf_has_achievement> },
5573 {
"get", &dispatch<&game_lua_kernel::intf_get_achievement> },
5574 {
"progress", &dispatch<&game_lua_kernel::intf_progress_achievement> },
5575 {
"has_sub_achievement", &dispatch<&game_lua_kernel::intf_has_sub_achievement> },
5576 {
"set_sub_achievement", &dispatch<&game_lua_kernel::intf_set_sub_achievement> },
5577 {
nullptr,
nullptr }
5579 lua_getglobal(L,
"wesnoth");
5581 luaL_setfuncs(L, achievement_callbacks, 0);
5582 lua_setfield(L, -2,
"achievements");
5586 cmd_log_ <<
"Adding audio module...\n";
5587 static luaL_Reg
const audio_callbacks[] {
5588 {
"play", &dispatch<&game_lua_kernel::intf_play_sound > },
5589 {
nullptr,
nullptr }
5591 lua_getglobal(L,
"wesnoth");
5593 luaL_setfuncs(L, audio_callbacks, 0);
5594 lua_setfield(L, -2,
"audio");
5598 cmd_log_ <<
"Adding paths module...\n";
5599 static luaL_Reg
const path_callbacks[] {
5600 {
"find_cost_map", &dispatch<&game_lua_kernel::intf_find_cost_map > },
5601 {
"find_path", &dispatch<&game_lua_kernel::intf_find_path > },
5602 {
"find_reach", &dispatch<&game_lua_kernel::intf_find_reach > },
5603 {
"find_vacant_hex", &dispatch<&game_lua_kernel::intf_find_vacant_tile > },
5604 {
"find_vision_range", &dispatch<&game_lua_kernel::intf_find_vision_range > },
5605 {
nullptr,
nullptr }
5607 lua_getglobal(L,
"wesnoth");
5609 luaL_setfuncs(L, path_callbacks, 0);
5610 lua_setfield(L, -2,
"paths");
5614 cmd_log_ <<
"Adding sync module...\n";
5615 static luaL_Reg
const sync_callbacks[] {
5620 {
nullptr,
nullptr }
5622 lua_getglobal(L,
"wesnoth");
5624 luaL_setfuncs(L, sync_callbacks, 0);
5625 lua_setfield(L, -2,
"sync");
5629 cmd_log_ <<
"Adding schedule module...\n";
5630 static luaL_Reg
const schedule_callbacks[] {
5631 {
"get_time_of_day", &dispatch<&game_lua_kernel::intf_get_time_of_day<false>>},
5632 {
"get_illumination", &dispatch<&game_lua_kernel::intf_get_time_of_day<true>>},
5633 {
"replace", &dispatch<&game_lua_kernel::intf_replace_schedule>},
5634 {
nullptr,
nullptr }
5636 lua_getglobal(L,
"wesnoth");
5638 luaL_setfuncs(L, schedule_callbacks, 0);
5639 lua_createtable(L, 0, 2);
5640 lua_setmetatable(L, -2);
5641 lua_setfield(L, -2,
"schedule");
5648 cmd_log_ <<
"Adding wml_actions table...\n";
5650 lua_getglobal(L,
"wesnoth");
5652 lua_setfield(L, -2,
"wml_actions");
5656 cmd_log_ <<
"Adding wml_conditionals table...\n";
5658 lua_getglobal(L,
"wesnoth");
5660 lua_setfield(L, -2,
"wml_conditionals");
5667 cmd_log_ <<
"Adding effects table...\n";
5669 lua_getglobal(L,
"wesnoth");
5671 lua_setfield(L, -2,
"effects");
5675 cmd_log_ <<
"Adding custom_synced_commands table...\n";
5677 lua_getglobal(L,
"wesnoth");
5679 lua_setfield(L, -2,
"custom_synced_commands");
5683 cmd_log_ <<
"Adding game_events module...\n";
5684 static luaL_Reg
const event_callbacks[] {
5685 {
"add", &dispatch<&game_lua_kernel::intf_add_event> },
5686 {
"add_repeating", &dispatch<&game_lua_kernel::intf_add_event_simple<false>> },
5687 {
"add_menu", &dispatch<&game_lua_kernel::intf_add_event_simple<true>> },
5688 {
"add_wml", &dispatch<&game_lua_kernel::intf_add_event_wml> },
5689 {
"remove", &dispatch<&game_lua_kernel::intf_remove_event> },
5690 {
"fire", &dispatch2<&game_lua_kernel::intf_fire_event, false> },
5691 {
"fire_by_id", &dispatch2<&game_lua_kernel::intf_fire_event, true> },
5692 {
"add_undo_actions", &dispatch<&game_lua_kernel::intf_add_undo_actions> },
5693 {
"set_undoable", &dispatch<&game_lua_kernel::intf_allow_undo > },
5694 {
nullptr,
nullptr }
5696 lua_getglobal(L,
"wesnoth");
5698 luaL_setfuncs(L, event_callbacks, 0);
5699 lua_createtable(L, 0, 2);
5701 lua_setfield(L, -2,
"__dir");
5703 lua_setfield(L, -2,
"__index");
5704 lua_pushstring(L,
"game_events");
5705 lua_setfield(L, -2,
"__metatable");
5706 lua_setmetatable(L, -2);
5707 lua_setfield(L, -2,
"game_events");
5711 cmd_log_ <<
"Adding game_display table...\n";
5715 lua_createtable(L, 0, 2);
5716 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_theme_items_get>);
5717 lua_setfield(L, -2,
"__index");
5718 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_theme_items_set>);
5719 lua_setfield(L, -2,
"__newindex");
5720 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_theme_items_dir>);
5721 lua_setfield(L, -2,
"__dir");
5722 lua_setmetatable(L, -2);
5723 lua_setfield(L, -2,
"game_display");
5727 cmd_log_ <<
"Adding scenario table...\n";
5731 lua_createtable(L, 0, 2);
5732 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_scenario_get>);
5733 lua_setfield(L, -2,
"__index");
5734 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_scenario_set>);
5735 lua_setfield(L, -2,
"__newindex");
5736 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_scenario_dir>);
5737 lua_setfield(L, -2,
"__dir");
5738 lua_setmetatable(L, -2);
5739 lua_setfield(L, -2,
"scenario");
5750 lua_pushstring(L, effect.c_str());
5766 cmd_log_ <<
"Adding races table...\n";
5769 lua_getglobal(L,
"wesnoth");
5771 lua_setfield(L, -2,
"races");
5775 cmd_log_ <<
"Running preload scripts...\n";
5798 using namespace std::literals::string_view_literals;
5799 static constexpr std::array handled_file_tags {
5812 "modify_unit_type"sv,
5818 "terrain_graphics"sv,
5826 return std::binary_search(handled_file_tags.begin(), handled_file_tags.end(),
s);
5842 for(
const auto [child_key, child_cfg] :
level.all_children_view())
5845 lua_createtable(L, 2, 0);
5846 lua_pushstring(L, child_key.c_str());
5847 lua_rawseti(L, -2, 1);
5849 lua_rawseti(L, -2, 2);
5850 lua_rawseti(L, -2, k++);
5864 if(!impl_get_callback<config>(L,
"on_save"))
5877 const std::vector<std::string> src_tags(temp.begin(), temp.end());
5879 for(
const auto& key : src_tags) {
5886 const std::string m =
"Tag is already used: [" + key +
"]";
5907 lua_pushstring(L, ev.
name.c_str());
5916 if (!
luaW_getglobal(L,
"wesnoth",
"custom_synced_commands", name)) {
5932 std::string which_effect = lua_tostring(L, lua_upvalueindex(1));
5947 lua_pushstring(L, description.c_str());
5960 int str_i = lua_gettop(L);
5963 lua_pushstring(L,
"__call");
5964 lua_pushvalue(L, str_i);
5965 lua_pushboolean(L,
true);
5966 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_builtin_effect>, 2);
5968 lua_pushstring(L,
"__descr");
5969 lua_pushvalue(L, str_i);
5970 lua_pushboolean(L,
false);
5971 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_builtin_effect>, 2);
5973 lua_setmetatable(L, -2);
5982 if(!lua_islightuserdata(L, lua_upvalueindex(1))) {
5983 lua_pushstring(L,
"Could not execute wml action: upvalue was tampered with");
5984 return lua_error(L);
5987 (lua_touserdata(L, lua_upvalueindex(1)));
6001 lua_getglobal(L,
"wesnoth");
6002 lua_pushstring(L,
"wml_actions");
6004 lua_pushstring(L, cmd.c_str());
6005 lua_pushlightuserdata(L,
reinterpret_cast<void *
>(
h));
6006 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_wml_action>, 1);
6018 if(!lua_islightuserdata(L, lua_upvalueindex(1))) {
6019 lua_pushstring(L,
"Could not evaluate wml condition: upvalue was tampered with");
6020 return lua_error(L);
6023 (lua_touserdata(L, lua_upvalueindex(1)));
6026 lua_pushboolean(L,
h(vcfg));
6037 lua_getglobal(L,
"wesnoth");
6038 lua_pushstring(L,
"wml_conditionals");
6040 lua_pushstring(L, cmd.c_str());
6041 lua_pushlightuserdata(L,
reinterpret_cast<void *
>(
h));
6083 ERR_WML <<
"unknown conditional wml: [" << cmd <<
"]";
6102 int argIdx = lua_gettop(L);
6104 return luaL_error(L,
"wesnoth.wml_actions.command is missing");
6106 lua_pushvalue(L, argIdx);
6115 int evtIdx = lua_gettop(L);
6117 return luaL_ref(L, evtIdx);
6124 int evtIdx = lua_gettop(L);
6125 std::ostringstream lua_name;
6126 lua_name <<
"event ";
6128 lua_name <<
"<anon>";
6133 lua_name <<
"[id=" <<
id <<
"]";
6136 ERR_LUA <<
"Failed to register WML event: " << lua_name.str();
6139 return luaL_ref(L, evtIdx);
6145 idx = lua_absindex(L, idx);
6147 int evtIdx = lua_gettop(L);
6148 lua_pushvalue(L, idx);
6149 return luaL_ref(L, evtIdx);
6156 luaL_unref(L, -1, ref);
6163 lua_geti(L, -1, ref);
6164 if(lua_isnil(L, -1))
return false;
6210 lua_pushvalue(L, -1);
6230 std::string message = std::string() +
"function " + name +
" not found";
6231 log_error(message.c_str(),
"Lua SUF Error");
6235 lua_insert(L, -nArgs - 1);
6247 int top = lua_gettop(L);
6258 if(lua_istable(L, -1)) {
6261 lua_pushvalue(L, -1);
6263 lua_pushvalue(L, top + 1);
6265 lua_pushvalue(L, top + 2);
6270 if(luaL_getmetafield(L, -1,
"__descr")) {
6272 if(lua_isstring(L, -1)) {
6274 descr = lua_tostring(L, -1);
6276 lua_pushvalue(L, -2);
6278 lua_pushvalue(L, top + 1);
6280 lua_pushvalue(L, top + 2);
6283 if(lua_isstring(L, -1) && !lua_isnumber(L, -1)) {
6284 descr = lua_tostring(L, -1);
6286 ERR_LUA <<
"Effect __descr metafunction should have returned a string, but instead returned ";
6287 if(lua_isnone(L, -1)) {
6290 ERR_LUA << lua_typename(L, lua_type(L, -1));
6295 }
else if(need_apply) {
6297 lua_pushvalue(L, top + 1);
6299 lua_pushvalue(L, top + 2);
6337 if(!impl_get_callback<bool>(L,
"on_mouse_button")) {
static bool is_enemy(std::size_t side, std::size_t other_side)
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.
Composite AI with turn sequence which is a vector of stages.
GAME_CONFIG_SETTER("debug", bool, application_lua_kernel)
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.
config & add_child(std::string_view key)
optional_config_impl< config > optional_child(std::string_view key, int n=0)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
config & child_or_add(std::string_view key)
Returns a reference to the first child with the given key.
child_itors child_range(std::string_view key)
void splice_children(config &src, std::string_view key)
Moves all the children with tag key from src to this.
auto child_name_view() const
A non-owning view over all child tag names.
bool has_child(std::string_view key) const
Determine whether a config has a child or not.
config & mandatory_child(std::string_view key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
void remove_children(std::string_view key, const std::function< bool(const config &)> &p={})
Removes all children with tag key for which p returns true.
virtual void play_slice()
void add_chat_message(const std::chrono::system_clock::time_point &time, const std::string &speaker, int side, const std::string &msg, events::chat_handler::MESSAGE_TYPE type, bool bell)
void clear_chat_messages()
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,...
virtual const unit_map & units() const =0
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
const team & viewing_team() const
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.
const display_context & context() const
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_border_size(int border)
void set_bg_color(const color_t &bg_color)
void set_clip_rect(const rect &r)
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(std::string_view 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.
void set_allow_end_turn(bool value, const t_string &reason={})
@ 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)
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)
Create a new floating label or replace an existing one.
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: ...
int impl_theme_item(lua_State *L, const std::string &name)
Executes its upvalue as a theme item generator.
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.
scoped_lua_argument push_wml_events_table(lua_State *L) const
Pushes the WML events table to the Lua stack.
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)
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< actions::undo_list > undo_stack_
undo_stack_ is never nullptr.
const std::unique_ptr< game_events::manager > events_manager_
game_events::wmi_manager & get_wml_menu_items()
Encapsulates the map of the game.
const t_translation::ter_list & get_terrain_list() const
Gets the list of terrains.
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) 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(const std::string &prog, const std::string &name, const error_handler &, bool allow_unsafe=false)
void run_lua_tag(const config &cfg)
Runs a [lua] tag.
Efficiently creates new LUA "named tuples" with the specified field names.
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)
void register_generator(const std::string &name, generator *)
config generate_builtin_report(const std::string &name, const context &rc)
Generate the specified report using the given context, excluding dynamic generators.
const std::set< std::string > & report_list()
Shallow wrapper around lua_geti which pops the top variable from the Lua stack when destroyed.
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 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.
const std::string & id() const
t_translation::terrain_code number() const
void replace_schedule(const config &time_cfg)
Replace the time of day schedule.
int number_of_turns() 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.
const std::vector< time_of_day > & times() const
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.
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::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 reset_affect_adjacent(const unit_map &units)
Refresh map around unit if has ability with [affect_adjacent/distant] tag.
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(const 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...
constexpr uint8_t ALPHA_OPAQUE
A component of the AI framework.
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)
@ border
The border of the map.
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 impl_exec_stage(lua_State *L)
static const char endLvlKey[]
static int intf_run_event_wml(lua_State *L)
static int intf_eval_conditional(lua_State *L)
Evaluates a boolean WML conditional.
luaW_Registry & gameConfigReg()
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 const char mpsettingKey[]
static std::string read_event_name(lua_State *L, int idx)
static int intf_remove_modifications(lua_State *L)
Removes modifications from a unit.
static int impl_exec_candidate_action(lua_State *L)
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 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.
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 resistance_against(const std::string &damage_name, bool attacker, const map_location &loc) const
The unit's resistance against a given damage type.
int defense_modifier(const t_translation::terrain_code &terrain, const map_location &loc) const
The unit's defense on a given terrain.
unit_animation_component & anim_comp() const
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(const 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.
void apply_builtin_effect(const std::string &type, const config &effect)
Apply a builtin effect to the unit.
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)
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_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, const 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.
Handling of system events.
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 intf_show_recall_dialog(lua_State *L)
int intf_show_recruit_dialog(lua_State *L)
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(std::string_view tag, Args &&... data)
Wraps the given data in the specified tag.
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, sound_tracks::type group, unsigned int repeats)
terrain_code read_terrain_code(std::string_view str, const ter_layer filler)
Reads a single terrain from a string.
constexpr terrain_code NONE_TERRAIN
std::string write_terrain_code(const terrain_code &tcode)
Writes a single terrain code to a string.
void move_unit(const std::vector< map_location > &path, const unit_ptr &u, bool animate, map_location::direction dir, bool force_scroll)
Display a unit moving along a given path.
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
auto find(Container &container, const Value &value, const Projection &projection={})
@ STRIP_SPACES
REMOVE_EMPTY: remove empty elements.
int stoi(std::string_view str)
Same interface as std::stoi and meant as a drop in replacement, except:
std::string join_map(const T &v, const std::string &major=",", const std::string &minor=":")
std::string join(const Range &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)
auto * find(Container &container, const Value &value)
Convenience wrapper for using find on a container without needing to comare to end()
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
std::unique_ptr< MIX_Audio, decltype(&MIX_DestroyAudio)> value
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 that implement the undoing (and redoing) of in-game commands.
Various functions implementing vision (through fog of war and shroud).