The Battle for Wesnoth  1.15.0-dev
lua_team.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2018 by Chris Beck <render787@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "scripting/lua_team.hpp"
16 
17 #include "scripting/lua_common.hpp"
19 #include "team.hpp"
20 #include "resources.hpp" // for gameboard
21 #include "game_board.hpp"
22 #include "game_display.hpp"
23 
24 #include <string>
25 
26 #include "lua/lua.h"
27 #include "lua/lauxlib.h"
28 
29 /**
30  * Implementation for a lua reference to a team,
31  * used by the wesnoth in-game sides table.
32  *
33  * (The userdata has type team** because lua holds
34  * only a pointer to a team, not a full-size team.
35  * If it were a full object then we would cast to
36  * type team *, since checkudata returns a pointer
37  * to the type corresponding to the sizeof expr
38  * used when we allocated the userdata.)
39  */
40 
41 // Registry key
42 static const char * Team = "side";
43 
44 /**
45  * Gets some data on a side (__index metamethod).
46  * - Arg 1: full userdata containing the team.
47  * - Arg 2: string containing the name of the property.
48  * - Ret 1: something containing the attribute.
49  */
50 static int impl_side_get(lua_State *L)
51 {
52  // Hidden metamethod, so arg1 has to be a pointer to a team.
53  team &t = luaW_checkteam(L, 1);
54  char const *m = luaL_checkstring(L, 2);
55 
56  // Find the corresponding attribute.
57  return_int_attrib("side", t.side());
58  return_string_attrib("save_id", t.save_id());
59  return_int_attrib("gold", t.gold());
60  return_tstring_attrib("objectives", t.objectives());
61  return_int_attrib("village_gold", t.village_gold());
62  return_int_attrib("village_support", t.village_support());
63  return_int_attrib("recall_cost", t.recall_cost());
64  return_int_attrib("base_income", t.base_income());
65  return_int_attrib("total_income", t.total_income());
66  return_bool_attrib("objectives_changed", t.objectives_changed());
67  return_bool_attrib("fog", t.uses_fog());
68  return_bool_attrib("shroud", t.uses_shroud());
69  return_bool_attrib("hidden", t.hidden());
70  return_bool_attrib("scroll_to_leader", t.get_scroll_to_leader());
71  return_string_attrib("flag", t.flag().empty() ? game_config::images::flag : t.flag());
73  return_tstring_attrib("user_team_name", t.user_team_name());
74  return_string_attrib("team_name", t.team_name());
75  return_string_attrib("faction", t.faction());
76  return_tstring_attrib("faction_name", t.faction_name());
77  return_string_attrib("color", t.color());
78  return_cstring_attrib("controller", t.controller().to_string().c_str());
79  return_bool_attrib("is_local", t.is_local());
80  return_string_attrib("defeat_condition", t.defeat_condition().to_string());
81  return_string_attrib("share_vision", t.share_vision().to_string());
82  return_float_attrib("carryover_bonus", t.carryover_bonus());
83  return_int_attrib("carryover_percentage", t.carryover_percentage());
84  return_bool_attrib("carryover_add", t.carryover_add());
85  return_bool_attrib("lost", t.lost());
86  return_bool_attrib("persistent", t.persistent());
87  return_bool_attrib("suppress_end_turn_confirmation", t.no_turn_confirmation());
88  return_string_attrib("share_vision", t.share_vision().to_string());
89  return_bool_attrib("share_maps", t.share_maps());
90  return_bool_attrib("share_view", t.share_view());
91  return_bool_attrib("chose_random", t.chose_random());
92  return_tstring_attrib("side_name", t.side_name_tstr());
93 
94  if (strcmp(m, "recruit") == 0) {
95  const std::set<std::string>& recruits = t.recruits();
96  lua_createtable(L, recruits.size(), 0);
97  int i = 1;
98  for (const std::string& r : t.recruits()) {
99  lua_pushstring(L, r.c_str());
100  lua_rawseti(L, -2, i++);
101  }
102  return 1;
103  }
104 
105  // These are blocked together because they are all part of the team_data struct.
106  // Some of these values involve iterating over the units map to calculate them.
107  auto d = [&](){ return resources::gameboard->calculate_team_data(t); };
108  return_int_attrib("num_units", d().units);
109  return_int_attrib("total_upkeep", d().upkeep);
110  return_int_attrib("num_villages", d().villages);
111  return_int_attrib("expenses", d().expenses);
112  return_int_attrib("net_income", d().net_income);
113 
114  return_cfg_attrib("__cfg", t.write(cfg));
115  if(luaW_getmetafield(L, 1, m)) {
116  return 1;
117  }
118  return 0;
119 }
120 
121 /**
122  * Sets some data on a side (__newindex metamethod).
123  * - Arg 1: full userdata containing the team.
124  * - Arg 2: string containing the name of the property.
125  * - Arg 3: something containing the attribute.
126  */
127 static int impl_side_set(lua_State *L)
128 {
129  // Hidden metamethod, so arg1 has to be a pointer to a team.
130  team &t = luaW_checkteam(L, 1);
131  char const *m = luaL_checkstring(L, 2);
132 
133  // Find the corresponding attribute.
134  modify_int_attrib("gold", t.set_gold(value));
135  modify_tstring_attrib("objectives", t.set_objectives(value, true));
136  //maybe add a setter for save_id too?
137  modify_int_attrib("village_gold", t.set_village_gold(value));
138  modify_int_attrib("village_support", t.set_village_support(value));
139  modify_int_attrib("recall_cost", t.set_recall_cost(value));
140  modify_int_attrib("base_income", t.set_base_income(value));
141  modify_bool_attrib("objectives_changed", t.set_objectives_changed(value));
142  modify_bool_attrib("hidden", t.set_hidden(value));
143  modify_bool_attrib("scroll_to_leader", t.set_scroll_to_leader(value));
144  modify_tstring_attrib("user_team_name", t.change_team(t.team_name(), value));
145  modify_string_attrib("team_name", t.change_team(value, t.user_team_name()));
146  modify_string_attrib("controller", t.change_controller_by_wml(value));
147  modify_string_attrib("color", {
148  auto* disp = lua_kernel_base::get_lua_kernel<game_lua_kernel>(L).get_display();
149  t.set_color(value);
150  if(disp) {
151  disp->reinit_flags_for_side(t.side());
152  }
153  });
154  modify_string_attrib("defeat_condition", t.set_defeat_condition_string(value));
155  modify_int_attrib("carryover_percentage", t.set_carryover_percentage(value));
156  modify_bool_attrib("carryover_add", t.set_carryover_add(value));
157  modify_bool_attrib("lost", t.set_lost(value));
158  modify_bool_attrib("persistent", t.set_persistent(value));
159  modify_bool_attrib("suppress_end_turn_confirmation", t.set_no_turn_confirmation(value));
160  modify_bool_attrib("shroud", t.set_shroud(value));
161  modify_bool_attrib("fog", t.set_fog(value));
162  modify_string_attrib("flag_icon", t.set_flag_icon(value));
163  modify_tstring_attrib("side_name", t.set_side_name(value));
164  modify_string_attrib("share_vision", {
165  team::SHARE_VISION v;
166  if(v.parse(value)) {
167  t.set_share_vision(v);
168  } else {
169  return luaL_argerror(L, 3, "Invalid share_vision value (should be 'all', 'none', or 'shroud')");
170  }
171  });
172 
173  if (strcmp(m, "carryover_bonus") == 0) {
175  return 0;
176  }
177 
178  if (strcmp(m, "recruit") == 0) {
179  t.set_recruits(std::set<std::string>());
180  if (!lua_istable(L, 3)) return 0;
181  for (int i = 1;; ++i) {
182  lua_rawgeti(L, 3, i);
183  if (lua_isnil(L, -1)) break;
184  t.add_recruit(lua_tostring(L, -1));
185  lua_pop(L, 1);
186  }
187  return 0;
188  }
189 
190  std::string err_msg = "unknown modifiable property of side: ";
191  err_msg += m;
192  return luaL_argerror(L, 2, err_msg.c_str());
193 }
194 
196 {
197  // Hidden metamethod, so arg1 has to be a pointer to a team.
198  team &t1 = luaW_checkteam(L, 1);
199  if(team* t2 = luaW_toteam(L, 2)) {
200  lua_pushboolean(L, t1.side() == t2->side());
201  } else {
202  lua_pushboolean(L, false);
203  }
204  return 1;
205 }
206 
207 namespace lua_team {
208 
209  std::string register_metatable(lua_State * L)
210  {
212 
213  static luaL_Reg const callbacks[] {
214  { "__index", &impl_side_get},
215  { "__newindex", &impl_side_set},
216  { "__eq", &impl_side_equal},
217  { nullptr, nullptr }
218  };
219  luaL_setfuncs(L, callbacks, 0);
220 
221  lua_pushstring(L, Team);
222  lua_setfield(L, -2, "__metatable");
223  // Side methods
224  luaW_getglobal(L, "wesnoth", "match_side");
225  lua_setfield(L, -2, "matches");
226 
227  return "Adding getside metatable...\n";
228  }
229 }
230 
232 {
233  team** t = static_cast<team**>(lua_newuserdata(L, sizeof(team*)));
234  *t = &tm;
236 }
237 
239 {
240  return **static_cast<team **>(luaL_checkudata(L, idx, Team));
241 }
242 
244 {
245  if(void* p = luaL_testudata(L, idx, Team)) {
246  return *static_cast<team **>(p);
247  }
248  return nullptr;
249 }
#define modify_bool_attrib(name, accessor)
Definition: lua_common.hpp:339
bool no_turn_confirmation() const
Definition: team.hpp:363
LUALIB_API void * luaL_checkudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.cpp:333
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:684
void set_shroud(bool shroud)
Definition: team.hpp:324
#define return_tstring_attrib(name, accessor)
Definition: lua_common.hpp:201
LUALIB_API lua_Number luaL_checknumber(lua_State *L, int arg)
Definition: lauxlib.cpp:408
void set_side_name(const t_string &new_name)
Definition: team.hpp:308
team & luaW_checkteam(lua_State *L, int idx)
Test if the top stack element is a team, and if not, error.
Definition: lua_team.cpp:238
void set_carryover_add(bool value)
Definition: team.hpp:354
void luaW_pushteam(lua_State *L, team &tm)
Create a full userdata containing a pointer to the team.
Definition: lua_team.cpp:231
bool persistent() const
Definition: team.hpp:347
void set_objectives(const t_string &new_objectives, bool silently=false)
Definition: team.cpp:635
LUA_API void lua_pushboolean(lua_State *L, int b)
Definition: lapi.cpp:557
LUA_API int lua_rawgeti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:658
t_string side_name_tstr() const
Definition: team.hpp:307
This namespace contains bindings for lua to hold a pointer to a team, and to access and modify it...
Definition: lua_team.cpp:207
const std::string & flag() const
Definition: team.hpp:300
bool carryover_add() const
Definition: team.hpp:355
bool share_view() const
Definition: team.hpp:390
LUA_API void lua_rawseti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:817
bool objectives_changed() const
Definition: team.hpp:241
#define return_string_attrib(name, accessor)
Definition: lua_common.hpp:217
void set_recall_cost(int cost)
Definition: team.hpp:195
const std::string & save_id() const
Definition: team.hpp:231
#define d
void set_persistent(bool value)
Definition: team.hpp:348
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:312
void set_defeat_condition_string(const std::string &value)
sets the defeat condition if
Definition: team.hpp:343
void add_recruit(const std::string &)
Definition: team.cpp:477
-file sdl_utils.hpp
void set_share_vision(const std::string &vision_status)
Definition: team.hpp:393
void set_hidden(bool value)
Definition: team.hpp:346
double carryover_bonus() const
Definition: team.hpp:357
void set_carryover_percentage(int value)
Definition: team.hpp:352
int village_support() const
Definition: team.hpp:199
LUA_API void * lua_newuserdata(lua_State *L, size_t size)
Definition: lapi.cpp:1184
const std::string & faction() const
Definition: team.hpp:309
static const char * Team
Implementation for a lua reference to a team, used by the wesnoth in-game sides table.
Definition: lua_team.cpp:42
void set_scroll_to_leader(bool value)
Definition: team.hpp:221
#define lua_pop(L, n)
Definition: lua.h:344
std::string flag_icon
bool uses_fog() const
Definition: team.hpp:317
int gold() const
Definition: team.hpp:189
int village_gold() const
Definition: team.hpp:192
void set_no_turn_confirmation(bool value)
Definition: team.hpp:364
std::string register_metatable(lua_State *L)
Definition: lua_team.cpp:209
void write(config &cfg) const
Definition: team.cpp:403
This class stores all the data for a single &#39;side&#39; (in game nomenclature).
Definition: team.hpp:44
SHARE_VISION share_vision() const
Definition: team.hpp:391
#define modify_tstring_attrib(name, accessor)
Definition: lua_common.hpp:283
void set_carryover_bonus(double value)
Definition: team.hpp:356
LUALIB_API int luaL_argerror(lua_State *L, int arg, const char *extramsg)
Definition: lauxlib.cpp:164
#define modify_string_attrib(name, accessor)
Definition: lua_common.hpp:292
#define return_int_attrib(name, accessor)
Definition: lua_common.hpp:226
bool luaW_getglobal(lua_State *L, const std::vector< std::string > &path)
Pushes the value found by following the variadic names (char *), if the value is not nil...
Definition: lua_common.cpp:851
static int impl_side_equal(lua_State *L)
Definition: lua_team.cpp:195
team_data calculate_team_data(const class team &tm) const
bool uses_shroud() const
Definition: team.hpp:316
int carryover_percentage() const
Definition: team.hpp:353
void set_lost(bool value=true)
Definition: team.hpp:349
game_board * gameboard
Definition: resources.cpp:20
const t_string & faction_name() const
Definition: team.hpp:310
void set_village_support(int support)
Definition: team.hpp:201
bool chose_random() const
Definition: team.hpp:410
LUALIB_API void * luaL_testudata(lua_State *L, int ud, const char *tname)
Definition: lauxlib.cpp:318
void set_fog(bool fog)
Definition: team.hpp:325
bool hidden() const
Definition: team.hpp:345
int recall_cost() const
Definition: team.hpp:193
void set_village_gold(int income)
Definition: team.hpp:194
#define return_cfg_attrib(name, accessor)
Definition: lua_common.hpp:250
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:299
#define lua_isnil(L, n)
Definition: lua.h:355
std::size_t i
Definition: function.cpp:933
void set_gold(int amount)
Definition: team.hpp:206
static int impl_side_set(lua_State *L)
Sets some data on a side (__newindex metamethod).
Definition: lua_team.cpp:127
mock_party p
const std::string & flag_icon() const
Definition: team.hpp:301
const t_string & objectives() const
Definition: team.hpp:240
#define lua_tostring(L, i)
Definition: lua.h:366
DEFEAT_CONDITION defeat_condition() const
Definition: team.hpp:340
void set_flag_icon(const std::string &flag_icon)
Definition: team.hpp:304
void set_objectives_changed(bool c=true) const
Definition: team.hpp:237
void change_controller_by_wml(const std::string &new_controller)
Definition: team.cpp:583
bool is_local() const
Definition: team.hpp:260
team * luaW_toteam(lua_State *L, int idx)
Test if the top stack element is a team, and if so, return it.
Definition: lua_team.cpp:243
bool get_scroll_to_leader() const
Definition: team.hpp:220
#define return_bool_attrib(name, accessor)
Definition: lua_common.hpp:242
bool luaW_getmetafield(lua_State *L, int idx, const char *key)
Like luaL_getmetafield, but returns false if key is an empty string or begins with two underscores...
Definition: lua_common.cpp:494
const std::string & color() const
Definition: team.hpp:256
bool share_maps() const
Definition: team.hpp:389
double t
Definition: astarsearch.cpp:64
#define lua_istable(L, n)
Definition: lua.h:353
#define return_float_attrib(name, accessor)
Definition: lua_common.hpp:234
static int impl_side_get(lua_State *L)
Gets some data on a side (__index metamethod).
Definition: lua_team.cpp:50
void change_team(const std::string &name, const t_string &user_name)
Definition: team.cpp:610
int base_income() const
Definition: team.hpp:191
void set_base_income(int amount)
Definition: team.hpp:209
void set_recruits(const std::set< std::string > &recruits)
Definition: team.cpp:470
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
Definition: lauxlib.cpp:934
int side() const
Definition: team.hpp:188
int total_income() const
Definition: team.hpp:196
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:491
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:777
bool lost() const
Definition: team.hpp:350
const std::string & team_name() const
Definition: team.hpp:296
const t_string & user_team_name() const
Definition: team.hpp:297
const std::set< std::string > & recruits() const
Definition: team.hpp:223
#define modify_int_attrib(name, accessor)
Definition: lua_common.hpp:301
void set_color(const std::string &color)
Definition: team.hpp:257
#define return_cstring_attrib(name, accessor)
Definition: lua_common.hpp:209
#define luaL_checkstring(L, n)
Definition: lauxlib.h:124
CONTROLLER controller() const
Definition: team.hpp:255