The Battle for Wesnoth  1.17.23+dev
lua_race.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2023
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/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) {
75  luaL_getmetatable(L, Gen);
76  lua_setmetatable(L, -2);
77  return 1;
78  }
79  if (strcmp(m, "female_name_gen") == 0) {
81  luaL_getmetatable(L, Gen);
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  */
92 static int impl_race_tostring(lua_State* L)
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  {
105  luaL_newmetatable(L, Race);
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");
126  luaL_setmetatable(L, Race);
127 }
128 
129 void luaW_pushracetable(lua_State *L)
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 }
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:161
const std::string & id() const
Definition: race.hpp:35
bool uses_global_traits() const
Definition: race.cpp:124
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:139
const config::const_child_itors & additional_traits() const
Definition: race.cpp:129
const name_generator & generator(GENDER gender) const
Definition: race.cpp:119
@ FEMALE
Definition: race.hpp:27
@ MALE
Definition: race.hpp:27
const race_map & races() const
Definition: types.hpp:397
const unit_race * find_race(const std::string &) const
Definition: types.cpp:1350
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:830
#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:43
static int impl_race_tostring(lua_State *L)
Turns a lua proxy race to string.
Definition: lua_race.cpp:92
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
void luaW_pushrace(lua_State *L, const unit_race &race)
Definition: lua_race.cpp:121
void luaW_pushracetable(lua_State *L)
Definition: lua_race.cpp:129
const unit_race & luaW_checkrace(lua_State *L, int idx)
Definition: lua_race.cpp:142
static const char * Gen
Definition: lua_race.cpp:35
This namespace contains bindings for lua to hold a pointer to a race, and to access and modify it.
Definition: lua_race.cpp:101
std::string register_metatable(lua_State *L)
Definition: lua_race.cpp:103
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:103
unit_type_data unit_types
Definition: types.cpp:1465