move [teleport] actionwml to lua.

This commit is contained in:
gfgtdf 2016-03-14 14:42:05 +01:00
parent ff5a37a064
commit 986550c040
6 changed files with 93 additions and 63 deletions

View file

@ -1752,3 +1752,14 @@ wml_actions.unstore_unit = function(cfg)
unit:to_recall()
end
end
wml_actions.teleport = function(cfg)
local context = wesnoth.current.event_context
local filter = helper.get_child(cfg, "filter") or { x = context.x1, y = context.y1 }
local unit = wesnoth.get_units(filter)[0]
if not unit then
-- No error if no unit matches.
return
end
wesnoth.teleport(unit, cfg.check_passability == false, cfg.clear_shroud ~= false, cfg.animate)
end

View file

@ -1140,69 +1140,6 @@ WML_HANDLER_FUNCTION(store_time_of_day, /*event_info*/, cfg)
}
}
WML_HANDLER_FUNCTION(teleport, event_info, cfg)
{
unit_map::iterator u = resources::units->find(event_info.loc1);
// Search for a valid unit filter, and if we have one, look for the matching unit
const vconfig & filter = cfg.child("filter");
if(!filter.null()) {
const unit_filter ufilt(filter, resources::filter_con);
for (u = resources::units->begin(); u != resources::units->end(); ++u){
if ( ufilt(*u) )
break;
}
}
if (u == resources::units->end()) return;
// We have found a unit that matches the filter
const map_location dst = cfg_to_loc(cfg);
if (dst == u->get_location() || !resources::gameboard->map().on_board(dst)) return;
const unit* pass_check = NULL;
if (cfg["check_passability"].to_bool(true))
pass_check = &*u;
const map_location vacant_dst = find_vacant_tile(dst, pathfind::VACANT_ANY, pass_check);
if (!resources::gameboard->map().on_board(vacant_dst)) return;
// Clear the destination hex before the move (so the animation can be seen).
bool clear_shroud = cfg["clear_shroud"].to_bool(true);
actions::shroud_clearer clearer;
if ( clear_shroud ) {
clearer.clear_dest(vacant_dst, *u);
}
map_location src_loc = u->get_location();
std::vector<map_location> teleport_path;
teleport_path.push_back(src_loc);
teleport_path.push_back(vacant_dst);
bool animate = cfg["animate"].to_bool();
unit_display::move_unit(teleport_path, u.get_shared_ptr(), animate);
resources::units->move(src_loc, vacant_dst);
unit::clear_status_caches();
u = resources::units->find(vacant_dst);
u->anim_comp().set_standing();
if ( clear_shroud ) {
// Now that the unit is visibly in position, clear the shroud.
clearer.clear_unit(vacant_dst, *u);
}
if (resources::gameboard->map().is_village(vacant_dst)) {
actions::get_village(vacant_dst, u->side());
}
resources::screen->invalidate_unit_after_move(src_loc, vacant_dst);
resources::screen->draw();
// Sighted events.
clearer.fire_events();
}
/// Creating a mask of the terrain
WML_HANDLER_FUNCTION(terrain_mask, /*event_info*/, cfg)
{

View file

@ -28,6 +28,7 @@
#include "global.hpp"
#include "actions/attack.hpp" // for battle_context_unit_stats, etc
#include "actions/move.hpp" // for clear_shroud
#include "actions/vision.hpp" // for clear_shroud
#include "ai/composite/ai.hpp" // for ai_composite
#include "ai/composite/component.hpp" // for component, etc
@ -4130,6 +4131,65 @@ int game_lua_kernel::intf_get_all_vars(lua_State *L) {
return 1;
}
/**
* Teeleports a unit to a location.
* Arg 1: unit
* Arg 2,3: taget location
* Arg 4: bool (ignore_passability)
* Arg 5: bool (clear_shroud)
* Arg 6: bool (animate)
*/
int game_lua_kernel::intf_teleport(lua_State *L)
{
unit_ptr u = luaW_checkunit_ptr(L, 1, true);
map_location dst(luaL_checkinteger(L, 2) - 1, luaL_checkinteger(L, 3) - 1);
bool check_passability = !lua_toboolean(L, 4);
bool clear_shroud = luaW_toboolean(L, 5);
bool animate = luaW_toboolean(L, 6);
if (dst == u->get_location() || !resources::gameboard->map().on_board(dst)) {
return 0;
}
const map_location vacant_dst = find_vacant_tile(dst, pathfind::VACANT_ANY, check_passability ? u.get() : NULL);
if (!resources::gameboard->map().on_board(vacant_dst)) {
return 0;
}
// Clear the destination hex before the move (so the animation can be seen).
actions::shroud_clearer clearer;
if ( clear_shroud ) {
clearer.clear_dest(vacant_dst, *u);
}
map_location src_loc = u->get_location();
std::vector<map_location> teleport_path;
teleport_path.push_back(src_loc);
teleport_path.push_back(vacant_dst);
unit_display::move_unit(teleport_path, u, animate);
resources::units->move(src_loc, vacant_dst);
unit::clear_status_caches();
u = &*resources::units->find(vacant_dst);
u->anim_comp().set_standing();
if ( clear_shroud ) {
// Now that the unit is visibly in position, clear the shroud.
clearer.clear_unit(vacant_dst, *u);
}
if (resources::gameboard->map().is_village(vacant_dst)) {
actions::get_village(vacant_dst, u->side());
}
resources::screen->invalidate_unit_after_move(src_loc, vacant_dst);
resources::screen->draw();
// Sighted events.
clearer.fire_events();
return 0;
}
// END CALLBACK IMPLEMENTATION
game_board & game_lua_kernel::board() {

View file

@ -159,6 +159,7 @@ class game_lua_kernel : public lua_kernel_base
int cfun_wml_action(lua_State *L);
int intf_fire_event(lua_State *L);
int intf_fire_wml_menu_item(lua_State *L);
int intf_teleport(lua_State *L);
//private helpers
std::string synced_state();

View file

@ -189,6 +189,20 @@ unit* luaW_tounit(lua_State *L, int index, bool only_on_map)
return lu->get();
}
unit_ptr luaW_tounit_ptr(lua_State *L, int index, bool only_on_map)
{
if (!luaW_hasmetatable(L, index, getunitKey)) return unit_ptr();
lua_unit *lu = static_cast<lua_unit *>(lua_touserdata(L, index));
if (only_on_map && !lu->on_map()) return unit_ptr();
return lu->get_shared();
}
unit_ptr luaW_checkunit_ptr(lua_State *L, int index, bool only_on_map)
{
unit_ptr u = luaW_tounit(L, index, only_on_map);
if (!u) luaL_typerror(L, index, "unit");
return u;
}
unit& luaW_checkunit(lua_State *L, int index, bool only_on_map)
{
unit* u = luaW_tounit(L, index, only_on_map);

View file

@ -45,6 +45,13 @@ bool luaW_pcall(lua_State *L, int nArgs, int nRets, bool allow_wml_error = false
unit& luaW_checkunit(lua_State *L, int index, bool only_on_map = false);
class lua_unit;
lua_unit* luaW_pushlocalunit(lua_State *L, unit& u);
/**
* Similar to luaW_checkunit/luaW_tounit but returns a unit_ptr, use this instead of
* luaW_checkunit/luaW_tounit when uasing an api that needs unit_ptr.
*/
unit_ptr luaW_tounit_ptr(lua_State *L, int index, bool only_on_map);
unit_ptr luaW_checkunit_ptr(lua_State *L, int index, bool only_on_map);
struct map_location;
/**