forked from Mirrorlandia_minetest/minetest
Genericize find_node_near and find_node_in implementations in C++
This commit is contained in:
parent
20b10b5691
commit
62629939ff
@ -46,14 +46,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "client/client.h"
|
#include "client/client.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const EnumString ModApiEnvMod::es_ClearObjectsMode[] =
|
const EnumString ModApiEnvBase::es_ClearObjectsMode[] =
|
||||||
{
|
{
|
||||||
{CLEAR_OBJECTS_MODE_FULL, "full"},
|
{CLEAR_OBJECTS_MODE_FULL, "full"},
|
||||||
{CLEAR_OBJECTS_MODE_QUICK, "quick"},
|
{CLEAR_OBJECTS_MODE_QUICK, "quick"},
|
||||||
{0, NULL},
|
{0, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
const EnumString ModApiEnvMod::es_BlockStatusType[] =
|
const EnumString ModApiEnvBase::es_BlockStatusType[] =
|
||||||
{
|
{
|
||||||
{ServerEnvironment::BS_UNKNOWN, "unknown"},
|
{ServerEnvironment::BS_UNKNOWN, "unknown"},
|
||||||
{ServerEnvironment::BS_EMERGING, "emerging"},
|
{ServerEnvironment::BS_EMERGING, "emerging"},
|
||||||
@ -796,7 +796,7 @@ int ModApiEnvMod::l_get_gametime(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModApiEnvMod::collectNodeIds(lua_State *L, int idx, const NodeDefManager *ndef,
|
void ModApiEnvBase::collectNodeIds(lua_State *L, int idx, const NodeDefManager *ndef,
|
||||||
std::vector<content_t> &filter)
|
std::vector<content_t> &filter)
|
||||||
{
|
{
|
||||||
if (lua_istable(L, idx)) {
|
if (lua_istable(L, idx)) {
|
||||||
@ -809,10 +809,28 @@ void ModApiEnvMod::collectNodeIds(lua_State *L, int idx, const NodeDefManager *n
|
|||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
} else if (lua_isstring(L, idx)) {
|
} else if (lua_isstring(L, idx)) {
|
||||||
ndef->getIds(readParam<std::string>(L, 3), filter);
|
ndef->getIds(readParam<std::string>(L, idx), filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
int ModApiEnvBase::findNodeNear(lua_State *L, v3s16 pos, int radius,
|
||||||
|
const std::vector<content_t> &filter, int start_radius, F &&getNode)
|
||||||
|
{
|
||||||
|
for (int d = start_radius; d <= radius; d++) {
|
||||||
|
const std::vector<v3s16> &list = FacePositionCache::getFacePositions(d);
|
||||||
|
for (const v3s16 &i : list) {
|
||||||
|
v3s16 p = pos + i;
|
||||||
|
content_t c = getNode(p).getContent();
|
||||||
|
if (CONTAINS(filter, c)) {
|
||||||
|
push_v3s16(L, p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// find_node_near(pos, radius, nodenames, [search_center]) -> pos or nil
|
// find_node_near(pos, radius, nodenames, [search_center]) -> pos or nil
|
||||||
// nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
|
// nodenames: eg. {"ignore", "group:tree"} or "default:dirt"
|
||||||
int ModApiEnvMod::l_find_node_near(lua_State *L)
|
int ModApiEnvMod::l_find_node_near(lua_State *L)
|
||||||
@ -835,21 +853,13 @@ int ModApiEnvMod::l_find_node_near(lua_State *L)
|
|||||||
radius = client->CSMClampRadius(pos, radius);
|
radius = client->CSMClampRadius(pos, radius);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int d = start_radius; d <= radius; d++) {
|
auto getNode = [&map] (v3s16 p) -> MapNode {
|
||||||
const std::vector<v3s16> &list = FacePositionCache::getFacePositions(d);
|
return map.getNode(p);
|
||||||
for (const v3s16 &i : list) {
|
};
|
||||||
v3s16 p = pos + i;
|
return findNodeNear(L, pos, radius, filter, start_radius, getNode);
|
||||||
content_t c = map.getNode(p).getContent();
|
|
||||||
if (CONTAINS(filter, c)) {
|
|
||||||
push_v3s16(L, p);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkArea(v3s16 &minp, v3s16 &maxp)
|
void ModApiEnvBase::checkArea(v3s16 &minp, v3s16 &maxp)
|
||||||
{
|
{
|
||||||
auto volume = VoxelArea(minp, maxp).getVolume();
|
auto volume = VoxelArea(minp, maxp).getVolume();
|
||||||
// Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
|
// Volume limit equal to 8 default mapchunks, (80 * 2) ^ 3 = 4,096,000
|
||||||
@ -864,32 +874,10 @@ static void checkArea(v3s16 &minp, v3s16 &maxp)
|
|||||||
#undef CLAMP
|
#undef CLAMP
|
||||||
}
|
}
|
||||||
|
|
||||||
// find_nodes_in_area(minp, maxp, nodenames, [grouped])
|
template <typename F>
|
||||||
int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
|
int ModApiEnvBase::findNodesInArea(lua_State *L, const NodeDefManager *ndef,
|
||||||
|
const std::vector<content_t> &filter, bool grouped, F &&iterate)
|
||||||
{
|
{
|
||||||
GET_PLAIN_ENV_PTR;
|
|
||||||
|
|
||||||
v3s16 minp = read_v3s16(L, 1);
|
|
||||||
v3s16 maxp = read_v3s16(L, 2);
|
|
||||||
sortBoxVerticies(minp, maxp);
|
|
||||||
|
|
||||||
const NodeDefManager *ndef = env->getGameDef()->ndef();
|
|
||||||
Map &map = env->getMap();
|
|
||||||
|
|
||||||
#ifndef SERVER
|
|
||||||
if (Client *client = getClient(L)) {
|
|
||||||
minp = client->CSMClampPos(minp);
|
|
||||||
maxp = client->CSMClampPos(maxp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
checkArea(minp, maxp);
|
|
||||||
|
|
||||||
std::vector<content_t> filter;
|
|
||||||
collectNodeIds(L, 3, ndef, filter);
|
|
||||||
|
|
||||||
bool grouped = lua_isboolean(L, 4) && readParam<bool>(L, 4);
|
|
||||||
|
|
||||||
if (grouped) {
|
if (grouped) {
|
||||||
// create the table we will be returning
|
// create the table we will be returning
|
||||||
lua_createtable(L, 0, filter.size());
|
lua_createtable(L, 0, filter.size());
|
||||||
@ -901,7 +889,7 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
|
|||||||
for (u32 i = 0; i < filter.size(); i++)
|
for (u32 i = 0; i < filter.size(); i++)
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
|
|
||||||
map.forEachNodeInArea(minp, maxp, [&](v3s16 p, MapNode n) -> bool {
|
iterate([&](v3s16 p, MapNode n) -> bool {
|
||||||
content_t c = n.getContent();
|
content_t c = n.getContent();
|
||||||
|
|
||||||
auto it = std::find(filter.begin(), filter.end(), c);
|
auto it = std::find(filter.begin(), filter.end(), c);
|
||||||
@ -935,7 +923,7 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
|
|||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
map.forEachNodeInArea(minp, maxp, [&](v3s16 p, MapNode n) -> bool {
|
iterate([&](v3s16 p, MapNode n) -> bool {
|
||||||
content_t c = n.getContent();
|
content_t c = n.getContent();
|
||||||
|
|
||||||
auto it = std::find(filter.begin(), filter.end(), c);
|
auto it = std::find(filter.begin(), filter.end(), c);
|
||||||
@ -959,17 +947,9 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find_nodes_in_area_under_air(minp, maxp, nodenames) -> list of positions
|
// find_nodes_in_area(minp, maxp, nodenames, [grouped])
|
||||||
// nodenames: e.g. {"ignore", "group:tree"} or "default:dirt"
|
int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
|
||||||
int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
|
|
||||||
{
|
{
|
||||||
/* Note: A similar but generalized (and therefore slower) version of this
|
|
||||||
* function could be created -- e.g. find_nodes_in_area_under -- which
|
|
||||||
* would accept a node name (or ID?) or list of names that the "above node"
|
|
||||||
* should be.
|
|
||||||
* TODO
|
|
||||||
*/
|
|
||||||
|
|
||||||
GET_PLAIN_ENV_PTR;
|
GET_PLAIN_ENV_PTR;
|
||||||
|
|
||||||
v3s16 minp = read_v3s16(L, 1);
|
v3s16 minp = read_v3s16(L, 1);
|
||||||
@ -991,16 +971,28 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
|
|||||||
std::vector<content_t> filter;
|
std::vector<content_t> filter;
|
||||||
collectNodeIds(L, 3, ndef, filter);
|
collectNodeIds(L, 3, ndef, filter);
|
||||||
|
|
||||||
|
bool grouped = lua_isboolean(L, 4) && readParam<bool>(L, 4);
|
||||||
|
|
||||||
|
auto iterate = [&] (auto &&callback) {
|
||||||
|
map.forEachNodeInArea(minp, maxp, callback);
|
||||||
|
};
|
||||||
|
return findNodesInArea(L, ndef, filter, grouped, iterate);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
int ModApiEnvBase::findNodesInAreaUnderAir(lua_State *L, v3s16 minp, v3s16 maxp,
|
||||||
|
const std::vector<content_t> &filter, F &&getNode)
|
||||||
|
{
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
v3s16 p;
|
v3s16 p;
|
||||||
for (p.X = minp.X; p.X <= maxp.X; p.X++)
|
for (p.X = minp.X; p.X <= maxp.X; p.X++)
|
||||||
for (p.Z = minp.Z; p.Z <= maxp.Z; p.Z++) {
|
for (p.Z = minp.Z; p.Z <= maxp.Z; p.Z++) {
|
||||||
p.Y = minp.Y;
|
p.Y = minp.Y;
|
||||||
content_t c = map.getNode(p).getContent();
|
content_t c = getNode(p).getContent();
|
||||||
for (; p.Y <= maxp.Y; p.Y++) {
|
for (; p.Y <= maxp.Y; p.Y++) {
|
||||||
v3s16 psurf(p.X, p.Y + 1, p.Z);
|
v3s16 psurf(p.X, p.Y + 1, p.Z);
|
||||||
content_t csurf = map.getNode(psurf).getContent();
|
content_t csurf = getNode(psurf).getContent();
|
||||||
if (c != CONTENT_AIR && csurf == CONTENT_AIR &&
|
if (c != CONTENT_AIR && csurf == CONTENT_AIR &&
|
||||||
CONTAINS(filter, c)) {
|
CONTAINS(filter, c)) {
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
@ -1012,6 +1004,41 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find_nodes_in_area_under_air(minp, maxp, nodenames) -> list of positions
|
||||||
|
// nodenames: e.g. {"ignore", "group:tree"} or "default:dirt"
|
||||||
|
int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
|
||||||
|
{
|
||||||
|
/* TODO: A similar but generalized (and therefore slower) version of this
|
||||||
|
* function could be created -- e.g. find_nodes_in_area_under -- which
|
||||||
|
* would accept a node name or list of names that the "above node" should be.
|
||||||
|
*/
|
||||||
|
GET_PLAIN_ENV_PTR;
|
||||||
|
|
||||||
|
v3s16 minp = read_v3s16(L, 1);
|
||||||
|
v3s16 maxp = read_v3s16(L, 2);
|
||||||
|
sortBoxVerticies(minp, maxp);
|
||||||
|
|
||||||
|
const NodeDefManager *ndef = env->getGameDef()->ndef();
|
||||||
|
Map &map = env->getMap();
|
||||||
|
|
||||||
|
#ifndef SERVER
|
||||||
|
if (Client *client = getClient(L)) {
|
||||||
|
minp = client->CSMClampPos(minp);
|
||||||
|
maxp = client->CSMClampPos(maxp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
checkArea(minp, maxp);
|
||||||
|
|
||||||
|
std::vector<content_t> filter;
|
||||||
|
collectNodeIds(L, 3, ndef, filter);
|
||||||
|
|
||||||
|
auto getNode = [&map] (v3s16 p) -> MapNode {
|
||||||
|
return map.getNode(p);
|
||||||
|
};
|
||||||
|
return findNodesInAreaUnderAir(L, minp, maxp, filter, getNode);
|
||||||
|
}
|
||||||
|
|
||||||
// get_perlin(seeddiff, octaves, persistence, scale)
|
// get_perlin(seeddiff, octaves, persistence, scale)
|
||||||
// returns world-specific PerlinNoise
|
// returns world-specific PerlinNoise
|
||||||
int ModApiEnvMod::l_get_perlin(lua_State *L)
|
int ModApiEnvMod::l_get_perlin(lua_State *L)
|
||||||
@ -1279,6 +1306,45 @@ int ModApiEnvMod::l_find_path(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool read_tree_def(lua_State *L, int idx,
|
||||||
|
const NodeDefManager *ndef, treegen::TreeDef &tree_def)
|
||||||
|
{
|
||||||
|
std::string trunk, leaves, fruit;
|
||||||
|
if (!lua_istable(L, idx))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
getstringfield(L, idx, "axiom", tree_def.initial_axiom);
|
||||||
|
getstringfield(L, idx, "rules_a", tree_def.rules_a);
|
||||||
|
getstringfield(L, idx, "rules_b", tree_def.rules_b);
|
||||||
|
getstringfield(L, idx, "rules_c", tree_def.rules_c);
|
||||||
|
getstringfield(L, idx, "rules_d", tree_def.rules_d);
|
||||||
|
getstringfield(L, idx, "trunk", trunk);
|
||||||
|
tree_def.trunknode = ndef->getId(trunk);
|
||||||
|
getstringfield(L, idx, "leaves", leaves);
|
||||||
|
tree_def.leavesnode = ndef->getId(leaves);
|
||||||
|
tree_def.leaves2_chance = 0;
|
||||||
|
getstringfield(L, idx, "leaves2", leaves);
|
||||||
|
if (!leaves.empty()) {
|
||||||
|
tree_def.leaves2node = ndef->getId(leaves);
|
||||||
|
getintfield(L, idx, "leaves2_chance", tree_def.leaves2_chance);
|
||||||
|
}
|
||||||
|
getintfield(L, idx, "angle", tree_def.angle);
|
||||||
|
getintfield(L, idx, "iterations", tree_def.iterations);
|
||||||
|
if (!getintfield(L, idx, "random_level", tree_def.iterations_random_level))
|
||||||
|
tree_def.iterations_random_level = 0;
|
||||||
|
getstringfield(L, idx, "trunk_type", tree_def.trunk_type);
|
||||||
|
getboolfield(L, idx, "thin_branches", tree_def.thin_branches);
|
||||||
|
tree_def.fruit_chance = 0;
|
||||||
|
getstringfield(L, idx, "fruit", fruit);
|
||||||
|
if (!fruit.empty()) {
|
||||||
|
tree_def.fruitnode = ndef->getId(fruit);
|
||||||
|
getintfield(L, idx, "fruit_chance", tree_def.fruit_chance);
|
||||||
|
}
|
||||||
|
tree_def.explicit_seed = getintfield(L, idx, "seed", tree_def.seed);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// spawn_tree(pos, treedef)
|
// spawn_tree(pos, treedef)
|
||||||
int ModApiEnvMod::l_spawn_tree(lua_State *L)
|
int ModApiEnvMod::l_spawn_tree(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -1287,41 +1353,9 @@ int ModApiEnvMod::l_spawn_tree(lua_State *L)
|
|||||||
v3s16 p0 = read_v3s16(L, 1);
|
v3s16 p0 = read_v3s16(L, 1);
|
||||||
|
|
||||||
treegen::TreeDef tree_def;
|
treegen::TreeDef tree_def;
|
||||||
std::string trunk,leaves,fruit;
|
|
||||||
const NodeDefManager *ndef = env->getGameDef()->ndef();
|
const NodeDefManager *ndef = env->getGameDef()->ndef();
|
||||||
|
|
||||||
if(lua_istable(L, 2))
|
if (!read_tree_def(L, 2, ndef, tree_def))
|
||||||
{
|
|
||||||
getstringfield(L, 2, "axiom", tree_def.initial_axiom);
|
|
||||||
getstringfield(L, 2, "rules_a", tree_def.rules_a);
|
|
||||||
getstringfield(L, 2, "rules_b", tree_def.rules_b);
|
|
||||||
getstringfield(L, 2, "rules_c", tree_def.rules_c);
|
|
||||||
getstringfield(L, 2, "rules_d", tree_def.rules_d);
|
|
||||||
getstringfield(L, 2, "trunk", trunk);
|
|
||||||
tree_def.trunknode=ndef->getId(trunk);
|
|
||||||
getstringfield(L, 2, "leaves", leaves);
|
|
||||||
tree_def.leavesnode=ndef->getId(leaves);
|
|
||||||
tree_def.leaves2_chance=0;
|
|
||||||
getstringfield(L, 2, "leaves2", leaves);
|
|
||||||
if (!leaves.empty()) {
|
|
||||||
tree_def.leaves2node=ndef->getId(leaves);
|
|
||||||
getintfield(L, 2, "leaves2_chance", tree_def.leaves2_chance);
|
|
||||||
}
|
|
||||||
getintfield(L, 2, "angle", tree_def.angle);
|
|
||||||
getintfield(L, 2, "iterations", tree_def.iterations);
|
|
||||||
if (!getintfield(L, 2, "random_level", tree_def.iterations_random_level))
|
|
||||||
tree_def.iterations_random_level = 0;
|
|
||||||
getstringfield(L, 2, "trunk_type", tree_def.trunk_type);
|
|
||||||
getboolfield(L, 2, "thin_branches", tree_def.thin_branches);
|
|
||||||
tree_def.fruit_chance=0;
|
|
||||||
getstringfield(L, 2, "fruit", fruit);
|
|
||||||
if (!fruit.empty()) {
|
|
||||||
tree_def.fruitnode=ndef->getId(fruit);
|
|
||||||
getintfield(L, 2, "fruit_chance",tree_def.fruit_chance);
|
|
||||||
}
|
|
||||||
tree_def.explicit_seed = getintfield(L, 2, "seed", tree_def.seed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ServerMap *map = &env->getServerMap();
|
ServerMap *map = &env->getServerMap();
|
||||||
@ -1334,6 +1368,7 @@ int ModApiEnvMod::l_spawn_tree(lua_State *L)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lua_pushboolean(L, true);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,38 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "serverenvironment.h"
|
#include "serverenvironment.h"
|
||||||
#include "raycast.h"
|
#include "raycast.h"
|
||||||
|
|
||||||
class ModApiEnvMod : public ModApiBase {
|
// base class containing helpers
|
||||||
|
class ModApiEnvBase : public ModApiBase {
|
||||||
|
protected:
|
||||||
|
|
||||||
|
static void collectNodeIds(lua_State *L, int idx,
|
||||||
|
const NodeDefManager *ndef, std::vector<content_t> &filter);
|
||||||
|
|
||||||
|
static void checkArea(v3s16 &minp, v3s16 &maxp);
|
||||||
|
|
||||||
|
// F must be (v3s16 pos) -> MapNode
|
||||||
|
template <typename F>
|
||||||
|
static int findNodeNear(lua_State *L, v3s16 pos, int radius,
|
||||||
|
const std::vector<content_t> &filter, int start_radius, F &&getNode);
|
||||||
|
|
||||||
|
// F must be (G callback) -> void
|
||||||
|
// with G being (v3s16 p, MapNode n) -> bool
|
||||||
|
// and behave like Map::forEachNodeInArea
|
||||||
|
template <typename F>
|
||||||
|
static int findNodesInArea(lua_State *L, const NodeDefManager *ndef,
|
||||||
|
const std::vector<content_t> &filter, bool grouped, F &&iterate);
|
||||||
|
|
||||||
|
// F must be (v3s16 pos) -> MapNode
|
||||||
|
template <typename F>
|
||||||
|
static int findNodesInAreaUnderAir(lua_State *L, v3s16 minp, v3s16 maxp,
|
||||||
|
const std::vector<content_t> &filter, F &&getNode);
|
||||||
|
|
||||||
|
static const EnumString es_ClearObjectsMode[];
|
||||||
|
static const EnumString es_BlockStatusType[];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModApiEnvMod : public ModApiEnvBase {
|
||||||
private:
|
private:
|
||||||
// set_node(pos, node)
|
// set_node(pos, node)
|
||||||
// pos = {x=num, y=num, z=num}
|
// pos = {x=num, y=num, z=num}
|
||||||
@ -198,20 +229,12 @@ private:
|
|||||||
// compare_block_status(nodepos)
|
// compare_block_status(nodepos)
|
||||||
static int l_compare_block_status(lua_State *L);
|
static int l_compare_block_status(lua_State *L);
|
||||||
|
|
||||||
// Get a string translated server side
|
// get_translated_string(lang_code, string)
|
||||||
static int l_get_translated_string(lua_State * L);
|
static int l_get_translated_string(lua_State * L);
|
||||||
|
|
||||||
/* Helpers */
|
|
||||||
|
|
||||||
static void collectNodeIds(lua_State *L, int idx,
|
|
||||||
const NodeDefManager *ndef, std::vector<content_t> &filter);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void Initialize(lua_State *L, int top);
|
static void Initialize(lua_State *L, int top);
|
||||||
static void InitializeClient(lua_State *L, int top);
|
static void InitializeClient(lua_State *L, int top);
|
||||||
|
|
||||||
static const EnumString es_ClearObjectsMode[];
|
|
||||||
static const EnumString es_BlockStatusType[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LuaABM : public ActiveBlockModifier {
|
class LuaABM : public ActiveBlockModifier {
|
||||||
|
Loading…
Reference in New Issue
Block a user