The Battle for Wesnoth  1.19.10+dev
lua_race.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2025
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("male_name", race.name(unit_race::GENDER::MALE));
51  return_tstring_attrib("female_name", race.name(unit_race::GENDER::FEMALE));
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) {
76  luaL_getmetatable(L, Gen);
77  lua_setmetatable(L, -2);
78  return 1;
79  }
80  if (strcmp(m, "female_name_gen") == 0) {
82  luaL_getmetatable(L, Gen);
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  */
93 static int impl_race_tostring(lua_State* L)
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  {
106  luaL_newmetatable(L, Race);
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");
127  luaL_setmetatable(L, Race);
128 }
129 
130 void luaW_pushracetable(lua_State *L)
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 }
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
const std::string & id() const
Definition: race.hpp:35
bool uses_global_traits() const
Definition: race.cpp:120
const t_string & name(GENDER gender=MALE) const
Definition: race.hpp:37
const std::string & undead_variation() const
Definition: race.hpp:49
const t_string & plural_name() const
Definition: race.hpp:38
const t_string & description() const
Definition: race.hpp:39
const config & get_cfg() const
Definition: race.hpp:34
unsigned int num_traits() const
Definition: race.cpp:135
const config::const_child_itors & additional_traits() const
Definition: race.cpp:125
const name_generator & generator(GENDER gender) const
Definition: race.cpp:115
@ FEMALE
Definition: race.hpp:28
@ MALE
Definition: race.hpp:28
const race_map & races() const
Definition: types.hpp:406
const unit_race * find_race(const std::string &) const
Definition: types.cpp:1369
config_array_view traits() const
Definition: types.hpp:408
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:905
#define return_string_attrib(name, accessor)
Definition: lua_common.hpp:266
#define return_cfgref_attrib(name, accessor)
Definition: lua_common.hpp:319
#define return_int_attrib(name, accessor)
Definition: lua_common.hpp:277
#define return_bool_attrib(name, accessor)
Definition: lua_common.hpp:297
#define return_tstring_attrib(name, accessor)
Definition: lua_common.hpp:246
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:93
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:122
void luaW_pushracetable(lua_State *L)
Definition: lua_race.cpp:130
const unit_race & luaW_checkrace(lua_State *L, int idx)
Definition: lua_race.cpp:143
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:102
std::string register_metatable(lua_State *L)
Definition: lua_race.cpp:104
void lua_push(lua_State *L, const T &val)
Definition: push_check.hpp:425
std::map< std::string, unit_race > race_map
Definition: race.hpp:104
unit_type_data unit_types
Definition: types.cpp:1504