add 'place_structures_wide' callback
This commit is contained in:
parent
6e0304248b
commit
a578cca325
@ -26,16 +26,26 @@ end
|
|||||||
function place_structures(x, z, w, d, seed, hmap, chunk_height)
|
function place_structures(x, z, w, d, seed, hmap, chunk_height)
|
||||||
local placements = {}
|
local placements = {}
|
||||||
place_ores(placements, x, z, w, d, seed, hmap, chunk_height)
|
place_ores(placements, x, z, w, d, seed, hmap, chunk_height)
|
||||||
|
return placements
|
||||||
|
end
|
||||||
|
|
||||||
|
function place_structures_wide(x, z, w, d, seed, chunk_height)
|
||||||
|
local placements = {}
|
||||||
if math.random() < 0.1 then -- generate caves
|
if math.random() < 0.1 then -- generate caves
|
||||||
local sy = math.random() * (chunk_height / 2)
|
local sy = math.random() * (chunk_height / 6) + 80
|
||||||
local ey = math.random() * (chunk_height / 2)
|
local ey = math.max(1, sy - chunk_height / 4)
|
||||||
local sx = x + math.random() * 20 - 10
|
local my = (sy + ey) / 2 + math.random() * 24 - 12
|
||||||
local ex = x + math.random() * 20 - 10
|
local sx = x + math.random() * 60 - 30
|
||||||
local sz = z + math.random() * 20 - 10
|
local ex = x + math.random() * 60 - 30
|
||||||
local ez = z + math.random() * 20 - 10
|
local mx = (sx + ex) / 2 + math.random() * 32 - 16
|
||||||
|
local sz = z + math.random() * 60 - 30
|
||||||
|
local ez = z + math.random() * 60 - 30
|
||||||
|
local mz = (sz + ez) / 2 + math.random() * 32 - 16
|
||||||
|
local width = math.random()*3+2
|
||||||
table.insert(placements,
|
table.insert(placements,
|
||||||
{":line", 0, {sx - 10, sy, sz - 10}, {ex + 10, ey, ez + 10}, math.random()*2+2})
|
{":line", 0, {sx, sy, sz}, {mx, my, mz}, width})
|
||||||
|
table.insert(placements,
|
||||||
|
{":line", 0, {mx, my, mz}, {ex, ey, ez}, width})
|
||||||
end
|
end
|
||||||
return placements
|
return placements
|
||||||
end
|
end
|
||||||
|
|||||||
@ -135,6 +135,36 @@ public:
|
|||||||
placements.structs.emplace_back(structIndex, pos, rotation);
|
placements.structs.emplace_back(structIndex, pos, rotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PrototypePlacements placeStructuresWide(
|
||||||
|
const glm::ivec2& offset,
|
||||||
|
const glm::ivec2& size,
|
||||||
|
uint64_t seed,
|
||||||
|
uint chunkHeight
|
||||||
|
) override {
|
||||||
|
PrototypePlacements placements {};
|
||||||
|
|
||||||
|
stackguard _(L);
|
||||||
|
pushenv(L, *env);
|
||||||
|
if (getfield(L, "place_structures_wide")) {
|
||||||
|
pushivec_stack(L, offset);
|
||||||
|
pushivec_stack(L, size);
|
||||||
|
pushinteger(L, seed);
|
||||||
|
pushinteger(L, chunkHeight);
|
||||||
|
if (call_nothrow(L, 6, 1)) {
|
||||||
|
int len = objlen(L, -1);
|
||||||
|
for (int i = 1; i <= len; i++) {
|
||||||
|
rawgeti(L, i);
|
||||||
|
|
||||||
|
perform_placement(L, placements);
|
||||||
|
|
||||||
|
pop(L);
|
||||||
|
}
|
||||||
|
pop(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return placements;
|
||||||
|
}
|
||||||
|
|
||||||
PrototypePlacements placeStructures(
|
PrototypePlacements placeStructures(
|
||||||
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed,
|
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed,
|
||||||
const std::shared_ptr<Heightmap>& heightmap, uint chunkHeight
|
const std::shared_ptr<Heightmap>& heightmap, uint chunkHeight
|
||||||
|
|||||||
@ -154,6 +154,13 @@ public:
|
|||||||
uint bpd
|
uint bpd
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
|
virtual PrototypePlacements placeStructuresWide(
|
||||||
|
const glm::ivec2& offset,
|
||||||
|
const glm::ivec2& size,
|
||||||
|
uint64_t seed,
|
||||||
|
uint chunkHeight
|
||||||
|
) = 0;
|
||||||
|
|
||||||
/// @brief Generate a list of structures placements. Structures may be
|
/// @brief Generate a list of structures placements. Structures may be
|
||||||
/// placed to nearest chunks also (position of out area).
|
/// placed to nearest chunks also (position of out area).
|
||||||
/// @param offset position of the area
|
/// @param offset position of the area
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
static debug::Logger logger("world-generator");
|
static debug::Logger logger("world-generator");
|
||||||
|
|
||||||
static inline constexpr uint MAX_PARAMETERS = 4;
|
static inline constexpr uint MAX_PARAMETERS = 4;
|
||||||
static inline constexpr uint MAX_CHUNK_PROTOTYPE_LEVELS = 5;
|
static inline constexpr uint MAX_CHUNK_PROTOTYPE_LEVELS = 10;
|
||||||
|
|
||||||
WorldGenerator::WorldGenerator(
|
WorldGenerator::WorldGenerator(
|
||||||
const GeneratorDef& def, const Content* content, uint64_t seed
|
const GeneratorDef& def, const Content* content, uint64_t seed
|
||||||
@ -41,13 +41,16 @@ WorldGenerator::WorldGenerator(
|
|||||||
}
|
}
|
||||||
prototypes[{x, z}] = generatePrototype(x, z);
|
prototypes[{x, z}] = generatePrototype(x, z);
|
||||||
});
|
});
|
||||||
surroundMap.setLevelCallback(2, [this](int const x, int const z) {
|
surroundMap.setLevelCallback(4, [this](int const x, int const z) {
|
||||||
|
generateStructuresWide(requirePrototype(x, z), x, z);
|
||||||
|
});
|
||||||
|
surroundMap.setLevelCallback(7, [this](int const x, int const z) {
|
||||||
generateBiomes(requirePrototype(x, z), x, z);
|
generateBiomes(requirePrototype(x, z), x, z);
|
||||||
});
|
});
|
||||||
surroundMap.setLevelCallback(3, [this](int const x, int const z) {
|
surroundMap.setLevelCallback(8, [this](int const x, int const z) {
|
||||||
generateHeightmap(requirePrototype(x, z), x, z);
|
generateHeightmap(requirePrototype(x, z), x, z);
|
||||||
});
|
});
|
||||||
surroundMap.setLevelCallback(4, [this](int const x, int const z) {
|
surroundMap.setLevelCallback(9, [this](int const x, int const z) {
|
||||||
generateStructures(requirePrototype(x, z), x, z);
|
generateStructures(requirePrototype(x, z), x, z);
|
||||||
});
|
});
|
||||||
for (int i = 0; i < def.structures.size(); i++) {
|
for (int i = 0; i < def.structures.size(); i++) {
|
||||||
@ -183,6 +186,41 @@ void WorldGenerator::placeLine(const LinePlacement& line) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldGenerator::placeStructures(
|
||||||
|
const PrototypePlacements& placements,
|
||||||
|
ChunkPrototype& prototype,
|
||||||
|
int chunkX,
|
||||||
|
int chunkZ
|
||||||
|
) {
|
||||||
|
util::concat(prototype.structures, placements.structs);
|
||||||
|
for (const auto& placement : prototype.structures) {
|
||||||
|
const auto& offset = placement.position;
|
||||||
|
if (placement.structure < 0 || placement.structure >= def.structures.size()) {
|
||||||
|
logger.error() << "invalid structure index " << placement.structure;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
placeStructure(
|
||||||
|
offset, placement.structure, placement.rotation, chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
for (const auto& line : placements.lines) {
|
||||||
|
placeLine(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldGenerator::generateStructuresWide(
|
||||||
|
ChunkPrototype& prototype, int chunkX, int chunkZ
|
||||||
|
) {
|
||||||
|
if (prototype.level >= ChunkPrototypeLevel::WIDE_STRUCTS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto placements = def.script->placeStructuresWide(
|
||||||
|
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed, CHUNK_H
|
||||||
|
);
|
||||||
|
placeStructures(placements, prototype, chunkX, chunkZ);
|
||||||
|
|
||||||
|
prototype.level = ChunkPrototypeLevel::WIDE_STRUCTS;
|
||||||
|
}
|
||||||
|
|
||||||
void WorldGenerator::generateStructures(
|
void WorldGenerator::generateStructures(
|
||||||
ChunkPrototype& prototype, int chunkX, int chunkZ
|
ChunkPrototype& prototype, int chunkX, int chunkZ
|
||||||
) {
|
) {
|
||||||
@ -196,20 +234,7 @@ void WorldGenerator::generateStructures(
|
|||||||
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed,
|
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed,
|
||||||
heightmap, CHUNK_H
|
heightmap, CHUNK_H
|
||||||
);
|
);
|
||||||
util::concat(prototype.structures, placements.structs);
|
placeStructures(placements, prototype, chunkX, chunkZ);
|
||||||
|
|
||||||
for (const auto& placement : prototype.structures) {
|
|
||||||
const auto& offset = placement.position;
|
|
||||||
if (placement.structure < 0 || placement.structure >= def.structures.size()) {
|
|
||||||
logger.error() << "invalid structure index " << placement.structure;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
placeStructure(
|
|
||||||
offset, placement.structure, placement.rotation, chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
for (const auto& line : placements.lines) {
|
|
||||||
placeLine(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
util::PseudoRandom structsRand;
|
util::PseudoRandom structsRand;
|
||||||
structsRand.setSeed(chunkX, chunkZ);
|
structsRand.setSeed(chunkX, chunkZ);
|
||||||
|
|||||||
@ -17,9 +17,10 @@ struct GeneratorDef;
|
|||||||
class Heightmap;
|
class Heightmap;
|
||||||
struct Biome;
|
struct Biome;
|
||||||
class VoxelFragment;
|
class VoxelFragment;
|
||||||
|
struct PrototypePlacements;
|
||||||
|
|
||||||
enum class ChunkPrototypeLevel {
|
enum class ChunkPrototypeLevel {
|
||||||
VOID=0, BIOMES, HEIGHTMAP, STRUCTURES
|
VOID=0, WIDE_STRUCTS, BIOMES, HEIGHTMAP, STRUCTURES
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ChunkPrototype {
|
struct ChunkPrototype {
|
||||||
@ -64,6 +65,8 @@ class WorldGenerator {
|
|||||||
|
|
||||||
ChunkPrototype& requirePrototype(int x, int z);
|
ChunkPrototype& requirePrototype(int x, int z);
|
||||||
|
|
||||||
|
void generateStructuresWide(ChunkPrototype& prototype, int x, int z);
|
||||||
|
|
||||||
void generateStructures(ChunkPrototype& prototype, int x, int z);
|
void generateStructures(ChunkPrototype& prototype, int x, int z);
|
||||||
|
|
||||||
void generateBiomes(ChunkPrototype& prototype, int x, int z);
|
void generateBiomes(ChunkPrototype& prototype, int x, int z);
|
||||||
@ -99,6 +102,11 @@ class WorldGenerator {
|
|||||||
int z,
|
int z,
|
||||||
const Biome** biomes
|
const Biome** biomes
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void placeStructures(
|
||||||
|
const PrototypePlacements& placements,
|
||||||
|
ChunkPrototype& prototype,
|
||||||
|
int x, int z);
|
||||||
public:
|
public:
|
||||||
WorldGenerator(
|
WorldGenerator(
|
||||||
const GeneratorDef& def,
|
const GeneratorDef& def,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user