114 #include <functional>
126 #include <SDL2/SDL_timer.h>
133 #define LOG_LUA LOG_STREAM(info, log_scripting_lua)
134 #define WRN_LUA LOG_STREAM(warn, log_scripting_lua)
135 #define ERR_LUA LOG_STREAM(err, log_scripting_lua)
138 #define ERR_WML LOG_STREAM(err, log_wml)
146 template <member_callback method>
148 return ((lua_kernel_base::get_lua_kernel<game_lua_kernel>(L)).*method)(L);
154 template <member_callback2 method,
bool b>
156 return ((lua_kernel_base::get_lua_kernel<game_lua_kernel>(L)).*method)(L,
b);
206 if(!sides.
empty()) {
WRN_LUA <<
"ignoring duplicate side filter information (inline side=)"; }
219 struct queued_event_context
222 std::stack<qe const *> & stack_;
224 queued_event_context(qe
const *new_qe, std::stack<qe const*> & stack)
230 ~queued_event_context()
245 lua_pushinteger(L, disp->viewing_side());
246 lua_pushboolean(L, disp->show_everything());
264 anim.~unit_animator();
273 std::string which = luaL_checkstring(L, 3);
275 std::string hits_str = luaL_checkstring(L, 4);
285 if(lua_istable(L, 5)) {
286 lua_getfield(L, 5,
"target");
289 return luaL_argerror(L, 5,
"target location must be different from animated unit's location");
291 return luaL_argerror(L, 5,
"target location must be adjacent to the animated unit");
296 if(!lua_isnoneornil(L, -1)) {
302 lua_getfield(L, 5,
"value");
303 if(lua_isnumber(L, -1)) {
304 v1 = lua_tointeger(L, -1);
305 }
else if(lua_istable(L, -1)) {
306 lua_rawgeti(L, -1, 1);
307 v1 = lua_tointeger(L, -1);
309 lua_rawgeti(L, -1, 2);
310 v2 = lua_tointeger(L, -1);
312 }
else if(!lua_isnoneornil(L, -1)) {
313 return luaW_type_error(L, 5,
"value",
"number or array of two numbers");
317 lua_getfield(L, 5,
"with_bars");
318 if(lua_isboolean(L, -1)) {
320 }
else if(!lua_isnoneornil(L, -1)) {
321 return luaW_type_error(L, 5,
"with_bars", lua_typename(L, LUA_TBOOLEAN));
325 lua_getfield(L, 5,
"text");
326 if(lua_isstring(L, -1)) {
327 text = lua_tostring(L, -1);
330 }
else if(!lua_isnoneornil(L, -1)) {
335 lua_getfield(L, 5,
"color");
336 if(lua_istable(L, -1) && lua_rawlen(L, -1) == 3) {
337 int idx = lua_absindex(L, -1);
338 lua_rawgeti(L, idx, 1);
339 lua_rawgeti(L, idx, 2);
340 lua_rawgeti(L, idx, 3);
341 color =
color_t(lua_tointeger(L, -3), lua_tointeger(L, -2), lua_tointeger(L, -1));
343 }
else if(!lua_isnoneornil(L, -1)) {
348 lua_getfield(L, 5,
"primary");
350 if(!primary && !lua_isnoneornil(L, -1)) {
355 lua_getfield(L, 5,
"secondary");
357 if(!secondary && !lua_isnoneornil(L, -1)) {
361 }
else if(!lua_isnoneornil(L, 5)) {
365 anim.
add_animation(up, which, u.
get_location(), dest, v1, bars, text, color, hits, primary, secondary, v2);
393 const char* m = lua_tostring(L, 2);
401 luaL_Reg metafuncs[] {
405 {
"run", &dispatch<&game_lua_kernel::impl_run_animation>},
409 luaL_setfuncs(L, metafuncs, 0);
410 lua_pushstring(L,
"__metatable");
413 lua_setmetatable(L, -2);
423 name = cfg[
"name"].str();
426 name = luaL_optstring(L, 1,
"");
444 if(lua_isstring(L, 1) && !lua_isnumber(L, 1)) {
445 std::string
id = luaL_checkstring(L, 1);
455 return luaL_argerror(L, 1,
"expected string or location");
459 if (!ui.
valid())
return 0;
480 if (!ui.
valid())
return 0;
498 std::vector<const unit*>
units;
502 return luaL_argerror(L, 2,
"unit not found");
505 }
else if(!lua_isnoneornil(L, 2)) {
509 return luaL_argerror(L, 2,
"invalid location");
524 lua_rawseti(L, 1,
i);
544 lua_pushboolean(L,
true);
550 WRN_LUA <<
"wesnoth.units.matches called with a secondary unit (3rd argument), ";
551 WRN_LUA <<
"but unit to match was on recall list. ";
552 WRN_LUA <<
"Thus the 3rd argument is ignored.";
559 return luaL_argerror(L, 3,
"unit not found");
561 lua_pushboolean(L,
unit_filter(filter).matches(*u, *u_adj));
567 lua_pushboolean(L,
unit_filter(filter).matches(*u, loc));
572 lua_pushboolean(L,
unit_filter(filter).matches(*u, loc));
597 if (!filter.
null()) {
599 t.save_id_or_number(),
t.recall_list().find_index(u->id()));
604 lua_rawseti(L, 1,
i);
623 char const *m = luaL_checkstring(L, 1);
640 if(
data.has_child(
"primary_attack")) {
641 data.add_child(
"first",
data.mandatory_child(
"primary_attack"));
642 data.remove_children(
"primary_attack");
644 if(
data.has_child(
"secondary_attack")) {
645 data.add_child(
"second",
data.mandatory_child(
"secondary_attack"));
646 data.remove_children(
"secondary_attack");
657 lua_pushboolean(L,
b);
675 char const *m = luaL_checkstring(L, 1);
680 lua_pushboolean(L,
b);
692 char const *m = luaL_checkstring(L, 1);
704 const std::string m = luaL_checkstring(L, 1);
705 if(m.empty())
return luaL_argerror(L, 1,
"empty variable name");
706 if (lua_isnoneornil(L, 2)) {
719 cfg[
"side"] =
teams().size() + 1;
734 std::string ids(luaL_checkstring(L, 1));
737 WRN_LUA <<
"[clear_menu_item] has been given an empty id=, ignoring";
754 if(lua_istable(L, 2)) {
766 return luaL_argerror(L, 2,
"expected list of locations");
785 if(lua_istable(L, 2)) {
813 if(!
map().on_board(loc))
return luaL_argerror(L, 1,
"not on board");
827 unsigned side_1, side_2;
831 side_1 = luaL_checkinteger(L, 1);
836 side_2 = luaL_checkinteger(L, 2);
839 lua_pushboolean(L,
board().get_team(side_1).is_enemy(side_2));
873 lua_pushstring(L, tod.
id.c_str());
874 lua_setfield(L, -2,
"id");
876 lua_setfield(L, -2,
"lawful_bonus");
878 lua_setfield(L, -2,
"bonus_modified");
879 lua_pushstring(L, tod.
image.c_str());
880 lua_setfield(L, -2,
"image");
882 lua_setfield(L, -2,
"name");
883 lua_pushstring(L, tod.
sounds.c_str());
884 lua_setfield(L, -2,
"sound");
886 lua_setfield(L, -2,
"mask");
888 lua_pushinteger(L, tod.
color.
r);
889 lua_setfield(L, -2,
"red");
890 lua_pushinteger(L, tod.
color.
g);
891 lua_setfield(L, -2,
"green");
892 lua_pushinteger(L, tod.
color.
b);
893 lua_setfield(L, -2,
"blue");
900 lua_newuserdatauv(L, 0, 1);
901 lua_pushinteger(L, area_index);
902 lua_setiuservalue(L, -2, 1);
903 if(luaL_newmetatable(L,
"schedule")) {
904 static luaL_Reg
const schedule_meta[] {
905 {
"__index", &dispatch<&game_lua_kernel::impl_schedule_get>},
906 {
"__newindex", &dispatch<&game_lua_kernel::impl_schedule_set>},
907 {
"__len", &dispatch<&game_lua_kernel::impl_schedule_len>},
910 luaL_setfuncs(L, schedule_meta, 0);
912 lua_setmetatable(L, -2);
917 int save_top = lua_gettop(L);
918 luaL_checkudata(L, idx,
"schedule");
919 lua_getiuservalue(L, idx, 1);
920 int i = luaL_checkinteger(L, -1);
921 lua_settop(L, save_top);
928 if(lua_isnumber(L, 2)) {
930 int i = lua_tointeger(L, 2) - 1;
931 if(i < 0 || i >=
static_cast<int>(times.size())) {
932 return luaL_argerror(L, 2,
"invalid time of day index");
937 const char* m = luaL_checkstring(L, 2);
938 if(area_index >= 0) {
941 if(strcmp(m,
"hexes") == 0) {
962 lua_pushinteger(L, times.size());
969 if(lua_isnumber(L, 2)) {
971 int i = lua_tointeger(L, 2) - 1;
972 if(i < 0 || i >=
static_cast<int>(times.size())) {
973 return luaL_argerror(L, 2,
"invalid time of day index");
983 const char* m = luaL_checkstring(L, 2);
984 if(strcmp(m,
"time_of_day") == 0) {
985 std::string value = luaL_checkstring(L, 3);
987 auto iter = std::find_if(times.begin(), times.end(), [&value](
const time_of_day& tod) {
988 return tod.id == value;
990 if(iter == times.end()) {
991 std::ostringstream
err;
992 err <<
"invalid time of day ID for ";
994 err <<
"global schedule";
1000 err <<
"anonymous empty time area";
1002 err <<
"anonymous time area at (" << hexes.begin()->wml_x() <<
',' << hexes.begin()->wml_y() <<
")";
1005 err <<
"time area with id=" <<
id;
1009 return lua_error(L);
1011 int n = std::distance(times.begin(), iter);
1012 if(area_index < 0) {
1018 if(area_index >= 0) {
1020 if(strcmp(m,
"hexes") == 0) {
1027 if(lua_isnil(L, 3) && strcmp(m,
"liminal_bonus") == 0) {
1044 char const *m = luaL_checkstring(L, 2);
1050 lua_pushstring(L,
info.id().c_str());
1051 lua_setfield(L, -2,
"id");
1053 lua_setfield(L, -2,
"name");
1055 lua_setfield(L, -2,
"editor_name");
1057 lua_setfield(L, -2,
"description");
1059 lua_setfield(L, -2,
"icon");
1061 lua_setfield(L, -2,
"editor_image");
1062 lua_pushinteger(L,
info.light_bonus(0));
1063 lua_setfield(L, -2,
"light");
1064 lua_pushboolean(L,
info.is_village());
1065 lua_setfield(L, -2,
"village");
1066 lua_pushboolean(L,
info.is_castle());
1067 lua_setfield(L, -2,
"castle");
1068 lua_pushboolean(L,
info.is_keep());
1069 lua_setfield(L, -2,
"keep");
1070 lua_pushinteger(L,
info.gives_healing());
1071 lua_setfield(L, -2,
"healing");
1082 template<
bool cons
ider_illuminates>
1089 if(!
board().
map().on_board_with_border(loc)) {
1090 return luaL_argerror(L, 1,
"coordinates are not on board");
1092 }
else if(lua_isstring(L, 1)) {
1095 return luaL_error(L,
"invalid or empty time_area ID");
1098 loc = *area.begin();
1099 }
else if(!lua_isnil(L, 1)) {
1102 return luaL_error(L,
"empty time_area");
1105 loc = *area.begin();
1108 if(lua_isnumber(L, 2)) {
1109 for_turn = luaL_checkinteger(L, 2);
1111 if(for_turn < 1 || (number_of_turns != -1 && for_turn > number_of_turns)) {
1112 return luaL_argerror(L, 2,
"turn number out of range");
1133 if (!
board().
map().is_village(loc))
1137 if (!side)
return 0;
1138 lua_pushinteger(L, side);
1150 if(!
board().
map().is_village(loc)) {
1155 const int new_side_num = lua_isnoneornil(L, 2) ? 0 : luaL_checkinteger(L, 2);
1157 team* old_side =
nullptr;
1158 team* new_side =
nullptr;
1160 if(old_side_num == new_side_num) {
1166 }
catch(
const std::out_of_range&) {
1173 }
catch(
const std::out_of_range&) {
1179 if(new_side &&
board().team_is_defeated(*new_side)) {
1212 if (!
board().
map().on_board(loc))
return 0;
1213 lua_pushinteger(L, loc.
wml_x());
1214 lua_pushinteger(L, loc.
wml_y());
1230 if (!
board().
map().on_board(loc))
return 0;
1231 lua_pushinteger(L, loc.
wml_x());
1232 lua_pushinteger(L, loc.
wml_y());
1245 std::string m = luaL_checkstring(L, 1);
1251 return luaL_argerror(L, 1, (
"Cannot find resource with id '" + m +
"'").c_str());
1263 std::string m = luaL_checkstring(L, 1);
1269 return luaL_argerror(L, 1, (
"Cannot find era with id '" + m +
"'").c_str());
1282 LOG_LUA <<
"impl_game_config_get";
1283 char const *m = luaL_checkstring(L, 2);
1298 if(strcmp(m,
"global_traits") == 0) {
1301 const std::string&
id = trait[
"id"];
1305 lua_pushstring(L,
id.c_str());
1334 LOG_LUA <<
"impl_game_config_set";
1335 char const *m = luaL_checkstring(L, 2);
1359 static config find_addon(
const std::string&
type,
const std::string&
id)
1368 const char* m = luaL_checkstring(L, 2);
1386 struct end_level_committer {
1388 ~end_level_committer() {
1389 pc_.set_end_level_data(data_);
1400 const char* m = luaL_checkstring(L, 2);
1416 data->~end_level_data();
1422 void*
p = lua_touserdata(L, lua_upvalueindex(1));
1424 if(lua_type(L, 2) == LUA_TNUMBER) {
1427 size_t i = luaL_checkinteger(L, 2);
1429 lua_createtable(L, 2, 0);
1430 lua_pushstring(L,
"options");
1438 auto iter =
settings.addons.begin();
1439 std::advance(iter,
i);
1441 iter->second.write(cfg);
1442 cfg[
"id"] = iter->first;
1444 lua_createtable(L, 2, 0);
1445 lua_pushstring(L,
"addon");
1453 char const *m = luaL_checkstring(L, 2);
1481 if(strcmp(m,
"savegame") == 0) {
1483 if(
savegame == saved_game_mode::type::no) {
1484 lua_pushboolean(L,
false);
1490 if(strcmp(m,
"side_players") == 0) {
1494 if(strcmp(m,
"addons") == 0) {
1495 for(
const auto& [
id, addon] :
settings.addons) {
1496 lua_createtable(L, 0, 4);
1498 lua_setfield(L, -2,
"id");
1500 lua_setfield(L, -2,
"name");
1501 lua_pushboolean(L, addon.required);
1502 lua_setfield(L, -2,
"required");
1503 if(addon.min_version) {
1505 lua_push(L, addon.min_version->str());
1507 lua_setfield(L, -2,
"min_version");
1513 lua_setfield(L, -2,
"version");
1515 lua_createtable(L, addon.content.size(), 0);
1516 for(
const auto& content : addon.content) {
1517 lua_createtable(L, 0, 3);
1519 lua_setfield(L, -2,
"id");
1521 lua_setfield(L, -2,
"name");
1523 lua_setfield(L, -2,
"type");
1524 lua_seti(L, -2, lua_rawlen(L, -2) + 1);
1526 lua_setfield(L, -2,
"content");
1542 void*
p = lua_touserdata(L, lua_upvalueindex(1));
1544 lua_pushinteger(L,
settings.addons.size() + 1);
1556 LOG_LUA <<
"impl_scenario_get";
1557 char const *m = luaL_checkstring(L, 2);
1566 if(strcmp(m,
"resources") == 0) {
1569 resources.push_back(find_addon(
"resource", rsrc));
1584 if(strcmp(m,
"modifications") == 0) {
1585 std::vector<config> mods;
1587 mods.push_back(find_addon(
"modification", mod));
1592 if(strcmp(m,
"end_level_data") == 0) {
1598 if(luaL_newmetatable(L,
"end level data")) {
1599 static luaL_Reg
const callbacks[] {
1601 {
"__newindex", &dispatch<&game_lua_kernel::impl_end_level_data_set>},
1603 {
nullptr,
nullptr }
1605 luaL_setfuncs(L, callbacks, 0);
1607 lua_setmetatable(L, -2);
1613 if(strcmp(m,
"mp_settings") == 0) {
1614 lua_newuserdatauv(L, 0, 0);
1615 if(luaL_newmetatable(L,
"mp settings")) {
1618 lua_setfield(L, -2,
"__index");
1621 lua_setfield(L, -2,
"__len");
1622 lua_pushstring(L,
"mp settings");
1623 lua_setfield(L, -2,
"__metatable");
1625 lua_setmetatable(L, -2);
1641 LOG_LUA <<
"impl_scenario_set";
1642 char const *m = luaL_checkstring(L, 2);
1654 if(strcmp(m,
"end_level_data") == 0) {
1658 data.proceed_to_next_level = cfg[
"proceed_to_next_level"].to_bool(
true);
1659 data.transient.carryover_report = cfg[
"carryover_report"].to_bool(
true);
1660 data.prescenario_save = cfg[
"save"].to_bool(
true);
1661 data.replay_save = cfg[
"replay_save"].to_bool(
true);
1662 data.transient.linger_mode = cfg[
"linger_mode"].to_bool(
true) && !
teams().empty();
1664 data.is_victory = cfg[
"result"] == level_result::victory;
1665 data.test_result = cfg[
"test_result"].str();
1686 return "local_choice";
1705 char const *m = luaL_checkstring(L, 2);
1713 if(strcmp(m,
"map") == 0) {
1716 if(strcmp(m,
"schedule") == 0) {
1721 if (strcmp(m,
"event_context") == 0)
1725 cfg[
"name"] = ev.
name;
1732 cfg.
add_child(
"second_weapon", *weapon);
1737 cfg[
"damage_inflicted"] = di;
1767 if (lua_isnone(L, 2)) {
1773 LOG_LUA <<
"Script says: \"" << m <<
"\"";
1782 double factor = luaL_checknumber(L, 1);
1809 if (!lua_isnoneornil(L, 1)) {
1810 int max = 2 *
teams().size();
1811 int npn = luaL_checkinteger(L, 1);
1812 if (npn <= 0 || npn > max) {
1813 return luaL_argerror(L, 1,
"side number out of range");
1830 lua_pushboolean(L,
b);
1848 const unit* u =
nullptr;
1849 int viewing_side = 0;
1851 if (lua_isuserdata(L, arg))
1855 viewing_side = u->
side();
1864 viewing_side = u->
side();
1872 return luaL_argerror(L, 1,
"invalid location");
1874 return luaL_argerror(L, arg,
"invalid location");
1878 bool ignore_units =
false, see_all =
false, ignore_teleport =
false;
1879 double stop_at = 10000;
1880 std::unique_ptr<pathfind::cost_calculator> calc;
1882 if (lua_istable(L, arg))
1884 ignore_units = luaW_table_get_def<bool>(L, arg,
"ignore_units",
false);
1885 see_all = luaW_table_get_def<bool>(L, arg,
"ignore_visibility",
false);
1886 ignore_teleport = luaW_table_get_def<bool>(L, arg,
"ignore_teleport",
false);
1888 stop_at = luaW_table_get_def<double>(L, arg,
"max_cost", stop_at);
1891 lua_pushstring(L,
"viewing_side");
1893 if (!lua_isnil(L, -1)) {
1894 int i = luaL_checkinteger(L, -1);
1895 if (
i >= 1 &&
i <=
static_cast<int>(
teams().
size())) viewing_side =
i;
1899 if(u) see_all =
true;
1900 deprecated_message(
"wesnoth.paths.find_path with viewing_side=0 (or an invalid side)",
DEP_LEVEL::FOR_REMOVAL, {1, 17, 0},
"To consider fogged and hidden units, use ignore_visibility=true instead.");
1905 lua_pushstring(L,
"calculate");
1907 if(lua_isfunction(L, -1)) {
1912 else if (lua_isfunction(L, arg))
1920 if(!ignore_teleport) {
1921 if(viewing_side == 0) {
1922 lua_warning(L,
"wesnoth.paths.find_path: ignore_teleport=false requires a valid viewing_side; continuing with ignore_teleport=true",
false);
1923 ignore_teleport =
true;
1931 return luaL_argerror(L, 1,
"unit not found OR custom cost function not provided");
1935 teams(),
map, ignore_units,
false, see_all));
1939 &teleport_locations);
1941 int nb = res.
steps.size();
1942 lua_createtable(L, nb, 0);
1943 for (
int i = 0;
i < nb; ++
i)
1946 lua_rawseti(L, -2,
i + 1);
1962 const unit* u =
nullptr;
1964 if (lua_isuserdata(L, arg))
1974 return luaL_argerror(L, 1,
"unit not found");
1979 int viewing_side = u->
side();
1980 bool ignore_units =
false, see_all =
false, ignore_teleport =
false;
1981 int additional_turns = 0;
1983 if (lua_istable(L, arg))
1985 ignore_units = luaW_table_get_def<bool>(L, arg,
"ignore_units",
false);
1986 see_all = luaW_table_get_def<bool>(L, arg,
"ignore_visibility",
false);
1987 ignore_teleport = luaW_table_get_def<bool>(L, arg,
"ignore_teleport",
false);
1988 additional_turns = luaW_table_get_def<int>(L, arg,
"max_cost", additional_turns);
1990 lua_pushstring(L,
"viewing_side");
1992 if (!lua_isnil(L, -1)) {
1993 int i = luaL_checkinteger(L, -1);
1994 if (
i >= 1 &&
i <=
static_cast<int>(
teams().
size())) viewing_side =
i;
1998 if(u) see_all =
true;
2008 viewing_team, additional_turns, see_all, ignore_units);
2011 lua_createtable(L, nb, 0);
2012 for (
int i = 0;
i < nb; ++
i)
2016 lua_pushinteger(L,
s.curr.wml_x());
2017 lua_rawseti(L, -2, 1);
2018 lua_pushinteger(L,
s.curr.wml_y());
2019 lua_rawseti(L, -2, 2);
2020 lua_pushinteger(L,
s.move_left);
2021 lua_rawseti(L, -2, 3);
2022 lua_rawseti(L, -2,
i + 1);
2037 const unit* u =
nullptr;
2039 if (lua_isuserdata(L, arg))
2049 return luaL_argerror(L, 1,
"unit not found");
2056 return luaL_error(L,
"wesnoth.find_vision_range: requires a valid unit");
2059 std::map<map_location, int> jamming_map;
2066 lua_pushinteger(L,
d.curr.wml_x());
2067 lua_rawseti(L, -2, 1);
2068 lua_pushinteger(L,
d.curr.wml_y());
2069 lua_rawseti(L, -2, 2);
2070 lua_pushinteger(L,
d.move_left);
2071 lua_rawseti(L, -2, 3);
2072 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
2074 for(
const auto&
e : res.
edges) {
2076 lua_pushinteger(L,
e.wml_x());
2077 lua_rawseti(L, -2, 1);
2078 lua_pushinteger(L,
e.wml_y());
2079 lua_rawseti(L, -2, 2);
2080 lua_pushinteger(L, -1);
2081 lua_rawseti(L, -2, 3);
2082 lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
2087 template<
typename T>
2090 for (
int i = 1, i_end = lua_rawlen(L, arg);
i <= i_end; ++
i)
2093 lua_rawgeti(L, arg,
i);
2094 int entry = lua_gettop(L);
2095 if (!lua_istable(L, entry)) {
2103 lua_rawgeti(L, entry, 3);
2104 if (!lua_isnumber(L, -1)) {
2105 lua_getfield(L, entry,
"side");
2106 if (!lua_isnumber(L, -1)) {
2110 int side = lua_tointeger(L, -1);
2112 lua_rawgeti(L, entry, 4);
2113 if (!lua_isstring(L, -1)) {
2114 lua_getfield(L, entry,
"type");
2115 if (!lua_isstring(L, -1)) {
2119 std::string
unit_type = lua_tostring(L, -1);
2123 lua_settop(L, entry - 1);
2127 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");
2145 std::vector<const ::unit*> real_units;
2146 typedef std::vector<std::tuple<map_location, int, std::string>> unit_type_vector;
2152 real_units.push_back(
unit);
2154 else if (!filter.
null())
2156 for(const ::unit* match :
unit_filter(filter).all_matches_on_map()) {
2157 if(match->get_location().valid()) {
2158 real_units.push_back(match);
2168 real_units.push_back(&(*ui));
2173 if (lua_istable(L, arg))
2181 return luaL_argerror(L, 1,
"unit(s) not found");
2184 int viewing_side = 0;
2185 bool ignore_units =
true, see_all =
true, ignore_teleport =
false,
debug =
false, use_max_moves =
false;
2187 if (lua_istable(L, arg))
2189 lua_pushstring(L,
"ignore_units");
2191 if (!lua_isnil(L, -1))
2197 lua_pushstring(L,
"ignore_teleport");
2199 if (!lua_isnil(L, -1))
2205 lua_pushstring(L,
"viewing_side");
2207 if (!lua_isnil(L, -1))
2209 int i = luaL_checkinteger(L, -1);
2210 if (
i >= 1 &&
i <=
static_cast<int>(
teams().
size()))
2217 lua_pushstring(L,
"debug");
2219 if (!lua_isnil(L, -1))
2225 lua_pushstring(L,
"use_max_moves");
2227 if (!lua_isnil(L, -1))
2244 const terrain_filter t_filter(filter, &fc,
false);
2249 const team& viewing_team = viewing_side
2254 ignore_units, !ignore_teleport, viewing_team, see_all, ignore_units);
2256 for (const ::unit*
const u : real_units)
2258 cost_map.
add_unit(*u, use_max_moves);
2260 for (
const unit_type_vector::value_type& fu :
fake_units)
2263 cost_map.
add_unit(std::get<0>(fu), ut, std::get<1>(fu));
2272 std::stringstream
s;
2288 lua_pushinteger(L, loc.wml_x());
2289 lua_rawseti(L, -2, 1);
2291 lua_pushinteger(L, loc.wml_y());
2292 lua_rawseti(L, -2, 2);
2294 lua_pushinteger(L, cost_map.
get_pair_at(loc).first);
2295 lua_rawseti(L, -2, 3);
2297 lua_pushinteger(L, cost_map.
get_pair_at(loc).second);
2298 lua_rawseti(L, -2, 4);
2300 lua_rawseti(L, -2, counter);
2310 return reinterpret_cast<int*
>(luaL_checkudata(L, idx,
labelKey));
2315 const char* m = luaL_checkstring(L, 2);
2323 int fade = luaL_optinteger(L, 2, -1);
2361 double width_ratio = 0;
2363 int lifetime = 2'000, fadeout = 100;
2369 if(lua_istable(L, 2)) {
2371 size = luaL_checkinteger(L, -1);
2375 width = lua_tointegerx(L, -1, &found_number);
2379 if(!value.empty() && value.back() ==
'%') {
2380 value.remove_suffix(1);
2381 width_ratio = std::stoi(std::string(value)) / 100.0;
2382 }
else throw std::invalid_argument(value.data());
2383 }
catch(std::invalid_argument&) {
2384 return luaL_argerror(L, -1,
"max_width should be integer or percentage");
2390 if(lua_isstring(L, -1)) {
2393 auto vec = lua_check<std::vector<int>>(L, -1);
2394 if(vec.size() != 3) {
2395 int idx = lua_absindex(L, -1);
2397 color.r = luaL_checkinteger(L, -3);
2398 color.g = luaL_checkinteger(L, -2);
2399 color.b = luaL_checkinteger(L, -1);
2401 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");
2411 if(lua_isstring(L, -1)) {
2414 auto vec = lua_check<std::vector<int>>(L, -1);
2415 if(vec.size() != 3) {
2416 int idx = lua_absindex(L, -1);
2418 bgcolor.r = luaL_checkinteger(L, -3);
2419 bgcolor.g = luaL_checkinteger(L, -2);
2420 bgcolor.b = luaL_checkinteger(L, -1);
2422 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");
2432 bgcolor.a = luaL_checkinteger(L, -1);
2437 lifetime = lua_tointegerx(L, -1, &found_number);
2440 if(value ==
"unlimited") {
2443 return luaL_argerror(L, -1,
"duration should be integer or 'unlimited'");
2448 fadeout = lua_tointeger(L, -1);
2454 static const char* options[] = {
"left",
"center",
"right"};
2455 alignment =
font::ALIGN(luaL_checkoption(L, -1,
nullptr, options));
2458 static const char* options[] = {
"top",
"center",
"bottom"};
2459 vertical_alignment =
font::ALIGN(luaL_checkoption(L, -1,
nullptr, options));
2471 int handle_idx = lua_gettop(L);
2478 if(width_ratio > 0) {
2479 width =
static_cast<int>(std::round(
rect.w * width_ratio));
2484 x =
rect.x + loc.wml_x();
2490 x =
rect.x +
rect.w / 2 + loc.wml_x();
2504 switch(vertical_alignment) {
2506 y =
rect.y + loc.wml_y();
2509 y =
rect.y +
rect.h / 2 + loc.wml_y();
2516 y =
rect.y +
rect.h - loc.wml_y() -
static_cast<int>(
size * 1.5);
2530 lua_settop(L, handle_idx);
2531 if(luaL_newmetatable(L,
labelKey)) {
2533 static const luaL_Reg methods[] = {
2534 {
"remove", &dispatch<&game_lua_kernel::intf_remove_floating_label>},
2535 {
"move", &dispatch<&game_lua_kernel::intf_move_floating_label>},
2536 {
"replace", &dispatch2<&game_lua_kernel::intf_set_floating_label, false>},
2538 {
nullptr,
nullptr }
2540 luaL_setfuncs(L, methods, 0);
2543 lua_setmetatable(L, handle_idx);
2544 lua_settop(L, handle_idx);
2569 return luaL_error(L,
"Attempted to move a unit while the map is locked");
2574 if (!
map().on_board(loc)) {
2575 return luaL_argerror(L, 2,
"invalid location");
2586 if (!
map().on_board(loc))
2587 return luaL_argerror(L, 1,
"invalid location");
2593 }
else if(!lua_isnoneornil(L, 1)) {
2594 const vconfig* vcfg =
nullptr;
2596 if (!
map().on_board(loc)) {
2599 if (!
map().on_board(loc))
2600 return luaL_argerror(L, 2,
"invalid location");
2606 u->set_location(loc);
2625 return luaL_error(L,
"Attempted to remove a unit while the map is locked");
2633 if (!
map().on_board(loc)) {
2634 return luaL_argerror(L, 1,
"invalid location");
2639 t.recall_list().erase_if_matches_id(u->
id());
2641 return luaL_argerror(L, 1,
"can't erase private units");
2644 if (!
map().on_board(loc)) {
2645 return luaL_argerror(L, 1,
"invalid location");
2648 return luaL_argerror(L, 1,
"expected unit or location");
2664 return luaL_error(L,
"Attempted to move a unit while the map is locked");
2668 int side = lua_tointeger(L, 2);
2669 if (
static_cast<unsigned>(side) >
teams().
size()) side = 0;
2673 u = lu->get_shared();
2674 if(lu->on_recall_list() && lu->on_recall_list() == side) {
2675 return luaL_argerror(L, 1,
"unit already on recall list");
2678 const vconfig* vcfg =
nullptr;
2690 std::size_t uid = u->underlying_id();
2691 t.recall_list().erase_by_underlying_id(uid);
2692 t.recall_list().add(u);
2697 u->anim_comp().clear_haloes();
2699 lu->lua_unit::~lua_unit();
2713 return luaL_error(L,
"Attempted to remove a unit while the map is locked");
2721 u->anim_comp().clear_haloes();
2722 }
else if (
int side = lu->on_recall_list()) {
2725 t.recall_list().erase_if_matches_id(u->id());
2731 lu->lua_unit::~lua_unit();
2747 if (!lua_isnoneornil(L, 2)) {
2751 const vconfig* vcfg =
nullptr;
2759 if (!res.
valid())
return 0;
2760 lua_pushinteger(L, res.
wml_x());
2761 lua_pushinteger(L, res.
wml_y());
2777 if (!lua_isnoneornil(L, 3)) {
2794 const vconfig* vcfg =
nullptr;
2824 char const *m = luaL_checkstring(L, 2);
2828 if(lua_isboolean(L, 3)) {
2830 if(!lua_isnoneornil(L, 4)) {
2833 }
else if(!lua_isnoneornil(L, 3)) {
2854 }
else if(lua_isstring(L, 2)) {
2855 char const *m = luaL_checkstring(L, 2);
2875 }
else if(lua_isstring(L, 2)) {
2876 char const *m = luaL_checkstring(L, 2);
2896 }
else if(lua_isstring(L, 2)) {
2897 char const *m = luaL_checkstring(L, 2);
2917 }
else if(lua_isstring(L, 2)) {
2918 char const *m = luaL_checkstring(L, 2);
2934 char const *m = luaL_checkstring(L, 2);
2948 char const *m = luaL_checkstring(L, 2);
2950 if (!utp)
return luaL_argerror(L, 2,
"unknown unit type");
2951 if(lua_isstring(L, 3)) {
2952 const std::string& m2 = lua_tostring(L, 3);
2953 if(!utp->
has_variation(m2))
return luaL_argerror(L, 2,
"unknown unit variation");
2967 lua_createtable(L, 0, 4);
2969 lua_setfield(L, -2,
"poisoned");
2970 lua_pushnumber(L, cmb.
slowed);
2971 lua_setfield(L, -2,
"slowed");
2973 lua_setfield(L, -2,
"untouched");
2975 lua_setfield(L, -2,
"average_hp");
2976 lua_createtable(L,
n, 0);
2977 for (
int i = 0;
i <
n; ++
i) {
2979 lua_rawseti(L, -2,
i);
2981 lua_setfield(L, -2,
"hp_chance");
2990 lua_createtable(L, 0, 16);
2993 lua_setfield(L, -2,
"num_blows");
2994 lua_pushnumber(L, bcustats.
damage);
2995 lua_setfield(L, -2,
"damage");
2997 lua_setfield(L, -2,
"chance_to_hit");
2998 lua_pushboolean(L, bcustats.
poisons);
2999 lua_setfield(L, -2,
"poisons");
3000 lua_pushboolean(L, bcustats.
slows);
3001 lua_setfield(L, -2,
"slows");
3003 lua_setfield(L, -2,
"petrifies");
3004 lua_pushboolean(L, bcustats.
plagues);
3005 lua_setfield(L, -2,
"plagues");
3007 lua_setfield(L, -2,
"plague_type");
3008 lua_pushnumber(L, bcustats.
rounds);
3009 lua_setfield(L, -2,
"rounds");
3011 lua_setfield(L, -2,
"firststrike");
3012 lua_pushboolean(L, bcustats.
drains);
3013 lua_setfield(L, -2,
"drains");
3015 lua_setfield(L, -2,
"drain_constant");
3017 lua_setfield(L, -2,
"drain_percent");
3022 lua_setfield(L, -2,
"attack_num");
3024 lua_setfield(L, -2,
"number");
3026 if(bcustats.
weapon !=
nullptr)
3028 lua_pushstring(L, bcustats.
weapon->id().c_str());
3029 lua_setfield(L, -2,
"name");
3031 lua_setfield(L, -2,
"weapon");
3050 int arg_num = 1, att_w = -1, def_w = -1;
3054 if (lua_isnumber(L, arg_num)) {
3055 att_w = lua_tointeger(L, arg_num) - 1;
3056 if (att_w < 0 || att_w >=
static_cast<int>(att->attacks().size()))
3057 return luaL_argerror(L, arg_num,
"weapon index out of bounds");
3063 if (lua_isnumber(L, arg_num)) {
3064 def_w = lua_tointeger(L, arg_num) - 1;
3065 if (def_w < 0 || def_w >=
static_cast<int>(def->attacks().size()))
3066 return luaL_argerror(L, arg_num,
"weapon index out of bounds");
3071 def->get_location(), att_w, def_w, 0.0,
nullptr, att, def);
3088 char const *m = luaL_checkstring(L, 1);
3089 int repeats = luaL_optinteger(L, 2, 0);
3101 const char* content_for = luaL_checkstring(L, 1);
3102 const char*
id = luaL_checkstring(L, 2);
3105 if(group.content_for_ == content_for) {
3107 if(achieve.
id_ ==
id) {
3134 ERR_LUA <<
"Achievement " <<
id <<
" not found for achievement group " << content_for;
3140 ERR_LUA <<
"Achievement group " << content_for <<
" not found";
3152 const char* content_for = luaL_checkstring(L, 1);
3153 const char*
id = luaL_checkstring(L, 2);
3156 ERR_LUA <<
"Returning false for whether a player has completed an achievement due to being networked multiplayer.";
3157 lua_pushboolean(L,
false);
3173 const char* content_for = luaL_checkstring(L, 1);
3174 const char*
id = luaL_checkstring(L, 2);
3178 if(group.content_for_ == content_for) {
3179 for(
const auto& achieve : group.achievements_) {
3180 if(achieve.id_ ==
id) {
3182 cfg[
"id"] = achieve.id_;
3183 cfg[
"name"] = achieve.name_;
3184 cfg[
"name_completed"] = achieve.name_completed_;
3185 cfg[
"description"] = achieve.description_;
3186 cfg[
"description_completed"] = achieve.description_completed_;
3187 cfg[
"icon"] = achieve.icon_;
3188 cfg[
"icon_completed"] = achieve.icon_completed_;
3189 cfg[
"hidden"] = achieve.hidden_;
3190 cfg[
"achieved"] = achieve.achieved_;
3191 cfg[
"max_progress"] = achieve.max_progress_;
3192 cfg[
"current_progress"] = achieve.current_progress_;
3194 for(
const auto& sub_ach : achieve.sub_achievements_) {
3196 sub[
"id"] = sub_ach.id_;
3197 sub[
"description"] = sub_ach.description_;
3198 sub[
"icon"] = sub_ach.icon_;
3199 sub[
"achieved"] = sub_ach.achieved_;
3207 ERR_LUA <<
"Achievement " <<
id <<
" not found for achievement group " << content_for;
3213 ERR_LUA <<
"Achievement group " << content_for <<
" not found";
3229 const char* content_for = luaL_checkstring(L, 1);
3230 const char*
id = luaL_checkstring(L, 2);
3231 int amount = luaL_checkinteger(L, 3);
3232 int limit = luaL_optinteger(L, 4, 999999999);
3235 if(group.content_for_ == content_for) {
3237 if(achieve.
id_ ==
id) {
3240 ERR_LUA <<
"Attempted to progress achievement " <<
id <<
" for achievement group " << content_for <<
", is not a progressible achievement.";
3241 lua_pushinteger(L, -1);
3242 lua_pushinteger(L, -1);
3257 lua_pushinteger(L, progress);
3259 lua_pushinteger(L, -1);
3267 lua_push(L,
"Achievement " + std::string(
id) +
" not found for achievement group " + content_for);
3268 return lua_error(L);
3273 lua_push(L,
"Achievement group " + std::string(content_for) +
" not found");
3274 return lua_error(L);
3286 const char* content_for = luaL_checkstring(L, 1);
3287 const char*
id = luaL_checkstring(L, 2);
3288 const char* sub_id = luaL_checkstring(L, 3);
3291 ERR_LUA <<
"Returning false for whether a player has completed an achievement due to being networked multiplayer.";
3292 lua_pushboolean(L,
false);
3308 const char* content_for = luaL_checkstring(L, 1);
3309 const char*
id = luaL_checkstring(L, 2);
3310 const char* sub_id = luaL_checkstring(L, 3);
3313 if(group.content_for_ == content_for) {
3315 if(achieve.
id_ ==
id) {
3322 if(sub_ach.
id_ == sub_id) {
3340 lua_push(L,
"Sub-achievement " + std::string(
id) +
" not found for achievement" +
id +
" in achievement group " + content_for);
3341 return lua_error(L);
3345 lua_push(L,
"Achievement " + std::string(
id) +
" not found for achievement group " + content_for);
3346 return lua_error(L);
3351 lua_push(L,
"Achievement group " + std::string(content_for) +
" not found");
3352 return lua_error(L);
3388 if(lua_isnoneornil(L, 1)) {
3393 if(!
map().on_board(loc))
return luaL_argerror(L, 1,
"not on board");
3394 bool highlight =
true;
3395 if(!lua_isnoneornil(L, 2))
3425 lua_pushboolean(L, skipping);
3436 if (!lua_isnone(L, 1)) {
3448 int user_choice_index;
3449 int random_choice_index;
3450 int ai_choice_index;
3452 lua_synchronize(lua_State *l,
const std::string& descr,
int user_index,
int random_index = 0,
int ai_index = 0)
3454 , user_choice_index(user_index)
3455 , random_choice_index(random_index)
3456 , ai_choice_index(ai_index != 0 ? ai_index : user_index)
3462 bool is_local_ai = lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).board().get_team(side).is_local_ai();
3464 query_lua(side, is_local_ai ? ai_choice_index : user_choice_index, cfg);
3471 if(random_choice_index != 0 && lua_isfunction(L, random_choice_index)) {
3472 query_lua(side, random_choice_index, cfg);
3482 void query_lua(
int side,
int function_index,
config& cfg)
const
3484 lua_pushvalue(L, function_index);
3485 lua_pushnumber(L, side);
3488 static const char*
msg =
"function returned to wesnoth.sync.[multi_]evaluate a table which was partially invalid";
3489 lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).log_error(
msg);
3490 lua_warning(L,
msg,
false);
3497 virtual bool is_visible()
const override {
return false; }
3511 std::string tagname =
"input";
3518 if(!lua_isfunction(L, nextarg) &&
luaW_totstring(L, nextarg, desc) ) {
3521 if(lua_isfunction(L, nextarg)) {
3522 human_func = nextarg++;
3525 return luaL_argerror(L, nextarg,
"expected a function");
3527 if(lua_isfunction(L, nextarg)) {
3528 ai_func = nextarg++;
3530 side_for = lua_tointeger(L, nextarg);
3546 std::string tagname =
"input";
3550 std::vector<int> sides_for;
3553 if(!lua_isfunction(L, nextarg) &&
luaW_totstring(L, nextarg, desc) ) {
3556 if(lua_isfunction(L, nextarg)) {
3557 human_func = nextarg++;
3560 return luaL_argerror(L, nextarg,
"expected a function");
3562 if(lua_isfunction(L, nextarg)) {
3563 null_func = nextarg++;
3565 sides_for = lua_check<std::vector<int>>(L, nextarg++);
3580 lua_pushvalue(L, 1);
3595 std::set<map_location> res;
3597 const terrain_filter t_filter(filter, &fc,
false);
3599 t_filter.get_locations(res, *
luaW_tounit(L, 2),
true);
3601 t_filter.get_locations(res,
true);
3620 if (filter.
null()) {
3621 lua_pushboolean(L,
true);
3626 const terrain_filter t_filter(filter, &fc,
false);
3628 lua_pushboolean(L, t_filter.match(loc, *
luaW_tounit(L, 3)));
3630 lua_pushboolean(L, t_filter.match(loc));
3647 if (filter.
null()) {
3648 lua_pushboolean(L,
true);
3656 lua_pushboolean(L, s_filter.
match(*
t));
3658 unsigned side = luaL_checkinteger(L, 1) - 1;
3660 lua_pushboolean(L, s_filter.
match(side + 1));
3671 team_i = luaL_checkinteger(L, 1);
3673 std::string
flag = luaL_optlstring(L, 2,
"",
nullptr);
3674 std::string color = luaL_optlstring(L, 3,
"",
nullptr);
3676 if(
flag.empty() && color.empty()) {
3679 if(team_i < 1 ||
static_cast<std::size_t
>(team_i) >
teams().
size()) {
3680 return luaL_error(L,
"set_side_id: side number %d out of range", team_i);
3684 if(!color.empty()) {
3699 side_num =
t->side();
3701 side_num = luaL_checkinteger(L, 1);
3703 std::string
path = luaL_checkstring(L, 2);
3708 if(strcmp(action,
"delete") == 0) {
3713 std::size_t len = std::string::npos, open_brak =
path.find_last_of(
'[');
3714 std::size_t dot =
path.find_last_of(
'.');
3715 if(open_brak != len) {
3716 len = open_brak - dot - 1;
3727 side_num =
t->side();
3729 side_num = luaL_checkinteger(L, 1);
3731 if(lua_isstring(L, 2)) {
3732 std::string file = luaL_checkstring(L, 2);
3734 std::string
err =
formatter() <<
"Could not load AI for side " << side_num <<
" from file " << file;
3735 lua_pushlstring(L,
err.c_str(),
err.length());
3736 return lua_error(L);
3748 side_num =
t->side();
3750 side_num = luaL_checkinteger(L, 1);
3754 cfg =
config {
"ai", cfg};
3756 bool added_dummy_stage =
false;
3758 added_dummy_stage =
true;
3762 if(added_dummy_stage) {
3764 if(iter->key ==
"stage" && iter->cfg[
"name"] ==
"empty") {
3765 iter = cfg.
erase(iter);
3775 unsigned i = luaL_checkinteger(L, 1);
3776 if(i < 1 || i >
teams().
size())
return 0;
3788 LOG_LUA <<
"intf_get_sides called: this = " << std::hex <<
this << std::dec <<
" myname = " <<
my_name();
3789 std::vector<int> sides;
3803 lua_createtable(L, sides.size(), 0);
3805 for(
int side : sides) {
3807 lua_rawseti(L, -2,
index);
3824 char const *m = luaL_checkstring(L, 2);
3826 if (sm ==
"advance") {
3830 if (sm !=
"advancement" && sm !=
"object" && sm !=
"trait") {
3831 return luaL_argerror(L, 2,
"unknown modification type");
3833 bool write_to_mods =
true;
3834 if (!lua_isnone(L, 4)) {
3838 write_to_mods =
false;
3856 std::vector<std::string> tags;
3857 if(lua_isstring(L, 3)) {
3858 tags.push_back(lua_check<std::string>(L, 3));
3859 }
else if (lua_istable(L, 3)){
3860 tags = lua_check<std::vector<std::string>>(L, 3);
3862 tags.push_back(
"object");
3868 for(
const std::string& tag : tags) {
3870 if(obj.matches(filter)) {
3871 obj[
"duration"] =
"now";
3891 if(lua_isboolean(L, 2)) {
3894 if(lua_isboolean(L, 3)) {
3908 char const *ty = luaL_checkstring(L, 1);
3911 std::stringstream ss;
3912 ss <<
"unknown unit type: '" << ty <<
"'";
3913 return luaL_argerror(L, 1, ss.str().c_str());
3930 std::string team_name;
3933 std::vector<std::string> team_names;
3934 std::transform(
teams.begin(),
teams.end(), std::back_inserter(team_names),
3935 [&](
int team) { return game_state_.get_disp_context().get_team(team).team_name(); });
3938 team_name = cfg[
"team_name"].str();
3943 team_name, cfg[
"name"], cfg[
"visible_in_fog"].to_bool(
true),
3944 cfg[
"submerge"].to_double(0), cfg[
"z_order"].to_double(0));
3957 char const *m = lua_tostring(L, 2);
3974 const int nargs = lua_gettop(L);
3975 if(nargs < 2 || nargs > 3) {
3976 return luaL_error(L,
"Wrong number of arguments to ai.log_replay() - should be 2 or 3 arguments.");
3978 const std::string key = nargs == 2 ? luaL_checkstring(L, 1) : luaL_checkstring(L, 2);
3984 }
else if(!lua_isstring(L, 3)) {
3985 return luaL_argerror(L, 3,
"accepts only string or config");
4008 cfg.
add_child(
"filter_lua")[
"code"] =
"<function>";
4018 if(lua_isstring(L, idx)) {
4019 return lua_tostring(L, idx);
4059 using namespace std::literals;
4065 }
else if(is_menu_item) {
4067 return luaL_argerror(L, 1,
"non-empty id is required for a menu item");
4069 name =
"menu item " +
id;
4071 if(
id.empty() && name.empty()) {
4072 return luaL_argerror(L, 1,
"either a name or id is required");
4075 if(new_handler.valid()) {
4076 bool has_lua_filter =
false;
4080 int filterIdx = lua_gettop(L);
4083 if(lua_isfunction(L, filterIdx)) {
4084 int fcnIdx = lua_absindex(L, -1);
4085 new_handler->add_filter(std::make_unique<lua_event_filter>(*
this, fcnIdx,
luaW_table_get_def(L, 1,
"filter_args",
config())));
4086 has_lua_filter =
true;
4088 #define READ_ONE_FILTER(key, tag) \
4090 if(luaW_tableget(L, filterIdx, key)) { \
4091 if(lua_isstring(L, -1)) { \
4092 filters.add_child("insert_tag", config{ \
4094 "variable", luaL_checkstring(L, -1) \
4097 filters.add_child(tag, luaW_checkconfig(L, -1)); \
4107 #undef READ_ONE_FILTER
4109 filters[
"filter_formula"] = luaL_checkstring(L, -1);
4113 new_handler->read_filters(filters);
4119 if(has_lua_filter) {
4124 new_handler->register_wml_event(*
this);
4137 lua_pushvalue(L, lua_upvalueindex(1));
4154 template<
bool is_menu_item>
4160 double priority = luaL_optnumber(L, 3, 0.);
4162 return luaL_argerror(L, 1,
"must not be empty");
4166 name =
"menu item " + name;
4167 }
else if(lua_absindex(L, -1) > 2 && lua_isfunction(L, -1)) {
4170 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_undoable_event>, 2);
4173 if(new_handler.valid()) {
4190 bool delayed_variable_substitution = cfg[
"delayed_variable_substitution"].to_bool(
true);
4191 if(delayed_variable_substitution) {
4218 lua_pushinteger(L, color.r);
4219 lua_pushinteger(L, color.g);
4220 lua_pushinteger(L, color.b);
4229 auto vec = lua_check<std::vector<uint8_t>>(L, 1);
4230 if(vec.size() != 4) {
4233 color_t fade{vec[0], vec[1], vec[2], vec[3]};
4251 lua_Integer delay = luaL_checkinteger(L, 1);
4259 const unsigned final = SDL_GetTicks() + delay;
4263 }
while (
static_cast<int>(
final - SDL_GetTicks()) > 0);
4287 std::string team_name;
4290 if(lua_gettop(L) == 1 && lua_istable(L, 1)) {
4291 using namespace std::literals;
4294 team_name = luaL_optstring(L, 2,
"");
4308 switch(lua_type(L, 2)) {
4310 case LUA_TNONE:
case LUA_TNIL:
4315 if(
size_t n = luaL_checkinteger(L, 2);
n > 0 &&
n <=
teams().size()) {
4355 for (
const int side : filter.
get_teams()){
4377 int side = cfg[
"side"];
4387 lua_getfield(L, -1,
"ca_ptr");
4401 lua_getfield(L, -1,
"stg_ptr");
4410 lua_createtable(L, 0, 0);
4412 lua_pushstring(L,
"name");
4413 lua_pushstring(L,
c->get_name().c_str());
4416 lua_pushstring(L,
"engine");
4417 lua_pushstring(L,
c->get_engine().c_str());
4420 lua_pushstring(L,
"id");
4421 lua_pushstring(L,
c->get_id().c_str());
4424 if (ct ==
"candidate_action") {
4425 lua_pushstring(L,
"ca_ptr");
4426 lua_pushlightuserdata(L,
c);
4429 lua_pushstring(L,
"exec");
4434 if (ct ==
"stage") {
4435 lua_pushstring(L,
"stg_ptr");
4436 lua_pushlightuserdata(L,
c);
4439 lua_pushstring(L,
"exec");
4445 std::vector<std::string> c_types =
c->get_children_types();
4447 for (std::vector<std::string>::const_iterator
t = c_types.begin();
t != c_types.end(); ++
t)
4449 std::vector<ai::component*> children =
c->get_children(*
t);
4450 std::string
type = *
t;
4451 if (
type ==
"aspect" ||
type ==
"goal" ||
type ==
"engine")
4456 lua_pushstring(L,
type.c_str());
4457 lua_createtable(L, 0, 0);
4459 for (std::vector<ai::component*>::const_iterator
i = children.begin();
i != children.end(); ++
i)
4461 lua_pushstring(L, (*i)->get_name().c_str());
4492 side = luaL_checkinteger(L, 1);
4499 std::vector<ai::component*> engines =
c->get_children(
"engine");
4501 for (std::vector<ai::component*>::const_iterator
i = engines.begin();
i != engines.end(); ++
i)
4503 if ((*i)->get_name() ==
"lua")
4513 if (lua_engine ==
nullptr)
4526 LOG_LUA <<
"Created new dummy lua-engine for debug_ai().";
4536 lua_pushstring(L,
"components");
4562 if(lua_isboolean(L, 1)) {
4587 std::set<map_location> locs;
4590 if(lua_gettop(L) == 1) {
4593 id = cfg[
"id"].str();
4594 const terrain_filter filter(cfg, &
game_state_,
false);
4595 filter.get_locations(locs,
true);
4598 id = luaL_checkstring(L, 1);
4599 if(!lua_isnoneornil(L, 3))
4604 const terrain_filter filter(cfg, &
game_state_,
false);
4605 filter.get_locations(locs,
true);
4613 LOG_LUA <<
"Lua inserted time_area '" <<
id <<
"'";
4622 const char *
id = luaL_checkstring(L, 1);
4624 LOG_LUA <<
"Lua removed time_area '" <<
id <<
"'";
4634 if(area_index < 0) {
4641 std::string area_id = luaL_checkstring(L, 1);
4643 if(
auto iter = std::find(area_ids.begin(), area_ids.end(), area_id); iter == area_ids.end()) {
4657 if(luaL_testudata(L, 1,
"schedule")) {
4667 ERR_LUA <<
"attempted to to replace ToD schedule with empty schedule";
4673 LOG_LUA <<
"replaced ToD schedule";
4681 int x = luaL_checkinteger(L, 1);
4682 int y = luaL_checkinteger(L, 2);
4701 lua_report_generator(lua_State *L,
const std::string &
n)
4710 if (!
luaW_getglobal(L,
"wesnoth",
"interface",
"game_display", name))
4734 char const *m = luaL_checkstring(L, 2);
4736 lua_pushvalue(L, 2);
4737 lua_pushvalue(L, -2);
4748 char const *m = luaL_checkstring(L, 2);
4749 lua_pushvalue(L, 2);
4750 lua_pushvalue(L, 3);
4782 if (dst == u->get_location() || !
map().on_board(dst)) {
4786 if (!
map().on_board(vacant_dst)) {
4797 std::vector<map_location> teleport_path;
4798 teleport_path.push_back(src_loc);
4799 teleport_path.push_back(vacant_dst);
4806 u->anim_comp().set_standing();
4813 if (
map().is_village(vacant_dst)) {
4832 const std::string& logger = lua_isstring(L, 2) ? luaL_checkstring(L, 1) :
"";
4833 const std::string&
msg = lua_isstring(L, 2) ? luaL_checkstring(L, 2) : luaL_checkstring(L, 1);
4835 if(logger ==
"wml" || logger ==
"WML") {
4849 lua_pushboolean(L, fog ?
t.fogged(loc) :
t.shrouded(loc));
4867 bool affect_normal_fog =
false;
4868 if(lua_isboolean(L, -1)) {
4871 std::set<int> sides;
4873 sides.insert(
t->side());
4874 }
else if(lua_isnumber(L, 1)) {
4875 sides.insert(lua_tointeger(L, 1));
4876 }
else if(lua_istable(L, 1) && lua_istable(L, 2)) {
4877 const auto& v = lua_check<std::vector<int>>(L, 1);
4878 sides.insert(v.begin(), v.end());
4881 sides.insert(
t.side()+1);
4886 for(
const int &side_num : sides) {
4887 if(side_num < 1 ||
static_cast<std::size_t
>(side_num) >
teams().
size()) {
4893 t.remove_fog_override(locs);
4894 if(affect_normal_fog) {
4897 }
else if(!affect_normal_fog) {
4899 t.add_fog_override(locs);
4917 const std::string name = luaL_checkstring(L, 1);
4922 if(!
luaW_getglobal(L,
"wesnoth",
"custom_synced_commands", name)) {
4923 return luaL_argerror(L, 1,
"Unknown synced command");
4926 cmd_tag[
"name"] = name;
4927 if(!lua_isnoneornil(L, 2)) {
4988 cmd_log_ <<
"Registering game-specific wesnoth lib functions...\n";
4991 static luaL_Reg
const callbacks[] {
4996 {
"cancel_action", &dispatch<&game_lua_kernel::intf_cancel_action > },
4997 {
"log_replay", &dispatch<&game_lua_kernel::intf_log_replay > },
4998 {
"log", &dispatch<&game_lua_kernel::intf_log > },
4999 {
"redraw", &dispatch<&game_lua_kernel::intf_redraw > },
5000 {
"simulate_combat", &dispatch<&game_lua_kernel::intf_simulate_combat > },
5001 {
nullptr,
nullptr }
5002 };lua_getglobal(L,
"wesnoth");
5003 if (!lua_istable(L,-1)) {
5006 luaL_setfuncs(L, callbacks, 0);
5008 lua_setglobal(L,
"wesnoth");
5010 lua_getglobal(L,
"gui");
5011 lua_pushcfunction(L, &dispatch<&game_lua_kernel::intf_gamestate_inspector>);
5012 lua_setfield(L, -2,
"show_inspector");
5018 static luaL_Reg
const test_callbacks[] {
5019 {
"fire_wml_menu_item", &dispatch<&game_lua_kernel::intf_fire_wml_menu_item> },
5020 {
nullptr,
nullptr }
5022 luaL_setfuncs(L, test_callbacks, 0);
5023 lua_setglobal(L,
"unit_test");
5049 cmd_log_ <<
"Adding terrain_types table...\n";
5050 lua_getglobal(L,
"wesnoth");
5051 lua_newuserdatauv(L, 0, 0);
5052 lua_createtable(L, 0, 2);
5053 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_get_terrain_info>);
5054 lua_setfield(L, -2,
"__index");
5055 lua_pushstring(L,
"terrain types");
5056 lua_setfield(L, -2,
"__metatable");
5057 lua_setmetatable(L, -2);
5058 lua_setfield(L, -2,
"terrain_types");
5062 cmd_log_ <<
"Adding ai elements table...\n";
5067 cmd_log_ <<
"Adding wesnoth current table...\n";
5069 lua_getglobal(L,
"wesnoth");
5070 lua_newuserdatauv(L, 0, 0);
5071 lua_createtable(L, 0, 2);
5072 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_current_get>);
5073 lua_setfield(L, -2,
"__index");
5074 lua_pushstring(L,
"current config");
5075 lua_setfield(L, -2,
"__metatable");
5076 lua_setmetatable(L, -2);
5077 lua_setfield(L, -2,
"current");
5081 lua_getglobal(L,
"wml");
5082 static luaL_Reg
const wml_callbacks[] {
5086 {
"get_variable", &dispatch<&game_lua_kernel::intf_get_variable>},
5087 {
"set_variable", &dispatch<&game_lua_kernel::intf_set_variable>},
5088 {
"get_all_vars", &dispatch<&game_lua_kernel::intf_get_all_vars>},
5089 {
nullptr,
nullptr }
5091 luaL_setfuncs(L, wml_callbacks, 0);
5096 static luaL_Reg
const map_callbacks[] {
5103 {
"get_owner", &dispatch<&game_lua_kernel::intf_get_village_owner>},
5104 {
"set_owner", &dispatch<&game_lua_kernel::intf_set_village_owner>},
5106 {
"add_label", &dispatch<&game_lua_kernel::intf_add_label>},
5107 {
"remove_label", &dispatch<&game_lua_kernel::intf_remove_label>},
5108 {
"get_label", &dispatch<&game_lua_kernel::intf_get_label>},
5110 {
"place_area", &dispatch<&game_lua_kernel::intf_add_time_area>},
5111 {
"remove_area", &dispatch<&game_lua_kernel::intf_remove_time_area>},
5112 {
"get_area", &dispatch<&game_lua_kernel::intf_get_time_area>},
5114 {
"find", &dispatch<&game_lua_kernel::intf_get_locations>},
5115 {
"matches", &dispatch<&game_lua_kernel::intf_match_location>},
5117 {
nullptr,
nullptr }
5119 luaL_setfuncs(L, map_callbacks, 0);
5123 cmd_log_ <<
"Adding units module...\n";
5124 static luaL_Reg
const unit_callbacks[] {
5127 {
"erase", &dispatch<&game_lua_kernel::intf_erase_unit>},
5128 {
"extract", &dispatch<&game_lua_kernel::intf_extract_unit>},
5129 {
"matches", &dispatch<&game_lua_kernel::intf_match_unit>},
5130 {
"select", &dispatch<&game_lua_kernel::intf_select_unit>},
5131 {
"to_map", &dispatch<&game_lua_kernel::intf_put_unit>},
5132 {
"to_recall", &dispatch<&game_lua_kernel::intf_put_recall_unit>},
5134 {
"teleport", &dispatch<&game_lua_kernel::intf_teleport>},
5136 {
"ability", &dispatch<&game_lua_kernel::intf_unit_ability>},
5147 {
"find_on_map", &dispatch<&game_lua_kernel::intf_get_units>},
5148 {
"find_on_recall", &dispatch<&game_lua_kernel::intf_get_recall_units>},
5149 {
"get", &dispatch<&game_lua_kernel::intf_get_unit>},
5150 {
"get_hovered", &dispatch<&game_lua_kernel::intf_get_displayed_unit>},
5151 {
"create_animator", &dispatch<&game_lua_kernel::intf_create_animator>},
5154 {
nullptr,
nullptr }
5156 lua_getglobal(L,
"wesnoth");
5158 luaL_setfuncs(L, unit_callbacks, 0);
5159 lua_setfield(L, -2,
"units");
5163 cmd_log_ <<
"Adding sides module...\n";
5164 static luaL_Reg
const side_callbacks[] {
5165 {
"is_enemy", &dispatch<&game_lua_kernel::intf_is_enemy> },
5166 {
"matches", &dispatch<&game_lua_kernel::intf_match_side> },
5167 {
"set_id", &dispatch<&game_lua_kernel::intf_set_side_id> },
5172 {
"find", &dispatch<&game_lua_kernel::intf_get_sides> },
5173 {
"get", &dispatch<&game_lua_kernel::intf_get_side> },
5174 {
"create", &dispatch<&game_lua_kernel::intf_create_side> },
5176 {
"place_shroud", &dispatch2<&game_lua_kernel::intf_toggle_shroud, true>},
5177 {
"remove_shroud", &dispatch2<&game_lua_kernel::intf_toggle_shroud, false>},
5178 {
"override_shroud", &dispatch<&game_lua_kernel::intf_override_shroud>},
5179 {
"is_shrouded", &dispatch2<&game_lua_kernel::intf_get_fog_or_shroud, false>},
5181 {
"place_fog", &dispatch2<&game_lua_kernel::intf_toggle_fog, false>},
5182 {
"remove_fog", &dispatch2<&game_lua_kernel::intf_toggle_fog, true>},
5183 {
"is_fogged", &dispatch2<&game_lua_kernel::intf_get_fog_or_shroud, true>},
5184 {
nullptr,
nullptr }
5186 std::vector<lua_cpp::Reg>
const cpp_side_callbacks {
5187 {
"add_ai_component", std::bind(
intf_modify_ai, std::placeholders::_1,
"add")},
5188 {
"delete_ai_component", std::bind(
intf_modify_ai, std::placeholders::_1,
"delete")},
5189 {
"change_ai_component", std::bind(
intf_modify_ai, std::placeholders::_1,
"change")},
5193 lua_getglobal(L,
"wesnoth");
5195 luaL_setfuncs(L, side_callbacks, 0);
5197 lua_setfield(L, -2,
"sides");
5201 cmd_log_ <<
"Adding interface module...\n";
5202 static luaL_Reg
const intf_callbacks[] {
5203 {
"add_hex_overlay", &dispatch<&game_lua_kernel::intf_add_tile_overlay>},
5204 {
"remove_hex_overlay", &dispatch<&game_lua_kernel::intf_remove_tile_overlay>},
5205 {
"get_color_adjust", &dispatch<&game_lua_kernel::intf_get_color_adjust>},
5206 {
"color_adjust", &dispatch<&game_lua_kernel::intf_color_adjust>},
5207 {
"screen_fade", &dispatch<&game_lua_kernel::intf_screen_fade>},
5208 {
"delay", &dispatch<&game_lua_kernel::intf_delay>},
5209 {
"deselect_hex", &dispatch<&game_lua_kernel::intf_deselect_hex>},
5210 {
"highlight_hex", &dispatch<&game_lua_kernel::intf_highlight_hex>},
5211 {
"float_label", &dispatch<&game_lua_kernel::intf_float_label>},
5212 {
"get_displayed_unit", &dispatch<&game_lua_kernel::intf_get_displayed_unit>},
5213 {
"get_hovered_hex", &dispatch<&game_lua_kernel::intf_get_mouseover_tile>},
5214 {
"get_selected_hex", &dispatch<&game_lua_kernel::intf_get_selected_tile>},
5215 {
"lock", &dispatch<&game_lua_kernel::intf_lock_view>},
5216 {
"is_locked", &dispatch<&game_lua_kernel::intf_view_locked>},
5217 {
"scroll", &dispatch<&game_lua_kernel::intf_scroll>},
5218 {
"scroll_to_hex", &dispatch<&game_lua_kernel::intf_scroll_to_tile>},
5219 {
"skip_messages", &dispatch<&game_lua_kernel::intf_skip_messages>},
5220 {
"is_skipping_messages", &dispatch<&game_lua_kernel::intf_is_skipping_messages>},
5221 {
"zoom", &dispatch<&game_lua_kernel::intf_zoom>},
5222 {
"clear_menu_item", &dispatch<&game_lua_kernel::intf_clear_menu_item>},
5223 {
"set_menu_item", &dispatch<&game_lua_kernel::intf_set_menu_item>},
5224 {
"allow_end_turn", &dispatch<&game_lua_kernel::intf_allow_end_turn>},
5225 {
"clear_chat_messages", &dispatch<&game_lua_kernel::intf_clear_messages>},
5226 {
"end_turn", &dispatch<&game_lua_kernel::intf_end_turn>},
5228 {
"add_chat_message", &dispatch<&game_lua_kernel::intf_message>},
5229 {
"add_overlay_text", &dispatch2<&game_lua_kernel::intf_set_floating_label, true>},
5231 {
nullptr,
nullptr }
5233 lua_getglobal(L,
"wesnoth");
5235 luaL_setfuncs(L, intf_callbacks, 0);
5236 lua_setfield(L, -2,
"interface");
5240 cmd_log_ <<
"Adding achievements module...\n";
5241 static luaL_Reg
const achievement_callbacks[] {
5242 {
"set", &dispatch<&game_lua_kernel::intf_set_achievement> },
5243 {
"has", &dispatch<&game_lua_kernel::intf_has_achievement> },
5244 {
"get", &dispatch<&game_lua_kernel::intf_get_achievement> },
5245 {
"progress", &dispatch<&game_lua_kernel::intf_progress_achievement> },
5246 {
"has_sub_achievement", &dispatch<&game_lua_kernel::intf_has_sub_achievement> },
5247 {
"set_sub_achievement", &dispatch<&game_lua_kernel::intf_set_sub_achievement> },
5248 {
nullptr,
nullptr }
5250 lua_getglobal(L,
"wesnoth");
5252 luaL_setfuncs(L, achievement_callbacks, 0);
5253 lua_setfield(L, -2,
"achievements");
5257 cmd_log_ <<
"Adding audio module...\n";
5258 static luaL_Reg
const audio_callbacks[] {
5259 {
"play", &dispatch<&game_lua_kernel::intf_play_sound > },
5260 {
nullptr,
nullptr }
5262 lua_getglobal(L,
"wesnoth");
5264 luaL_setfuncs(L, audio_callbacks, 0);
5265 lua_setfield(L, -2,
"audio");
5269 cmd_log_ <<
"Adding paths module...\n";
5270 static luaL_Reg
const path_callbacks[] {
5271 {
"find_cost_map", &dispatch<&game_lua_kernel::intf_find_cost_map > },
5272 {
"find_path", &dispatch<&game_lua_kernel::intf_find_path > },
5273 {
"find_reach", &dispatch<&game_lua_kernel::intf_find_reach > },
5274 {
"find_vacant_hex", &dispatch<&game_lua_kernel::intf_find_vacant_tile > },
5275 {
"find_vision_range", &dispatch<&game_lua_kernel::intf_find_vision_range > },
5276 {
nullptr,
nullptr }
5278 lua_getglobal(L,
"wesnoth");
5280 luaL_setfuncs(L, path_callbacks, 0);
5281 lua_setfield(L, -2,
"paths");
5285 cmd_log_ <<
"Adding sync module...\n";
5286 static luaL_Reg
const sync_callbacks[] {
5291 {
nullptr,
nullptr }
5293 lua_getglobal(L,
"wesnoth");
5295 luaL_setfuncs(L, sync_callbacks, 0);
5296 lua_setfield(L, -2,
"sync");
5300 cmd_log_ <<
"Adding schedule module...\n";
5301 static luaL_Reg
const schedule_callbacks[] {
5302 {
"get_time_of_day", &dispatch<&game_lua_kernel::intf_get_time_of_day<false>>},
5303 {
"get_illumination", &dispatch<&game_lua_kernel::intf_get_time_of_day<true>>},
5304 {
"replace", &dispatch<&game_lua_kernel::intf_replace_schedule>},
5305 {
nullptr,
nullptr }
5307 lua_getglobal(L,
"wesnoth");
5309 luaL_setfuncs(L, schedule_callbacks, 0);
5310 lua_createtable(L, 0, 2);
5311 lua_setmetatable(L, -2);
5312 lua_setfield(L, -2,
"schedule");
5319 cmd_log_ <<
"Adding wml_actions table...\n";
5321 lua_getglobal(L,
"wesnoth");
5323 lua_setfield(L, -2,
"wml_actions");
5327 cmd_log_ <<
"Adding wml_conditionals table...\n";
5329 lua_getglobal(L,
"wesnoth");
5331 lua_setfield(L, -2,
"wml_conditionals");
5338 cmd_log_ <<
"Adding effects table...\n";
5340 lua_getglobal(L,
"wesnoth");
5342 lua_setfield(L, -2,
"effects");
5346 cmd_log_ <<
"Adding custom_synced_commands table...\n";
5348 lua_getglobal(L,
"wesnoth");
5350 lua_setfield(L, -2,
"custom_synced_commands");
5354 cmd_log_ <<
"Adding game_events module...\n";
5355 static luaL_Reg
const event_callbacks[] {
5356 {
"add", &dispatch<&game_lua_kernel::intf_add_event> },
5357 {
"add_repeating", &dispatch<&game_lua_kernel::intf_add_event_simple<false>> },
5358 {
"add_menu", &dispatch<&game_lua_kernel::intf_add_event_simple<true>> },
5359 {
"add_wml", &dispatch<&game_lua_kernel::intf_add_event_wml> },
5360 {
"remove", &dispatch<&game_lua_kernel::intf_remove_event> },
5361 {
"fire", &dispatch2<&game_lua_kernel::intf_fire_event, false> },
5362 {
"fire_by_id", &dispatch2<&game_lua_kernel::intf_fire_event, true> },
5363 {
"add_undo_actions", &dispatch<&game_lua_kernel::intf_add_undo_actions> },
5364 {
"set_undoable", &dispatch<&game_lua_kernel::intf_allow_undo > },
5365 {
nullptr,
nullptr }
5367 lua_getglobal(L,
"wesnoth");
5369 luaL_setfuncs(L, event_callbacks, 0);
5370 lua_setfield(L, -2,
"game_events");
5374 cmd_log_ <<
"Adding game_display table...\n";
5378 lua_createtable(L, 0, 2);
5379 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_theme_items_get>);
5380 lua_setfield(L, -2,
"__index");
5381 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_theme_items_set>);
5382 lua_setfield(L, -2,
"__newindex");
5383 lua_setmetatable(L, -2);
5384 lua_setfield(L, -2,
"game_display");
5388 cmd_log_ <<
"Adding scenario table...\n";
5392 lua_createtable(L, 0, 2);
5393 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_scenario_get>);
5394 lua_setfield(L, -2,
"__index");
5395 lua_pushcfunction(L, &dispatch<&game_lua_kernel::impl_scenario_set>);
5396 lua_setfield(L, -2,
"__newindex");
5397 lua_setmetatable(L, -2);
5398 lua_setfield(L, -2,
"scenario");
5409 lua_pushstring(L, effect.c_str());
5427 cmd_log_ <<
"Adding races table...\n";
5430 lua_getglobal(L,
"wesnoth");
5432 lua_setfield(L, -2,
"races");
5436 cmd_log_ <<
"Running preload scripts...\n";
5459 using namespace std::literals::string_view_literals;
5460 static const std::array handled_file_tags {
5473 "modify_unit_type"sv,
5479 "terrain_graphics"sv,
5487 return std::binary_search(handled_file_tags.begin(), handled_file_tags.end(),
s);
5506 lua_createtable(L, 2, 0);
5507 lua_pushstring(L, v.key.c_str());
5508 lua_rawseti(L, -2, 1);
5510 lua_rawseti(L, -2, 2);
5511 lua_rawseti(L, -2, k++);
5546 const std::string m =
"Tag is already used: [" +
i->key +
"]";
5567 lua_pushstring(L, ev.
name.c_str());
5576 if (!
luaW_getglobal(L,
"wesnoth",
"custom_synced_commands", name)) {
5592 std::string which_effect = lua_tostring(L, lua_upvalueindex(1));
5607 lua_pushstring(L, description.c_str());
5620 int str_i = lua_gettop(L);
5623 lua_pushstring(L,
"__call");
5624 lua_pushvalue(L, str_i);
5625 lua_pushboolean(L,
true);
5626 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_builtin_effect>, 2);
5628 lua_pushstring(L,
"__descr");
5629 lua_pushvalue(L, str_i);
5630 lua_pushboolean(L,
false);
5631 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_builtin_effect>, 2);
5633 lua_setmetatable(L, -2);
5643 (lua_touserdata(L, lua_upvalueindex(1)));
5657 lua_getglobal(L,
"wesnoth");
5658 lua_pushstring(L,
"wml_actions");
5660 lua_pushstring(L, cmd.c_str());
5661 lua_pushlightuserdata(L,
reinterpret_cast<void *
>(
h));
5662 lua_pushcclosure(L, &dispatch<&game_lua_kernel::cfun_wml_action>, 1);
5675 (lua_touserdata(L, lua_upvalueindex(1)));
5678 lua_pushboolean(L,
h(vcfg));
5689 lua_getglobal(L,
"wesnoth");
5690 lua_pushstring(L,
"wml_conditionals");
5692 lua_pushstring(L, cmd.c_str());
5693 lua_pushlightuserdata(L,
reinterpret_cast<void *
>(
h));
5735 ERR_WML <<
"unknown conditional wml: [" << cmd <<
"]";
5754 int argIdx = lua_gettop(L);
5756 return luaL_error(L,
"wesnoth.wml_actions.command is missing");
5758 lua_pushvalue(L, argIdx);
5767 int evtIdx = lua_gettop(L);
5772 return luaL_ref(L, evtIdx);
5779 int evtIdx = lua_gettop(L);
5783 std::ostringstream lua_name;
5784 lua_name <<
"event ";
5786 lua_name <<
"<anon>";
5791 lua_name <<
"[id=" <<
id <<
"]";
5794 ERR_LUA <<
"Failed to register WML event: " << lua_name.str();
5797 return luaL_ref(L, evtIdx);
5803 idx = lua_absindex(L, idx);
5805 int evtIdx = lua_gettop(L);
5809 lua_pushvalue(L, idx);
5810 return luaL_ref(L, evtIdx);
5817 luaL_unref(L, -1, ref);
5828 lua_geti(L, -1, ref);
5829 if(lua_isnil(L, -1))
return false;
5875 lua_pushvalue(L, -1);
5895 std::string message = std::string() +
"function " + name +
" not found";
5896 log_error(message.c_str(),
"Lua SUF Error");
5900 lua_insert(L, -nArgs - 1);
5912 int top = lua_gettop(L);
5923 if(lua_istable(L, -1)) {
5926 lua_pushvalue(L, -1);
5928 lua_pushvalue(L, top + 1);
5930 lua_pushvalue(L, top + 2);
5935 if(luaL_getmetafield(L, -1,
"__descr")) {
5937 if(lua_isstring(L, -1)) {
5939 descr = lua_tostring(L, -1);
5941 lua_pushvalue(L, -2);
5943 lua_pushvalue(L, top + 1);
5945 lua_pushvalue(L, top + 2);
5948 if(lua_isstring(L, -1) && !lua_isnumber(L, -1)) {
5949 descr = lua_tostring(L, -1);
5951 ERR_LUA <<
"Effect __descr metafunction should have returned a string, but instead returned ";
5952 if(lua_isnone(L, -1)) {
5955 ERR_LUA << lua_typename(L, lua_type(L, -1));
5960 }
else if(need_apply) {
5962 lua_pushvalue(L, top + 1);
5964 lua_pushvalue(L, top + 2);
5989 if (!
luaW_getglobal(L,
"wesnoth",
"game_events",
"on_mouse_move")) {
6002 if (!
luaW_getglobal(L,
"wesnoth",
"game_events",
"on_mouse_button")) {
6021 if (!
luaW_getglobal(L,
"wesnoth",
"game_events",
"on_mouse_action")) {
Various functions that implement attacks and attack calculations.
Various functions related to moving units.
void advance_unit_at(const advance_unit_params ¶ms)
Various functions that implement advancements of units.
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
Class to encapsulate fog/shroud clearing and the resultant sighted events.
bool clear_dest(const map_location &dest, const unit &viewer)
Clears shroud (and fog) at the provided location and its immediate neighbors.
game_events::pump_result_t fire_events()
Fires the sighted events that were earlier recorded by fog/shroud clearing.
bool clear_unit(const map_location &view_loc, team &view_team, std::size_t viewer_id, int sight_range, bool slowed, const movetype::terrain_costs &costs, const map_location &real_loc, const std::set< map_location > *known_units=nullptr, std::size_t *enemy_count=nullptr, std::size_t *friend_count=nullptr, move_unit_spectator *spectator=nullptr, bool instant=true)
Clears shroud (and fog) around the provided location for view_team based on sight_range,...
virtual ai_context & get_ai_context()
unwrap
virtual double evaluate()=0
Evaluate the candidate action, resetting the internal state of the action.
virtual void execute()=0
Execute the candidate action.
static bool add_component(component *root, const std::string &path, const config &cfg)
static void expand_simplified_aspects(side_number side, config &cfg)
Expand simplified aspects, similar to the change from 1.7.2 to 1.7.3 but with some additional syntax ...
static const config & get_default_ai_parameters()
get default AI parameters
virtual config to_config() const
Serialize to config.
virtual void push_ai_table()
Method that pushes the AI table of the lua_context on the stack for debugging purposes.
component * get_component(component *root, const std::string &path)
Proxy class for calling AI action handlers defined in Lua.
static lua_ai_action_handler * create(lua_State *L, char const *code, lua_ai_context &context)
Proxy table for the AI context.
static void init(lua_State *L)
static lua_ai_context * create(lua_State *L, char const *code, engine_lua *engine)
bool add_ai_for_side_from_config(side_number side, const config &cfg, bool replace=true)
Adds active AI for specified side from cfg.
void append_active_ai_for_side(ai::side_number side, const config &cfg)
Appends AI parameters to active AI of the given side.
void raise_user_interact()
Notifies all observers of 'ai_user_interact' event.
static manager & get_singleton()
void modify_active_ai_for_side(ai::side_number side, const config &cfg)
Modifies AI parameters for active AI of the given side.
ai::holder & get_active_ai_holder_for_side_dbg(side_number side)
Gets the active AI holder for debug purposes.
bool play_stage()
Play the turn - strategy.
Computes the statistics of a battle between an attacker and a defender unit.
const battle_context_unit_stats & get_defender_stats() const
This method returns the statistics of the defender.
const combatant & get_attacker_combatant(const combatant *prev_def=nullptr)
Get the simulation results.
const battle_context_unit_stats & get_attacker_stats() const
This method returns the statistics of the attacker.
const combatant & get_defender_combatant(const combatant *prev_def=nullptr)
Variant for storing WML attributes.
std::string str(const std::string &fallback="") const
bool empty() const
Tests for an attribute that either was never set or was set to "".
A config object defines a single node in a WML file, with access to child nodes.
all_children_iterator erase(const all_children_iterator &i)
const_all_children_iterator ordered_begin() const
std::size_t attribute_count() const
Count the number of non-blank attributes.
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
const_attr_itors attribute_range() const
const_all_children_iterator ordered_end() const
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
child_itors child_range(config_key_type key)
config & child_or_add(config_key_type key)
Returns a reference to the first child with the given key.
std::size_t all_children_count() const
void append_children(const config &cfg)
Adds children from cfg.
void splice_children(config &src, const std::string &key)
Moves all the children with tag key from src to this.
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Euivalent to mandatory_child, but returns an empty optional if the nth child was not found.
config & add_child(config_key_type key)
virtual void play_slice(bool is_delay_enabled=true)
void clear_chat_messages()
void add_chat_message(const std::time_t &time, const std::string &speaker, int side, const std::string &msg, events::chat_handler::MESSAGE_TYPE type, bool bell)
int village_owner(const map_location &loc) const
Given the location of a village, will return the 1-based number of the team that currently owns it,...
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
void remove_overlay(const map_location &loc)
remove_overlay will remove all overlays on a tile.
std::size_t viewing_team() const
The viewing team is the team currently viewing the game.
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.
bool scroll(int xmov, int ymov, bool force=false)
Scrolls the display by xmov,ymov pixels.
void set_theme(const std::string &new_theme)
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.
const map_location & selected_hex() const
void fade_to(const color_t &color, int duration)
Screen fade.
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.
void add_overlay(const map_location &loc, const std::string &image, const std::string &halo="", const std::string &team_name="", const std::string &item_id="", bool visible_under_fog=true, float submerge=0.0f, float z_order=0)
Functions to add and remove overlays from locations.
void select_hex(const map_location &hex, const bool browse, const bool highlight=true, const bool fire_event=true)
void set_lifetime(int lifetime, int fadeout=100)
void set_position(double xpos, double ypos)
void set_alignment(ALIGN align)
void set_color(const color_t &color)
void set_clip_rect(const SDL_Rect &r)
void set_bg_color(const color_t &bg_color)
void set_font_size(int font_size)
virtual const std::vector< team > & teams() const override
unit_map::iterator find_visible_unit(const map_location &loc, const team ¤t_team, bool see_all=false)
virtual const unit_map & units() const override
virtual const gamemap & map() const override
std::string difficulty
The difficulty level the game is being played on.
std::vector< std::string > active_mods
bool end_credits
whether to show the standard credits at the end
unsigned int end_text_duration
for how long the end-of-campaign text is shown
std::string campaign
The id of the campaign being played.
bool is_multiplayer() const
std::string end_text
end-of-campaign text
static game_config_manager * get()
const game_config_view & game_config() const
A class grating read only view to a vector of config objects, viewed as one config with all children ...
const config & find_mandatory_child(config_key_type key, const std::string &name, const std::string &value) const
void clear_variable(const std::string &varname)
Clears attributes config children does nothing if varname is no valid variable name.
@ PRELOAD
the preload [event] is fired next phase: PRESTART (normal game), TURN_STARTING_WAITING (reloaded game...
@ INITIAL
creating intitial [unit]s, executing toplevel [lua] etc.
@ PRESTART
the prestart [event] is fired next phase: START (default), GAME_ENDING
@ TURN_PLAYING
The User is controlling the game and invoking actions The game can be saved here.
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_allow_end_turn(bool value, const t_string &reason="")
variable_access_const get_variable_access_read(const std::string &varname) const
returns a variable_access that cannot be used to change the game variables
void display_unit_hex(map_location hex)
Change the unit to be displayed in the sidebar.
void invalidate_unit_after_move(const map_location &src, const map_location &dst)
Same as invalidate_unit() if moving the displayed unit.
virtual void highlight_hex(map_location hex) override
Function to highlight a location.
virtual const map_location & displayed_unit_hex() const override
Virtual functions shadowed in game_display.
void new_turn()
Update lighting settings.
bool maybe_rebuild()
Rebuilds the screen if needs_rebuild(true) was previously called, and resets the flag.
display_chat_manager & get_chat_manager()
void float_label(const map_location &loc, const std::string &text, const color_t &color)
Function to float a label above a tile.
void set_arguments(const config &cfg)
The game event manager loads the scenario configuration object, and ensures that events are handled a...
void add_event_handler_from_wml(const config &handler, game_lua_kernel &lk, bool is_menu_item=false)
Create an event handler from an [event] tag.
pending_event_handler add_event_handler_from_lua(const std::string &name, const std::string &id, bool repeat=false, double priority=0., bool is_menu_item=false)
Create an empty event handler.
bool fire_item(const std::string &id, const map_location &hex, game_data &gamedata, filter_context &fc, unit_map &units, bool is_key_hold_repeat=false) const
Fires the menu item with the given id.
bool erase(const std::string &id)
Erases the item with the provided id.
void set_item(const std::string &id, const vconfig &menu_item)
Updates or creates (as appropriate) the menu item with the given id.
void(* handler)(const queued_event &, const vconfig &)
static const map & registry()
void set_action_canceled()
Sets whether or not wml wants to abort the currently executed user action.
pump_result_t fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
void set_undo_disabled(bool mutated)
[allow_undo] implementation
int intf_get_mouseover_tile(lua_State *L)
Returns the currently overed tile.
void custom_command(const std::string &, const config &)
int intf_put_unit(lua_State *L)
Places a unit on the map.
int intf_get_label(lua_State *L)
int intf_cancel_action(lua_State *)
int intf_set_floating_label(lua_State *L, bool spawn)
Arg 1: text - string Arg 2: options table.
int intf_replace_schedule(lua_State *l)
Replacing the current time of day schedule.
int intf_select_unit(lua_State *L)
Selects and highlights the given location on the map.
int intf_deselect_hex(lua_State *L)
Deselects any highlighted hex on the map.
std::stack< game_events::queued_event const * > queued_events_
int intf_get_all_vars(lua_State *L)
Gets all the WML variables currently set.
int intf_remove_tile_overlay(lua_State *L)
Removes an overlay from a tile.
int intf_screen_fade(lua_State *L)
int intf_erase_unit(lua_State *L)
Erases a unit from the map.
int intf_get_fog_or_shroud(lua_State *L, bool fog)
int intf_override_shroud(lua_State *L)
Overrides the shroud entirely.
int intf_get_variable(lua_State *L)
Gets a WML variable.
int intf_scroll(lua_State *L)
game_lua_kernel(game_state &, play_controller &, reports &)
int intf_set_sub_achievement(lua_State *L)
Marks a single sub-achievement as completed.
int intf_lock_view(lua_State *L)
Sets whether gamemap scrolling is disabled for the user.
void put_unit_helper(const map_location &loc)
int intf_toggle_shroud(lua_State *L, bool place_shroud)
Toggle shroud on some locations Arg 1: Side number Arg 2: List of locations on which to place/remove ...
int intf_match_side(lua_State *L)
Matches a side against the given filter.
int intf_get_selected_tile(lua_State *L)
Returns the currently selected tile.
int cfun_wml_action(lua_State *L)
Executes its upvalue as a wml action.
virtual void log_error(char const *msg, char const *context="Lua error") override
Error reporting mechanisms, used by virtual methods protected_call and load_string.
int cfun_builtin_effect(lua_State *L)
Applies its upvalue as an effect Arg 1: The unit to apply to Arg 3: The [effect] tag contents Arg 3: ...
ai::lua_ai_context * create_lua_ai_context(char const *code, ai::engine_lua *engine)
int intf_has_achievement(lua_State *L)
Returns whether an achievement has been completed.
int intf_gamestate_inspector(lua_State *)
int intf_float_label(lua_State *L)
Floats some text on the map.
int intf_find_reach(lua_State *L)
Finds all the locations reachable by a unit.
bool run_event(const game_events::queued_event &)
Executes the game_events.on_event function.
int intf_end_turn(lua_State *)
int save_wml_event()
Store a WML event in the Lua registry, as a function.
int 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.
static config preload_config
int intf_find_cost_map(lua_State *L)
Is called with one or more units and builds a cost map.
int intf_get_time_area(lua_State *)
int intf_highlight_hex(lua_State *L)
Highlights the given location on the map.
bool run_wml_event(int ref, const vconfig &args, const game_events::queued_event &ev, bool *out=nullptr)
Run a WML stored in the Lua registry.
int intf_scroll_to_tile(lua_State *L)
Scrolls to given tile.
int intf_get_side(lua_State *L)
int intf_remove_event(lua_State *L)
int intf_is_enemy(lua_State *L)
Returns whether the first side is an enemy of the second one.
static void extract_preload_scripts(const game_config_view &game_config)
int impl_get_terrain_info(lua_State *L)
Gets details about a terrain.
virtual std::string my_name() override
User-visible name of the lua kernel that they are talking to.
int intf_remove_label(lua_State *L)
bool run_wml_action(const std::string &, const vconfig &, const game_events::queued_event &)
Runs a command from an event handler.
int intf_move_floating_label(lua_State *L)
int intf_match_unit(lua_State *L)
Matches a unit against the given filter.
int intf_add_time_area(lua_State *)
Adding new time_areas dynamically with Standard Location Filters.
void clear_wml_event(int ref)
Clear a WML event store in the Lua registry.
int intf_create_animator(lua_State *)
int 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_
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...
int impl_game_config_set(lua_State *L) override
Sets some game_config data (__newindex metamethod).
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.
std::vector< team > & teams()
int intf_progress_achievement(lua_State *L)
Progresses the provided achievement.
int intf_match_location(lua_State *L)
Matches a location against the given filter.
int intf_toggle_fog(lua_State *L, const bool clear)
Implements the lifting and resetting of fog via WML.
int intf_extract_unit(lua_State *L)
Extracts a unit from the map or a recall list and gives it to Lua.
int intf_log(lua_State *L)
Logs a message Arg 1: (optional) Logger; "wml" for WML errors or deprecations Arg 2: Message Arg 3: W...
int intf_clear_messages(lua_State *)
Removes all messages from the chat window.
int intf_allow_undo(lua_State *)
Allow undo sets the flag saying whether the event has mutated the game to false.
int impl_schedule_get(lua_State *L)
int intf_set_variable(lua_State *L)
Sets a WML variable.
int impl_theme_items_set(lua_State *L)
Sets a field of the theme_items table (__newindex metamethod).
void set_game_display(game_display *gd)
int intf_set_menu_item(lua_State *L)
ai::lua_ai_action_handler * create_lua_ai_action_handler(char const *code, ai::lua_ai_context &context)
int impl_theme_item(lua_State *L, std::string name)
Executes its upvalue as a theme item generator.
bool mouse_button_callback(const map_location &loc, const std::string &button, const std::string &event)
int intf_get_achievement(lua_State *L)
Returns information on a single achievement, or no data if the achievement is not found.
std::vector< int > get_sides_vector(const vconfig &cfg)
Gets a vector of sides from side= attribute in a given config node.
int intf_fire_event(lua_State *L, const bool by_id)
Fires an event.
int intf_delay(lua_State *L)
Delays engine for a while.
int intf_add_event_simple(lua_State *L)
Add a new event handler Arg 1: Event to handle, as a string or list of strings; or menu item ID if th...
bool run_filter(char const *name, const unit &u)
Runs a script from a unit filter.
int intf_find_vision_range(lua_State *L)
Finds all the locations for which a given unit would remove the fog (if there was fog on the map).
int intf_skip_messages(lua_State *L)
Set whether to skip messages Arg 1 (optional) - boolean.
int impl_game_config_get(lua_State *L) override
Gets some game_config data (__index metamethod).
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.
bool do_healing_
True if healing should be done at the beginning of the next side turn.
const std::unique_ptr< game_events::manager > events_manager_
game_events::wmi_manager & get_wml_menu_items()
int w() const
Effective map width.
int h() const
Effective map height.
Encapsulates the map of the game.
const std::shared_ptr< terrain_type_data > & tdata() const
virtual void log_error(char const *msg, char const *context="Lua error")
Error reporting mechanisms, used by virtual methods protected_call and load_string.
virtual int impl_game_config_get(lua_State *L)
virtual int impl_game_config_set(lua_State *L)
bool load_string(char const *prog, const std::string &name, error_handler)
void run_lua_tag(const config &cfg)
Runs a [lua] tag.
Storage for a unit, either owned by the Lua code (ptr != 0), a local variable unit (c_ptr !...
bool put_map(const map_location &loc)
int on_recall_list() const
unit_ptr get_shared() const
const terrain_label * set_label(const map_location &loc, const t_string &text, const int creator=-1, const std::string &team="", const color_t color=font::NORMAL_COLOR, const bool visible_in_fog=true, const bool visible_in_shroud=false, const bool immutable=false, const std::string &category="", const t_string &tooltip="")
const terrain_label * get_label(const map_location &loc, const std::string &team_name) const
void recalculate_shroud()
game_classification & get_classification()
bool reveal_map_default() const
void set_end_level_data(const end_level_data &data)
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_regular_game_end() const
const mp_game_settings & get_mp_settings()
const end_level_data & get_end_level_data() const
int current_side() const
Returns the number of the side whose turn it is.
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::string get_loaded_resources() const
t_string get_scenario_name() const
std::set< std::string > & encountered_units()
int progress_achievement(const std::string &content_for, const std::string &id, int limit=999999, int max_progress=999999, int amount=0)
Increments the achievement's current progress by amount if it hasn't already been completed.
void set_achievement(const std::string &content_for, const std::string &id)
Marks the specified achievement as completed.
void set_sub_achievement(const std::string &content_for, const std::string &id, const std::string &sub_id)
Marks the specified sub-achievement as completed.
void add_log_data(const std::string &key, const std::string &var)
config generate_report(const std::string &name, const context &ct, bool only_static=false)
void register_generator(const std::string &name, generator *)
An object to leave the synced context during draw or unsynced wml items when we don’t know whether we...
std::vector< int > get_teams() const
bool match(const team &t) const
static map & registry()
using static function variable instead of static member variable to prevent static initialization fia...
static void add_undo_commands(const config &commands, const game_events::queued_event &ctx)
static synced_state get_synced_state()
This class stores all the data for a single 'side' (in game nomenclature).
game_events::pump_result_t get_village(const map_location &, const int owner_side, game_data *fire_event)
Acquires a village from owner_side.
const std::string & team_name() const
void set_color(const std::string &color)
void set_flag(const std::string &flag)
void lose_village(const map_location &)
To store label data Class implements logic for rendering.
void replace_schedule(const config &time_cfg)
Replace the time of day schedule.
int number_of_turns() const
const time_of_day get_illuminated_time_of_day(const unit_map &units, const gamemap &map, const map_location &loc, int for_turn=0) const
Returns time of day object for the passed turn at a location.
const std::vector< time_of_day > & times(const map_location &loc=map_location::null_location()) const
const std::string & get_area_id(int area_index) const
std::vector< std::string > get_area_ids() const
const std::set< map_location > & get_area_by_index(int index) const
void remove_time_area(const std::string &id)
Removes a time area from config, making it follow the scenario's normal time-of-day sequence.
void set_current_time(int time)
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.
void replace_area_locations(int index, const std::set< map_location > &locs)
void reset_max_liminal_bonus()
const std::set< map_location > & get_area_by_id(const std::string &id) const
std::pair< int, std::string > get_area_on_hex(const map_location &loc) const
void wait_for_end() const
void add_animation(unit_const_ptr animated_unit, const unit_animation *animation, const map_location &src=map_location::null_location(), bool with_bars=false, const std::string &text="", const color_t text_color={0, 0, 0})
std::vector< const unit * > all_matches_with_unit(const unit &u) const
std::vector< const unit * > all_matches_at(const map_location &loc) const
std::vector< const unit * > all_matches_on_map(const map_location *loc=nullptr, const unit *other_unit=nullptr) const
Container associating units to locations.
unit_ptr extract(const map_location &loc)
Extracts a unit from the map.
unit_iterator find(std::size_t id)
std::size_t erase(const map_location &l)
Erases the unit at location l, if any.
umap_retval_pair_t insert(unit_ptr p)
Inserts the unit pointed to by p into the map.
umap_retval_pair_t move(const map_location &src, const map_location &dst)
Moves a unit from location src to location dst.
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
config_array_view traits() const
A single unit type that the player may recruit.
const unit_type & get_variation(const std::string &id) const
bool has_variation(const std::string &variation_id) const
This class represents a single unit of a specific type.
static void clear_status_caches()
Clear this unit status cache for all units.
static unit_ptr create(const config &cfg, bool use_traits=false, const vconfig *vcfg=nullptr)
Initializes a unit from a config.
Additional functionality for a non-const variable_info.
Information on a WML variable.
A variable-expanding proxy for the config class.
static vconfig unconstructed_vconfig()
This is just a wrapper for the default constructor; it exists for historical reasons and to make it c...
vconfig child(const std::string &key) const
Returns a child of *this whose key is key.
const config & get_config() const
config get_parsed_config() const
child_list get_children(const std::string &key) const
constexpr uint8_t ALPHA_OPAQUE
A component of the AI framework.
Composite AI with turn sequence which is a vector of stages.
Define conditionals for the game's events mechanism, a.k.a.
Managing the AIs configuration - headers.
std::string deprecated_message(const std::string &elem_name, DEP_LEVEL level, const version_info &version, const std::string &detail)
LUA AI Support engine - creating specific ai components from config.
Define locations as used by the game's events mechanism.
static int intf_modify_ai(lua_State *L, const char *action)
int dispatch(lua_State *L)
static int load_fake_units(lua_State *L, int arg, T &fake_units)
static int impl_animator_get(lua_State *L)
static int impl_animator_collect(lua_State *L)
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)
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 READ_ONE_FILTER(key, tag)
bool(*)(const vconfig &) wml_conditional_handler
static int cfun_exec_candidate_action(lua_State *L)
static int intf_run_event_wml(lua_State *L)
static int intf_eval_conditional(lua_State *L)
Evaluates a boolean WML conditional.
static int impl_clear_animation(lua_State *L)
static int intf_advance_unit(lua_State *L)
Advances a unit if the unit has enough xp.
static int impl_add_animation(lua_State *L)
static int intf_debug_ai(lua_State *L)
Debug access to the ai tables.
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.
static void luaW_pushsimdata(lua_State *L, const combatant &cmb)
Puts a table at the top of the stack with some combat result.
static std::string read_event_name(lua_State *L, int idx)
static int intf_remove_modifications(lua_State *L)
Removes modifications from a unit.
int dispatch2(lua_State *L)
static int intf_copy_unit(lua_State *L)
Copies a unit.
static void push_component(lua_State *L, ai::component *c, const std::string &ct="")
static int impl_mp_settings_get(lua_State *L)
static int cfun_exec_stage(lua_State *L)
static int 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 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...
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 is_handled_file_tag(const std::string &s)
These are the child tags of [scenario] (and the like) that are handled elsewhere (in the C++ code).
static int cfun_wml_condition(lua_State *L)
Executes its upvalue as a wml condition and returns the result.
static int * luaW_check_floating_label(lua_State *L, int idx)
static int intf_unit_vision_cost(lua_State *L)
Returns unit vision cost on a given terrain.
static std::string _(const char *str)
bool get_ability_bool(const std::string &tag_name, const map_location &loc) const
Checks whether this unit currently possesses or is affected by a given ability.
const std::string & id() const
Gets this unit's id.
int side() const
The side this unit belongs to.
void advance_to(const unit_type &t, bool use_traits=false)
Advances this unit to another type.
int defense_modifier(const t_translation::terrain_code &terrain) const
The unit's defense on a given terrain.
int resistance_against(const std::string &damage_name, bool attacker, const map_location &loc, const_attack_ptr weapon=nullptr, const_attack_ptr opp_weapon=nullptr) const
The unit's resistance against a given damage type.
void apply_builtin_effect(std::string type, const config &effect)
Apply a builtin effect to the unit.
void add_modification(const std::string &type, const config &modification, bool no_add=false)
Add a new modification to the unit.
static const std::set< std::string > builtin_effects
std::string describe_builtin_effect(std::string type, const config &effect)
Construct a string describing a built-in effect.
config & get_modifications()
Get the raw modifications.
void expire_modifications(const std::string &duration)
Clears those modifications whose duration has expired.
const map_location & get_location() const
The current map location this unit is at.
int movement_cost(const t_translation::terrain_code &terrain) const
Get the unit's movement cost on a particular terrain.
int vision_cost(const t_translation::terrain_code &terrain) const
Get the unit's vision cost on a particular terrain.
int jamming_cost(const t_translation::terrain_code &terrain) const
Get the unit's jamming cost on a particular terrain.
std::string label
What to show in the filter's drop-down list.
std::string id
Text to match against addon_info.tags()
Define the handlers for the game's events mechanism.
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Standard logging facilities (interface).
#define log_scope(description)
void luaW_pushconfig(lua_State *L, const config &cfg)
Converts a config object to a Lua table pushed at the top of the stack.
bool luaW_iststring(lua_State *L, int index)
void luaW_push_namedtuple(lua_State *L, const std::vector< std::string > &names)
Push an empty "named tuple" onto the stack.
config luaW_checkconfig(lua_State *L, int index)
Converts an optional table or vconfig to a config object.
void luaW_pushlocation(lua_State *L, const map_location &ml)
Converts a map location object to a Lua table pushed at the top of the stack.
std::set< map_location > luaW_check_locationset(lua_State *L, int idx)
Converts a table of integer pairs to a set of map location objects.
void luaW_pushtstring(lua_State *L, const t_string &v)
Pushes a t_string on the top of the stack.
bool luaW_pushvariable(lua_State *L, variable_access_const &v)
bool luaW_tovconfig(lua_State *L, int index, vconfig &vcfg)
Gets an optional vconfig from either a table or a userdata.
void luaW_pushvconfig(lua_State *L, const vconfig &cfg)
Pushes a vconfig on the top of the stack.
bool luaW_toboolean(lua_State *L, int n)
int luaW_type_error(lua_State *L, int narg, const char *tname)
std::string_view luaW_tostring(lua_State *L, int index)
bool luaW_getmetafield(lua_State *L, int idx, const char *key)
Like luaL_getmetafield, but returns false if key is an empty string or begins with two underscores.
bool luaW_totstring(lua_State *L, int index, t_string &str)
Converts a scalar to a translatable string.
bool luaW_tableget(lua_State *L, int index, const char *key)
bool luaW_checkvariable(lua_State *L, variable_access_create &v, int n)
bool luaW_pcall(lua_State *L, int nArgs, int nRets, bool allow_wml_error)
Calls a Lua function stored below its nArgs arguments at the top of the stack.
bool luaW_toconfig(lua_State *L, int index, config &cfg)
Converts an optional table or vconfig to a config object.
int luaW_push_locationset(lua_State *L, const std::set< map_location > &locs)
Converts a set of map locations to a Lua table pushed at the top of the stack.
vconfig luaW_checkvconfig(lua_State *L, int index, bool allow_missing)
Gets an optional vconfig from either a table or a userdata.
bool luaW_tolocation(lua_State *L, int index, map_location &loc)
Converts an optional table or pair of integers to a map location object.
map_location luaW_checklocation(lua_State *L, int index)
Converts an optional table or pair of integers to a map location object.
bool luaW_getglobal(lua_State *L, const std::vector< std::string > &path)
Pushes the value found by following the variadic names (char *), if the value is not nil.
t_string luaW_checktstring(lua_State *L, int index)
Converts a scalar to a translatable string.
#define return_cfgref_attrib_deprecated(name, prefix, level, version, msg, accessor)
#define return_vector_string_attrib(name, accessor)
#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_int_attrib_deprecated(name, prefix, level, version, msg, accessor)
#define modify_bool_attrib(name, accessor)
#define modify_string_attrib_deprecated(name, prefix, level, version, msg, accessor)
#define return_vector_string_attrib_deprecated(name, prefix, level, version, msg, accessor)
#define modify_vector_string_attrib_deprecated(name, prefix, level, version, msg, accessor)
#define return_bool_attrib(name, accessor)
#define return_tstring_attrib(name, accessor)
#define modify_int_attrib(name, accessor)
#define return_cfg_attrib(name, accessor)
#define modify_tstring_attrib(name, accessor)
#define modify_string_attrib(name, accessor)
#define modify_vector_string_attrib(name, accessor)
#define return_int_attrib_deprecated(name, prefix, level, version, msg, accessor)
#define return_string_attrib_deprecated(name, prefix, level, version, msg, accessor)
void luaW_pushracetable(lua_State *L)
void luaW_pushteam(lua_State *L, team &tm)
Create a full userdata containing a pointer to the team.
team * luaW_toteam(lua_State *L, int idx)
Test if the top stack element is a team, and if so, return it.
team & luaW_checkteam(lua_State *L, int idx)
Test if the top stack element is a team, and if not, error.
std::set< map_location > location_set
int intf_terrain_mask(lua_State *L)
Replaces part of the map.
int intf_on_border(lua_State *L)
int intf_on_board(lua_State *L)
int intf_terrainmap_iter(lua_State *L)
int intf_terrainmap_get(lua_State *L)
int intf_replace_if_failed(lua_State *L)
lua_unit * luaW_checkunit_ref(lua_State *L, int index)
Similar to luaW_checkunit but returns a lua_unit; use this if you need to handle map and recall units...
unit & luaW_checkunit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
bool luaW_isunit(lua_State *L, int index)
Test if a Lua value is a unit.
unit_ptr luaW_checkunit_ptr(lua_State *L, int index, bool only_on_map)
Similar to luaW_checkunit but returns a unit_ptr; use this instead of luaW_checkunit when using an ap...
lua_unit * luaW_pushlocalunit(lua_State *L, unit &u)
Pushes a private unit on the stack.
unit * luaW_tounit(lua_State *L, int index, bool only_on_map)
Converts a Lua value to a unit pointer.
lua_unit * luaW_pushunit(lua_State *L, Args... args)
int intf_create_attack(lua_State *L)
const_attack_ptr luaW_toweapon(lua_State *L, int idx)
void luaW_pushweapon(lua_State *L, attack_ptr weapon)
bool clear_shroud(int side, bool reset_fog, bool fire_events)
Function that will clear shroud (and fog) based on current unit positions.
game_events::pump_result_t get_village(const map_location &loc, int side, bool *action_timebonus, bool fire_event)
Makes it so the village at the given location is owned by the given side.
void create_jamming_map(std::map< map_location, int > &jamming, const team &view_team)
Helper function that creates the map of enemy anti-vision that's needed when creating a pathfinding::...
void clear()
Clear the current render target.
const color_t LABEL_COLOR
int add_floating_label(const floating_label &flabel)
add a label floating on the screen above everything else.
void remove_floating_label(int handle, int fadeout)
removes the floating label given by 'handle' from the screen
void move_floating_label(int handle, double xmove, double ymove)
moves the floating label given by 'handle' by (xmove,ymove)
Game configuration data as global variables.
void load_config(const config &v)
bool variable_matches(const vconfig &values)
bool have_location(const vconfig &cfg)
bool have_unit(const vconfig &cfg)
bool conditional_passed(const vconfig &cond)
bool fire_event(const ui_event event, const std::vector< std::pair< widget *, ui_event >> &event_chain, widget *dispatcher, widget *w, F &&... params)
Helper function for fire_event.
std::shared_ptr< halo_record > handle
std::stringstream & log_to_chat()
Use this to show WML errors in the ingame chat.
std::string register_table(lua_State *L)
std::string register_vconfig_metatable(lua_State *L)
Adds the vconfig metatable.
int intf_tovconfig(lua_State *L)
Creates a vconfig containing the WML table.
void set_functions(lua_State *L, const std::vector< lua_cpp::Reg > &functions)
Analogous to lua_setfuncs, it registers a collection of function wrapper objects into a table,...
void push_closure(lua_State *L, const lua_function &f, int nup)
Pushes a closure which retains a std::function object as its first up-value.
int show_gamestate_inspector(const std::string &name, const game_data &data, const game_state &state)
std::string register_metatable(lua_State *L)
std::string register_metatable(lua_State *L)
std::string register_metatables(lua_State *L)
std::string register_metatable(lua_State *L)
std::string register_table(lua_State *L)
std::string register_metatables(lua_State *L)
std::string register_attacks_metatables(lua_State *L)
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
game_classification * classification
play_controller * controller
std::shared_ptr< wb::manager > whiteboard
Contains the general settings which have a default.
void play_sound(const std::string &files, channel_group group, unsigned int repeats)
terrain_code read_terrain_code(std::string_view str, const ter_layer filler)
Reads a single terrain from a string.
const terrain_code NONE_TERRAIN
void move_unit(const std::vector< map_location > &path, unit_ptr u, bool animate, map_location::DIRECTION dir, bool force_scroll)
Display a unit moving along a given path.
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
@ STRIP_SPACES
REMOVE_EMPTY: remove empty elements.
std::string join_map(const T &v, const std::string &major=",", const std::string &minor=":")
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::vector< std::string > split(const config_attribute_value &val)
bool headless()
The game is running headless.
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
This module contains various pathfinding functions and utilities.
std::shared_ptr< const unit > unit_const_ptr
std::shared_ptr< const attack_type > const_attack_ptr
std::shared_ptr< unit > unit_ptr
Define the game's event mechanism.
std::decay_t< T > lua_check(lua_State *L, int n)
void lua_push(lua_State *L, const T &val)
std::decay_t< T > luaW_table_get_def(lua_State *L, int index, std::string_view k, const T &def)
returns t[k] where k is the table at index index and k is k or def if it is not convertible to the co...
void luaW_table_set(lua_State *L, int index, std::string_view k, const T &value)
candidate action framework
#define ON_SCOPE_EXIT(...)
Run some arbitrary code (a lambda) when the current scope exits The lambda body follows this header,...
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.
The basic class for representing 8-bit RGB or RGBA colour values.
static color_t from_rgb_string(const std::string &c)
Creates a new opaque color_t object from a string variable in "R,G,B" format.
static color_t from_hex_string(const std::string &c)
Creates a new color_t object from a string variable in hex 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)
Additional information on the game outcome which can be provided by WML.
Error used for any general game error, e.g.
const map_location & filter_loc() const
Represents a single filter condition on an event.
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.
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.
static std::string get_string(enum_type key)
Converts a enum to its string equivalent.
static constexpr utils::optional< enum_type > get_enum(const std::string_view value)
Converts a string into its enum equivalent.
Represents a distinct sub-achievement within another achievement.
std::string id_
The ID of the sub-achievement.
bool achieved_
Whether the sub-achievement has been completed.
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Object which defines a time of day with associated bonuses, image, sounds etc.
tod_color color
The color modifications that should be made to the game board to reflect the time of day.
int lawful_bonus
The % bonus lawful units receive.
std::string image
The image to be displayed in the game status.
std::string sounds
List of "ambient" sounds associated with this time_of_day, Played at the beginning of turn.
std::string image_mask
The image that is to be laid over all images while this time of day lasts.
pointer get_shared_ptr() const
This is exactly the same as operator-> but it's slightly more readable, and can replace &*iter syntax...
static map_location::DIRECTION n
static map_location::DIRECTION s
unit_type_data unit_types
Display units performing various actions: moving, attacking, and dying.
Various functions implementing vision (through fog of war and shroud).