The Battle for Wesnoth  1.19.2+dev
lua_race.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2024
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 
27 /**
28  * Implementation for a lua reference to a race,
29  * used by the wesnoth in-game races table.
30  */
31 
32 // Registry key
33 static const char * Race = "race";
34 static const char * Gen = "name generator";
35 
36 /**
37  * Gets some data on a race (__index metamethod).
38  * - Arg 1: table containing an "id" field.
39  * - Arg 2: string containing the name of the property.
40  * - Ret 1: something containing the attribute.
41  */
42 static int impl_race_get(lua_State* L)
43 {
44  const unit_race& race = luaW_checkrace(L, 1);
45  char const* m = luaL_checkstring(L, 2);
46 
47  return_tstring_attrib("description", race.description());
48  return_tstring_attrib("name", race.name());
49  return_int_attrib("num_traits", race.num_traits());
50  return_tstring_attrib("plural_name", race.plural_name());
51  return_bool_attrib("ignore_global_traits", !race.uses_global_traits());
52  return_string_attrib("undead_variation", race.undead_variation());
53  return_cfgref_attrib("__cfg", race.get_cfg());
54  if (strcmp(m, "traits") == 0) {
55  lua_newtable(L);
56  if (race.uses_global_traits()) {
57  for (const config& trait : unit_types.traits()) {
58  const std::string& id = trait["id"];
59  lua_pushlstring(L, id.c_str(), id.length());
60  luaW_pushconfig(L, trait);
61  lua_rawset(L, -3);
62  }
63  }
64  for (const config& trait : race.additional_traits()) {
65  const std::string& id = trait["id"];
66  lua_pushlstring(L, id.c_str(), id.length());
67  luaW_pushconfig(L, trait);
68  lua_rawset(L, -3);
69  }
70  return 1;
71  }
72  if (strcmp(m, "male_name_gen") == 0) {
74  luaL_getmetatable(L, Gen);
75  lua_setmetatable(L, -2);
76  return 1;
77  }
78  if (strcmp(m, "female_name_gen") == 0) {
80  luaL_getmetatable(L, Gen);
81  lua_setmetatable(L, -2);
82  return 1;
83  }
84 
85  return 0;
86 }
87 
88 /**
89  * Turns a lua proxy race to string. (__tostring metamethod)
90  */
91 static int impl_race_tostring(lua_State* L)
92 {
93  const unit_race& race = luaW_checkrace(L, 1);
94  std::ostringstream str;
95  str << "race: <" << race.id() << '>';
96  lua_push(L, str.str());
97  return 1;
98 }
99 
100 namespace lua_race {
101 
102  std::string register_metatable(lua_State * L)
103  {
104  luaL_newmetatable(L, Race);
105 
106  static luaL_Reg const callbacks[] {
107  { "__index", &impl_race_get},
108  { "__tostring", &impl_race_tostring},
109  { nullptr, nullptr }
110  };
111  luaL_setfuncs(L, callbacks, 0);
112 
113  lua_pushstring(L, "race");
114  lua_setfield(L, -2, "__metatable");
115 
116  return "Adding getrace metatable...\n";
117  }
118 }
119 
120 void luaW_pushrace(lua_State *L, const unit_race & race)
121 {
122  lua_createtable(L, 0, 1);
123  lua_pushstring(L, race.id().c_str());
124  lua_setfield(L, -2, "id");
125  luaL_setmetatable(L, Race);
126 }
127 
128 void luaW_pushracetable(lua_State *L)
129 {
130  const race_map& races = unit_types.races();
131  lua_createtable(L, 0, races.size());
132 
133  for (const race_map::value_type &race : races)
134  {
135  assert(race.first == race.second.id());
136  luaW_pushrace(L, race.second);
137  lua_setfield(L, -2, race.first.c_str());
138  }
139 }
140 
141 const unit_race& luaW_checkrace(lua_State* L, int idx)
142 {
143  lua_pushstring(L, "id");
144  lua_rawget(L, idx);
145  const unit_race* raceptr = unit_types.find_race(lua_tostring(L, -1));
146  if(!raceptr) {
147  luaL_argerror(L, idx, "unknown race");
148  throw "UNREACHABLE";
149  }
150  return *raceptr;
151 }
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
const std::string & id() const
Definition: race.hpp:36
bool uses_global_traits() const
Definition: race.cpp:122
const t_string & name(GENDER gender=MALE) const
Definition: race.hpp:38
const std::string & undead_variation() const
Definition: race.hpp:50
const t_string & plural_name() const
Definition: race.hpp:39
const t_string & description() const
Definition: race.hpp:40
const config & get_cfg() const
Definition: race.hpp:35
unsigned int num_traits() const
Definition: race.cpp:137
const config::const_child_itors & additional_traits() const
Definition: race.cpp:127
const name_generator & generator(GENDER gender) const
Definition: race.cpp:117
@ FEMALE
Definition: race.hpp:28
@ MALE
Definition: race.hpp:28
const race_map & races() const
Definition: types.hpp:396
const unit_race * find_race(const std::string &) const
Definition: types.cpp:1371
config_array_view traits() const
Definition: types.hpp:398
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:824
#define return_string_attrib(name, accessor)
Definition: lua_common.hpp:256
#define return_cfgref_attrib(name, accessor)
Definition: lua_common.hpp:309
#define return_int_attrib(name, accessor)
Definition: lua_common.hpp:267
#define return_bool_attrib(name, accessor)
Definition: lua_common.hpp:287
#define return_tstring_attrib(name, accessor)
Definition: lua_common.hpp:236
static int impl_race_get(lua_State *L)
Gets some data on a race (__index metamethod).
Definition: lua_race.cpp:42
static int impl_race_tostring(lua_State *L)
Turns a lua proxy race to string.
Definition: lua_race.cpp:91
static const char * Race
Implementation for a lua reference to a race, used by the wesnoth in-game races table.
Definition: lua_race.cpp:33
void luaW_pushrace(lua_State *L, const unit_race &race)
Definition: lua_race.cpp:120
void luaW_pushracetable(lua_State *L)
Definition: lua_race.cpp:128
const unit_race & luaW_checkrace(lua_State *L, int idx)
Definition: lua_race.cpp:141
static const char * Gen
Definition: lua_race.cpp:34
This namespace contains bindings for lua to hold a pointer to a race, and to access and modify it.
Definition: lua_race.cpp:100
std::string register_metatable(lua_State *L)
Definition: lua_race.cpp:102
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:373
std::map< std::string, unit_race > race_map
Definition: race.hpp:105
unit_type_data unit_types
Definition: types.cpp:1486