1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-02 16:38:41 +00:00

Add L-system trees as decorations (#14355)

This commit is contained in:
cx384 2024-03-12 20:10:28 +01:00 committed by GitHub
parent f07e1026ac
commit 60810c2d37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 125 additions and 46 deletions

View file

@ -37,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h" // For FATAL_ERROR
#include <SColor.h>
#include <json/json.h>
#include "mapgen/treegen.h"
struct EnumString es_TileAnimationType[] =
{
@ -2006,6 +2007,51 @@ void push_noiseparams(lua_State *L, NoiseParams *np)
lua_setfield(L, -2, "spread");
}
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.m_nodenames.push_back(trunk);
getstringfield(L, idx, "leaves", leaves);
tree_def.m_nodenames.push_back(leaves);
tree_def.leaves2_chance = 0;
getstringfield(L, idx, "leaves2", leaves);
if (!leaves.empty()) {
getintfield(L, idx, "leaves2_chance", tree_def.leaves2_chance);
if (tree_def.leaves2_chance)
tree_def.m_nodenames.push_back(leaves);
}
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()) {
getintfield(L, idx, "fruit_chance", tree_def.fruit_chance);
if (tree_def.fruit_chance)
tree_def.m_nodenames.push_back(fruit);
}
tree_def.explicit_seed = getintfield(L, idx, "seed", tree_def.seed);
// Resolves the node IDs for trunk, leaves, leaves2 and fruit at runtime,
// when tree_def.resolveNodeNames will be called.
ndef->pendNodeResolve(&tree_def);
return true;
}
/******************************************************************************/
// Returns depth of json value tree
static int push_json_value_getdepth(const Json::Value &value)

View file

@ -70,6 +70,7 @@ struct NoiseParams;
class Schematic;
class ServerActiveObject;
struct collisionMoveResult;
namespace treegen { struct TreeDef; }
extern struct EnumString es_TileAnimationType[];
@ -189,6 +190,10 @@ bool read_noiseparams (lua_State *L, int index,
NoiseParams *np);
void push_noiseparams (lua_State *L, NoiseParams *np);
bool read_tree_def (lua_State *L, int idx,
const NodeDefManager *ndef,
treegen::TreeDef &tree_def);
void luaentity_get (lua_State *L,u16 id);
bool push_json_value (lua_State *L,

View file

@ -1331,45 +1331,6 @@ int ModApiEnv::l_find_path(lua_State *L)
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)
int ModApiEnv::l_spawn_tree(lua_State *L)
{

View file

@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapgen/mg_schematic.h"
#include "mapgen/mapgen_v5.h"
#include "mapgen/mapgen_v7.h"
#include "mapgen/treegen.h"
#include "filesys.h"
#include "settings.h"
#include "log.h"
@ -110,6 +111,7 @@ bool read_schematic_def(lua_State *L, int index,
bool read_deco_simple(lua_State *L, DecoSimple *deco);
bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic *deco);
bool read_deco_lsystem(lua_State *L, const NodeDefManager *ndef, DecoLSystem *deco);
///////////////////////////////////////////////////////////////////////////////
@ -1226,6 +1228,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
success = read_deco_schematic(L, schemmgr, (DecoSchematic *)deco);
break;
case DECO_LSYSTEM:
success = read_deco_lsystem(L, ndef, (DecoLSystem *)deco);
break;
}
@ -1308,6 +1311,17 @@ bool read_deco_schematic(lua_State *L, SchematicManager *schemmgr, DecoSchematic
return schem != NULL;
}
bool read_deco_lsystem(lua_State *L, const NodeDefManager *ndef, DecoLSystem *deco)
{
deco->tree_def = std::make_shared<treegen::TreeDef>();
lua_getfield(L, 1, "treedef");
bool has_def = read_tree_def(L, -1, ndef, *(deco->tree_def));
lua_pop(L, 1);
return has_def;
}
// register_ore({lots of stuff})
int ModApiMapgen::l_register_ore(lua_State *L)