The Battle for Wesnoth  1.17.0-dev
aspect_advancements.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2021
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/lauxlib.h" // for luaL_ref, LUA_REFNIL
20 #include "lua/lua.h" // for lua_isstring, etc
21 #include "map/location.hpp" // for map_location
22 #include "serialization/string_utils.hpp" // for split
23 #include "units/unit.hpp"
24 #include "units/map.hpp" // for unit_map::const_iterator, etc
25 
26 #include <ostream> // for operator<<, basic_ostream, etc
27 #include <string> // for string, char_traits, etc
28 #include <vector> // for vector
29 
30 struct lua_State;
31 
32 
33 static lg::log_domain log_ai_engine_lua("ai/engine/lua");
34 #define LOG_LUA LOG_STREAM(info, log_ai_engine_lua)
35 #define ERR_LUA LOG_STREAM(err, log_ai_engine_lua)
36 
37 namespace ai{
38 
40  val_(), L_(),ref_()
41 {
42 }
43 
45  : val_("Lua Function")
46  , L_(L)
47  , ref_()
48 {
49  lua_settop(L, n);
50 
51  //on the top of the Lua-Stack is now the pointer to the function. Save it:
53 
54 }
55 
57 {
58 }
59 
61 {
62  if(L_) {
63  // Remove the function from the registry
65  }
66 }
67 
68 const std::vector<std::string> unit_advancements_aspect::get_advancements(const unit_map::const_iterator& unit) const
69 {
70 
71  if(!unit.valid())
72  {
73  return std::vector<std::string>();
74  }
75 
76  const std::string& unit_id = (*unit).id();
77  const int unit_x = (*unit).get_location().wml_x();
78  const int unit_y = (*unit).get_location().wml_y();
79 
80  LOG_LUA << "Entering unit_advancements_aspect::get_advancements() in instance " << this << " with unit " << unit_id << " on (x,y) = (" << unit_x << ", " << unit_y << ")\n";
81 
82  if(L_ == nullptr || ref_ == LUA_REFNIL)
83  {
84  //If we end up here, most likely the aspect don't use the lua-engine.
85  //Just to make sure:
86  if (val_ == "Lua Function")
87  {
88  return std::vector<std::string>();
89  }
90  return utils::split(val_);
91  }
92 
93  //put the Pointer back on the Stack
95 
96  if(lua_isstring(L_, -1))
97  {
98  return utils::split(lua_tostring(L_, -1));
99  }
100 
101  if(!lua_isfunction(L_, -1))
102  {
103  ERR_LUA << "Can't evaluate advancement aspect: Value is neither a string nor a function." << std::endl;
104  return std::vector<std::string>();
105  }
106 
107  //push parameter to the stack
108  lua_pushinteger(L_, unit_x);
109  lua_pushinteger(L_, unit_y);
110 
111  //To make unit_id a Parameter of the Lua function:
112  //lua_pushfstring(L_, unit_id.c_str());
113 
114  //call function
115  if(lua_pcall(L_, 2, 1, 0) != 0)
116  {
117  ERR_LUA << "LUA Error while evaluating advancements_aspect: " << lua_tostring(L_, -1) << std::endl;
118  return std::vector<std::string>();
119  }
120  if (!lua_isstring(L_, -1))
121  {
122  ERR_LUA << "LUA Error while evaluating advancements_aspect: Function must return String " << std::endl;
123  return std::vector<std::string>();
124  }
125 
126  //get result from Lua-Stack
127  const std::string retval = std::string(lua_tostring(L_, -1));
128  lua_pop(L_, 1);
129 
130  LOG_LUA << "Called Lua advancement function. Result was: \"" << retval << "\".\n";
131 
132  return utils::split(retval);
133 }
134 
135 const std::string unit_advancements_aspect::get_value() const
136 {
137  return val_;
138 }
139 }
static lg::log_domain log_ai_engine_lua("ai/engine/lua")
LUA_API void lua_settop(lua_State *L, int idx)
Definition: lapi.cpp:173
This class represents a single unit of a specific type.
Definition: unit.hpp:121
LUA_API int lua_rawgeti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:710
LUALIB_API int luaL_ref(lua_State *L, int t)
Definition: lauxlib.cpp:646
#define val_(o)
Definition: lobject.h:70
#define LOG_LUA
#define lua_pop(L, n)
Definition: lua.h:364
const std::vector< std::string > get_advancements(const unit_map::const_iterator &unit) const
#define lua_pcall(L, n, r, f)
Definition: lua.h:287
A small explanation about what&#39;s going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:61
LUA_API int lua_isstring(lua_State *L, int idx)
Definition: lapi.cpp:292
#define ERR_LUA
#define lua_isfunction(L, n)
Definition: lua.h:372
#define lua_tostring(L, i)
Definition: lua.h:386
const std::string get_value() const
#define LUA_REGISTRYINDEX
Definition: lua.h:44
std::vector< std::string > split(const config_attribute_value &val)
Standard logging facilities (interface).
LUALIB_API void luaL_unref(lua_State *L, int t, int ref)
Definition: lauxlib.cpp:667
retval
Default window/dialog return values.
Definition: retval.hpp:29
bool valid() const
Definition: map.hpp:274
static map_location::DIRECTION n
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:489
#define LUA_REFNIL
Definition: lauxlib.h:86