The Battle for Wesnoth  1.17.0-dev
lua_race.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2021
3  by Chris Beck <render787@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 
16 #include "scripting/lua_race.hpp"
17 
18 #include "units/race.hpp"
19 #include "scripting/lua_common.hpp"
20 #include "scripting/push_check.hpp"
21 #include "units/types.hpp"
22 
23 #include <string>
24 #include <cstring>
25 
26 #include "lua/lua.h"
27 #include "lua/lauxlib.h"
28 
29 /**
30  * Implementation for a lua reference to a race,
31  * used by the wesnoth in-game races table.
32  */
33 
34 // Registry key
35 static const char * Race = "race";
36 static const char * Gen = "name generator";
37 
38 /**
39  * Gets some data on a race (__index metamethod).
40  * - Arg 1: table containing an "id" field.
41  * - Arg 2: string containing the name of the property.
42  * - Ret 1: something containing the attribute.
43  */
44 static int impl_race_get(lua_State* L)
45 {
46  const unit_race& race = luaW_checkrace(L, 1);
47  char const* m = luaL_checkstring(L, 2);
48 
49  return_tstring_attrib("description", race.description());
50  return_tstring_attrib("name", race.name());
51  return_int_attrib("num_traits", race.num_traits());
52  return_tstring_attrib("plural_name", race.plural_name());
53  return_bool_attrib("ignore_global_traits", !race.uses_global_traits());
54  return_string_attrib("undead_variation", race.undead_variation());
55  return_cfgref_attrib("__cfg", race.get_cfg());
56  if (strcmp(m, "traits") == 0) {
57  lua_newtable(L);
58  if (race.uses_global_traits()) {
59  for (const config& trait : unit_types.traits()) {
60  const std::string& id = trait["id"];
61  lua_pushlstring(L, id.c_str(), id.length());
62  luaW_pushconfig(L, trait);
63  lua_rawset(L, -3);
64  }
65  }
66  for (const config& trait : race.additional_traits()) {
67  const std::string& id = trait["id"];
68  lua_pushlstring(L, id.c_str(), id.length());
69  luaW_pushconfig(L, trait);
70  lua_rawset(L, -3);
71  }
72  return 1;
73  }
74  if (strcmp(m, "male_name_gen") == 0) {
77  lua_setmetatable(L, -2);
78  return 1;
79  }
80  if (strcmp(m, "female_name_gen") == 0) {
83  lua_setmetatable(L, -2);
84  return 1;
85  }
86 
87  return 0;
88 }
89 
90 /**
91  * Turns a lua proxy race to string. (__tostring metamethod)
92  */
94 {
95  const unit_race& race = luaW_checkrace(L, 1);
96  std::ostringstream str;
97  str << "race: <" << race.id() << '>';
98  lua_push(L, str.str());
99  return 1;
100 }
101 
102 namespace lua_race {
103 
104  std::string register_metatable(lua_State * L)
105  {
107 
108  static luaL_Reg const callbacks[] {
109  { "__index", &impl_race_get},
110  { "__tostring", &impl_race_tostring},
111  { nullptr, nullptr }
112  };
113  luaL_setfuncs(L, callbacks, 0);
114 
115  lua_pushstring(L, "race");
116  lua_setfield(L, -2, "__metatable");
117 
118  return "Adding getrace metatable...\n";
119  }
120 }
121 
122 void luaW_pushrace(lua_State *L, const unit_race & race)
123 {
124  lua_createtable(L, 0, 1);
125  lua_pushstring(L, race.id().c_str());
126  lua_setfield(L, -2, "id");
128 }
129 
131 {
132  const race_map& races = unit_types.races();
133  lua_createtable(L, 0, races.size());
134 
135  for (const race_map::value_type &race : races)
136  {
137  assert(race.first == race.second.id());
138  luaW_pushrace(L, race.second);
139  lua_setfield(L, -2, race.first.c_str());
140  }
141 }
142 
143 const unit_race& luaW_checkrace(lua_State* L, int idx)
144 {
145  lua_pushstring(L, "id");
146  lua_rawget(L, idx);
147  const unit_race* raceptr = unit_types.find_race(lua_tostring(L, -1));
148  if(!raceptr) {
149  luaL_argerror(L, idx, "unknown race");
150  throw "UNREACHABLE";
151  }
152  return *raceptr;
153 }
LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
Definition: lapi.cpp:728
#define return_tstring_attrib(name, accessor)
Definition: lua_common.hpp:236
void luaW_pushconfig(lua_State *L, const config &cfg)
Converts a config object to a Lua table pushed at the top of the stack.
Definition: lua_common.cpp:812
config_array_view traits() const
Definition: types.hpp:400
const std::string & id() const
Definition: race.hpp:35
const name_generator & generator(GENDER gender) const
Definition: race.cpp:116
#define return_string_attrib(name, accessor)
Definition: lua_common.hpp:256
LUA_API int lua_rawget(lua_State *L, int idx)
Definition: lapi.cpp:698
unit_type_data unit_types
Definition: types.cpp:1481
#define luaL_getmetatable(L, n)
Definition: lauxlib.h:149
const t_string & description() const
Definition: race.hpp:39
const race_map & races() const
Definition: types.hpp:399
LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:324
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:385
const unit_race & luaW_checkrace(lua_State *L, int idx)
Definition: lua_race.cpp:143
const t_string & name(GENDER gender=MALE) const
Definition: race.hpp:37
#define return_cfgref_attrib(name, accessor)
Definition: lua_common.hpp:309
static int impl_race_tostring(lua_State *L)
Turns a lua proxy race to string.
Definition: lua_race.cpp:93
LUALIB_API int luaL_argerror(lua_State *L, int arg, const char *extramsg)
Definition: lauxlib.cpp:175
#define return_int_attrib(name, accessor)
Definition: lua_common.hpp:267
This namespace contains bindings for lua to hold a pointer to a race, and to access and modify it...
Definition: lua_race.cpp:102
const t_string & plural_name() const
Definition: race.hpp:38
LUA_API const char * lua_pushlstring(lua_State *L, const char *s, size_t len)
Definition: lapi.cpp:502
LUA_API int lua_setmetatable(lua_State *L, int objindex)
Definition: lapi.cpp:901
const config::const_child_itors & additional_traits() const
Definition: race.cpp:126
static const char * Race
Implementation for a lua reference to a race, used by the wesnoth in-game races table.
Definition: lua_race.cpp:35
#define lua_newtable(L)
Definition: lua.h:366
unsigned int num_traits() const
Definition: race.cpp:136
LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname)
Definition: lauxlib.cpp:311
const config & get_cfg() const
Definition: race.hpp:34
const unit_race * find_race(const std::string &) const
Definition: types.cpp:1368
void luaW_pushracetable(lua_State *L)
Definition: lua_race.cpp:130
static int impl_race_get(lua_State *L)
Gets some data on a race (__index metamethod).
Definition: lua_race.cpp:44
LUA_API void lua_rawset(lua_State *L, int idx)
Definition: lapi.cpp:877
bool uses_global_traits() const
Definition: race.cpp:121
#define lua_tostring(L, i)
Definition: lua.h:386
std::string register_metatable(lua_State *L)
Definition: lua_race.cpp:104
void luaW_pushrace(lua_State *L, const unit_race &race)
Definition: lua_race.cpp:122
#define return_bool_attrib(name, accessor)
Definition: lua_common.hpp:287
static const char * Gen
Definition: lua_race.cpp:36
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
Definition: lauxlib.cpp:904
std::map< std::string, unit_race > race_map
Definition: race.hpp:95
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:61
const std::string & undead_variation() const
Definition: race.hpp:49
LUA_API const char * lua_pushstring(lua_State *L, const char *s)
Definition: lapi.cpp:514
LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
Definition: lapi.cpp:837
#define luaL_checkstring(L, n)
Definition: lauxlib.h:138