The new mapgen, noise functions, et al.
parent
736b386554
commit
11afcbff69
|
@ -218,6 +218,7 @@ set(common_SRCS
|
|||
sha1.cpp
|
||||
base64.cpp
|
||||
ban.cpp
|
||||
biome.cpp
|
||||
clientserver.cpp
|
||||
staticobject.cpp
|
||||
util/serialize.cpp
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010-2011 kwolekr, Ryan Kwolek <kwolekr2@cs.scranton.edu>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "biome.h"
|
||||
#include "nodedef.h"
|
||||
#include "map.h" //for ManualMapVoxelManipulator
|
||||
#include "main.h"
|
||||
|
||||
#define BT_NONE 0
|
||||
#define BT_OCEAN 1
|
||||
#define BT_LAKE 2
|
||||
#define BT_SBEACH 3
|
||||
#define BT_GBEACH 4
|
||||
#define BT_PLAINS 5
|
||||
#define BT_HILLS 6
|
||||
#define BT_EXTREMEHILLS 7
|
||||
#define BT_MOUNTAINS 8
|
||||
#define BT_DESERT 9
|
||||
#define BT_DESERTHILLS 10
|
||||
#define BT_HELL 11
|
||||
#define BT_AETHER 12
|
||||
|
||||
#define BT_BTMASK 0x3F
|
||||
|
||||
#define BTF_SNOW 0x40
|
||||
#define BTF_FOREST 0x80
|
||||
|
||||
#define BGFREQ_1 ( 0.40)
|
||||
#define BGFREQ_2 (BGFREQ_1 + 0.05)
|
||||
#define BGFREQ_3 (BGFREQ_2 + 0.08)
|
||||
#define BGFREQ_4 (BGFREQ_3 + 0.35)
|
||||
#define BGFREQ_5 (BGFREQ_4 + 0.18)
|
||||
//BGFREQ_5 is not checked as an upper bound; it ought to sum up to 1.00, but it's okay if it doesn't.
|
||||
|
||||
|
||||
/*float bg1_temps[] = {0.0};
|
||||
int bg1_biomes[] = {BT_OCEAN};
|
||||
|
||||
float bg2_temps[] = {10.0};
|
||||
int bg2_biomes[] = {BT_GBEACH, BT_SBEACH};
|
||||
|
||||
float bg3_temps[] = {30.0, 40.0};
|
||||
int bg3_biomes[] = {BT_HILLS, BT_EXTREMEHILLS, BT_MOUNTAINS};
|
||||
|
||||
float bg4_temps[] = {25.0, 30.0, 35.0, 40.0};
|
||||
int bg4_biomes[] = {BT_HILLS, BT_EXTREMEHILLS, BT_MOUNTAINS, BT_DESERT, BT_DESERTHILLS};
|
||||
|
||||
float bg5_temps[] = {5.0, 40.0};
|
||||
int bg5_biomes[] = {BT_LAKE, BT_PLAINS, BT_DESERT};*/
|
||||
|
||||
|
||||
BiomeDefManager::BiomeDefManager(IGameDef *gamedef) {
|
||||
this->m_gamedef = gamedef;
|
||||
this->ndef = gamedef->ndef();
|
||||
|
||||
//addDefaultBiomes(); //can't do this in the ctor, too early
|
||||
}
|
||||
|
||||
|
||||
BiomeDefManager::~BiomeDefManager() {
|
||||
for (int i = 0; i != bgroups.size(); i++)
|
||||
delete bgroups[i];
|
||||
}
|
||||
|
||||
|
||||
void BiomeDefManager::addBiome() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
NoiseParams npmtdef = {0.0, 20.0, v3f(250., 250., 250.), 82341, 5, 0.6};
|
||||
|
||||
void BiomeDefManager::addDefaultBiomes() {
|
||||
std::vector<Biome *> *bgroup;
|
||||
Biome *b;
|
||||
|
||||
//bgroup = new std::vector<Biome *>;
|
||||
|
||||
b = new Biome;
|
||||
b->name = "Default";
|
||||
b->n_top = MapNode(ndef->getId("mapgen_stone"));
|
||||
b->n_filler = b->n_top;
|
||||
b->ntopnodes = 0;
|
||||
b->height_min = -MAP_GENERATION_LIMIT;
|
||||
b->height_max = MAP_GENERATION_LIMIT;
|
||||
b->heat_min = FLT_MIN;
|
||||
b->heat_max = FLT_MAX;
|
||||
b->humidity_min = FLT_MIN;
|
||||
b->humidity_max = FLT_MAX;
|
||||
b->np = &npmtdef;
|
||||
biome_default = b;
|
||||
|
||||
//bgroup->push_back(b);
|
||||
//bgroups.push_back(bgroup);
|
||||
}
|
||||
|
||||
|
||||
Biome *BiomeDefManager::getBiome(float bgfreq, float heat, float humidity) {
|
||||
std::vector<Biome *> bgroup;
|
||||
Biome *b;
|
||||
int i;
|
||||
|
||||
int ngroups = bgroup_freqs.size();
|
||||
if (!ngroups)
|
||||
return biome_default;
|
||||
for (i = 0; (i != ngroups - 1) && (bgfreq > bgroup_freqs[i]); i++);
|
||||
bgroup = *(bgroups[i]);
|
||||
|
||||
int nbiomes = bgroup.size();
|
||||
if (!nbiomes)
|
||||
return biome_default;
|
||||
for (i = 0; i != nbiomes - 1; i++) {
|
||||
b = bgroup[i];
|
||||
if (heat >= b->heat_min && heat <= b->heat_max &&
|
||||
humidity >= b->humidity_min && humidity <= b->humidity_max)
|
||||
return b;
|
||||
}
|
||||
|
||||
return biome_default;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////// [ Generic biome ] ////////////////////////////////
|
||||
|
||||
|
||||
int Biome::getSurfaceHeight(float noise_terrain) {
|
||||
return np->offset + np->scale * noise_terrain;
|
||||
}
|
||||
|
||||
|
||||
void Biome::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
|
||||
//printf("(%d, %d): %f\n", x, z, mg->map_terrain[z * mg->ystride + x]);
|
||||
|
||||
//int surfaceh = 4;
|
||||
int surfaceh = np->offset + np->scale * mg->map_terrain[(z - mg->node_min.Z) * 80 /*THIS IS TEMPORARY mg->ystride*/ + (x - mg->node_min.X)];
|
||||
//printf("gen column %f\n", );
|
||||
int y = y1;
|
||||
int i = mg->vmanip->m_area.index(x, y, z); //z * mg->zstride + x + (y - mg->vmanip->m_area.MinEdge.Y) * mg->ystride;
|
||||
for (; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = n_filler;
|
||||
for (; y <= surfaceh && y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = n_top;
|
||||
for (; y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = mg->n_air;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////// [ Ocean biome ] /////////////////////////////////
|
||||
|
||||
|
||||
|
||||
void BiomeOcean::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
|
||||
int y, i = 0;
|
||||
|
||||
int surfaceh = np->offset + np->scale * mg->map_terrain[z * mg->ystride + x];
|
||||
|
||||
i = z * mg->zstride + x;
|
||||
for (y = y1; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = n_filler;
|
||||
for (; y <= surfaceh && y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = n_top;
|
||||
for (; y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = mg->n_air;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////// [ Nether biome ] /////////////////////////////////
|
||||
|
||||
|
||||
int BiomeHell::getSurfaceHeight(float noise_terrain) {
|
||||
return np->offset + np->scale * noise_terrain;
|
||||
}
|
||||
|
||||
|
||||
void BiomeHell::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
|
||||
int y, i = 0;
|
||||
|
||||
int surfaceh = np->offset + np->scale * mg->map_terrain[z * mg->ystride + x];
|
||||
|
||||
i = z * mg->zstride + x;
|
||||
for (y = y1; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = n_filler;
|
||||
for (; y <= surfaceh && y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = n_top;
|
||||
for (; y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = mg->n_air;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////// [ Aether biome ] ////////////////////////////////
|
||||
|
||||
/////////////////////////// [ Superflat biome ] ///////////////////////////////
|
||||
|
||||
|
||||
int BiomeSuperflat::getSurfaceHeight(float noise_terrain) {
|
||||
return ntopnodes;
|
||||
}
|
||||
|
||||
|
||||
void BiomeSuperflat::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
|
||||
int y, i = 0;
|
||||
|
||||
int surfaceh = ntopnodes;
|
||||
|
||||
i = z * mg->zstride + x;
|
||||
for (y = y1; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = n_filler;
|
||||
for (; y <= surfaceh && y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = n_top;
|
||||
for (; y <= y2; y++, i += mg->ystride)
|
||||
mg->vmanip->m_data[i] = mg->n_air;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010-2011 kwolekr, Ryan Kwolek <kwolekr2@cs.scranton.edu>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef BIOME_HEADER
|
||||
#define BIOME_HEADER
|
||||
|
||||
#include "nodedef.h"
|
||||
#include "gamedef.h"
|
||||
#include "mapnode.h"
|
||||
#include "noise.h"
|
||||
#include "mapgen.h"
|
||||
|
||||
class Biome {
|
||||
public:
|
||||
MapNode n_top;
|
||||
MapNode n_filler;
|
||||
s16 ntopnodes;
|
||||
s16 flags;
|
||||
s16 height_min;
|
||||
s16 height_max;
|
||||
float heat_min;
|
||||
float heat_max;
|
||||
float humidity_min;
|
||||
float humidity_max;
|
||||
const char *name;
|
||||
NoiseParams *np;
|
||||
|
||||
virtual void genColumn(Mapgen *mg, int x, int z, int y1, int y2);
|
||||
virtual int getSurfaceHeight(float noise_terrain);
|
||||
};
|
||||
|
||||
class BiomeOcean : public Biome {
|
||||
virtual void genColumn(Mapgen *mg, int x, int z, int y1, int y2);
|
||||
};
|
||||
|
||||
class BiomeHell : public Biome {
|
||||
virtual void genColumn(Mapgen *mg, int x, int z, int y1, int y2);
|
||||
virtual int getSurfaceHeight(float noise_terrain);
|
||||
};
|
||||
|
||||
class BiomeSuperflat : public Biome {
|
||||
virtual void genColumn(Mapgen *mg, int x, int z, int y1, int y2);
|
||||
virtual int getSurfaceHeight(float noise_terrain);
|
||||
};
|
||||
|
||||
class BiomeDefManager {
|
||||
public:
|
||||
std::vector<float> bgroup_freqs;
|
||||
std::vector<std::vector<Biome *> *> bgroups;
|
||||
Biome *biome_default;
|
||||
IGameDef *m_gamedef;
|
||||
INodeDefManager *ndef;
|
||||
|
||||
BiomeDefManager(IGameDef *gamedef);
|
||||
~BiomeDefManager();
|
||||
|
||||
Biome *getBiome(float bgfreq, float heat, float humidity);
|
||||
|
||||
void addBiome();
|
||||
void addDefaultBiomes();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -163,7 +163,7 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("max_block_generate_distance", "7");
|
||||
settings->setDefault("time_send_interval", "5");
|
||||
settings->setDefault("time_speed", "72");
|
||||
settings->setDefault("water_level", "1");
|
||||
settings->setDefault("default_water_level", "1");
|
||||
settings->setDefault("server_unload_unused_data_timeout", "29");
|
||||
settings->setDefault("server_map_save_interval", "5.3");
|
||||
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
|
||||
|
|
|
@ -1301,6 +1301,7 @@ u16 ServerEnvironment::addActiveObject(ServerActiveObject *object)
|
|||
return id;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool ServerEnvironment::addActiveObjectAsStatic(ServerActiveObject *obj)
|
||||
{
|
||||
assert(obj);
|
||||
|
@ -1343,6 +1344,7 @@ bool ServerEnvironment::addActiveObjectAsStatic(ServerActiveObject *obj)
|
|||
|
||||
return succeeded;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Finds out what new objects have been added to
|
||||
|
@ -1563,13 +1565,15 @@ void ServerEnvironment::removeRemovedObjects()
|
|||
*/
|
||||
if(obj->m_static_exists && obj->m_removed)
|
||||
{
|
||||
MapBlock *block = m_map->emergeBlock(obj->m_static_block);
|
||||
if(block)
|
||||
{
|
||||
MapBlock *block = m_map->emergeBlock(obj->m_static_block, false);
|
||||
if (block) {
|
||||
block->m_static_objects.remove(id);
|
||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
||||
"removeRemovedObjects");
|
||||
obj->m_static_exists = false;
|
||||
} else {
|
||||
infostream << "failed to emerge block from which "
|
||||
"an object to be removed was loaded from. id="<<id<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1717,6 +1721,8 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
|
|||
|
||||
If force_delete is set, active object is deleted nevertheless. It
|
||||
shall only be set so in the destructor of the environment.
|
||||
|
||||
If block wasn't generated (not in memory or on disk),
|
||||
*/
|
||||
void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
||||
{
|
||||
|
|
|
@ -241,8 +241,9 @@ public:
|
|||
MapBlock.
|
||||
Caller allocates memory, ServerEnvironment frees memory.
|
||||
Return value: true if succeeded, false if failed.
|
||||
(note: not used, pending removal from engine)
|
||||
*/
|
||||
bool addActiveObjectAsStatic(ServerActiveObject *object);
|
||||
//bool addActiveObjectAsStatic(ServerActiveObject *object);
|
||||
|
||||
/*
|
||||
Find out what new objects have been added to
|
||||
|
|
|
@ -120,14 +120,14 @@ HeightPoint ground_height(u64 seed, v2s16 p2d)
|
|||
if(n)
|
||||
return n->getValue();
|
||||
HeightPoint hp;
|
||||
s16 level = mapgen::find_ground_level_from_noise(seed, p2d, 3);
|
||||
s16 level = Mapgen::find_ground_level_from_noise(seed, p2d, 3);
|
||||
hp.gh = (level-4)*BS;
|
||||
hp.ma = (4)*BS;
|
||||
/*hp.gh = BS*base_rock_level_2d(seed, p2d);
|
||||
hp.ma = BS*get_mud_add_amount(seed, p2d);*/
|
||||
hp.have_sand = mapgen::get_have_beach(seed, p2d);
|
||||
hp.have_sand = Mapgen::get_have_beach(seed, p2d);
|
||||
if(hp.gh > BS*WATER_LEVEL)
|
||||
hp.tree_amount = mapgen::tree_amount_2d(seed, p2d);
|
||||
hp.tree_amount = Mapgen::tree_amount_2d(seed, p2d);
|
||||
else
|
||||
hp.tree_amount = 0;
|
||||
// No mud has been added if mud amount is less than 1
|
||||
|
|
45
src/map.cpp
45
src/map.cpp
|
@ -1994,7 +1994,7 @@ void Map::removeNodeTimer(v3s16 p)
|
|||
ServerMap
|
||||
*/
|
||||
|
||||
ServerMap::ServerMap(std::string savedir, IGameDef *gamedef):
|
||||
ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emerge):
|
||||
Map(dout_server, gamedef),
|
||||
m_seed(0),
|
||||
m_map_metadata_changed(true),
|
||||
|
@ -2004,6 +2004,8 @@ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef):
|
|||
{
|
||||
verbosestream<<__FUNCTION_NAME<<std::endl;
|
||||
|
||||
m_emerge = emerge;
|
||||
|
||||
//m_chunksize = 8; // Takes a few seconds
|
||||
|
||||
if (g_settings->get("fixed_map_seed").empty())
|
||||
|
@ -2011,12 +2013,15 @@ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef):
|
|||
m_seed = (((u64)(myrand()%0xffff)<<0)
|
||||
+ ((u64)(myrand()%0xffff)<<16)
|
||||
+ ((u64)(myrand()%0xffff)<<32)
|
||||
+ ((u64)(myrand()%0xffff)<<48));
|
||||
+ ((u64)(myrand()&0xffff)<<48));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_seed = g_settings->getU64("fixed_map_seed");
|
||||
}
|
||||
emerge->seed = m_seed;
|
||||
emerge->water_level = g_settings->getS16("default_water_level");
|
||||
//<set noiseparams here>
|
||||
|
||||
/*
|
||||
Experimental and debug stuff
|
||||
|
@ -2136,7 +2141,7 @@ ServerMap::~ServerMap()
|
|||
#endif
|
||||
}
|
||||
|
||||
void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
|
||||
void ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos)
|
||||
{
|
||||
bool enable_mapgen_debug_info = g_settings->getBool("enable_mapgen_debug_info");
|
||||
if(enable_mapgen_debug_info)
|
||||
|
@ -2208,7 +2213,7 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
|
|||
|
||||
Refer to the map generator heuristics.
|
||||
*/
|
||||
bool ug = mapgen::block_is_underground(data->seed, p);
|
||||
bool ug = m_emerge->isBlockUnderground(p);
|
||||
block->setIsUnderground(ug);
|
||||
}
|
||||
|
||||
|
@ -2243,7 +2248,7 @@ void ServerMap::initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos)
|
|||
// Data is ready now.
|
||||
}
|
||||
|
||||
MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
|
||||
MapBlock* ServerMap::finishBlockMake(BlockMakeData *data,
|
||||
core::map<v3s16, MapBlock*> &changed_blocks)
|
||||
{
|
||||
v3s16 blockpos_min = data->blockpos_min;
|
||||
|
@ -2483,6 +2488,7 @@ ServerMapSector * ServerMap::createSector(v2s16 p2d)
|
|||
return sector;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
This is a quick-hand function for calling makeBlock().
|
||||
*/
|
||||
|
@ -2518,7 +2524,7 @@ MapBlock * ServerMap::generateBlock(
|
|||
/*
|
||||
Create block make data
|
||||
*/
|
||||
mapgen::BlockMakeData data;
|
||||
BlockMakeData data;
|
||||
initBlockMake(&data, p);
|
||||
|
||||
/*
|
||||
|
@ -2526,7 +2532,8 @@ MapBlock * ServerMap::generateBlock(
|
|||
*/
|
||||
{
|
||||
TimeTaker t("mapgen::make_block()");
|
||||
mapgen::make_block(&data);
|
||||
mapgen->makeChunk(&data);
|
||||
//mapgen::make_block(&data);
|
||||
|
||||
if(enable_mapgen_debug_info == false)
|
||||
t.stop(true); // Hide output
|
||||
|
@ -2595,6 +2602,7 @@ MapBlock * ServerMap::generateBlock(
|
|||
|
||||
return block;
|
||||
}
|
||||
#endif
|
||||
|
||||
MapBlock * ServerMap::createBlock(v3s16 p)
|
||||
{
|
||||
|
@ -2656,14 +2664,15 @@ MapBlock * ServerMap::createBlock(v3s16 p)
|
|||
}
|
||||
// Create blank
|
||||
block = sector->createBlankBlock(block_y);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
MapBlock * ServerMap::emergeBlock(v3s16 p, bool allow_generate)
|
||||
MapBlock * ServerMap::emergeBlock(v3s16 p, bool create_blank)
|
||||
{
|
||||
DSTACKF("%s: p=(%d,%d,%d), allow_generate=%d",
|
||||
DSTACKF("%s: p=(%d,%d,%d), create_blank=%d",
|
||||
__FUNCTION_NAME,
|
||||
p.X, p.Y, p.Z, allow_generate);
|
||||
p.X, p.Y, p.Z, create_blank);
|
||||
|
||||
{
|
||||
MapBlock *block = getBlockNoCreateNoEx(p);
|
||||
|
@ -2677,7 +2686,13 @@ MapBlock * ServerMap::emergeBlock(v3s16 p, bool allow_generate)
|
|||
return block;
|
||||
}
|
||||
|
||||
if(allow_generate)
|
||||
if (create_blank) {
|
||||
ServerMapSector *sector = createSector(v2s16(p.X, p.Z));
|
||||
MapBlock *block = sector->createBlankBlock(p.Y);
|
||||
|
||||
return block;
|
||||
}
|
||||
/*if(allow_generate)
|
||||
{
|
||||
core::map<v3s16, MapBlock*> modified_blocks;
|
||||
MapBlock *block = generateBlock(p, modified_blocks);
|
||||
|
@ -2700,7 +2715,7 @@ MapBlock * ServerMap::emergeBlock(v3s16 p, bool allow_generate)
|
|||
|
||||
return block;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2742,7 +2757,7 @@ plan_b:
|
|||
Determine from map generator noise functions
|
||||
*/
|
||||
|
||||
s16 level = mapgen::find_ground_level_from_noise(m_seed, p2d, 1);
|
||||
s16 level = m_emerge->getGroundLevelAtPoint(p2d);
|
||||
return level;
|
||||
|
||||
//double level = base_rock_level_2d(m_seed, p2d) + AVERAGE_MUD_AMOUNT;
|
||||
|
@ -3062,6 +3077,7 @@ void ServerMap::saveMapMeta()
|
|||
|
||||
Settings params;
|
||||
params.setU64("seed", m_seed);
|
||||
params.setS16("water_level", m_emerge->water_level);
|
||||
|
||||
params.writeLines(os);
|
||||
|
||||
|
@ -3102,6 +3118,9 @@ void ServerMap::loadMapMeta()
|
|||
}
|
||||
|
||||
m_seed = params.getU64("seed");
|
||||
m_emerge->seed = m_seed;
|
||||
m_emerge->water_level = params.getS16("water_level");
|
||||
//m_emerge->np = ;
|
||||
|
||||
verbosestream<<"ServerMap::loadMapMeta(): "<<"seed="<<m_seed<<std::endl;
|
||||
}
|
||||
|
|
22
src/map.h
22
src/map.h
|
@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "mapnode.h"
|
||||
#include "constants.h"
|
||||
#include "voxel.h"
|
||||
#include "mapgen.h" //for BlockMakeData and EmergeManager
|
||||
#include "modifiedstate.h"
|
||||
#include "util/container.h"
|
||||
#include "nodetimer.h"
|
||||
|
@ -46,9 +47,6 @@ class NodeMetadata;
|
|||
class IGameDef;
|
||||
class IRollbackReportSink;
|
||||
|
||||
namespace mapgen{
|
||||
struct BlockMakeData;
|
||||
};
|
||||
|
||||
/*
|
||||
MapEditEvent
|
||||
|
@ -360,7 +358,7 @@ public:
|
|||
/*
|
||||
savedir: directory to which map data should be saved
|
||||
*/
|
||||
ServerMap(std::string savedir, IGameDef *gamedef);
|
||||
ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emerge);
|
||||
~ServerMap();
|
||||
|
||||
s32 mapType() const
|
||||
|
@ -379,15 +377,15 @@ public:
|
|||
/*
|
||||
Blocks are generated by using these and makeBlock().
|
||||
*/
|
||||
void initBlockMake(mapgen::BlockMakeData *data, v3s16 blockpos);
|
||||
MapBlock* finishBlockMake(mapgen::BlockMakeData *data,
|
||||
void initBlockMake(BlockMakeData *data, v3s16 blockpos);
|
||||
MapBlock* finishBlockMake(BlockMakeData *data,
|
||||
core::map<v3s16, MapBlock*> &changed_blocks);
|
||||
|
||||
// A non-threaded wrapper to the above
|
||||
MapBlock * generateBlock(
|
||||
// A non-threaded wrapper to the above - DEFUNCT
|
||||
/* MapBlock * generateBlock(
|
||||
v3s16 p,
|
||||
core::map<v3s16, MapBlock*> &modified_blocks
|
||||
);
|
||||
);*/
|
||||
|
||||
/*
|
||||
Get a block from somewhere.
|
||||
|
@ -400,9 +398,10 @@ public:
|
|||
Forcefully get a block from somewhere.
|
||||
- Memory
|
||||
- Load from disk
|
||||
- Generate
|
||||
- Create blank filled with CONTENT_IGNORE
|
||||
|
||||
*/
|
||||
MapBlock * emergeBlock(v3s16 p, bool allow_generate=true);
|
||||
MapBlock * emergeBlock(v3s16 p, bool create_blank=true);
|
||||
|
||||
// Helper for placing objects on ground level
|
||||
s16 findGroundLevel(v2s16 p2d);
|
||||
|
@ -479,6 +478,7 @@ public:
|
|||
|
||||
u64 getSeed(){ return m_seed; }
|
||||
|
||||
EmergeManager *m_emerge;
|
||||
private:
|
||||
// Seed used for all kinds of randomness in generation
|
||||
u64 m_seed;
|
||||
|
|
294
src/mapgen.cpp
294
src/mapgen.cpp
|
@ -20,7 +20,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "mapgen.h"
|
||||
#include "voxel.h"
|
||||
#include "noise.h"
|
||||
#include "biome.h"
|
||||
#include "mapblock.h"
|
||||
#include "mapnode.h"
|
||||
#include "map.h"
|
||||
//#include "serverobject.h"
|
||||
#include "content_sao.h"
|
||||
|
@ -28,9 +30,296 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "content_mapnode.h" // For content_mapnode_get_new_name
|
||||
#include "voxelalgorithms.h"
|
||||
#include "profiler.h"
|
||||
#include "settings.h" // For g_settings
|
||||
#include "main.h" // For g_profiler
|
||||
#include "treegen.h"
|
||||
|
||||
NoiseParams nparams_mtdefault =
|
||||
{0.0, 20.0, v3f(250., 250., 250.), 82341, 5, 0.6}; //terrain
|
||||
NoiseParams nparams_def_bgroup =
|
||||
{0.5, 1/(2*1.6), v3f(250., 250., 250.), 5923, 2, 0.60}; //0 to 1
|
||||
NoiseParams nparams_def_heat =
|
||||
{25.0, 50.0, v3f(500., 500., 500.), 35293, 1, 0.00}; //-25 to 75
|
||||
NoiseParams nparams_def_humidity =
|
||||
{50, 100/(2*1.6), v3f(750., 750., 750.), 12094, 2, 0.60}; //0 to 100
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
Mapgen::Mapgen(BiomeDefManager *biomedef) {
|
||||
Mapgen(0, 0, biomedef);
|
||||
}*/
|
||||
|
||||
|
||||
Mapgen::Mapgen(BiomeDefManager *biomedef, int mapgenid, u64 seed) {
|
||||
initMapgen(biomedef, mapgenid, seed,
|
||||
&nparams_mtdefault, &nparams_def_bgroup,
|
||||
&nparams_def_heat, &nparams_def_humidity);
|
||||
}
|
||||
|
||||
|
||||
Mapgen::Mapgen(BiomeDefManager *biomedef, int mapgenid, u64 seed,
|
||||
NoiseParams *np_terrain, NoiseParams *np_bgroup,
|
||||
NoiseParams *np_heat, NoiseParams *np_humidity) {
|
||||
initMapgen(biomedef, mapgenid, seed,
|
||||
np_terrain, np_bgroup, np_heat, np_humidity);
|
||||
}
|
||||
|
||||
void Mapgen::initMapgen(BiomeDefManager *biomedef, int mapgenid, u64 seed,
|
||||
NoiseParams *np_terrain, NoiseParams *np_bgroup,
|
||||
NoiseParams *np_heat, NoiseParams *np_humidity) {
|
||||
this->generating = false;
|
||||
this->id = mapgenid;
|
||||
this->seed = (int)seed;
|
||||
this->biomedef = biomedef;
|
||||
this->csize = v3s16(5, 5, 5) * MAP_BLOCKSIZE; /////////////////get this from config!
|
||||
this->water_level = g_settings->getS16("default_water_level"); ////fix this!
|
||||
|
||||
this->np_terrain = np_terrain;
|
||||
this->np_bgroup = np_bgroup;
|
||||
this->np_heat = np_heat;
|
||||
this->np_humidity = np_humidity;
|
||||
noise_terrain = new Noise(np_terrain, seed, csize.X, csize.Y);
|
||||
noise_bgroup = new Noise(np_bgroup, seed, csize.X, csize.Y);
|
||||
noise_heat = new Noise(np_heat, seed, csize.X, csize.Y);
|
||||
noise_humidity = new Noise(np_humidity, seed, csize.X, csize.Y);
|
||||
|
||||
this->ndef = biomedef->ndef;
|
||||
n_air = MapNode(ndef->getId("mapgen_air"));
|
||||
n_water = MapNode(ndef->getId("mapgen_water_source"));
|
||||
n_lava = MapNode(ndef->getId("mapgen_lava_source"));
|
||||
}
|
||||
|
||||
|
||||
Mapgen::~Mapgen() {
|
||||
delete noise_terrain;
|
||||
delete noise_bgroup;
|
||||
delete noise_heat;
|
||||
delete noise_humidity;
|
||||
}
|
||||
|
||||
|
||||
void Mapgen::makeChunk(BlockMakeData *data) {
|
||||
if (data->no_op)
|
||||
return;
|
||||
|
||||
//printf("generating...\n");//////////////
|
||||
|
||||
assert(data->vmanip);
|
||||
assert(data->nodedef);
|
||||
assert(data->blockpos_requested.X >= data->blockpos_min.X &&
|
||||
data->blockpos_requested.Y >= data->blockpos_min.Y &&
|
||||
data->blockpos_requested.Z >= data->blockpos_min.Z);
|
||||
assert(data->blockpos_requested.X <= data->blockpos_max.X &&
|
||||
data->blockpos_requested.Y <= data->blockpos_max.Y &&
|
||||
data->blockpos_requested.Z <= data->blockpos_max.Z);
|
||||
|
||||
this->generating = true;
|
||||
|
||||
this->data = data;
|
||||
this->vmanip = data->vmanip;
|
||||
v3s16 em = vmanip->m_area.getExtent();
|
||||
this->ystride = em.X;
|
||||
this->zstride = em.Y * em.X;
|
||||
|
||||
node_min = (data->blockpos_min) * MAP_BLOCKSIZE;
|
||||
node_max = (data->blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1);
|
||||
v3s16 full_node_min = (data->blockpos_min - 1) * MAP_BLOCKSIZE;
|
||||
v3s16 full_node_max = (data->blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1,1,1);
|
||||
|
||||
int y1 = node_min.Y;
|
||||
int y2 = node_max.Y;
|
||||
int x = node_min.X;
|
||||
int z = node_min.Z;
|
||||
//printf("full_node_min.X: %d | full_node_min.Z: %d | MinEdge: %d | MaxEdge: %d\n", node_min.X, node_min.Z, vmanip->m_area.MinEdge.X, vmanip->m_area.MinEdge.Z);
|
||||
TimeTaker timer("Generating terrain");
|
||||
map_terrain = noise_terrain->perlinMap2D(x, z);
|
||||
map_bgroup = noise_bgroup->perlinMap2D(x, z);
|
||||
map_heat = noise_heat->perlinMap2D(x, z);
|
||||
map_humidity = noise_humidity->perlinMap2D(x, z);
|
||||
|
||||
int i = 0;
|
||||
for (x = node_min.X; x <= node_max.X; x++) {
|
||||
for (z = node_min.Z; z <= node_max.Z; z++) {
|
||||
Biome *biome = biomedef->getBiome(map_bgroup[i], map_heat[i], map_humidity[i]);
|
||||
biome->genColumn(this, x, z, y1, y2);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
//genCave();
|
||||
//genDungeon();
|
||||
//add blobs of dirt and gravel underground
|
||||
//decorateChunk();
|
||||
//updateLiquid(full_node_min, full_node_max);
|
||||
updateLighting(node_min, node_max);
|
||||
|
||||
this->generating = false;
|
||||
//printf("generated block (%d, %d) to (%d, %d)\n", node_min.X, node_min.Y, node_max.X, node_max.Y);//////////
|
||||
}
|
||||
|
||||
|
||||
void Mapgen::updateLiquid(v3s16 node_min, v3s16 node_max) {
|
||||
bool isliquid, wasliquid;
|
||||
u32 i;
|
||||
content_t c;
|
||||
|
||||
for (s16 z = node_min.Z; z <= node_max.Z; z++) {
|
||||
for (s16 x = node_min.X; x <= node_max.X; x++) {
|
||||
v2s16 p2d(x, z);
|
||||
wasliquid = true;
|
||||
v3s16 em = vmanip->m_area.getExtent();
|
||||
i = vmanip->m_area.index(v3s16(p2d.X, node_max.Y, p2d.Y));
|
||||
|
||||
for (s16 y = node_max.Y; y >= node_min.Y; y--) {
|
||||
isliquid = ndef->get(vmanip->m_data[i]).isLiquid();
|
||||
//there was a change between liquid and nonliquid, add to queue
|
||||
if (isliquid != wasliquid)
|
||||
data->transforming_liquid.push_back(v3s16(p2d.X, y, p2d.Y));
|
||||
|
||||
wasliquid = isliquid;
|
||||
vmanip->m_area.add_y(em, i, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Mapgen::updateLighting(v3s16 node_min, v3s16 node_max) {
|
||||
enum LightBank banks[2] = {LIGHTBANK_DAY, LIGHTBANK_NIGHT};
|
||||
|
||||
VoxelArea a(node_min - v3s16(1,0,1) * MAP_BLOCKSIZE,
|
||||
node_max + v3s16(1,0,1) * MAP_BLOCKSIZE);
|
||||
bool block_is_underground = (water_level > node_max.Y);
|
||||
bool sunlight = !block_is_underground;
|
||||
|
||||
ScopeProfiler sp(g_profiler, "EmergeThread: mapgen lighting update", SPT_AVG);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
enum LightBank bank = banks[i];
|
||||
core::map<v3s16, bool> light_sources;
|
||||
core::map<v3s16, u8> unlight_from;
|
||||
|
||||
voxalgo::clearLightAndCollectSources(*vmanip, a, bank, ndef,
|
||||
light_sources, unlight_from);
|
||||
voxalgo::propagateSunlight(*vmanip, a, sunlight, light_sources, ndef);
|
||||
printf("light_sources: %d\t\tunlight_from: %d\n", light_sources.size(), unlight_from.size());
|
||||
vmanip->unspreadLight(bank, unlight_from, light_sources, ndef);
|
||||
vmanip->spreadLight(bank, light_sources, ndef);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*class EmergeManager {
|
||||
public:
|
||||
int seed;
|
||||
int water_level;
|
||||
BiomeDefManager *biomedef;
|
||||
|
||||
//mapgen objects here
|
||||
|
||||
void addBlockToQueue();
|
||||
|
||||
|
||||
//mapgen helper methods
|
||||
int getGroundLevelAtPoint(u64 mseed, v2s16 p);
|
||||
bool isBlockUnderground(u64 mseed, v3s16 blockpos);
|
||||
u32 getBlockSeed(u64 mseed, v3s16 p);
|
||||
};*/
|
||||
|
||||
EmergeManager::EmergeManager(IGameDef *gamedef) {
|
||||
this->seed = 0;
|
||||
this->water_level = 0;
|
||||
this->np_terrain = &nparams_mtdefault;
|
||||
this->np_bgroup = &nparams_def_bgroup;
|
||||
this->np_heat = &nparams_def_heat;
|
||||
this->np_humidity = &nparams_def_humidity;
|
||||
|
||||
this->biomedef = new BiomeDefManager(gamedef);
|
||||
}
|
||||
|
||||
|
||||
EmergeManager::~EmergeManager() {
|
||||
delete biomedef;
|
||||
}
|
||||
|
||||
|
||||
void EmergeManager::addBlockToQueue() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
Biome *EmergeManager::getBiomeAtPoint(v3s16 p) {
|
||||
float bgroup = NoisePerlin2D(np_bgroup, p.X, p.Y, seed);
|
||||
float heat = NoisePerlin2D(np_heat, p.X, p.Y, seed);
|
||||
float humidity = NoisePerlin2D(np_humidity, p.X, p.Y, seed);
|
||||
return biomedef->getBiome(bgroup, heat, humidity);
|
||||
}
|
||||
|
||||
|
||||
//FIXME: This assumes y == 0, that is, always in a non-hell/non-sky biome
|
||||
int EmergeManager::getGroundLevelAtPoint(v2s16 p) {
|
||||
float terrain = NoisePerlin2D(np_terrain, p.X, p.Y, seed);
|
||||
Biome *biome = getBiomeAtPoint(v3s16(p.X, p.Y, 0));
|
||||
return biome->getSurfaceHeight(terrain);
|
||||
}
|
||||
|
||||
|
||||
bool EmergeManager::isBlockUnderground(v3s16 blockpos) {
|
||||
/*
|
||||
v2s16 p = v2s16((blockpos.X * MAP_BLOCKSIZE) + MAP_BLOCKSIZE / 2,
|
||||
(blockpos.Y * MAP_BLOCKSIZE) + MAP_BLOCKSIZE / 2);
|
||||
int ground_level = getGroundLevelAtPoint(p);
|
||||
return blockpos.Y * (MAP_BLOCKSIZE + 1) <= min(water_level, ground_level);
|
||||
*/
|
||||
|
||||
//yuck, but then again, should i bother being accurate?
|
||||
//the height of the nodes in a single block is quite variable
|
||||
return false; //blockpos.Y * (MAP_BLOCKSIZE + 1) <= water_level;
|
||||
}
|
||||
|
||||
|
||||
u32 EmergeManager::getBlockSeed(v3s16 p) {
|
||||
return (u32)(seed & 0xFFFFFFFF) +
|
||||
p.Z * 38134234 +
|
||||
p.Y * 42123 +
|
||||
p.Y * 23;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////// legacy static functions for farmesh
|
||||
|
||||
|
||||
s16 Mapgen::find_ground_level_from_noise(u64 seed, v2s16 p2d, s16 precision) {
|
||||
//just need to return something
|
||||
s16 level = 5;
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
bool Mapgen::get_have_beach(u64 seed, v2s16 p2d) {
|
||||
double sandnoise = noise2d_perlin(
|
||||
0.2+(float)p2d.X/250, 0.7+(float)p2d.Y/250,
|
||||
seed+59420, 3, 0.50);
|
||||
|
||||
return (sandnoise > 0.15);
|
||||
}
|
||||
|
||||
|
||||
double Mapgen::tree_amount_2d(u64 seed, v2s16 p) {
|
||||
double noise = noise2d_perlin(
|
||||
0.5+(float)p.X/125, 0.5+(float)p.Y/125,
|
||||
seed+2, 4, 0.66);
|
||||
double zeroval = -0.39;
|
||||
if(noise < zeroval)
|
||||
return 0;
|
||||
else
|
||||
return 0.04 * (noise-zeroval) / (1.0-zeroval);
|
||||
}
|
||||
|
||||
|
||||
#if 0 /// BIG COMMENT
|
||||
namespace mapgen
|
||||
{
|
||||
|
||||
|
@ -121,6 +410,7 @@ static s16 find_stone_level(VoxelManipulator &vmanip, v2s16 p2d,
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
static void make_papyrus(VoxelManipulator &vmanip, v3s16 p0,
|
||||
|
@ -2756,6 +3046,8 @@ void make_block(BlockMakeData *data)
|
|||
}
|
||||
}
|
||||
|
||||
#endif ///BIG COMMENT
|
||||
|
||||
BlockMakeData::BlockMakeData():
|
||||
no_op(false),
|
||||
vmanip(NULL),
|
||||
|
@ -2768,6 +3060,6 @@ BlockMakeData::~BlockMakeData()
|
|||
delete vmanip;
|
||||
}
|
||||
|
||||
}; // namespace mapgen
|
||||
//}; // namespace mapgen
|
||||
|
||||
|
||||
|
|
118
src/mapgen.h
118
src/mapgen.h
|
@ -22,12 +22,121 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "util/container.h" // UniqueQueue
|
||||
#include "gamedef.h"
|
||||
#include "mapnode.h"
|
||||
#include "noise.h"
|
||||
|
||||
struct BlockMakeData;
|
||||
class BiomeDefManager;
|
||||
class Biome;
|
||||
|
||||
//struct BlockMakeData;
|
||||
class MapBlock;
|
||||
class ManualMapVoxelManipulator;
|
||||
class INodeDefManager;
|
||||
|
||||
struct BlockMakeData {
|
||||
bool no_op;
|
||||
ManualMapVoxelManipulator *vmanip;
|
||||
u64 seed;
|
||||
v3s16 blockpos_min;
|
||||
v3s16 blockpos_max;
|
||||
v3s16 blockpos_requested;
|
||||
UniqueQueue<v3s16> transforming_liquid;
|
||||
INodeDefManager *nodedef;
|
||||
|
||||
BlockMakeData();
|
||||
~BlockMakeData();
|
||||
};
|
||||
|
||||
class Mapgen {
|
||||
public:
|
||||
BlockMakeData *data;
|
||||
ManualMapVoxelManipulator *vmanip;
|
||||
INodeDefManager *ndef;
|
||||
BiomeDefManager *biomedef;
|
||||
|
||||
int ystride;
|
||||
int zstride;
|
||||
|
||||
v3s16 csize;
|
||||
int seed;
|
||||
int water_level;
|
||||
|
||||
Noise *noise_terrain;
|
||||
Noise *noise_bgroup;
|
||||
Noise *noise_heat;
|
||||
Noise *noise_humidity;
|
||||
|
||||
v3s16 node_min;
|
||||
v3s16 node_max;
|
||||
|
||||
float *map_terrain;
|
||||
float *map_bgroup;
|
||||
float *map_heat;
|
||||
float *map_humidity;
|
||||
|
||||
bool generating;
|
||||
int id;
|
||||
|
||||
NoiseParams *np_terrain;
|
||||
NoiseParams *np_bgroup;
|
||||
NoiseParams *np_heat;
|
||||
NoiseParams *np_humidity;
|
||||
|
||||
//should these be broken off into a "commonly used nodes" class?
|
||||
MapNode n_air;
|
||||
MapNode n_water;
|
||||
MapNode n_lava;
|
||||
|
||||
Mapgen(BiomeDefManager *biomedef, int mapgenid=0, u64 seed=0);
|
||||
Mapgen(BiomeDefManager *biomedef, int mapgenid, u64 seed,
|
||||
NoiseParams *np_terrain, NoiseParams *np_bgroup,
|
||||
NoiseParams *np_heat, NoiseParams *np_humidity);
|
||||
void initMapgen(BiomeDefManager *biomedef, int mapgenid, u64 seed,
|
||||
NoiseParams *np_terrain, NoiseParams *np_bgroup,
|
||||
NoiseParams *np_heat, NoiseParams *np_humidity);
|
||||
~Mapgen();
|
||||
|
||||
void makeChunk(BlockMakeData *data);
|
||||
void updateLiquid(v3s16 node_min, v3s16 node_max);
|
||||
void updateLighting(v3s16 node_min, v3s16 node_max);
|
||||
|
||||
//Legacy functions for Farmesh (pending removal)
|
||||
static bool get_have_beach(u64 seed, v2s16 p2d);
|
||||
static double tree_amount_2d(u64 seed, v2s16 p);
|
||||
static s16 find_ground_level_from_noise(u64 seed, v2s16 p2d, s16 precision);
|
||||
};
|
||||
|
||||
class EmergeManager {
|
||||
public:
|
||||
//settings
|
||||
u64 seed;
|
||||
int water_level;
|
||||
NoiseParams *np_terrain;
|
||||
NoiseParams *np_bgroup;
|
||||
NoiseParams *np_heat;
|
||||
NoiseParams *np_humidity;
|
||||
|
||||
//biome manager
|
||||
BiomeDefManager *biomedef;
|
||||
|
||||
//mapgen objects here
|
||||
|
||||
EmergeManager(IGameDef *gamedef);
|
||||
~EmergeManager();
|
||||
void addBlockToQueue();
|
||||
|
||||
|
||||
|
||||
//mapgen helper methods
|
||||
Biome *getBiomeAtPoint(v3s16 p);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
bool isBlockUnderground(v3s16 blockpos);
|
||||
u32 getBlockSeed(v3s16 p);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
namespace mapgen
|
||||
{
|
||||
// Finds precise ground level at any position
|
||||
|
@ -42,9 +151,8 @@ namespace mapgen
|
|||
// Main map generation routine
|
||||
void make_block(BlockMakeData *data);
|
||||
|
||||
/*
|
||||
These are used by FarMesh
|
||||
*/
|
||||
|
||||
//These are used by FarMesh
|
||||
bool get_have_beach(u64 seed, v2s16 p2d);
|
||||
double tree_amount_2d(u64 seed, v2s16 p);
|
||||
|
||||
|
@ -64,6 +172,6 @@ namespace mapgen
|
|||
};
|
||||
|
||||
}; // namespace mapgen
|
||||
|
||||
*/
|
||||
#endif
|
||||
|
||||
|
|
701
src/noise.cpp
701
src/noise.cpp
|
@ -21,89 +21,116 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "noise.h"
|
||||
#include <iostream>
|
||||
#include "debug.h"
|
||||
#include "util/numeric.h"
|
||||
|
||||
#define NOISE_MAGIC_X 1619
|
||||
#define NOISE_MAGIC_Y 31337
|
||||
#define NOISE_MAGIC_Z 52591
|
||||
#define NOISE_MAGIC_X 1619
|
||||
#define NOISE_MAGIC_Y 31337
|
||||
#define NOISE_MAGIC_Z 52591
|
||||
#define NOISE_MAGIC_SEED 1013
|
||||
|
||||
double cos_lookup[16] = {
|
||||
1.0,0.9238,0.7071,0.3826,0,-0.3826,-0.7071,-0.9238,
|
||||
1.0,-0.9238,-0.7071,-0.3826,0,0.3826,0.7071,0.9238
|
||||
float cos_lookup[16] = {
|
||||
1.0, 0.9238, 0.7071, 0.3826, 0, -0.3826, -0.7071, -0.9238,
|
||||
1.0, -0.9238, -0.7071, -0.3826, 0, 0.3826, 0.7071, 0.9238
|
||||
};
|
||||
|
||||
double dotProduct(double vx, double vy, double wx, double wy){
|
||||
return vx*wx+vy*wy;
|
||||
}
|
||||
|
||||
double easeCurve(double t){
|
||||
return t * t * t * (6. * t * t - 15. * t + 10.);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double linearInterpolation(double x0, double x1, double t){
|
||||
return x0+(x1-x0)*t;
|
||||
}
|
||||
|
||||
double biLinearInterpolation(double x0y0, double x1y0, double x0y1, double x1y1, double x, double y){
|
||||
double tx = easeCurve(x);
|
||||
double ty = easeCurve(y);
|
||||
/*double tx = x;
|
||||
double ty = y;*/
|
||||
double u = linearInterpolation(x0y0,x1y0,tx);
|
||||
double v = linearInterpolation(x0y1,x1y1,tx);
|
||||
return linearInterpolation(u,v,ty);
|
||||
}
|
||||
|
||||
double triLinearInterpolation(
|
||||
double v000, double v100, double v010, double v110,
|
||||
double v001, double v101, double v011, double v111,
|
||||
double x, double y, double z)
|
||||
{
|
||||
/*double tx = easeCurve(x);
|
||||
double ty = easeCurve(y);
|
||||
double tz = easeCurve(z);*/
|
||||
double tx = x;
|
||||
double ty = y;
|
||||
double tz = z;
|
||||
return(
|
||||
v000*(1-tx)*(1-ty)*(1-tz) +
|
||||
v100*tx*(1-ty)*(1-tz) +
|
||||
v010*(1-tx)*ty*(1-tz) +
|
||||
v110*tx*ty*(1-tz) +
|
||||
v001*(1-tx)*(1-ty)*tz +
|
||||
v101*tx*(1-ty)*tz +
|
||||
v011*(1-tx)*ty*tz +
|
||||
v111*tx*ty*tz
|
||||
);
|
||||
}
|
||||
|
||||
double noise2d(int x, int y, int seed)
|
||||
{
|
||||
//noise poly: p(n) = 60493n^3 + 19990303n + 137612589
|
||||
float noise2d(int x, int y, int seed) {
|
||||
int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y
|
||||
+ NOISE_MAGIC_SEED * seed) & 0x7fffffff;
|
||||
n = (n>>13)^n;
|
||||
n = (n * (n*n*60493+19990303) + 1376312589) & 0x7fffffff;
|
||||
return 1.0 - (double)n/1073741824;
|
||||
n = (n >> 13) ^ n;
|
||||
n = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
|
||||
return 1.f - (float)n / 0x40000000;
|
||||
}
|
||||
|
||||
double noise3d(int x, int y, int z, int seed)
|
||||
{
|
||||
|
||||
float noise3d(int x, int y, int z, int seed) {
|
||||
int n = (NOISE_MAGIC_X * x + NOISE_MAGIC_Y * y + NOISE_MAGIC_Z * z
|
||||
+ NOISE_MAGIC_SEED * seed) & 0x7fffffff;
|
||||
n = (n>>13)^n;
|
||||
n = (n * (n*n*60493+19990303) + 1376312589) & 0x7fffffff;
|
||||
return 1.0 - (double)n/1073741824;
|
||||
n = (n >> 13) ^ n;
|
||||
n = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff;
|
||||
return 1.f - (float)n / 0x40000000;
|
||||
}
|
||||
|
||||
|
||||
float dotProduct(float vx, float vy, float wx, float wy) {
|
||||
return vx * wx + vy * wy;
|
||||
}
|
||||
|
||||
|
||||
inline float linearInterpolation(float v0, float v1, float t) {
|
||||
return v0 + (v1 - v0) * t;
|
||||
}
|
||||
|
||||
|
||||
float biLinearInterpolation(float v00, float v10,
|
||||
float v01, float v11,
|
||||
float x, float y) {
|
||||
float tx = easeCurve(x);
|
||||
float ty = easeCurve(y);
|
||||
float u = linearInterpolation(v00, v10, tx);
|
||||
float v = linearInterpolation(v01, v11, tx);
|
||||
return linearInterpolation(u, v, ty);
|
||||
}
|
||||
|
||||
|
||||
float biLinearInterpolationNoEase(float x0y0, float x1y0,
|
||||
float x0y1, float x1y1,
|
||||
float x, float y) {
|
||||
float u = linearInterpolation(x0y0, x1y0, x);
|
||||
float v = linearInterpolation(x0y1, x1y1, x);
|
||||
return linearInterpolation(u, v, y);
|
||||
}
|
||||
|
||||
|
||||
float triLinearInterpolation(
|
||||
float v000, float v100, float v010, float v110,
|
||||
float v001, float v101, float v011, float v111,
|
||||
float x, float y, float z) {
|
||||
float u = biLinearInterpolationNoEase(v000, v100, v010, v110, x, y);
|
||||
float v = biLinearInterpolationNoEase(v001, v101, v011, v111, x, y);
|
||||
return linearInterpolation(u, v, z);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
double noise2d_gradient(double x, double y, int seed)
|
||||
float triLinearInterpolation(
|
||||
float v000, float v100, float v010, float v110,
|
||||
float v001, float v101, float v011, float v111,
|
||||
float x, float y, float z)
|
||||
{
|
||||
/*float tx = easeCurve(x);
|
||||
float ty = easeCurve(y);
|
||||
float tz = easeCurve(z);*/
|
||||
float tx = x;
|
||||
float ty = y;
|
||||
float tz = z;
|
||||
return(
|
||||
v000 * (1 - tx) * (1 - ty) * (1 - tz) +
|
||||
v100 * tx * (1 - ty) * (1 - tz) +
|
||||
v010 * (1 - tx) * ty * (1 - tz) +
|
||||
v110 * tx * ty * (1 - tz) +
|
||||
v001 * (1 - tx) * (1 - ty) * tz +
|
||||
v101 * tx * (1 - ty) * tz +
|
||||
v011 * (1 - tx) * ty * tz +
|
||||
v111 * tx * ty * tz
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
float noise2d_gradient(float x, float y, int seed)
|
||||
{
|
||||
// Calculate the integer coordinates
|
||||
int x0 = (x > 0.0 ? (int)x : (int)x - 1);
|
||||
int y0 = (y > 0.0 ? (int)y : (int)y - 1);
|
||||
// Calculate the remaining part of the coordinates
|
||||
double xl = x - (double)x0;
|
||||
double yl = y - (double)y0;
|
||||
float xl = x - (float)x0;
|
||||
float yl = y - (float)y0;
|
||||
// Calculate random cosine lookup table indices for the integer corners.
|
||||
// They are looked up as unit vector gradients from the lookup table.
|
||||
int n00 = (int)((noise2d(x0, y0, seed)+1)*8);
|
||||
|
@ -111,119 +138,126 @@ double noise2d_gradient(double x, double y, int seed)
|
|||
int n01 = (int)((noise2d(x0, y0+1, seed)+1)*8);
|
||||
int n11 = (int)((noise2d(x0+1, y0+1, seed)+1)*8);
|
||||
// Make a dot product for the gradients and the positions, to get the values
|
||||
double s = dotProduct(cos_lookup[n00], cos_lookup[(n00+12)%16], xl, yl);
|
||||
double u = dotProduct(-cos_lookup[n10], cos_lookup[(n10+12)%16], 1.-xl, yl);
|
||||
double v = dotProduct(cos_lookup[n01], -cos_lookup[(n01+12)%16], xl, 1.-yl);
|
||||
double w = dotProduct(-cos_lookup[n11], -cos_lookup[(n11+12)%16], 1.-xl, 1.-yl);
|
||||
float s = dotProduct(cos_lookup[n00], cos_lookup[(n00+12)%16], xl, yl);
|
||||
float u = dotProduct(-cos_lookup[n10], cos_lookup[(n10+12)%16], 1.-xl, yl);
|
||||
float v = dotProduct(cos_lookup[n01], -cos_lookup[(n01+12)%16], xl, 1.-yl);
|
||||
float w = dotProduct(-cos_lookup[n11], -cos_lookup[(n11+12)%16], 1.-xl, 1.-yl);
|
||||
// Interpolate between the values
|
||||
return biLinearInterpolation(s,u,v,w,xl,yl);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
double noise2d_gradient(double x, double y, int seed)
|
||||
|
||||
float noise2d_gradient(float x, float y, int seed)
|
||||
{
|
||||
// Calculate the integer coordinates
|
||||
int x0 = (x > 0.0 ? (int)x : (int)x - 1);
|
||||
int y0 = (y > 0.0 ? (int)y : (int)y - 1);
|
||||
int x0 = myfloor(x);
|
||||
int y0 = myfloor(y);
|
||||
// Calculate the remaining part of the coordinates
|
||||
double xl = x - (double)x0;
|
||||
double yl = y - (double)y0;
|
||||
// Get values for corners of cube
|
||||
double v00 = noise2d(x0, y0, seed);
|
||||
double v10 = noise2d(x0+1, y0, seed);
|
||||
double v01 = noise2d(x0, y0+1, seed);
|
||||
double v11 = noise2d(x0+1, y0+1, seed);
|
||||
float xl = x - (float)x0;
|
||||
float yl = y - (float)y0;
|
||||
// Get values for corners of square
|
||||
float v00 = noise2d(x0, y0, seed);
|
||||
float v10 = noise2d(x0+1, y0, seed);
|
||||
float v01 = noise2d(x0, y0+1, seed);
|
||||
float v11 = noise2d(x0+1, y0+1, seed);
|
||||
// Interpolate
|
||||
return biLinearInterpolation(v00,v10,v01,v11,xl,yl);
|
||||
}
|
||||
#endif
|
||||
|
||||
double noise3d_gradient(double x, double y, double z, int seed)
|
||||
|
||||
float noise3d_gradient(float x, float y, float z, int seed)
|
||||
{
|
||||
// Calculate the integer coordinates
|
||||
int x0 = (x > 0.0 ? (int)x : (int)x - 1);
|
||||
int y0 = (y > 0.0 ? (int)y : (int)y - 1);
|
||||
int z0 = (z > 0.0 ? (int)z : (int)z - 1);
|
||||
int x0 = myfloor(x);
|
||||
int y0 = myfloor(y);
|
||||
int z0 = myfloor(z);
|
||||
// Calculate the remaining part of the coordinates
|
||||
double xl = x - (double)x0;
|
||||
double yl = y - (double)y0;
|
||||
double zl = z - (double)z0;
|
||||
float xl = x - (float)x0;
|
||||
float yl = y - (float)y0;
|
||||
float zl = z - (float)z0;
|
||||
// Get values for corners of cube
|
||||
double v000 = noise3d(x0, y0, z0, seed);
|
||||
double v100 = noise3d(x0+1, y0, z0, seed);
|
||||
double v010 = noise3d(x0, y0+1, z0, seed);
|
||||
double v110 = noise3d(x0+1, y0+1, z0, seed);
|
||||
double v001 = noise3d(x0, y0, z0+1, seed);
|
||||
double v101 = noise3d(x0+1, y0, z0+1, seed);
|
||||
double v011 = noise3d(x0, y0+1, z0+1, seed);
|
||||
double v111 = noise3d(x0+1, y0+1, z0+1, seed);
|
||||
float v000 = noise3d(x0, y0, z0, seed);
|
||||
float v100 = noise3d(x0 + 1, y0, z0, seed);
|
||||
float v010 = noise3d(x0, y0 + 1, z0, seed);
|
||||
float v110 = noise3d(x0 + 1, y0 + 1, z0, seed);
|
||||
float v001 = noise3d(x0, y0, z0 + 1, seed);
|
||||
float v101 = noise3d(x0 + 1, y0, z0 + 1, seed);
|
||||
float v011 = noise3d(x0, y0 + 1, z0 + 1, seed);
|
||||
float v111 = noise3d(x0 + 1, y0 + 1, z0 + 1, seed);
|
||||
// Interpolate
|
||||
return triLinearInterpolation(v000,v100,v010,v110,v001,v101,v011,v111,xl,yl,zl);
|
||||
return triLinearInterpolation(v000, v100, v010, v110,
|
||||
v001, v101, v011, v111,
|
||||
xl, yl, zl);
|
||||
}
|
||||
|
||||
double noise2d_perlin(double x, double y, int seed,
|
||||
int octaves, double persistence)
|
||||
|
||||
float noise2d_perlin(float x, float y, int seed,
|
||||
int octaves, float persistence)
|
||||
{
|
||||
double a = 0;
|
||||
double f = 1.0;
|
||||
double g = 1.0;
|
||||
for(int i=0; i<octaves; i++)
|
||||
float a = 0;
|
||||
float f = 1.0;
|
||||
float g = 1.0;
|
||||
for (int i = 0; i < octaves; i++)
|
||||
{
|
||||
a += g * noise2d_gradient(x*f, y*f, seed+i);
|
||||
a += g * noise2d_gradient(x * f, y * f, seed + i);
|
||||
f *= 2.0;
|
||||
g *= persistence;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
double noise2d_perlin_abs(double x, double y, int seed,
|
||||
int octaves, double persistence)
|
||||
|
||||
float noise2d_perlin_abs(float x, float y, int seed,
|
||||
int octaves, float persistence)
|
||||
{
|
||||
double a = 0;
|
||||
double f = 1.0;
|
||||
double g = 1.0;
|
||||
for(int i=0; i<octaves; i++)
|
||||
float a = 0;
|
||||
float f = 1.0;
|
||||
float g = 1.0;
|
||||
for (int i = 0; i < octaves; i++)
|
||||
{
|
||||
a += g * fabs(noise2d_gradient(x*f, y*f, seed+i));
|
||||
a += g * fabs(noise2d_gradient(x * f, y * f, seed + i));
|
||||
f *= 2.0;
|
||||
g *= persistence;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
double noise3d_perlin(double x, double y, double z, int seed,
|
||||
int octaves, double persistence)
|
||||
|
||||
float noise3d_perlin(float x, float y, float z, int seed,
|
||||
int octaves, float persistence)
|
||||
{
|
||||
double a = 0;
|
||||
double f = 1.0;
|
||||
double g = 1.0;
|
||||
for(int i=0; i<octaves; i++)
|
||||
float a = 0;
|
||||
float f = 1.0;
|
||||
float g = 1.0;
|
||||
for (int i = 0; i < octaves; i++)
|
||||
{
|
||||
a += g * noise3d_gradient(x*f, y*f, z*f, seed+i);
|
||||
a += g * noise3d_gradient(x * f, y * f, z * f, seed + i);
|
||||
f *= 2.0;
|
||||
g *= persistence;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
double noise3d_perlin_abs(double x, double y, double z, int seed,
|
||||
int octaves, double persistence)
|
||||
|
||||
float noise3d_perlin_abs(float x, float y, float z, int seed,
|
||||
int octaves, float persistence)
|
||||
{
|
||||
double a = 0;
|
||||
double f = 1.0;
|
||||
double g = 1.0;
|
||||
for(int i=0; i<octaves; i++)
|
||||
float a = 0;
|
||||
float f = 1.0;
|
||||
float g = 1.0;
|
||||
for (int i = 0; i < octaves; i++)
|
||||
{
|
||||
a += g * fabs(noise3d_gradient(x*f, y*f, z*f, seed+i));
|
||||
a += g * fabs(noise3d_gradient(x * f, y * f, z * f, seed + i));
|
||||
f *= 2.0;
|
||||
g *= persistence;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
// -1->0, 0->1, 1->0
|
||||
double contour(double v)
|
||||
float contour(float v)
|
||||
{
|
||||
v = fabs(v);
|
||||
if(v >= 1.0)
|
||||
|
@ -231,195 +265,276 @@ double contour(double v)
|
|||
return (1.0-v);
|
||||
}
|
||||
|
||||
double noise3d_param(const NoiseParams ¶m, double x, double y, double z)
|
||||
{
|
||||
double s = param.pos_scale;
|
||||
x /= s;
|
||||
y /= s;
|
||||
z /= s;
|
||||
|
||||
if(param.type == NOISE_CONSTANT_ONE)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
else if(param.type == NOISE_PERLIN)
|
||||
{
|
||||
return param.noise_scale*noise3d_perlin(x,y,z, param.seed,
|
||||
param.octaves,
|
||||
param.persistence);
|
||||
}
|
||||
else if(param.type == NOISE_PERLIN_ABS)
|
||||
{
|
||||
return param.noise_scale*noise3d_perlin_abs(x,y,z, param.seed,
|
||||
param.octaves,
|
||||
param.persistence);
|
||||
}
|
||||
else if(param.type == NOISE_PERLIN_CONTOUR)
|
||||
{
|
||||
return contour(param.noise_scale*noise3d_perlin(x,y,z,
|
||||
param.seed, param.octaves,
|
||||
param.persistence));
|
||||
}
|
||||
else if(param.type == NOISE_PERLIN_CONTOUR_FLIP_YZ)
|
||||
{
|
||||
return contour(param.noise_scale*noise3d_perlin(x,z,y,
|
||||
param.seed, param.octaves,
|
||||
param.persistence));
|
||||
}
|
||||
else assert(0);
|
||||
///////////////////////// [ New perlin stuff ] ////////////////////////////
|
||||
|
||||
|
||||
Noise::Noise(NoiseParams *np, int seed, int sx, int sy) {
|
||||
int nlx, nly;
|
||||
float ofactor;
|
||||
|
||||
//maximum possible spread value factor
|
||||
ofactor = (float)(1 << (np->octaves - 1));
|
||||
|
||||
//noise lattice point count
|
||||
//(int)(sz * spread * ofactor) is # of lattice points crossed due to length
|
||||
// + 2 for the two initial endpoints
|
||||
// + 1 for potentially crossing a boundary due to offset
|
||||
nlx = (int)(sx * ofactor / np->spread.X) + 3;
|
||||
nly = (int)(sy * ofactor / np->spread.Y) + 3;
|
||||
|
||||
this->np = np;
|
||||
this->seed = seed;
|
||||
this->sx = sx;
|
||||
this->sy = sy;
|
||||
this->sz = 0;
|
||||
this->noisebuf = new float[nlx * nly];
|
||||
this->buf = new float[sx * sy];
|
||||
this->result = new float[sx * sy];
|
||||
}
|
||||
|
||||
|
||||
Noise::Noise(NoiseParams *np, int seed, int sx, int sy, int sz) {
|
||||
int nlx, nly, nlz;
|
||||
float ofactor;
|
||||
|
||||
ofactor = (float)(1 << (np->octaves - 1));
|
||||
nlx = (int)(sx * ofactor / np->spread.X) + 3;
|
||||
nly = (int)(sy * ofactor / np->spread.Y) + 3;
|
||||
nlz = (int)(sz * ofactor / np->spread.Z) + 3;
|
||||
|
||||
this->np = np;
|
||||
this->seed = seed;
|
||||
this->sx = sx;
|
||||
this->sy = sy;
|
||||
this->sz = sz;
|
||||
this->noisebuf = new float[nlx * nly * nlz];
|
||||
this->buf = new float[sx * sy * sz];
|
||||
this->result = new float[sx * sy * sz];
|
||||
}
|
||||
|
||||
|
||||
Noise::~Noise() {
|
||||
delete[] buf;
|
||||
delete[] result;
|
||||
delete[] noisebuf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
NoiseBuffer
|
||||
*/
|
||||
* NB: This algorithm is not optimal in terms of space complexity. The entire
|
||||
* integer lattice of noise points could be done as 2 lines instead, and for 3D,
|
||||
* 2 lines + 2 planes.
|
||||
* However, this would require the noise calls to be interposed with the
|
||||
* interpolation loops, which may trash the icache, leading to lower overall
|
||||
* performance.
|
||||
* Another optimization that could save half as many noise calls is to carry over
|
||||
* values from the previous noise lattice as midpoints in the new lattice for the
|
||||
* next octave.
|
||||
*/
|
||||
void Noise::gradientMap2D(float x, float y, float step_x, float step_y, int seed) {
|
||||
float v00, v01, v10, v11, u, v, orig_u;
|
||||
int index, i, j, x0, y0, noisex, noisey;
|
||||
int nlx, nly;
|
||||
|
||||
NoiseBuffer::NoiseBuffer():
|
||||
m_data(NULL)
|
||||
{
|
||||
}
|
||||
x0 = floor(x);
|
||||
y0 = floor(y);
|
||||
u = x - (float)x0;
|
||||
v = y - (float)y0;
|
||||
orig_u = u;
|
||||
|
||||
NoiseBuffer::~NoiseBuffer()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
//calculate noise point lattice
|
||||
|
||||
void NoiseBuffer::clear()
|
||||
{
|
||||
if(m_data)
|
||||
delete[] m_data;
|
||||
m_data = NULL;
|
||||
m_size_x = 0;
|
||||
m_size_y = 0;
|
||||
m_size_z = 0;
|
||||
}
|
||||
nlx = (int)(u + sx * step_x) + 2;
|
||||
nly = (int)(v + sy * step_y) + 2;
|
||||
index = 0;
|
||||
for (j = 0; j != nly; j++)
|
||||
for (i = 0; i != nlx; i++)
|
||||
noisebuf[index++] = noise2d(x0 + i, y0 + j, seed);
|
||||
|
||||
void NoiseBuffer::create(const NoiseParams ¶m,
|
||||
double first_x, double first_y, double first_z,
|
||||
double last_x, double last_y, double last_z,
|
||||
double samplelength_x, double samplelength_y, double samplelength_z)
|
||||
{
|
||||
clear();
|
||||
//calculate interpolations
|
||||
noisey = 0;
|
||||
for (j = 0; j != sy; j++) {
|
||||
v00 = noisebuf[noisey * nlx];
|
||||
v10 = noisebuf[noisey * nlx + 1];
|
||||
v01 = noisebuf[(noisey + 1) * nlx];
|
||||
v11 = noisebuf[(noisey + 1) * nlx + 1];
|
||||
|
||||
m_start_x = first_x - samplelength_x;
|
||||
m_start_y = first_y - samplelength_y;
|
||||
m_start_z = first_z - samplelength_z;
|
||||
m_samplelength_x = samplelength_x;
|
||||
m_samplelength_y = samplelength_y;
|
||||
m_samplelength_z = samplelength_z;
|
||||
u = orig_u;
|
||||
noisex = 0;
|
||||
for (i = 0; i != sx; i++) {
|
||||
buf[j * sx + i] = biLinearInterpolation(v00, v10, v01, v11, u, v);
|
||||
u += step_x;
|
||||
if (u >= 1.0) {
|
||||
u -= 1.0;
|
||||
noisex++;
|
||||
v00 = v10;
|
||||
v01 = v11;
|
||||
v10 = noisebuf[noisey * nlx + noisex + 1];
|
||||
v11 = noisebuf[(noisey + 1) * nlx + noisex + 1];
|
||||
}
|
||||
}
|
||||
|
||||
m_size_x = (last_x - m_start_x)/samplelength_x + 2;
|
||||
m_size_y = (last_y - m_start_y)/samplelength_y + 2;
|
||||
m_size_z = (last_z - m_start_z)/samplelength_z + 2;
|
||||
|
||||
m_data = new double[m_size_x*m_size_y*m_size_z];
|
||||
|
||||
for(int x=0; x<m_size_x; x++)
|
||||
for(int y=0; y<m_size_y; y++)
|
||||
for(int z=0; z<m_size_z; z++)
|
||||
{
|
||||
double xd = (m_start_x + (double)x*m_samplelength_x);
|
||||
double yd = (m_start_y + (double)y*m_samplelength_y);
|
||||
double zd = (m_start_z + (double)z*m_samplelength_z);
|
||||
double a = noise3d_param(param, xd,yd,zd);
|
||||
intSet(x,y,z, a);
|
||||
v += step_y;
|
||||
if (v >= 1.0) {
|
||||
v -= 1.0;
|
||||
noisey++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseBuffer::multiply(const NoiseParams ¶m)
|
||||
{
|
||||
assert(m_data != NULL);
|
||||
|
||||
for(int x=0; x<m_size_x; x++)
|
||||
for(int y=0; y<m_size_y; y++)
|
||||
for(int z=0; z<m_size_z; z++)
|
||||
{
|
||||
double xd = (m_start_x + (double)x*m_samplelength_x);
|
||||
double yd = (m_start_y + (double)y*m_samplelength_y);
|
||||
double zd = (m_start_z + (double)z*m_samplelength_z);
|
||||
double a = noise3d_param(param, xd,yd,zd);
|
||||
intMultiply(x,y,z, a);
|
||||
void Noise::gradientMap3D(float x, float y, float z,
|
||||
float step_x, float step_y, float step_z,
|
||||
int seed) {
|
||||
float v000, v010, v100, v110;
|
||||
float v001, v011, v101, v111;
|
||||
float u, v, w, orig_u, orig_w;
|
||||
int index, i, j, k, x0, y0, z0, noisex, noisey, noisez;
|
||||
int nlx, nly, nlz;
|
||||
|
||||
x0 = floor(x);
|
||||
y0 = floor(y);
|
||||
z0 = floor(z);
|
||||
u = x - (float)x0;
|
||||
v = y - (float)y0;
|
||||
w = z - (float)z0;
|
||||
orig_u = u;
|
||||
orig_w = w;
|
||||
|
||||
//calculate noise point lattice
|
||||
nlx = (int)(u + sx * step_x) + 2;
|
||||
nly = (int)(v + sy * step_y) + 2;
|
||||
nlz = (int)(v + sy * step_z) + 2;
|
||||
index = 0;
|
||||
for (k = 0; k != nlz; k++)
|
||||
for (j = 0; j != nly; j++)
|
||||
for (i = 0; i != nlx; i++)
|
||||
noisebuf[index++] = noise3d(x0 + i, y0 + j, z0 + k, seed);
|
||||
|
||||
#define index(x, y, z) ((z) * nly * nlx + (y) * nlx + (x))
|
||||
|
||||
//calculate interpolations
|
||||
noisey = 0;
|
||||
noisez = 0;
|
||||
for (k = 0; k != sz; k++) {
|
||||
v000 = noisebuf[index(0, noisey, noisez)];
|
||||
v100 = noisebuf[index(1, noisey, noisez)];
|
||||
v010 = noisebuf[index(0, noisey + 1, noisez)];
|
||||
v110 = noisebuf[index(1, noisey + 1, noisez)];
|
||||
v001 = noisebuf[index(0, noisey, noisez + 1)];
|
||||
v101 = noisebuf[index(1, noisey, noisez + 1)];
|
||||
v011 = noisebuf[index(0, noisey + 1, noisez + 1)];
|
||||
v111 = noisebuf[index(1, noisey + 1, noisez + 1)];
|
||||
|
||||
w = orig_w;
|
||||
noisey = 0;
|
||||
for (j = 0; j != sy; j++) {
|
||||
v000 = noisebuf[index(0, noisey, noisez)];
|
||||
v100 = noisebuf[index(1, noisey, noisez)];
|
||||
v010 = noisebuf[index(0, noisey + 1, noisez)];
|
||||
v110 = noisebuf[index(1, noisey + 1, noisez)];
|
||||
v001 = noisebuf[index(0, noisey, noisez + 1)];
|
||||
v101 = noisebuf[index(1, noisey, noisez + 1)];
|
||||
v011 = noisebuf[index(0, noisey + 1, noisez + 1)];
|
||||
v111 = noisebuf[index(1, noisey + 1, noisez + 1)];
|
||||
|
||||
u = orig_u;
|
||||
noisex = 0;
|
||||
for (i = 0; i != sx; i++) {
|
||||
buf[j * sx + i] = triLinearInterpolation(
|
||||
v000, v100, v010, v110,
|
||||
v001, v101, v011, v111,
|
||||
u, v, w);
|
||||
u += step_x;
|
||||
if (u >= 1.0) {
|
||||
u -= 1.0;
|
||||
noisex++;
|
||||
v000 = v100;
|
||||
v010 = v110;
|
||||
v100 = noisebuf[index(noisex + 1, noisey, noisez)];
|
||||
v110 = noisebuf[index(noisex + 1, noisey + 1, noisez)];
|
||||
v001 = v101;
|
||||
v011 = v111;
|
||||
v101 = noisebuf[index(noisex + 1, noisey, noisez + 1)];
|
||||
v111 = noisebuf[index(noisex + 1, noisey + 1, noisez + 1)];
|
||||
}
|
||||
}
|
||||
|
||||
v += step_y;
|
||||
if (v >= 1.0) {
|
||||
v -= 1.0;
|
||||
noisey++;
|
||||
}
|
||||
}
|
||||
|
||||
w += step_z;
|
||||
if (w >= 1.0) {
|
||||
w -= 1.0;
|
||||
noisez++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
void NoiseBuffer::create(int seed, int octaves, double persistence,
|
||||
bool abs,
|
||||
double first_x, double first_y, double first_z,
|
||||
double last_x, double last_y, double last_z,
|
||||
double samplelength_x, double samplelength_y, double samplelength_z)
|
||||
{
|
||||
NoiseParams param;
|
||||
param.type = abs ? NOISE_PERLIN_ABS : NOISE_PERLIN;
|
||||
param.seed = seed;
|
||||
param.octaves = octaves;
|
||||
param.persistence = persistence;
|
||||
|
||||
create(param, first_x, first_y, first_z,
|
||||
last_x, last_y, last_z,
|
||||
samplelength_x, samplelength_y, samplelength_z);
|
||||
float *Noise::perlinMap2D(float x, float y) {
|
||||
float a = 0.0, f = 1.0, g = 1.0;
|
||||
int i, j, index, oct;
|
||||
|
||||
x /= np->spread.X;
|
||||
y /= np->spread.Y;
|
||||
|
||||
memset(result, 0, sizeof(float) * sx * sy);
|
||||
|
||||
for (oct = 0; oct < np->octaves; oct++) {
|
||||
gradientMap2D(x * f, y * f,
|
||||
f / np->spread.X, f / np->spread.Y,
|
||||
seed + np->seed + oct);
|
||||
|
||||
index = 0;
|
||||
for (j = 0; j != sy; j++) {
|
||||
for (i = 0; i != sx; i++) {
|
||||
result[index] += g * buf[index];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
f *= 2.0;
|
||||
g *= np->persist;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void NoiseBuffer::intSet(int x, int y, int z, double d)
|
||||
{
|
||||
int i = m_size_x*m_size_y*z + m_size_x*y + x;
|
||||
assert(i >= 0);
|
||||
assert(i < m_size_x*m_size_y*m_size_z);
|
||||
m_data[i] = d;
|
||||
|
||||
float *Noise::perlinMap3D(float x, float y, float z) {
|
||||
float a = 0.0, f = 1.0, g = 1.0;
|
||||
int i, j, k, index, oct;
|
||||
|
||||
x /= np->spread.X;
|
||||
y /= np->spread.Y;
|
||||
z /= np->spread.Z;
|
||||
|
||||
memset(result, 0, sizeof(float) * sx * sy * sz);
|
||||
|
||||
for (oct = 0; oct < np->octaves; oct++) {
|
||||
gradientMap3D(x * f, y * f, z * f,
|
||||
f / np->spread.X, f / np->spread.Y, f / np->spread.Z,
|
||||
seed + np->seed + oct);
|
||||
|
||||
index = 0;
|
||||
for (k = 0; k != sz; k++) {
|
||||
for (j = 0; j != sy; j++) {
|
||||
for (i = 0; i != sx; i++) {
|
||||
result[index] += g * buf[index];
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f *= 2.0;
|
||||
g *= np->persist;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void NoiseBuffer::intMultiply(int x, int y, int z, double d)
|
||||
{
|
||||
int i = m_size_x*m_size_y*z + m_size_x*y + x;
|
||||
assert(i >= 0);
|
||||
assert(i < m_size_x*m_size_y*m_size_z);
|
||||
m_data[i] = m_data[i] * d;
|
||||
}
|
||||
|
||||
double NoiseBuffer::intGet(int x, int y, int z)
|
||||
{
|
||||
int i = m_size_x*m_size_y*z + m_size_x*y + x;
|
||||
assert(i >= 0);
|
||||
assert(i < m_size_x*m_size_y*m_size_z);
|
||||
return m_data[i];
|
||||
}
|
||||
|
||||
double NoiseBuffer::get(double x, double y, double z)
|
||||
{
|
||||
x -= m_start_x;
|
||||
y -= m_start_y;
|
||||
z -= m_start_z;
|
||||
x /= m_samplelength_x;
|
||||
y /= m_samplelength_y;
|
||||
z /= m_samplelength_z;
|
||||
// Calculate the integer coordinates
|
||||
int x0 = (x > 0.0 ? (int)x : (int)x - 1);
|
||||
int y0 = (y > 0.0 ? (int)y : (int)y - 1);
|
||||
int z0 = (z > 0.0 ? (int)z : (int)z - 1);
|
||||
// Calculate the remaining part of the coordinates
|
||||
double xl = x - (double)x0;
|
||||
double yl = y - (double)y0;
|
||||
double zl = z - (double)z0;
|
||||
// Get values for corners of cube
|
||||
double v000 = intGet(x0, y0, z0);
|
||||
double v100 = intGet(x0+1, y0, z0);
|
||||
double v010 = intGet(x0, y0+1, z0);
|
||||
double v110 = intGet(x0+1, y0+1, z0);
|
||||
double v001 = intGet(x0, y0, z0+1);
|
||||
double v101 = intGet(x0+1, y0, z0+1);
|
||||
double v011 = intGet(x0, y0+1, z0+1);
|
||||
double v111 = intGet(x0+1, y0+1, z0+1);
|
||||
// Interpolate
|
||||
return triLinearInterpolation(v000,v100,v010,v110,v001,v101,v011,v111,xl,yl,zl);
|
||||
}
|
||||
|
||||
/*bool NoiseBuffer::contains(double x, double y, double z)
|
||||
{
|
||||
x -= m_start_x;
|
||||
y -= m_start_y;
|
||||
z -= m_start_z;
|
||||
x /= m_samplelength_x;
|
||||
y /= m_samplelength_y;
|
||||
z /= m_samplelength_z;
|
||||
if(x <= 0.0 || x >= m_size_x)
|
||||
}*/
|
||||
|
||||
|
|
131
src/noise.h
131
src/noise.h
|
@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define NOISE_HEADER
|
||||
|
||||
#include "debug.h"
|
||||
#include "irr_v3d.h"
|
||||
|
||||
class PseudoRandom
|
||||
{
|
||||
|
@ -59,91 +60,69 @@ private:
|
|||
int m_next;
|
||||
};
|
||||
|
||||
double easeCurve(double t);
|
||||
|
||||
// Return value: -1 ... 1
|
||||
double noise2d(int x, int y, int seed);
|
||||
double noise3d(int x, int y, int z, int seed);
|
||||
|
||||
double noise2d_gradient(double x, double y, int seed);
|
||||
double noise3d_gradient(double x, double y, double z, int seed);
|
||||
|
||||
double noise2d_perlin(double x, double y, int seed,
|
||||
int octaves, double persistence);
|
||||
|
||||
double noise2d_perlin_abs(double x, double y, int seed,
|
||||
int octaves, double persistence);
|
||||
|
||||
double noise3d_perlin(double x, double y, double z, int seed,
|
||||
int octaves, double persistence);
|
||||
|
||||
double noise3d_perlin_abs(double x, double y, double z, int seed,
|
||||
int octaves, double persistence);
|
||||
|
||||
enum NoiseType
|
||||
{
|
||||
NOISE_CONSTANT_ONE,
|
||||
NOISE_PERLIN,
|
||||
NOISE_PERLIN_ABS,
|
||||
NOISE_PERLIN_CONTOUR,
|
||||
NOISE_PERLIN_CONTOUR_FLIP_YZ,
|
||||
};
|
||||
|
||||
struct NoiseParams
|
||||
{
|
||||
NoiseType type;
|
||||
struct NoiseParams {
|
||||
float offset;
|
||||
float scale;
|
||||
v3f spread;
|
||||
int seed;
|
||||
int octaves;
|
||||
double persistence;
|
||||
double pos_scale;
|
||||
double noise_scale; // Useful for contour noises
|
||||
|
||||
NoiseParams(NoiseType type_=NOISE_PERLIN, int seed_=0,
|
||||
int octaves_=3, double persistence_=0.5,
|
||||
double pos_scale_=100.0, double noise_scale_=1.0):
|
||||
type(type_),
|
||||
seed(seed_),
|
||||
octaves(octaves_),
|
||||
persistence(persistence_),
|
||||
pos_scale(pos_scale_),
|
||||
noise_scale(noise_scale_)
|
||||
{
|
||||
}
|
||||
float persist;
|
||||
};
|
||||
|
||||
double noise3d_param(const NoiseParams ¶m, double x, double y, double z);
|
||||
|
||||
class NoiseBuffer
|
||||
{
|
||||
class Noise {
|
||||
public:
|
||||
NoiseBuffer();
|
||||
~NoiseBuffer();
|
||||
NoiseParams *np;
|
||||
int seed;
|
||||
int sx;
|
||||
int sy;
|
||||
int sz;
|
||||
float *noisebuf;
|
||||
float *buf;
|
||||
float *result;
|
||||
|
||||
void clear();
|
||||
void create(const NoiseParams ¶m,
|
||||
double first_x, double first_y, double first_z,
|
||||
double last_x, double last_y, double last_z,
|
||||
double samplelength_x, double samplelength_y, double samplelength_z);
|
||||
void multiply(const NoiseParams ¶m);
|
||||
// Deprecated
|
||||
void create(int seed, int octaves, double persistence,
|
||||
bool abs,
|
||||
double first_x, double first_y, double first_z,
|
||||
double last_x, double last_y, double last_z,
|
||||
double samplelength_x, double samplelength_y, double samplelength_z);
|
||||
Noise(NoiseParams *np, int seed, int sx, int sy);
|
||||
Noise(NoiseParams *np, int seed, int sx, int sy, int sz);
|
||||
~Noise();
|
||||
|
||||
void intSet(int x, int y, int z, double d);
|
||||
void intMultiply(int x, int y, int z, double d);
|
||||
double intGet(int x, int y, int z);
|
||||
double get(double x, double y, double z);
|
||||
//bool contains(double x, double y, double z);
|
||||
|
||||
private:
|
||||
double *m_data;
|
||||
double m_start_x, m_start_y, m_start_z;
|
||||
double m_samplelength_x, m_samplelength_y, m_samplelength_z;
|
||||
int m_size_x, m_size_y, m_size_z;
|
||||
void gradientMap2D(
|
||||
float x, float y,
|
||||
float step_x, float step_y,
|
||||
int seed);
|
||||
void gradientMap3D(
|
||||
float x, float y, float z,
|
||||
float step_x, float step_y, float step_z,
|
||||
int seed);
|
||||
float *perlinMap2D(float x, float y);
|
||||
float *perlinMap3D(float x, float y, float z);
|
||||
};
|
||||
|
||||
// Return value: -1 ... 1
|
||||
float noise2d(int x, int y, int seed);
|
||||
float noise3d(int x, int y, int z, int seed);
|
||||
|
||||
float noise2d_gradient(float x, float y, int seed);
|
||||
float noise3d_gradient(float x, float y, float z, int seed);
|
||||
|
||||
float noise2d_perlin(float x, float y, int seed,
|
||||
int octaves, float persistence);
|
||||
|
||||
float noise2d_perlin_abs(float x, float y, int seed,
|
||||
int octaves, float persistence);
|
||||
|
||||
float noise3d_perlin(float x, float y, float z, int seed,
|
||||
int octaves, float persistence);
|
||||
|
||||
float noise3d_perlin_abs(float x, float y, float z, int seed,
|
||||
int octaves, float persistence);
|
||||
|
||||
inline float easeCurve(float t) {
|
||||
return t * t * t * (t * (6.f * t - 15.f) + 10.f);
|
||||
}
|
||||
|
||||
#define NoisePerlin2D(np, x, y, s) ((np)->offset + (np)->scale * \
|
||||
noise2d_perlin((float)(x) * (np)->spread.X, (float)(y) * (np)->spread.Y, \
|
||||
(s) + (np)->seed, (np)->octaves, (np)->persist))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -3240,8 +3240,8 @@ class LuaPerlinNoise
|
|||
private:
|
||||
int seed;
|
||||
int octaves;
|
||||
double persistence;
|
||||
double scale;
|
||||
float persistence;
|
||||
float scale;
|
||||
static const char className[];
|
||||
static const luaL_reg methods[];
|
||||
|
||||
|
@ -3273,8 +3273,8 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
LuaPerlinNoise(int a_seed, int a_octaves, double a_persistence,
|
||||
double a_scale):
|
||||
LuaPerlinNoise(int a_seed, int a_octaves, float a_persistence,
|
||||
float a_scale):
|
||||
seed(a_seed),
|
||||
octaves(a_octaves),
|
||||
persistence(a_persistence),
|
||||
|
@ -3292,8 +3292,8 @@ public:
|
|||
{
|
||||
int seed = luaL_checkint(L, 1);
|
||||
int octaves = luaL_checkint(L, 2);
|
||||
double persistence = luaL_checknumber(L, 3);
|
||||
double scale = luaL_checknumber(L, 4);
|
||||
float persistence = luaL_checknumber(L, 3);
|
||||
float scale = luaL_checknumber(L, 4);
|
||||
LuaPerlinNoise *o = new LuaPerlinNoise(seed, octaves, persistence, scale);
|
||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||
luaL_getmetatable(L, className);
|
||||
|
@ -3999,8 +3999,8 @@ private:
|
|||
|
||||
int seeddiff = luaL_checkint(L, 2);
|
||||
int octaves = luaL_checkint(L, 3);
|
||||
double persistence = luaL_checknumber(L, 4);
|
||||
double scale = luaL_checknumber(L, 5);
|
||||
float persistence = luaL_checknumber(L, 4);
|
||||
float scale = luaL_checknumber(L, 5);
|
||||
|
||||
LuaPerlinNoise *n = new LuaPerlinNoise(seeddiff + int(env->getServerMap().getSeed()), octaves, persistence, scale);
|
||||
*(void **)(lua_newuserdata(L, sizeof(void *))) = n;
|
||||
|
|
|
@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "itemdef.h"
|
||||
#include "craftdef.h"
|
||||
#include "mapgen.h"
|
||||
#include "biome.h"
|
||||
#include "content_mapnode.h"
|
||||
#include "content_nodemeta.h"
|
||||
#include "content_abm.h"
|
||||
|
@ -169,6 +170,10 @@ void * EmergeThread::Thread()
|
|||
|
||||
v3s16 last_tried_pos(-32768,-32768,-32768); // For error output
|
||||
|
||||
ServerMap &map = ((ServerMap&)m_server->m_env->getMap());
|
||||
EmergeManager *emerge = m_server->m_emerge;
|
||||
Mapgen *mapgen = new Mapgen( m_server->m_emerge->biomedef,/*mapgenid*/ 0, map.getSeed()); ////////fix this...!
|
||||
|
||||
/*
|
||||
Get block info from queue, emerge them and send them
|
||||
to clients.
|
||||
|
@ -233,7 +238,7 @@ void * EmergeThread::Thread()
|
|||
<<"("<<p.X<<","<<p.Y<<","<<p.Z<<") "
|
||||
<<"only_from_disk="<<only_from_disk<<std::endl;
|
||||
|
||||
ServerMap &map = ((ServerMap&)m_server->m_env->getMap());
|
||||
|
||||
|
||||
MapBlock *block = NULL;
|
||||
bool got_block = true;
|
||||
|
@ -245,7 +250,7 @@ void * EmergeThread::Thread()
|
|||
*/
|
||||
|
||||
bool started_generate = false;
|
||||
mapgen::BlockMakeData data;
|
||||
BlockMakeData data;
|
||||
|
||||
{
|
||||
JMutexAutoLock envlock(m_server->m_env_mutex);
|
||||
|
@ -287,7 +292,8 @@ void * EmergeThread::Thread()
|
|||
SPT_AVG);
|
||||
TimeTaker t("mapgen::make_block()");
|
||||
|
||||
mapgen::make_block(&data);
|
||||
mapgen->makeChunk(&data);
|
||||
//mapgen::make_block(&data);
|
||||
|
||||
if(enable_mapgen_debug_info == false)
|
||||
t.stop(true); // Hide output
|
||||
|
@ -332,7 +338,7 @@ void * EmergeThread::Thread()
|
|||
{
|
||||
TimeTaker timer("on_generated");
|
||||
scriptapi_environment_on_generated(m_server->m_lua,
|
||||
minp, maxp, mapgen::get_blockseed(data.seed, minp));
|
||||
minp, maxp, emerge->getBlockSeed(minp));
|
||||
/*int t = timer.stop(true);
|
||||
dstream<<"on_generated took "<<t<<"ms"<<std::endl;*/
|
||||
}
|
||||
|
@ -937,6 +943,7 @@ Server::Server(
|
|||
m_rollback(NULL),
|
||||
m_rollback_sink_enabled(true),
|
||||
m_enable_rollback_recording(false),
|
||||
m_emerge(NULL),
|
||||
m_lua(NULL),
|
||||
m_itemdef(createItemDefManager()),
|
||||
m_nodedef(createNodeDefManager()),
|
||||
|
@ -976,6 +983,9 @@ Server::Server(
|
|||
infostream<<"- config: "<<m_path_config<<std::endl;
|
||||
infostream<<"- game: "<<m_gamespec.path<<std::endl;
|
||||
|
||||
// Create emerge manager
|
||||
m_emerge = new EmergeManager(this);
|
||||
|
||||
// Create rollback manager
|
||||
std::string rollback_path = m_path_world+DIR_DELIM+"rollback.txt";
|
||||
m_rollback = createRollbackManager(rollback_path, this);
|
||||
|
@ -1082,9 +1092,12 @@ Server::Server(
|
|||
// Apply item aliases in the node definition manager
|
||||
m_nodedef->updateAliases(m_itemdef);
|
||||
|
||||
// Add default biomes after nodedef had its aliases added
|
||||
m_emerge->biomedef->addDefaultBiomes();
|
||||
|
||||
// Initialize Environment
|
||||
|
||||
m_env = new ServerEnvironment(new ServerMap(path_world, this), m_lua,
|
||||
m_env = new ServerEnvironment(new ServerMap(path_world, this, m_emerge), m_lua,
|
||||
this, this);
|
||||
|
||||
// Give environment reference to scripting api
|
||||
|
@ -1184,6 +1197,7 @@ Server::~Server()
|
|||
i = m_clients.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
|
||||
// Delete client
|
||||
delete i.getNode()->getValue();
|
||||
}
|
||||
|
@ -1192,6 +1206,7 @@ Server::~Server()
|
|||
// Delete things in the reverse order of creation
|
||||
delete m_env;
|
||||
delete m_rollback;
|
||||
delete m_emerge;
|
||||
delete m_event;
|
||||
delete m_itemdef;
|
||||
delete m_nodedef;
|
||||
|
@ -4832,7 +4847,7 @@ v3f findSpawnPos(ServerMap &map)
|
|||
#endif
|
||||
|
||||
#if 1
|
||||
s16 water_level = g_settings->getS16("water_level");
|
||||
s16 water_level = map.m_emerge->water_level; //g_settings->getS16("default_water_level");
|
||||
|
||||
// Try to find a good place a few times
|
||||
for(s32 i=0; i<1000; i++)
|
||||
|
|
|
@ -739,6 +739,9 @@ private:
|
|||
bool m_rollback_sink_enabled;
|
||||
bool m_enable_rollback_recording; // Updated once in a while
|
||||
|
||||
// Emerge manager
|
||||
EmergeManager *m_emerge;
|
||||
|
||||
// Scripting
|
||||
// Envlock and conlock should be locked when using Lua
|
||||
lua_State *m_lua;
|
||||
|
|
|
@ -574,10 +574,7 @@ public:
|
|||
set(name, "false");
|
||||
}
|
||||
|
||||
void setS32(std::string name, s32 value)
|
||||
{
|
||||
set(name, itos(value));
|
||||
}
|
||||
|
||||
|
||||
void setFloat(std::string name, float value)
|
||||
{
|
||||
|
@ -598,6 +595,16 @@ public:
|
|||
set(name, os.str());
|
||||
}
|
||||
|
||||
void setS16(std::string name, s16 value)
|
||||
{
|
||||
set(name, itos(value));
|
||||
}
|
||||
|
||||
void setS32(std::string name, s32 value)
|
||||
{
|
||||
set(name, itos(value));
|
||||
}
|
||||
|
||||
void setU64(std::string name, u64 value)
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
|
|
@ -120,6 +120,7 @@ inline s16 rangelim(s16 i, s16 max)
|
|||
}
|
||||
|
||||
#define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
|
||||
#define myfloor(x) ((x) > 0.0 ? (int)(x) : (int)(x) - 1)
|
||||
|
||||
inline v3s16 arealim(v3s16 p, s16 d)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue