mirror of
https://github.com/luanti-org/luanti.git
synced 2025-09-05 18:41:05 +00:00
Lua on each mapgen thread (#13092)
This commit is contained in:
parent
d4b107e2e8
commit
3cac17d23e
32 changed files with 1329 additions and 193 deletions
|
@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "daynightratio.h"
|
||||
#include "util/pointedthing.h"
|
||||
#include "mapgen/treegen.h"
|
||||
#include "emerge.h"
|
||||
#include "emerge_internal.h"
|
||||
#include "pathfinder.h"
|
||||
#include "face_position_cache.h"
|
||||
#include "remoteplayer.h"
|
||||
|
@ -241,7 +241,7 @@ void LuaEmergeAreaCallback(v3s16 blockpos, EmergeAction action, void *param)
|
|||
delete state;
|
||||
}
|
||||
|
||||
// Exported functions
|
||||
/* Exported functions */
|
||||
|
||||
// set_node(pos, node)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
|
@ -1538,3 +1538,189 @@ void ModApiEnv::InitializeClient(lua_State *L, int top)
|
|||
API_FCT(line_of_sight);
|
||||
API_FCT(raycast);
|
||||
}
|
||||
|
||||
#define GET_VM_PTR \
|
||||
MMVManip *vm = getVManip(L); \
|
||||
if (!vm) \
|
||||
return 0
|
||||
|
||||
// get_node_max_level(pos)
|
||||
int ModApiEnvVM::l_get_node_max_level(lua_State *L)
|
||||
{
|
||||
GET_VM_PTR;
|
||||
|
||||
v3s16 pos = read_v3s16(L, 1);
|
||||
MapNode n = vm->getNodeNoExNoEmerge(pos);
|
||||
lua_pushnumber(L, n.getMaxLevel(getGameDef(L)->ndef()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_node_level(pos)
|
||||
int ModApiEnvVM::l_get_node_level(lua_State *L)
|
||||
{
|
||||
GET_VM_PTR;
|
||||
|
||||
v3s16 pos = read_v3s16(L, 1);
|
||||
MapNode n = vm->getNodeNoExNoEmerge(pos);
|
||||
lua_pushnumber(L, n.getLevel(getGameDef(L)->ndef()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// set_node_level(pos, level)
|
||||
int ModApiEnvVM::l_set_node_level(lua_State *L)
|
||||
{
|
||||
GET_VM_PTR;
|
||||
|
||||
v3s16 pos = read_v3s16(L, 1);
|
||||
u8 level = 1;
|
||||
if (lua_isnumber(L, 2))
|
||||
level = lua_tonumber(L, 2);
|
||||
MapNode n = vm->getNodeNoExNoEmerge(pos);
|
||||
lua_pushnumber(L, n.setLevel(getGameDef(L)->ndef(), level));
|
||||
vm->setNodeNoEmerge(pos, n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// add_node_level(pos, level)
|
||||
int ModApiEnvVM::l_add_node_level(lua_State *L)
|
||||
{
|
||||
GET_VM_PTR;
|
||||
|
||||
v3s16 pos = read_v3s16(L, 1);
|
||||
u8 level = 1;
|
||||
if (lua_isnumber(L, 2))
|
||||
level = lua_tonumber(L, 2);
|
||||
MapNode n = vm->getNodeNoExNoEmerge(pos);
|
||||
lua_pushnumber(L, n.addLevel(getGameDef(L)->ndef(), level));
|
||||
vm->setNodeNoEmerge(pos, n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// find_node_near(pos, radius, nodenames, [search_center])
|
||||
int ModApiEnvVM::l_find_node_near(lua_State *L)
|
||||
{
|
||||
GET_VM_PTR;
|
||||
|
||||
const NodeDefManager *ndef = getGameDef(L)->ndef();
|
||||
|
||||
v3s16 pos = read_v3s16(L, 1);
|
||||
int radius = luaL_checkinteger(L, 2);
|
||||
std::vector<content_t> filter;
|
||||
collectNodeIds(L, 3, ndef, filter);
|
||||
int start_radius = (lua_isboolean(L, 4) && readParam<bool>(L, 4)) ? 0 : 1;
|
||||
|
||||
auto getNode = [&vm] (v3s16 p) -> MapNode {
|
||||
return vm->getNodeNoExNoEmerge(p);
|
||||
};
|
||||
return findNodeNear(L, pos, radius, filter, start_radius, getNode);
|
||||
}
|
||||
|
||||
// find_nodes_in_area(minp, maxp, nodenames, [grouped])
|
||||
int ModApiEnvVM::l_find_nodes_in_area(lua_State *L)
|
||||
{
|
||||
GET_VM_PTR;
|
||||
|
||||
const NodeDefManager *ndef = getGameDef(L)->ndef();
|
||||
|
||||
v3s16 minp = read_v3s16(L, 1);
|
||||
v3s16 maxp = read_v3s16(L, 2);
|
||||
sortBoxVerticies(minp, maxp);
|
||||
|
||||
checkArea(minp, maxp);
|
||||
// avoid the loop going out-of-bounds
|
||||
{
|
||||
VoxelArea cropped = VoxelArea(minp, maxp).intersect(vm->m_area);
|
||||
minp = cropped.MinEdge;
|
||||
maxp = cropped.MaxEdge;
|
||||
}
|
||||
|
||||
std::vector<content_t> filter;
|
||||
collectNodeIds(L, 3, ndef, filter);
|
||||
|
||||
bool grouped = lua_isboolean(L, 4) && readParam<bool>(L, 4);
|
||||
|
||||
auto iterate = [&] (auto callback) {
|
||||
for (s16 z = minp.Z; z <= maxp.Z; z++)
|
||||
for (s16 y = minp.Y; y <= maxp.Y; y++) {
|
||||
u32 vi = vm->m_area.index(minp.X, y, z);
|
||||
for (s16 x = minp.X; x <= maxp.X; x++) {
|
||||
v3s16 pos(x, y, z);
|
||||
MapNode n = vm->m_data[vi];
|
||||
if (!callback(pos, n))
|
||||
return;
|
||||
++vi;
|
||||
}
|
||||
}
|
||||
};
|
||||
return findNodesInArea(L, ndef, filter, grouped, iterate);
|
||||
}
|
||||
|
||||
// find_nodes_in_area_under_air(minp, maxp, nodenames)
|
||||
int ModApiEnvVM::l_find_nodes_in_area_under_air(lua_State *L)
|
||||
{
|
||||
GET_VM_PTR;
|
||||
|
||||
const NodeDefManager *ndef = getGameDef(L)->ndef();
|
||||
|
||||
v3s16 minp = read_v3s16(L, 1);
|
||||
v3s16 maxp = read_v3s16(L, 2);
|
||||
sortBoxVerticies(minp, maxp);
|
||||
checkArea(minp, maxp);
|
||||
|
||||
std::vector<content_t> filter;
|
||||
collectNodeIds(L, 3, ndef, filter);
|
||||
|
||||
auto getNode = [&vm] (v3s16 p) -> MapNode {
|
||||
return vm->getNodeNoExNoEmerge(p);
|
||||
};
|
||||
return findNodesInAreaUnderAir(L, minp, maxp, filter, getNode);
|
||||
}
|
||||
|
||||
// spawn_tree(pos, treedef)
|
||||
int ModApiEnvVM::l_spawn_tree(lua_State *L)
|
||||
{
|
||||
GET_VM_PTR;
|
||||
|
||||
const NodeDefManager *ndef = getGameDef(L)->ndef();
|
||||
|
||||
v3s16 p0 = read_v3s16(L, 1);
|
||||
|
||||
treegen::TreeDef tree_def;
|
||||
if (!read_tree_def(L, 2, ndef, tree_def))
|
||||
return 0;
|
||||
|
||||
treegen::error e;
|
||||
if ((e = treegen::make_ltree(*vm, p0, ndef, tree_def)) != treegen::SUCCESS) {
|
||||
if (e == treegen::UNBALANCED_BRACKETS) {
|
||||
throw LuaError("spawn_tree(): closing ']' has no matching opening bracket");
|
||||
} else {
|
||||
throw LuaError("spawn_tree(): unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
MMVManip *ModApiEnvVM::getVManip(lua_State *L)
|
||||
{
|
||||
auto emerge = getEmergeThread(L);
|
||||
if (emerge)
|
||||
return emerge->getMapgen()->vm;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ModApiEnvVM::InitializeEmerge(lua_State *L, int top)
|
||||
{
|
||||
// other, more trivial functions are in builtin/emerge/env.lua
|
||||
API_FCT(get_node_max_level);
|
||||
API_FCT(get_node_level);
|
||||
API_FCT(set_node_level);
|
||||
API_FCT(add_node_level);
|
||||
API_FCT(find_node_near);
|
||||
API_FCT(find_nodes_in_area);
|
||||
API_FCT(find_nodes_in_area_under_air);
|
||||
API_FCT(spawn_tree);
|
||||
}
|
||||
|
||||
#undef GET_VM_PTR
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue