mirror of
https://github.com/minetest/minetest.git
synced 2024-12-22 22:22:23 +01:00
Add core.spawn_tree_on_vmanip
(#15415)
This function works like `core.spawn_tree`, but spawns an L-system tree onto a VoxelManip object instead on the map.
This commit is contained in:
parent
8d43ad2522
commit
c7fe2ee5c9
@ -6588,6 +6588,9 @@ Environment access
|
|||||||
on-the-fly
|
on-the-fly
|
||||||
* `core.spawn_tree (pos, {treedef})`
|
* `core.spawn_tree (pos, {treedef})`
|
||||||
* spawns L-system tree at given `pos` with definition in `treedef` table
|
* spawns L-system tree at given `pos` with definition in `treedef` table
|
||||||
|
* `core.spawn_tree_on_vmanip(vmanip, pos, treedef)`
|
||||||
|
* analogous to `core.spawn_tree`, but spawns a L-system tree onto the specified
|
||||||
|
VoxelManip object `vmanip` instead of the map.
|
||||||
* `core.transforming_liquid_add(pos)`
|
* `core.transforming_liquid_add(pos)`
|
||||||
* add node to liquid flow update queue
|
* add node to liquid flow update queue
|
||||||
* `core.get_node_max_level(pos)`
|
* `core.get_node_max_level(pos)`
|
||||||
|
@ -105,3 +105,68 @@ core.register_craftitem("testitems:telescope_stick", {
|
|||||||
return itemstack
|
return itemstack
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
-- Tree spawners
|
||||||
|
|
||||||
|
local tree_def={
|
||||||
|
axiom="Af",
|
||||||
|
rules_a="TT[&GB][&+GB][&++GB][&+++GB]A",
|
||||||
|
rules_b="[+GB]fB",
|
||||||
|
trunk="basenodes:tree",
|
||||||
|
leaves="basenodes:leaves",
|
||||||
|
angle=90,
|
||||||
|
iterations=4,
|
||||||
|
trunk_type="single",
|
||||||
|
thin_branches=true,
|
||||||
|
}
|
||||||
|
|
||||||
|
core.register_craftitem("testitems:tree_spawner", {
|
||||||
|
description = S("Tree Spawner"),
|
||||||
|
inventory_image = "testitems_tree_spawner.png",
|
||||||
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
|
if (not pointed_thing or pointed_thing.type ~= "node") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
core.spawn_tree(pointed_thing.above, tree_def)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
local vmanip_for_trees = {} -- per player
|
||||||
|
core.register_craftitem("testitems:tree_spawner_vmanip", {
|
||||||
|
description = S("Tree Spawner using VoxelManip"),
|
||||||
|
inventory_image = "testitems_tree_spawner_vmanip.png",
|
||||||
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
|
if (not pointed_thing or pointed_thing.type ~= "node" or
|
||||||
|
not core.is_player(placer)) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local name = placer:get_player_name()
|
||||||
|
local vm = vmanip_for_trees[name]
|
||||||
|
if not vm then
|
||||||
|
vm = VoxelManip(vector.add(pointed_thing.above, 20),
|
||||||
|
vector.subtract(pointed_thing.above, 20))
|
||||||
|
vmanip_for_trees[name] = vm
|
||||||
|
core.chat_send_player(name,
|
||||||
|
"Tree in new VoxelManip spawned, left click to apply to map, "..
|
||||||
|
"or right click to add more trees.")
|
||||||
|
end
|
||||||
|
core.spawn_tree_on_vmanip(vm, pointed_thing.above, tree_def)
|
||||||
|
end,
|
||||||
|
on_use = function(itemstack, user, pointed_thing)
|
||||||
|
if not core.is_player(user) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local name = user:get_player_name()
|
||||||
|
local vm = vmanip_for_trees[name]
|
||||||
|
if vm then
|
||||||
|
vm:write_to_map()
|
||||||
|
vmanip_for_trees[name] = nil
|
||||||
|
core.chat_send_player(name, "VoxelManip written to map.")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
core.register_on_leaveplayer(function(player, timed_out)
|
||||||
|
vmanip_for_trees[player:get_player_name()] = nil
|
||||||
|
end)
|
||||||
|
BIN
games/devtest/mods/testitems/textures/testitems_tree_spawner.png
Normal file
BIN
games/devtest/mods/testitems/textures/testitems_tree_spawner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 120 B |
Binary file not shown.
After Width: | Height: | Size: 150 B |
@ -875,4 +875,15 @@ void make_pine_tree(MMVManip &vmanip, v3s16 p0, const NodeDefManager *ndef,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string error_to_string(error e)
|
||||||
|
{
|
||||||
|
switch (e) {
|
||||||
|
case SUCCESS:
|
||||||
|
return "success";
|
||||||
|
case UNBALANCED_BRACKETS:
|
||||||
|
return "closing ']' has no matching opening bracket";
|
||||||
|
}
|
||||||
|
return "unknown error";
|
||||||
|
}
|
||||||
|
|
||||||
}; // namespace treegen
|
}; // namespace treegen
|
||||||
|
@ -68,4 +68,7 @@ namespace treegen {
|
|||||||
treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, const TreeDef &def);
|
treegen::error make_ltree(MMVManip &vmanip, v3s16 p0, const TreeDef &def);
|
||||||
// Helper to spawn it directly on map
|
// Helper to spawn it directly on map
|
||||||
treegen::error spawn_ltree(ServerMap *map, v3s16 p0, const TreeDef &def);
|
treegen::error spawn_ltree(ServerMap *map, v3s16 p0, const TreeDef &def);
|
||||||
|
|
||||||
|
// Helper to get a string from the error message
|
||||||
|
std::string error_to_string(error e);
|
||||||
}; // namespace treegen
|
}; // namespace treegen
|
||||||
|
@ -1307,11 +1307,7 @@ int ModApiEnv::l_spawn_tree(lua_State *L)
|
|||||||
ServerMap *map = &env->getServerMap();
|
ServerMap *map = &env->getServerMap();
|
||||||
treegen::error e;
|
treegen::error e;
|
||||||
if ((e = treegen::spawn_ltree (map, p0, tree_def)) != treegen::SUCCESS) {
|
if ((e = treegen::spawn_ltree (map, p0, tree_def)) != treegen::SUCCESS) {
|
||||||
if (e == treegen::UNBALANCED_BRACKETS) {
|
throw LuaError("spawn_tree(): " + treegen::error_to_string(e));
|
||||||
luaL_error(L, "spawn_tree(): closing ']' has no matching opening bracket");
|
|
||||||
} else {
|
|
||||||
luaL_error(L, "spawn_tree(): unknown error");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushboolean(L, true);
|
lua_pushboolean(L, true);
|
||||||
@ -1614,11 +1610,7 @@ int ModApiEnvVM::l_spawn_tree(lua_State *L)
|
|||||||
|
|
||||||
treegen::error e;
|
treegen::error e;
|
||||||
if ((e = treegen::make_ltree(*vm, p0, tree_def)) != treegen::SUCCESS) {
|
if ((e = treegen::make_ltree(*vm, p0, tree_def)) != treegen::SUCCESS) {
|
||||||
if (e == treegen::UNBALANCED_BRACKETS) {
|
throw LuaError("spawn_tree(): " + treegen::error_to_string(e));
|
||||||
throw LuaError("spawn_tree(): closing ']' has no matching opening bracket");
|
|
||||||
} else {
|
|
||||||
throw LuaError("spawn_tree(): unknown error");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushboolean(L, true);
|
lua_pushboolean(L, true);
|
||||||
|
@ -1773,6 +1773,27 @@ int ModApiMapgen::l_place_schematic_on_vmanip(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// spawn_tree_on_vmanip(vmanip, pos, treedef)
|
||||||
|
int ModApiMapgen::l_spawn_tree_on_vmanip(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
|
||||||
|
MMVManip *vm = checkObject<LuaVoxelManip>(L, 1)->vm;
|
||||||
|
v3s16 p0 = read_v3s16(L, 2);
|
||||||
|
treegen::TreeDef tree_def;
|
||||||
|
const NodeDefManager *ndef = getGameDef(L)->ndef();
|
||||||
|
if (!read_tree_def(L, 3, ndef, tree_def))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
treegen::error e = treegen::make_ltree(*vm, p0, tree_def);
|
||||||
|
if (e != treegen::SUCCESS) {
|
||||||
|
throw LuaError("spawn_tree_on_vmanip(): " + treegen::error_to_string(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushboolean(L, true);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// serialize_schematic(schematic, format, options={...})
|
// serialize_schematic(schematic, format, options={...})
|
||||||
int ModApiMapgen::l_serialize_schematic(lua_State *L)
|
int ModApiMapgen::l_serialize_schematic(lua_State *L)
|
||||||
@ -2023,6 +2044,7 @@ void ModApiMapgen::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(create_schematic);
|
API_FCT(create_schematic);
|
||||||
API_FCT(place_schematic);
|
API_FCT(place_schematic);
|
||||||
API_FCT(place_schematic_on_vmanip);
|
API_FCT(place_schematic_on_vmanip);
|
||||||
|
API_FCT(spawn_tree_on_vmanip);
|
||||||
API_FCT(serialize_schematic);
|
API_FCT(serialize_schematic);
|
||||||
API_FCT(read_schematic);
|
API_FCT(read_schematic);
|
||||||
}
|
}
|
||||||
@ -2049,6 +2071,7 @@ void ModApiMapgen::InitializeEmerge(lua_State *L, int top)
|
|||||||
API_FCT(generate_ores);
|
API_FCT(generate_ores);
|
||||||
API_FCT(generate_decorations);
|
API_FCT(generate_decorations);
|
||||||
API_FCT(place_schematic_on_vmanip);
|
API_FCT(place_schematic_on_vmanip);
|
||||||
|
API_FCT(spawn_tree_on_vmanip);
|
||||||
API_FCT(serialize_schematic);
|
API_FCT(serialize_schematic);
|
||||||
API_FCT(read_schematic);
|
API_FCT(read_schematic);
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,9 @@ private:
|
|||||||
// replacements, force_placement, flagstring)
|
// replacements, force_placement, flagstring)
|
||||||
static int l_place_schematic_on_vmanip(lua_State *L);
|
static int l_place_schematic_on_vmanip(lua_State *L);
|
||||||
|
|
||||||
|
// spawn_tree_on_vmanip(vmanip, pos, treedef)
|
||||||
|
static int l_spawn_tree_on_vmanip(lua_State *L);
|
||||||
|
|
||||||
// serialize_schematic(schematic, format, options={...})
|
// serialize_schematic(schematic, format, options={...})
|
||||||
static int l_serialize_schematic(lua_State *L);
|
static int l_serialize_schematic(lua_State *L);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user