mirror of
https://github.com/luanti-org/luanti.git
synced 2025-10-23 20:55:43 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -311,7 +311,7 @@ $(OPENSSL_LIB): $(OPENSSL_TIMESTAMP)
|
|||||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-openssl; \
|
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-openssl; \
|
||||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||||
--install-dir=$${TOOLCHAIN} --system=linux-x86_64; \
|
--install-dir=$${TOOLCHAIN}; \
|
||||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||||
CC=${CROSS_PREFIX}gcc ./Configure android-${TARGET_ARCH} no-idea no-seed -no-sha0 -DL_ENDIAN;\
|
CC=${CROSS_PREFIX}gcc ./Configure android-${TARGET_ARCH} no-idea no-seed -no-sha0 -DL_ENDIAN;\
|
||||||
CC=${CROSS_PREFIX}gcc ANDROID_DEV=/tmp/ndk-${TARGET_HOST} make build_libs; \
|
CC=${CROSS_PREFIX}gcc ANDROID_DEV=/tmp/ndk-${TARGET_HOST} make build_libs; \
|
||||||
@@ -359,7 +359,7 @@ $(LEVELDB_LIB): $(LEVELDB_TIMESTAMP)
|
|||||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-leveldb; \
|
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-leveldb; \
|
||||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||||
--install-dir=$${TOOLCHAIN} --system=linux-x86_64; \
|
--install-dir=$${TOOLCHAIN}; \
|
||||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||||
export CC=${CROSS_PREFIX}gcc; \
|
export CC=${CROSS_PREFIX}gcc; \
|
||||||
export CXX=${CROSS_PREFIX}g++; \
|
export CXX=${CROSS_PREFIX}g++; \
|
||||||
@@ -518,7 +518,7 @@ $(CURL_LIB): $(CURL_TIMESTAMP) $(OPENSSL_LIB)
|
|||||||
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-curl; \
|
export TOOLCHAIN=/tmp/ndk-${TARGET_HOST}-curl; \
|
||||||
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
${ANDROID_NDK}/build/tools/make-standalone-toolchain.sh \
|
||||||
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
--toolchain=${TARGET_TOOLCHAIN}${COMPILER_VERSION} \
|
||||||
--install-dir=$${TOOLCHAIN} --system=linux-x86_64; \
|
--install-dir=$${TOOLCHAIN}; \
|
||||||
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
export PATH="$${TOOLCHAIN}/bin:$${PATH}"; \
|
||||||
export CC=${CROSS_PREFIX}gcc; \
|
export CC=${CROSS_PREFIX}gcc; \
|
||||||
export CXX=${CROSS_PREFIX}g++; \
|
export CXX=${CROSS_PREFIX}g++; \
|
||||||
|
@@ -74,6 +74,7 @@ IF(GETTEXT_FOUND)
|
|||||||
SET(GETTEXT_MO_DEST_PATH ${LOCALEDIR}/<locale>/LC_MESSAGES)
|
SET(GETTEXT_MO_DEST_PATH ${LOCALEDIR}/<locale>/LC_MESSAGES)
|
||||||
FILE(GLOB GETTEXT_AVAILABLE_LOCALES RELATIVE ${GETTEXT_PO_PATH} "${GETTEXT_PO_PATH}/*")
|
FILE(GLOB GETTEXT_AVAILABLE_LOCALES RELATIVE ${GETTEXT_PO_PATH} "${GETTEXT_PO_PATH}/*")
|
||||||
LIST(REMOVE_ITEM GETTEXT_AVAILABLE_LOCALES minetest.pot)
|
LIST(REMOVE_ITEM GETTEXT_AVAILABLE_LOCALES minetest.pot)
|
||||||
|
LIST(REMOVE_ITEM GETTEXT_AVAILABLE_LOCALES timestamp)
|
||||||
MACRO(SET_MO_PATHS _buildvar _destvar _locale)
|
MACRO(SET_MO_PATHS _buildvar _destvar _locale)
|
||||||
STRING(REPLACE "<locale>" ${_locale} ${_buildvar} ${GETTEXT_MO_BUILD_PATH})
|
STRING(REPLACE "<locale>" ${_locale} ${_buildvar} ${GETTEXT_MO_BUILD_PATH})
|
||||||
STRING(REPLACE "<locale>" ${_locale} ${_destvar} ${GETTEXT_MO_DEST_PATH})
|
STRING(REPLACE "<locale>" ${_locale} ${_destvar} ${GETTEXT_MO_DEST_PATH})
|
||||||
|
@@ -2336,7 +2336,6 @@ This is basically a reference to a C++ `ServerActiveObject`
|
|||||||
* `right_click(clicker)`; `clicker` is another `ObjectRef`
|
* `right_click(clicker)`; `clicker` is another `ObjectRef`
|
||||||
* `get_hp()`: returns number of hitpoints (2 * number of hearts)
|
* `get_hp()`: returns number of hitpoints (2 * number of hearts)
|
||||||
* `set_hp(hp)`: set number of hitpoints (2 * number of hearts)
|
* `set_hp(hp)`: set number of hitpoints (2 * number of hearts)
|
||||||
* `apply_damage(damage)`: set amount of damage to object. If damage < 0, heal the target
|
|
||||||
* `get_inventory()`: returns an `InvRef`
|
* `get_inventory()`: returns an `InvRef`
|
||||||
* `get_wield_list()`: returns the name of the inventory list the wielded item is in
|
* `get_wield_list()`: returns the name of the inventory list the wielded item is in
|
||||||
* `get_wield_index()`: returns the index of the wielded item
|
* `get_wield_index()`: returns the index of the wielded item
|
||||||
@@ -2515,7 +2514,8 @@ an itemstring, a table or `nil`.
|
|||||||
Returns taken `ItemStack`.
|
Returns taken `ItemStack`.
|
||||||
|
|
||||||
### `PseudoRandom`
|
### `PseudoRandom`
|
||||||
A pseudorandom number generator.
|
A 16-bit pseudorandom number generator.
|
||||||
|
Uses a well-known LCG algorithm introduced by K&R.
|
||||||
|
|
||||||
It can be created via `PseudoRandom(seed)`.
|
It can be created via `PseudoRandom(seed)`.
|
||||||
|
|
||||||
@@ -2525,6 +2525,19 @@ It can be created via `PseudoRandom(seed)`.
|
|||||||
* `((max - min) == 32767) or ((max-min) <= 6553))` must be true
|
* `((max - min) == 32767) or ((max-min) <= 6553))` must be true
|
||||||
due to the simple implementation making bad distribution otherwise.
|
due to the simple implementation making bad distribution otherwise.
|
||||||
|
|
||||||
|
### `PcgRandom`
|
||||||
|
A 32-bit pseudorandom number generator.
|
||||||
|
Uses PCG32, an algorithm of the permuted congruential generator family, offering very strong randomness.
|
||||||
|
|
||||||
|
It can be created via `PcgRandom(seed)` or `PcgRandom(seed, sequence)`.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
* `next()`: return next integer random number [`-2147483648`...`2147483647`]
|
||||||
|
* `next(min, max)`: return next integer random number [`min`...`max`]
|
||||||
|
* `rand_normal_dist(min, max, num_trials=6)`: return normally distributed random number [`min`...`max`]
|
||||||
|
* This is only a rough approximation of a normal distribution with mean=(max-min)/2 and variance=1
|
||||||
|
* Increasing num_trials improves accuracy of the approximation
|
||||||
|
|
||||||
### `PerlinNoise`
|
### `PerlinNoise`
|
||||||
A perlin noise generator.
|
A perlin noise generator.
|
||||||
It can be created via `PerlinNoise(seed, octaves, persistence, scale)`
|
It can be created via `PerlinNoise(seed, octaves, persistence, scale)`
|
||||||
|
@@ -197,7 +197,7 @@
|
|||||||
# which PNG optimizers usually discard, sometimes resulting in a dark or
|
# which PNG optimizers usually discard, sometimes resulting in a dark or
|
||||||
# light edge to transparent textures. Apply this filter to clean that up
|
# light edge to transparent textures. Apply this filter to clean that up
|
||||||
# at texture load time.
|
# at texture load time.
|
||||||
#texture_clean_transparent = true
|
#texture_clean_transparent = false
|
||||||
# When using bilinear/trilinear/anisotropic filters, low-resolution textures
|
# When using bilinear/trilinear/anisotropic filters, low-resolution textures
|
||||||
# can be blurred, so automatically upscale them with nearest-neighbor
|
# can be blurred, so automatically upscale them with nearest-neighbor
|
||||||
# interpolation to preserve crisp pixels. This sets the minimum texture size
|
# interpolation to preserve crisp pixels. This sets the minimum texture size
|
||||||
@@ -205,7 +205,7 @@
|
|||||||
# memory. Powers of 2 are recommended. Setting this higher than 1 may not
|
# memory. Powers of 2 are recommended. Setting this higher than 1 may not
|
||||||
# have a visible effect unless bilinear/trilinear/anisotropic filtering is
|
# have a visible effect unless bilinear/trilinear/anisotropic filtering is
|
||||||
# enabled.
|
# enabled.
|
||||||
#texture_min_size = 16
|
#texture_min_size = 64
|
||||||
# Set to true to pre-generate all item visuals
|
# Set to true to pre-generate all item visuals
|
||||||
#preload_item_visuals = false
|
#preload_item_visuals = false
|
||||||
# Set to true to enable shaders. Disable them if video_driver = direct3d9/8.
|
# Set to true to enable shaders. Disable them if video_driver = direct3d9/8.
|
||||||
|
@@ -192,13 +192,18 @@ video::IImage *textureMinSizeUpscale(video::IVideoDriver *driver, video::IImage
|
|||||||
if(orig == NULL)
|
if(orig == NULL)
|
||||||
return orig;
|
return orig;
|
||||||
s32 scaleto = g_settings->getS32("texture_min_size");
|
s32 scaleto = g_settings->getS32("texture_min_size");
|
||||||
if (scaleto > 0) {
|
if (scaleto > 1) {
|
||||||
|
const core::dimension2d<u32> dim = orig->getDimension();
|
||||||
|
|
||||||
|
// Don't upscale 1px images. They don't benefit from it anyway
|
||||||
|
// (wouldn't have been blurred) and MIGHT be sun/moon tonemaps.
|
||||||
|
if ((dim.Width <= 1) || (dim.Height <= 1))
|
||||||
|
return orig;
|
||||||
|
|
||||||
/* Calculate scaling needed to make the shortest texture dimension
|
/* Calculate scaling needed to make the shortest texture dimension
|
||||||
* equal to the target minimum. If e.g. this is a vertical frames
|
* equal to the target minimum. If e.g. this is a vertical frames
|
||||||
* animation, the short dimension will be the real size.
|
* animation, the short dimension will be the real size.
|
||||||
*/
|
*/
|
||||||
const core::dimension2d<u32> dim = orig->getDimension();
|
|
||||||
u32 xscale = scaleto / dim.Width;
|
u32 xscale = scaleto / dim.Width;
|
||||||
u32 yscale = scaleto / dim.Height;
|
u32 yscale = scaleto / dim.Height;
|
||||||
u32 scale = (xscale > yscale) ? xscale : yscale;
|
u32 scale = (xscale > yscale) ? xscale : yscale;
|
||||||
|
@@ -149,8 +149,8 @@ void set_default_settings(Settings *settings)
|
|||||||
settings->setDefault("anisotropic_filter", "false");
|
settings->setDefault("anisotropic_filter", "false");
|
||||||
settings->setDefault("bilinear_filter", "false");
|
settings->setDefault("bilinear_filter", "false");
|
||||||
settings->setDefault("trilinear_filter", "false");
|
settings->setDefault("trilinear_filter", "false");
|
||||||
settings->setDefault("texture_clean_transparent", "true");
|
settings->setDefault("texture_clean_transparent", "false");
|
||||||
settings->setDefault("texture_min_size", "16");
|
settings->setDefault("texture_min_size", "64");
|
||||||
settings->setDefault("preload_item_visuals", "false");
|
settings->setDefault("preload_item_visuals", "false");
|
||||||
settings->setDefault("enable_bumpmapping", "false");
|
settings->setDefault("enable_bumpmapping", "false");
|
||||||
settings->setDefault("enable_parallax_occlusion", "false");
|
settings->setDefault("enable_parallax_occlusion", "false");
|
||||||
|
@@ -515,14 +515,10 @@ void MapgenParams::load(const Settings &settings)
|
|||||||
std::string seed_str;
|
std::string seed_str;
|
||||||
const char *seed_name = (&settings == g_settings) ? "fixed_map_seed" : "seed";
|
const char *seed_name = (&settings == g_settings) ? "fixed_map_seed" : "seed";
|
||||||
|
|
||||||
if (settings.getNoEx(seed_name, seed_str) && !seed_str.empty()) {
|
if (settings.getNoEx(seed_name, seed_str) && !seed_str.empty())
|
||||||
seed = read_seed(seed_str.c_str());
|
seed = read_seed(seed_str.c_str());
|
||||||
} else {
|
else
|
||||||
seed = ((u64)(myrand() & 0xFFFF) << 0) |
|
myrand_bytes(&seed, sizeof(seed));
|
||||||
((u64)(myrand() & 0xFFFF) << 16) |
|
|
||||||
((u64)(myrand() & 0xFFFF) << 32) |
|
|
||||||
((u64)(myrand() & 0xFFFF) << 48);
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.getNoEx("mg_name", mg_name);
|
settings.getNoEx("mg_name", mg_name);
|
||||||
settings.getS16NoEx("water_level", water_level);
|
settings.getS16NoEx("water_level", water_level);
|
||||||
|
@@ -204,6 +204,8 @@ public:
|
|||||||
|
|
||||||
virtual GenElement *getByName(const std::string &name);
|
virtual GenElement *getByName(const std::string &name);
|
||||||
|
|
||||||
|
INodeDefManager *getNodeDef() { return m_ndef; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
INodeDefManager *m_ndef;
|
INodeDefManager *m_ndef;
|
||||||
std::vector<GenElement *> m_elements;
|
std::vector<GenElement *> m_elements;
|
||||||
|
@@ -377,9 +377,9 @@ int MapgenV5::generateBaseTerrain()
|
|||||||
stone_surface_max_y = y;
|
stone_surface_max_y = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
index2d = index2d - ystride;
|
index2d -= ystride;
|
||||||
}
|
}
|
||||||
index2d = index2d + ystride;
|
index2d += ystride;
|
||||||
}
|
}
|
||||||
|
|
||||||
return stone_surface_max_y;
|
return stone_surface_max_y;
|
||||||
@@ -391,10 +391,6 @@ bool MapgenV5::generateBiomes(float *heat_map, float *humidity_map)
|
|||||||
if (node_max.Y < water_level)
|
if (node_max.Y < water_level)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MapNode n_air(CONTENT_AIR);
|
|
||||||
MapNode n_stone(c_stone);
|
|
||||||
MapNode n_water(c_water_source);
|
|
||||||
|
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
bool desert_stone = false;
|
bool desert_stone = false;
|
||||||
@@ -496,9 +492,9 @@ void MapgenV5::generateCaves(int max_stone_y)
|
|||||||
if (d1*d2 > 0.125)
|
if (d1*d2 > 0.125)
|
||||||
vm->m_data[i] = MapNode(CONTENT_AIR);
|
vm->m_data[i] = MapNode(CONTENT_AIR);
|
||||||
}
|
}
|
||||||
index2d = index2d - ystride;
|
index2d -= ystride;
|
||||||
}
|
}
|
||||||
index2d = index2d + ystride;
|
index2d += ystride;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node_max.Y > LARGE_CAVE_DEPTH)
|
if (node_max.Y > LARGE_CAVE_DEPTH)
|
||||||
@@ -528,27 +524,25 @@ void MapgenV5::dustTopNodes()
|
|||||||
if (biome->c_dust == CONTENT_IGNORE)
|
if (biome->c_dust == CONTENT_IGNORE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
s16 y_full_max = full_node_max.Y;
|
u32 vi = vm->m_area.index(x, full_node_max.Y, z);
|
||||||
u32 vi_full_max = vm->m_area.index(x, y_full_max, z);
|
content_t c_full_max = vm->m_data[vi].getContent();
|
||||||
content_t c_full_max = vm->m_data[vi_full_max].getContent();
|
|
||||||
s16 y_start;
|
s16 y_start;
|
||||||
|
|
||||||
if (c_full_max == CONTENT_AIR) {
|
if (c_full_max == CONTENT_AIR) {
|
||||||
y_start = y_full_max - 1;
|
y_start = full_node_max.Y - 1;
|
||||||
} else if (c_full_max == CONTENT_IGNORE) {
|
} else if (c_full_max == CONTENT_IGNORE) {
|
||||||
s16 y_max = node_max.Y;
|
vi = vm->m_area.index(x, node_max.Y + 1, z);
|
||||||
u32 vi_max = vm->m_area.index(x, y_max, z);
|
content_t c_max = vm->m_data[vi].getContent();
|
||||||
content_t c_max = vm->m_data[vi_max].getContent();
|
|
||||||
|
|
||||||
if (c_max == CONTENT_AIR)
|
if (c_max == CONTENT_AIR)
|
||||||
y_start = y_max - 1;
|
y_start = node_max.Y;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 vi = vm->m_area.index(x, y_start, z);
|
vi = vm->m_area.index(x, y_start, z);
|
||||||
for (s16 y = y_start; y >= node_min.Y - 1; y--) {
|
for (s16 y = y_start; y >= node_min.Y - 1; y--) {
|
||||||
if (vm->m_data[vi].getContent() != CONTENT_AIR)
|
if (vm->m_data[vi].getContent() != CONTENT_AIR)
|
||||||
break;
|
break;
|
||||||
|
@@ -877,9 +877,10 @@ void MapgenV6::placeTreesAndJungleGrass()
|
|||||||
for (u32 i = 0; i < grass_count; i++) {
|
for (u32 i = 0; i < grass_count; i++) {
|
||||||
s16 x = grassrandom.range(p2d_min.X, p2d_max.X);
|
s16 x = grassrandom.range(p2d_min.X, p2d_max.X);
|
||||||
s16 z = grassrandom.range(p2d_min.Y, p2d_max.Y);
|
s16 z = grassrandom.range(p2d_min.Y, p2d_max.Y);
|
||||||
|
int mapindex = central_area_size.X * (z - node_min.Z)
|
||||||
s16 y = findGroundLevelFull(v2s16(x, z)); ////////////////optimize this!
|
+ (x - node_min.X);
|
||||||
if (y < water_level || y < node_min.Y || y > node_max.Y)
|
s16 y = heightmap[mapindex];
|
||||||
|
if (y < water_level)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
u32 vi = vm->m_area.index(x, y, z);
|
u32 vi = vm->m_area.index(x, y, z);
|
||||||
@@ -895,7 +896,9 @@ void MapgenV6::placeTreesAndJungleGrass()
|
|||||||
for (u32 i = 0; i < tree_count; i++) {
|
for (u32 i = 0; i < tree_count; i++) {
|
||||||
s16 x = myrand_range(p2d_min.X, p2d_max.X);
|
s16 x = myrand_range(p2d_min.X, p2d_max.X);
|
||||||
s16 z = myrand_range(p2d_min.Y, p2d_max.Y);
|
s16 z = myrand_range(p2d_min.Y, p2d_max.Y);
|
||||||
s16 y = findGroundLevelFull(v2s16(x, z)); ////////////////////optimize this!
|
int mapindex = central_area_size.X * (z - node_min.Z)
|
||||||
|
+ (x - node_min.X);
|
||||||
|
s16 y = heightmap[mapindex];
|
||||||
// Don't make a tree under water level
|
// Don't make a tree under water level
|
||||||
// Don't make a tree so high that it doesn't fit
|
// Don't make a tree so high that it doesn't fit
|
||||||
if(y < water_level || y > node_max.Y - 6)
|
if(y < water_level || y > node_max.Y - 6)
|
||||||
|
@@ -58,7 +58,7 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
|||||||
//// amount of elements to skip for the next index
|
//// amount of elements to skip for the next index
|
||||||
//// for noise/height/biome maps (not vmanip)
|
//// for noise/height/biome maps (not vmanip)
|
||||||
this->ystride = csize.X;
|
this->ystride = csize.X;
|
||||||
this->zstride = csize.X * csize.Y;
|
this->zstride = csize.X * (csize.Y + 2);
|
||||||
|
|
||||||
this->biomemap = new u8[csize.X * csize.Z];
|
this->biomemap = new u8[csize.X * csize.Z];
|
||||||
this->heightmap = new s16[csize.X * csize.Z];
|
this->heightmap = new s16[csize.X * csize.Z];
|
||||||
@@ -77,10 +77,10 @@ MapgenV7::MapgenV7(int mapgenid, MapgenParams *params, EmergeManager *emerge)
|
|||||||
noise_ridge_uwater = new Noise(&sp->np_ridge_uwater, seed, csize.X, csize.Z);
|
noise_ridge_uwater = new Noise(&sp->np_ridge_uwater, seed, csize.X, csize.Z);
|
||||||
|
|
||||||
//// 3d terrain noise
|
//// 3d terrain noise
|
||||||
noise_mountain = new Noise(&sp->np_mountain, seed, csize.X, csize.Y, csize.Z);
|
noise_mountain = new Noise(&sp->np_mountain, seed, csize.X, csize.Y + 2, csize.Z);
|
||||||
noise_ridge = new Noise(&sp->np_ridge, seed, csize.X, csize.Y, csize.Z);
|
noise_ridge = new Noise(&sp->np_ridge, seed, csize.X, csize.Y + 2, csize.Z);
|
||||||
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y, csize.Z);
|
noise_cave1 = new Noise(&sp->np_cave1, seed, csize.X, csize.Y + 2, csize.Z);
|
||||||
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y, csize.Z);
|
noise_cave2 = new Noise(&sp->np_cave2, seed, csize.X, csize.Y + 2, csize.Z);
|
||||||
|
|
||||||
//// Biome noise
|
//// Biome noise
|
||||||
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
noise_heat = new Noise(¶ms->np_biome_heat, seed, csize.X, csize.Z);
|
||||||
@@ -314,7 +314,9 @@ void MapgenV7::makeChunk(BlockMakeData *data)
|
|||||||
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
updateLiquid(&data->transforming_liquid, full_node_min, full_node_max);
|
||||||
|
|
||||||
if (flags & MG_LIGHT)
|
if (flags & MG_LIGHT)
|
||||||
calcLighting(node_min, node_max);
|
calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0),
|
||||||
|
full_node_min, full_node_max);
|
||||||
|
|
||||||
//setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
//setLighting(node_min - v3s16(1, 0, 1) * MAP_BLOCKSIZE,
|
||||||
// node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF);
|
// node_max + v3s16(1, 0, 1) * MAP_BLOCKSIZE, 0xFF);
|
||||||
|
|
||||||
@@ -326,7 +328,7 @@ void MapgenV7::calculateNoise()
|
|||||||
{
|
{
|
||||||
//TimeTaker t("calculateNoise", NULL, PRECISION_MICRO);
|
//TimeTaker t("calculateNoise", NULL, PRECISION_MICRO);
|
||||||
int x = node_min.X;
|
int x = node_min.X;
|
||||||
int y = node_min.Y;
|
int y = node_min.Y - 1;
|
||||||
int z = node_min.Z;
|
int z = node_min.Z;
|
||||||
|
|
||||||
noise_terrain_persist->perlinMap2D(x, z);
|
noise_terrain_persist->perlinMap2D(x, z);
|
||||||
@@ -489,8 +491,8 @@ int MapgenV7::generateBaseTerrain()
|
|||||||
if (surface_y > stone_surface_max_y)
|
if (surface_y > stone_surface_max_y)
|
||||||
stone_surface_max_y = surface_y;
|
stone_surface_max_y = surface_y;
|
||||||
|
|
||||||
u32 i = vm->m_area.index(x, node_min.Y, z);
|
u32 i = vm->m_area.index(x, node_min.Y - 1, z);
|
||||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
|
||||||
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
if (vm->m_data[i].getContent() == CONTENT_IGNORE) {
|
||||||
if (y <= surface_y)
|
if (y <= surface_y)
|
||||||
vm->m_data[i] = n_stone;
|
vm->m_data[i] = n_stone;
|
||||||
@@ -516,7 +518,7 @@ int MapgenV7::generateMountainTerrain(int ymax)
|
|||||||
u32 j = 0;
|
u32 j = 0;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
|
||||||
u32 vi = vm->m_area.index(node_min.X, y, z);
|
u32 vi = vm->m_area.index(node_min.X, y, z);
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++) {
|
||||||
int index = (z - node_min.Z) * csize.X + (x - node_min.X);
|
int index = (z - node_min.Z) * csize.X + (x - node_min.X);
|
||||||
@@ -549,7 +551,7 @@ void MapgenV7::generateRidgeTerrain()
|
|||||||
float width = 0.2; // TODO: figure out acceptable perlin noise values
|
float width = 0.2; // TODO: figure out acceptable perlin noise values
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
for (s16 z = node_min.Z; z <= node_max.Z; z++)
|
||||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
|
||||||
u32 vi = vm->m_area.index(node_min.X, y, z);
|
u32 vi = vm->m_area.index(node_min.X, y, z);
|
||||||
for (s16 x = node_min.X; x <= node_max.X; x++, index++, vi++) {
|
for (s16 x = node_min.X; x <= node_max.X; x++, index++, vi++) {
|
||||||
int j = (z - node_min.Z) * csize.X + (x - node_min.X);
|
int j = (z - node_min.Z) * csize.X + (x - node_min.X);
|
||||||
@@ -583,10 +585,6 @@ bool MapgenV7::generateBiomes(float *heat_map, float *humidity_map)
|
|||||||
if (node_max.Y < water_level)
|
if (node_max.Y < water_level)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MapNode n_air(CONTENT_AIR);
|
|
||||||
MapNode n_stone(c_stone);
|
|
||||||
MapNode n_water(c_water_source);
|
|
||||||
|
|
||||||
v3s16 em = vm->m_area.getExtent();
|
v3s16 em = vm->m_area.getExtent();
|
||||||
u32 index = 0;
|
u32 index = 0;
|
||||||
bool desert_stone = false;
|
bool desert_stone = false;
|
||||||
@@ -608,16 +606,6 @@ bool MapgenV7::generateBiomes(float *heat_map, float *humidity_map)
|
|||||||
for (s16 y = node_max.Y; y >= node_min.Y; y--) {
|
for (s16 y = node_max.Y; y >= node_min.Y; y--) {
|
||||||
content_t c = vm->m_data[i].getContent();
|
content_t c = vm->m_data[i].getContent();
|
||||||
|
|
||||||
// It could be the case that the elevation is equal to the chunk
|
|
||||||
// boundary, but the chunk above has not been generated yet
|
|
||||||
if (y == node_max.Y && c_above == CONTENT_IGNORE &&
|
|
||||||
y == heightmap[index] && c == c_stone) {
|
|
||||||
int j = (z - node_min.Z) * zstride +
|
|
||||||
(y - node_min.Y) * ystride +
|
|
||||||
(x - node_min.X);
|
|
||||||
have_air = !getMountainTerrainFromMap(j, index, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c != CONTENT_IGNORE && c != CONTENT_AIR && (y == node_max.Y || have_air)) {
|
if (c != CONTENT_IGNORE && c != CONTENT_AIR && (y == node_max.Y || have_air)) {
|
||||||
biome = bmgr->getBiome(heat_map[index], humidity_map[index], y);
|
biome = bmgr->getBiome(heat_map[index], humidity_map[index], y);
|
||||||
dfiller = biome->depth_filler + noise_filler_depth->result[index];
|
dfiller = biome->depth_filler + noise_filler_depth->result[index];
|
||||||
@@ -691,27 +679,25 @@ void MapgenV7::dustTopNodes()
|
|||||||
if (biome->c_dust == CONTENT_IGNORE)
|
if (biome->c_dust == CONTENT_IGNORE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
s16 y_full_max = full_node_max.Y;
|
u32 vi = vm->m_area.index(x, full_node_max.Y, z);
|
||||||
u32 vi_full_max = vm->m_area.index(x, y_full_max, z);
|
content_t c_full_max = vm->m_data[vi].getContent();
|
||||||
content_t c_full_max = vm->m_data[vi_full_max].getContent();
|
|
||||||
s16 y_start;
|
s16 y_start;
|
||||||
|
|
||||||
if (c_full_max == CONTENT_AIR) {
|
if (c_full_max == CONTENT_AIR) {
|
||||||
y_start = y_full_max - 1;
|
y_start = full_node_max.Y - 1;
|
||||||
} else if (c_full_max == CONTENT_IGNORE) {
|
} else if (c_full_max == CONTENT_IGNORE) {
|
||||||
s16 y_max = node_max.Y;
|
vi = vm->m_area.index(x, node_max.Y + 1, z);
|
||||||
u32 vi_max = vm->m_area.index(x, y_max, z);
|
content_t c_max = vm->m_data[vi].getContent();
|
||||||
content_t c_max = vm->m_data[vi_max].getContent();
|
|
||||||
|
|
||||||
if (c_max == CONTENT_AIR)
|
if (c_max == CONTENT_AIR)
|
||||||
y_start = y_max - 1;
|
y_start = node_max.Y;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 vi = vm->m_area.index(x, y_start, z);
|
vi = vm->m_area.index(x, y_start, z);
|
||||||
for (s16 y = y_start; y >= node_min.Y - 1; y--) {
|
for (s16 y = y_start; y >= node_min.Y - 1; y--) {
|
||||||
if (vm->m_data[vi].getContent() != CONTENT_AIR)
|
if (vm->m_data[vi].getContent() != CONTENT_AIR)
|
||||||
break;
|
break;
|
||||||
@@ -831,7 +817,7 @@ void MapgenV7::generateCaves(int max_stone_y)
|
|||||||
u32 index2d = 0;
|
u32 index2d = 0;
|
||||||
|
|
||||||
for (s16 z = node_min.Z; z <= node_max.Z; z++) {
|
for (s16 z = node_min.Z; z <= node_max.Z; z++) {
|
||||||
for (s16 y = node_min.Y; y <= node_max.Y; y++) {
|
for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++) {
|
||||||
u32 i = vm->m_area.index(node_min.X, y, z);
|
u32 i = vm->m_area.index(node_min.X, y, z);
|
||||||
for (s16 x = node_min.X; x <= node_max.X;
|
for (s16 x = node_min.X; x <= node_max.X;
|
||||||
x++, i++, index++, index2d++) {
|
x++, i++, index++, index2d++) {
|
||||||
|
@@ -308,7 +308,7 @@ void OreVein::generate(MMVManip *vm, int mapseed, u32 blockseed,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// randval ranges from -1..1
|
// randval ranges from -1..1
|
||||||
float randval = (float)pr.next() / (PSEUDORANDOM_MAX / 2) - 1.f;
|
float randval = (float)pr.next() / (pr.RANDOM_RANGE / 2) - 1.f;
|
||||||
float noiseval = contour(noise->result[index]);
|
float noiseval = contour(noise->result[index]);
|
||||||
float noiseval2 = contour(noise2->result[index]);
|
float noiseval2 = contour(noise2->result[index]);
|
||||||
if (noiseval * noiseval2 + randval * random_factor < nthresh)
|
if (noiseval * noiseval2 + randval * random_factor < nthresh)
|
||||||
|
@@ -207,6 +207,11 @@ bool Schematic::loadSchematicFromFile(const char *filename, INodeDefManager *nde
|
|||||||
bool have_cignore = false;
|
bool have_cignore = false;
|
||||||
|
|
||||||
std::ifstream is(filename, std::ios_base::binary);
|
std::ifstream is(filename, std::ios_base::binary);
|
||||||
|
if (!is.good()) {
|
||||||
|
errorstream << "loadSchematicFile: unable to open file '"
|
||||||
|
<< filename << "'" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
u32 signature = readU32(is);
|
u32 signature = readU32(is);
|
||||||
if (signature != MTSCHEM_FILE_SIGNATURE) {
|
if (signature != MTSCHEM_FILE_SIGNATURE) {
|
||||||
|
@@ -2924,7 +2924,7 @@ void Connection::Send(u16 peer_id, u8 channelnum,
|
|||||||
|
|
||||||
ConnectionCommand c;
|
ConnectionCommand c;
|
||||||
|
|
||||||
c.send(peer_id, channelnum, pkt->oldForgePacket(), reliable);
|
c.send(peer_id, channelnum, pkt, reliable);
|
||||||
putCommand(c);
|
putCommand(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -437,19 +437,12 @@ struct ConnectionCommand
|
|||||||
peer_id = peer_id_;
|
peer_id = peer_id_;
|
||||||
}
|
}
|
||||||
void send(u16 peer_id_, u8 channelnum_,
|
void send(u16 peer_id_, u8 channelnum_,
|
||||||
SharedBuffer<u8> data_, bool reliable_)
|
NetworkPacket* pkt, bool reliable_)
|
||||||
{
|
{
|
||||||
type = CONNCMD_SEND;
|
type = CONNCMD_SEND;
|
||||||
peer_id = peer_id_;
|
peer_id = peer_id_;
|
||||||
channelnum = channelnum_;
|
channelnum = channelnum_;
|
||||||
data = data_;
|
data = pkt->oldForgePacket();
|
||||||
reliable = reliable_;
|
|
||||||
}
|
|
||||||
void sendToAll(u8 channelnum_, SharedBuffer<u8> data_, bool reliable_)
|
|
||||||
{
|
|
||||||
type = CONNCMD_SEND_TO_ALL;
|
|
||||||
channelnum = channelnum_;
|
|
||||||
data = data_;
|
|
||||||
reliable = reliable_;
|
reliable = reliable_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -510,7 +510,7 @@ NetworkPacket& NetworkPacket::operator<<(video::SColor src)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedBuffer<u8> NetworkPacket::oldForgePacket()
|
Buffer<u8> NetworkPacket::oldForgePacket()
|
||||||
{
|
{
|
||||||
SharedBuffer<u8> sb(m_datasize + 2);
|
SharedBuffer<u8> sb(m_datasize + 2);
|
||||||
writeU16(&sb[0], m_command);
|
writeU16(&sb[0], m_command);
|
||||||
|
@@ -104,7 +104,7 @@ public:
|
|||||||
NetworkPacket& operator<<(video::SColor src);
|
NetworkPacket& operator<<(video::SColor src);
|
||||||
|
|
||||||
// Temp, we remove SharedBuffer when migration finished
|
// Temp, we remove SharedBuffer when migration finished
|
||||||
SharedBuffer<u8> oldForgePacket();
|
Buffer<u8> oldForgePacket();
|
||||||
private:
|
private:
|
||||||
template<typename T> void checkDataSize()
|
template<typename T> void checkDataSize()
|
||||||
{
|
{
|
||||||
|
@@ -62,6 +62,94 @@ FlagDesc flagdesc_noiseparams[] = {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PcgRandom::PcgRandom(u64 state, u64 seq)
|
||||||
|
{
|
||||||
|
seed(state, seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PcgRandom::seed(u64 state, u64 seq)
|
||||||
|
{
|
||||||
|
m_state = 0U;
|
||||||
|
m_inc = (seq << 1u) | 1u;
|
||||||
|
next();
|
||||||
|
m_state += state;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u32 PcgRandom::next()
|
||||||
|
{
|
||||||
|
u64 oldstate = m_state;
|
||||||
|
m_state = oldstate * 6364136223846793005ULL + m_inc;
|
||||||
|
|
||||||
|
u32 xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
|
||||||
|
u32 rot = oldstate >> 59u;
|
||||||
|
return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
u32 PcgRandom::range(u32 bound)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
If the bound is not a multiple of the RNG's range, it may cause bias,
|
||||||
|
e.g. a RNG has a range from 0 to 3 and we take want a number 0 to 2.
|
||||||
|
Using rand() % 3, the number 0 would be twice as likely to appear.
|
||||||
|
With a very large RNG range, the effect becomes less prevalent but
|
||||||
|
still present. This can be solved by modifying the range of the RNG
|
||||||
|
to become a multiple of bound by dropping values above the a threshhold.
|
||||||
|
In our example, threshhold == 4 - 3 = 1 % 3 == 1, so reject 0, thus
|
||||||
|
making the range 3 with no bias.
|
||||||
|
|
||||||
|
This loop looks dangerous, but will always terminate due to the
|
||||||
|
RNG's property of uniformity.
|
||||||
|
*/
|
||||||
|
u32 threshhold = -bound % bound;
|
||||||
|
u32 r;
|
||||||
|
|
||||||
|
while ((r = next()) < threshhold)
|
||||||
|
;
|
||||||
|
|
||||||
|
return r % bound;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
s32 PcgRandom::range(s32 min, s32 max)
|
||||||
|
{
|
||||||
|
assert(max >= min);
|
||||||
|
u32 bound = max - min + 1;
|
||||||
|
return range(bound) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PcgRandom::bytes(void *out, size_t len)
|
||||||
|
{
|
||||||
|
u8 *outb = (u8 *)out;
|
||||||
|
int bytes_left = 0;
|
||||||
|
u32 r;
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
if (bytes_left == 0) {
|
||||||
|
bytes_left = sizeof(u32);
|
||||||
|
r = next();
|
||||||
|
}
|
||||||
|
|
||||||
|
*outb = r & 0xFF;
|
||||||
|
outb++;
|
||||||
|
bytes_left--;
|
||||||
|
r >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
s32 PcgRandom::randNormalDist(s32 min, s32 max, int num_trials)
|
||||||
|
{
|
||||||
|
s32 accum = 0;
|
||||||
|
for (int i = 0; i != num_trials; i++)
|
||||||
|
accum += range(min, max);
|
||||||
|
return ((float)accum / num_trials) + 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
float noise2d(int x, int y, int seed)
|
float noise2d(int x, int y, int seed)
|
||||||
{
|
{
|
||||||
|
71
src/noise.h
71
src/noise.h
@@ -30,47 +30,67 @@
|
|||||||
#include "irr_v3d.h"
|
#include "irr_v3d.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
|
||||||
#define PSEUDORANDOM_MAX 32767
|
|
||||||
|
|
||||||
extern FlagDesc flagdesc_noiseparams[];
|
extern FlagDesc flagdesc_noiseparams[];
|
||||||
|
|
||||||
class PseudoRandom
|
// Note: this class is not polymorphic so that its high level of
|
||||||
{
|
// optimizability may be preserved in the common use case
|
||||||
|
class PseudoRandom {
|
||||||
public:
|
public:
|
||||||
PseudoRandom(): m_next(0)
|
const static u32 RANDOM_RANGE = 32767;
|
||||||
|
|
||||||
|
inline PseudoRandom(int seed=0):
|
||||||
|
m_next(seed)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
PseudoRandom(int seed): m_next(seed)
|
|
||||||
{
|
inline void seed(int seed)
|
||||||
}
|
|
||||||
void seed(int seed)
|
|
||||||
{
|
{
|
||||||
m_next = seed;
|
m_next = seed;
|
||||||
}
|
}
|
||||||
// Returns 0...PSEUDORANDOM_MAX
|
|
||||||
int next()
|
inline int next()
|
||||||
{
|
{
|
||||||
m_next = m_next * 1103515245 + 12345;
|
m_next = m_next * 1103515245 + 12345;
|
||||||
return((unsigned)(m_next/65536) % (PSEUDORANDOM_MAX + 1));
|
return (unsigned)(m_next / 65536) % (RANDOM_RANGE + 1);
|
||||||
}
|
}
|
||||||
int range(int min, int max)
|
|
||||||
|
inline int range(int min, int max)
|
||||||
{
|
{
|
||||||
if (max-min > (PSEUDORANDOM_MAX + 1) / 10)
|
assert(max >= min);
|
||||||
{
|
/*
|
||||||
//dstream<<"WARNING: PseudoRandom::range: max > 32767"<<std::endl;
|
Here, we ensure the range is not too large relative to RANDOM_MAX,
|
||||||
assert("Something wrong with random number" == NULL);
|
as otherwise the effects of bias would become noticable. Unlike
|
||||||
}
|
PcgRandom, we cannot modify this RNG's range as it would change the
|
||||||
if(min > max)
|
output of this RNG for reverse compatibility.
|
||||||
{
|
*/
|
||||||
assert("Something wrong with random number" == NULL);
|
assert((u32)(max - min) <= (RANDOM_RANGE + 1) / 10);
|
||||||
//return max;
|
|
||||||
}
|
return (next() % (max - min + 1)) + min;
|
||||||
return (next()%(max-min+1))+min;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_next;
|
int m_next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PcgRandom {
|
||||||
|
public:
|
||||||
|
const static s32 RANDOM_MIN = -0x7fffffff - 1;
|
||||||
|
const static s32 RANDOM_MAX = 0x7fffffff;
|
||||||
|
const static u32 RANDOM_RANGE = 0xffffffff;
|
||||||
|
|
||||||
|
PcgRandom(u64 state=0x853c49e6748fea9bULL, u64 seq=0xda3e39cb94b95bdbULL);
|
||||||
|
void seed(u64 state, u64 seq=0xda3e39cb94b95bdbULL);
|
||||||
|
u32 next();
|
||||||
|
u32 range(u32 bound);
|
||||||
|
s32 range(s32 min, s32 max);
|
||||||
|
void bytes(void *out, size_t len);
|
||||||
|
s32 randNormalDist(s32 min, s32 max, int num_trials=6);
|
||||||
|
|
||||||
|
private:
|
||||||
|
u64 m_state;
|
||||||
|
u64 m_inc;
|
||||||
|
};
|
||||||
|
|
||||||
#define NOISE_FLAG_DEFAULTS 0x01
|
#define NOISE_FLAG_DEFAULTS 0x01
|
||||||
#define NOISE_FLAG_EASED 0x02
|
#define NOISE_FLAG_EASED 0x02
|
||||||
#define NOISE_FLAG_ABSVALUE 0x04
|
#define NOISE_FLAG_ABSVALUE 0x04
|
||||||
@@ -89,7 +109,8 @@ struct NoiseParams {
|
|||||||
float lacunarity;
|
float lacunarity;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
|
|
||||||
NoiseParams() {
|
NoiseParams()
|
||||||
|
{
|
||||||
offset = 0.0f;
|
offset = 0.0f;
|
||||||
scale = 1.0f;
|
scale = 1.0f;
|
||||||
spread = v3f(250, 250, 250);
|
spread = v3f(250, 250, 250);
|
||||||
|
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include "jthread/jmutexautolock.h"
|
||||||
#include "util/numeric.h"
|
#include "util/numeric.h"
|
||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
@@ -240,6 +241,8 @@ void Player::deSerialize(std::istream &is, std::string playername)
|
|||||||
|
|
||||||
u32 Player::addHud(HudElement *toadd)
|
u32 Player::addHud(HudElement *toadd)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
u32 id = getFreeHudID();
|
u32 id = getFreeHudID();
|
||||||
|
|
||||||
if (id < hud.size())
|
if (id < hud.size())
|
||||||
@@ -252,6 +255,8 @@ u32 Player::addHud(HudElement *toadd)
|
|||||||
|
|
||||||
HudElement* Player::getHud(u32 id)
|
HudElement* Player::getHud(u32 id)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
if (id < hud.size())
|
if (id < hud.size())
|
||||||
return hud[id];
|
return hud[id];
|
||||||
|
|
||||||
@@ -260,6 +265,8 @@ HudElement* Player::getHud(u32 id)
|
|||||||
|
|
||||||
HudElement* Player::removeHud(u32 id)
|
HudElement* Player::removeHud(u32 id)
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
HudElement* retval = NULL;
|
HudElement* retval = NULL;
|
||||||
if (id < hud.size()) {
|
if (id < hud.size()) {
|
||||||
retval = hud[id];
|
retval = hud[id];
|
||||||
@@ -270,6 +277,8 @@ HudElement* Player::removeHud(u32 id)
|
|||||||
|
|
||||||
void Player::clearHud()
|
void Player::clearHud()
|
||||||
{
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
while(!hud.empty()) {
|
while(!hud.empty()) {
|
||||||
delete hud.back();
|
delete hud.back();
|
||||||
hud.pop_back();
|
hud.pop_back();
|
||||||
|
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "irrlichttypes_bloated.h"
|
#include "irrlichttypes_bloated.h"
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include "constants.h" // BS
|
#include "constants.h" // BS
|
||||||
|
#include "jthread/jmutex.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#define PLAYERNAME_SIZE 20
|
#define PLAYERNAME_SIZE 20
|
||||||
@@ -202,7 +203,7 @@ public:
|
|||||||
return m_collisionbox;
|
return m_collisionbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 getFreeHudID() const {
|
u32 getFreeHudID() {
|
||||||
size_t size = hud.size();
|
size_t size = hud.size();
|
||||||
for (size_t i = 0; i != size; i++) {
|
for (size_t i = 0; i != size; i++) {
|
||||||
if (!hud[i])
|
if (!hud[i])
|
||||||
@@ -318,6 +319,11 @@ protected:
|
|||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
|
|
||||||
std::vector<HudElement *> hud;
|
std::vector<HudElement *> hud;
|
||||||
|
private:
|
||||||
|
// Protect some critical areas
|
||||||
|
// hud for example can be modified by EmergeThread
|
||||||
|
// and ServerThread
|
||||||
|
JMutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -393,6 +393,8 @@ int ModApiCraft::l_get_craft_recipe(lua_State *L)
|
|||||||
std::vector<CraftDefinition*> recipes = server->cdef()
|
std::vector<CraftDefinition*> recipes = server->cdef()
|
||||||
->getCraftRecipes(output, server, 1);
|
->getCraftRecipes(output, server, 1);
|
||||||
|
|
||||||
|
lua_createtable(L, 1, 0);
|
||||||
|
|
||||||
if (recipes.empty()) {
|
if (recipes.empty()) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
lua_setfield(L, -2, "items");
|
lua_setfield(L, -2, "items");
|
||||||
|
@@ -89,7 +89,7 @@ struct EnumString ModApiMapgen::es_Rotation[] =
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
bool read_schematic(lua_State *L, int index, Schematic *schem,
|
bool read_schematic_def(lua_State *L, int index, Schematic *schem,
|
||||||
INodeDefManager *ndef, std::map<std::string, std::string> &replace_names)
|
INodeDefManager *ndef, std::map<std::string, std::string> &replace_names)
|
||||||
{
|
{
|
||||||
//// Get schematic size
|
//// Get schematic size
|
||||||
@@ -175,20 +175,45 @@ bool read_schematic(lua_State *L, int index, Schematic *schem,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool get_schematic(lua_State *L, int index, Schematic *schem,
|
Schematic *get_schematic(lua_State *L, int index, SchematicManager *schemmgr,
|
||||||
INodeDefManager *ndef, std::map<std::string, std::string> &replace_names)
|
std::map<std::string, std::string> &replace_names)
|
||||||
{
|
{
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
index = lua_gettop(L) + 1 + index;
|
index = lua_gettop(L) + 1 + index;
|
||||||
|
|
||||||
if (lua_istable(L, index)) {
|
Schematic *schem;
|
||||||
return read_schematic(L, index, schem, ndef, replace_names);
|
|
||||||
} else if (lua_isstring(L, index)) {
|
if (lua_isnumber(L, index)) {
|
||||||
|
return (Schematic *)schemmgr->get(lua_tointeger(L, index));
|
||||||
|
} else if (lua_istable(L, index)) {
|
||||||
|
schem = new Schematic;
|
||||||
|
if (!read_schematic_def(L, index, schem,
|
||||||
|
schemmgr->getNodeDef(), replace_names)) {
|
||||||
|
delete schem;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else if (lua_isstring(L, index)) {
|
||||||
const char *filename = lua_tostring(L, index);
|
const char *filename = lua_tostring(L, index);
|
||||||
return schem->loadSchematicFromFile(filename, ndef, replace_names);
|
schem = (Schematic *)schemmgr->getByName(filename);
|
||||||
|
if (schem)
|
||||||
|
return schem;
|
||||||
|
|
||||||
|
schem = new Schematic;
|
||||||
|
if (!schem->loadSchematicFromFile(filename,
|
||||||
|
schemmgr->getNodeDef(), replace_names)) {
|
||||||
|
delete schem;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (schemmgr->add(schem) == (u32)-1) {
|
||||||
|
delete schem;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return schem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -469,32 +494,10 @@ int ModApiMapgen::l_register_biome(lua_State *L)
|
|||||||
ndef->pendNodeResolve(nri);
|
ndef->pendNodeResolve(nri);
|
||||||
|
|
||||||
verbosestream << "register_biome: " << b->name << std::endl;
|
verbosestream << "register_biome: " << b->name << std::endl;
|
||||||
|
|
||||||
lua_pushinteger(L, id);
|
lua_pushinteger(L, id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModApiMapgen::l_clear_registered_biomes(lua_State *L)
|
|
||||||
{
|
|
||||||
BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr;
|
|
||||||
bmgr->clear();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ModApiMapgen::l_clear_registered_decorations(lua_State *L)
|
|
||||||
{
|
|
||||||
DecorationManager *dmgr = getServer(L)->getEmergeManager()->decomgr;
|
|
||||||
dmgr->clear();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ModApiMapgen::l_clear_registered_ores(lua_State *L)
|
|
||||||
{
|
|
||||||
OreManager *omgr = getServer(L)->getEmergeManager()->oremgr;
|
|
||||||
omgr->clear();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// register_decoration({lots of stuff})
|
// register_decoration({lots of stuff})
|
||||||
int ModApiMapgen::l_register_decoration(lua_State *L)
|
int ModApiMapgen::l_register_decoration(lua_State *L)
|
||||||
{
|
{
|
||||||
@@ -504,6 +507,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
||||||
DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr;
|
DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr;
|
||||||
BiomeManager *biomemgr = getServer(L)->getEmergeManager()->biomemgr;
|
BiomeManager *biomemgr = getServer(L)->getEmergeManager()->biomemgr;
|
||||||
|
SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;
|
||||||
|
|
||||||
enum DecorationType decotype = (DecorationType)getenumfield(L, index,
|
enum DecorationType decotype = (DecorationType)getenumfield(L, index,
|
||||||
"deco_type", es_DecorationType, -1);
|
"deco_type", es_DecorationType, -1);
|
||||||
@@ -562,7 +566,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
success = regDecoSimple(L, nri, (DecoSimple *)deco);
|
success = regDecoSimple(L, nri, (DecoSimple *)deco);
|
||||||
break;
|
break;
|
||||||
case DECO_SCHEMATIC:
|
case DECO_SCHEMATIC:
|
||||||
success = regDecoSchematic(L, ndef, (DecoSchematic *)deco);
|
success = regDecoSchematic(L, schemmgr, (DecoSchematic *)deco);
|
||||||
break;
|
break;
|
||||||
case DECO_LSYSTEM:
|
case DECO_LSYSTEM:
|
||||||
break;
|
break;
|
||||||
@@ -582,7 +586,6 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
verbosestream << "register_decoration: " << deco->name << std::endl;
|
verbosestream << "register_decoration: " << deco->name << std::endl;
|
||||||
|
|
||||||
lua_pushinteger(L, id);
|
lua_pushinteger(L, id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -627,8 +630,8 @@ bool ModApiMapgen::regDecoSimple(lua_State *L,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModApiMapgen::regDecoSchematic(lua_State *L, INodeDefManager *ndef,
|
bool ModApiMapgen::regDecoSchematic(lua_State *L,
|
||||||
DecoSchematic *deco)
|
SchematicManager *schemmgr, DecoSchematic *deco)
|
||||||
{
|
{
|
||||||
int index = 1;
|
int index = 1;
|
||||||
|
|
||||||
@@ -641,19 +644,12 @@ bool ModApiMapgen::regDecoSchematic(lua_State *L, INodeDefManager *ndef,
|
|||||||
read_schematic_replacements(L, replace_names, lua_gettop(L));
|
read_schematic_replacements(L, replace_names, lua_gettop(L));
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
// TODO(hmmmm): get a ref from registered schematics
|
|
||||||
Schematic *schem = new Schematic;
|
|
||||||
lua_getfield(L, index, "schematic");
|
lua_getfield(L, index, "schematic");
|
||||||
if (!get_schematic(L, -1, schem, ndef, replace_names)) {
|
Schematic *schem = get_schematic(L, -1, schemmgr, replace_names);
|
||||||
lua_pop(L, 1);
|
|
||||||
delete schem;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
deco->schematic = schem;
|
deco->schematic = schem;
|
||||||
|
return schem != NULL;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// register_ore({lots of stuff})
|
// register_ore({lots of stuff})
|
||||||
@@ -741,11 +737,100 @@ int ModApiMapgen::l_register_ore(lua_State *L)
|
|||||||
ndef->pendNodeResolve(nri);
|
ndef->pendNodeResolve(nri);
|
||||||
|
|
||||||
verbosestream << "register_ore: " << ore->name << std::endl;
|
verbosestream << "register_ore: " << ore->name << std::endl;
|
||||||
|
|
||||||
lua_pushinteger(L, id);
|
lua_pushinteger(L, id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// register_schematic({schematic}, replacements={})
|
||||||
|
int ModApiMapgen::l_register_schematic(lua_State *L)
|
||||||
|
{
|
||||||
|
SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;
|
||||||
|
|
||||||
|
std::map<std::string, std::string> replace_names;
|
||||||
|
if (lua_istable(L, 2))
|
||||||
|
read_schematic_replacements(L, replace_names, 2);
|
||||||
|
|
||||||
|
Schematic *schem = get_schematic(L, 1, schemmgr, replace_names);
|
||||||
|
if (!schem)
|
||||||
|
return 0;
|
||||||
|
printf("register_schematic!\n");
|
||||||
|
verbosestream << "register_schematic: " << schem->name << std::endl;
|
||||||
|
lua_pushinteger(L, schem->id);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear_registered_biomes()
|
||||||
|
int ModApiMapgen::l_clear_registered_biomes(lua_State *L)
|
||||||
|
{
|
||||||
|
BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr;
|
||||||
|
bmgr->clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear_registered_decorations()
|
||||||
|
int ModApiMapgen::l_clear_registered_decorations(lua_State *L)
|
||||||
|
{
|
||||||
|
DecorationManager *dmgr = getServer(L)->getEmergeManager()->decomgr;
|
||||||
|
dmgr->clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear_registered_ores()
|
||||||
|
int ModApiMapgen::l_clear_registered_ores(lua_State *L)
|
||||||
|
{
|
||||||
|
OreManager *omgr = getServer(L)->getEmergeManager()->oremgr;
|
||||||
|
omgr->clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear_registered_schematics()
|
||||||
|
int ModApiMapgen::l_clear_registered_schematics(lua_State *L)
|
||||||
|
{
|
||||||
|
SchematicManager *smgr = getServer(L)->getEmergeManager()->schemmgr;
|
||||||
|
smgr->clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate_ores(vm, p1, p2, [ore_id])
|
||||||
|
int ModApiMapgen::l_generate_ores(lua_State *L)
|
||||||
|
{
|
||||||
|
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||||
|
|
||||||
|
Mapgen mg;
|
||||||
|
mg.seed = emerge->params.seed;
|
||||||
|
mg.vm = LuaVoxelManip::checkobject(L, 1)->vm;
|
||||||
|
mg.ndef = getServer(L)->getNodeDefManager();
|
||||||
|
|
||||||
|
u32 blockseed = Mapgen::getBlockSeed(mg.vm->m_area.MinEdge, mg.seed);
|
||||||
|
|
||||||
|
v3s16 pmin = read_v3s16(L, 2);
|
||||||
|
v3s16 pmax = read_v3s16(L, 3);
|
||||||
|
|
||||||
|
emerge->oremgr->placeAllOres(&mg, blockseed, pmin, pmax);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate_decorations(vm, p1, p2, [deco_id])
|
||||||
|
int ModApiMapgen::l_generate_decorations(lua_State *L)
|
||||||
|
{
|
||||||
|
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
||||||
|
|
||||||
|
Mapgen mg;
|
||||||
|
mg.seed = emerge->params.seed;
|
||||||
|
mg.vm = LuaVoxelManip::checkobject(L, 1)->vm;
|
||||||
|
mg.ndef = getServer(L)->getNodeDefManager();
|
||||||
|
|
||||||
|
u32 blockseed = Mapgen::getBlockSeed(mg.vm->m_area.MinEdge, mg.seed);
|
||||||
|
|
||||||
|
v3s16 pmin = read_v3s16(L, 2);
|
||||||
|
v3s16 pmax = read_v3s16(L, 3);
|
||||||
|
|
||||||
|
emerge->decomgr->placeAllDecos(&mg, blockseed, pmin, pmax);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// create_schematic(p1, p2, probability_list, filename)
|
// create_schematic(p1, p2, probability_list, filename)
|
||||||
int ModApiMapgen::l_create_schematic(lua_State *L)
|
int ModApiMapgen::l_create_schematic(lua_State *L)
|
||||||
{
|
{
|
||||||
@@ -806,53 +891,11 @@ int ModApiMapgen::l_create_schematic(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate_ores(vm, p1, p2, [ore_id])
|
|
||||||
int ModApiMapgen::l_generate_ores(lua_State *L)
|
|
||||||
{
|
|
||||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
|
||||||
|
|
||||||
Mapgen mg;
|
|
||||||
mg.seed = emerge->params.seed;
|
|
||||||
mg.vm = LuaVoxelManip::checkobject(L, 1)->vm;
|
|
||||||
mg.ndef = getServer(L)->getNodeDefManager();
|
|
||||||
|
|
||||||
u32 blockseed = Mapgen::getBlockSeed(mg.vm->m_area.MinEdge, mg.seed);
|
|
||||||
|
|
||||||
v3s16 pmin = read_v3s16(L, 2);
|
|
||||||
v3s16 pmax = read_v3s16(L, 3);
|
|
||||||
|
|
||||||
emerge->oremgr->placeAllOres(&mg, blockseed, pmin, pmax);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate_decorations(vm, p1, p2, [deco_id])
|
|
||||||
int ModApiMapgen::l_generate_decorations(lua_State *L)
|
|
||||||
{
|
|
||||||
EmergeManager *emerge = getServer(L)->getEmergeManager();
|
|
||||||
|
|
||||||
Mapgen mg;
|
|
||||||
mg.seed = emerge->params.seed;
|
|
||||||
mg.vm = LuaVoxelManip::checkobject(L, 1)->vm;
|
|
||||||
mg.ndef = getServer(L)->getNodeDefManager();
|
|
||||||
|
|
||||||
u32 blockseed = Mapgen::getBlockSeed(mg.vm->m_area.MinEdge, mg.seed);
|
|
||||||
|
|
||||||
v3s16 pmin = read_v3s16(L, 2);
|
|
||||||
v3s16 pmax = read_v3s16(L, 3);
|
|
||||||
|
|
||||||
emerge->decomgr->placeAllDecos(&mg, blockseed, pmin, pmax);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// place_schematic(p, schematic, rotation, replacement)
|
// place_schematic(p, schematic, rotation, replacement)
|
||||||
int ModApiMapgen::l_place_schematic(lua_State *L)
|
int ModApiMapgen::l_place_schematic(lua_State *L)
|
||||||
{
|
{
|
||||||
Schematic schem;
|
|
||||||
|
|
||||||
Map *map = &(getEnv(L)->getMap());
|
Map *map = &(getEnv(L)->getMap());
|
||||||
INodeDefManager *ndef = getServer(L)->getNodeDefManager();
|
SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;
|
||||||
|
|
||||||
//// Read position
|
//// Read position
|
||||||
v3s16 p = read_v3s16(L, 1);
|
v3s16 p = read_v3s16(L, 1);
|
||||||
@@ -873,12 +916,14 @@ int ModApiMapgen::l_place_schematic(lua_State *L)
|
|||||||
read_schematic_replacements(L, replace_names, 4);
|
read_schematic_replacements(L, replace_names, 4);
|
||||||
|
|
||||||
//// Read schematic
|
//// Read schematic
|
||||||
if (!get_schematic(L, 2, &schem, ndef, replace_names)) {
|
Schematic *schem = get_schematic(L, 2, schemmgr, replace_names);
|
||||||
|
if (!schem) {
|
||||||
errorstream << "place_schematic: failed to get schematic" << std::endl;
|
errorstream << "place_schematic: failed to get schematic" << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
schem.placeStructure(map, p, 0, (Rotation)rot, force_placement, ndef);
|
schem->placeStructure(map, p, 0, (Rotation)rot, force_placement,
|
||||||
|
schemmgr->getNodeDef());
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -895,14 +940,15 @@ void ModApiMapgen::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(register_biome);
|
API_FCT(register_biome);
|
||||||
API_FCT(register_decoration);
|
API_FCT(register_decoration);
|
||||||
API_FCT(register_ore);
|
API_FCT(register_ore);
|
||||||
|
API_FCT(register_schematic);
|
||||||
|
|
||||||
API_FCT(clear_registered_biomes);
|
API_FCT(clear_registered_biomes);
|
||||||
API_FCT(clear_registered_decorations);
|
API_FCT(clear_registered_decorations);
|
||||||
API_FCT(clear_registered_ores);
|
API_FCT(clear_registered_ores);
|
||||||
|
API_FCT(clear_registered_schematics);
|
||||||
|
|
||||||
API_FCT(generate_ores);
|
API_FCT(generate_ores);
|
||||||
API_FCT(generate_decorations);
|
API_FCT(generate_decorations);
|
||||||
|
|
||||||
API_FCT(create_schematic);
|
API_FCT(create_schematic);
|
||||||
API_FCT(place_schematic);
|
API_FCT(place_schematic);
|
||||||
}
|
}
|
||||||
|
@@ -26,6 +26,7 @@ class INodeDefManager;
|
|||||||
struct NodeResolveInfo;
|
struct NodeResolveInfo;
|
||||||
class DecoSimple;
|
class DecoSimple;
|
||||||
class DecoSchematic;
|
class DecoSchematic;
|
||||||
|
class SchematicManager;
|
||||||
|
|
||||||
class ModApiMapgen : public ModApiBase {
|
class ModApiMapgen : public ModApiBase {
|
||||||
private:
|
private:
|
||||||
@@ -56,12 +57,18 @@ private:
|
|||||||
// register_ore({lots of stuff})
|
// register_ore({lots of stuff})
|
||||||
static int l_register_ore(lua_State *L);
|
static int l_register_ore(lua_State *L);
|
||||||
|
|
||||||
|
// register_schematic({schematic}, replacements={})
|
||||||
|
static int l_register_schematic(lua_State *L);
|
||||||
|
|
||||||
// clear_registered_biomes()
|
// clear_registered_biomes()
|
||||||
static int l_clear_registered_biomes(lua_State *L);
|
static int l_clear_registered_biomes(lua_State *L);
|
||||||
|
|
||||||
// clear_registered_decorations()
|
// clear_registered_decorations()
|
||||||
static int l_clear_registered_decorations(lua_State *L);
|
static int l_clear_registered_decorations(lua_State *L);
|
||||||
|
|
||||||
|
// clear_registered_schematics()
|
||||||
|
static int l_clear_registered_schematics(lua_State *L);
|
||||||
|
|
||||||
// generate_ores(vm, p1, p2)
|
// generate_ores(vm, p1, p2)
|
||||||
static int l_generate_ores(lua_State *L);
|
static int l_generate_ores(lua_State *L);
|
||||||
|
|
||||||
@@ -80,7 +87,7 @@ private:
|
|||||||
static bool regDecoSimple(lua_State *L,
|
static bool regDecoSimple(lua_State *L,
|
||||||
NodeResolveInfo *nri, DecoSimple *deco);
|
NodeResolveInfo *nri, DecoSimple *deco);
|
||||||
static bool regDecoSchematic(lua_State *L,
|
static bool regDecoSchematic(lua_State *L,
|
||||||
INodeDefManager *ndef, DecoSchematic *deco);
|
SchematicManager *schemmgr, DecoSchematic *deco);
|
||||||
|
|
||||||
static struct EnumString es_BiomeTerrainType[];
|
static struct EnumString es_BiomeTerrainType[];
|
||||||
static struct EnumString es_DecorationType[];
|
static struct EnumString es_DecorationType[];
|
||||||
|
@@ -23,12 +23,19 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "common/c_content.h"
|
#include "common/c_content.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
// garbage collector
|
///////////////////////////////////////
|
||||||
int LuaPerlinNoise::gc_object(lua_State *L)
|
/*
|
||||||
|
LuaPerlinNoise
|
||||||
|
*/
|
||||||
|
|
||||||
|
LuaPerlinNoise::LuaPerlinNoise(NoiseParams *params) :
|
||||||
|
np(*params)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LuaPerlinNoise::~LuaPerlinNoise()
|
||||||
{
|
{
|
||||||
LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
|
|
||||||
delete o;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -54,19 +61,6 @@ int LuaPerlinNoise::l_get3d(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LuaPerlinNoise::LuaPerlinNoise(NoiseParams *params) :
|
|
||||||
np(*params)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LuaPerlinNoise::~LuaPerlinNoise()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// LuaPerlinNoise(seed, octaves, persistence, scale)
|
|
||||||
// Creates an LuaPerlinNoise and leaves it on top of stack
|
|
||||||
int LuaPerlinNoise::create_object(lua_State *L)
|
int LuaPerlinNoise::create_object(lua_State *L)
|
||||||
{
|
{
|
||||||
NO_MAP_LOCK_REQUIRED;
|
NO_MAP_LOCK_REQUIRED;
|
||||||
@@ -91,14 +85,22 @@ int LuaPerlinNoise::create_object(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LuaPerlinNoise* LuaPerlinNoise::checkobject(lua_State *L, int narg)
|
int LuaPerlinNoise::gc_object(lua_State *L)
|
||||||
|
{
|
||||||
|
LuaPerlinNoise *o = *(LuaPerlinNoise **)(lua_touserdata(L, 1));
|
||||||
|
delete o;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LuaPerlinNoise *LuaPerlinNoise::checkobject(lua_State *L, int narg)
|
||||||
{
|
{
|
||||||
NO_MAP_LOCK_REQUIRED;
|
NO_MAP_LOCK_REQUIRED;
|
||||||
luaL_checktype(L, narg, LUA_TUSERDATA);
|
luaL_checktype(L, narg, LUA_TUSERDATA);
|
||||||
void *ud = luaL_checkudata(L, narg, className);
|
void *ud = luaL_checkudata(L, narg, className);
|
||||||
if (!ud)
|
if (!ud)
|
||||||
luaL_typerror(L, narg, className);
|
luaL_typerror(L, narg, className);
|
||||||
return *(LuaPerlinNoise**)ud; // unbox pointer
|
return *(LuaPerlinNoise **)ud;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -111,7 +113,7 @@ void LuaPerlinNoise::Register(lua_State *L)
|
|||||||
|
|
||||||
lua_pushliteral(L, "__metatable");
|
lua_pushliteral(L, "__metatable");
|
||||||
lua_pushvalue(L, methodtable);
|
lua_pushvalue(L, methodtable);
|
||||||
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
lua_pushliteral(L, "__index");
|
lua_pushliteral(L, "__index");
|
||||||
lua_pushvalue(L, methodtable);
|
lua_pushvalue(L, methodtable);
|
||||||
@@ -121,12 +123,11 @@ void LuaPerlinNoise::Register(lua_State *L)
|
|||||||
lua_pushcfunction(L, gc_object);
|
lua_pushcfunction(L, gc_object);
|
||||||
lua_settable(L, metatable);
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
lua_pop(L, 1); // drop metatable
|
lua_pop(L, 1);
|
||||||
|
|
||||||
luaL_openlib(L, 0, methods, 0); // fill methodtable
|
luaL_openlib(L, 0, methods, 0);
|
||||||
lua_pop(L, 1); // drop methodtable
|
lua_pop(L, 1);
|
||||||
|
|
||||||
// Can be created from Lua (PerlinNoise(seed, octaves, persistence)
|
|
||||||
lua_register(L, className, create_object);
|
lua_register(L, className, create_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,16 +139,26 @@ const luaL_reg LuaPerlinNoise::methods[] = {
|
|||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
/*
|
/*
|
||||||
PerlinNoiseMap
|
LuaPerlinNoiseMap
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int LuaPerlinNoiseMap::gc_object(lua_State *L)
|
LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *params, int seed, v3s16 size)
|
||||||
{
|
{
|
||||||
LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1));
|
m_is3d = size.Z > 1;
|
||||||
delete o;
|
np = *params;
|
||||||
return 0;
|
try {
|
||||||
|
noise = new Noise(&np, seed, size.X, size.Y, size.Z);
|
||||||
|
} catch (InvalidNoiseParamsException &e) {
|
||||||
|
throw LuaError(e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LuaPerlinNoiseMap::~LuaPerlinNoiseMap()
|
||||||
|
{
|
||||||
|
delete noise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -251,26 +262,6 @@ int LuaPerlinNoiseMap::l_get3dMap_flat(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LuaPerlinNoiseMap::LuaPerlinNoiseMap(NoiseParams *params, int seed, v3s16 size)
|
|
||||||
{
|
|
||||||
m_is3d = size.Z > 1;
|
|
||||||
np = *params;
|
|
||||||
try {
|
|
||||||
noise = new Noise(&np, seed, size.X, size.Y, size.Z);
|
|
||||||
} catch (InvalidNoiseParamsException &e) {
|
|
||||||
throw LuaError(e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LuaPerlinNoiseMap::~LuaPerlinNoiseMap()
|
|
||||||
{
|
|
||||||
delete noise;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// LuaPerlinNoiseMap(np, size)
|
|
||||||
// Creates an LuaPerlinNoiseMap and leaves it on top of stack
|
|
||||||
int LuaPerlinNoiseMap::create_object(lua_State *L)
|
int LuaPerlinNoiseMap::create_object(lua_State *L)
|
||||||
{
|
{
|
||||||
NoiseParams np;
|
NoiseParams np;
|
||||||
@@ -286,6 +277,14 @@ int LuaPerlinNoiseMap::create_object(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LuaPerlinNoiseMap::gc_object(lua_State *L)
|
||||||
|
{
|
||||||
|
LuaPerlinNoiseMap *o = *(LuaPerlinNoiseMap **)(lua_touserdata(L, 1));
|
||||||
|
delete o;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LuaPerlinNoiseMap *LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
|
LuaPerlinNoiseMap *LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
|
||||||
{
|
{
|
||||||
luaL_checktype(L, narg, LUA_TUSERDATA);
|
luaL_checktype(L, narg, LUA_TUSERDATA);
|
||||||
@@ -294,7 +293,7 @@ LuaPerlinNoiseMap *LuaPerlinNoiseMap::checkobject(lua_State *L, int narg)
|
|||||||
if (!ud)
|
if (!ud)
|
||||||
luaL_typerror(L, narg, className);
|
luaL_typerror(L, narg, className);
|
||||||
|
|
||||||
return *(LuaPerlinNoiseMap **)ud; // unbox pointer
|
return *(LuaPerlinNoiseMap **)ud;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -307,7 +306,7 @@ void LuaPerlinNoiseMap::Register(lua_State *L)
|
|||||||
|
|
||||||
lua_pushliteral(L, "__metatable");
|
lua_pushliteral(L, "__metatable");
|
||||||
lua_pushvalue(L, methodtable);
|
lua_pushvalue(L, methodtable);
|
||||||
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
lua_pushliteral(L, "__index");
|
lua_pushliteral(L, "__index");
|
||||||
lua_pushvalue(L, methodtable);
|
lua_pushvalue(L, methodtable);
|
||||||
@@ -317,12 +316,11 @@ void LuaPerlinNoiseMap::Register(lua_State *L)
|
|||||||
lua_pushcfunction(L, gc_object);
|
lua_pushcfunction(L, gc_object);
|
||||||
lua_settable(L, metatable);
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
lua_pop(L, 1); // drop metatable
|
lua_pop(L, 1);
|
||||||
|
|
||||||
luaL_openlib(L, 0, methods, 0); // fill methodtable
|
luaL_openlib(L, 0, methods, 0);
|
||||||
lua_pop(L, 1); // drop methodtable
|
lua_pop(L, 1);
|
||||||
|
|
||||||
// Can be created from Lua (PerlinNoiseMap(np, size)
|
|
||||||
lua_register(L, className, create_object);
|
lua_register(L, className, create_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,32 +334,23 @@ const luaL_reg LuaPerlinNoiseMap::methods[] = {
|
|||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
/*
|
/*
|
||||||
LuaPseudoRandom
|
LuaPseudoRandom
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// garbage collector
|
|
||||||
int LuaPseudoRandom::gc_object(lua_State *L)
|
|
||||||
{
|
|
||||||
LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
|
|
||||||
delete o;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// next(self, min=0, max=32767) -> get next value
|
|
||||||
int LuaPseudoRandom::l_next(lua_State *L)
|
int LuaPseudoRandom::l_next(lua_State *L)
|
||||||
{
|
{
|
||||||
NO_MAP_LOCK_REQUIRED;
|
NO_MAP_LOCK_REQUIRED;
|
||||||
LuaPseudoRandom *o = checkobject(L, 1);
|
LuaPseudoRandom *o = checkobject(L, 1);
|
||||||
int min = 0;
|
int min = 0;
|
||||||
int max = 32767;
|
int max = 32767;
|
||||||
lua_settop(L, 3); // Fill 2 and 3 with nil if they don't exist
|
lua_settop(L, 3);
|
||||||
if(!lua_isnil(L, 2))
|
if (lua_isnumber(L, 2))
|
||||||
min = luaL_checkinteger(L, 2);
|
min = luaL_checkinteger(L, 2);
|
||||||
if(!lua_isnil(L, 3))
|
if (lua_isnumber(L, 3))
|
||||||
max = luaL_checkinteger(L, 3);
|
max = luaL_checkinteger(L, 3);
|
||||||
if(max < min){
|
if (max < min) {
|
||||||
errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl;
|
errorstream<<"PseudoRandom.next(): max="<<max<<" min="<<min<<std::endl;
|
||||||
throw LuaError("PseudoRandom.next(): max < min");
|
throw LuaError("PseudoRandom.next(): max < min");
|
||||||
}
|
}
|
||||||
@@ -378,30 +367,6 @@ int LuaPseudoRandom::l_next(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LuaPseudoRandom::LuaPseudoRandom(int seed):
|
|
||||||
m_pseudo(seed)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LuaPseudoRandom::~LuaPseudoRandom()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const PseudoRandom& LuaPseudoRandom::getItem() const
|
|
||||||
{
|
|
||||||
return m_pseudo;
|
|
||||||
}
|
|
||||||
|
|
||||||
PseudoRandom& LuaPseudoRandom::getItem()
|
|
||||||
{
|
|
||||||
return m_pseudo;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// LuaPseudoRandom(seed)
|
|
||||||
// Creates an LuaPseudoRandom and leaves it on top of stack
|
|
||||||
int LuaPseudoRandom::create_object(lua_State *L)
|
int LuaPseudoRandom::create_object(lua_State *L)
|
||||||
{
|
{
|
||||||
int seed = luaL_checknumber(L, 1);
|
int seed = luaL_checknumber(L, 1);
|
||||||
@@ -413,13 +378,21 @@ int LuaPseudoRandom::create_object(lua_State *L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LuaPseudoRandom* LuaPseudoRandom::checkobject(lua_State *L, int narg)
|
int LuaPseudoRandom::gc_object(lua_State *L)
|
||||||
|
{
|
||||||
|
LuaPseudoRandom *o = *(LuaPseudoRandom **)(lua_touserdata(L, 1));
|
||||||
|
delete o;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LuaPseudoRandom *LuaPseudoRandom::checkobject(lua_State *L, int narg)
|
||||||
{
|
{
|
||||||
luaL_checktype(L, narg, LUA_TUSERDATA);
|
luaL_checktype(L, narg, LUA_TUSERDATA);
|
||||||
void *ud = luaL_checkudata(L, narg, className);
|
void *ud = luaL_checkudata(L, narg, className);
|
||||||
if (!ud)
|
if (!ud)
|
||||||
luaL_typerror(L, narg, className);
|
luaL_typerror(L, narg, className);
|
||||||
return *(LuaPseudoRandom**)ud; // unbox pointer
|
return *(LuaPseudoRandom **)ud;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -432,7 +405,7 @@ void LuaPseudoRandom::Register(lua_State *L)
|
|||||||
|
|
||||||
lua_pushliteral(L, "__metatable");
|
lua_pushliteral(L, "__metatable");
|
||||||
lua_pushvalue(L, methodtable);
|
lua_pushvalue(L, methodtable);
|
||||||
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
lua_pushliteral(L, "__index");
|
lua_pushliteral(L, "__index");
|
||||||
lua_pushvalue(L, methodtable);
|
lua_pushvalue(L, methodtable);
|
||||||
@@ -442,12 +415,11 @@ void LuaPseudoRandom::Register(lua_State *L)
|
|||||||
lua_pushcfunction(L, gc_object);
|
lua_pushcfunction(L, gc_object);
|
||||||
lua_settable(L, metatable);
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
lua_pop(L, 1); // drop metatable
|
lua_pop(L, 1);
|
||||||
|
|
||||||
luaL_openlib(L, 0, methods, 0); // fill methodtable
|
luaL_openlib(L, 0, methods, 0);
|
||||||
lua_pop(L, 1); // drop methodtable
|
lua_pop(L, 1);
|
||||||
|
|
||||||
// Can be created from Lua (LuaPseudoRandom(seed))
|
|
||||||
lua_register(L, className, create_object);
|
lua_register(L, className, create_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -457,3 +429,101 @@ const luaL_reg LuaPseudoRandom::methods[] = {
|
|||||||
luamethod(LuaPseudoRandom, next),
|
luamethod(LuaPseudoRandom, next),
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
/*
|
||||||
|
LuaPcgRandom
|
||||||
|
*/
|
||||||
|
|
||||||
|
int LuaPcgRandom::l_next(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
|
||||||
|
LuaPcgRandom *o = checkobject(L, 1);
|
||||||
|
u32 min = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : o->m_rnd.RANDOM_MIN;
|
||||||
|
u32 max = lua_isnumber(L, 3) ? lua_tointeger(L, 3) : o->m_rnd.RANDOM_MAX;
|
||||||
|
|
||||||
|
lua_pushinteger(L, o->m_rnd.range(min, max));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LuaPcgRandom::l_rand_normal_dist(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
|
||||||
|
LuaPcgRandom *o = checkobject(L, 1);
|
||||||
|
u32 min = lua_isnumber(L, 2) ? lua_tointeger(L, 2) : o->m_rnd.RANDOM_MIN;
|
||||||
|
u32 max = lua_isnumber(L, 3) ? lua_tointeger(L, 3) : o->m_rnd.RANDOM_MAX;
|
||||||
|
int num_trials = lua_isnumber(L, 4) ? lua_tointeger(L, 4) : 6;
|
||||||
|
|
||||||
|
lua_pushinteger(L, o->m_rnd.randNormalDist(min, max, num_trials));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LuaPcgRandom::create_object(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_Integer seed = luaL_checknumber(L, 1);
|
||||||
|
LuaPcgRandom *o = lua_isnumber(L, 2) ?
|
||||||
|
new LuaPcgRandom(seed, lua_tointeger(L, 2)) :
|
||||||
|
new LuaPcgRandom(seed);
|
||||||
|
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||||
|
luaL_getmetatable(L, className);
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LuaPcgRandom::gc_object(lua_State *L)
|
||||||
|
{
|
||||||
|
LuaPcgRandom *o = *(LuaPcgRandom **)(lua_touserdata(L, 1));
|
||||||
|
delete o;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LuaPcgRandom *LuaPcgRandom::checkobject(lua_State *L, int narg)
|
||||||
|
{
|
||||||
|
luaL_checktype(L, narg, LUA_TUSERDATA);
|
||||||
|
void *ud = luaL_checkudata(L, narg, className);
|
||||||
|
if (!ud)
|
||||||
|
luaL_typerror(L, narg, className);
|
||||||
|
return *(LuaPcgRandom **)ud;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LuaPcgRandom::Register(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_newtable(L);
|
||||||
|
int methodtable = lua_gettop(L);
|
||||||
|
luaL_newmetatable(L, className);
|
||||||
|
int metatable = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__metatable");
|
||||||
|
lua_pushvalue(L, methodtable);
|
||||||
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__index");
|
||||||
|
lua_pushvalue(L, methodtable);
|
||||||
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__gc");
|
||||||
|
lua_pushcfunction(L, gc_object);
|
||||||
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
luaL_openlib(L, 0, methods, 0);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_register(L, className, create_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char LuaPcgRandom::className[] = "PcgRandom";
|
||||||
|
const luaL_reg LuaPcgRandom::methods[] = {
|
||||||
|
luamethod(LuaPcgRandom, next),
|
||||||
|
luamethod(LuaPcgRandom, rand_normal_dist),
|
||||||
|
{0,0}
|
||||||
|
};
|
||||||
|
@@ -64,6 +64,9 @@ class LuaPerlinNoiseMap : public ModApiBase {
|
|||||||
static const char className[];
|
static const char className[];
|
||||||
static const luaL_reg methods[];
|
static const luaL_reg methods[];
|
||||||
|
|
||||||
|
// Exported functions
|
||||||
|
|
||||||
|
// garbage collector
|
||||||
static int gc_object(lua_State *L);
|
static int gc_object(lua_State *L);
|
||||||
|
|
||||||
static int l_get2dMap(lua_State *L);
|
static int l_get2dMap(lua_State *L);
|
||||||
@@ -104,18 +107,51 @@ private:
|
|||||||
static int l_next(lua_State *L);
|
static int l_next(lua_State *L);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LuaPseudoRandom(int seed);
|
LuaPseudoRandom(int seed) :
|
||||||
|
m_pseudo(seed) {}
|
||||||
~LuaPseudoRandom();
|
|
||||||
|
|
||||||
const PseudoRandom& getItem() const;
|
|
||||||
PseudoRandom& getItem();
|
|
||||||
|
|
||||||
// LuaPseudoRandom(seed)
|
// LuaPseudoRandom(seed)
|
||||||
// Creates an LuaPseudoRandom and leaves it on top of stack
|
// Creates an LuaPseudoRandom and leaves it on top of stack
|
||||||
static int create_object(lua_State *L);
|
static int create_object(lua_State *L);
|
||||||
|
|
||||||
static LuaPseudoRandom* checkobject(lua_State *L, int narg);
|
static LuaPseudoRandom *checkobject(lua_State *L, int narg);
|
||||||
|
|
||||||
|
static void Register(lua_State *L);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
LuaPcgRandom
|
||||||
|
*/
|
||||||
|
class LuaPcgRandom : public ModApiBase {
|
||||||
|
private:
|
||||||
|
PcgRandom m_rnd;
|
||||||
|
|
||||||
|
static const char className[];
|
||||||
|
static const luaL_reg methods[];
|
||||||
|
|
||||||
|
// Exported functions
|
||||||
|
|
||||||
|
// garbage collector
|
||||||
|
static int gc_object(lua_State *L);
|
||||||
|
|
||||||
|
// next(self, min=-2147483648, max=2147483647) -> get next value
|
||||||
|
static int l_next(lua_State *L);
|
||||||
|
|
||||||
|
// rand_normal_dist(self, min=-2147483648, max=2147483647, num_trials=6) ->
|
||||||
|
// get next normally distributed random value
|
||||||
|
static int l_rand_normal_dist(lua_State *L);
|
||||||
|
|
||||||
|
public:
|
||||||
|
LuaPcgRandom(u64 seed) :
|
||||||
|
m_rnd(seed) {}
|
||||||
|
LuaPcgRandom(u64 seed, u64 seq) :
|
||||||
|
m_rnd(seed, seq) {}
|
||||||
|
|
||||||
|
// LuaPcgRandom(seed)
|
||||||
|
// Creates an LuaPcgRandom and leaves it on top of stack
|
||||||
|
static int create_object(lua_State *L);
|
||||||
|
|
||||||
|
static LuaPcgRandom *checkobject(lua_State *L, int narg);
|
||||||
|
|
||||||
static void Register(lua_State *L);
|
static void Register(lua_State *L);
|
||||||
};
|
};
|
||||||
|
@@ -29,8 +29,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "content_sao.h"
|
#include "content_sao.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
#include "settings.h"
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct EnumString es_HudElementType[] =
|
struct EnumString es_HudElementType[] =
|
||||||
@@ -257,10 +255,10 @@ int ObjectRef::l_set_hp(lua_State *L)
|
|||||||
ObjectRef *ref = checkobject(L, 1);
|
ObjectRef *ref = checkobject(L, 1);
|
||||||
luaL_checknumber(L, 2);
|
luaL_checknumber(L, 2);
|
||||||
ServerActiveObject *co = getobject(ref);
|
ServerActiveObject *co = getobject(ref);
|
||||||
if(co == NULL)
|
if(co == NULL) return 0;
|
||||||
return 0;
|
|
||||||
int hp = lua_tonumber(L, 2);
|
int hp = lua_tonumber(L, 2);
|
||||||
|
/*infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
|
||||||
|
<<" hp="<<hp<<std::endl;*/
|
||||||
// Do it
|
// Do it
|
||||||
co->setHP(hp);
|
co->setHP(hp);
|
||||||
if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
|
if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
|
||||||
@@ -291,38 +289,6 @@ int ObjectRef::l_get_hp(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply_damage(self, damage)
|
|
||||||
// damage = amount of damage to apply
|
|
||||||
// if damage is negative, heal the player
|
|
||||||
// returns: nil
|
|
||||||
int ObjectRef::l_apply_damage(lua_State *L)
|
|
||||||
{
|
|
||||||
NO_MAP_LOCK_REQUIRED;
|
|
||||||
ObjectRef *ref = checkobject(L, 1);
|
|
||||||
luaL_checknumber(L, 2);
|
|
||||||
ServerActiveObject *co = getobject(ref);
|
|
||||||
if(co == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int damage = lua_tonumber(L, 2);
|
|
||||||
|
|
||||||
// No damage, no heal => do nothing
|
|
||||||
if (damage == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// If damage is positive (not healing) and damage is disabled, ignore
|
|
||||||
if (damage > 0 && g_settings->getBool("enable_damage") == false)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Do damage/heal
|
|
||||||
co->setHP(co->getHP() - damage);
|
|
||||||
if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
|
|
||||||
getServer(L)->SendPlayerHPOrDie(((PlayerSAO*)co)->getPeerID(), co->getHP() == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_inventory(self)
|
// get_inventory(self)
|
||||||
int ObjectRef::l_get_inventory(lua_State *L)
|
int ObjectRef::l_get_inventory(lua_State *L)
|
||||||
{
|
{
|
||||||
@@ -1379,7 +1345,6 @@ const luaL_reg ObjectRef::methods[] = {
|
|||||||
luamethod(ObjectRef, right_click),
|
luamethod(ObjectRef, right_click),
|
||||||
luamethod(ObjectRef, set_hp),
|
luamethod(ObjectRef, set_hp),
|
||||||
luamethod(ObjectRef, get_hp),
|
luamethod(ObjectRef, get_hp),
|
||||||
luamethod(ObjectRef, apply_damage),
|
|
||||||
luamethod(ObjectRef, get_inventory),
|
luamethod(ObjectRef, get_inventory),
|
||||||
luamethod(ObjectRef, get_wield_list),
|
luamethod(ObjectRef, get_wield_list),
|
||||||
luamethod(ObjectRef, get_wield_index),
|
luamethod(ObjectRef, get_wield_index),
|
||||||
|
@@ -83,12 +83,6 @@ private:
|
|||||||
// 0 if not applicable to this type of object
|
// 0 if not applicable to this type of object
|
||||||
static int l_get_hp(lua_State *L);
|
static int l_get_hp(lua_State *L);
|
||||||
|
|
||||||
// apply_damage(self, damage)
|
|
||||||
// damage = amount of damage to apply
|
|
||||||
// if damage is negative, heal the player
|
|
||||||
// returns: nil
|
|
||||||
static int l_apply_damage(lua_State *L);
|
|
||||||
|
|
||||||
// get_inventory(self)
|
// get_inventory(self)
|
||||||
static int l_get_inventory(lua_State *L);
|
static int l_get_inventory(lua_State *L);
|
||||||
|
|
||||||
|
@@ -92,6 +92,7 @@ void GameScripting::InitializeModApi(lua_State *L, int top)
|
|||||||
LuaPerlinNoise::Register(L);
|
LuaPerlinNoise::Register(L);
|
||||||
LuaPerlinNoiseMap::Register(L);
|
LuaPerlinNoiseMap::Register(L);
|
||||||
LuaPseudoRandom::Register(L);
|
LuaPseudoRandom::Register(L);
|
||||||
|
LuaPcgRandom::Register(L);
|
||||||
LuaVoxelManip::Register(L);
|
LuaVoxelManip::Register(L);
|
||||||
NodeMetaRef::Register(L);
|
NodeMetaRef::Register(L);
|
||||||
NodeTimerRef::Register(L);
|
NodeTimerRef::Register(L);
|
||||||
|
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "../constants.h" // BS, MAP_BLOCKSIZE
|
#include "../constants.h" // BS, MAP_BLOCKSIZE
|
||||||
|
#include "../noise.h" // PseudoRandom, PcgRandom
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@@ -115,36 +116,32 @@ void FacePositionCache::generateFacePosition(u16 d)
|
|||||||
myrand
|
myrand
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static unsigned long next = 1;
|
PcgRandom g_pcgrand;
|
||||||
|
|
||||||
/* RAND_MAX assumed to be 32767 */
|
u32 myrand()
|
||||||
int myrand(void)
|
|
||||||
{
|
{
|
||||||
next = next * 1103515245 + 12345;
|
return g_pcgrand.next();
|
||||||
return((unsigned)(next/65536) % 32768);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mysrand(unsigned seed)
|
void mysrand(unsigned int seed)
|
||||||
{
|
{
|
||||||
next = seed;
|
g_pcgrand.seed(seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void myrand_bytes(void *out, size_t len)
|
||||||
|
{
|
||||||
|
g_pcgrand.bytes(out, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int myrand_range(int min, int max)
|
int myrand_range(int min, int max)
|
||||||
{
|
{
|
||||||
if(max-min > MYRAND_MAX)
|
return g_pcgrand.range(min, max);
|
||||||
{
|
|
||||||
errorstream<<"WARNING: myrand_range: max-min > MYRAND_MAX"<<std::endl;
|
|
||||||
max = min + MYRAND_MAX;
|
|
||||||
}
|
|
||||||
if(min > max)
|
|
||||||
{
|
|
||||||
errorstream<<"WARNING: myrand_range: min > max"<<std::endl;
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
return (myrand()%(max-min+1))+min;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 64-bit unaligned version of MurmurHash
|
|
||||||
|
/*
|
||||||
|
64-bit unaligned version of MurmurHash
|
||||||
|
*/
|
||||||
u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed)
|
u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed)
|
||||||
{
|
{
|
||||||
const u64 m = 0xc6a4a7935bd1e995ULL;
|
const u64 m = 0xc6a4a7935bd1e995ULL;
|
||||||
@@ -159,12 +156,12 @@ u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed)
|
|||||||
memcpy(&k, data, sizeof(u64));
|
memcpy(&k, data, sizeof(u64));
|
||||||
data++;
|
data++;
|
||||||
|
|
||||||
k *= m;
|
k *= m;
|
||||||
k ^= k >> r;
|
k ^= k >> r;
|
||||||
k *= m;
|
k *= m;
|
||||||
|
|
||||||
h ^= k;
|
h ^= k;
|
||||||
h *= m;
|
h *= m;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char *data2 = (const unsigned char *)data;
|
const unsigned char *data2 = (const unsigned char *)data;
|
||||||
@@ -178,13 +175,13 @@ u64 murmur_hash_64_ua(const void *key, int len, unsigned int seed)
|
|||||||
case 1: h ^= (u64)data2[0];
|
case 1: h ^= (u64)data2[0];
|
||||||
h *= m;
|
h *= m;
|
||||||
}
|
}
|
||||||
|
|
||||||
h ^= h >> r;
|
h ^= h >> r;
|
||||||
h *= m;
|
h *= m;
|
||||||
h ^= h >> r;
|
h ^= h >> r;
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -197,7 +194,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
|
|||||||
f32 camera_fov, f32 range, f32 *distance_ptr)
|
f32 camera_fov, f32 range, f32 *distance_ptr)
|
||||||
{
|
{
|
||||||
v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE;
|
v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE;
|
||||||
|
|
||||||
// Block center position
|
// Block center position
|
||||||
v3f blockpos(
|
v3f blockpos(
|
||||||
((float)blockpos_nodes.X + MAP_BLOCKSIZE/2) * BS,
|
((float)blockpos_nodes.X + MAP_BLOCKSIZE/2) * BS,
|
||||||
@@ -213,7 +210,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
|
|||||||
|
|
||||||
if(distance_ptr)
|
if(distance_ptr)
|
||||||
*distance_ptr = d;
|
*distance_ptr = d;
|
||||||
|
|
||||||
// If block is far away, it's not in sight
|
// If block is far away, it's not in sight
|
||||||
if(d > range)
|
if(d > range)
|
||||||
return false;
|
return false;
|
||||||
@@ -221,7 +218,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
|
|||||||
// Maximum radius of a block. The magic number is
|
// Maximum radius of a block. The magic number is
|
||||||
// sqrt(3.0) / 2.0 in literal form.
|
// sqrt(3.0) / 2.0 in literal form.
|
||||||
f32 block_max_radius = 0.866025403784 * MAP_BLOCKSIZE * BS;
|
f32 block_max_radius = 0.866025403784 * MAP_BLOCKSIZE * BS;
|
||||||
|
|
||||||
// If block is (nearly) touching the camera, don't
|
// If block is (nearly) touching the camera, don't
|
||||||
// bother validating further (that is, render it anyway)
|
// bother validating further (that is, render it anyway)
|
||||||
if(d < block_max_radius)
|
if(d < block_max_radius)
|
||||||
@@ -242,7 +239,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
|
|||||||
// Cosine of the angle between the camera direction
|
// Cosine of the angle between the camera direction
|
||||||
// and the block direction (camera_dir is an unit vector)
|
// and the block direction (camera_dir is an unit vector)
|
||||||
f32 cosangle = dforward / blockpos_adj.getLength();
|
f32 cosangle = dforward / blockpos_adj.getLength();
|
||||||
|
|
||||||
// If block is not in the field of view, skip it
|
// If block is not in the field of view, skip it
|
||||||
if(cosangle < cos(camera_fov / 2))
|
if(cosangle < cos(camera_fov / 2))
|
||||||
return false;
|
return false;
|
||||||
|
@@ -239,10 +239,10 @@ inline float wrapDegrees_180(float f)
|
|||||||
/*
|
/*
|
||||||
Pseudo-random (VC++ rand() sucks)
|
Pseudo-random (VC++ rand() sucks)
|
||||||
*/
|
*/
|
||||||
int myrand(void);
|
#define MYRAND_RANGE 0xffffffff
|
||||||
void mysrand(unsigned seed);
|
u32 myrand();
|
||||||
#define MYRAND_MAX 32767
|
void mysrand(unsigned int seed);
|
||||||
|
void myrand_bytes(void *out, size_t len);
|
||||||
int myrand_range(int min, int max);
|
int myrand_range(int min, int max);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user