AI/Lua: formatting cleanup

This commit is contained in:
Charles Dang 2018-05-01 01:38:18 +11:00
parent dbffb51394
commit 64bd866ef2
4 changed files with 522 additions and 461 deletions

View file

@ -14,30 +14,30 @@
#include "ai/lua/aspect_advancements.hpp"
#include "log.hpp" // for LOG_STREAM, logger, etc
#include "lua/lauxlib.h" // for luaL_ref, LUA_REFNIL
#include "lua/lua.h" // for lua_isstring, etc
#include "map/location.hpp" // for map_location
#include "serialization/string_utils.hpp" // for split
#include "log.hpp" // for LOG_STREAM, logger, etc
#include "lua/lauxlib.h" // for luaL_ref, LUA_REFNIL
#include "lua/lua.h" // for lua_isstring, etc
#include "map/location.hpp" // for map_location
#include "serialization/string_utils.hpp" // for split
#include "units/map.hpp" // for unit_map::const_iterator, etc
#include "units/unit.hpp"
#include "units/map.hpp" // for unit_map::const_iterator, etc
#include <ostream> // for operator<<, basic_ostream, etc
#include <string> // for string, char_traits, etc
#include <vector> // for vector
#include <ostream> // for operator<<, basic_ostream, etc
#include <string> // for string, char_traits, etc
#include <vector> // for vector
struct lua_State;
static lg::log_domain log_ai_engine_lua("ai/engine/lua");
#define LOG_LUA LOG_STREAM(info, log_ai_engine_lua)
#define ERR_LUA LOG_STREAM(err, log_ai_engine_lua)
namespace ai{
unit_advancements_aspect::unit_advancements_aspect():
val_(), L_(),ref_()
namespace ai
{
unit_advancements_aspect::unit_advancements_aspect()
: val_()
, L_()
, ref_()
{
}
@ -48,12 +48,14 @@ unit_advancements_aspect::unit_advancements_aspect(lua_State* L, int n)
{
lua_settop(L, n);
//on the top of the Lua-Stack is now the pointer to the function. Save it:
// on the top of the Lua-Stack is now the pointer to the function. Save it:
ref_ = luaL_ref(L, LUA_REGISTRYINDEX);
}
unit_advancements_aspect::unit_advancements_aspect(const std::string& val): val_(val), L_(), ref_()
unit_advancements_aspect::unit_advancements_aspect(const std::string& val)
: val_(val)
, L_()
, ref_()
{
}
@ -67,10 +69,7 @@ unit_advancements_aspect::~unit_advancements_aspect()
const std::vector<std::string> unit_advancements_aspect::get_advancements(const unit_map::const_iterator& unit) const
{
if(!unit.valid())
{
if(!unit.valid()) {
return std::vector<std::string>();
}
@ -78,53 +77,50 @@ const std::vector<std::string> unit_advancements_aspect::get_advancements(const
const int unit_x = (*unit).get_location().wml_x();
const int unit_y = (*unit).get_location().wml_y();
LOG_LUA << "Entering unit_advancements_aspect::get_advancements() in instance " << this << " with unit " << unit_id << " on (x,y) = (" << unit_x << ", " << unit_y << ")\n";
LOG_LUA << "Entering unit_advancements_aspect::get_advancements() in instance " << this << " with unit " << unit_id
<< " on (x,y) = (" << unit_x << ", " << unit_y << ")\n";
if(L_ == nullptr || ref_ == LUA_REFNIL)
{
//If we end up here, most likely the aspect don't use the lua-engine.
//Just to make sure:
if (val_ == "Lua Function")
{
if(L_ == nullptr || ref_ == LUA_REFNIL) {
// If we end up here, most likely the aspect don't use the lua-engine.
// Just to make sure:
if(val_ == "Lua Function") {
return std::vector<std::string>();
}
return utils::split(val_);
}
//put the Pointer back on the Stack
// put the Pointer back on the Stack
lua_rawgeti(L_, LUA_REGISTRYINDEX, ref_);
if(lua_isstring(L_, -1))
{
if(lua_isstring(L_, -1)) {
return utils::split(lua_tostring(L_, -1));
}
if(!lua_isfunction(L_, -1))
{
if(!lua_isfunction(L_, -1)) {
ERR_LUA << "Can't evaluate advancement aspect: Value is neither a string nor a function." << std::endl;
return std::vector<std::string>();
}
//push parameter to the stack
// push parameter to the stack
lua_pushinteger(L_, unit_x);
lua_pushinteger(L_, unit_y);
//To make unit_id a Parameter of the Lua function:
//lua_pushfstring(L_, unit_id.c_str());
// To make unit_id a Parameter of the Lua function:
// lua_pushfstring(L_, unit_id.c_str());
//call function
if(lua_pcall(L_, 2, 1, 0) != 0)
{
// call function
if(lua_pcall(L_, 2, 1, 0) != 0) {
ERR_LUA << "LUA Error while evaluating advancements_aspect: " << lua_tostring(L_, -1) << std::endl;
return std::vector<std::string>();
}
if (!lua_isstring(L_, -1))
{
if(!lua_isstring(L_, -1)) {
ERR_LUA << "LUA Error while evaluating advancements_aspect: Function must return String " << std::endl;
return std::vector<std::string>();
}
//get result from Lua-Stack
// get result from Lua-Stack
const std::string retval = std::string(lua_tostring(L_, -1));
lua_pop(L_, 1);
@ -133,7 +129,6 @@ const std::vector<std::string> unit_advancements_aspect::get_advancements(const
return utils::split(retval);
}
const std::string unit_advancements_aspect::get_value() const
{
return val_;

File diff suppressed because it is too large Load diff

View file

@ -18,26 +18,24 @@
*/
#include "ai/lua/engine_lua.hpp"
#include "ai/composite/ai.hpp"
#include "ai/composite/aspect.hpp"
#include "ai/composite/goal.hpp"
#include "ai/composite/rca.hpp"
#include "ai/composite/stage.hpp"
#include "ai/composite/aspect.hpp"
#include "ai/gamestate_observer.hpp"
#include "log.hpp"
#include "resources.hpp"
#include "ai/lua/core.hpp"
#include "ai/lua/lua_object.hpp"
#include "game_board.hpp"
#include "log.hpp"
#include "resources.hpp"
#include "scripting/game_lua_kernel.hpp"
#include "units/unit.hpp"
#include "units/map.hpp"
#include "units/unit.hpp"
namespace ai {
namespace ai
{
static lg::log_domain log_ai_engine_lua("ai/engine/lua");
#define DBG_AI_LUA LOG_STREAM(debug, log_ai_engine_lua)
#define LOG_AI_LUA LOG_STREAM(info, log_ai_engine_lua)
@ -46,28 +44,33 @@ static lg::log_domain log_ai_engine_lua("ai/engine/lua");
#ifdef _MSC_VER
#pragma warning(push)
//silence "inherits via dominance" warnings
#pragma warning(disable:4250)
// silence "inherits via dominance" warnings
#pragma warning(disable : 4250)
#endif
typedef std::shared_ptr< lua_object<int> > lua_int_obj;
class lua_candidate_action_wrapper_base : public candidate_action {
typedef std::shared_ptr<lua_object<int>> lua_int_obj;
class lua_candidate_action_wrapper_base : public candidate_action
{
public:
lua_candidate_action_wrapper_base( rca_context &context, const config &cfg)
: candidate_action(context, cfg),evaluation_action_handler_(),execution_action_handler_(),serialized_evaluation_state_(cfg.child_or_empty("args"))
lua_candidate_action_wrapper_base(rca_context& context, const config& cfg)
: candidate_action(context, cfg)
, evaluation_action_handler_()
, execution_action_handler_()
, serialized_evaluation_state_(cfg.child_or_empty("args"))
{
// do nothing
}
virtual ~lua_candidate_action_wrapper_base() {}
virtual ~lua_candidate_action_wrapper_base()
{
}
virtual double evaluate()
{
lua_int_obj l_obj(new lua_object<int>());
if (evaluation_action_handler_) {
if(evaluation_action_handler_) {
evaluation_action_handler_->handle(serialized_evaluation_state_, true, l_obj);
} else {
return BAD_SCORE;
@ -78,17 +81,18 @@ public:
return result ? *result : 0.0;
}
virtual void execute() {
if (execution_action_handler_) {
virtual void execute()
{
if(execution_action_handler_) {
lua_object_ptr nil;
execution_action_handler_->handle(serialized_evaluation_state_, false, nil);
}
}
virtual config to_config() const {
virtual config to_config() const
{
config cfg = candidate_action::to_config();
cfg.add_child("args",serialized_evaluation_state_);
cfg.add_child("args", serialized_evaluation_state_);
return cfg;
}
@ -98,17 +102,23 @@ protected:
config serialized_evaluation_state_;
};
class lua_candidate_action_wrapper : public lua_candidate_action_wrapper_base {
class lua_candidate_action_wrapper : public lua_candidate_action_wrapper_base
{
public:
lua_candidate_action_wrapper( rca_context &context, const config &cfg, lua_ai_context &lua_ai_ctx)
: lua_candidate_action_wrapper_base(context,cfg),evaluation_(cfg["evaluation"]),execution_(cfg["execution"])
lua_candidate_action_wrapper(rca_context& context, const config& cfg, lua_ai_context& lua_ai_ctx)
: lua_candidate_action_wrapper_base(context, cfg)
, evaluation_(cfg["evaluation"])
, execution_(cfg["execution"])
{
evaluation_action_handler_.reset(resources::lua_kernel->create_lua_ai_action_handler(evaluation_.c_str(),lua_ai_ctx));
execution_action_handler_.reset(resources::lua_kernel->create_lua_ai_action_handler(execution_.c_str(),lua_ai_ctx));
evaluation_action_handler_.reset(
resources::lua_kernel->create_lua_ai_action_handler(evaluation_.c_str(), lua_ai_ctx));
execution_action_handler_.reset(
resources::lua_kernel->create_lua_ai_action_handler(execution_.c_str(), lua_ai_ctx));
}
virtual ~lua_candidate_action_wrapper() {}
virtual ~lua_candidate_action_wrapper()
{
}
virtual config to_config() const
{
@ -123,12 +133,15 @@ private:
std::string execution_;
};
class lua_candidate_action_wrapper_external : public lua_candidate_action_wrapper_base {
class lua_candidate_action_wrapper_external : public lua_candidate_action_wrapper_base
{
public:
lua_candidate_action_wrapper_external(rca_context& context, const config& cfg, lua_ai_context &lua_ai_ctx)
: lua_candidate_action_wrapper_base(context,cfg), location_(cfg["location"]), use_parms_(false)
lua_candidate_action_wrapper_external(rca_context& context, const config& cfg, lua_ai_context& lua_ai_ctx)
: lua_candidate_action_wrapper_base(context, cfg)
, location_(cfg["location"])
, use_parms_(false)
{
if (cfg.has_attribute("exec_parms") || cfg.has_attribute("eval_parms")) {
if(cfg.has_attribute("exec_parms") || cfg.has_attribute("eval_parms")) {
use_parms_ = true;
exec_parms_ = cfg["exec_parms"].str();
eval_parms_ = cfg["eval_parms"].str();
@ -137,20 +150,25 @@ public:
std::string exec_code;
generate_code(eval_code, exec_code);
evaluation_action_handler_.reset(resources::lua_kernel->create_lua_ai_action_handler(eval_code.c_str(),lua_ai_ctx));
execution_action_handler_.reset(resources::lua_kernel->create_lua_ai_action_handler(exec_code.c_str(),lua_ai_ctx));
evaluation_action_handler_.reset(
resources::lua_kernel->create_lua_ai_action_handler(eval_code.c_str(), lua_ai_ctx));
execution_action_handler_.reset(
resources::lua_kernel->create_lua_ai_action_handler(exec_code.c_str(), lua_ai_ctx));
}
virtual ~lua_candidate_action_wrapper_external() {}
virtual ~lua_candidate_action_wrapper_external()
{
}
virtual config to_config() const
{
config cfg = lua_candidate_action_wrapper_base::to_config();
cfg["location"] = location_;
if (use_parms_) {
if(use_parms_) {
cfg["eval_parms"] = eval_parms_;
cfg["exec_parms"] = exec_parms_;
}
return cfg;
}
@ -160,10 +178,12 @@ private:
std::string exec_parms_;
bool use_parms_;
void generate_code(std::string& eval, std::string& exec) {
void generate_code(std::string& eval, std::string& exec)
{
std::string preamble = "local self, params, data = ...\n";
std::string load = "wesnoth.require(\"" + location_ + "\")";
if (use_parms_) {
if(use_parms_) {
eval = preamble + "return " + load + ":evaluation(ai, {" + eval_parms_ + "}, {data = data})";
exec = preamble + load + ":execution(ai, {" + exec_parms_ + "}, {data = data})";
} else {
@ -173,9 +193,10 @@ private:
}
};
class lua_sticky_candidate_action_wrapper : public lua_candidate_action_wrapper {
class lua_sticky_candidate_action_wrapper : public lua_candidate_action_wrapper
{
public:
lua_sticky_candidate_action_wrapper( rca_context &context, const config &cfg, lua_ai_context &lua_ai_ctx)
lua_sticky_candidate_action_wrapper(rca_context& context, const config& cfg, lua_ai_context& lua_ai_ctx)
: lua_candidate_action_wrapper(context, cfg, lua_ai_ctx)
, bound_unit_()
{
@ -185,12 +206,9 @@ public:
virtual double evaluate()
{
if (resources::gameboard->units().find(bound_unit_->underlying_id()).valid())
{
if(resources::gameboard->units().find(bound_unit_->underlying_id()).valid()) {
return lua_candidate_action_wrapper_base::evaluate();
}
else
{
} else {
this->set_to_be_removed();
return 0; // Is 0 what we return when we don't want the action to be executed?
}
@ -201,17 +219,21 @@ public:
lua_candidate_action_wrapper_base::execute();
this->disable(); // we do not want to execute the same sticky CA twice -> will be moved out to Lua later
}
private:
unit_ptr bound_unit_;
};
class lua_stage_wrapper : public stage {
class lua_stage_wrapper : public stage
{
public:
lua_stage_wrapper( ai_context &context, const config &cfg, lua_ai_context &lua_ai_ctx )
: stage(context,cfg),action_handler_(),code_(cfg["code"]),serialized_evaluation_state_(cfg.child_or_empty("args"))
lua_stage_wrapper(ai_context& context, const config& cfg, lua_ai_context& lua_ai_ctx)
: stage(context, cfg)
, action_handler_()
, code_(cfg["code"])
, serialized_evaluation_state_(cfg.child_or_empty("args"))
{
action_handler_.reset(resources::lua_kernel->create_lua_ai_action_handler(code_.c_str(),lua_ai_ctx));
action_handler_.reset(resources::lua_kernel->create_lua_ai_action_handler(code_.c_str(), lua_ai_ctx));
}
virtual ~lua_stage_wrapper()
@ -222,7 +244,7 @@ public:
{
gamestate_observer gs_o;
if (action_handler_) {
if(action_handler_) {
lua_object_ptr nil;
action_handler_->handle(serialized_evaluation_state_, false, nil);
}
@ -234,40 +256,39 @@ public:
{
config cfg = stage::to_config();
cfg["code"] = code_;
cfg.add_child("args",serialized_evaluation_state_);
cfg.add_child("args", serialized_evaluation_state_);
return cfg;
}
private:
std::shared_ptr<lua_ai_action_handler> action_handler_;
std::string code_;
config serialized_evaluation_state_;
};
/**
* Note that initially we get access only to readonly context (engine is created rather early, when there's no way to move/attack.
* We inject full ai_context later.
* Note that initially we get access only to readonly context (engine is created rather early, when there's no way to
* move/attack. We inject full ai_context later.
*/
engine_lua::engine_lua( readonly_context &context, const config &cfg )
: engine(context,cfg)
engine_lua::engine_lua(readonly_context& context, const config& cfg)
: engine(context, cfg)
, code_(get_engine_code(cfg))
, lua_ai_context_(resources::lua_kernel->create_lua_ai_context(
get_engine_code(cfg).c_str(), this))
, lua_ai_context_(resources::lua_kernel->create_lua_ai_context(get_engine_code(cfg).c_str(), this))
{
name_ = "lua";
config data(cfg.child_or_empty("data"));
config args(cfg.child_or_empty("args"));
if (lua_ai_context_) { // The context might be nullptr if the config contains errors
if(lua_ai_context_) { // The context might be nullptr if the config contains errors
lua_ai_context_->set_persistent_data(data);
lua_ai_context_->set_arguments(args);
lua_ai_context_->update_state();
}
}
std::string engine_lua::get_engine_code(const config &cfg) const
std::string engine_lua::get_engine_code(const config& cfg) const
{
if (cfg.has_attribute("code")) {
if(cfg.has_attribute("code")) {
return cfg["code"].str();
}
// If there is no engine defined we create a dummy engine
@ -286,96 +307,100 @@ bool engine_lua::is_ok() const
void engine_lua::push_ai_table()
{
if (game_config::debug)
{
if(game_config::debug) {
lua_ai_context_->push_ai_table();
}
}
void engine_lua::do_parse_candidate_action_from_config( rca_context &context, const config &cfg, std::back_insert_iterator<std::vector< candidate_action_ptr > > b ){
if (!cfg) {
void engine_lua::do_parse_candidate_action_from_config(
rca_context& context, const config& cfg, std::back_insert_iterator<std::vector<candidate_action_ptr>> b)
{
if(!cfg) {
return;
}
if (!lua_ai_context_) {
if(!lua_ai_context_) {
return;
}
candidate_action_ptr ca_ptr;
if (!cfg["sticky"].to_bool())
{
if (cfg.has_attribute("location")) {
ca_ptr.reset(new lua_candidate_action_wrapper_external(context,cfg,*lua_ai_context_));
if(!cfg["sticky"].to_bool()) {
if(cfg.has_attribute("location")) {
ca_ptr.reset(new lua_candidate_action_wrapper_external(context, cfg, *lua_ai_context_));
} else {
ca_ptr.reset(new lua_candidate_action_wrapper(context,cfg,*lua_ai_context_));
ca_ptr.reset(new lua_candidate_action_wrapper(context, cfg, *lua_ai_context_));
}
}
else
{
ca_ptr.reset(new lua_sticky_candidate_action_wrapper(context,cfg,*lua_ai_context_));
} else {
ca_ptr.reset(new lua_sticky_candidate_action_wrapper(context, cfg, *lua_ai_context_));
}
if (ca_ptr) {
if(ca_ptr) {
*b = ca_ptr;
}
}
void engine_lua::do_parse_stage_from_config( ai_context &context, const config &cfg, std::back_insert_iterator<std::vector< stage_ptr > > b )
void engine_lua::do_parse_stage_from_config(
ai_context& context, const config& cfg, std::back_insert_iterator<std::vector<stage_ptr>> b)
{
if (!cfg) {
if(!cfg) {
return;
}
if (!lua_ai_context_) {
if(!lua_ai_context_) {
return;
}
stage_ptr st_ptr(new lua_stage_wrapper(context,cfg,*lua_ai_context_));
if (st_ptr) {
stage_ptr st_ptr(new lua_stage_wrapper(context, cfg, *lua_ai_context_));
if(st_ptr) {
st_ptr->on_create();
*b = st_ptr;
}
}
void engine_lua::do_parse_aspect_from_config( const config &cfg, const std::string &id, std::back_insert_iterator<std::vector< aspect_ptr > > b )
void engine_lua::do_parse_aspect_from_config(
const config& cfg, const std::string& id, std::back_insert_iterator<std::vector<aspect_ptr>> b)
{
const std::string aspect_factory_key = id+"*lua_aspect"; // @note: factory key for a lua_aspect
const std::string aspect_factory_key = id + "*lua_aspect"; // @note: factory key for a lua_aspect
lua_aspect_factory::factory_map::iterator f = lua_aspect_factory::get_list().find(aspect_factory_key);
if (f == lua_aspect_factory::get_list().end()){
ERR_AI_LUA << "side "<<ai_.get_side()<< " : UNKNOWN aspect["<<aspect_factory_key<<"]" << std::endl;
if(f == lua_aspect_factory::get_list().end()) {
ERR_AI_LUA << "side " << ai_.get_side() << " : UNKNOWN aspect[" << aspect_factory_key << "]" << std::endl;
DBG_AI_LUA << "config snippet contains: " << std::endl << cfg << std::endl;
return;
}
aspect_ptr new_aspect = f->second->get_new_instance(ai_,cfg,id,lua_ai_context_);
if (!new_aspect) {
ERR_AI_LUA << "side "<<ai_.get_side()<< " : UNABLE TO CREATE aspect, key=["<<aspect_factory_key<<"]"<< std::endl;
aspect_ptr new_aspect = f->second->get_new_instance(ai_, cfg, id, lua_ai_context_);
if(!new_aspect) {
ERR_AI_LUA << "side " << ai_.get_side() << " : UNABLE TO CREATE aspect, key=[" << aspect_factory_key << "]"
<< std::endl;
DBG_AI_LUA << "config snippet contains: " << std::endl << cfg << std::endl;
return;
}
*b = new_aspect;
}
void engine_lua::do_parse_goal_from_config(const config &cfg, std::back_insert_iterator<std::vector< goal_ptr > > b )
void engine_lua::do_parse_goal_from_config(const config& cfg, std::back_insert_iterator<std::vector<goal_ptr>> b)
{
goal_factory::factory_map::iterator f = goal_factory::get_list().find(cfg["name"]);
if (f == goal_factory::get_list().end()){
ERR_AI_LUA << "side "<<ai_.get_side()<< " : UNKNOWN goal["<<cfg["name"]<<"]"<< std::endl;
if(f == goal_factory::get_list().end()) {
ERR_AI_LUA << "side " << ai_.get_side() << " : UNKNOWN goal[" << cfg["name"] << "]" << std::endl;
DBG_AI_LUA << "config snippet contains: " << std::endl << cfg << std::endl;
return;
}
goal_ptr new_goal = f->second->get_new_instance(ai_,cfg);
goal_ptr new_goal = f->second->get_new_instance(ai_, cfg);
new_goal->on_create(lua_ai_context_);
if (!new_goal || !new_goal->ok()) {
ERR_AI_LUA << "side "<<ai_.get_side()<< " : UNABLE TO CREATE goal["<<cfg["name"]<<"]"<< std::endl;
if(!new_goal || !new_goal->ok()) {
ERR_AI_LUA << "side " << ai_.get_side() << " : UNABLE TO CREATE goal[" << cfg["name"] << "]" << std::endl;
DBG_AI_LUA << "config snippet contains: " << std::endl << cfg << std::endl;
return;
}
*b = new_goal;
}
std::string engine_lua::evaluate(const std::string &/*str*/)
std::string engine_lua::evaluate(const std::string& /*str*/)
{
///@todo this is not mandatory, but if we want to allow lua to evaluate
// something 'in context' of this ai, this will be useful
@ -389,7 +414,7 @@ config engine_lua::to_config() const
cfg["id"] = get_id();
cfg["code"] = this->code_;
if (lua_ai_context_) {
if(lua_ai_context_) {
config data = config();
lua_ai_context_->get_persistent_data(data);
cfg.add_child("data") = data;
@ -402,4 +427,4 @@ config engine_lua::to_config() const
#pragma warning(pop)
#endif
} //end of namespace ai
} // end of namespace ai

View file

@ -17,58 +17,61 @@
* Lua object(code) wrapper implementation
*/
#include "ai/lua/lua_object.hpp"
#include "ai/lua/engine_lua.hpp"
#include "ai/default/aspect_attacks.hpp"
#include "scripting/lua_common.hpp"
#include "ai/lua/engine_lua.hpp"
#include "resources.hpp"
#include "scripting/lua_common.hpp"
#include "lua/lauxlib.h"
namespace ai {
namespace ai
{
lua_object_base::lua_object_base()
{
// empty
}
lua_object_base::lua_object_base()
{
// empty
}
// MSVC fails to compile without this line
template class lua_object<aspect_attacks_lua_filter>;
// MSVC fails to compile without this line
template class lua_object<aspect_attacks_lua_filter>;
template<>
std::shared_ptr<aspect_attacks_lua_filter> lua_object<aspect_attacks_lua_filter>::to_type(lua_State* L, int n)
{
std::shared_ptr<aspect_attacks_lua_filter> att(new aspect_attacks_lua_filter);
att->lua = nullptr;
att->ref_own_ = att->ref_enemy_ = -1;
template <>
std::shared_ptr<aspect_attacks_lua_filter> lua_object<aspect_attacks_lua_filter>::to_type(lua_State *L, int n)
{
std::shared_ptr<aspect_attacks_lua_filter> att(new aspect_attacks_lua_filter);
att->lua = nullptr;
att->ref_own_ = att->ref_enemy_ = -1;
if(!lua_istable(L, n)) {
return att;
}
lua_getfield(L, n, "own");
if(lua_istable(L, -1)) {
vconfig vcfg(config(), true);
if(luaW_tovconfig(L, -1, vcfg)) {
att->filter_own_.reset(new unit_filter(vcfg));
}
} else if(lua_isfunction(L, -1)) {
att->lua = L;
att->ref_own_ = luaL_ref(L, LUA_REGISTRYINDEX);
assert(att->ref_own_ != -1);
}
lua_getfield(L, n, "enemy");
if(lua_istable(L, -1)) {
vconfig vcfg(config(), true);
if(luaW_tovconfig(L, -1, vcfg)) {
att->filter_enemy_.reset(new unit_filter(vcfg));
}
} else if(lua_isfunction(L, -1)) {
att->lua = L;
att->ref_enemy_ = luaL_ref(L, LUA_REGISTRYINDEX);
assert(att->ref_enemy_ != -1);
}
lua_pop(L, 2);
if(!lua_istable(L, n)) {
return att;
}
} //end of namespace ai
lua_getfield(L, n, "own");
if(lua_istable(L, -1)) {
vconfig vcfg(config(), true);
if(luaW_tovconfig(L, -1, vcfg)) {
att->filter_own_.reset(new unit_filter(vcfg));
}
} else if(lua_isfunction(L, -1)) {
att->lua = L;
att->ref_own_ = luaL_ref(L, LUA_REGISTRYINDEX);
assert(att->ref_own_ != -1);
}
lua_getfield(L, n, "enemy");
if(lua_istable(L, -1)) {
vconfig vcfg(config(), true);
if(luaW_tovconfig(L, -1, vcfg)) {
att->filter_enemy_.reset(new unit_filter(vcfg));
}
} else if(lua_isfunction(L, -1)) {
att->lua = L;
att->ref_enemy_ = luaL_ref(L, LUA_REGISTRYINDEX);
assert(att->ref_enemy_ != -1);
}
lua_pop(L, 2);
return att;
}
} // end of namespace ai