The Battle for Wesnoth  1.19.0-dev
aspect_advancements.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2024
3  by Felix Bauer <fehlxb+wesnoth@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
17 
18 #include "log.hpp" // for LOG_STREAM, logger, etc
19 #include "lua/wrapper_lauxlib.h" // for luaL_ref, LUA_REFNIL, lua_isstring, etc
20 #include "map/location.hpp" // for map_location
21 #include "serialization/string_utils.hpp" // for split
22 #include "units/unit.hpp"
23 #include "units/map.hpp" // for unit_map::const_iterator, etc
24 
25 #include <string> // for string, char_traits, etc
26 #include <vector> // for vector
27 
28 
29 
30 static lg::log_domain log_ai_engine_lua("ai/engine/lua");
31 #define LOG_LUA LOG_STREAM(info, log_ai_engine_lua)
32 #define ERR_LUA LOG_STREAM(err, log_ai_engine_lua)
33 
34 namespace ai{
35 
37  val_(), L_(),ref_()
38 {
39 }
40 
42  : val_("Lua Function")
43  , L_(L)
44  , ref_()
45 {
46  lua_settop(L, n);
47 
48  //on the top of the Lua-Stack is now the pointer to the function. Save it:
49  ref_ = luaL_ref(L, LUA_REGISTRYINDEX);
50 
51 }
52 
53 unit_advancements_aspect::unit_advancements_aspect(const std::string& val): val_(val), L_(), ref_()
54 {
55 }
56 
58 {
59  if(L_) {
60  // Remove the function from the registry
61  luaL_unref(L_, LUA_REGISTRYINDEX, ref_);
62  }
63 }
64 
65 const std::vector<std::string> unit_advancements_aspect::get_advancements(const unit_map::const_iterator& unit) const
66 {
67 
68  if(!unit.valid())
69  {
70  return std::vector<std::string>();
71  }
72 
73  const std::string& unit_id = (*unit).id();
74  const int unit_x = (*unit).get_location().wml_x();
75  const int unit_y = (*unit).get_location().wml_y();
76 
77  LOG_LUA << "Entering unit_advancements_aspect::get_advancements() in instance " << this << " with unit " << unit_id << " on (x,y) = (" << unit_x << ", " << unit_y << ")";
78 
79  if(L_ == nullptr || ref_ == LUA_REFNIL)
80  {
81  //If we end up here, most likely the aspect don't use the lua-engine.
82  //Just to make sure:
83  if (val_ == "Lua Function")
84  {
85  return std::vector<std::string>();
86  }
87  return utils::split(val_);
88  }
89 
90  //put the Pointer back on the Stack
91  lua_rawgeti(L_, LUA_REGISTRYINDEX, ref_);
92 
93  if(lua_isstring(L_, -1))
94  {
95  return utils::split(lua_tostring(L_, -1));
96  }
97 
98  if(!lua_isfunction(L_, -1))
99  {
100  ERR_LUA << "Can't evaluate advancement aspect: Value is neither a string nor a function.";
101  return std::vector<std::string>();
102  }
103 
104  //push parameter to the stack
105  lua_pushinteger(L_, unit_x);
106  lua_pushinteger(L_, unit_y);
107 
108  //To make unit_id a Parameter of the Lua function:
109  //lua_pushfstring(L_, unit_id.c_str());
110 
111  //call function
112  if(lua_pcall(L_, 2, 1, 0) != 0)
113  {
114  ERR_LUA << "LUA Error while evaluating advancements_aspect: " << lua_tostring(L_, -1);
115  return std::vector<std::string>();
116  }
117  if (!lua_isstring(L_, -1))
118  {
119  ERR_LUA << "LUA Error while evaluating advancements_aspect: Function must return String ";
120  return std::vector<std::string>();
121  }
122 
123  //get result from Lua-Stack
124  const std::string retval = std::string(lua_tostring(L_, -1));
125  lua_pop(L_, 1);
126 
127  LOG_LUA << "Called Lua advancement function. Result was: \"" << retval << "\".";
128 
129  return utils::split(retval);
130 }
131 
132 const std::string unit_advancements_aspect::get_value() const
133 {
134  return val_;
135 }
136 }
#define ERR_LUA
static lg::log_domain log_ai_engine_lua("ai/engine/lua")
#define LOG_LUA
const std::vector< std::string > get_advancements(const unit_map::const_iterator &unit) const
const std::string get_value() const
This class represents a single unit of a specific type.
Definition: unit.hpp:133
Standard logging facilities (interface).
A small explanation about what's going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:59
retval
Default window/dialog return values.
Definition: retval.hpp:30
std::vector< std::string > split(const config_attribute_value &val)
static map_location::DIRECTION n