diff -Nur -X./diff_ignore ./LT2_5/client/luascript/api_client_base.c ./LT2_5-my/client/luascript/api_client_base.c --- ./LT2_5/client/luascript/api_client_base.c 2019-01-19 17:40:00.495912862 +0300 +++ ./LT2_5-my/client/luascript/api_client_base.c 2019-08-02 00:32:41.682910444 +0300 @@ -16,9 +16,14 @@ #endif /* common */ +#include "fc_types.h" + #include "connection.h" #include "featured_text.h" #include "unit.h" +#include "road.h" +#include "base.h" +#include "packets.h" /*struct packet_unit_orders*/ /* common/scriptcore */ #include "luascript.h" @@ -26,10 +31,38 @@ /* client */ #include "chatline_common.h" #include "client_main.h" +#include "control.h" #include "goto.h" #include "api_client_base.h" @@ -109,3 +142,479 @@ output_window_printf(ftc_chat_luaconsole, "%s", msg); } + +/**********************************************************************//*** + Add unit to the selection +***************************************************************************/ +void api_client_unit_focus_add(lua_State *L, Unit *punit) +{ + LUASCRIPT_CHECK_STATE(L); + LUASCRIPT_CHECK_ARG_NIL(L, punit, 2, Unit); + + unit_focus_add(punit); +} + + +/**********************************************************************//*** + Remove unit from the selection +***************************************************************************/ +void api_client_unit_focus_remove(lua_State *L, Unit *punit) +{ + LUASCRIPT_CHECK_STATE(L); + LUASCRIPT_CHECK_ARG_NIL(L, punit, 2, Unit); + + unit_focus_remove(punit); +} + +/**********************************************************************//*** + Is a unit in focus +***************************************************************************/ +bool api_client_unit_is_in_focus(lua_State *L, Unit *punit) +{ + LUASCRIPT_CHECK_STATE(L, FALSE); + LUASCRIPT_CHECK_SELF(L, punit, NULL); + + return unit_is_in_focus(punit); +} + +/**********************************************************************//*** + Number of units in focus +***************************************************************************/ +int api_client_num_units_in_focus(lua_State *L) +{ + LUASCRIPT_CHECK_STATE(L, -1); + return get_num_units_in_focus(); +} + +/**********************************************************************//*** + units in focus (for use in iterators) +***************************************************************************/ +Unit_List_Link *api_client_private_focus_head(lua_State *L) +{ + LUASCRIPT_CHECK_STATE(L, NULL); + return unit_list_head(get_units_in_focus()); +} diff -Nur -X./diff_ignore ./LT2_5/client/luascript/api_client_base.h ./LT2_5-my/client/luascript/api_client_base.h --- ./LT2_5/client/luascript/api_client_base.h 2019-01-19 17:40:00.495912862 +0300 +++ ./LT2_5-my/client/luascript/api_client_base.h 2019-08-02 00:14:56.541573891 +0300 @@ -31,6 +31,25 @@ void api_client_unit_upgrade(lua_State *L, Unit *punit); void api_client_diplomat_action(lua_State *L, Unit *pdiplo, int target_id, int value, int action); +void api_client_unit_focus_add(lua_State *L, Unit *punit); +void api_client_unit_focus_remove(lua_State *L, Unit *punit); +bool api_client_unit_is_in_focus(lua_State *L, Unit *punit); +int api_client_num_units_in_focus(lua_State *L); +Unit_List_Link *api_client_private_focus_head(lua_State *L); #ifdef __cplusplus diff -Nur -X./diff_ignore ./LT2_5/client/luascript/tolua_client.pkg ./LT2_5-my/client/luascript/tolua_client.pkg --- ./LT2_5/client/luascript/tolua_client.pkg 2019-01-19 17:40:00.495912862 +0300 +++ ./LT2_5-my/client/luascript/tolua_client.pkg 2019-08-05 22:20:33.179324721 +0300 @@ -60,4 +60,106 @@ @ unit_upgrade (lua_State *L, Unit *punit); void api_client_diplomat_action @ diplomat_action (lua_State *L, Unit *pdiplo, int target_id, int value, int action); +/* Focus module */ +module focus { + void api_client_unit_focus_add @ add(lua_State *L, Unit *punit); + void api_client_unit_focus_remove @ remove (lua_State *L, Unit *punit); + bool api_client_unit_is_in_focus @ contains (lua_State *L, Unit *punit); + int api_client_num_units_in_focus @ number(lua_State *L); +} + +/* hidden for inner use */ +module private_methods{ + Unit_List_Link *api_client_private_focus_head @ focus_head(lua_State *L); +} + +$[ +do + local focus_head = private_methods.focus_head + + function focus.list() -- Note: units can be destroyed afterwards + local list, link = {}, focus_head() + while link do + list[#list + 1] = link:data() + link = link:next() + end + + return list + end + + -- The iterator can be called between pakets processings that will + -- remove the units, so make it safe (paranoid?) + function focus.iterate() + local idlist, i, n, link = {}, 1, focus.number(), focus_head(); + for j = 1, n do + idlist[j] = link:data().id + link = link:next() + end + return function() + local u + while i <= n do + u = find.unit(nil, idlist[i]) + i = i + 1 + if u then break end + end + return u + end + end +end +$] + +module Unit { + void api_client_unit_focus_add + @ select (lua_State *L, Unit *punit); + void api_client_unit_focus_remove + @ unselect (lua_State *L, Unit *punit); + bool api_client_unit_is_in_focus + @ selected (lua_State *L, Unit *punit); } diff -Nur -X./diff_ignore ./LT2_5/common/scriptcore/api_game_find.c ./LT2_5-my/common/scriptcore/api_game_find.c --- ./LT2_5/common/scriptcore/api_game_find.c 2019-01-19 17:40:00.511917844 +0300 +++ ./LT2_5-my/common/scriptcore/api_game_find.c 2019-08-05 22:22:24.301676664 +0300 @@ -35,6 +35,38 @@ } /***************************************************************************** + Return a player with the given name +*****************************************************************************/ +Player *api_find_player_by_name(lua_State *L, const char* plrname) +{ + LUASCRIPT_CHECK_STATE(L, NULL); + LUASCRIPT_CHECK_ARG_NIL(L, plrname, 2, string, NULL); + + return player_by_name(plrname); +} + +/***************************************************************************** + Return any city with the given name (case-insensitive). +*****************************************************************************/ +City *api_find_city_by_name(lua_State *L, Player *pplayer, const char *name) +{ + LUASCRIPT_CHECK_STATE(L, NULL); + LUASCRIPT_CHECK_ARG_NIL(L, name, 3, string, NULL); + + if (pplayer) { + return city_list_find_name(pplayer->cities, name); + } else { + cities_iterate (pcity) { + if (!fc_strcasecmp(name, city_name(pcity))) { + return pcity; + } + } cities_iterate_end; + } + return NULL; +} + + +/***************************************************************************** Return a player city with the given city_id. *****************************************************************************/ City *api_find_city(lua_State *L, Player *pplayer, int city_id) diff -Nur -X./diff_ignore ./LT2_5/common/scriptcore/api_game_find.h ./LT2_5-my/common/scriptcore/api_game_find.h --- ./LT2_5/common/scriptcore/api_game_find.h 2019-01-19 17:40:00.511917844 +0300 +++ ./LT2_5-my/common/scriptcore/api_game_find.h 2019-08-05 22:40:41.287188996 +0300 @@ -25,8 +25,10 @@ #include "luascript_types.h" /* Object find module. */ +Player *api_find_player_by_name(lua_State *L, const char* plrname); Player *api_find_player(lua_State *L, int player_id); +City *api_find_city_by_name(lua_State *L, Player *pplayer, const char *name); City *api_find_city(lua_State *L, Player *pplayer, int city_id); Unit *api_find_unit(lua_State *L, Player *pplayer, int unit_id); diff -Nur -X./diff_ignore ./LT2_5/common/scriptcore/api_game_methods.c ./LT2_5-my/common/scriptcore/api_game_methods.c --- ./LT2_5/common/scriptcore/api_game_methods.c 2019-01-19 17:40:00.511917844 +0300 +++ ./LT2_5-my/common/scriptcore/api_game_methods.c 2019-08-05 22:28:24.804382854 +0300 @@ -121,6 +121,29 @@ /***************************************************************************** + Return link to the list of city supported units +*****************************************************************************/ +Unit_List_Link +*api_methods_private_city_supported_units_link(lua_State *L, City *pcity) +{ + LUASCRIPT_CHECK_STATE(L, NULL); + LUASCRIPT_CHECK_SELF(L, pcity, NULL); + + return unit_list_head(pcity->units_supported); +} + +/***************************************************************************** + Return number of city supported units +*****************************************************************************/ +int api_methods_city_supported_units_number(lua_State *L, City *pcity) +{ + LUASCRIPT_CHECK_STATE(L, 0); + LUASCRIPT_CHECK_SELF(L, pcity, 0); + + return unit_list_size(pcity->units_supported); +} + +/***************************************************************************** Return TRUE iff city has building *****************************************************************************/ bool api_methods_city_has_building(lua_State *L, City *pcity, @@ -500,6 +523,19 @@ } /***************************************************************************** + Return the native x and y coordinates of the tile. +*****************************************************************************/ +void api_methods_tile_nat_coords(lua_State *L, Tile *ptile, + int *x, int *y) +{ + LUASCRIPT_CHECK_STATE(L); + LUASCRIPT_CHECK_SELF(L, ptile); + + *x = index_to_native_pos_x(tile_index(ptile)); + *y = index_to_native_pos_y(tile_index(ptile)); +} + +/***************************************************************************** Return the map x coordinate of the tile. *****************************************************************************/ int api_methods_tile_map_x(lua_State *L, Tile *ptile) @@ -522,6 +558,19 @@ } /***************************************************************************** + Return the map x and y coordinates of the tile. +*****************************************************************************/ +void api_methods_tile_map_coords(lua_State *L, Tile *ptile, + int *x, int *y) +{ + LUASCRIPT_CHECK_STATE(L); + LUASCRIPT_CHECK_SELF(L, ptile); + + *x = index_to_map_pos_x(tile_index(ptile)); + *y = index_to_map_pos_y(tile_index(ptile)); +} + +/***************************************************************************** Return Player owning ptile, else NULL *****************************************************************************/ Player *api_methods_tile_owner(lua_State *L, Tile *ptile) @@ -738,6 +787,70 @@ } /***************************************************************************** + Get direction name +*****************************************************************************/ +const char *api_methods_dir2str(lua_State *L, Direction dir) +{ + LUASCRIPT_CHECK_STATE(L, NULL); + LUASCRIPT_CHECK(L, is_valid_dir(dir), "Direction is invalid", NULL); + + return direction8_name(dir); +} + +/***************************************************************************** + Get unit health +*****************************************************************************/ +int api_methods_unit_hp_get(lua_State *L, Unit *punit) +{ + LUASCRIPT_CHECK_STATE(L, -1); + LUASCRIPT_CHECK_ARG_NIL(L, punit, 2, Unit, -1); + + return punit->hp; +} + +/***************************************************************************** + Get unit moves +*****************************************************************************/ +int api_methods_unit_moves_left_get(lua_State *L, Unit *punit) +{ + LUASCRIPT_CHECK_STATE(L, -1); + LUASCRIPT_CHECK_ARG_NIL(L, punit, 2, Unit, -1); + + return punit->moves_left; +} + +/***************************************************************************** + Get unit veteranship rank +*****************************************************************************/ +int api_methods_unit_vet_get(lua_State *L, Unit *punit) +{ + LUASCRIPT_CHECK_STATE(L, -1); + LUASCRIPT_CHECK_ARG_NIL(L, punit, 2, Unit, -1); + + return punit->veteran; +} +/***************************************************************************** Return TRUE if punit_type has flag. *****************************************************************************/ bool api_methods_unit_type_has_flag(lua_State *L, Unit_Type *punit_type, diff -Nur -X./diff_ignore ./LT2_5/common/scriptcore/api_game_methods.h ./LT2_5-my/common/scriptcore/api_game_methods.h --- ./LT2_5/common/scriptcore/api_game_methods.h 2019-01-19 17:40:00.511917844 +0300 +++ ./LT2_5-my/common/scriptcore/api_game_methods.h 2019-08-05 22:29:28.244606780 +0300 @@ -48,6 +48,9 @@ int api_methods_city_size_get(lua_State *L, City *pcity); Tile *api_methods_city_tile_get(lua_State *L, City *pcity); int api_methods_city_inspire_partisans(lua_State *L, City *self, Player *inspirer); +Unit_List_Link +*api_methods_private_city_supported_units_link(lua_State *L, City *pcity); +int api_methods_city_supported_units_number(lua_State *L, City *pcity); /* Government */ const char *api_methods_government_rule_name(lua_State *L, @@ -102,6 +105,10 @@ int api_methods_tile_nat_y(lua_State *L, Tile *ptile); int api_methods_tile_map_x(lua_State *L, Tile *ptile); int api_methods_tile_map_y(lua_State *L, Tile *ptile); +void api_methods_tile_nat_coords(lua_State *L, Tile *ptile, + int *x, int *y); +void api_methods_tile_map_coords(lua_State *L, Tile *ptile, + int *x, int *y); Resource *api_methods_tile_resource(lua_State *L, Tile *ptile); Player *api_methods_tile_owner(lua_State *L, Tile *ptile); City *api_methods_tile_city(lua_State *L, Tile *ptile); @@ -122,10 +129,18 @@ /* Resource */ const char *api_methods_resource_rule_name(lua_State *L, Resource *presource); +/* Direction */ +const char *api_methods_dir2str(lua_State *L, Direction dir); + /* Unit */ bool api_methods_unit_city_can_be_built_here(lua_State *L, Unit *punit); Tile *api_methods_unit_tile_get(lua_State *L, Unit * punit); Direction api_methods_unit_orientation_get(lua_State *L, Unit *punit); +int api_methods_unit_hp_get(lua_State *L, Unit *punit); +int api_methods_unit_moves_left_get(lua_State *L, Unit *punit); +int api_methods_unit_vet_get(lua_State *L, Unit *punit); /* Unit Type */ bool api_methods_unit_type_has_flag(lua_State *L, Unit_Type *punit_type, @@ -139,6 +154,7 @@ Unit_Type *punit_type); const char *api_methods_unit_type_name_translation(lua_State *L, Unit_Type *punit_type); + /* Unit_List_Link Type */ Unit *api_methods_unit_list_link_data(lua_State *L, Unit_List_Link *link); diff -Nur -X./diff_ignore ./LT2_5/common/scriptcore/tolua_game.pkg ./LT2_5-my/common/scriptcore/tolua_game.pkg --- ./LT2_5/common/scriptcore/tolua_game.pkg 2019-01-19 17:40:00.511917844 +0300 +++ ./LT2_5-my/common/scriptcore/tolua_game.pkg 2019-08-05 22:55:20.692645038 +0300 @@ -167,6 +167,8 @@ @ size(lua_State *L, City *self); Tile *api_methods_city_tile_get @ tile(lua_State *L, City *self); + int api_methods_city_supported_units_number + @ supported_count(lua_State *L, City *pcity); } bool api_methods_city_has_building @@ -177,6 +179,13 @@ @ inspire_partisans(lua_State *L, City *self, Player *inspirer); } +module methods_private { + module City { + Unit_List_Link *api_methods_private_city_supported_units_link + @ supported_head(lua_State *L, City *pcity); + } +} + $[ -- City methods. @@ -191,12 +200,20 @@ module properties { Tile *api_methods_unit_tile_get @ tile(lua_State *L, Unit *self); + int api_methods_unit_hp_get + @ hp(lua_State *L, Unit *punit); + int api_methods_unit_moves_left_get + @ moves_left(lua_State *L, Unit *punit); + int api_methods_unit_vet_get + @ veteran(lua_State *L, Unit *punit); } bool api_methods_unit_city_can_be_built_here @ is_on_possible_city_tile (lua_State *L, Unit *self); Direction api_methods_unit_orientation_get @ facing(lua_State *L, Unit *self); } $[ @@ -225,6 +242,12 @@ @ y (lua_State *L, Tile *self); } + void api_methods_tile_nat_coords + @ nat_coords (lua_State *L, Tile *ptile, + int *x = 0, int *y = 0); + void api_methods_tile_map_coords + @ coords (lua_State *L, Tile *ptile, + int *x = 0, int *y = 0); Resource *api_methods_tile_resource @ resource (lua_State *L, Tile *self); City *api_methods_tile_city @@ -380,9 +403,15 @@ } /* Module find. */ +/* NOTE: For overloading to work correctly, the string function + * must be before the integer function for each case below. */ module find { + Player *api_find_player_by_name + @ player (lua_State *L, const char* plrname); Player *api_find_player @ player (lua_State *L, int player_id); + City *api_find_city_by_name + @ city (lua_State *L, Player *pplayer, const char *name); City *api_find_city @ city (lua_State *L, Player *pplayer, int city_id); Unit *api_find_unit @@ -394,9 +423,6 @@ @ tile (lua_State *L, int nat_x, int nat_y); Tile *api_find_tile_by_index @ tile (lua_State *L, int index); - - /* NOTE: For overloading to work correctly, the string function - * must be before the integer function for each case below. */ Government *api_find_government_by_name @ government (lua_State *L, const char *name_orig); Government *api_find_government @@ -423,6 +449,10 @@ @ terrain (lua_State *L, const char *name_orig); Terrain *api_find_terrain @ terrain (lua_State *L, int terrain_id); Nonexistent *api_find_nonexistent @ nonexistent (lua_State *L); } @@ -445,6 +475,8 @@ module direction { Direction api_utilities_str2dir @ str2dir (lua_State *L, const char *str); + const char *api_methods_dir2str + @ name (lua_State *L, Direction dir); } $[ @@ -454,6 +534,11 @@ function Tile:units_iterate() return safe_iterate_list(private.Tile.unit_list_head(self)) end + + -- Safe iteration over supported units + function City:supported_iterate() + return safe_iterate_list(private.City.supported_head(self)) + end end -- ***************************************************************************