Move Lua unit attacks metatable to own file

This commit is contained in:
Celtic Minstrel 2016-08-11 23:25:32 -04:00
parent fa0e63e3a3
commit 22a39d0bb4
6 changed files with 275 additions and 203 deletions

View file

@ -166,6 +166,8 @@
9193FC7F1D5BB64F004F6C07 /* advancement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9193FC7C1D5BB64E004F6C07 /* advancement.cpp */; };
9193FC821D5C2CF8004F6C07 /* lua_unit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9193FC801D5C2CF7004F6C07 /* lua_unit.cpp */; };
9193FC831D5C2D00004F6C07 /* lua_unit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9193FC801D5C2CF7004F6C07 /* lua_unit.cpp */; };
9193FC861D5D7461004F6C07 /* lua_unit_attacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9193FC841D5D7452004F6C07 /* lua_unit_attacks.cpp */; };
9193FC871D5D7461004F6C07 /* lua_unit_attacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9193FC841D5D7452004F6C07 /* lua_unit_attacks.cpp */; };
919B37F81BAF789E00E0094C /* synced_user_choice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 919B37F71BAF789D00E0094C /* synced_user_choice.cpp */; };
919B37FC1BAF7A9D00E0094C /* synced_choice_wait.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 919B37FA1BAF7A9D00E0094C /* synced_choice_wait.cpp */; };
91A214E51CAD666B00927AEA /* arrow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B52EE8A1121359A600CFBDAB /* arrow.cpp */; };
@ -1596,6 +1598,8 @@
9193FC7D1D5BB64E004F6C07 /* advancement.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = advancement.hpp; sourceTree = "<group>"; };
9193FC801D5C2CF7004F6C07 /* lua_unit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_unit.cpp; sourceTree = "<group>"; };
9193FC811D5C2CF8004F6C07 /* lua_unit.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = lua_unit.hpp; sourceTree = "<group>"; };
9193FC841D5D7452004F6C07 /* lua_unit_attacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lua_unit_attacks.cpp; sourceTree = "<group>"; };
9193FC851D5D745D004F6C07 /* lua_unit_attacks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = lua_unit_attacks.hpp; sourceTree = "<group>"; };
919B37F71BAF789D00E0094C /* synced_user_choice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = synced_user_choice.cpp; sourceTree = "<group>"; };
919B37F91BAF78AB00E0094C /* synced_user_choice.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = synced_user_choice.hpp; sourceTree = "<group>"; };
919B37FA1BAF7A9D00E0094C /* synced_choice_wait.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = synced_choice_wait.cpp; sourceTree = "<group>"; };
@ -4150,6 +4154,8 @@
F4C02A0F182F1F64008525C6 /* lua_types.hpp */,
9193FC801D5C2CF7004F6C07 /* lua_unit.cpp */,
9193FC811D5C2CF8004F6C07 /* lua_unit.hpp */,
9193FC841D5D7452004F6C07 /* lua_unit_attacks.cpp */,
9193FC851D5D745D004F6C07 /* lua_unit_attacks.hpp */,
EC5430221A4E6024006D206C /* lua_unit_type.cpp */,
91B621EE1B76BB2C00B00E0F /* lua_unit_type.hpp */,
EC59F2601A4529D2001910CB /* manager.cpp */,
@ -5237,6 +5243,7 @@
9193FC7E1D5BB64F004F6C07 /* advancement.cpp in Sources */,
917746C11D680C7C00E8689A /* walker_tree_node.cpp in Sources */,
9193FC821D5C2CF8004F6C07 /* lua_unit.cpp in Sources */,
9193FC861D5D7461004F6C07 /* lua_unit_attacks.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -5809,6 +5816,7 @@
9193FC7F1D5BB64F004F6C07 /* advancement.cpp in Sources */,
917746C21D680C7C00E8689A /* walker_tree_node.cpp in Sources */,
9193FC831D5C2D00004F6C07 /* lua_unit.cpp in Sources */,
9193FC871D5D7461004F6C07 /* lua_unit_attacks.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View file

@ -73,6 +73,7 @@
#include "replay.hpp" // for get_user_choice, etc
#include "reports.hpp" // for register_generator, etc
#include "scripting/lua_unit.hpp"
#include "scripting/lua_unit_attacks.hpp"
#include "scripting/lua_common.hpp"
#include "scripting/lua_cpp_function.hpp"
#include "scripting/lua_gui2.hpp" // for show_gamestate_inspector
@ -4233,6 +4234,7 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle
//Create the unit metatables
cmd_log_ << lua_units::register_metatables(L);
cmd_log_ << lua_units::register_attacks_metatables(L);
// Create the vconfig metatable.
cmd_log_ << lua_common::register_vconfig_metatable(L);

View file

@ -20,6 +20,7 @@
#include "map/location.hpp" // for map_location
#include "resources.hpp"
#include "scripting/lua_common.hpp"
#include "scripting/lua_unit_attacks.hpp"
#include "scripting/push_check.hpp"
#include "scripting/game_lua_kernel.hpp"
#include "units/unit.hpp"
@ -342,13 +343,7 @@ static int impl_unit_get(lua_State *L)
return 1;
}
if(strcmp(m, "attacks") == 0) {
lua_createtable(L, 1, 0);
lua_pushvalue(L, 1);
// hack: store the unit at -1 becasue we want positive indexes to refers to the attacks.
lua_rawseti(L, -2, -1);
lua_pushlightuserdata(L, uattacksKey);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2);
push_unit_attacks_table(L, 1);
return 1;
}
return_bool_attrib("hidden", u.get_hidden());
@ -501,171 +496,6 @@ static int impl_unit_variables_get(lua_State *L)
variable_access_const v(m, u->variables());
return luaW_pushvariable(L, v) ? 1 : 0;
}
/**
* Gets the attacks of a unit or unit type (__index metamethod).
* - Arg 1: table containing the userdata containing the unit or unit type.
* - Arg 2: index (int) or id (string) identifying a particular attack.
* - Ret 1: the unit's attacks.
*/
static int impl_unit_attacks_get(lua_State *L)
{
if(!lua_istable(L, 1)) {
return luaL_typerror(L, 1, "unit attacks");
}
lua_rawgeti(L, 1, -1);
const unit* u = luaW_tounit(L, -1);
const unit_type* ut = static_cast<const unit_type*>(luaL_testudata(L, -1, "unit type"));
if(!u && !ut) {
return luaL_argerror(L, 1, "unknown unit");
}
const attack_type* attack = nullptr;
const std::vector<attack_type>& attacks = u ? u->attacks() : ut->attacks();
if(!lua_isnumber(L,2)) {
std::string attack_id = luaL_checkstring(L, 2);
for(const attack_type& at : attacks) {
if(at.id() == attack_id) {
attack = &at;
break;
}
}
if(attack == nullptr) {
//return nil on invalid index, just like lua tables do.
return 0;
}
} else {
size_t index = luaL_checkinteger(L, 2) - 1;
if(index >= attacks.size()) {
//return nil on invalid index, just like lua tables do.
return 0;
}
attack = &attacks[index];
}
// stack { lua_unit }, id/index, lua_unit
lua_createtable(L, 2, 0);
// stack { lua_unit }, id/index, lua_unit, table
lua_pushvalue(L, -2);
// stack { lua_unit }, id/index, lua_unit, table, lua_unit
lua_rawseti(L, -2, 1);
// stack { lua_unit }, id/index, lua_unit, table
lua_pushstring(L, attack->id().c_str());
// stack { lua_unit }, id/index, lua_unit, table, attack id
lua_rawseti(L, -2, 2);
// stack { lua_unit }, id/index, lua_unit, table
lua_pushlightuserdata(L, uattackKey);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2);
return 1;
}
/**
* Counts the attacks of a unit (__len metamethod).
* - Arg 1: table containing the userdata containing the unit id.
* - Ret 1: size of unit attacks vector.
*/
static int impl_unit_attacks_len(lua_State *L)
{
if(!lua_istable(L, 1)) {
return luaL_typerror(L, 1, "unit attacks");
}
lua_rawgeti(L, 1, -1);
const unit* u = luaW_tounit(L, -1);
if(!u) {
return luaL_argerror(L, 1, "unknown unit");
}
lua_pushinteger(L, u->attacks().size());
return 1;
}
/**
* Gets a propoerty of a units attack (__index metamethod).
* - Arg 1: table containing the userdata containing the unit id. and a string identyfying the attack.
* - Arg 2: string
* - Ret 1:
*/
static int impl_unit_attack_get(lua_State *L)
{
if(!lua_istable(L, 1)) {
return luaL_typerror(L, 1, "unit attack");
}
lua_rawgeti(L, 1, 1);
const unit* u = luaW_tounit(L, -1);
if(!u) {
return luaL_argerror(L, 1, "unknown unit");
}
lua_rawgeti(L, 1, 2);
std::string attack_id = luaL_checkstring(L, -1);
char const *m = luaL_checkstring(L, 2);
for(const attack_type& attack : u->attacks()) {
if(attack.id() == attack_id) {
return_string_attrib("description", attack.name());
return_string_attrib("name", attack.id());
return_string_attrib("type", attack.type());
return_string_attrib("icon", attack.icon());
return_string_attrib("range", attack.range());
return_int_attrib("damage", attack.damage());
return_int_attrib("number", attack.num_attacks());
return_int_attrib("attack_weight", attack.attack_weight());
return_int_attrib("defense_weight", attack.defense_weight());
return_int_attrib("accuracy", attack.accuracy());
return_int_attrib("movement_used", attack.movement_used());
return_int_attrib("parry", attack.parry());
return_cfgref_attrib("specials", attack.specials());
return_cfgref_attrib("__cfg", attack.to_config());
std::string err_msg = "unknown property of attack: ";
err_msg += m;
return luaL_argerror(L, 2, err_msg.c_str());
}
}
return luaL_argerror(L, 1, "invalid attack id");
}
/**
* Gets a propoerty of a units attack (__index metamethod).
* - Arg 1: table containing the userdata containing the unit id. and a string identyfying the attack.
* - Arg 2: string
* - Ret 1:
*/
static int impl_unit_attack_set(lua_State *L)
{
if(!lua_istable(L, 1)) {
return luaL_typerror(L, 1, "unit attack");
}
lua_rawgeti(L, 1, 1);
unit* u = luaW_tounit(L, -1);
if(!u) {
return luaL_argerror(L, 1, "unknown unit");
}
lua_rawgeti(L, 1, 2);
std::string attack_id = luaL_checkstring(L, -1);
char const *m = luaL_checkstring(L, 2);
for(attack_type& attack : u->attacks()) {
if(attack.id() == attack_id) {
modify_tstring_attrib("description", attack.set_name(value));
// modify_string_attrib("name", attack.set_id(value));
modify_string_attrib("type", attack.set_type(value));
modify_string_attrib("icon", attack.set_icon(value));
modify_string_attrib("range", attack.set_range(value));
modify_int_attrib("damage", attack.set_damage(value));
modify_int_attrib("number", attack.set_num_attacks(value));
modify_int_attrib("attack_weight", attack.set_attack_weight(value));
modify_int_attrib("defense_weight", attack.set_defense_weight(value));
modify_int_attrib("accuracy", attack.set_accuracy(value));
modify_int_attrib("movement_used", attack.set_movement_used(value));
modify_int_attrib("parry", attack.set_parry(value));
if(strcmp(m, "specials") == 0) { \
attack.set_specials(luaW_checkconfig(L, 3));
return 0;
}
return_cfgref_attrib("specials", attack.specials());
std::string err_msg = "unknown modifyable property of attack: ";
err_msg += m;
return luaL_argerror(L, 2, err_msg.c_str());
}
}
return luaL_argerror(L, 1, "invalid attack id");
}
/**
* Sets the variable of a unit (__newindex metamethod).
@ -728,30 +558,6 @@ namespace lua_units {
lua_setfield(L, -2, "__metatable");
lua_rawset(L, LUA_REGISTRYINDEX);
// Create the unit attacks metatable.
cmd_out << "Adding unit attacks metatable...\n";
lua_pushlightuserdata(L, uattacksKey);
lua_createtable(L, 0, 3);
lua_pushcfunction(L, impl_unit_attacks_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, impl_unit_attacks_len);
lua_setfield(L, -2, "__len");
lua_pushstring(L, "unit attacks");
lua_setfield(L, -2, "__metatable");
lua_rawset(L, LUA_REGISTRYINDEX);
// Create the unit attack metatable
lua_pushlightuserdata(L, uattackKey);
lua_createtable(L, 0, 3);
lua_pushcfunction(L, impl_unit_attack_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, impl_unit_attack_set);
lua_setfield(L, -2, "__newindex");
lua_pushstring(L, "unit attack");
lua_setfield(L, -2, "__metatable");
lua_rawset(L, LUA_REGISTRYINDEX);
// Create the unit variables metatable.
cmd_out << "Adding unit variables metatable...\n";

View file

@ -0,0 +1,233 @@
/*
Copyright (C) 2009 - 2016 by Guillaume Melquiond <guillaume.melquiond@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "lua_unit_attacks.hpp"
#include "lua_types.hpp"
#include "scripting/lua_common.hpp"
#include "scripting/lua_unit.hpp"
#include "units/unit.hpp"
#include "lua/lauxlib.h"
#include "lua/lua.h" // for lua_State, lua_settop, etc
void push_unit_attacks_table(lua_State* L, int idx)
{
lua_createtable(L, 1, 0);
lua_pushvalue(L, idx);
// hack: store the unit_type at -1 because we want positive indices to refer to the attacks.
lua_rawseti(L, -2, -1);
lua_pushlightuserdata(L, uattacksKey);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2);
}
/**
* Gets the attacks of a unit or unit type (__index metamethod).
* - Arg 1: table containing the userdata containing the unit or unit type.
* - Arg 2: index (int) or id (string) identifying a particular attack.
* - Ret 1: the unit's attacks.
*/
static int impl_unit_attacks_get(lua_State *L)
{
if(!lua_istable(L, 1)) {
return luaL_typerror(L, 1, "unit attacks");
}
lua_rawgeti(L, 1, -1);
const unit* u = luaW_tounit(L, -1);
const unit_type* ut = static_cast<const unit_type*>(luaL_testudata(L, -1, "unit type"));
if(!u && !ut) {
return luaL_argerror(L, 1, "unknown unit");
}
const attack_type* attack = nullptr;
const std::vector<attack_type>& attacks = u ? u->attacks() : ut->attacks();
if(!lua_isnumber(L,2)) {
std::string attack_id = luaL_checkstring(L, 2);
for(const attack_type& at : attacks) {
if(at.id() == attack_id) {
attack = &at;
break;
}
}
if(attack == nullptr) {
//return nil on invalid index, just like lua tables do.
return 0;
}
} else {
size_t index = luaL_checkinteger(L, 2) - 1;
if(index >= attacks.size()) {
//return nil on invalid index, just like lua tables do.
return 0;
}
attack = &attacks[index];
}
// stack { lua_unit }, id/index, lua_unit
lua_createtable(L, 2, 0);
// stack { lua_unit }, id/index, lua_unit, table
lua_pushvalue(L, -2);
// stack { lua_unit }, id/index, lua_unit, table, lua_unit
lua_rawseti(L, -2, 1);
// stack { lua_unit }, id/index, lua_unit, table
lua_pushstring(L, attack->id().c_str());
// stack { lua_unit }, id/index, lua_unit, table, attack id
lua_rawseti(L, -2, 2);
// stack { lua_unit }, id/index, lua_unit, table
lua_pushlightuserdata(L, uattackKey);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2);
return 1;
}
/**
* Counts the attacks of a unit (__len metamethod).
* - Arg 1: table containing the userdata containing the unit id.
* - Ret 1: size of unit attacks vector.
*/
static int impl_unit_attacks_len(lua_State *L)
{
if(!lua_istable(L, 1)) {
return luaL_typerror(L, 1, "unit attacks");
}
lua_rawgeti(L, 1, -1);
const unit* u = luaW_tounit(L, -1);
if(!u) {
return luaL_argerror(L, 1, "unknown unit");
}
lua_pushinteger(L, u->attacks().size());
return 1;
}
/**
* Gets a propoerty of a units attack (__index metamethod).
* - Arg 1: table containing the userdata containing the unit id. and a string identyfying the attack.
* - Arg 2: string
* - Ret 1:
*/
static int impl_unit_attack_get(lua_State *L)
{
if(!lua_istable(L, 1)) {
return luaL_typerror(L, 1, "unit attack");
}
lua_rawgeti(L, 1, 1);
const unit* u = luaW_tounit(L, -1);
if(!u) {
return luaL_argerror(L, 1, "unknown unit");
}
lua_rawgeti(L, 1, 2);
std::string attack_id = luaL_checkstring(L, -1);
char const *m = luaL_checkstring(L, 2);
for(const attack_type& attack : u->attacks()) {
if(attack.id() == attack_id) {
return_string_attrib("description", attack.name());
return_string_attrib("name", attack.id());
return_string_attrib("type", attack.type());
return_string_attrib("icon", attack.icon());
return_string_attrib("range", attack.range());
return_int_attrib("damage", attack.damage());
return_int_attrib("number", attack.num_attacks());
return_int_attrib("attack_weight", attack.attack_weight());
return_int_attrib("defense_weight", attack.defense_weight());
return_int_attrib("accuracy", attack.accuracy());
return_int_attrib("movement_used", attack.movement_used());
return_int_attrib("parry", attack.parry());
return_cfgref_attrib("specials", attack.specials());
return_cfgref_attrib("__cfg", attack.to_config());
std::string err_msg = "unknown property of attack: ";
err_msg += m;
return luaL_argerror(L, 2, err_msg.c_str());
}
}
return luaL_argerror(L, 1, "invalid attack id");
}
/**
* Gets a propoerty of a units attack (__index metamethod).
* - Arg 1: table containing the userdata containing the unit id. and a string identyfying the attack.
* - Arg 2: string
* - Ret 1:
*/
static int impl_unit_attack_set(lua_State *L)
{
if(!lua_istable(L, 1)) {
return luaL_typerror(L, 1, "unit attack");
}
lua_rawgeti(L, 1, 1);
unit* u = luaW_tounit(L, -1);
if(!u) {
return luaL_argerror(L, 1, "unknown unit");
}
lua_rawgeti(L, 1, 2);
std::string attack_id = luaL_checkstring(L, -1);
char const *m = luaL_checkstring(L, 2);
for(attack_type& attack : u->attacks()) {
if(attack.id() == attack_id) {
modify_tstring_attrib("description", attack.set_name(value));
// modify_string_attrib("name", attack.set_id(value));
modify_string_attrib("type", attack.set_type(value));
modify_string_attrib("icon", attack.set_icon(value));
modify_string_attrib("range", attack.set_range(value));
modify_int_attrib("damage", attack.set_damage(value));
modify_int_attrib("number", attack.set_num_attacks(value));
modify_int_attrib("attack_weight", attack.set_attack_weight(value));
modify_int_attrib("defense_weight", attack.set_defense_weight(value));
modify_int_attrib("accuracy", attack.set_accuracy(value));
modify_int_attrib("movement_used", attack.set_movement_used(value));
modify_int_attrib("parry", attack.set_parry(value));
if(strcmp(m, "specials") == 0) {
attack.set_specials(luaW_checkconfig(L, 3));
return 0;
}
return_cfgref_attrib("specials", attack.specials());
std::string err_msg = "unknown modifyable property of attack: ";
err_msg += m;
return luaL_argerror(L, 2, err_msg.c_str());
}
}
return luaL_argerror(L, 1, "invalid attack id");
}
namespace lua_units {
std::string register_attacks_metatables(lua_State* L)
{
std::ostringstream cmd_out;
// Create the unit attacks metatable.
cmd_out << "Adding unit attacks metatable...\n";
lua_pushlightuserdata(L, uattacksKey);
lua_createtable(L, 0, 3);
lua_pushcfunction(L, impl_unit_attacks_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, impl_unit_attacks_len);
lua_setfield(L, -2, "__len");
lua_pushstring(L, "unit attacks");
lua_setfield(L, -2, "__metatable");
lua_rawset(L, LUA_REGISTRYINDEX);
// Create the unit attack metatable
lua_pushlightuserdata(L, uattackKey);
lua_createtable(L, 0, 3);
lua_pushcfunction(L, impl_unit_attack_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, impl_unit_attack_set);
lua_setfield(L, -2, "__newindex");
lua_pushstring(L, "unit attack");
lua_setfield(L, -2, "__metatable");
lua_rawset(L, LUA_REGISTRYINDEX);
return cmd_out.str();
}
}

View file

@ -0,0 +1,28 @@
/*
Copyright (C) 2009 - 2016 by Guillaume Melquiond <guillaume.melquiond@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef SCRIPTING_LUA_UNIT_ATTACKS_HPP
#define SCRIPTING_LUA_UNIT_ATTACKS_HPP
#include <string>
struct lua_State;
void push_unit_attacks_table(lua_State* L, int idx);
namespace lua_units {
std::string register_attacks_metatables(lua_State* L);
}
#endif

View file

@ -15,6 +15,7 @@
#include "scripting/lua_unit_type.hpp"
#include "scripting/lua_common.hpp"
#include "scripting/lua_unit_attacks.hpp"
#include "scripting/push_check.hpp"
#include "units/types.hpp"
@ -73,13 +74,7 @@ static int impl_unit_type_get(lua_State *L)
return 1;
}
if (strcmp(m, "attacks") == 0) {
lua_createtable(L, 1, 0);
lua_pushvalue(L, 1);
// hack: store the unit_type at -1 because we want positive indices to refer to the attacks.
lua_rawseti(L, -2, -1);
lua_pushlightuserdata(L, uattacksKey);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_setmetatable(L, -2);
push_unit_attacks_table(L, 1);
return 1;
}
return 0;