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