forked from Mirrorlandia_minetest/minetest
The new mapgen, noise functions, et al.
This commit is contained in:
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
|
||||
|
229
src/biome.cpp
Normal file
229
src/biome.cpp
Normal file
@ -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;
|
||||
}
|
79
src/biome.h
Normal file
79
src/biome.h
Normal file
@ -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
|
||||
|
@ -1,253 +1,253 @@
|
||||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 "guiPauseMenu.h"
|
||||
#include "debug.h"
|
||||
#include "serialization.h"
|
||||
#include "porting.h"
|
||||
#include "config.h"
|
||||
#include "main.h"
|
||||
#include <IGUICheckBox.h>
|
||||
#include <IGUIEditBox.h>
|
||||
#include <IGUIButton.h>
|
||||
#include <IGUIStaticText.h>
|
||||
#include <IGUIFont.h>
|
||||
#include "gettext.h"
|
||||
#include "util/string.h"
|
||||
|
||||
GUIPauseMenu::GUIPauseMenu(gui::IGUIEnvironment* env,
|
||||
gui::IGUIElement* parent, s32 id,
|
||||
IGameCallback *gamecallback,
|
||||
IMenuManager *menumgr,
|
||||
bool simple_singleplayer_mode):
|
||||
GUIModalMenu(env, parent, id, menumgr),
|
||||
m_gamecallback(gamecallback),
|
||||
m_simple_singleplayer_mode(simple_singleplayer_mode)
|
||||
{
|
||||
}
|
||||
|
||||
GUIPauseMenu::~GUIPauseMenu()
|
||||
{
|
||||
removeChildren();
|
||||
}
|
||||
|
||||
void GUIPauseMenu::removeChildren()
|
||||
{
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(256);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(257);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(258);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(259);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(260);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(261);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
}
|
||||
|
||||
void GUIPauseMenu::regenerateGui(v2u32 screensize)
|
||||
{
|
||||
/*
|
||||
Remove stuff
|
||||
*/
|
||||
removeChildren();
|
||||
|
||||
/*
|
||||
Calculate new sizes and positions
|
||||
*/
|
||||
core::rect<s32> rect(
|
||||
screensize.X/2 - 580/2,
|
||||
screensize.Y/2 - 300/2,
|
||||
screensize.X/2 + 580/2,
|
||||
screensize.Y/2 + 300/2
|
||||
);
|
||||
|
||||
DesiredRect = rect;
|
||||
recalculateAbsolutePosition(false);
|
||||
|
||||
v2s32 size = rect.getSize();
|
||||
|
||||
/*
|
||||
Add stuff
|
||||
*/
|
||||
const s32 btn_height = 30;
|
||||
const s32 btn_gap = 20;
|
||||
const s32 btn_num = m_simple_singleplayer_mode ? 3 : 4;
|
||||
s32 btn_y = size.Y/2-((btn_num*btn_height+(btn_num-1)*btn_gap))/2;
|
||||
changeCtype("");
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 140, btn_height);
|
||||
rect = rect + v2s32(size.X/2-140/2, btn_y);
|
||||
Environment->addButton(rect, this, 256,
|
||||
wgettext("Continue"));
|
||||
}
|
||||
btn_y += btn_height + btn_gap;
|
||||
if(!m_simple_singleplayer_mode)
|
||||
{
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 140, btn_height);
|
||||
rect = rect + v2s32(size.X/2-140/2, btn_y);
|
||||
Environment->addButton(rect, this, 261,
|
||||
wgettext("Change Password"));
|
||||
}
|
||||
btn_y += btn_height + btn_gap;
|
||||
}
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 140, btn_height);
|
||||
rect = rect + v2s32(size.X/2-140/2, btn_y);
|
||||
Environment->addButton(rect, this, 260,
|
||||
wgettext("Exit to Menu"));
|
||||
}
|
||||
btn_y += btn_height + btn_gap;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 140, btn_height);
|
||||
rect = rect + v2s32(size.X/2-140/2, btn_y);
|
||||
Environment->addButton(rect, this, 257,
|
||||
wgettext("Exit to OS"));
|
||||
}
|
||||
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 180, 240);
|
||||
rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2);
|
||||
Environment->addStaticText(chartowchar_t(gettext(
|
||||
"Default Controls:\n"
|
||||
"- WASD: Walk\n"
|
||||
"- Mouse left: dig/hit\n"
|
||||
"- Mouse right: place/use\n"
|
||||
"- Mouse wheel: select item\n"
|
||||
"- 0...9: select item\n"
|
||||
"- Shift: sneak\n"
|
||||
"- R: Toggle viewing all loaded chunks\n"
|
||||
"- I: Inventory menu\n"
|
||||
"- ESC: This menu\n"
|
||||
"- T: Chat\n"
|
||||
)), rect, false, true, this, 258);
|
||||
}
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 180, 220);
|
||||
rect = rect + v2s32(size.X/2 - 90 - rect.getWidth(), size.Y/2-rect.getHeight()/2);
|
||||
|
||||
v2u32 max_texture_size;
|
||||
{
|
||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
max_texture_size = driver->getMaxTextureSize();
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
os<<"Minetest\n";
|
||||
os<<BUILD_INFO<<"\n";
|
||||
os<<"path_user = "<<wrap_rows(porting::path_user, 20)<<"\n";
|
||||
|
||||
Environment->addStaticText(narrow_to_wide(os.str()).c_str(), rect, false, true, this, 259);
|
||||
}
|
||||
changeCtype("C");
|
||||
}
|
||||
|
||||
void GUIPauseMenu::drawMenu()
|
||||
{
|
||||
gui::IGUISkin* skin = Environment->getSkin();
|
||||
if (!skin)
|
||||
return;
|
||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
|
||||
video::SColor bgcolor(140,0,0,0);
|
||||
driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);
|
||||
|
||||
gui::IGUIElement::draw();
|
||||
}
|
||||
|
||||
bool GUIPauseMenu::OnEvent(const SEvent& event)
|
||||
{
|
||||
|
||||
if(event.EventType==EET_KEY_INPUT_EVENT)
|
||||
{
|
||||
if(event.KeyInput.PressedDown)
|
||||
{
|
||||
if(event.KeyInput.Key==KEY_ESCAPE)
|
||||
{
|
||||
quitMenu();
|
||||
return true;
|
||||
}
|
||||
else if(event.KeyInput.Key==KEY_RETURN)
|
||||
{
|
||||
quitMenu();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(event.EventType==EET_GUI_EVENT)
|
||||
{
|
||||
if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST
|
||||
&& isVisible())
|
||||
{
|
||||
if(!canTakeFocus(event.GUIEvent.Element))
|
||||
{
|
||||
dstream<<"GUIPauseMenu: Not allowing focus change."
|
||||
<<std::endl;
|
||||
// Returning true disables focus change
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
|
||||
{
|
||||
switch(event.GUIEvent.Caller->getID())
|
||||
{
|
||||
case 256: // continue
|
||||
quitMenu();
|
||||
// ALWAYS return immediately after quitMenu()
|
||||
return true;
|
||||
case 261:
|
||||
quitMenu();
|
||||
m_gamecallback->changePassword();
|
||||
return true;
|
||||
case 260: // disconnect
|
||||
m_gamecallback->disconnect();
|
||||
quitMenu();
|
||||
return true;
|
||||
case 257: // exit
|
||||
m_gamecallback->exitToOS();
|
||||
quitMenu();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Parent ? Parent->OnEvent(event) : false;
|
||||
}
|
||||
|
||||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 "guiPauseMenu.h"
|
||||
#include "debug.h"
|
||||
#include "serialization.h"
|
||||
#include "porting.h"
|
||||
#include "config.h"
|
||||
#include "main.h"
|
||||
#include <IGUICheckBox.h>
|
||||
#include <IGUIEditBox.h>
|
||||
#include <IGUIButton.h>
|
||||
#include <IGUIStaticText.h>
|
||||
#include <IGUIFont.h>
|
||||
#include "gettext.h"
|
||||
#include "util/string.h"
|
||||
|
||||
GUIPauseMenu::GUIPauseMenu(gui::IGUIEnvironment* env,
|
||||
gui::IGUIElement* parent, s32 id,
|
||||
IGameCallback *gamecallback,
|
||||
IMenuManager *menumgr,
|
||||
bool simple_singleplayer_mode):
|
||||
GUIModalMenu(env, parent, id, menumgr),
|
||||
m_gamecallback(gamecallback),
|
||||
m_simple_singleplayer_mode(simple_singleplayer_mode)
|
||||
{
|
||||
}
|
||||
|
||||
GUIPauseMenu::~GUIPauseMenu()
|
||||
{
|
||||
removeChildren();
|
||||
}
|
||||
|
||||
void GUIPauseMenu::removeChildren()
|
||||
{
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(256);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(257);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(258);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(259);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(260);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(261);
|
||||
if(e != NULL)
|
||||
e->remove();
|
||||
}
|
||||
}
|
||||
|
||||
void GUIPauseMenu::regenerateGui(v2u32 screensize)
|
||||
{
|
||||
/*
|
||||
Remove stuff
|
||||
*/
|
||||
removeChildren();
|
||||
|
||||
/*
|
||||
Calculate new sizes and positions
|
||||
*/
|
||||
core::rect<s32> rect(
|
||||
screensize.X/2 - 580/2,
|
||||
screensize.Y/2 - 300/2,
|
||||
screensize.X/2 + 580/2,
|
||||
screensize.Y/2 + 300/2
|
||||
);
|
||||
|
||||
DesiredRect = rect;
|
||||
recalculateAbsolutePosition(false);
|
||||
|
||||
v2s32 size = rect.getSize();
|
||||
|
||||
/*
|
||||
Add stuff
|
||||
*/
|
||||
const s32 btn_height = 30;
|
||||
const s32 btn_gap = 20;
|
||||
const s32 btn_num = m_simple_singleplayer_mode ? 3 : 4;
|
||||
s32 btn_y = size.Y/2-((btn_num*btn_height+(btn_num-1)*btn_gap))/2;
|
||||
changeCtype("");
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 140, btn_height);
|
||||
rect = rect + v2s32(size.X/2-140/2, btn_y);
|
||||
Environment->addButton(rect, this, 256,
|
||||
wgettext("Continue"));
|
||||
}
|
||||
btn_y += btn_height + btn_gap;
|
||||
if(!m_simple_singleplayer_mode)
|
||||
{
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 140, btn_height);
|
||||
rect = rect + v2s32(size.X/2-140/2, btn_y);
|
||||
Environment->addButton(rect, this, 261,
|
||||
wgettext("Change Password"));
|
||||
}
|
||||
btn_y += btn_height + btn_gap;
|
||||
}
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 140, btn_height);
|
||||
rect = rect + v2s32(size.X/2-140/2, btn_y);
|
||||
Environment->addButton(rect, this, 260,
|
||||
wgettext("Exit to Menu"));
|
||||
}
|
||||
btn_y += btn_height + btn_gap;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 140, btn_height);
|
||||
rect = rect + v2s32(size.X/2-140/2, btn_y);
|
||||
Environment->addButton(rect, this, 257,
|
||||
wgettext("Exit to OS"));
|
||||
}
|
||||
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 180, 240);
|
||||
rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2);
|
||||
Environment->addStaticText(chartowchar_t(gettext(
|
||||
"Default Controls:\n"
|
||||
"- WASD: Walk\n"
|
||||
"- Mouse left: dig/hit\n"
|
||||
"- Mouse right: place/use\n"
|
||||
"- Mouse wheel: select item\n"
|
||||
"- 0...9: select item\n"
|
||||
"- Shift: sneak\n"
|
||||
"- R: Toggle viewing all loaded chunks\n"
|
||||
"- I: Inventory menu\n"
|
||||
"- ESC: This menu\n"
|
||||
"- T: Chat\n"
|
||||
)), rect, false, true, this, 258);
|
||||
}
|
||||
{
|
||||
core::rect<s32> rect(0, 0, 180, 220);
|
||||
rect = rect + v2s32(size.X/2 - 90 - rect.getWidth(), size.Y/2-rect.getHeight()/2);
|
||||
|
||||
v2u32 max_texture_size;
|
||||
{
|
||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
max_texture_size = driver->getMaxTextureSize();
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
os<<"Minetest\n";
|
||||
os<<BUILD_INFO<<"\n";
|
||||
os<<"path_user = "<<wrap_rows(porting::path_user, 20)<<"\n";
|
||||
|
||||
Environment->addStaticText(narrow_to_wide(os.str()).c_str(), rect, false, true, this, 259);
|
||||
}
|
||||
changeCtype("C");
|
||||
}
|
||||
|
||||
void GUIPauseMenu::drawMenu()
|
||||
{
|
||||
gui::IGUISkin* skin = Environment->getSkin();
|
||||
if (!skin)
|
||||
return;
|
||||
video::IVideoDriver* driver = Environment->getVideoDriver();
|
||||
|
||||
video::SColor bgcolor(140,0,0,0);
|
||||
driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);
|
||||
|
||||
gui::IGUIElement::draw();
|
||||
}
|
||||
|
||||
bool GUIPauseMenu::OnEvent(const SEvent& event)
|
||||
{
|
||||
|
||||
if(event.EventType==EET_KEY_INPUT_EVENT)
|
||||
{
|
||||
if(event.KeyInput.PressedDown)
|
||||
{
|
||||
if(event.KeyInput.Key==KEY_ESCAPE)
|
||||
{
|
||||
quitMenu();
|
||||
return true;
|
||||
}
|
||||
else if(event.KeyInput.Key==KEY_RETURN)
|
||||
{
|
||||
quitMenu();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(event.EventType==EET_GUI_EVENT)
|
||||
{
|
||||
if(event.GUIEvent.EventType==gui::EGET_ELEMENT_FOCUS_LOST
|
||||
&& isVisible())
|
||||
{
|
||||
if(!canTakeFocus(event.GUIEvent.Element))
|
||||
{
|
||||
dstream<<"GUIPauseMenu: Not allowing focus change."
|
||||
<<std::endl;
|
||||
// Returning true disables focus change
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(event.GUIEvent.EventType==gui::EGET_BUTTON_CLICKED)
|
||||
{
|
||||
switch(event.GUIEvent.Caller->getID())
|
||||
{
|
||||
case 256: // continue
|
||||
quitMenu();
|
||||
// ALWAYS return immediately after quitMenu()
|
||||
return true;
|
||||
case 261:
|
||||
quitMenu();
|
||||
m_gamecallback->changePassword();
|
||||
return true;
|
||||
case 260: // disconnect
|
||||
m_gamecallback->disconnect();
|
||||
quitMenu();
|
||||
return true;
|
||||
case 257: // exit
|
||||
m_gamecallback->exitToOS();
|
||||
quitMenu();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Parent ? Parent->OnEvent(event) : false;
|
||||
}
|
||||
|
||||
|
@ -1,60 +1,60 @@
|
||||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 GUIPAUSEMENU_HEADER
|
||||
#define GUIPAUSEMENU_HEADER
|
||||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "modalMenu.h"
|
||||
|
||||
class IGameCallback
|
||||
{
|
||||
public:
|
||||
virtual void exitToOS() = 0;
|
||||
virtual void disconnect() = 0;
|
||||
virtual void changePassword() = 0;
|
||||
};
|
||||
|
||||
class GUIPauseMenu : public GUIModalMenu
|
||||
{
|
||||
public:
|
||||
GUIPauseMenu(gui::IGUIEnvironment* env,
|
||||
gui::IGUIElement* parent, s32 id,
|
||||
IGameCallback *gamecallback,
|
||||
IMenuManager *menumgr,
|
||||
bool simple_singleplayer_mode);
|
||||
~GUIPauseMenu();
|
||||
|
||||
void removeChildren();
|
||||
/*
|
||||
Remove and re-add (or reposition) stuff
|
||||
*/
|
||||
void regenerateGui(v2u32 screensize);
|
||||
|
||||
void drawMenu();
|
||||
|
||||
bool OnEvent(const SEvent& event);
|
||||
|
||||
private:
|
||||
IGameCallback *m_gamecallback;
|
||||
bool m_simple_singleplayer_mode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Minetest-c55
|
||||
Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
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 GUIPAUSEMENU_HEADER
|
||||
#define GUIPAUSEMENU_HEADER
|
||||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "modalMenu.h"
|
||||
|
||||
class IGameCallback
|
||||
{
|
||||
public:
|
||||
virtual void exitToOS() = 0;
|
||||
virtual void disconnect() = 0;
|
||||
virtual void changePassword() = 0;
|
||||
};
|
||||
|
||||
class GUIPauseMenu : public GUIModalMenu
|
||||
{
|
||||
public:
|
||||
GUIPauseMenu(gui::IGUIEnvironment* env,
|
||||
gui::IGUIElement* parent, s32 id,
|
||||
IGameCallback *gamecallback,
|
||||
IMenuManager *menumgr,
|
||||
bool simple_singleplayer_mode);
|
||||
~GUIPauseMenu();
|
||||
|
||||
void removeChildren();
|
||||
/*
|
||||
Remove and re-add (or reposition) stuff
|
||||
*/
|
||||
void regenerateGui(v2u32 screensize);
|
||||
|
||||
void drawMenu();
|
||||
|
||||
bool OnEvent(const SEvent& event);
|
||||
|
||||
private:
|
||||
IGameCallback *m_gamecallback;
|
||||
bool m_simple_singleplayer_mode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
47
src/map.cpp
47
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);
|
||||
|
||||
@ -3100,8 +3116,11 @@ void ServerMap::loadMapMeta()
|
||||
break;
|
||||
params.parseConfigLine(line);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
442
src/mapgen.cpp
442
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,
|
||||
@ -190,7 +480,7 @@ static void make_room1(VoxelManipulator &vmanip, v3s16 roomsize, v3s16 roomplace
|
||||
vmanip.m_data[vi] = MapNode(ndef->getId("mapgen_cobble"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make +-Z walls
|
||||
for(s16 x=0; x<roomsize.X; x++)
|
||||
for(s16 y=0; y<roomsize.Y; y++)
|
||||
@ -214,7 +504,7 @@ static void make_room1(VoxelManipulator &vmanip, v3s16 roomsize, v3s16 roomplace
|
||||
vmanip.m_data[vi] = MapNode(ndef->getId("mapgen_cobble"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make +-Y walls (floor and ceiling)
|
||||
for(s16 z=0; z<roomsize.Z; z++)
|
||||
for(s16 x=0; x<roomsize.X; x++)
|
||||
@ -238,7 +528,7 @@ static void make_room1(VoxelManipulator &vmanip, v3s16 roomsize, v3s16 roomplace
|
||||
vmanip.m_data[vi] = MapNode(ndef->getId("mapgen_cobble"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fill with air
|
||||
for(s16 z=1; z<roomsize.Z-1; z++)
|
||||
for(s16 y=1; y<roomsize.Y-1; y++)
|
||||
@ -401,9 +691,9 @@ static void make_corridor(VoxelManipulator &vmanip, v3s16 doorplace,
|
||||
if(partcount >= partlength)
|
||||
{
|
||||
partcount = 0;
|
||||
|
||||
|
||||
dir = random_turn(random, dir);
|
||||
|
||||
|
||||
partlength = random.range(1,length);
|
||||
|
||||
make_stairs = 0;
|
||||
@ -443,7 +733,7 @@ public:
|
||||
{
|
||||
m_dir = dir;
|
||||
}
|
||||
|
||||
|
||||
bool findPlaceForDoor(v3s16 &result_place, v3s16 &result_dir)
|
||||
{
|
||||
for(u32 i=0; i<100; i++)
|
||||
@ -540,7 +830,7 @@ public:
|
||||
if(doordir == v3s16(0,0,-1)) // Z-
|
||||
roomplace = doorplace + v3s16(-roomsize.X/2,-1,-roomsize.Z+1);
|
||||
#endif
|
||||
|
||||
|
||||
// Check fit
|
||||
bool fits = true;
|
||||
for(s16 z=1; z<roomsize.Z-1; z++)
|
||||
@ -587,7 +877,7 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random,
|
||||
v3s16 areasize = vmanip.m_area.getExtent();
|
||||
v3s16 roomsize;
|
||||
v3s16 roomplace;
|
||||
|
||||
|
||||
/*
|
||||
Find place for first room
|
||||
*/
|
||||
@ -627,20 +917,20 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random,
|
||||
// No place found
|
||||
if(fits == false)
|
||||
return;
|
||||
|
||||
|
||||
/*
|
||||
Stores the center position of the last room made, so that
|
||||
a new corridor can be started from the last room instead of
|
||||
the new room, if chosen so.
|
||||
*/
|
||||
v3s16 last_room_center = roomplace+v3s16(roomsize.X/2,1,roomsize.Z/2);
|
||||
|
||||
|
||||
u32 room_count = random.range(2,7);
|
||||
for(u32 i=0; i<room_count; i++)
|
||||
{
|
||||
// Make a room to the determined place
|
||||
make_room1(vmanip, roomsize, roomplace, ndef);
|
||||
|
||||
|
||||
v3s16 room_center = roomplace + v3s16(roomsize.X/2,1,roomsize.Z/2);
|
||||
|
||||
// Place torch at room center (for testing)
|
||||
@ -649,7 +939,7 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random,
|
||||
// Quit if last room
|
||||
if(i == room_count-1)
|
||||
break;
|
||||
|
||||
|
||||
// Determine walker start position
|
||||
|
||||
bool start_in_last_room = (random.range(0,2)!=0);
|
||||
@ -667,7 +957,7 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random,
|
||||
// Store center of current room as the last one
|
||||
last_room_center = room_center;
|
||||
}
|
||||
|
||||
|
||||
// Create walker and find a place for a door
|
||||
RoomWalker walker(vmanip, walker_start_place, random, ndef);
|
||||
v3s16 doorplace;
|
||||
@ -675,20 +965,20 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random,
|
||||
bool r = walker.findPlaceForDoor(doorplace, doordir);
|
||||
if(r == false)
|
||||
return;
|
||||
|
||||
|
||||
if(random.range(0,1)==0)
|
||||
// Make the door
|
||||
make_door1(vmanip, doorplace, doordir, ndef);
|
||||
else
|
||||
// Don't actually make a door
|
||||
doorplace -= doordir;
|
||||
|
||||
|
||||
// Make a random corridor starting from the door
|
||||
v3s16 corridor_end;
|
||||
v3s16 corridor_end_dir;
|
||||
make_corridor(vmanip, doorplace, doordir, corridor_end,
|
||||
corridor_end_dir, random, ndef);
|
||||
|
||||
|
||||
// Find a place for a random sized room
|
||||
roomsize = v3s16(random.range(4,8),random.range(4,6),random.range(4,8));
|
||||
walker.setPos(corridor_end);
|
||||
@ -703,7 +993,7 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random,
|
||||
else
|
||||
// Don't actually make a door
|
||||
roomplace -= doordir;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -926,7 +1216,7 @@ s16 find_ground_level_from_noise(u64 seed, v2s16 p2d, s16 precision)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This is more like the actual ground level
|
||||
level += dec[i-1]/2;
|
||||
|
||||
@ -1024,7 +1314,7 @@ bool block_is_underground(u64 seed, v3s16 blockpos)
|
||||
seed, v2s16(blockpos.X, blockpos.Z));*/
|
||||
// Nah, this is just a heuristic, just return something
|
||||
s16 minimum_groundlevel = WATER_LEVEL;
|
||||
|
||||
|
||||
if(blockpos.Y*MAP_BLOCKSIZE + MAP_BLOCKSIZE <= minimum_groundlevel)
|
||||
return true;
|
||||
else
|
||||
@ -1132,9 +1422,9 @@ BiomeType get_biome(u64 seed, v2s16 p2d)
|
||||
double d = noise2d_perlin(
|
||||
0.6+(float)p2d.X/250, 0.2+(float)p2d.Y/250,
|
||||
seed+9130, 3, 0.50);
|
||||
if(d > 0.45)
|
||||
if(d > 0.45)
|
||||
return BT_DESERT;
|
||||
if(d > 0.35 && (noise2d( p2d.X, p2d.Y, int(seed) ) + 1.0) > ( 0.45 - d ) * 20.0 )
|
||||
if(d > 0.35 && (noise2d( p2d.X, p2d.Y, int(seed) ) + 1.0) > ( 0.45 - d ) * 20.0 )
|
||||
return BT_DESERT;
|
||||
return BT_NORMAL;
|
||||
};
|
||||
@ -1169,7 +1459,7 @@ void make_block(BlockMakeData *data)
|
||||
// Hack: use minimum block coordinates for old code that assumes
|
||||
// a single block
|
||||
v3s16 blockpos = data->blockpos_requested;
|
||||
|
||||
|
||||
/*dstream<<"makeBlock(): ("<<blockpos.X<<","<<blockpos.Y<<","
|
||||
<<blockpos.Z<<")"<<std::endl;*/
|
||||
|
||||
@ -1177,7 +1467,7 @@ void make_block(BlockMakeData *data)
|
||||
v3s16 blockpos_max = data->blockpos_max;
|
||||
v3s16 blockpos_full_min = blockpos_min - v3s16(1,1,1);
|
||||
v3s16 blockpos_full_max = blockpos_max + v3s16(1,1,1);
|
||||
|
||||
|
||||
ManualMapVoxelManipulator &vmanip = *(data->vmanip);
|
||||
// Area of central chunk
|
||||
v3s16 node_min = blockpos_min*MAP_BLOCKSIZE;
|
||||
@ -1193,10 +1483,10 @@ void make_block(BlockMakeData *data)
|
||||
int volume_blocks = (blockpos_max.X - blockpos_min.X + 1)
|
||||
* (blockpos_max.Y - blockpos_min.Y + 1)
|
||||
* (blockpos_max.Z - blockpos_max.Z + 1);
|
||||
|
||||
|
||||
int volume_nodes = volume_blocks *
|
||||
MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE;
|
||||
|
||||
|
||||
// Generated surface area
|
||||
//double gen_area_nodes = MAP_BLOCKSIZE*MAP_BLOCKSIZE * rel_volume;
|
||||
|
||||
@ -1207,7 +1497,7 @@ void make_block(BlockMakeData *data)
|
||||
Create a block-specific seed
|
||||
*/
|
||||
u32 blockseed = get_blockseed(data->seed, full_node_min);
|
||||
|
||||
|
||||
/*
|
||||
Cache some ground type values for speed
|
||||
*/
|
||||
@ -1253,13 +1543,13 @@ void make_block(BlockMakeData *data)
|
||||
{
|
||||
#if 1
|
||||
TimeTaker timer1("Generating ground level");
|
||||
|
||||
|
||||
for(s16 x=node_min.X; x<=node_max.X; x++)
|
||||
for(s16 z=node_min.Z; z<=node_max.Z; z++)
|
||||
{
|
||||
// Node position
|
||||
v2s16 p2d = v2s16(x,z);
|
||||
|
||||
|
||||
/*
|
||||
Skip of already generated
|
||||
*/
|
||||
@ -1274,7 +1564,7 @@ void make_block(BlockMakeData *data)
|
||||
|
||||
// Use perlin noise for ground height
|
||||
surface_y_f = base_rock_level_2d(data->seed, p2d);
|
||||
|
||||
|
||||
/*// Experimental stuff
|
||||
{
|
||||
float a = highlands_level_2d(data->seed, p2d);
|
||||
@ -1284,7 +1574,7 @@ void make_block(BlockMakeData *data)
|
||||
|
||||
// Convert to integer
|
||||
s16 surface_y = (s16)surface_y_f;
|
||||
|
||||
|
||||
// Log it
|
||||
if(surface_y > stone_surface_max_y)
|
||||
stone_surface_max_y = surface_y;
|
||||
@ -1316,9 +1606,9 @@ void make_block(BlockMakeData *data)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}//timer1
|
||||
|
||||
|
||||
// Limit dirt flow area by 1 because mud is flown into neighbors.
|
||||
assert(central_area_size.X == central_area_size.Z);
|
||||
s16 mudflow_minpos = 0-max_spread_amount+1;
|
||||
@ -1375,7 +1665,7 @@ void make_block(BlockMakeData *data)
|
||||
tunnel_routepoints = ps.range(10, ps.range(15,30));
|
||||
}
|
||||
bool large_cave_is_flat = (ps.range(0,1) == 0);
|
||||
|
||||
|
||||
v3f main_direction(0,0,0);
|
||||
|
||||
// Allowed route area size in nodes
|
||||
@ -1391,7 +1681,7 @@ void make_block(BlockMakeData *data)
|
||||
s16 more = max_spread_amount - max_tunnel_diameter/2 - insure;
|
||||
ar += v3s16(1,0,1) * more * 2;
|
||||
of -= v3s16(1,0,1) * more;
|
||||
|
||||
|
||||
s16 route_y_min = 0;
|
||||
// Allow half a diameter + 7 over stone surface
|
||||
s16 route_y_max = -of.Y + stone_surface_max_y + max_tunnel_diameter/2 + 7;
|
||||
@ -1434,7 +1724,7 @@ void make_block(BlockMakeData *data)
|
||||
if(coming_from_surface)
|
||||
route_start_y_min = -of.Y + stone_surface_max_y + 10;
|
||||
}*/
|
||||
|
||||
|
||||
route_start_y_min = rangelim(route_start_y_min, 0, ar.Y-1);
|
||||
route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y-1);
|
||||
|
||||
@ -1451,11 +1741,11 @@ void make_block(BlockMakeData *data)
|
||||
MapNode airnode(CONTENT_AIR);
|
||||
MapNode waternode(c_water_source);
|
||||
MapNode lavanode(c_lava_source);
|
||||
|
||||
|
||||
/*
|
||||
Generate some tunnel starting from orp
|
||||
*/
|
||||
|
||||
|
||||
for(u16 j=0; j<tunnel_routepoints; j++)
|
||||
{
|
||||
if(j%dswitchint==0 && large_cave == false)
|
||||
@ -1467,12 +1757,12 @@ void make_block(BlockMakeData *data)
|
||||
);
|
||||
main_direction *= (float)ps.range(0, 10)/10;
|
||||
}
|
||||
|
||||
|
||||
// Randomize size
|
||||
s16 min_d = min_tunnel_diameter;
|
||||
s16 max_d = max_tunnel_diameter;
|
||||
s16 rs = ps.range(min_d, max_d);
|
||||
|
||||
|
||||
// Every second section is rough
|
||||
bool randomize_xz = (ps2.range(1,2) == 1);
|
||||
|
||||
@ -1495,13 +1785,13 @@ void make_block(BlockMakeData *data)
|
||||
}
|
||||
|
||||
v3f vec;
|
||||
|
||||
|
||||
vec = v3f(
|
||||
(float)(ps.next()%(maxlen.X*1))-(float)maxlen.X/2,
|
||||
(float)(ps.next()%(maxlen.Y*1))-(float)maxlen.Y/2,
|
||||
(float)(ps.next()%(maxlen.Z*1))-(float)maxlen.Z/2
|
||||
);
|
||||
|
||||
|
||||
// Jump downward sometimes
|
||||
if(!large_cave && ps.range(0,12) == 0)
|
||||
{
|
||||
@ -1511,7 +1801,7 @@ void make_block(BlockMakeData *data)
|
||||
(float)(ps.next()%(maxlen.Z*1))-(float)maxlen.Z/2
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*if(large_cave){
|
||||
v3f p = orp + vec;
|
||||
s16 h = find_ground_level_clever(vmanip,
|
||||
@ -1573,12 +1863,12 @@ void make_block(BlockMakeData *data)
|
||||
s16 x = cp.X + x0;
|
||||
v3s16 p(x,y,z);
|
||||
p += of;
|
||||
|
||||
|
||||
if(vmanip.m_area.contains(p) == false)
|
||||
continue;
|
||||
|
||||
|
||||
u32 i = vmanip.m_area.index(p);
|
||||
|
||||
|
||||
if(large_cave)
|
||||
{
|
||||
if(full_node_min.Y < WATER_LEVEL &&
|
||||
@ -1602,7 +1892,7 @@ void make_block(BlockMakeData *data)
|
||||
vmanip.m_data[i].getContent() == c_water_source ||
|
||||
vmanip.m_data[i].getContent() == c_lava_source)
|
||||
continue;
|
||||
|
||||
|
||||
vmanip.m_data[i] = airnode;
|
||||
|
||||
// Set tunnel flag
|
||||
@ -1615,12 +1905,12 @@ void make_block(BlockMakeData *data)
|
||||
|
||||
orp = rp;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}//timer1
|
||||
#endif
|
||||
|
||||
|
||||
#if 1
|
||||
{
|
||||
// 15ms @cs=8
|
||||
@ -1629,13 +1919,13 @@ void make_block(BlockMakeData *data)
|
||||
/*
|
||||
Add mud to the central chunk
|
||||
*/
|
||||
|
||||
|
||||
for(s16 x=node_min.X; x<=node_max.X; x++)
|
||||
for(s16 z=node_min.Z; z<=node_max.Z; z++)
|
||||
{
|
||||
// Node position in 2d
|
||||
v2s16 p2d = v2s16(x,z);
|
||||
|
||||
|
||||
// Randomize mud amount
|
||||
s16 mud_add_amount = get_mud_add_amount(data->seed, p2d) / 2.0 + 0.5;
|
||||
|
||||
@ -1660,7 +1950,7 @@ void make_block(BlockMakeData *data)
|
||||
surface_y + mud_add_amount <= WATER_LEVEL+2){
|
||||
addnode = MapNode(c_sand);
|
||||
}
|
||||
|
||||
|
||||
if(bt == BT_DESERT){
|
||||
if(surface_y > 20){
|
||||
mud_add_amount = MYMAX(0, mud_add_amount - (surface_y - 20)/5);
|
||||
@ -1691,7 +1981,7 @@ void make_block(BlockMakeData *data)
|
||||
{
|
||||
if(mudcount >= mud_add_amount)
|
||||
break;
|
||||
|
||||
|
||||
MapNode &n = vmanip.m_data[i];
|
||||
n = addnode;
|
||||
mudcount++;
|
||||
@ -1756,7 +2046,7 @@ void make_block(BlockMakeData *data)
|
||||
/*
|
||||
Flow mud away from steep edges
|
||||
*/
|
||||
|
||||
|
||||
// Iterate a few times
|
||||
for(s16 k=0; k<3; k++)
|
||||
{
|
||||
@ -1773,7 +2063,7 @@ void make_block(BlockMakeData *data)
|
||||
|
||||
// Node position in 2d
|
||||
v2s16 p2d = v2s16(node_min.X, node_min.Z) + v2s16(x,z);
|
||||
|
||||
|
||||
v3s16 em = vmanip.m_area.getExtent();
|
||||
u32 i = vmanip.m_area.index(v3s16(p2d.X, node_max.Y, p2d.Y));
|
||||
s16 y=node_max.Y;
|
||||
@ -1794,7 +2084,7 @@ void make_block(BlockMakeData *data)
|
||||
n->getContent() == c_dirt_with_grass ||
|
||||
n->getContent() == c_gravel)
|
||||
break;
|
||||
|
||||
|
||||
vmanip.m_area.add_y(em, i, -1);
|
||||
}
|
||||
|
||||
@ -1813,7 +2103,7 @@ void make_block(BlockMakeData *data)
|
||||
{
|
||||
// Make it exactly mud
|
||||
n->setContent(c_dirt);
|
||||
|
||||
|
||||
/*
|
||||
Don't flow it if the stuff under it is not mud
|
||||
*/
|
||||
@ -1851,7 +2141,7 @@ void make_block(BlockMakeData *data)
|
||||
}
|
||||
|
||||
// Drop mud on side
|
||||
|
||||
|
||||
for(u32 di=0; di<4; di++)
|
||||
{
|
||||
v3s16 dirp = dirs4[di];
|
||||
@ -1894,7 +2184,7 @@ void make_block(BlockMakeData *data)
|
||||
// Loop one up so that we're in air
|
||||
vmanip.m_area.add_y(em, i2, 1);
|
||||
n2 = &vmanip.m_data[i2];
|
||||
|
||||
|
||||
bool old_is_water = (n->getContent() == c_water_source);
|
||||
// Move mud to new place
|
||||
if(!dropped_to_unknown) {
|
||||
@ -1912,7 +2202,7 @@ void make_block(BlockMakeData *data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}//timer1
|
||||
@ -1940,7 +2230,7 @@ void make_block(BlockMakeData *data)
|
||||
for(s16 y=full_node_max.Y; y>=full_node_min.Y; y--)
|
||||
{
|
||||
if(y == full_node_max.Y){
|
||||
water_found =
|
||||
water_found =
|
||||
(vmanip.m_data[i].getContent() == c_water_source ||
|
||||
vmanip.m_data[i].getContent() == c_lava_source);
|
||||
}
|
||||
@ -1982,7 +2272,7 @@ void make_block(BlockMakeData *data)
|
||||
{
|
||||
// Node position in 2d
|
||||
v2s16 p2d = v2s16(x,z);
|
||||
|
||||
|
||||
/*
|
||||
Find the lowest surface to which enough light ends up
|
||||
to make grass grow.
|
||||
@ -2008,7 +2298,7 @@ void make_block(BlockMakeData *data)
|
||||
else
|
||||
surface_y = full_node_min.Y;
|
||||
}
|
||||
|
||||
|
||||
u32 i = vmanip.m_area.index(p2d.X, surface_y, p2d.Y);
|
||||
MapNode *n = &vmanip.m_data[i];
|
||||
if(n->getContent() == c_dirt){
|
||||
@ -2113,7 +2403,7 @@ void make_block(BlockMakeData *data)
|
||||
else
|
||||
vmanip.m_data[i] = n_stone;
|
||||
}
|
||||
|
||||
|
||||
vmanip->m_area.add_y(em, i, 1);
|
||||
}
|
||||
}
|
||||
@ -2168,7 +2458,7 @@ void make_block(BlockMakeData *data)
|
||||
/*
|
||||
Add dungeons
|
||||
*/
|
||||
|
||||
|
||||
//if(node_min.Y < approx_groundlevel)
|
||||
//if(myrand() % 3 == 0)
|
||||
//if(myrand() % 3 == 0 && node_min.Y < approx_groundlevel)
|
||||
@ -2182,7 +2472,7 @@ void make_block(BlockMakeData *data)
|
||||
// Dungeon generator doesn't modify places which have this set
|
||||
vmanip->clearFlag(VMANIP_FLAG_DUNGEON_INSIDE
|
||||
| VMANIP_FLAG_DUNGEON_PRESERVE);
|
||||
|
||||
|
||||
// Set all air and water to be untouchable to make dungeons open
|
||||
// to caves and open air
|
||||
for(s16 x=full_node_min.X; x<=full_node_max.X; x++)
|
||||
@ -2204,12 +2494,12 @@ void make_block(BlockMakeData *data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PseudoRandom random(blockseed+2);
|
||||
|
||||
// Add it
|
||||
make_dungeon1(vmanip, random, ndef);
|
||||
|
||||
|
||||
// Convert some cobble to mossy cobble
|
||||
for(s16 x=full_node_min.X; x<=full_node_max.X; x++)
|
||||
for(s16 z=full_node_min.Z; z<=full_node_max.Z; z++)
|
||||
@ -2257,7 +2547,7 @@ void make_block(BlockMakeData *data)
|
||||
make_nc(vmanip, ncrandom, ndef);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Add top and bottom side of water to transforming_liquid queue
|
||||
*/
|
||||
@ -2346,7 +2636,7 @@ void make_block(BlockMakeData *data)
|
||||
if(current_depth == 0 && y <= WATER_LEVEL+2
|
||||
&& possibly_have_sand)
|
||||
have_sand = true;
|
||||
|
||||
|
||||
if(current_depth < 4)
|
||||
{
|
||||
if(have_sand)
|
||||
@ -2384,7 +2674,7 @@ void make_block(BlockMakeData *data)
|
||||
/*
|
||||
Calculate some stuff
|
||||
*/
|
||||
|
||||
|
||||
float surface_humidity = surface_humidity_2d(data->seed, p2d_center);
|
||||
bool is_jungle = surface_humidity > 0.75;
|
||||
// Amount of trees
|
||||
@ -2521,7 +2811,7 @@ void make_block(BlockMakeData *data)
|
||||
/*
|
||||
Add some kind of random stones
|
||||
*/
|
||||
|
||||
|
||||
u32 random_stone_count = gen_area_nodes *
|
||||
randomstone_amount_2d(data->seed, p2d_center);
|
||||
// Put in random places on part of division
|
||||
@ -2555,7 +2845,7 @@ void make_block(BlockMakeData *data)
|
||||
/*
|
||||
Add larger stones
|
||||
*/
|
||||
|
||||
|
||||
u32 large_stone_count = gen_area_nodes *
|
||||
largestone_amount_2d(data->seed, p2d_center);
|
||||
//u32 large_stone_count = 1;
|
||||
@ -2612,7 +2902,7 @@ void make_block(BlockMakeData *data)
|
||||
if(mineralrandom.next()%8 == 0)
|
||||
vmanip.m_data[vi] = MapNode(c_mese);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
@ -2742,7 +3032,7 @@ void make_block(BlockMakeData *data)
|
||||
|
||||
voxalgo::clearLightAndCollectSources(vmanip, a, bank, ndef,
|
||||
light_sources, unlight_from);
|
||||
|
||||
|
||||
bool inexistent_top_provides_sunlight = !block_is_underground;
|
||||
voxalgo::SunlightPropagateResult res = voxalgo::propagateSunlight(
|
||||
vmanip, a, inexistent_top_provides_sunlight,
|
||||
@ -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
|
||||
|
||||
|
||||
|
120
src/mapgen.h
120
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
|
||||
@ -41,10 +150,9 @@ 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
|
||||
|
||||
|
@ -106,7 +106,7 @@ void NodeBox::deSerialize(std::istream &is)
|
||||
/*
|
||||
TileDef
|
||||
*/
|
||||
|
||||
|
||||
void TileDef::serialize(std::ostream &os) const
|
||||
{
|
||||
writeU8(os, 0); // version
|
||||
@ -173,7 +173,7 @@ void ContentFeatures::reset()
|
||||
has_after_destruct = false;
|
||||
/*
|
||||
Actual data
|
||||
|
||||
|
||||
NOTE: Most of this is always overridden by the default values given
|
||||
in builtin.lua
|
||||
*/
|
||||
@ -354,7 +354,7 @@ public:
|
||||
ContentFeatures &f = m_content_features[i];
|
||||
f.reset(); // Reset to defaults
|
||||
}
|
||||
|
||||
|
||||
// Set CONTENT_AIR
|
||||
{
|
||||
ContentFeatures f;
|
||||
@ -541,11 +541,11 @@ public:
|
||||
bool new_style_water = g_settings->getBool("new_style_water");
|
||||
bool new_style_leaves = g_settings->getBool("new_style_leaves");
|
||||
bool opaque_water = g_settings->getBool("opaque_water");
|
||||
|
||||
|
||||
for(u16 i=0; i<=MAX_CONTENT; i++)
|
||||
{
|
||||
ContentFeatures *f = &m_content_features[i];
|
||||
|
||||
|
||||
// Figure out the actual tiles to use
|
||||
TileDef tiledef[6];
|
||||
for(u32 j=0; j<6; j++)
|
||||
|
703
src/noise.cpp
703
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();
|
||||
|
||||
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;
|
||||
//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_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;
|
||||
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_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();
|
||||
|
||||
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);
|
||||
NoiseParams *np;
|
||||
int seed;
|
||||
int sx;
|
||||
int sy;
|
||||
int sz;
|
||||
float *noisebuf;
|
||||
float *buf;
|
||||
float *result;
|
||||
|
||||
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);
|
||||
Noise(NoiseParams *np, int seed, int sx, int sy);
|
||||
Noise(NoiseParams *np, int seed, int sx, int sy, int sz);
|
||||
~Noise();
|
||||
|
||||
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;
|
||||
|
419
src/server.cpp
419
src/server.cpp
File diff suppressed because it is too large
Load Diff
@ -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)
|
||||
{
|
||||
|
34
src/voxel.h
34
src/voxel.h
@ -72,7 +72,7 @@ public:
|
||||
MaxEdge(p)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Modifying methods
|
||||
*/
|
||||
@ -106,14 +106,14 @@ public:
|
||||
if(p.Y > MaxEdge.Y) MaxEdge.Y = p.Y;
|
||||
if(p.Z > MaxEdge.Z) MaxEdge.Z = p.Z;
|
||||
}
|
||||
|
||||
|
||||
// Pad with d nodes
|
||||
void pad(v3s16 d)
|
||||
{
|
||||
MinEdge -= d;
|
||||
MaxEdge += d;
|
||||
}
|
||||
|
||||
|
||||
/*void operator+=(v3s16 off)
|
||||
{
|
||||
MinEdge += off;
|
||||
@ -202,7 +202,7 @@ public:
|
||||
}
|
||||
|
||||
assert(contains(a));
|
||||
|
||||
|
||||
// Take back area, XY inclusive
|
||||
{
|
||||
v3s16 min(MinEdge.X, MinEdge.Y, a.MaxEdge.Z+1);
|
||||
@ -258,7 +258,7 @@ public:
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Translates position from virtual coordinates to array index
|
||||
*/
|
||||
@ -274,7 +274,7 @@ public:
|
||||
{
|
||||
return index(p.X, p.Y, p.Z);
|
||||
}
|
||||
|
||||
|
||||
// Translate index in the X coordinate
|
||||
void add_x(const v3s16 &extent, u32 &i, s16 a)
|
||||
{
|
||||
@ -343,7 +343,7 @@ class VoxelManipulator /*: public NodeContainer*/
|
||||
public:
|
||||
VoxelManipulator();
|
||||
virtual ~VoxelManipulator();
|
||||
|
||||
|
||||
/*
|
||||
Virtuals from NodeContainer
|
||||
*/
|
||||
@ -430,7 +430,7 @@ public:
|
||||
void setNode(v3s16 p, const MapNode &n)
|
||||
{
|
||||
emerge(p);
|
||||
|
||||
|
||||
m_data[m_area.index(p)] = n;
|
||||
m_flags[m_area.index(p)] &= ~VOXELFLAG_INEXISTENT;
|
||||
m_flags[m_area.index(p)] &= ~VOXELFLAG_NOT_LOADED;
|
||||
@ -457,10 +457,10 @@ public:
|
||||
//dstream<<"operator[] p=("<<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;
|
||||
if(isValidPosition(p) == false)
|
||||
emerge(VoxelArea(p));
|
||||
|
||||
|
||||
return m_data[m_area.index(p)];
|
||||
}*/
|
||||
|
||||
|
||||
/*
|
||||
Set stuff if available without an emerge.
|
||||
Return false if failed.
|
||||
@ -496,7 +496,7 @@ public:
|
||||
|
||||
void print(std::ostream &o, INodeDefManager *nodemgr,
|
||||
VoxelPrintMode mode=VOXELPRINT_MATERIAL);
|
||||
|
||||
|
||||
void addArea(VoxelArea area);
|
||||
|
||||
/*
|
||||
@ -505,7 +505,7 @@ public:
|
||||
*/
|
||||
void copyFrom(MapNode *src, VoxelArea src_area,
|
||||
v3s16 from_pos, v3s16 to_pos, v3s16 size);
|
||||
|
||||
|
||||
// Copy data
|
||||
void copyTo(MapNode *dst, VoxelArea dst_area,
|
||||
v3s16 dst_pos, v3s16 from_pos, v3s16 size);
|
||||
@ -523,15 +523,15 @@ public:
|
||||
void unspreadLight(enum LightBank bank,
|
||||
core::map<v3s16, u8> & from_nodes,
|
||||
core::map<v3s16, bool> & light_sources, INodeDefManager *nodemgr);
|
||||
|
||||
|
||||
void spreadLight(enum LightBank bank, v3s16 p, INodeDefManager *nodemgr);
|
||||
void spreadLight(enum LightBank bank,
|
||||
core::map<v3s16, bool> & from_nodes, INodeDefManager *nodemgr);
|
||||
|
||||
|
||||
/*
|
||||
Virtual functions
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
Get the contents of the requested area from somewhere.
|
||||
Shall touch only nodes that have VOXELFLAG_NOT_LOADED
|
||||
@ -565,7 +565,7 @@ public:
|
||||
MaxEdge is 1 higher than maximum allowed position
|
||||
*/
|
||||
VoxelArea m_area;
|
||||
|
||||
|
||||
/*
|
||||
NULL if data size is 0 (extent (0,0,0))
|
||||
Data is stored as [z*h*w + y*h + x]
|
||||
@ -576,7 +576,7 @@ public:
|
||||
Flags of all nodes
|
||||
*/
|
||||
u8 *m_flags;
|
||||
|
||||
|
||||
//TODO: Use these or remove them
|
||||
//TODO: Would these make any speed improvement?
|
||||
//bool m_pressure_route_valid;
|
||||
|
@ -86,10 +86,10 @@ SunlightPropagateResult propagateSunlight(VoxelManipulator &v, VoxelArea a,
|
||||
required_a.pad(v3s16(0,1,0));
|
||||
// Make sure we have access to it
|
||||
v.emerge(a);
|
||||
|
||||
|
||||
s16 max_y = a.MaxEdge.Y;
|
||||
s16 min_y = a.MinEdge.Y;
|
||||
|
||||
|
||||
for(s32 x=a.MinEdge.X; x<=a.MaxEdge.X; x++)
|
||||
for(s32 z=a.MinEdge.Z; z<=a.MaxEdge.Z; z++)
|
||||
{
|
||||
@ -125,11 +125,11 @@ SunlightPropagateResult propagateSunlight(VoxelManipulator &v, VoxelArea a,
|
||||
|
||||
if(incoming_light > old_light)
|
||||
n.setLight(LIGHTBANK_DAY, incoming_light, ndef);
|
||||
|
||||
|
||||
if(diminish_light(incoming_light) != 0)
|
||||
light_sources.insert(p, true);
|
||||
}
|
||||
|
||||
|
||||
// Check validity of sunlight at top of block below if it
|
||||
// hasn't already been proven invalid
|
||||
if(bottom_sunlight_valid)
|
||||
|
Loading…
Reference in New Issue
Block a user