mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 16:13:46 +01:00
Add Generator Element Management framework
Add BiomeManager, OreManager, DecorationManager, and SchematicManager
This commit is contained in:
parent
f25cc0dbae
commit
7616537bc0
@ -40,8 +40,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
#include "mg_biome.h"
|
#include "mg_biome.h"
|
||||||
#include "mg_decoration.h"
|
|
||||||
#include "mg_ore.h"
|
#include "mg_ore.h"
|
||||||
|
#include "mg_decoration.h"
|
||||||
|
#include "mg_schematic.h"
|
||||||
#include "mapgen_v5.h"
|
#include "mapgen_v5.h"
|
||||||
#include "mapgen_v6.h"
|
#include "mapgen_v6.h"
|
||||||
#include "mapgen_v7.h"
|
#include "mapgen_v7.h"
|
||||||
@ -88,8 +89,11 @@ EmergeManager::EmergeManager(IGameDef *gamedef) {
|
|||||||
registerMapgen("v7", new MapgenFactoryV7());
|
registerMapgen("v7", new MapgenFactoryV7());
|
||||||
registerMapgen("singlenode", new MapgenFactorySinglenode());
|
registerMapgen("singlenode", new MapgenFactorySinglenode());
|
||||||
|
|
||||||
this->ndef = gamedef->getNodeDefManager();
|
this->ndef = gamedef->getNodeDefManager();
|
||||||
this->biomedef = new BiomeDefManager(gamedef->getNodeDefManager()->getResolver());
|
this->biomemgr = new BiomeManager(gamedef);
|
||||||
|
this->oremgr = new OreManager(gamedef);
|
||||||
|
this->decomgr = new DecorationManager(gamedef);
|
||||||
|
this->schemmgr = new SchematicManager(gamedef);
|
||||||
this->gennotify = 0;
|
this->gennotify = 0;
|
||||||
|
|
||||||
// Note that accesses to this variable are not synchronized.
|
// Note that accesses to this variable are not synchronized.
|
||||||
@ -141,21 +145,15 @@ EmergeManager::~EmergeManager() {
|
|||||||
emergethread.clear();
|
emergethread.clear();
|
||||||
mapgen.clear();
|
mapgen.clear();
|
||||||
|
|
||||||
for (unsigned int i = 0; i < ores.size(); i++)
|
std::map<std::string, MapgenFactory *>::iterator it;
|
||||||
delete ores[i];
|
for (it = mglist.begin(); it != mglist.end(); ++it)
|
||||||
ores.clear();
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < decorations.size(); i++)
|
|
||||||
delete decorations[i];
|
|
||||||
decorations.clear();
|
|
||||||
|
|
||||||
for (std::map<std::string, MapgenFactory *>::iterator it = mglist.begin();
|
|
||||||
it != mglist.end(); ++it) {
|
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
|
||||||
mglist.clear();
|
mglist.clear();
|
||||||
|
|
||||||
delete biomedef;
|
delete biomemgr;
|
||||||
|
delete oremgr;
|
||||||
|
delete decomgr;
|
||||||
|
delete schemmgr;
|
||||||
|
|
||||||
if (params.sparams) {
|
if (params.sparams) {
|
||||||
delete params.sparams;
|
delete params.sparams;
|
||||||
|
32
src/emerge.h
32
src/emerge.h
@ -23,8 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include "irr_v3d.h"
|
#include "irr_v3d.h"
|
||||||
#include "util/container.h"
|
#include "util/container.h"
|
||||||
#include "map.h" // for ManualMapVoxelManipulator
|
|
||||||
#include "mapgen.h" // for MapgenParams
|
#include "mapgen.h" // for MapgenParams
|
||||||
|
#include "map.h"
|
||||||
|
|
||||||
#define MGPARAMS_SET_MGNAME 1
|
#define MGPARAMS_SET_MGNAME 1
|
||||||
#define MGPARAMS_SET_SEED 2
|
#define MGPARAMS_SET_SEED 2
|
||||||
@ -34,16 +34,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define BLOCK_EMERGE_ALLOWGEN (1<<0)
|
#define BLOCK_EMERGE_ALLOWGEN (1<<0)
|
||||||
|
|
||||||
#define EMERGE_DBG_OUT(x) \
|
#define EMERGE_DBG_OUT(x) \
|
||||||
{ if (enable_mapgen_debug_info) \
|
do { \
|
||||||
infostream << "EmergeThread: " x << std::endl; }
|
if (enable_mapgen_debug_info) \
|
||||||
|
infostream << "EmergeThread: " x << std::endl; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
class EmergeThread;
|
class EmergeThread;
|
||||||
class Biome;
|
|
||||||
class BiomeDefManager;
|
|
||||||
class Decoration;
|
|
||||||
class Ore;
|
|
||||||
class INodeDefManager;
|
class INodeDefManager;
|
||||||
class Settings;
|
class Settings;
|
||||||
|
//class ManualMapVoxelManipulator;
|
||||||
|
|
||||||
|
class BiomeManager;
|
||||||
|
class OreManager;
|
||||||
|
class DecorationManager;
|
||||||
|
class SchematicManager;
|
||||||
|
|
||||||
struct BlockMakeData {
|
struct BlockMakeData {
|
||||||
ManualMapVoxelManipulator *vmanip;
|
ManualMapVoxelManipulator *vmanip;
|
||||||
@ -88,16 +92,18 @@ public:
|
|||||||
|
|
||||||
u32 gennotify;
|
u32 gennotify;
|
||||||
|
|
||||||
//block emerge queue data structures
|
//// Block emerge queue data structures
|
||||||
JMutex queuemutex;
|
JMutex queuemutex;
|
||||||
std::map<v3s16, BlockEmergeData *> blocks_enqueued;
|
std::map<v3s16, BlockEmergeData *> blocks_enqueued;
|
||||||
std::map<u16, u16> peer_queue_count;
|
std::map<u16, u16> peer_queue_count;
|
||||||
|
|
||||||
//Mapgen-related structures
|
//// Managers of map generation-related components
|
||||||
BiomeDefManager *biomedef;
|
BiomeManager *biomemgr;
|
||||||
std::vector<Ore *> ores;
|
OreManager *oremgr;
|
||||||
std::vector<Decoration *> decorations;
|
DecorationManager *decomgr;
|
||||||
|
SchematicManager *schemmgr;
|
||||||
|
|
||||||
|
//// Methods
|
||||||
EmergeManager(IGameDef *gamedef);
|
EmergeManager(IGameDef *gamedef);
|
||||||
~EmergeManager();
|
~EmergeManager();
|
||||||
|
|
||||||
@ -105,7 +111,7 @@ public:
|
|||||||
void initMapgens();
|
void initMapgens();
|
||||||
Mapgen *getCurrentMapgen();
|
Mapgen *getCurrentMapgen();
|
||||||
Mapgen *createMapgen(std::string mgname, int mgid,
|
Mapgen *createMapgen(std::string mgname, int mgid,
|
||||||
MapgenParams *mgparams);
|
MapgenParams *mgparams);
|
||||||
MapgenSpecificParams *createMapgenParams(std::string mgname);
|
MapgenSpecificParams *createMapgenParams(std::string mgname);
|
||||||
void startThreads();
|
void startThreads();
|
||||||
void stopThreads();
|
void stopThreads();
|
||||||
|
@ -37,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
const char *GenElementManager::ELEMENT_TITLE = "element";
|
||||||
|
|
||||||
FlagDesc flagdesc_mapgen[] = {
|
FlagDesc flagdesc_mapgen[] = {
|
||||||
{"trees", MG_TREES},
|
{"trees", MG_TREES},
|
||||||
@ -57,16 +58,10 @@ FlagDesc flagdesc_gennotify[] = {
|
|||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Mapgen::Mapgen() {
|
Mapgen::Mapgen() {
|
||||||
seed = 0;
|
seed = 0;
|
||||||
water_level = 0;
|
water_level = 0;
|
||||||
@ -283,10 +278,85 @@ void Mapgen::calcLightingOld(v3s16 nmin, v3s16 nmax) {
|
|||||||
std::map<v3s16, u8> unlight_from;
|
std::map<v3s16, u8> unlight_from;
|
||||||
|
|
||||||
voxalgo::clearLightAndCollectSources(*vm, a, bank, ndef,
|
voxalgo::clearLightAndCollectSources(*vm, a, bank, ndef,
|
||||||
light_sources, unlight_from);
|
light_sources, unlight_from);
|
||||||
voxalgo::propagateSunlight(*vm, a, sunlight, light_sources, ndef);
|
voxalgo::propagateSunlight(*vm, a, sunlight, light_sources, ndef);
|
||||||
|
|
||||||
vm->unspreadLight(bank, unlight_from, light_sources, ndef);
|
vm->unspreadLight(bank, unlight_from, light_sources, ndef);
|
||||||
vm->spreadLight(bank, light_sources, ndef);
|
vm->spreadLight(bank, light_sources, ndef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
GenElementManager::~GenElementManager()
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i != m_elements.size(); i++)
|
||||||
|
delete m_elements[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u32 GenElementManager::add(GenElement *elem)
|
||||||
|
{
|
||||||
|
size_t nelem = m_elements.size();
|
||||||
|
|
||||||
|
for (size_t i = 0; i != nelem; i++) {
|
||||||
|
if (m_elements[i] == NULL) {
|
||||||
|
elem->id = i;
|
||||||
|
m_elements[i] = elem;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nelem >= this->ELEMENT_LIMIT)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
elem->id = nelem;
|
||||||
|
m_elements.push_back(elem);
|
||||||
|
|
||||||
|
verbosestream << "GenElementManager: added " << this->ELEMENT_TITLE
|
||||||
|
<< " element '" << elem->name << "'" << std::endl;
|
||||||
|
|
||||||
|
return nelem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenElement *GenElementManager::get(u32 id)
|
||||||
|
{
|
||||||
|
return (id < m_elements.size()) ? m_elements[id] : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenElement *GenElementManager::getByName(const char *name)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i != m_elements.size(); i++) {
|
||||||
|
GenElement *elem = m_elements[i];
|
||||||
|
if (elem && !strcmp(elem->name.c_str(), name))
|
||||||
|
return elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GenElement *GenElementManager::getByName(std::string &name)
|
||||||
|
{
|
||||||
|
return getByName(name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenElement *GenElementManager::update(u32 id, GenElement *elem)
|
||||||
|
{
|
||||||
|
if (id >= m_elements.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
GenElement *old_elem = m_elements[id];
|
||||||
|
m_elements[id] = elem;
|
||||||
|
return old_elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GenElement *GenElementManager::remove(u32 id)
|
||||||
|
{
|
||||||
|
return update(id, NULL);
|
||||||
|
}
|
||||||
|
43
src/mapgen.h
43
src/mapgen.h
@ -20,13 +20,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#ifndef MAPGEN_HEADER
|
#ifndef MAPGEN_HEADER
|
||||||
#define MAPGEN_HEADER
|
#define MAPGEN_HEADER
|
||||||
|
|
||||||
#include "irrlichttypes_bloated.h"
|
|
||||||
#include "util/container.h" // UniqueQueue
|
|
||||||
#include "gamedef.h"
|
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
#include "mapnode.h"
|
#include "mapnode.h"
|
||||||
#include "noise.h"
|
#include "util/string.h"
|
||||||
#include "settings.h"
|
#include "util/container.h"
|
||||||
|
|
||||||
#define DEFAULT_MAPGEN "v6"
|
#define DEFAULT_MAPGEN "v6"
|
||||||
|
|
||||||
@ -39,11 +36,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#define NUM_GEN_NOTIFY 6
|
#define NUM_GEN_NOTIFY 6
|
||||||
|
|
||||||
|
class Settings;
|
||||||
|
class ManualMapVoxelManipulator;
|
||||||
|
class INodeDefManager;
|
||||||
|
|
||||||
extern FlagDesc flagdesc_mapgen[];
|
extern FlagDesc flagdesc_mapgen[];
|
||||||
extern FlagDesc flagdesc_gennotify[];
|
extern FlagDesc flagdesc_gennotify[];
|
||||||
|
|
||||||
class BiomeDefManager;
|
|
||||||
class Biome;
|
class Biome;
|
||||||
class EmergeManager;
|
class EmergeManager;
|
||||||
class MapBlock;
|
class MapBlock;
|
||||||
@ -53,7 +52,6 @@ struct BlockMakeData;
|
|||||||
class VoxelArea;
|
class VoxelArea;
|
||||||
class Map;
|
class Map;
|
||||||
|
|
||||||
|
|
||||||
enum MapgenObject {
|
enum MapgenObject {
|
||||||
MGOBJ_VMANIP,
|
MGOBJ_VMANIP,
|
||||||
MGOBJ_HEIGHTMAP,
|
MGOBJ_HEIGHTMAP,
|
||||||
@ -131,10 +129,37 @@ public:
|
|||||||
|
|
||||||
struct MapgenFactory {
|
struct MapgenFactory {
|
||||||
virtual Mapgen *createMapgen(int mgid, MapgenParams *params,
|
virtual Mapgen *createMapgen(int mgid, MapgenParams *params,
|
||||||
EmergeManager *emerge) = 0;
|
EmergeManager *emerge) = 0;
|
||||||
virtual MapgenSpecificParams *createMapgenParams() = 0;
|
virtual MapgenSpecificParams *createMapgenParams() = 0;
|
||||||
virtual ~MapgenFactory() {}
|
virtual ~MapgenFactory() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
class GenElement {
|
||||||
|
public:
|
||||||
|
uint32_t id;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GenElementManager {
|
||||||
|
public:
|
||||||
|
static const char *ELEMENT_TITLE;
|
||||||
|
static const size_t ELEMENT_LIMIT = -1;
|
||||||
|
|
||||||
|
GenElementManager() {}
|
||||||
|
virtual ~GenElementManager();
|
||||||
|
|
||||||
|
virtual GenElement *create(int type) = 0;
|
||||||
|
|
||||||
|
virtual u32 add(GenElement *elem);
|
||||||
|
virtual GenElement *get(u32 id);
|
||||||
|
virtual GenElement *update(u32 id, GenElement *elem);
|
||||||
|
virtual GenElement *remove(u32 id);
|
||||||
|
|
||||||
|
virtual GenElement *getByName(const char *name);
|
||||||
|
virtual GenElement *getByName(std::string &name);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<GenElement *> m_elements;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -51,7 +51,7 @@ MapgenV5::MapgenV5(int mapgenid, MapgenParams *params, EmergeManager *emerge_) {
|
|||||||
this->generating = false;
|
this->generating = false;
|
||||||
this->id = mapgenid;
|
this->id = mapgenid;
|
||||||
this->emerge = emerge_;
|
this->emerge = emerge_;
|
||||||
this->bmgr = emerge->biomedef;
|
this->bmgr = emerge->biomemgr;
|
||||||
|
|
||||||
this->seed = (int)params->seed;
|
this->seed = (int)params->seed;
|
||||||
this->water_level = params->water_level;
|
this->water_level = params->water_level;
|
||||||
@ -247,16 +247,10 @@ void MapgenV5::makeChunk(BlockMakeData *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate the registered decorations
|
// Generate the registered decorations
|
||||||
for (size_t i = 0; i != emerge->decorations.size(); i++) {
|
emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
|
||||||
Decoration *deco = emerge->decorations[i];
|
|
||||||
deco->placeDeco(this, blockseed + i, node_min, node_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the registered ores
|
// Generate the registered ores
|
||||||
for (unsigned int i = 0; i != emerge->ores.size(); i++) {
|
emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
|
||||||
Ore *ore = emerge->ores[i];
|
|
||||||
ore->placeOre(this, blockseed + i, node_min, node_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprinkle some dust on top after everything else was generated
|
// Sprinkle some dust on top after everything else was generated
|
||||||
dustTopNodes();
|
dustTopNodes();
|
||||||
@ -405,7 +399,7 @@ void MapgenV5::generateBiomes() {
|
|||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
Biome *biome = bmgr->biomes[biomemap[index]];
|
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||||
s16 dfiller = biome->depth_filler + noise_filler_depth->result[index];
|
s16 dfiller = biome->depth_filler + noise_filler_depth->result[index];
|
||||||
s16 y0_top = biome->depth_top;
|
s16 y0_top = biome->depth_top;
|
||||||
s16 y0_filler = biome->depth_filler + biome->depth_top + dfiller;
|
s16 y0_filler = biome->depth_filler + biome->depth_top + dfiller;
|
||||||
@ -467,7 +461,7 @@ void MapgenV5::dustTopNodes() {
|
|||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
Biome *biome = bmgr->biomes[biomemap[index]];
|
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||||
|
|
||||||
if (biome->c_dust == CONTENT_IGNORE)
|
if (biome->c_dust == CONTENT_IGNORE)
|
||||||
continue;
|
continue;
|
||||||
|
@ -50,7 +50,7 @@ struct MapgenV5Params : public MapgenSpecificParams {
|
|||||||
class MapgenV5 : public Mapgen {
|
class MapgenV5 : public Mapgen {
|
||||||
public:
|
public:
|
||||||
EmergeManager *emerge;
|
EmergeManager *emerge;
|
||||||
BiomeDefManager *bmgr;
|
BiomeManager *bmgr;
|
||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
int zstride;
|
int zstride;
|
||||||
|
@ -537,16 +537,10 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
|
|||||||
placeTreesAndJungleGrass();
|
placeTreesAndJungleGrass();
|
||||||
|
|
||||||
// Generate the registered decorations
|
// Generate the registered decorations
|
||||||
for (unsigned int i = 0; i != emerge->decorations.size(); i++) {
|
emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
|
||||||
Decoration *deco = emerge->decorations[i];
|
|
||||||
deco->placeDeco(this, blockseed + i, node_min, node_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the registered ores
|
// Generate the registered ores
|
||||||
for (unsigned int i = 0; i != emerge->ores.size(); i++) {
|
emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
|
||||||
Ore *ore = emerge->ores[i];
|
|
||||||
ore->placeOre(this, blockseed + i, node_min, node_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate lighting
|
// Calculate lighting
|
||||||
if (flags & MG_LIGHT)
|
if (flags & MG_LIGHT)
|
||||||
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define MAPGENV6_HEADER
|
#define MAPGENV6_HEADER
|
||||||
|
|
||||||
#include "mapgen.h"
|
#include "mapgen.h"
|
||||||
|
#include "noise.h"
|
||||||
|
|
||||||
#define AVERAGE_MUD_AMOUNT 4
|
#define AVERAGE_MUD_AMOUNT 4
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge) {
|
|||||||
this->generating = false;
|
this->generating = false;
|
||||||
this->id = mapgenid;
|
this->id = mapgenid;
|
||||||
this->emerge = emerge;
|
this->emerge = emerge;
|
||||||
this->bmgr = emerge->biomedef;
|
this->bmgr = emerge->biomemgr;
|
||||||
|
|
||||||
this->seed = (int)params->seed;
|
this->seed = (int)params->seed;
|
||||||
this->water_level = params->water_level;
|
this->water_level = params->water_level;
|
||||||
@ -250,16 +250,12 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
|
|||||||
dgen.generate(blockseed, full_node_min, full_node_max);
|
dgen.generate(blockseed, full_node_min, full_node_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i != emerge->decorations.size(); i++) {
|
// Generate the registered decorations
|
||||||
Decoration *deco = emerge->decorations[i];
|
emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max);
|
||||||
deco->placeDeco(this, blockseed + i, node_min, node_max);
|
|
||||||
}
|
// Generate the registered ores
|
||||||
|
emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max);
|
||||||
|
|
||||||
for (size_t i = 0; i != emerge->ores.size(); i++) {
|
|
||||||
Ore *ore = emerge->ores[i];
|
|
||||||
ore->placeOre(this, blockseed + i, node_min, node_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sprinkle some dust on top after everything else was generated
|
// Sprinkle some dust on top after everything else was generated
|
||||||
dustTopNodes();
|
dustTopNodes();
|
||||||
|
|
||||||
@ -538,11 +534,11 @@ void MapgenV7::generateBiomes() {
|
|||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
Biome *biome = bmgr->biomes[biomemap[index]];
|
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||||
s16 dfiller = biome->depth_filler + noise_filler_depth->result[index];
|
s16 dfiller = biome->depth_filler + noise_filler_depth->result[index];
|
||||||
s16 y0_top = biome->depth_top;
|
s16 y0_top = biome->depth_top;
|
||||||
s16 y0_filler = biome->depth_filler + biome->depth_top + dfiller;
|
s16 y0_filler = biome->depth_filler + biome->depth_top + dfiller;
|
||||||
|
|
||||||
s16 nplaced = 0;
|
s16 nplaced = 0;
|
||||||
u32 i = vm->m_area.index(x, node_max.Y, z);
|
u32 i = vm->m_area.index(x, node_max.Y, z);
|
||||||
|
|
||||||
@ -607,7 +603,7 @@ void MapgenV7::dustTopNodes() {
|
|||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++) {
|
||||||
Biome *biome = bmgr->biomes[biomemap[index]];
|
Biome *biome = (Biome *)bmgr->get(biomemap[index]);
|
||||||
|
|
||||||
if (biome->c_dust == CONTENT_IGNORE)
|
if (biome->c_dust == CONTENT_IGNORE)
|
||||||
continue;
|
continue;
|
||||||
|
@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define MGV7_MOUNTAINS 0x01
|
#define MGV7_MOUNTAINS 0x01
|
||||||
#define MGV7_RIDGES 0x02
|
#define MGV7_RIDGES 0x02
|
||||||
|
|
||||||
|
class BiomeManager;
|
||||||
|
|
||||||
extern FlagDesc flagdesc_mapgen_v7[];
|
extern FlagDesc flagdesc_mapgen_v7[];
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ struct MapgenV7Params : public MapgenSpecificParams {
|
|||||||
class MapgenV7 : public Mapgen {
|
class MapgenV7 : public Mapgen {
|
||||||
public:
|
public:
|
||||||
EmergeManager *emerge;
|
EmergeManager *emerge;
|
||||||
BiomeDefManager *bmgr;
|
BiomeManager *bmgr;
|
||||||
|
|
||||||
int ystride;
|
int ystride;
|
||||||
int zstride;
|
int zstride;
|
||||||
|
@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mg_biome.h"
|
#include "mg_biome.h"
|
||||||
|
#include "gamedef.h"
|
||||||
#include "nodedef.h"
|
#include "nodedef.h"
|
||||||
#include "map.h" //for ManualMapVoxelManipulator
|
#include "map.h" //for ManualMapVoxelManipulator
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -26,19 +27,25 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "util/mathconstants.h"
|
#include "util/mathconstants.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
|
|
||||||
|
const char *BiomeManager::ELEMENT_TITLE = "biome";
|
||||||
|
|
||||||
NoiseParams nparams_biome_def_heat(50, 50, v3f(500.0, 500.0, 500.0), 5349, 3, 0.70);
|
NoiseParams nparams_biome_def_heat(50, 50, v3f(500.0, 500.0, 500.0), 5349, 3, 0.70);
|
||||||
NoiseParams nparams_biome_def_humidity(50, 50, v3f(500.0, 500.0, 500.0), 842, 3, 0.55);
|
NoiseParams nparams_biome_def_humidity(50, 50, v3f(500.0, 500.0, 500.0), 842, 3, 0.55);
|
||||||
|
|
||||||
|
|
||||||
BiomeDefManager::BiomeDefManager(NodeResolver *resolver)
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
BiomeManager::BiomeManager(IGameDef *gamedef)
|
||||||
{
|
{
|
||||||
biome_registration_finished = false;
|
NodeResolver *resolver = gamedef->getNodeDefManager()->getResolver();
|
||||||
|
|
||||||
np_heat = &nparams_biome_def_heat;
|
np_heat = &nparams_biome_def_heat;
|
||||||
np_humidity = &nparams_biome_def_humidity;
|
np_humidity = &nparams_biome_def_humidity;
|
||||||
|
|
||||||
// Create default biome to be used in case none exist
|
// Create default biome to be used in case none exist
|
||||||
Biome *b = new Biome;
|
Biome *b = new Biome;
|
||||||
|
|
||||||
b->id = 0;
|
b->id = 0;
|
||||||
b->name = "Default";
|
b->name = "Default";
|
||||||
b->flags = 0;
|
b->flags = 0;
|
||||||
@ -55,41 +62,21 @@ BiomeDefManager::BiomeDefManager(NodeResolver *resolver)
|
|||||||
resolver->addNode("air", "", CONTENT_AIR, &b->c_dust);
|
resolver->addNode("air", "", CONTENT_AIR, &b->c_dust);
|
||||||
resolver->addNode("mapgen_water_source", "", CONTENT_AIR, &b->c_dust_water);
|
resolver->addNode("mapgen_water_source", "", CONTENT_AIR, &b->c_dust_water);
|
||||||
|
|
||||||
biomes.push_back(b);
|
add(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BiomeDefManager::~BiomeDefManager()
|
|
||||||
|
BiomeManager::~BiomeManager()
|
||||||
{
|
{
|
||||||
//if (biomecache)
|
//if (biomecache)
|
||||||
// delete[] biomecache;
|
// delete[] biomecache;
|
||||||
|
|
||||||
for (size_t i = 0; i != biomes.size(); i++)
|
|
||||||
delete biomes[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Biome *BiomeDefManager::createBiome(BiomeTerrainType btt)
|
|
||||||
{
|
|
||||||
/*switch (btt) {
|
|
||||||
case BIOME_TERRAIN_NORMAL:
|
|
||||||
return new Biome;
|
|
||||||
case BIOME_TERRAIN_LIQUID:
|
|
||||||
return new BiomeLiquid;
|
|
||||||
case BIOME_TERRAIN_NETHER:
|
|
||||||
return new BiomeHell;
|
|
||||||
case BIOME_TERRAIN_AETHER:
|
|
||||||
return new BiomeSky;
|
|
||||||
case BIOME_TERRAIN_FLAT:
|
|
||||||
return new BiomeSuperflat;
|
|
||||||
}
|
|
||||||
return NULL;*/
|
|
||||||
return new Biome;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// just a PoC, obviously needs optimization later on (precalculate this)
|
// just a PoC, obviously needs optimization later on (precalculate this)
|
||||||
void BiomeDefManager::calcBiomes(BiomeNoiseInput *input, u8 *biomeid_map)
|
void BiomeManager::calcBiomes(BiomeNoiseInput *input, u8 *biomeid_map)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (int y = 0; y != input->mapsize.Y; y++) {
|
for (int y = 0; y != input->mapsize.Y; y++) {
|
||||||
@ -102,38 +89,17 @@ void BiomeDefManager::calcBiomes(BiomeNoiseInput *input, u8 *biomeid_map)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BiomeDefManager::addBiome(Biome *b)
|
Biome *BiomeManager::getBiome(float heat, float humidity, s16 y)
|
||||||
{
|
|
||||||
if (biome_registration_finished) {
|
|
||||||
errorstream << "BiomeDefManager: biome registration already "
|
|
||||||
"finished, dropping " << b->name << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nbiomes = biomes.size();
|
|
||||||
if (nbiomes >= 0xFF) {
|
|
||||||
errorstream << "BiomeDefManager: too many biomes, dropping "
|
|
||||||
<< b->name << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
b->id = (u8)nbiomes;
|
|
||||||
biomes.push_back(b);
|
|
||||||
verbosestream << "BiomeDefManager: added biome " << b->name << std::endl;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Biome *BiomeDefManager::getBiome(float heat, float humidity, s16 y)
|
|
||||||
{
|
{
|
||||||
Biome *b, *biome_closest = NULL;
|
Biome *b, *biome_closest = NULL;
|
||||||
float dist_min = FLT_MAX;
|
float dist_min = FLT_MAX;
|
||||||
|
|
||||||
for (size_t i = 1; i < biomes.size(); i++) {
|
for (size_t i = 1; i < m_elements.size(); i++) {
|
||||||
b = biomes[i];
|
b = (Biome *)m_elements[i];
|
||||||
if (y > b->height_max || y < b->height_min)
|
if (!b || y > b->height_max || y < b->height_min) {
|
||||||
|
printf("not good - %p %d %d %d\n", b, y, b->height_max, b->height_min);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
float d_heat = heat - b->heat_point;
|
float d_heat = heat - b->heat_point;
|
||||||
float d_humidity = humidity - b->humidity_point;
|
float d_humidity = humidity - b->humidity_point;
|
||||||
@ -145,16 +111,5 @@ Biome *BiomeDefManager::getBiome(float heat, float humidity, s16 y)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return biome_closest ? biome_closest : biomes[0];
|
return biome_closest ? biome_closest : (Biome *)m_elements[0];
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
u8 BiomeDefManager::getBiomeIdByName(const char *name)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i != biomes.size(); i++) {
|
|
||||||
if (!strcasecmp(name, biomes[i]->name.c_str()))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#ifndef MG_BIOME_HEADER
|
#ifndef MG_BIOME_HEADER
|
||||||
#define MG_BIOME_HEADER
|
#define MG_BIOME_HEADER
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include "nodedef.h"
|
|
||||||
#include "gamedef.h"
|
|
||||||
#include "mapnode.h"
|
|
||||||
#include "noise.h"
|
|
||||||
#include "mapgen.h"
|
#include "mapgen.h"
|
||||||
|
#include "noise.h"
|
||||||
|
|
||||||
|
//#include <string>
|
||||||
|
//#include "nodedef.h"
|
||||||
|
//#include "gamedef.h"
|
||||||
|
//#include "mapnode.h"
|
||||||
|
|
||||||
enum BiomeTerrainType
|
enum BiomeTerrainType
|
||||||
{
|
{
|
||||||
@ -39,10 +40,16 @@ enum BiomeTerrainType
|
|||||||
extern NoiseParams nparams_biome_def_heat;
|
extern NoiseParams nparams_biome_def_heat;
|
||||||
extern NoiseParams nparams_biome_def_humidity;
|
extern NoiseParams nparams_biome_def_humidity;
|
||||||
|
|
||||||
class Biome {
|
|
||||||
|
struct BiomeNoiseInput {
|
||||||
|
v2s16 mapsize;
|
||||||
|
float *heat_map;
|
||||||
|
float *humidity_map;
|
||||||
|
s16 *height_map;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Biome : public GenElement {
|
||||||
public:
|
public:
|
||||||
u8 id;
|
|
||||||
std::string name;
|
|
||||||
u32 flags;
|
u32 flags;
|
||||||
|
|
||||||
content_t c_top;
|
content_t c_top;
|
||||||
@ -60,33 +67,24 @@ public:
|
|||||||
float humidity_point;
|
float humidity_point;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BiomeNoiseInput {
|
class BiomeManager : public GenElementManager {
|
||||||
v2s16 mapsize;
|
|
||||||
float *heat_map;
|
|
||||||
float *humidity_map;
|
|
||||||
s16 *height_map;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BiomeDefManager {
|
|
||||||
public:
|
public:
|
||||||
std::vector<Biome *> biomes;
|
static const char *ELEMENT_TITLE;
|
||||||
|
static const size_t ELEMENT_LIMIT = 0x100;
|
||||||
|
|
||||||
bool biome_registration_finished;
|
|
||||||
NoiseParams *np_heat;
|
NoiseParams *np_heat;
|
||||||
NoiseParams *np_humidity;
|
NoiseParams *np_humidity;
|
||||||
|
|
||||||
BiomeDefManager(NodeResolver *resolver);
|
BiomeManager(IGameDef *gamedef);
|
||||||
~BiomeDefManager();
|
~BiomeManager();
|
||||||
|
|
||||||
Biome *createBiome(BiomeTerrainType btt);
|
Biome *create(int btt)
|
||||||
void calcBiomes(BiomeNoiseInput *input, u8 *biomeid_map);
|
{
|
||||||
|
return new Biome;
|
||||||
|
}
|
||||||
|
|
||||||
|
void calcBiomes(BiomeNoiseInput *input, u8 *biomeid_map);
|
||||||
Biome *getBiome(float heat, float humidity, s16 y);
|
Biome *getBiome(float heat, float humidity, s16 y);
|
||||||
|
|
||||||
bool addBiome(Biome *b);
|
|
||||||
u8 getBiomeIdByName(const char *name);
|
|
||||||
|
|
||||||
s16 calcBlockHeat(v3s16 p, u64 seed, float timeofday, float totaltime);
|
|
||||||
s16 calcBlockHumidity(v3s16 p, u64 seed, float timeofday, float totaltime);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,28 +20,44 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "mg_decoration.h"
|
#include "mg_decoration.h"
|
||||||
#include "mg_schematic.h"
|
#include "mg_schematic.h"
|
||||||
#include "mapgen.h"
|
#include "mapgen.h"
|
||||||
|
#include "noise.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
|
|
||||||
|
const char *DecorationManager::ELEMENT_TITLE = "decoration";
|
||||||
|
|
||||||
|
FlagDesc flagdesc_deco_schematic[] = {
|
||||||
|
{"place_center_x", DECO_PLACE_CENTER_X},
|
||||||
|
{"place_center_y", DECO_PLACE_CENTER_Y},
|
||||||
|
{"place_center_z", DECO_PLACE_CENTER_Z},
|
||||||
|
{NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
Decoration *createDecoration(DecorationType type)
|
size_t DecorationManager::placeAllDecos(Mapgen *mg, u32 seed, v3s16 nmin, v3s16 nmax)
|
||||||
{
|
{
|
||||||
switch (type) {
|
size_t nplaced = 0;
|
||||||
case DECO_SIMPLE:
|
|
||||||
return new DecoSimple;
|
for (size_t i = 0; i != m_elements.size(); i++) {
|
||||||
case DECO_SCHEMATIC:
|
Decoration *deco = (Decoration *)m_elements[i];
|
||||||
return new DecoSchematic;
|
if (!deco)
|
||||||
//case DECO_LSYSTEM:
|
continue;
|
||||||
// return new DecoLSystem;
|
|
||||||
default:
|
nplaced += deco->placeDeco(mg, seed, nmin, nmax);
|
||||||
return NULL;
|
seed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nplaced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
Decoration::Decoration()
|
Decoration::Decoration()
|
||||||
{
|
{
|
||||||
mapseed = 0;
|
mapseed = 0;
|
||||||
@ -57,7 +73,7 @@ Decoration::~Decoration()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
size_t Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
||||||
{
|
{
|
||||||
PseudoRandom ps(blockseed + 53);
|
PseudoRandom ps(blockseed + 53);
|
||||||
int carea_size = nmax.X - nmin.X + 1;
|
int carea_size = nmax.X - nmin.X + 1;
|
||||||
@ -131,6 +147,8 @@ void Decoration::placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
|||||||
generate(mg, &ps, max_y, v3s16(x, y, z));
|
generate(mg, &ps, max_y, v3s16(x, y, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -190,6 +208,7 @@ void Decoration::placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
bool DecoSimple::canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p)
|
bool DecoSimple::canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p)
|
||||||
{
|
{
|
||||||
// Don't bother if there aren't any decorations to place
|
// Don't bother if there aren't any decorations to place
|
||||||
@ -269,7 +288,33 @@ int DecoSimple::getHeight()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string DecoSimple::getName()
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
void DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
|
||||||
{
|
{
|
||||||
return "";
|
ManualMapVoxelManipulator *vm = mg->vm;
|
||||||
|
|
||||||
|
if (flags & DECO_PLACE_CENTER_X)
|
||||||
|
p.X -= (schematic->size.X + 1) / 2;
|
||||||
|
if (flags & DECO_PLACE_CENTER_Y)
|
||||||
|
p.Y -= (schematic->size.Y + 1) / 2;
|
||||||
|
if (flags & DECO_PLACE_CENTER_Z)
|
||||||
|
p.Z -= (schematic->size.Z + 1) / 2;
|
||||||
|
|
||||||
|
u32 vi = vm->m_area.index(p);
|
||||||
|
content_t c = vm->m_data[vi].getContent();
|
||||||
|
if (!CONTAINS(c_place_on, c))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Rotation rot = (rotation == ROTATE_RAND) ?
|
||||||
|
(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
|
||||||
|
|
||||||
|
schematic->blitToVManip(p, vm, rot, false, mg->ndef);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int DecoSchematic::getHeight()
|
||||||
|
{
|
||||||
|
return schematic->size.Y;
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define MG_DECORATION_HEADER
|
#define MG_DECORATION_HEADER
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "mapnode.h"
|
#include "mapgen.h"
|
||||||
|
|
||||||
class NoiseParams;
|
class NoiseParams;
|
||||||
class Mapgen;
|
class Mapgen;
|
||||||
class ManualMapVoxelManipulator;
|
class ManualMapVoxelManipulator;
|
||||||
class PseudoRandom;
|
class PseudoRandom;
|
||||||
|
class Schematic;
|
||||||
|
|
||||||
enum DecorationType {
|
enum DecorationType {
|
||||||
DECO_SIMPLE,
|
DECO_SIMPLE,
|
||||||
@ -34,6 +35,13 @@ enum DecorationType {
|
|||||||
DECO_LSYSTEM
|
DECO_LSYSTEM
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DECO_PLACE_CENTER_X 0x01
|
||||||
|
#define DECO_PLACE_CENTER_Y 0x02
|
||||||
|
#define DECO_PLACE_CENTER_Z 0x04
|
||||||
|
|
||||||
|
extern FlagDesc flagdesc_deco_schematic[];
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
struct CutoffData {
|
struct CutoffData {
|
||||||
VoxelArea a;
|
VoxelArea a;
|
||||||
@ -49,7 +57,7 @@ struct CutoffData {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Decoration {
|
class Decoration : public GenElement {
|
||||||
public:
|
public:
|
||||||
INodeDefManager *ndef;
|
INodeDefManager *ndef;
|
||||||
|
|
||||||
@ -66,12 +74,11 @@ public:
|
|||||||
Decoration();
|
Decoration();
|
||||||
virtual ~Decoration();
|
virtual ~Decoration();
|
||||||
|
|
||||||
void placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
size_t placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
||||||
void placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
size_t placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
||||||
|
|
||||||
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) = 0;
|
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p) = 0;
|
||||||
virtual int getHeight() = 0;
|
virtual int getHeight() = 0;
|
||||||
virtual std::string getName() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DecoSimple : public Decoration {
|
class DecoSimple : public Decoration {
|
||||||
@ -87,9 +94,22 @@ public:
|
|||||||
bool canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p);
|
bool canPlaceDecoration(ManualMapVoxelManipulator *vm, v3s16 p);
|
||||||
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
|
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
|
||||||
virtual int getHeight();
|
virtual int getHeight();
|
||||||
virtual std::string getName();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DecoSchematic : public Decoration {
|
||||||
|
public:
|
||||||
|
u32 flags;
|
||||||
|
Rotation rotation;
|
||||||
|
Schematic *schematic;
|
||||||
|
std::string filename;
|
||||||
|
|
||||||
|
~DecoSchematic() {}
|
||||||
|
|
||||||
|
void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
|
||||||
|
virtual int getHeight();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
class DecoLSystem : public Decoration {
|
class DecoLSystem : public Decoration {
|
||||||
public:
|
public:
|
||||||
@ -97,6 +117,29 @@ public:
|
|||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Decoration *createDecoration(DecorationType type);
|
class DecorationManager : public GenElementManager {
|
||||||
|
public:
|
||||||
|
static const char *ELEMENT_TITLE;
|
||||||
|
static const size_t ELEMENT_LIMIT = 0x10000;
|
||||||
|
|
||||||
|
DecorationManager(IGameDef *gamedef) {}
|
||||||
|
~DecorationManager() {}
|
||||||
|
|
||||||
|
Decoration *create(int type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case DECO_SIMPLE:
|
||||||
|
return new DecoSimple;
|
||||||
|
case DECO_SCHEMATIC:
|
||||||
|
return new DecoSchematic;
|
||||||
|
//case DECO_LSYSTEM:
|
||||||
|
// return new DecoLSystem;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t placeAllDecos(Mapgen *mg, u32 seed, v3s16 nmin, v3s16 nmax);
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,10 +19,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "mg_ore.h"
|
#include "mg_ore.h"
|
||||||
#include "mapgen.h"
|
#include "mapgen.h"
|
||||||
|
#include "noise.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
const char *OreManager::ELEMENT_TITLE = "ore";
|
||||||
|
|
||||||
FlagDesc flagdesc_ore[] = {
|
FlagDesc flagdesc_ore[] = {
|
||||||
{"absheight", OREFLAG_ABSHEIGHT},
|
{"absheight", OREFLAG_ABSHEIGHT},
|
||||||
@ -31,24 +33,36 @@ FlagDesc flagdesc_ore[] = {
|
|||||||
{NULL, 0}
|
{NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
Ore *createOre(OreType type)
|
size_t OreManager::placeAllOres(Mapgen *mg, u32 seed, v3s16 nmin, v3s16 nmax)
|
||||||
{
|
{
|
||||||
switch (type) {
|
size_t nplaced = 0;
|
||||||
case ORE_SCATTER:
|
|
||||||
return new OreScatter;
|
for (size_t i = 0; i != m_elements.size(); i++) {
|
||||||
case ORE_SHEET:
|
Ore *ore = (Ore *)m_elements[i];
|
||||||
return new OreSheet;
|
if (!ore)
|
||||||
//case ORE_CLAYLIKE: //TODO: implement this!
|
continue;
|
||||||
// return new OreClaylike;
|
|
||||||
default:
|
nplaced += ore->placeOre(mg, seed, nmin, nmax);
|
||||||
return NULL;
|
seed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nplaced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Ore::Ore()
|
||||||
|
{
|
||||||
|
c_ore = CONTENT_IGNORE;
|
||||||
|
np = NULL;
|
||||||
|
noise = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Ore::~Ore()
|
Ore::~Ore()
|
||||||
{
|
{
|
||||||
delete np;
|
delete np;
|
||||||
@ -56,7 +70,13 @@ Ore::~Ore()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
std::string Ore::getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
||||||
{
|
{
|
||||||
int in_range = 0;
|
int in_range = 0;
|
||||||
|
|
||||||
@ -64,7 +84,7 @@ void Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
|||||||
if (flags & OREFLAG_ABSHEIGHT)
|
if (flags & OREFLAG_ABSHEIGHT)
|
||||||
in_range |= (nmin.Y >= -height_max && nmax.Y <= -height_min) << 1;
|
in_range |= (nmin.Y >= -height_max && nmax.Y <= -height_min) << 1;
|
||||||
if (!in_range)
|
if (!in_range)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
int ymin, ymax;
|
int ymin, ymax;
|
||||||
if (in_range & ORE_RANGE_MIRROR) {
|
if (in_range & ORE_RANGE_MIRROR) {
|
||||||
@ -75,11 +95,13 @@ void Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax)
|
|||||||
ymax = MYMIN(nmax.Y, height_max);
|
ymax = MYMIN(nmax.Y, height_max);
|
||||||
}
|
}
|
||||||
if (clust_size >= ymax - ymin + 1)
|
if (clust_size >= ymax - ymin + 1)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
nmin.Y = ymin;
|
nmin.Y = ymin;
|
||||||
nmax.Y = ymax;
|
nmax.Y = ymax;
|
||||||
generate(mg->vm, mg->seed, blockseed, nmin, nmax);
|
generate(mg->vm, mg->seed, blockseed, nmin, nmax);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
48
src/mg_ore.h
48
src/mg_ore.h
@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define MG_ORE_HEADER
|
#define MG_ORE_HEADER
|
||||||
|
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
#include "mapnode.h"
|
#include "mapgen.h"
|
||||||
|
|
||||||
class NoiseParams;
|
class NoiseParams;
|
||||||
class Noise;
|
class Noise;
|
||||||
@ -29,10 +29,13 @@ class Mapgen;
|
|||||||
class ManualMapVoxelManipulator;
|
class ManualMapVoxelManipulator;
|
||||||
|
|
||||||
/////////////////// Ore generation flags
|
/////////////////// Ore generation flags
|
||||||
|
|
||||||
// Use absolute value of height to determine ore placement
|
// Use absolute value of height to determine ore placement
|
||||||
#define OREFLAG_ABSHEIGHT 0x01
|
#define OREFLAG_ABSHEIGHT 0x01
|
||||||
|
|
||||||
// Use 3d noise to get density of ore placement, instead of just the position
|
// Use 3d noise to get density of ore placement, instead of just the position
|
||||||
#define OREFLAG_DENSITY 0x02 // not yet implemented
|
#define OREFLAG_DENSITY 0x02 // not yet implemented
|
||||||
|
|
||||||
// For claylike ore types, place ore if the number of surrounding
|
// For claylike ore types, place ore if the number of surrounding
|
||||||
// nodes isn't the specified node
|
// nodes isn't the specified node
|
||||||
#define OREFLAG_NODEISNT 0x04 // not yet implemented
|
#define OREFLAG_NODEISNT 0x04 // not yet implemented
|
||||||
@ -40,7 +43,6 @@ class ManualMapVoxelManipulator;
|
|||||||
#define ORE_RANGE_ACTUAL 1
|
#define ORE_RANGE_ACTUAL 1
|
||||||
#define ORE_RANGE_MIRROR 2
|
#define ORE_RANGE_MIRROR 2
|
||||||
|
|
||||||
extern FlagDesc flagdesc_ore[];
|
|
||||||
|
|
||||||
enum OreType {
|
enum OreType {
|
||||||
ORE_SCATTER,
|
ORE_SCATTER,
|
||||||
@ -48,7 +50,9 @@ enum OreType {
|
|||||||
ORE_CLAYLIKE
|
ORE_CLAYLIKE
|
||||||
};
|
};
|
||||||
|
|
||||||
class Ore {
|
extern FlagDesc flagdesc_ore[];
|
||||||
|
|
||||||
|
class Ore : public GenElement {
|
||||||
public:
|
public:
|
||||||
content_t c_ore; // the node to place
|
content_t c_ore; // the node to place
|
||||||
std::vector<content_t> c_wherein; // the nodes to be placed in
|
std::vector<content_t> c_wherein; // the nodes to be placed in
|
||||||
@ -63,32 +67,50 @@ public:
|
|||||||
NoiseParams *np; // noise for distribution of clusters (NULL for uniform scattering)
|
NoiseParams *np; // noise for distribution of clusters (NULL for uniform scattering)
|
||||||
Noise *noise;
|
Noise *noise;
|
||||||
|
|
||||||
Ore() {
|
Ore();
|
||||||
c_ore = CONTENT_IGNORE;
|
|
||||||
np = NULL;
|
|
||||||
noise = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~Ore();
|
virtual ~Ore();
|
||||||
|
|
||||||
void placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
size_t placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
||||||
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
|
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
|
||||||
u32 blockseed, v3s16 nmin, v3s16 nmax) = 0;
|
u32 blockseed, v3s16 nmin, v3s16 nmax) = 0;
|
||||||
|
virtual std::string getName();
|
||||||
};
|
};
|
||||||
|
|
||||||
class OreScatter : public Ore {
|
class OreScatter : public Ore {
|
||||||
~OreScatter() {}
|
virtual ~OreScatter() {}
|
||||||
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
|
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
|
||||||
u32 blockseed, v3s16 nmin, v3s16 nmax);
|
u32 blockseed, v3s16 nmin, v3s16 nmax);
|
||||||
};
|
};
|
||||||
|
|
||||||
class OreSheet : public Ore {
|
class OreSheet : public Ore {
|
||||||
~OreSheet() {}
|
virtual ~OreSheet() {}
|
||||||
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
|
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
|
||||||
u32 blockseed, v3s16 nmin, v3s16 nmax);
|
u32 blockseed, v3s16 nmin, v3s16 nmax);
|
||||||
};
|
};
|
||||||
|
|
||||||
Ore *createOre(OreType type);
|
class OreManager : public GenElementManager {
|
||||||
|
public:
|
||||||
|
static const char *ELEMENT_TITLE;
|
||||||
|
static const size_t ELEMENT_LIMIT = 0x10000;
|
||||||
|
|
||||||
|
OreManager(IGameDef *gamedef) {}
|
||||||
|
~OreManager() {}
|
||||||
|
|
||||||
|
Ore *create(int type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case ORE_SCATTER:
|
||||||
|
return new OreScatter;
|
||||||
|
case ORE_SHEET:
|
||||||
|
return new OreSheet;
|
||||||
|
//case ORE_CLAYLIKE: //TODO: implement this!
|
||||||
|
// return new OreClaylike;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t placeAllOres(Mapgen *mg, u32 seed, v3s16 nmin, v3s16 nmax);
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,79 +28,42 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "serialization.h"
|
#include "serialization.h"
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
|
|
||||||
FlagDesc flagdesc_deco_schematic[] = {
|
const char *SchematicManager::ELEMENT_TITLE = "schematic";
|
||||||
{"place_center_x", DECO_PLACE_CENTER_X},
|
|
||||||
{"place_center_y", DECO_PLACE_CENTER_Y},
|
|
||||||
{"place_center_z", DECO_PLACE_CENTER_Z},
|
|
||||||
{NULL, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
DecoSchematic::DecoSchematic()
|
Schematic::Schematic()
|
||||||
{
|
{
|
||||||
schematic = NULL;
|
schemdata = NULL;
|
||||||
slice_probs = NULL;
|
slice_probs = NULL;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
size = v3s16(0, 0, 0);
|
size = v3s16(0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DecoSchematic::~DecoSchematic()
|
Schematic::~Schematic()
|
||||||
{
|
{
|
||||||
delete []schematic;
|
delete []schemdata;
|
||||||
delete []slice_probs;
|
delete []slice_probs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DecoSchematic::updateContentIds()
|
void Schematic::updateContentIds()
|
||||||
{
|
{
|
||||||
if (flags & DECO_SCHEM_CIDS_UPDATED)
|
if (flags & SCHEM_CIDS_UPDATED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flags |= DECO_SCHEM_CIDS_UPDATED;
|
flags |= SCHEM_CIDS_UPDATED;
|
||||||
|
|
||||||
for (int i = 0; i != size.X * size.Y * size.Z; i++)
|
for (int i = 0; i != size.X * size.Y * size.Z; i++)
|
||||||
schematic[i].setContent(c_nodes[schematic[i].getContent()]);
|
schemdata[i].setContent(c_nodes[schemdata[i].getContent()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DecoSchematic::generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p)
|
void Schematic::blitToVManip(v3s16 p, ManualMapVoxelManipulator *vm,
|
||||||
{
|
Rotation rot, bool force_placement, INodeDefManager *ndef)
|
||||||
ManualMapVoxelManipulator *vm = mg->vm;
|
|
||||||
|
|
||||||
if (flags & DECO_PLACE_CENTER_X)
|
|
||||||
p.X -= (size.X + 1) / 2;
|
|
||||||
if (flags & DECO_PLACE_CENTER_Y)
|
|
||||||
p.Y -= (size.Y + 1) / 2;
|
|
||||||
if (flags & DECO_PLACE_CENTER_Z)
|
|
||||||
p.Z -= (size.Z + 1) / 2;
|
|
||||||
|
|
||||||
u32 vi = vm->m_area.index(p);
|
|
||||||
content_t c = vm->m_data[vi].getContent();
|
|
||||||
if (!CONTAINS(c_place_on, c))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Rotation rot = (rotation == ROTATE_RAND) ?
|
|
||||||
(Rotation)pr->range(ROTATE_0, ROTATE_270) : rotation;
|
|
||||||
|
|
||||||
blitToVManip(p, vm, rot, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int DecoSchematic::getHeight() {
|
|
||||||
return size.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string DecoSchematic::getName() {
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DecoSchematic::blitToVManip(v3s16 p, ManualMapVoxelManipulator *vm,
|
|
||||||
Rotation rot, bool force_placement)
|
|
||||||
{
|
{
|
||||||
int xstride = 1;
|
int xstride = 1;
|
||||||
int ystride = size.X;
|
int ystride = size.X;
|
||||||
@ -150,10 +113,10 @@ void DecoSchematic::blitToVManip(v3s16 p, ManualMapVoxelManipulator *vm,
|
|||||||
if (!vm->m_area.contains(vi))
|
if (!vm->m_area.contains(vi))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (schematic[i].getContent() == CONTENT_IGNORE)
|
if (schemdata[i].getContent() == CONTENT_IGNORE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (schematic[i].param1 == MTSCHEM_PROB_NEVER)
|
if (schemdata[i].param1 == MTSCHEM_PROB_NEVER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!force_placement) {
|
if (!force_placement) {
|
||||||
@ -162,11 +125,11 @@ void DecoSchematic::blitToVManip(v3s16 p, ManualMapVoxelManipulator *vm,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schematic[i].param1 != MTSCHEM_PROB_ALWAYS &&
|
if (schemdata[i].param1 != MTSCHEM_PROB_ALWAYS &&
|
||||||
myrand_range(1, 255) > schematic[i].param1)
|
myrand_range(1, 255) > schemdata[i].param1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vm->m_data[vi] = schematic[i];
|
vm->m_data[vi] = schemdata[i];
|
||||||
vm->m_data[vi].param1 = 0;
|
vm->m_data[vi].param1 = 0;
|
||||||
|
|
||||||
if (rot)
|
if (rot)
|
||||||
@ -178,13 +141,14 @@ void DecoSchematic::blitToVManip(v3s16 p, ManualMapVoxelManipulator *vm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DecoSchematic::placeStructure(Map *map, v3s16 p, bool force_placement)
|
void Schematic::placeStructure(Map *map, v3s16 p, u32 flags,
|
||||||
|
Rotation rot, bool force_placement, INodeDefManager *ndef)
|
||||||
{
|
{
|
||||||
assert(schematic != NULL);
|
assert(schemdata != NULL);
|
||||||
ManualMapVoxelManipulator *vm = new ManualMapVoxelManipulator(map);
|
ManualMapVoxelManipulator *vm = new ManualMapVoxelManipulator(map);
|
||||||
|
|
||||||
Rotation rot = (rotation == ROTATE_RAND) ?
|
if (rot == ROTATE_RAND)
|
||||||
(Rotation)myrand_range(ROTATE_0, ROTATE_270) : rotation;
|
rot = (Rotation)myrand_range(ROTATE_0, ROTATE_270);
|
||||||
|
|
||||||
v3s16 s = (rot == ROTATE_90 || rot == ROTATE_270) ?
|
v3s16 s = (rot == ROTATE_90 || rot == ROTATE_270) ?
|
||||||
v3s16(size.Z, size.Y, size.X) : size;
|
v3s16(size.Z, size.Y, size.X) : size;
|
||||||
@ -200,7 +164,7 @@ void DecoSchematic::placeStructure(Map *map, v3s16 p, bool force_placement)
|
|||||||
v3s16 bp2 = getNodeBlockPos(p + s - v3s16(1,1,1));
|
v3s16 bp2 = getNodeBlockPos(p + s - v3s16(1,1,1));
|
||||||
vm->initialEmerge(bp1, bp2);
|
vm->initialEmerge(bp1, bp2);
|
||||||
|
|
||||||
blitToVManip(p, vm, rot, force_placement);
|
blitToVManip(p, vm, rot, force_placement, ndef);
|
||||||
|
|
||||||
std::map<v3s16, MapBlock *> lighting_modified_blocks;
|
std::map<v3s16, MapBlock *> lighting_modified_blocks;
|
||||||
std::map<v3s16, MapBlock *> modified_blocks;
|
std::map<v3s16, MapBlock *> modified_blocks;
|
||||||
@ -221,13 +185,14 @@ void DecoSchematic::placeStructure(Map *map, v3s16 p, bool force_placement)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DecoSchematic::loadSchematicFile(NodeResolver *resolver,
|
bool Schematic::loadSchematicFromFile(const char *filename,
|
||||||
|
NodeResolver *resolver,
|
||||||
std::map<std::string, std::string> &replace_names)
|
std::map<std::string, std::string> &replace_names)
|
||||||
{
|
{
|
||||||
content_t cignore = CONTENT_IGNORE;
|
content_t cignore = CONTENT_IGNORE;
|
||||||
bool have_cignore = false;
|
bool have_cignore = false;
|
||||||
|
|
||||||
std::ifstream is(filename.c_str(), std::ios_base::binary);
|
std::ifstream is(filename, std::ios_base::binary);
|
||||||
|
|
||||||
u32 signature = readU32(is);
|
u32 signature = readU32(is);
|
||||||
if (signature != MTSCHEM_FILE_SIGNATURE) {
|
if (signature != MTSCHEM_FILE_SIGNATURE) {
|
||||||
@ -247,13 +212,8 @@ bool DecoSchematic::loadSchematicFile(NodeResolver *resolver,
|
|||||||
|
|
||||||
delete []slice_probs;
|
delete []slice_probs;
|
||||||
slice_probs = new u8[size.Y];
|
slice_probs = new u8[size.Y];
|
||||||
if (version >= 3) {
|
for (int y = 0; y != size.Y; y++)
|
||||||
for (int y = 0; y != size.Y; y++)
|
slice_probs[y] = (version >= 3) ? readU8(is) : MTSCHEM_PROB_ALWAYS;
|
||||||
slice_probs[y] = readU8(is);
|
|
||||||
} else {
|
|
||||||
for (int y = 0; y != size.Y; y++)
|
|
||||||
slice_probs[y] = MTSCHEM_PROB_ALWAYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nodecount = size.X * size.Y * size.Z;
|
int nodecount = size.X * size.Y * size.Z;
|
||||||
|
|
||||||
@ -268,7 +228,6 @@ bool DecoSchematic::loadSchematicFile(NodeResolver *resolver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::string>::iterator it;
|
std::map<std::string, std::string>::iterator it;
|
||||||
|
|
||||||
it = replace_names.find(name);
|
it = replace_names.find(name);
|
||||||
if (it != replace_names.end())
|
if (it != replace_names.end())
|
||||||
name = it->second;
|
name = it->second;
|
||||||
@ -276,17 +235,17 @@ bool DecoSchematic::loadSchematicFile(NodeResolver *resolver,
|
|||||||
resolver->addNodeList(name.c_str(), &c_nodes);
|
resolver->addNodeList(name.c_str(), &c_nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete []schematic;
|
delete []schemdata;
|
||||||
schematic = new MapNode[nodecount];
|
schemdata = new MapNode[nodecount];
|
||||||
MapNode::deSerializeBulk(is, SER_FMT_VER_HIGHEST_READ, schematic,
|
MapNode::deSerializeBulk(is, SER_FMT_VER_HIGHEST_READ, schemdata,
|
||||||
nodecount, 2, 2, true);
|
nodecount, 2, 2, true);
|
||||||
|
|
||||||
if (version == 1) { // fix up the probability values
|
if (version == 1) { // fix up the probability values
|
||||||
for (int i = 0; i != nodecount; i++) {
|
for (int i = 0; i != nodecount; i++) {
|
||||||
if (schematic[i].param1 == 0)
|
if (schemdata[i].param1 == 0)
|
||||||
schematic[i].param1 = MTSCHEM_PROB_ALWAYS;
|
schemdata[i].param1 = MTSCHEM_PROB_ALWAYS;
|
||||||
if (have_cignore && schematic[i].getContent() == cignore)
|
if (have_cignore && schemdata[i].getContent() == cignore)
|
||||||
schematic[i].param1 = MTSCHEM_PROB_NEVER;
|
schemdata[i].param1 = MTSCHEM_PROB_NEVER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,7 +283,7 @@ bool DecoSchematic::loadSchematicFile(NodeResolver *resolver,
|
|||||||
2 - Fixed messy never/always place; 0 probability is now never, 0xFF is always
|
2 - Fixed messy never/always place; 0 probability is now never, 0xFF is always
|
||||||
3 - Added y-slice probabilities; this allows for variable height structures
|
3 - Added y-slice probabilities; this allows for variable height structures
|
||||||
*/
|
*/
|
||||||
void DecoSchematic::saveSchematicFile(INodeDefManager *ndef)
|
void Schematic::saveSchematicToFile(const char *filename, INodeDefManager *ndef)
|
||||||
{
|
{
|
||||||
std::ostringstream ss(std::ios_base::binary);
|
std::ostringstream ss(std::ios_base::binary);
|
||||||
|
|
||||||
@ -337,7 +296,7 @@ void DecoSchematic::saveSchematicFile(INodeDefManager *ndef)
|
|||||||
|
|
||||||
std::vector<content_t> usednodes;
|
std::vector<content_t> usednodes;
|
||||||
int nodecount = size.X * size.Y * size.Z;
|
int nodecount = size.X * size.Y * size.Z;
|
||||||
build_nnlist_and_update_ids(schematic, nodecount, &usednodes);
|
build_nnlist_and_update_ids(schemdata, nodecount, &usednodes);
|
||||||
|
|
||||||
u16 numids = usednodes.size();
|
u16 numids = usednodes.size();
|
||||||
writeU16(ss, numids); // name count
|
writeU16(ss, numids); // name count
|
||||||
@ -345,7 +304,7 @@ void DecoSchematic::saveSchematicFile(INodeDefManager *ndef)
|
|||||||
ss << serializeString(ndef->get(usednodes[i]).name); // node names
|
ss << serializeString(ndef->get(usednodes[i]).name); // node names
|
||||||
|
|
||||||
// compressed bulk node data
|
// compressed bulk node data
|
||||||
MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE, schematic,
|
MapNode::serializeBulk(ss, SER_FMT_VER_HIGHEST_WRITE, schemdata,
|
||||||
nodecount, 2, 2, true);
|
nodecount, 2, 2, true);
|
||||||
|
|
||||||
fs::safeWriteToFile(filename, ss.str());
|
fs::safeWriteToFile(filename, ss.str());
|
||||||
@ -377,7 +336,7 @@ void build_nnlist_and_update_ids(MapNode *nodes, u32 nodecount,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool DecoSchematic::getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2)
|
bool Schematic::getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2)
|
||||||
{
|
{
|
||||||
ManualMapVoxelManipulator *vm = new ManualMapVoxelManipulator(map);
|
ManualMapVoxelManipulator *vm = new ManualMapVoxelManipulator(map);
|
||||||
|
|
||||||
@ -391,15 +350,15 @@ bool DecoSchematic::getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2)
|
|||||||
for (s16 y = 0; y != size.Y; y++)
|
for (s16 y = 0; y != size.Y; y++)
|
||||||
slice_probs[y] = MTSCHEM_PROB_ALWAYS;
|
slice_probs[y] = MTSCHEM_PROB_ALWAYS;
|
||||||
|
|
||||||
schematic = new MapNode[size.X * size.Y * size.Z];
|
schemdata = new MapNode[size.X * size.Y * size.Z];
|
||||||
|
|
||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
for (s16 z = p1.Z; z <= p2.Z; z++)
|
for (s16 z = p1.Z; z <= p2.Z; z++)
|
||||||
for (s16 y = p1.Y; y <= p2.Y; y++) {
|
for (s16 y = p1.Y; y <= p2.Y; y++) {
|
||||||
u32 vi = vm->m_area.index(p1.X, y, z);
|
u32 vi = vm->m_area.index(p1.X, y, z);
|
||||||
for (s16 x = p1.X; x <= p2.X; x++, i++, vi++) {
|
for (s16 x = p1.X; x <= p2.X; x++, i++, vi++) {
|
||||||
schematic[i] = vm->m_data[vi];
|
schemdata[i] = vm->m_data[vi];
|
||||||
schematic[i].param1 = MTSCHEM_PROB_ALWAYS;
|
schemdata[i].param1 = MTSCHEM_PROB_ALWAYS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,7 +367,7 @@ bool DecoSchematic::getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DecoSchematic::applyProbabilities(v3s16 p0,
|
void Schematic::applyProbabilities(v3s16 p0,
|
||||||
std::vector<std::pair<v3s16, u8> > *plist,
|
std::vector<std::pair<v3s16, u8> > *plist,
|
||||||
std::vector<std::pair<s16, u8> > *splist)
|
std::vector<std::pair<s16, u8> > *splist)
|
||||||
{
|
{
|
||||||
@ -417,11 +376,11 @@ void DecoSchematic::applyProbabilities(v3s16 p0,
|
|||||||
int index = p.Z * (size.Y * size.X) + p.Y * size.X + p.X;
|
int index = p.Z * (size.Y * size.X) + p.Y * size.X + p.X;
|
||||||
if (index < size.Z * size.Y * size.X) {
|
if (index < size.Z * size.Y * size.X) {
|
||||||
u8 prob = (*plist)[i].second;
|
u8 prob = (*plist)[i].second;
|
||||||
schematic[index].param1 = prob;
|
schemdata[index].param1 = prob;
|
||||||
|
|
||||||
// trim unnecessary node names from schematic
|
// trim unnecessary node names from schematic
|
||||||
if (prob == MTSCHEM_PROB_NEVER)
|
if (prob == MTSCHEM_PROB_NEVER)
|
||||||
schematic[index].setContent(CONTENT_AIR);
|
schemdata[index].setContent(CONTENT_AIR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,11 +30,8 @@ class ManualMapVoxelManipulator;
|
|||||||
class PseudoRandom;
|
class PseudoRandom;
|
||||||
class NodeResolver;
|
class NodeResolver;
|
||||||
|
|
||||||
/////////////////// Decoration flags
|
/////////////////// Schematic flags
|
||||||
#define DECO_PLACE_CENTER_X 1
|
#define SCHEM_CIDS_UPDATED 0x08
|
||||||
#define DECO_PLACE_CENTER_Y 2
|
|
||||||
#define DECO_PLACE_CENTER_Z 4
|
|
||||||
#define DECO_SCHEM_CIDS_UPDATED 8
|
|
||||||
|
|
||||||
|
|
||||||
#define MTSCHEM_FILE_SIGNATURE 0x4d54534d // 'MTSM'
|
#define MTSCHEM_FILE_SIGNATURE 0x4d54534d // 'MTSM'
|
||||||
@ -44,42 +41,50 @@ class NodeResolver;
|
|||||||
#define MTSCHEM_PROB_NEVER 0x00
|
#define MTSCHEM_PROB_NEVER 0x00
|
||||||
#define MTSCHEM_PROB_ALWAYS 0xFF
|
#define MTSCHEM_PROB_ALWAYS 0xFF
|
||||||
|
|
||||||
extern FlagDesc flagdesc_deco_schematic[];
|
|
||||||
|
|
||||||
class DecoSchematic : public Decoration {
|
class Schematic : public GenElement {
|
||||||
public:
|
public:
|
||||||
std::string filename;
|
|
||||||
|
|
||||||
std::vector<content_t> c_nodes;
|
std::vector<content_t> c_nodes;
|
||||||
|
|
||||||
u32 flags;
|
u32 flags;
|
||||||
Rotation rotation;
|
|
||||||
v3s16 size;
|
v3s16 size;
|
||||||
MapNode *schematic;
|
MapNode *schemdata;
|
||||||
u8 *slice_probs;
|
u8 *slice_probs;
|
||||||
|
|
||||||
DecoSchematic();
|
Schematic();
|
||||||
~DecoSchematic();
|
~Schematic();
|
||||||
|
|
||||||
void updateContentIds();
|
void updateContentIds();
|
||||||
virtual void generate(Mapgen *mg, PseudoRandom *pr, s16 max_y, v3s16 p);
|
|
||||||
virtual int getHeight();
|
|
||||||
virtual std::string getName();
|
|
||||||
|
|
||||||
void blitToVManip(v3s16 p, ManualMapVoxelManipulator *vm,
|
void blitToVManip(v3s16 p, ManualMapVoxelManipulator *vm,
|
||||||
Rotation rot, bool force_placement);
|
Rotation rot, bool force_placement, INodeDefManager *ndef);
|
||||||
|
|
||||||
bool loadSchematicFile(NodeResolver *resolver,
|
bool loadSchematicFromFile(const char *filename, NodeResolver *resolver,
|
||||||
std::map<std::string, std::string> &replace_names);
|
std::map<std::string, std::string> &replace_names);
|
||||||
void saveSchematicFile(INodeDefManager *ndef);
|
void saveSchematicToFile(const char *filename, INodeDefManager *ndef);
|
||||||
|
|
||||||
bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
|
bool getSchematicFromMap(Map *map, v3s16 p1, v3s16 p2);
|
||||||
void placeStructure(Map *map, v3s16 p, bool force_placement);
|
|
||||||
|
void placeStructure(Map *map, v3s16 p, u32 flags,
|
||||||
|
Rotation rot, bool force_placement, INodeDefManager *nef);
|
||||||
void applyProbabilities(v3s16 p0,
|
void applyProbabilities(v3s16 p0,
|
||||||
std::vector<std::pair<v3s16, u8> > *plist,
|
std::vector<std::pair<v3s16, u8> > *plist,
|
||||||
std::vector<std::pair<s16, u8> > *splist);
|
std::vector<std::pair<s16, u8> > *splist);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SchematicManager : public GenElementManager {
|
||||||
|
public:
|
||||||
|
static const char *ELEMENT_TITLE;
|
||||||
|
static const size_t ELEMENT_LIMIT = 0x10000;
|
||||||
|
|
||||||
|
SchematicManager(IGameDef *gamedef) {}
|
||||||
|
~SchematicManager() {}
|
||||||
|
|
||||||
|
Schematic *create(int type)
|
||||||
|
{
|
||||||
|
return new Schematic;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void build_nnlist_and_update_ids(MapNode *nodes, u32 nodecount,
|
void build_nnlist_and_update_ids(MapNode *nodes, u32 nodecount,
|
||||||
std::vector<content_t> *usednodes);
|
std::vector<content_t> *usednodes);
|
||||||
|
|
||||||
|
@ -1009,86 +1009,98 @@ bool read_noiseparams_nc(lua_State *L, int index, NoiseParams *np)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
bool read_schematic(lua_State *L, int index, DecoSchematic *dschem, Server *server) {
|
|
||||||
|
bool get_schematic(lua_State *L, int index, Schematic *schem,
|
||||||
|
INodeDefManager *ndef, std::map<std::string, std::string> &replace_names)
|
||||||
|
{
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
index = lua_gettop(L) + 1 + index;
|
index = lua_gettop(L) + 1 + index;
|
||||||
|
|
||||||
INodeDefManager *ndef = server->getNodeDefManager();
|
|
||||||
|
|
||||||
if (lua_istable(L, index)) {
|
if (lua_istable(L, index)) {
|
||||||
lua_getfield(L, index, "size");
|
return read_schematic(L, index, schem, ndef, replace_names);
|
||||||
v3s16 size = read_v3s16(L, -1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
int numnodes = size.X * size.Y * size.Z;
|
|
||||||
MapNode *schemdata = new MapNode[numnodes];
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
// Get schematic data
|
|
||||||
lua_getfield(L, index, "data");
|
|
||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
|
||||||
|
|
||||||
lua_pushnil(L);
|
|
||||||
while (lua_next(L, -2)) {
|
|
||||||
if (i < numnodes) {
|
|
||||||
// same as readnode, except param1 default is MTSCHEM_PROB_CONST
|
|
||||||
lua_getfield(L, -1, "name");
|
|
||||||
const char *name = luaL_checkstring(L, -1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
u8 param1;
|
|
||||||
lua_getfield(L, -1, "param1");
|
|
||||||
param1 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : MTSCHEM_PROB_ALWAYS;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
u8 param2;
|
|
||||||
lua_getfield(L, -1, "param2");
|
|
||||||
param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
schemdata[i] = MapNode(ndef, name, param1, param2);
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i != numnodes) {
|
|
||||||
errorstream << "read_schematic: incorrect number of "
|
|
||||||
"nodes provided in raw schematic data (got " << i <<
|
|
||||||
", expected " << numnodes << ")." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 *sliceprobs = new u8[size.Y];
|
|
||||||
for (i = 0; i != size.Y; i++)
|
|
||||||
sliceprobs[i] = MTSCHEM_PROB_ALWAYS;
|
|
||||||
|
|
||||||
// Get Y-slice probability values (if present)
|
|
||||||
lua_getfield(L, index, "yslice_prob");
|
|
||||||
if (lua_istable(L, -1)) {
|
|
||||||
lua_pushnil(L);
|
|
||||||
while (lua_next(L, -2)) {
|
|
||||||
if (getintfield(L, -1, "ypos", i) && i >= 0 && i < size.Y) {
|
|
||||||
sliceprobs[i] = getintfield_default(L, -1,
|
|
||||||
"prob", MTSCHEM_PROB_ALWAYS);
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dschem->size = size;
|
|
||||||
dschem->schematic = schemdata;
|
|
||||||
dschem->slice_probs = sliceprobs;
|
|
||||||
|
|
||||||
} else if (lua_isstring(L, index)) {
|
} else if (lua_isstring(L, index)) {
|
||||||
dschem->filename = std::string(lua_tostring(L, index));
|
NodeResolver *resolver = ndef->getResolver();
|
||||||
|
const char *filename = lua_tostring(L, index);
|
||||||
|
return schem->loadSchematicFromFile(filename, resolver, replace_names);
|
||||||
} else {
|
} else {
|
||||||
errorstream << "read_schematic: missing schematic "
|
|
||||||
"filename or raw schematic data" << std::endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool read_schematic(lua_State *L, int index, Schematic *schem,
|
||||||
|
INodeDefManager *ndef, std::map<std::string, std::string> &replace_names)
|
||||||
|
{
|
||||||
|
//// Get schematic size
|
||||||
|
lua_getfield(L, index, "size");
|
||||||
|
v3s16 size = read_v3s16(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
//// Get schematic data
|
||||||
|
lua_getfield(L, index, "data");
|
||||||
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
|
|
||||||
|
int numnodes = size.X * size.Y * size.Z;
|
||||||
|
MapNode *schemdata = new MapNode[numnodes];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
lua_pushnil(L);
|
||||||
|
while (lua_next(L, -2)) {
|
||||||
|
if (i < numnodes) {
|
||||||
|
// same as readnode, except param1 default is MTSCHEM_PROB_CONST
|
||||||
|
lua_getfield(L, -1, "name");
|
||||||
|
std::string name = luaL_checkstring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
u8 param1;
|
||||||
|
lua_getfield(L, -1, "param1");
|
||||||
|
param1 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : MTSCHEM_PROB_ALWAYS;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
u8 param2;
|
||||||
|
lua_getfield(L, -1, "param2");
|
||||||
|
param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
std::map<std::string, std::string>::iterator it;
|
||||||
|
it = replace_names.find(name);
|
||||||
|
if (it != replace_names.end())
|
||||||
|
name = it->second;
|
||||||
|
|
||||||
|
schemdata[i] = MapNode(ndef, name, param1, param2);
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != numnodes) {
|
||||||
|
errorstream << "read_schematic: incorrect number of "
|
||||||
|
"nodes provided in raw schematic data (got " << i <<
|
||||||
|
", expected " << numnodes << ")." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//// Get Y-slice probability values (if present)
|
||||||
|
u8 *slice_probs = new u8[size.Y];
|
||||||
|
for (i = 0; i != size.Y; i++)
|
||||||
|
slice_probs[i] = MTSCHEM_PROB_ALWAYS;
|
||||||
|
|
||||||
|
lua_getfield(L, index, "yslice_prob");
|
||||||
|
if (lua_istable(L, -1)) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
while (lua_next(L, -2)) {
|
||||||
|
if (getintfield(L, -1, "ypos", i) && i >= 0 && i < size.Y) {
|
||||||
|
slice_probs[i] = getintfield_default(L, -1,
|
||||||
|
"prob", MTSCHEM_PROB_ALWAYS);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
schem->flags = 0;
|
||||||
|
schem->size = size;
|
||||||
|
schem->schemdata = schemdata;
|
||||||
|
schem->slice_probs = slice_probs;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ struct DigParams;
|
|||||||
struct HitParams;
|
struct HitParams;
|
||||||
struct EnumString;
|
struct EnumString;
|
||||||
struct NoiseParams;
|
struct NoiseParams;
|
||||||
class DecoSchematic;
|
class Schematic;
|
||||||
|
|
||||||
|
|
||||||
ContentFeatures read_content_features (lua_State *L, int index);
|
ContentFeatures read_content_features (lua_State *L, int index);
|
||||||
@ -151,10 +151,14 @@ NoiseParams* read_noiseparams (lua_State *L, int index);
|
|||||||
|
|
||||||
bool read_noiseparams_nc (lua_State *L, int index,
|
bool read_noiseparams_nc (lua_State *L, int index,
|
||||||
NoiseParams *np);
|
NoiseParams *np);
|
||||||
|
bool get_schematic (lua_State *L, int index,
|
||||||
|
Schematic *schem,
|
||||||
|
INodeDefManager *ndef,
|
||||||
|
std::map<std::string, std::string> &replace_names);
|
||||||
bool read_schematic (lua_State *L, int index,
|
bool read_schematic (lua_State *L, int index,
|
||||||
DecoSchematic *dschem,
|
Schematic *dschem,
|
||||||
Server *server);
|
INodeDefManager *ndef,
|
||||||
|
std::map<std::string, std::string> &replace_names);
|
||||||
|
|
||||||
void luaentity_get (lua_State *L,u16 id);
|
void luaentity_get (lua_State *L,u16 id);
|
||||||
|
|
||||||
|
@ -25,13 +25,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
#include "mg_biome.h"
|
|
||||||
#include "emerge.h"
|
#include "emerge.h"
|
||||||
#include "mg_biome.h"
|
#include "mg_biome.h"
|
||||||
#include "mg_ore.h"
|
#include "mg_ore.h"
|
||||||
#include "mg_decoration.h"
|
#include "mg_decoration.h"
|
||||||
#include "mg_schematic.h"
|
#include "mg_schematic.h"
|
||||||
#include "mapgen_v7.h"
|
#include "mapgen_v7.h"
|
||||||
|
#include "settings.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ struct EnumString ModApiMapgen::es_Rotation[] =
|
|||||||
|
|
||||||
|
|
||||||
static void read_schematic_replacements(lua_State *L,
|
static void read_schematic_replacements(lua_State *L,
|
||||||
std::map<std::string, std::string> replace_names, int index)
|
std::map<std::string, std::string> &replace_names, int index)
|
||||||
{
|
{
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next(L, index)) {
|
while (lua_next(L, index)) {
|
||||||
@ -310,13 +310,13 @@ int ModApiMapgen::l_register_biome(lua_State *L)
|
|||||||
luaL_checktype(L, index, LUA_TTABLE);
|
luaL_checktype(L, index, LUA_TTABLE);
|
||||||
|
|
||||||
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
||||||
BiomeDefManager *bmgr = getServer(L)->getEmergeManager()->biomedef;
|
BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr;
|
||||||
|
|
||||||
enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index,
|
enum BiomeTerrainType terrain = (BiomeTerrainType)getenumfield(L, index,
|
||||||
"terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
|
"terrain_type", es_BiomeTerrainType, BIOME_TERRAIN_NORMAL);
|
||||||
Biome *b = bmgr->createBiome(terrain);
|
Biome *b = bmgr->create(terrain);
|
||||||
|
|
||||||
b->name = getstringfield_default(L, index, "name", "<no name>");
|
b->name = getstringfield_default(L, index, "name", "");
|
||||||
b->depth_top = getintfield_default(L, index, "depth_top", 1);
|
b->depth_top = getintfield_default(L, index, "depth_top", 1);
|
||||||
b->depth_filler = getintfield_default(L, index, "depth_filler", 3);
|
b->depth_filler = getintfield_default(L, index, "depth_filler", 3);
|
||||||
b->height_min = getintfield_default(L, index, "height_min", 0);
|
b->height_min = getintfield_default(L, index, "height_min", 0);
|
||||||
@ -325,7 +325,8 @@ int ModApiMapgen::l_register_biome(lua_State *L)
|
|||||||
b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.);
|
b->humidity_point = getfloatfield_default(L, index, "humidity_point", 0.);
|
||||||
b->flags = 0; //reserved
|
b->flags = 0; //reserved
|
||||||
|
|
||||||
if (!bmgr->addBiome(b)) {
|
u32 id = bmgr->add(b);
|
||||||
|
if (id == (u32)-1) {
|
||||||
delete b;
|
delete b;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -344,7 +345,8 @@ int ModApiMapgen::l_register_biome(lua_State *L)
|
|||||||
|
|
||||||
verbosestream << "register_biome: " << b->name << std::endl;
|
verbosestream << "register_biome: " << b->name << std::endl;
|
||||||
|
|
||||||
return 0;
|
lua_pushinteger(L, id);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// register_decoration({lots of stuff})
|
// register_decoration({lots of stuff})
|
||||||
@ -353,20 +355,22 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
int index = 1;
|
int index = 1;
|
||||||
luaL_checktype(L, index, LUA_TTABLE);
|
luaL_checktype(L, index, LUA_TTABLE);
|
||||||
|
|
||||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||||
BiomeDefManager *bdef = emerge->biomedef;
|
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
||||||
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr;
|
||||||
|
BiomeManager *biomemgr = getServer(L)->getEmergeManager()->biomemgr;
|
||||||
|
|
||||||
enum DecorationType decotype = (DecorationType)getenumfield(L, index,
|
enum DecorationType decotype = (DecorationType)getenumfield(L, index,
|
||||||
"deco_type", es_DecorationType, -1);
|
"deco_type", es_DecorationType, -1);
|
||||||
|
|
||||||
Decoration *deco = createDecoration(decotype);
|
Decoration *deco = decomgr->create(decotype);
|
||||||
if (!deco) {
|
if (!deco) {
|
||||||
errorstream << "register_decoration: decoration placement type "
|
errorstream << "register_decoration: decoration placement type "
|
||||||
<< decotype << " not implemented";
|
<< decotype << " not implemented";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deco->name = getstringfield_default(L, index, "name", "");
|
||||||
deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
|
deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
|
||||||
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
||||||
if (deco->sidelen <= 0) {
|
if (deco->sidelen <= 0) {
|
||||||
@ -391,9 +395,11 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
std::vector<const char *> biome_list;
|
std::vector<const char *> biome_list;
|
||||||
getstringlistfield(L, index, "biomes", biome_list);
|
getstringlistfield(L, index, "biomes", biome_list);
|
||||||
for (size_t i = 0; i != biome_list.size(); i++) {
|
for (size_t i = 0; i != biome_list.size(); i++) {
|
||||||
u8 biomeid = bdef->getBiomeIdByName(biome_list[i]);
|
Biome *b = (Biome *)biomemgr->getByName(biome_list[i]);
|
||||||
if (biomeid)
|
if (!b)
|
||||||
deco->biomes.insert(biomeid);
|
continue;
|
||||||
|
|
||||||
|
deco->biomes.insert(b->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Handle decoration type-specific parameters
|
//// Handle decoration type-specific parameters
|
||||||
@ -403,7 +409,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
success = regDecoSimple(L, resolver, (DecoSimple *)deco);
|
success = regDecoSimple(L, resolver, (DecoSimple *)deco);
|
||||||
break;
|
break;
|
||||||
case DECO_SCHEMATIC:
|
case DECO_SCHEMATIC:
|
||||||
success = regDecoSchematic(L, resolver, (DecoSchematic *)deco);
|
success = regDecoSchematic(L, ndef, (DecoSchematic *)deco);
|
||||||
break;
|
break;
|
||||||
case DECO_LSYSTEM:
|
case DECO_LSYSTEM:
|
||||||
break;
|
break;
|
||||||
@ -414,12 +420,14 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
emerge->decorations.push_back(deco);
|
u32 id = decomgr->add(deco);
|
||||||
|
if (id == (u32)-1) {
|
||||||
|
delete deco;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
verbosestream << "register_decoration: decoration '" << deco->getName()
|
lua_pushinteger(L, id);
|
||||||
<< "' registered" << std::endl;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModApiMapgen::regDecoSimple(lua_State *L,
|
bool ModApiMapgen::regDecoSimple(lua_State *L,
|
||||||
@ -461,8 +469,8 @@ bool ModApiMapgen::regDecoSimple(lua_State *L,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModApiMapgen::regDecoSchematic(lua_State *L,
|
bool ModApiMapgen::regDecoSchematic(lua_State *L, INodeDefManager *ndef,
|
||||||
NodeResolver *resolver, DecoSchematic *deco)
|
DecoSchematic *deco)
|
||||||
{
|
{
|
||||||
int index = 1;
|
int index = 1;
|
||||||
|
|
||||||
@ -478,19 +486,16 @@ bool ModApiMapgen::regDecoSchematic(lua_State *L,
|
|||||||
read_schematic_replacements(L, replace_names, lua_gettop(L));
|
read_schematic_replacements(L, replace_names, lua_gettop(L));
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
Schematic *schem = new Schematic;
|
||||||
lua_getfield(L, index, "schematic");
|
lua_getfield(L, index, "schematic");
|
||||||
if (!read_schematic(L, -1, deco, getServer(L))) {
|
if (!get_schematic(L, -1, schem, ndef, replace_names)) {
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
delete schem;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
if (!deco->filename.empty() &&
|
deco->schematic = schem;
|
||||||
!deco->loadSchematicFile(resolver, replace_names)) {
|
|
||||||
errorstream << "register_decoration: failed to load schematic"
|
|
||||||
" file '" << deco->filename << "'" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -501,25 +506,25 @@ int ModApiMapgen::l_register_ore(lua_State *L)
|
|||||||
int index = 1;
|
int index = 1;
|
||||||
luaL_checktype(L, index, LUA_TTABLE);
|
luaL_checktype(L, index, LUA_TTABLE);
|
||||||
|
|
||||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
|
||||||
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
||||||
|
OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr;
|
||||||
|
|
||||||
enum OreType oretype = (OreType)getenumfield(L, index,
|
enum OreType oretype = (OreType)getenumfield(L, index,
|
||||||
"ore_type", es_OreType, ORE_SCATTER);
|
"ore_type", es_OreType, ORE_SCATTER);
|
||||||
Ore *ore = createOre(oretype);
|
Ore *ore = oremgr->create(oretype);
|
||||||
if (!ore) {
|
if (!ore) {
|
||||||
errorstream << "register_ore: ore_type "
|
errorstream << "register_ore: ore_type " << oretype << " not implemented";
|
||||||
<< oretype << " not implemented";
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ore->name = getstringfield_default(L, index, "name", "");
|
||||||
ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0);
|
ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0);
|
||||||
ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
|
ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
|
||||||
ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
|
ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
|
||||||
ore->clust_size = getintfield_default(L, index, "clust_size", 0);
|
ore->clust_size = getintfield_default(L, index, "clust_size", 0);
|
||||||
ore->height_min = getintfield_default(L, index, "height_min", 0);
|
ore->height_min = getintfield_default(L, index, "height_min", 0);
|
||||||
ore->height_max = getintfield_default(L, index, "height_max", 0);
|
ore->height_max = getintfield_default(L, index, "height_max", 0);
|
||||||
ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0.);
|
ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0);
|
||||||
ore->noise = NULL;
|
ore->noise = NULL;
|
||||||
ore->flags = 0;
|
ore->flags = 0;
|
||||||
|
|
||||||
@ -536,6 +541,12 @@ int ModApiMapgen::l_register_ore(lua_State *L)
|
|||||||
ore->np = read_noiseparams(L, -1);
|
ore->np = read_noiseparams(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
u32 id = oremgr->add(ore);
|
||||||
|
if (id == (u32)-1) {
|
||||||
|
delete ore;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<const char *> wherein_names;
|
std::vector<const char *> wherein_names;
|
||||||
getstringlistfield(L, index, "wherein", wherein_names);
|
getstringlistfield(L, index, "wherein", wherein_names);
|
||||||
for (size_t i = 0; i != wherein_names.size(); i++)
|
for (size_t i = 0; i != wherein_names.size(); i++)
|
||||||
@ -544,17 +555,14 @@ int ModApiMapgen::l_register_ore(lua_State *L)
|
|||||||
resolver->addNode(getstringfield_default(L, index, "ore", ""),
|
resolver->addNode(getstringfield_default(L, index, "ore", ""),
|
||||||
"", CONTENT_AIR, &ore->c_ore);
|
"", CONTENT_AIR, &ore->c_ore);
|
||||||
|
|
||||||
emerge->ores.push_back(ore);
|
lua_pushinteger(L, id);
|
||||||
|
return 1;
|
||||||
//verbosestream << "register_ore: ore '" << ore->ore_name
|
|
||||||
// << "' registered" << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create_schematic(p1, p2, probability_list, filename)
|
// create_schematic(p1, p2, probability_list, filename)
|
||||||
int ModApiMapgen::l_create_schematic(lua_State *L)
|
int ModApiMapgen::l_create_schematic(lua_State *L)
|
||||||
{
|
{
|
||||||
DecoSchematic dschem;
|
Schematic schem;
|
||||||
|
|
||||||
Map *map = &(getEnv(L)->getMap());
|
Map *map = &(getEnv(L)->getMap());
|
||||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||||
@ -594,20 +602,19 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *s = lua_tostring(L, 4);
|
const char *filename = luaL_checkstring(L, 4);
|
||||||
dschem.filename = std::string(s ? s : "");
|
|
||||||
|
|
||||||
if (!dschem.getSchematicFromMap(map, p1, p2)) {
|
if (!schem.getSchematicFromMap(map, p1, p2)) {
|
||||||
errorstream << "create_schematic: failed to get schematic "
|
errorstream << "create_schematic: failed to get schematic "
|
||||||
"from map" << std::endl;
|
"from map" << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dschem.applyProbabilities(p1, &prob_list, &slice_prob_list);
|
schem.applyProbabilities(p1, &prob_list, &slice_prob_list);
|
||||||
|
|
||||||
dschem.saveSchematicFile(ndef);
|
schem.saveSchematicToFile(filename, ndef);
|
||||||
actionstream << "create_schematic: saved schematic file '"
|
actionstream << "create_schematic: saved schematic file '"
|
||||||
<< dschem.filename << "'." << std::endl;
|
<< filename << "'." << std::endl;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -615,38 +622,36 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
|
|||||||
// place_schematic(p, schematic, rotation, replacement)
|
// place_schematic(p, schematic, rotation, replacement)
|
||||||
int ModApiMapgen::l_place_schematic(lua_State *L)
|
int ModApiMapgen::l_place_schematic(lua_State *L)
|
||||||
{
|
{
|
||||||
DecoSchematic dschem;
|
Schematic schem;
|
||||||
|
|
||||||
Map *map = &(getEnv(L)->getMap());
|
Map *map = &(getEnv(L)->getMap());
|
||||||
NodeResolver *resolver = getServer(L)->getNodeDefManager()->getResolver();
|
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||||
|
|
||||||
|
//// Read position
|
||||||
v3s16 p = read_v3s16(L, 1);
|
v3s16 p = read_v3s16(L, 1);
|
||||||
if (!read_schematic(L, 2, &dschem, getServer(L)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
//// Read rotation
|
||||||
int rot = ROTATE_0;
|
int rot = ROTATE_0;
|
||||||
if (lua_isstring(L, 3))
|
if (lua_isstring(L, 3))
|
||||||
string_to_enum(es_Rotation, rot, std::string(lua_tostring(L, 3)));
|
string_to_enum(es_Rotation, rot, std::string(lua_tostring(L, 3)));
|
||||||
|
|
||||||
dschem.rotation = (Rotation)rot;
|
//// Read force placement
|
||||||
|
|
||||||
std::map<std::string, std::string> replace_names;
|
|
||||||
if (lua_istable(L, 4))
|
|
||||||
read_schematic_replacements(L, replace_names, 4);
|
|
||||||
|
|
||||||
bool force_placement = true;
|
bool force_placement = true;
|
||||||
if (lua_isboolean(L, 5))
|
if (lua_isboolean(L, 5))
|
||||||
force_placement = lua_toboolean(L, 5);
|
force_placement = lua_toboolean(L, 5);
|
||||||
|
|
||||||
if (!dschem.filename.empty()) {
|
//// Read node replacements
|
||||||
if (!dschem.loadSchematicFile(resolver, replace_names)) {
|
std::map<std::string, std::string> replace_names;
|
||||||
errorstream << "place_schematic: failed to load schematic file '"
|
if (lua_istable(L, 4))
|
||||||
<< dschem.filename << "'" << std::endl;
|
read_schematic_replacements(L, replace_names, 4);
|
||||||
return 0;
|
|
||||||
}
|
//// Read schematic
|
||||||
|
if (!get_schematic(L, 2, &schem, ndef, replace_names)) {
|
||||||
|
errorstream << "place_schematic: failed to get schematic" << std::endl;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dschem.placeStructure(map, p, force_placement);
|
schem.placeStructure(map, p, 0, (Rotation)rot, force_placement, ndef);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "lua_api/l_base.h"
|
#include "lua_api/l_base.h"
|
||||||
|
|
||||||
|
class INodeDefManager;
|
||||||
class NodeResolver;
|
class NodeResolver;
|
||||||
class DecoSimple;
|
class DecoSimple;
|
||||||
class DecoSchematic;
|
class DecoSchematic;
|
||||||
@ -60,7 +61,7 @@ private:
|
|||||||
static bool regDecoSimple(lua_State *L,
|
static bool regDecoSimple(lua_State *L,
|
||||||
NodeResolver *resolver, DecoSimple *deco);
|
NodeResolver *resolver, DecoSimple *deco);
|
||||||
static bool regDecoSchematic(lua_State *L,
|
static bool regDecoSchematic(lua_State *L,
|
||||||
NodeResolver *resolver, DecoSchematic *deco);
|
INodeDefManager *ndef, DecoSchematic *deco);
|
||||||
|
|
||||||
static struct EnumString es_BiomeTerrainType[];
|
static struct EnumString es_BiomeTerrainType[];
|
||||||
static struct EnumString es_DecorationType[];
|
static struct EnumString es_DecorationType[];
|
||||||
|
Loading…
Reference in New Issue
Block a user