Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

AI/lua: Command 'lua wesnoth.debug_ai(2).ai' gives now access to ai-t…

…able
  • Loading branch information...
commit f9a231f09da9d4239ac562ce284ad07e4dc0fd90 1 parent 5301eed
@flixx flixx authored
View
2  changelog
@@ -1,6 +1,8 @@
Version 1.11.4+dev:
* AI:
* Recruiting in Micro and Experimental AIs: allow more terrain codes for castles/keeps
+ * Improved/Added: Command 'lua wesnoth.debug_ai([side]).ai' will now give access to the
+ ai-table of [side].
* Campaigns:
* Legend of Wesmere:
* Scenario 05: Elvish Horse Archers can now carry the treasure
View
4 src/ai/composite/engine_lua.cpp
@@ -234,7 +234,7 @@ class lua_stage_wrapper : public stage {
*/
engine_lua::engine_lua( readonly_context &context, const config &cfg )
: engine(context,cfg)
- , code_(cfg["code"])
+ , code_(get_engine_code(cfg))
, lua_ai_context_(resources::lua_kernel->create_lua_ai_context(
get_engine_code(cfg).c_str(), this))
{
@@ -269,7 +269,7 @@ void engine_lua::push_ai_table()
{
if (game_config::debug)
{
- lua_ai_context_->load();
+ lua_ai_context_->load_and_inject_ai_table(this);
}
}
View
148 src/ai/lua/core.cpp
@@ -815,6 +815,76 @@ static int cfun_ai_recalculate_move_maps_enemy(lua_State *L)
return 1;
}
+static void generate_and_push_ai_table(lua_State* L, ai::engine_lua* engine) {
+ //push data table here
+ lua_newtable(L);
+ lua_pushinteger(L, engine->get_readonly_context().get_side());
+ lua_setfield(L, -2, "side"); //stack size is 2 [- 1: new table; -2 ai as string]
+ static luaL_Reg const callbacks[] = {
+ { "attack", &cfun_ai_execute_attack },
+ // Move maps
+ { "get_new_dst_src", &cfun_ai_get_dstsrc },
+ { "get_new_src_dst", &cfun_ai_get_srcdst },
+ { "get_new_enemy_dst_src", &cfun_ai_get_enemy_dstsrc },
+ { "get_new_enemy_src_dst", &cfun_ai_get_enemy_srcdst },
+ { "recalculate_move_maps", &cfun_ai_recalculate_move_maps },
+ { "recalculate_enemy_move_maps", &cfun_ai_recalculate_move_maps_enemy },
+ // End of move maps
+ // Goals and targets
+ { "get_targets", &cfun_ai_get_targets },
+ // End of G & T
+ // Aspects
+ { "get_aggression", &cfun_ai_get_aggression },
+ { "get_avoid", &cfun_ai_get_avoid },
+ { "get_attack_depth", &cfun_ai_get_attack_depth },
+ { "get_attacks", &cfun_ai_get_attacks },
+ { "get_caution", &cfun_ai_get_caution },
+ { "get_grouping", &cfun_ai_get_grouping },
+ { "get_leader_aggression", &cfun_ai_get_leader_aggression },
+ { "get_leader_goal", &cfun_ai_get_leader_goal },
+ { "get_leader_ignores_keep", &cfun_ai_get_leader_ignores_keep },
+ { "get_leader_value", &cfun_ai_get_leader_value },
+ { "get_number_of_possible_recruits_to_force_recruit", &cfun_ai_get_number_of_possible_recruits_to_force_recruit },
+ { "get_passive_leader", &cfun_ai_get_passive_leader },
+ { "get_passive_leader_shares_keep", &cfun_ai_get_passive_leader_shares_keep },
+ { "get_recruitment_ignore_bad_combat", &cfun_ai_get_recruitment_ignore_bad_combat },
+ { "get_recruitment_ignore_bad_movement", &cfun_ai_get_recruitment_ignore_bad_movement },
+ { "get_recruitment_pattern", &cfun_ai_get_recruitment_pattern },
+ { "get_scout_village_targeting", &cfun_ai_get_scout_village_targeting },
+ { "get_simple_targeting", &cfun_ai_get_simple_targeting },
+ { "get_support_villages", &cfun_ai_get_support_villages },
+ { "get_village_value", &cfun_ai_get_village_value },
+ { "get_villages_per_scout", &cfun_ai_get_villages_per_scout },
+ // End of aspects
+ // Validation/cache functions
+ { "is_dst_src_valid", &cfun_ai_is_dst_src_valid },
+ { "is_enemy_dst_src_valid", &cfun_ai_is_dst_src_enemy_valid },
+ { "is_src_dst_valid", &cfun_ai_is_src_dst_valid },
+ { "is_enemy_src_dst_valid", &cfun_ai_is_src_dst_enemy_valid },
+ // End of validation functions
+ { "move", &cfun_ai_execute_move_partial },
+ { "move_full", &cfun_ai_execute_move_full },
+ { "recall", &cfun_ai_execute_recall },
+ { "recruit", &cfun_ai_execute_recruit },
+ { "stopunit_all", &cfun_ai_execute_stopunit_all },
+ { "stopunit_attacks", &cfun_ai_execute_stopunit_attacks },
+ { "stopunit_moves", &cfun_ai_execute_stopunit_moves },
+ { "suitable_keep", &cfun_ai_get_suitable_keep },
+ { "check_recall", &cfun_ai_check_recall },
+ { "check_move", &cfun_ai_check_move },
+ { "check_stopunit", &cfun_ai_check_stopunit },
+ { "check_attack", &cfun_ai_check_attack },
+ { "check_recruit", &cfun_ai_check_recruit },
+ //{ "",},
+ //{ "",},
+ { NULL, NULL } };
+ for (const luaL_Reg* p = callbacks; p->name; ++p) {
+ lua_pushlightuserdata(L, engine);
+ lua_pushcclosure(L, p->func, 1);
+ lua_setfield(L, -2, p->name);
+ }
+}
+
lua_ai_context* lua_ai_context::create(lua_State *L, char const *code, ai::engine_lua *engine)
{
int res_ai = luaL_loadstring(L, code);//stack size is now 1 [ -1: ai_context]
@@ -827,76 +897,7 @@ lua_ai_context* lua_ai_context::create(lua_State *L, char const *code, ai::engin
return NULL;
}
//push data table here
- lua_newtable(L);// stack size is 2 [ -1: new table, -2: ai as string ]
- lua_pushinteger(L, engine->get_readonly_context().get_side());
-
- lua_setfield(L, -2, "side");//stack size is 2 [- 1: new table; -2 ai as string]
-
- static luaL_Reg const callbacks[] = {
- { "attack", &cfun_ai_execute_attack },
- // Move maps
- { "get_new_dst_src", &cfun_ai_get_dstsrc },
- { "get_new_src_dst", &cfun_ai_get_srcdst },
- { "get_new_enemy_dst_src", &cfun_ai_get_enemy_dstsrc },
- { "get_new_enemy_src_dst", &cfun_ai_get_enemy_srcdst },
- { "recalculate_move_maps", &cfun_ai_recalculate_move_maps },
- { "recalculate_enemy_move_maps",&cfun_ai_recalculate_move_maps_enemy },
- // End of move maps
- // Goals and targets
- { "get_targets", &cfun_ai_get_targets },
- // End of G & T
- // Aspects
- { "get_aggression", &cfun_ai_get_aggression },
- { "get_avoid", &cfun_ai_get_avoid },
- { "get_attack_depth", &cfun_ai_get_attack_depth },
- { "get_attacks", &cfun_ai_get_attacks },
- { "get_caution", &cfun_ai_get_caution },
- { "get_grouping", &cfun_ai_get_grouping },
- { "get_leader_aggression", &cfun_ai_get_leader_aggression },
- { "get_leader_goal", &cfun_ai_get_leader_goal },
- { "get_leader_ignores_keep", &cfun_ai_get_leader_ignores_keep},
- { "get_leader_value", &cfun_ai_get_leader_value },
- { "get_number_of_possible_recruits_to_force_recruit", &cfun_ai_get_number_of_possible_recruits_to_force_recruit},
- { "get_passive_leader", &cfun_ai_get_passive_leader },
- { "get_passive_leader_shares_keep", &cfun_ai_get_passive_leader_shares_keep},
- { "get_recruitment_ignore_bad_combat", &cfun_ai_get_recruitment_ignore_bad_combat},
- { "get_recruitment_ignore_bad_movement", &cfun_ai_get_recruitment_ignore_bad_movement},
- { "get_recruitment_pattern", &cfun_ai_get_recruitment_pattern },
- { "get_scout_village_targeting", &cfun_ai_get_scout_village_targeting },
- { "get_simple_targeting", &cfun_ai_get_simple_targeting },
- { "get_support_villages", &cfun_ai_get_support_villages },
- { "get_village_value", &cfun_ai_get_village_value },
- { "get_villages_per_scout", &cfun_ai_get_villages_per_scout },
- // End of aspects
- // Validation/cache functions
- { "is_dst_src_valid", &cfun_ai_is_dst_src_valid },
- { "is_enemy_dst_src_valid", &cfun_ai_is_dst_src_enemy_valid },
- { "is_src_dst_valid", &cfun_ai_is_src_dst_valid },
- { "is_enemy_src_dst_valid", &cfun_ai_is_src_dst_enemy_valid },
- // End of validation functions
- { "move", &cfun_ai_execute_move_partial },
- { "move_full", &cfun_ai_execute_move_full },
- { "recall", &cfun_ai_execute_recall },
- { "recruit", &cfun_ai_execute_recruit },
- { "stopunit_all", &cfun_ai_execute_stopunit_all },
- { "stopunit_attacks", &cfun_ai_execute_stopunit_attacks },
- { "stopunit_moves", &cfun_ai_execute_stopunit_moves },
- { "suitable_keep", &cfun_ai_get_suitable_keep },
- { "check_recall", &cfun_ai_check_recall },
- { "check_move", &cfun_ai_check_move },
- { "check_stopunit", &cfun_ai_check_stopunit },
- { "check_attack", &cfun_ai_check_attack },
- { "check_recruit", &cfun_ai_check_recruit },
- //{ "",},
- //{ "",},
- { NULL, NULL }
- };
-
- for (const luaL_Reg *p = callbacks; p->name; ++p) {
- lua_pushlightuserdata(L, engine);
- lua_pushcclosure(L, p->func, 1);
- lua_setfield(L, -2, p->name);
- }
+ generate_and_push_ai_table(L, engine);
//compile the ai as a closure
if (!luaW_pcall(L, 1, 1, true)) {
@@ -948,6 +949,13 @@ void lua_ai_context::load()
lua_remove(L,-2);
}
+void lua_ai_context::load_and_inject_ai_table(ai::engine_lua* engine)
+{
+ load(); //stack size is 1 [-1: ai_context]
+ generate_and_push_ai_table(L, engine); //stack size is 2 [-1: ai_table -2: ai_context]
+ lua_setfield(L, -2, "ai"); //stack size is 1 [-1: ai_context]
+}
+
lua_ai_context::~lua_ai_context()
{
// Remove the ai context from the registry, so that it can be collected.
View
1  src/ai/lua/core.hpp
@@ -51,6 +51,7 @@ class lua_ai_context
{
}
void load();
+ void load_and_inject_ai_table(engine_lua* engine);
void get_persistent_data(config &) const;
void set_persistent_data(const config &);
static void init(lua_State *L);
View
5 src/ai/manager.cpp
@@ -286,6 +286,11 @@ component* holder::get_component(component *root, const std::string &path) {
if (root == NULL) // Return root component(ai_)
{
+ if (!this->ai_) {
+ this->init(this->side_);
+ }
+ assert(this->ai_);
+
return &*this->ai_;
}
View
19 src/scripting/lua.cpp
@@ -59,6 +59,9 @@
#include "ai/lua/core.hpp"
#include "version.hpp"
#include "gui/widgets/clickable.hpp"
+#include "ai/contexts.hpp"
+#include "ai/configuration.hpp"
+#include "ai/composite/ai.hpp"
#ifdef GUI2_EXPERIMENTAL_LISTBOX
#include "gui/widgets/list.hpp"
#else
@@ -3608,8 +3611,20 @@ static int intf_debug_ai(lua_State *L)
if (lua_engine == NULL)
{
- lua_createtable(L, 0, 0);
- return 1;
+ //no lua engine is defined for this side.
+ //so set up a dummy engine
+
+ ai::ai_composite * ai_ptr = dynamic_cast<ai::ai_composite *>(c);
+ ai::ai_context& ai_context = ai_ptr->get_ai_context();
+ config cfg = ai::configuration::get_default_ai_parameters();
+
+ lua_engine = new ai::engine_lua(ai_context, cfg);
+ LOG_LUA << "Created new dummy lua-engine for debug_ai(). \n";
+
+ //and add the dummy engine as a component
+ //to the manager, so we could use it later
+ cfg.add_child("engine", lua_engine->to_config());
+ ai::component_manager::add_component(c, "engine[]", cfg);
}
lua_engine->push_ai_table(); // stack: [-1: ai_context]
Please sign in to comment.
Something went wrong with that request. Please try again.