Skip to content

Commit

Permalink
move [teleport] actionwml to lua.
Browse files Browse the repository at this point in the history
  • Loading branch information
gfgtdf committed Mar 14, 2016
1 parent ff5a37a commit 986550c
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 63 deletions.
11 changes: 11 additions & 0 deletions data/lua/wml-tags.lua
Expand Up @@ -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
63 changes: 0 additions & 63 deletions src/game_events/action_wml.cpp
Expand Up @@ -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)
{
Expand Down
60 changes: 60 additions & 0 deletions src/scripting/game_lua_kernel.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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() {
Expand Down
1 change: 1 addition & 0 deletions src/scripting/game_lua_kernel.hpp
Expand Up @@ -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();
Expand Down
14 changes: 14 additions & 0 deletions src/scripting/lua_api.cpp
Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions src/scripting/lua_api.hpp
Expand Up @@ -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;

/**
Expand Down

0 comments on commit 986550c

Please sign in to comment.