From 86bdfeb6c4bf4b61d49034177ff20ff30da52ce5 Mon Sep 17 00:00:00 2001 From: darkrose Date: Wed, 19 Jul 2017 02:06:40 +1000 Subject: [PATCH] boulders and meteors --- src/CMakeLists.txt | 1 + src/mapgen.h | 6 +++- src/mapgen/mapgen.cpp | 59 +++++++++++++++++++++++++++++---- src/mapgen/mapgen_rocks.cpp | 66 +++++++++++++++++++++++++++++++++++++ src/mapgen/mapgen_space.cpp | 45 ++++++------------------- src/mapgen/mapgen_util.cpp | 45 +++++++++++++++++-------- 6 files changed, 167 insertions(+), 55 deletions(-) create mode 100644 src/mapgen/mapgen_rocks.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5ebbdad..0ff24c8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -198,6 +198,7 @@ set(common_SRCS content_sao.cpp mapgen/mapgen.cpp mapgen/mapgen_trees.cpp + mapgen/mapgen_rocks.cpp mapgen/mapgen_plants.cpp mapgen/mapgen_dungeon.cpp mapgen/mapgen_util.cpp diff --git a/src/mapgen.h b/src/mapgen.h index 36110d6..e68f82d 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -28,6 +28,7 @@ #include "common_irrlicht.h" #include "utility.h" // UniqueQueue +#include "mapnode.h" class MapBlock; class ManualMapVoxelManipulator; @@ -97,6 +98,9 @@ namespace mapgen void make_largetree(ManualMapVoxelManipulator &vmanip, v3s16 p0); void make_jungletree(ManualMapVoxelManipulator &vmanip, v3s16 p0); + /* defined in mapgen_rocks.cpp */ + void make_boulder(ManualMapVoxelManipulator &vmanip, v3s16 pos, uint16_t size, content_t inner, content_t outer, content_t replace); + /* defined in mapgen_dungeon.cpp */ void make_dungeon(BlockMakeData *data, uint32_t blockseed); @@ -110,10 +114,10 @@ namespace mapgen int16_t get_ground_height(uint64_t seed, v2s16 p); uint32_t get_tree_density(BlockMakeData *data, v2s16 p); uint32_t get_grass_density(BlockMakeData *data, v2s16 p); + uint32_t get_boulder_density(BlockMakeData *data, v2s16 p); bool is_cave(uint64_t seed, v3s16 p); double debris_amount_2d(uint64_t seed, v2s16 p); - double largestone_amount_2d(uint64_t seed, v2s16 p); s16 find_ground_level_from_noise(BlockMakeData *data, v2s16 p2d, s16 precision); double get_sector_average_ground_level(BlockMakeData *data, v2s16 sectorpos); double get_sector_maximum_ground_level(BlockMakeData *data, v2s16 sectorpos); diff --git a/src/mapgen/mapgen.cpp b/src/mapgen/mapgen.cpp index 0043824..c71a76e 100644 --- a/src/mapgen/mapgen.cpp +++ b/src/mapgen/mapgen.cpp @@ -530,9 +530,55 @@ void make_block(BlockMakeData *data) } } + /* add boulders */ + u32 boulder_count = get_boulder_density(data, p2d_center); + if (boulder_count) { + PseudoRandom boulderrandom(blockseed); + // Put trees in random places on part of division + for (u32 i=0; i node_max.Y) + continue; + /* + Find exact ground level + */ + v3s16 p(x,y+6,z); + bool found = false; + for (; p.Y >= y-6; p.Y--) { + u32 i = data->vmanip->m_area.index(p); + MapNode *n = &data->vmanip->m_data[i]; + if (n->getContent() != CONTENT_AIR && n->getContent() != CONTENT_WATERSOURCE && n->getContent() != CONTENT_IGNORE) { + found = true; + break; + } + } + // If not found, handle next one + if (found == false) + continue; + + { + u32 i = data->vmanip->m_area.index(p); + MapNode *n = &data->vmanip->m_data[i]; + + if (n->getContent() == CONTENT_MUD || n->getContent() == CONTENT_CLAY) { + if (data->biome == BIOME_WASTELANDS) { + p.Y++; + make_boulder(vmanip,p,3,CONTENT_SPACEROCK,CONTENT_SPACEROCK,CONTENT_IGNORE); + }else{ + make_boulder(vmanip,p,2,CONTENT_STONE,CONTENT_STONE,CONTENT_IGNORE); + } + } + } + } + } + /* add trees */ u32 tree_count = get_tree_density(data, p2d_center); - if (tree_count) { + if (tree_count) { PseudoRandom treerandom(blockseed); // Put trees in random places on part of division for (u32 i=0; i= y-6; p.Y--) { u32 i = data->vmanip->m_area.index(p); MapNode *n = &data->vmanip->m_data[i]; - if (content_features(*n).is_ground_content || n->getContent() == CONTENT_JUNGLETREE) { + if ( + n->getContent() == CONTENT_MUD + || n->getContent() == CONTENT_CLAY + || n->getContent() == CONTENT_SAND + || n->getContent() == CONTENT_JUNGLETREE + ) { found = true; break; } @@ -671,10 +722,6 @@ void make_block(BlockMakeData *data) } } } - - if (data->biome == BIOME_WASTELANDS) { - /* fallen meteor */ - } } } diff --git a/src/mapgen/mapgen_rocks.cpp b/src/mapgen/mapgen_rocks.cpp new file mode 100644 index 0000000..1b886e9 --- /dev/null +++ b/src/mapgen/mapgen_rocks.cpp @@ -0,0 +1,66 @@ +/************************************************************************ +* Minetest-c55 +* Copyright (C) 2010-2011 celeron55, Perttu Ahola +* +* mapgen.cpp +* voxelands - 3d voxel world sandbox game +* Copyright (C) Lisa 'darkrose' Milne 2014-2017 +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see +* +* License updated from GPLv2 or later to GPLv3 or later by Lisa Milne +* for Voxelands. +************************************************************************/ + +#include "mapgen.h" +#include "voxel.h" +#include "content_mapnode.h" +#include "map.h" + +namespace mapgen +{ + +void make_boulder(ManualMapVoxelManipulator &vmanip, v3s16 pos, uint16_t size, content_t inner, content_t outer, content_t replace) +{ + int edge; + int16_t min = -size; + int16_t max = size; + + for (s16 x=min; x<=max; x++) { + for (s16 y=min; y<=max; y++) { + for (s16 z=min; z<=max; z++) { + edge = 0; + if (x == min || x == max) + edge++; + if (y == min || y == max) + edge++; + if (z == min || z == max) + edge++; + + if (edge > 1) + continue; + u32 vi = vmanip.m_area.index(pos+v3s16(x,y,z)); + if (replace != CONTENT_IGNORE && vmanip.m_data[vi].getContent() != replace) + continue; + if (edge) { + vmanip.m_data[vi] = MapNode(outer); + continue; + } + vmanip.m_data[vi] = MapNode(inner); + } + } + } +} + +} diff --git a/src/mapgen/mapgen_space.cpp b/src/mapgen/mapgen_space.cpp index e2e0f83..88e36c3 100644 --- a/src/mapgen/mapgen_space.cpp +++ b/src/mapgen/mapgen_space.cpp @@ -126,54 +126,29 @@ void make_space(BlockMakeData *data) u16 comet_size = debris_amount-11; if (comet_size > 5) comet_size = 5; - s16 comet_min = -comet_size; - s16 comet_max = comet_size; - MapNode new_content(CONTENT_SPACEROCK); + content_t inner = CONTENT_SPACEROCK; float mineral_noise = noisebuf_mineral.get(pos.X,pos.Y,pos.Z); if (mineral_noise < -0.5) { - new_content = MapNode(CONTENT_LAVASOURCE); + inner = CONTENT_LAVASOURCE;; }else if (mineral_noise < -0.3) { - new_content = MapNode(CONTENT_ICE); + inner = CONTENT_ICE;; }else if (mineral_noise < -0.1) { - new_content = MapNode(CONTENT_STEEL); + inner = CONTENT_STEEL;; }else if (mineral_noise > 0.4) { - new_content = MapNode(CONTENT_SILVER); + inner = CONTENT_SILVER;; }else if (mineral_noise > 0.3) { - new_content = MapNode(CONTENT_MITHRIL_BLOCK); + inner = CONTENT_MITHRIL_BLOCK;; }else if (mineral_noise > 0.2) { - new_content = MapNode(CONTENT_COPPER); + inner = CONTENT_COPPER;; }else if (mineral_noise > 0.1) { - new_content = MapNode(CONTENT_TIN); + inner = CONTENT_TIN;; }else if (mineral_noise > 0.0) { - new_content = MapNode(CONTENT_GOLD); + inner = CONTENT_GOLD;; } - for (s16 x=comet_min; x<=comet_max; x++) { - for (s16 y=comet_min; y<=comet_max; y++) { - for (s16 z=comet_min; z<=comet_max; z++) { - int edge = 0; - if (x == comet_min || x == comet_max) - edge++; - if (y == comet_min || y == comet_max) - edge++; - if (z == comet_min || z == comet_max) - edge++; - - if (edge > 1) - continue; - u32 vi = vmanip.m_area.index(pos+v3s16(x,y,z)); - if (vmanip.m_data[vi].getContent() != CONTENT_VACUUM) - continue; - if (edge) { - vmanip.m_data[vi] = MapNode(CONTENT_SPACEROCK); - continue; - } - vmanip.m_data[vi] = new_content; - } - } - } + make_boulder(vmanip,pos,comet_size,inner,CONTENT_SPACEROCK,CONTENT_VACUUM); } } diff --git a/src/mapgen/mapgen_util.cpp b/src/mapgen/mapgen_util.cpp index 386fc91..31cb0a1 100644 --- a/src/mapgen/mapgen_util.cpp +++ b/src/mapgen/mapgen_util.cpp @@ -125,7 +125,7 @@ uint32_t get_tree_density(BlockMakeData *data, v2s16 p) }else if (data->biome == BIOME_LAKE || data->biome == BIOME_SNOWCAP || data->biome == BIOME_WOODLANDS) { if (r < 1) r = 5; - }else if (data->biome == BIOME_PLAINS|| data->biome == BIOME_WASTELANDS) { + }else if (data->biome == BIOME_PLAINS) { if (r) r /= 5; } @@ -170,6 +170,37 @@ uint32_t get_grass_density(BlockMakeData *data, v2s16 p) return r*3; } +uint32_t get_boulder_density(BlockMakeData *data, v2s16 p) +{ + double zeroval = 0.3; + double density = 0.0; + double factor = 500.0; + double noise = 0.0; + uint32_t r = 0; + + if (data->biome == BIOME_DESERT || data->biome == BIOME_SNOWCAP || data->biome == BIOME_OCEAN || data->biome == BIOME_BEACH) + return 0; + if (data->biome == BIOME_WASTELANDS) + factor = 200.0; + if (data->biome == BIOME_WOODLANDS) + factor = 250.0; + + noise = noise2d_perlin( + 0.5+(float)p.X/factor, + 0.5+(float)p.Y/factor, + data->seed+14143242, + 4, + 0.66 + ); + + if (noise >= zeroval) { + density = 0.005 * (noise-zeroval) / (1.0-zeroval); + r = density*(double)(MAP_BLOCKSIZE*MAP_BLOCKSIZE); + } + + return !!r; +} + // used in space double debris_amount_2d(uint64_t seed, v2s16 p) { @@ -187,18 +218,6 @@ double debris_amount_2d(uint64_t seed, v2s16 p) return 0.037 * (noise-zeroval) / (1.0-zeroval); } -double largestone_amount_2d(uint64_t seed, v2s16 p) -{ - double noise = noise2d_perlin( - 0.5+(float)p.X/250, 0.5+(float)p.Y/250, - seed+14143242, 5, 0.66); - double zeroval = 0.3; - if(noise < zeroval) - return 0; - else - return 0.005 * (noise-zeroval) / (1.0-zeroval); -} - /* Incrementally find ground level from 3d noise */