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 <ostream> // for operator<<, basic_ostream, etc
26 #include <string> // for string, char_traits, etc
27 #include <vector> // for vector
28 
29 struct lua_State;
30 
31 
32 static lg::log_domain log_ai_engine_lua("ai/engine/lua");
33 #define LOG_LUA LOG_STREAM(info, log_ai_engine_lua)
34 #define ERR_LUA LOG_STREAM(err, log_ai_engine_lua)
35 
36 namespace ai{
37 
39  val_(), L_(),ref_()
40 {
41 }
42 
44  : val_("Lua Function")
45  , L_(L)
46  , ref_()
47 {
48  lua_settop(L, n);
49 
50  //on the top of the Lua-Stack is now the pointer to the function. Save it:
51  ref_ = luaL_ref(L, LUA_REGISTRYINDEX);
52 
53 }
54 
55 unit_advancements_aspect::unit_advancements_aspect(const std::string& val): val_(val), L_(), ref_()
56 {
57 }
58 
60 {
61  if(L_) {
62  // Remove the function from the registry
63  luaL_unref(L_, LUA_REGISTRYINDEX, ref_);
64  }
65 }
66 
67 const std::vector<std::string> unit_advancements_aspect::get_advancements(const unit_map::const_iterator& unit) const
68 {
69 
70  if(!unit.valid())
71  {
72  return std::vector<std::string>();
73  }
74 
75  const std::string& unit_id = (*unit).id();
76  const int unit_x = (*unit).get_location().wml_x();
77  const int unit_y = (*unit).get_location().wml_y();
78 
79  LOG_LUA << "Entering unit_advancements_aspect::get_advancements() in instance " << this << " with unit " << unit_id << " on (x,y) = (" << unit_x << ", " << unit_y << ")";
80 
81  if(L_ == nullptr || ref_ == LUA_REFNIL)
82  {
83  //If we end up here, most likely the aspect don't use the lua-engine.
84  //Just to make sure:
85  if (val_ == "Lua Function")
86  {
87  return std::vector<std::string>();
88  }
89  return utils::split(val_);
90  }
91 
92  //put the Pointer back on the Stack
93  lua_rawgeti(L_, LUA_REGISTRYINDEX, ref_);
94 
95  if(lua_isstring(L_, -1))
96  {
97  return utils::split(lua_tostring(L_, -1));
98  }
99 
100  if(!lua_isfunction(L_, -1))
101  {
102  ERR_LUA << "Can't evaluate advancement aspect: Value is neither a string nor a function.";
103  return std::vector<std::string>();
104  }
105 
106  //push parameter to the stack
107  lua_pushinteger(L_, unit_x);
108  lua_pushinteger(L_, unit_y);
109 
110  //To make unit_id a Parameter of the Lua function:
111  //lua_pushfstring(L_, unit_id.c_str());
112 
113  //call function
114  if(lua_pcall(L_, 2, 1, 0) != 0)
115  {
116  ERR_LUA << "LUA Error while evaluating advancements_aspect: " << lua_tostring(L_, -1);
117  return std::vector<std::string>();
118  }
119  if (!lua_isstring(L_, -1))
120  {
121  ERR_LUA << "LUA Error while evaluating advancements_aspect: Function must return String ";
122  return std::vector<std::string>();
123  }
124 
125  //get result from Lua-Stack
126  const std::string retval = std::string(lua_tostring(L_, -1));
127  lua_pop(L_, 1);
128 
129  LOG_LUA << "Called Lua advancement function. Result was: \"" << retval << "\".";
130 
131  return utils::split(retval);
132 }
133 
134 const std::string unit_advancements_aspect::get_value() const
135 {
136  return val_;
137 }
138 }
#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:135
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:61
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