diff --git a/src/test/TestCustomDimension.cpp b/src/test/TestCustomDimension.cpp index 0ec0b7d..7cb511c 100644 --- a/src/test/TestCustomDimension.cpp +++ b/src/test/TestCustomDimension.cpp @@ -1,4 +1,5 @@ #include "test/generator/flat-gen-village/FlatVillageDimension.h" +#include "test/generator/generator-custom-structure/dimension/CustomStructureDimension.h" #include "test/generator/generator-terrain/NxnBorderTerrainDimension.h" #include "ll/api/event/EventBus.h" @@ -10,21 +11,40 @@ static bool reg = [] { using namespace ll::event; EventBus::getInstance().emplaceListener([](ServerStartedEvent&) { + // simplate dimension test + // vanilla overworld type dimension test more_dimensions::CustomDimensionManager::getInstance().addDimension( "testNewDimension" ); + + // vanilla flat type dimension test more_dimensions::CustomDimensionManager::getInstance() .addDimension("testNewFlatDimension", 345, GeneratorType::Flat); + + // vanilla nether type dimension test more_dimensions::CustomDimensionManager::getInstance() .addDimension("testNewNetherDimension", 345, GeneratorType::Nether); + + // vanilla the end type dimension test more_dimensions::CustomDimensionManager::getInstance() .addDimension("testNewTheEndDimension", 345, GeneratorType::TheEnd); + + // vanilla void dimension test more_dimensions::CustomDimensionManager::getInstance() .addDimension("testNewVoidDimension", 345, GeneratorType::Void); + + // custom diomension test + // flat type generator village dimension test more_dimensions::CustomDimensionManager::getInstance() .addDimension("testFlatVillage"); + + // flat type custom terrain dimension test more_dimensions::CustomDimensionManager::getInstance() .addDimension("testFlatTerrain", 5); + + // flat type custom structure dimension test + more_dimensions::CustomDimensionManager::getInstance() + .addDimension("testCustomStructure"); }); return true; }(); diff --git a/src/test/generator/generator-custom-structure/CustomStructure.cpp b/src/test/generator/generator-custom-structure/CustomStructure.cpp new file mode 100644 index 0000000..878b1e3 --- /dev/null +++ b/src/test/generator/generator-custom-structure/CustomStructure.cpp @@ -0,0 +1,146 @@ +#include "CustomStructure.h" + +#include "ll/api/memory/Hook.h" + +#include "mc/deps/core/threading/WorkerPool.h" +#include "mc/resources/BaseGameVersion.h" +#include "mc/world/level/block/VanillaBlockTypeIds.h" +#include "mc/world/level/block/registry/BlockTypeRegistry.h" +#include "mc/world/level/levelgen/feature/registry/FeatureRegistry.h" +#include "mc/world/level/levelgen/structure/Projection.h" +#include "mc/world/level/levelgen/structure/StructureManager.h" +#include "mc/world/level/levelgen/structure/registry/JigsawStructureBlockRulesRegistry.h" +#include "mc/world/level/levelgen/structure/registry/JigsawStructureElementRegistry.h" +#include "mc/world/level/levelgen/structure/registry/JigsawStructureRegistry.h" +#include "mc/world/level/levelgen/structure/registry/StructurePools.h" +#include "mc/world/level/levelgen/structure/structurepools/StructurePoolActorRule.h" +#include "mc/world/level/levelgen/structure/structurepools/StructurePoolBlockPredicateAlwaysTrue.h" +#include "mc/world/level/levelgen/structure/structurepools/StructurePoolBlockPredicateBlockMatchRandom.h" +#include "mc/world/level/levelgen/structure/structurepools/StructurePoolBlockRule.h" +#include "mc/world/level/levelgen/structure/structurepools/StructurePoolBlockTagRule.h" +#include "mc/world/level/levelgen/structure/structurepools/StructurePoolElement.h" +#include "mc/world/level/levelgen/structure/structurepools/StructureTemplatePool.h" +#include "mc/world/level/storage/Experiments.h" + +#include + +namespace custom_structure { + +void CustomJigsawStructureBlockRules::initialize(JigsawStructureRegistry& registry) { + auto& jigsawBlockRulesRegistry = registry.getJigsawStructureBlockRulesRegistry(); + // auto& DefaultBlockState = + // BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::PolishedBlackstoneBricks(), 1); + auto& resultBlock = BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::RedstoneBlock(), 1); + auto& block = BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::Blackstone(), 1); + + std::unique_ptr sourceBlock = + std::make_unique(block, 0.3); + std::unique_ptr targetBlock = + std::make_unique(); + + auto blockRule = + std::make_unique(std::move(sourceBlock), std::move(targetBlock), &resultBlock); + + auto ruleList = std::make_unique>>(); + + ruleList->push_back(std::move(blockRule)); + + jigsawBlockRulesRegistry.registerBlockRules("custom:custom_structure_block_rule", std::move(ruleList)); +} + +void CustomJigsawStructureElements::initialize( + gsl::not_null> manager, + FeatureRegistry& featureRegistry, + JigsawStructureRegistry& jigsawRegistry +) { + auto& jigsawBlockRulesRegistry = jigsawRegistry.getJigsawStructureBlockRulesRegistry(); + auto& jigsawStructureElementRegistry = jigsawRegistry.getJigsawStructureElementRegistry(); + auto ruleList = jigsawBlockRulesRegistry.lookupByName("custom:custom_structure_block_rule"); + std::vector> blockTag{}; + std::vector> actorRule{}; + // blockTag.push_back(nullptr); + // actorRule.push_back(nullptr); + + // 每一个结构nbt文件都得这样注册进来,多个nbt结构文件的可以使用同一个Block Rule + jigsawStructureElementRegistry.registerStructureElement( + "mike:21room", + std::make_unique( + manager, + "custom/21room", + ruleList, + nullptr, + nullptr, + Projection::Rigid, + PostProcessSettings::None + ) + ); + + jigsawStructureElementRegistry.registerStructureElement( + "mike:ew7x4", + std::make_unique( + manager, + "custom/ewhall", + ruleList, + nullptr, + nullptr, + Projection::Rigid, + PostProcessSettings::None + ) + ); + + jigsawStructureElementRegistry.registerStructureElement( + "mike:ns7x4", + std::make_unique( + manager, + "custom/nshall", + ruleList, + nullptr, + nullptr, + Projection::Rigid, + PostProcessSettings::None + ) + ); +} + +void CustomJigsawStructure::initialize( + Bedrock::NotNullNonOwnerPtr<::StructureManager> manager, + FeatureRegistry& featureRegistry, + JigsawStructureRegistry& registry +) { + CustomJigsawStructureBlockRules::initialize(registry); + CustomJigsawStructureElements::initialize(manager, featureRegistry, registry); + auto& jigsawStructureElementRegistry = registry.getJigsawStructureElementRegistry(); + + std::vector> templates_room{ + {jigsawStructureElementRegistry.lookupByName("mike:21room"), 1} + }; + std::vector> templates_ew{ + {jigsawStructureElementRegistry.lookupByName("mike:ew7x4"), 1} + }; + std::vector> templates_ns{ + {jigsawStructureElementRegistry.lookupByName("mike:ns7x4"), 1} + }; + + registry.registerPool(std::make_unique("mike:21room", "empty", templates_room)); + registry.registerPool(std::make_unique("mike:ew7x4", "empty", templates_ew)); + registry.registerPool(std::make_unique("mike:ns7x4", "empty", templates_ns)); +} + +} // namespace custom_structure + +LL_AUTO_TYPE_STATIC_HOOK( + InitStructure, + HookPriority::Normal, + br::worldgen::StructurePools, + br::worldgen::StructurePools::bootstrap, + void, + Bedrock::NotNullNonOwnerPtr structureManager, + FeatureRegistry& featureRegistry, + JigsawStructureRegistry& jigsawStructureRegistry, + BaseGameVersion const& baseGameVersion, + Experiments const& experiments +) { + origin(structureManager, featureRegistry, jigsawStructureRegistry, baseGameVersion, experiments); + custom_structure::CustomJigsawStructure::initialize(structureManager, featureRegistry, jigsawStructureRegistry); + return; +}; \ No newline at end of file diff --git a/src/test/generator/generator-custom-structure/CustomStructure.h b/src/test/generator/generator-custom-structure/CustomStructure.h new file mode 100644 index 0000000..25d6f45 --- /dev/null +++ b/src/test/generator/generator-custom-structure/CustomStructure.h @@ -0,0 +1,41 @@ +#pragma once + +#include "mc/deps/core/utility/NonOwnerPointer.h" + +#include "gsl/pointers" + +class FeatureRegistry; +class JigsawStructureRegistry; +class WorkerPool; +class StructureManager; + +namespace custom_structure { + +namespace CustomJigsawStructure { + +// 总注册初始化函数 +void initialize( + Bedrock::NotNullNonOwnerPtr<::StructureManager> manager, + FeatureRegistry& featureRegistry, + JigsawStructureRegistry& registry +); + +} // namespace CustomJigsawStructure + +namespace CustomJigsawStructureBlockRules { + +void initialize(JigsawStructureRegistry& registry); + +} + +namespace CustomJigsawStructureElements { + +void initialize( + gsl::not_null> manager, + FeatureRegistry& featureRegistry, + JigsawStructureRegistry& jigsawRegistry +); + +} + +} // namespace custom_structure diff --git a/src/test/generator/generator-custom-structure/README.md b/src/test/generator/generator-custom-structure/README.md new file mode 100644 index 0000000..fcd3461 --- /dev/null +++ b/src/test/generator/generator-custom-structure/README.md @@ -0,0 +1,5 @@ +## You need to copy the files in the `structure-files` folder to this path + +``` +behavior_packs\vanilla\structures\ +``` \ No newline at end of file diff --git a/src/test/generator/generator-custom-structure/dimension/CustomStructureDimension.cpp b/src/test/generator/generator-custom-structure/dimension/CustomStructureDimension.cpp new file mode 100644 index 0000000..99ce5bb --- /dev/null +++ b/src/test/generator/generator-custom-structure/dimension/CustomStructureDimension.cpp @@ -0,0 +1,123 @@ +#include "CustomStructureDimension.h" + +#include "test/generator/generator-custom-structure/generator/CustomStructureGenerator.h" +#include "test/generator/generator-custom-structure/structure/CustomStructureFeature.h" + +#include "mc/common/Brightness.h" +#include "mc/common/BrightnessPair.h" +#include "mc/deps/core/math/Vec3.h" +#include "mc/world/level/BlockSource.h" +#include "mc/world/level/DimensionConversionData.h" +#include "mc/world/level/Level.h" +#include "mc/world/level/LevelSeed64.h" +#include "mc/world/level/chunk/vanilla_level_chunk_upgrade/VanillaLevelChunkUpgrade.h" +#include "mc/world/level/dimension/DimensionBrightnessRamp.h" +#include "mc/world/level/dimension/DimensionHeightRange.h" +#include "mc/world/level/dimension/OverworldBrightnessRamp.h" +#include "mc/world/level/dimension/VanillaDimensions.h" +#include "mc/world/level/levelgen/structure/StructureFeatureRegistry.h" +#include "mc/world/level/levelgen/structure/VillageFeature.h" +#include "mc/world/level/levelgen/structure/registry/StructureSetRegistry.h" +#include "mc/world/level/levelgen/v2/ChunkGeneratorStructureState.h" +#include "mc/world/level/storage/LevelData.h" + + +namespace custom_structure_dimension { + +CustomStructureDimension::CustomStructureDimension( + std::string const& name, + more_dimensions::DimensionFactoryInfo const& info +) +: Dimension(info.level, info.dimId, {-64, 320}, info.scheduler, name) { + // 这里说明下,在DimensionFactoryInfo里面more-dimensions会提供维度id,请不要使用固定维度id,避免id冲突导致维度注册出现异常 + mDefaultBrightness->sky = Brightness::MAX(); + mSeaLevel = -61; + mHasWeather = true; + mDimensionBrightnessRamp = std::make_unique(); + mDimensionBrightnessRamp->buildBrightnessRamp(); +} + +CompoundTag CustomStructureDimension::generateNewData() { return {}; } + +std::unique_ptr +CustomStructureDimension::createGenerator(br::worldgen::StructureSetRegistry const& structureSetRegistry) { + std::unique_ptr worldGenerator; + uint seed = 2024; + auto& levelData = getLevel().getLevelData(); + + // 实例化我们写的Generator类 + worldGenerator = std::make_unique( + *this, + seed, + levelData.getFlatWorldGeneratorOptions() + ); + // structureSetRegistry里面仅有的土径结构村庄生成需要用到,所以我们拿一下 + std::vector> structureMap; + for (auto iter = structureSetRegistry.mStructureSets->begin(); iter != structureSetRegistry.mStructureSets->end(); iter++) { + structureMap.emplace_back(iter->second); + } + worldGenerator->getStructureFeatureRegistry().mGeneratorState->mSeed = seed; + worldGenerator->getStructureFeatureRegistry().mGeneratorState->mSeed64 = + LevelSeed64(seed); + + // 这个就相当于在这个生成器里注册结构了 + // VillageFeature的第二第三个参数是村庄之间的最大间隔与最小间隔 + worldGenerator->getStructureFeatureRegistry().mStructureFeatures->emplace_back( + std::make_unique(seed, 34, 8) + ); + worldGenerator->getStructureFeatureRegistry().mStructureFeatures->emplace_back( + std::make_unique(seed) + ); + // 此为必须,一些结构生成相关 + worldGenerator->getStructureFeatureRegistry().mGeneratorState = + br::worldgen::ChunkGeneratorStructureState::createFlat(seed, worldGenerator->getBiomeSource(), structureMap); + + return std::move(worldGenerator); +} + +void CustomStructureDimension::upgradeLevelChunk(ChunkSource& cs, LevelChunk& lc, LevelChunk& generatedChunk) { + auto blockSource = BlockSource(getLevel(), *this, cs, false, true, false); + VanillaLevelChunkUpgrade::_upgradeLevelChunkViaMetaData(lc, generatedChunk, blockSource); + VanillaLevelChunkUpgrade::_upgradeLevelChunkLegacy(lc, blockSource); +} + +void CustomStructureDimension::fixWallChunk(ChunkSource& cs, LevelChunk& lc) { + auto blockSource = BlockSource(getLevel(), *this, cs, false, true, false); + VanillaLevelChunkUpgrade::fixWallChunk(lc, blockSource); +} + +bool CustomStructureDimension::levelChunkNeedsUpgrade(LevelChunk const& lc) const { + return VanillaLevelChunkUpgrade::levelChunkNeedsUpgrade(lc); +} +void CustomStructureDimension::_upgradeOldLimboEntity(CompoundTag& tag, ::LimboEntitiesVersion vers) { + auto isTemplate = getLevel().getLevelData().isFromWorldTemplate(); + return VanillaLevelChunkUpgrade::upgradeOldLimboEntity(tag, vers, isTemplate); +} + +std::unique_ptr CustomStructureDimension:: + _wrapStorageForVersionCompatibility(std::unique_ptr cs, ::StorageVersion /*ver*/) { + return cs; +} + +Vec3 CustomStructureDimension::translatePosAcrossDimension(Vec3 const& fromPos, DimensionType fromId) const { + Vec3 topos; + VanillaDimensions::convertPointBetweenDimensions( + fromPos, + topos, + fromId, + mId, + getLevel().getDimensionConversionData() + ); + constexpr auto clampVal = 32000000.0f - 128.0f; + + topos.x = std::clamp(topos.x, -clampVal, clampVal); + topos.z = std::clamp(topos.z, -clampVal, clampVal); + + return topos; +} + +short CustomStructureDimension::getCloudHeight() const { return 192; } + +bool CustomStructureDimension::hasPrecipitationFog() const { return true; } + +} // namespace custom_structure_dimension \ No newline at end of file diff --git a/src/test/generator/generator-custom-structure/dimension/CustomStructureDimension.h b/src/test/generator/generator-custom-structure/dimension/CustomStructureDimension.h new file mode 100644 index 0000000..57a4692 --- /dev/null +++ b/src/test/generator/generator-custom-structure/dimension/CustomStructureDimension.h @@ -0,0 +1,47 @@ +#pragma once + +#include "mc/world/level/dimension/Dimension.h" // 新维度类需要继承的类 +#include "more_dimensions/api/dimension/CustomDimensionManager.h" // 引入DimensionFactoryInfo的声明 + +// 建议是加一个命名空间,避免与其他插件同类名的情况 +namespace custom_structure_dimension { + +class CustomStructureDimension : public Dimension { +public: + // 建议固定这样写,DimensionFactoryInfo类里面提供了Dimension实例化的基本数据,name就是维度名,多维度是维度名区分不同维度 + CustomStructureDimension(std::string const& name, more_dimensions::DimensionFactoryInfo const& info); + + // 多维度需要的一个方法,参数是你需要处理的数据,比如种子,这里不没有这样的需要,后面说原因 + static CompoundTag generateNewData(); + + // 以下六个是必须重写的函数 + // 维度地形的生成器,是本教程主要更改的地方 + std::unique_ptr createGenerator(br::worldgen::StructureSetRegistry const&) override; + + // 与本教程无关,按照本教程写的就行,无需留意 + void upgradeLevelChunk(ChunkSource& chunkSource, LevelChunk& oldLc, LevelChunk& newLc) override; + + // 与本教程无关,按照本教程写的就行,无需留意 + void fixWallChunk(ChunkSource& cs, LevelChunk& lc) override; + + // 与本教程无关,按照本教程写的就行,无需留意 + bool levelChunkNeedsUpgrade(LevelChunk const& lc) const override; + + // 与本教程无关,按照本教程写的就行,无需留意 + void _upgradeOldLimboEntity(CompoundTag& tag, ::LimboEntitiesVersion vers) override; + + // 与本教程无关,按照本教程写的就行,无需留意 + std::unique_ptr + _wrapStorageForVersionCompatibility(std::unique_ptr cs, ::StorageVersion ver) override; + + // 当你转到这个维度时,坐标怎么转换,比如主世界与地狱的 + Vec3 translatePosAcrossDimension(Vec3 const& pos, DimensionType did) const override; + + // 云高度,默认是y128,但多维度高度范围是在y-64~320,与主世界相同,重写它,放高些 + short getCloudHeight() const override; + + // 非必要。下雨时,可视范围的更改 + bool hasPrecipitationFog() const override; +}; + +} // namespace custom_structure_dimension \ No newline at end of file diff --git a/src/test/generator/generator-custom-structure/generator/CustomStructureGenerator.cpp b/src/test/generator/generator-custom-structure/generator/CustomStructureGenerator.cpp new file mode 100644 index 0000000..6e1e371 --- /dev/null +++ b/src/test/generator/generator-custom-structure/generator/CustomStructureGenerator.cpp @@ -0,0 +1,134 @@ +#include "CustomStructureGenerator.h" + +#include "mc/deps/core/math/Random.h" +#include "mc/platform/threading/Mutex.h" +#include "mc/util/ThreadOwner.h" +#include "mc/world/level/BlockSource.h" +#include "mc/world/level/ChunkPos.h" +#include "mc/world/level/Level.h" +#include "mc/world/level/biome/registry/BiomeRegistry.h" +#include "mc/world/level/biome/registry/VanillaBiomeNames.h" +#include "mc/world/level/biome/source/FixedBiomeSource.h" +#include "mc/world/level/chunk/ChunkViewSource.h" +#include "mc/world/level/chunk/LevelChunk.h" +#include "mc/world/level/chunk/PostprocessingManager.h" +#include "mc/world/level/dimension/Dimension.h" +#include "mc/world/level/levelgen/v1/ChunkLocalNoiseCache.h" + + +namespace custom_structure_generator { + +CustomStructureGenerator::CustomStructureGenerator( + Dimension& dimension, + uint seed, + Json::Value const& generationOptionsJSON +) +: FlatWorldGenerator(dimension, seed, generationOptionsJSON) { + // 值得注意的是,我们是继承的FlatWorldGenerator,后续也会使用其内部成员,所以我们需要调用FlatWorldGenerator的构造 + random.mRandom->mObject.mSeed = seed; + mSeed = seed; + + mBiome = getLevel().getBiomeRegistry().lookupByHash(VanillaBiomeNames::Plains()); + mBiomeSource = std::make_unique(*mBiome); +} + +bool CustomStructureGenerator::postProcess(ChunkViewSource& neighborhood) { + ChunkPos chunkPos; + chunkPos.x = neighborhood.getArea().mBounds.mMin->x; + chunkPos.z = neighborhood.getArea().mBounds.mMin->z; + auto levelChunk = neighborhood.getExistingChunk(chunkPos); + + auto seed = mSeed; + + // 必须,需要给区块上锁 + auto lockChunk = + levelChunk->getDimension().mPostProcessingManager->tryLock(levelChunk->getPosition(), neighborhood); + + if (!lockChunk) { + return false; + } + BlockSource blockSource(getLevel(), neighborhood.getDimension(), neighborhood, false, true, true); + auto chunkPosL = levelChunk->getPosition(); + random.mRandom->mObject.mSeed = seed; + auto one = 2 * (random.nextInt() / 2) + 1; + auto two = 2 * (random.nextInt() / 2) + 1; + random.mRandom->mObject.mSeed = seed ^ (chunkPosL.x * one + chunkPosL.z * two); + // 放置结构体,如果包含有某个结构的区块,就会放置loadChunk准备的结构 + WorldGenerator::postProcessStructureFeatures(blockSource, random, chunkPosL.x, chunkPosL.z); + // 处理其它单体结构,比如沉船,这里不是必须 + WorldGenerator::postProcessStructures(blockSource, random, chunkPosL.x, chunkPosL.z); + levelChunk->finalizePostProcessing(); + return true; +} + +void CustomStructureGenerator::loadChunk(LevelChunk& levelchunk, bool forceImmediateReplacementDataLoad) { + auto chunkPos = levelchunk.getPosition(); + + auto blockPos = BlockPos(chunkPos, 0); + DividedPos2d<4> dividedPos2D; + dividedPos2D.x = (blockPos.x >> 31) - ((blockPos.x >> 31) - blockPos.x) / 4; + dividedPos2D.z = (blockPos.z >> 31) - ((blockPos.z >> 31) - blockPos.z) / 4; + + // 处理其它单体结构,比如沉船,这里不是必须 + // WorldGenerator::preProcessStructures(getDimension(), chunkPos, getBiomeSource()); + // 准备要放置的结构,如果是某个某个结构的区块,就会准备结构 + WorldGenerator::prepareStructureFeatureBlueprints(getDimension(), chunkPos, getBiomeSource(), *this); + + // 这里并没有放置结构,只有单纯基本地形 + levelchunk.setBlockVolume(mPrototype, 0); + + levelchunk.recomputeHeightMap(0); + ChunkLocalNoiseCache chunkLocalNoiseCache(dividedPos2D, 8); + mBiomeSource->fillBiomes(levelchunk, chunkLocalNoiseCache); + levelchunk.setSaved(); + levelchunk.changeState(ChunkState::Generating, ChunkState::Generated); +} + +std::optional CustomStructureGenerator::getPreliminarySurfaceLevel(DividedPos2d<4> worldPos) const { + // 超平坦的高度都是一样的,直接返回固定值即可 + return -61; +} + +void CustomStructureGenerator::prepareAndComputeHeights( + BlockVolume& box, + ChunkPos const& chunkPos, + std::vector& ZXheights, + bool factorInBeardsAndShavers, + int skipTopN +) { + auto heightMap = mPrototype->computeHeightMap(); + ZXheights.assign(heightMap->begin(), heightMap->end()); +} + +void CustomStructureGenerator::prepareHeights( + BlockVolume& box, + ChunkPos const& chunkPos, + bool factorInBeardsAndShavers +) { + // 在其它类型世界里,这里是需要对box进行处理,生成地形,超平坦没有这个需要,所以直接赋值即可 + box = mPrototype; +}; + +HashedString CustomStructureGenerator::findStructureFeatureTypeAt(BlockPos const& blockPos) { + return WorldGenerator::findStructureFeatureTypeAt(blockPos); +}; + +bool CustomStructureGenerator::isStructureFeatureTypeAt(const BlockPos& blockPos, ::HashedString type) const { + return WorldGenerator::isStructureFeatureTypeAt(blockPos, type); +} + +bool CustomStructureGenerator::findNearestStructureFeature( + ::HashedString type, + BlockPos const& blockPos, + BlockPos& blockPos1, + bool mustBeInNewChunks, + std::optional hash +) { + return WorldGenerator::findNearestStructureFeature(type, blockPos, blockPos1, mustBeInNewChunks, hash); +}; + +void CustomStructureGenerator::garbageCollectBlueprints(buffer_span activeChunks) { + return WorldGenerator::garbageCollectBlueprints(activeChunks); +}; + +} // namespace custom_structure_generator diff --git a/src/test/generator/generator-custom-structure/generator/CustomStructureGenerator.h b/src/test/generator/generator-custom-structure/generator/CustomStructureGenerator.h new file mode 100644 index 0000000..425ce8b --- /dev/null +++ b/src/test/generator/generator-custom-structure/generator/CustomStructureGenerator.h @@ -0,0 +1,68 @@ +#pragma once + +#include "mc/deps/core/string/HashedString.h" +#include "mc/deps/core/utility/buffer_span.h" +#include "mc/util/Random.h" +#include "mc/world/level/BlockPos.h" +#include "mc/world/level/DividedPos2d.h" +#include "mc/world/level/block/BlockVolume.h" +#include "mc/world/level/levelgen/flat/FlatWorldGenerator.h" + + +#include + +class ChunkViewSource; +class LevelChunk; +class ChunkPos; + +// 依旧建议加一个命名空间避免冲突 +namespace custom_structure_generator { + +// 我们直接继承原版超平坦这个类来写会方便很多 +class CustomStructureGenerator : public FlatWorldGenerator { +public: + Random random; // 这个是BDS生成随机数有关的类 + uint mSeed; + + // 后面的generationOptionsJSON虽然用不上,但FlatWorldGenerator的实例化需要 + CustomStructureGenerator(Dimension& dimension, uint seed, Json::Value const& generationOptionsJSON); + + // 这里是处理结构放置相关的,包括地物,结构,地形 + bool postProcess(ChunkViewSource& neighborhood); + + // 这里是初始处理新的单区块的方块生成相关的,比如一些大量的方块(石头,泥土) + void loadChunk(LevelChunk& levelchunk, bool forceImmediateReplacementDataLoad); + + // 判断某个点在哪个结构范围里 + HashedString findStructureFeatureTypeAt(BlockPos const&); + + // 判断某个点是否在某个结构范围里 + bool isStructureFeatureTypeAt(BlockPos const&, ::HashedString) const; + + // 这里是获取某个坐标的最高方块 + std::optional getPreliminarySurfaceLevel(DividedPos2d<4> worldPos) const; + + // 如意,以一个坐标,在一定范围内查找某个类型的结构 + bool + findNearestStructureFeature(::HashedString, BlockPos const&, BlockPos&, bool, std::optional); + + // 无需在意,照写就行 + void garbageCollectBlueprints(buffer_span); + + // 处理地形 + void prepareHeights(BlockVolume& box, ChunkPos const& chunkPos, bool factorInBeardsAndShavers); + + // 与prepareHeights一样,不过与之不同的是,还会计算单区块内的高度 + void prepareAndComputeHeights( + BlockVolume& box, + ChunkPos const& chunkPos, + std::vector& ZXheights, + bool factorInBeardsAndShavers, + int skipTopN + ); + + // 可选,可以不写 + BlockPos findSpawnPosition() const { return {0, 16, 0}; }; +}; + +} // namespace flat_village_generator \ No newline at end of file diff --git a/src/test/generator/generator-custom-structure/structure-files/README.md b/src/test/generator/generator-custom-structure/structure-files/README.md new file mode 100644 index 0000000..2a6c2e4 --- /dev/null +++ b/src/test/generator/generator-custom-structure/structure-files/README.md @@ -0,0 +1,5 @@ +## You need to copy this folder to this path: + +``` +behavior_packs\vanilla\structures\ +``` \ No newline at end of file diff --git a/src/test/generator/generator-custom-structure/structure-files/custom/21room.mcstructure b/src/test/generator/generator-custom-structure/structure-files/custom/21room.mcstructure new file mode 100644 index 0000000..1348f4e Binary files /dev/null and b/src/test/generator/generator-custom-structure/structure-files/custom/21room.mcstructure differ diff --git a/src/test/generator/generator-custom-structure/structure-files/custom/ewhall.mcstructure b/src/test/generator/generator-custom-structure/structure-files/custom/ewhall.mcstructure new file mode 100644 index 0000000..c7d2058 Binary files /dev/null and b/src/test/generator/generator-custom-structure/structure-files/custom/ewhall.mcstructure differ diff --git a/src/test/generator/generator-custom-structure/structure-files/custom/nbt/back_bridge_bottom.nbt b/src/test/generator/generator-custom-structure/structure-files/custom/nbt/back_bridge_bottom.nbt new file mode 100644 index 0000000..e2e64cc Binary files /dev/null and b/src/test/generator/generator-custom-structure/structure-files/custom/nbt/back_bridge_bottom.nbt differ diff --git a/src/test/generator/generator-custom-structure/structure-files/custom/nbt/back_bridge_top.nbt b/src/test/generator/generator-custom-structure/structure-files/custom/nbt/back_bridge_top.nbt new file mode 100644 index 0000000..d60e84e Binary files /dev/null and b/src/test/generator/generator-custom-structure/structure-files/custom/nbt/back_bridge_top.nbt differ diff --git a/src/test/generator/generator-custom-structure/structure-files/custom/nbt/bridge.nbt b/src/test/generator/generator-custom-structure/structure-files/custom/nbt/bridge.nbt new file mode 100644 index 0000000..ca0cba4 Binary files /dev/null and b/src/test/generator/generator-custom-structure/structure-files/custom/nbt/bridge.nbt differ diff --git a/src/test/generator/generator-custom-structure/structure-files/custom/nshall.mcstructure b/src/test/generator/generator-custom-structure/structure-files/custom/nshall.mcstructure new file mode 100644 index 0000000..251d015 Binary files /dev/null and b/src/test/generator/generator-custom-structure/structure-files/custom/nshall.mcstructure differ diff --git a/src/test/generator/generator-custom-structure/structure/CustomStructureFeature.cpp b/src/test/generator/generator-custom-structure/structure/CustomStructureFeature.cpp new file mode 100644 index 0000000..13ed9db --- /dev/null +++ b/src/test/generator/generator-custom-structure/structure/CustomStructureFeature.cpp @@ -0,0 +1,59 @@ +#include "CustomStructureFeature.h" + +#include "test/generator/generator-custom-structure/structure/CustomStructurePiece.h" +#include "test/generator/generator-custom-structure/structure/CustomStructureStart.h" + + +#include "mc/deps/core/string/HashedString.h" +#include "mc/world/level/ChunkPos.h" +#include "mc/world/level/Level.h" +#include "mc/world/level/biome/Biome.h" +#include "mc/world/level/biome/source/BiomeSource.h" +#include "mc/world/level/dimension/Dimension.h" +#include "mc/world/level/levelgen/structure/BoundingBox.h" +#include "mc/world/level/levelgen/structure/StructureStart.h" + + + +#include + +namespace custom_structure { +bool CustomStructureFeature::getNearestGeneratedFeature( + ::Dimension& dimension, + ::BiomeSource const& biomeSource, + ::BlockPos const& origin, + ::BlockPos& pos, + ::IPreliminarySurfaceProvider const& preliminarySurfaceLevel, + bool mustBeInNewChunks, + ::std::optional<::HashedString> const& biomeTag +) { + return false; +}; + +bool CustomStructureFeature:: + isFeatureChunk(::BiomeSource const&, ::Random&, ::ChunkPos const& cpos, uint, ::IPreliminarySurfaceProvider const&, ::Dimension const&) { + if (cpos.x == 1 && cpos.z == 1) { + return true; + } + return false; +}; + +std::unique_ptr<::StructureStart> CustomStructureFeature:: + createStructureStart(::Dimension& dim, ::BiomeSource const& biomeSource, ::Random& random, ::ChunkPos const& cpos, ::IPreliminarySurfaceProvider const&) { + auto start = std::make_unique(); + CustomStructurePiece::addPieces( + {cpos.x * 16, 0, cpos.z * 16}, + start->pieces, + random, + dim.getLevel().getJigsawStructureRegistry(), + biomeSource.getBiome(cpos.x * 16, 1, cpos.z * 16)->getBiomeType(), + dim + ); + start->calculateBoundingBox(); + return std::move(start); +}; + +CustomStructureFeature::CustomStructureFeature(uint seed) +: StructureFeature(seed, HashedString("custom:custom_structure_test")) {} + +} // namespace custom_structure diff --git a/src/test/generator/generator-custom-structure/structure/CustomStructureFeature.h b/src/test/generator/generator-custom-structure/structure/CustomStructureFeature.h new file mode 100644 index 0000000..22fc6bf --- /dev/null +++ b/src/test/generator/generator-custom-structure/structure/CustomStructureFeature.h @@ -0,0 +1,27 @@ +#pragma once + +#include "mc/world/level/levelgen/structure/StructureFeature.h" + +namespace custom_structure { +class CustomStructureFeature : public StructureFeature { +public: + virtual bool getNearestGeneratedFeature( + ::Dimension& dimension, + ::BiomeSource const& biomeSource, + ::BlockPos const& origin, + ::BlockPos& pos, + ::IPreliminarySurfaceProvider const& preliminarySurfaceLevel, + bool mustBeInNewChunks, + ::std::optional<::HashedString> const& biomeTag + ); + + virtual bool + isFeatureChunk(::BiomeSource const&, ::Random&, ::ChunkPos const&, uint, ::IPreliminarySurfaceProvider const&, ::Dimension const&); + + virtual ::std::unique_ptr<::StructureStart> + createStructureStart(::Dimension&, ::BiomeSource const&, ::Random&, ::ChunkPos const&, ::IPreliminarySurfaceProvider const&); + + CustomStructureFeature(uint seed); +}; + +} // namespace custom_structure \ No newline at end of file diff --git a/src/test/generator/generator-custom-structure/structure/CustomStructurePiece.cpp b/src/test/generator/generator-custom-structure/structure/CustomStructurePiece.cpp new file mode 100644 index 0000000..4f5400e --- /dev/null +++ b/src/test/generator/generator-custom-structure/structure/CustomStructurePiece.cpp @@ -0,0 +1,71 @@ +#include "CustomStructurePiece.h" + +#include "mc/world/level/BlockPos.h" +#include "mc/world/level/block/VanillaBlockTypeIds.h" +#include "mc/world/level/block/registry/BlockTypeRegistry.h" +#include "mc/world/level/dimension/Dimension.h" +#include "mc/world/level/levelgen/structure/JigsawPlacement.h" +#include "mc/world/level/levelgen/structure/registry/JigsawStructureRegistry.h" +#include "mc/world/level/levelgen/structure/structurepools/StructureTemplatePool.h" +#include "mc/world/level/levelgen/structure/structurepools/alias/PoolAliasBinding.h" +#include "mc/world/level/levelgen/v1/AdjustmentEffect.h" +#include + + +namespace custom_structure { + +int CustomStructurePiece:: + generateHeightAtPosition(BlockPos const&, Dimension& dim, BlockVolume&, std::unordered_map>>&) + const { + return dim.mSeaLevel + 1; +}; + +Block const* CustomStructurePiece::getSupportBlock(::BlockSource&, ::BlockPos const&, ::Block const&) const { + return &BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::Netherrack(), 1); +}; + +Block const& CustomStructurePiece::getBeardStabilizeBlock(::Block const&) const { + return BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::Netherrack(), 1); +}; + +AdjustmentEffect CustomStructurePiece::getTerrainAdjustmentEffect() const { return AdjustmentEffect::BeardAndShave; }; + +CustomStructurePiece::CustomStructurePiece( + ::StructurePoolElement const& element, + ::BlockPos position, + ::Rotation rotation, + int genDepth, + ::JigsawJunction& junction, + ::BoundingBox const& box, + ::BlockPos refPos +) +: PoolElementStructurePiece(element, position, rotation, genDepth, junction, box, refPos){}; + +void CustomStructurePiece::addPieces( + BlockPos position, + std::vector>& pieces, + Random& random, + JigsawStructureRegistry& pools, + VanillaBiomeTypes biomeType, + Dimension& dimension +) { + auto templates = pools.lookupByName("mike:21room"); + // templates.getRandomTemplate(random); + + auto lambda = [](StructurePoolElement const& element, + ::BlockPos const& pos, + ::Rotation const& rot, + int unk, + ::JigsawJunction& jigction, + ::BoundingBox const& bb, + ::BlockPos const& pos1) { + return std::make_unique(element, pos, rot, unk, jigction, bb, pos1); + }; + JigsawPlacement place(15, 80, pieces, lambda, random, pools, dimension); + + place.addPieces(*templates->getRandomTemplate(random), position, Rotation::Rotate90, "", {}); +} + +} // namespace custom_structure + +PoolAliasBinding::PoolAliasLookup::PoolAliasLookup()=default; \ No newline at end of file diff --git a/src/test/generator/generator-custom-structure/structure/CustomStructurePiece.h b/src/test/generator/generator-custom-structure/structure/CustomStructurePiece.h new file mode 100644 index 0000000..0bd57c5 --- /dev/null +++ b/src/test/generator/generator-custom-structure/structure/CustomStructurePiece.h @@ -0,0 +1,43 @@ +#pragma once + +#include "mc/world/level/biome/components/vanilla/VanillaBiomeTypes.h" +#include "mc/world/level/levelgen/structure/PoolElementStructurePiece.h" + + +class JigsawStructureRegistry; + +namespace custom_structure { + +class CustomStructurePiece : public PoolElementStructurePiece { +public: + virtual int + generateHeightAtPosition(::BlockPos const&, ::Dimension&, ::BlockVolume&, ::std::unordered_map<::ChunkPos, ::std::unique_ptr<::std::vector>>&) + const; + + virtual Block const* getSupportBlock(::BlockSource&, ::BlockPos const&, ::Block const&) const; + + virtual Block const& getBeardStabilizeBlock(::Block const&) const; + + virtual AdjustmentEffect getTerrainAdjustmentEffect() const; + + CustomStructurePiece( + ::StructurePoolElement const& element, + ::BlockPos position, + ::Rotation rotation, + int genDepth, + ::JigsawJunction& junction, + ::BoundingBox const& box, + ::BlockPos refPos + ); + + static void addPieces( + BlockPos position, + std::vector>& pieces, + Random& random, + JigsawStructureRegistry& pools, + VanillaBiomeTypes biomeType, + Dimension& dimension + ); +}; + +} // namespace custom_structure diff --git a/src/test/generator/generator-custom-structure/structure/CustomStructureStart.cpp b/src/test/generator/generator-custom-structure/structure/CustomStructureStart.cpp new file mode 100644 index 0000000..9c8e6da --- /dev/null +++ b/src/test/generator/generator-custom-structure/structure/CustomStructureStart.cpp @@ -0,0 +1 @@ +#include "CustomStructureStart.h" diff --git a/src/test/generator/generator-custom-structure/structure/CustomStructureStart.h b/src/test/generator/generator-custom-structure/structure/CustomStructureStart.h new file mode 100644 index 0000000..da4eabd --- /dev/null +++ b/src/test/generator/generator-custom-structure/structure/CustomStructureStart.h @@ -0,0 +1,10 @@ +#pragma once + +#include "mc/world/level/levelgen/structure/StructureStart.h" + + +class CustomStructureStart : public StructureStart { +public: + CustomStructureStart() = default; + virtual std::string_view getStructureName() const { return "custom:custom_structure_start"; }; +}; diff --git a/src/test/generator/generator-structure/FeatureStructureGen.cpp b/src/test/generator/generator-structure/FeatureStructureGen.cpp deleted file mode 100644 index a3da8f9..0000000 --- a/src/test/generator/generator-structure/FeatureStructureGen.cpp +++ /dev/null @@ -1,142 +0,0 @@ -// -// Created by User on 2024/2/22. -// - -#include "FeatureStructureGen.h" - -#include "magic_enum.hpp" -#include "mc/world/level/BlockSource.h" -#include "mc/world/level/Level.h" -#include "mc/world/level/biome/VanillaBiomeNames.h" -#include "mc/world/level/biome/registry/BiomeRegistry.h" -#include "mc/world/level/block/Block.h" -#include "mc/world/level/block/registry/BlockTypeRegistry.h" -#include "mc/world/level/block/utils/AirBlockCache.h" -#include "mc/world/level/block/utils/BedrockBlockNames.h" -#include "mc/world/level/block/utils/VanillaBlockTypeIds.h" -#include "mc/world/level/chunk/ChunkViewSource.h" -#include "mc/world/level/chunk/LevelChunk.h" -#include "mc/world/level/chunk/PostprocessingManager.h" -#include "mc/world/level/levelgen/structure/StructureFeature.h" -#include "mc/world/level/levelgen/structure/StructureFeatureRegistry.h" -#include "mc/world/level/levelgen/v1/ChunkLocalNoiseCache.h" - -FeatureStructureGen::FeatureStructureGen(Dimension& dimension, uint seed) : WorldGenerator(dimension) { - mSeed = seed; - buffer_span_mut buffer; - mPrototypeBlocks.resize(4096); - buffer.mBegin = &*mPrototypeBlocks.begin(); - buffer.mEnd = &*mPrototypeBlocks.end(); - auto& defaultBlock = BlockTypeRegistry::getDefaultBlockState(BedrockBlockNames::Air, true); - // 参数说明:后面的48意思维度最低的是y48,会在计算高度时用到 - mPrototype = BlockVolume(buffer, 16, 16, 16, defaultBlock, 48); - random.mRandom.mObject._setSeed(seed); - - // 构建BlockVolume,大小是16*16*16,并且里面是填满草方块 - for (int i = 0; i < 256; i++) { - for (int j = 0; j < 16; j++) { - mPrototypeBlocks[16 * i + j] = &BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::Grass); - } - }; - mBiome = getLevel().getBiomeRegistry().lookupByHash(VanillaBiomeNames::Plains); - mBiomeSource = std::make_unique(*mBiome); -} - -bool FeatureStructureGen::postProcess(ChunkViewSource& neighborhood) { - ChunkPos chunkPos; - chunkPos.x = neighborhood.getArea().mBounds.min.x; - chunkPos.z = neighborhood.getArea().mBounds.min.z; - auto levelChunk = neighborhood.getExistingChunk(chunkPos); - - // 必须,需要给区块上锁 - auto lockChunk = - levelChunk->getDimension().mPostProcessingManager->tryLock(levelChunk->getPosition(), neighborhood); - - if (!lockChunk) { - return false; - } - BlockSource blockSource(getLevel(), neighborhood.getDimension(), neighborhood, false, true, true); - auto chunkPosL = levelChunk->getPosition(); - random.mRandom.mObject._setSeed(345); - auto one = 2 * (random.nextInt() / 2) + 1; - auto two = 2 * (random.nextInt() / 2) + 1; - random.mRandom.mObject._setSeed(345 ^ (chunkPosL.x * one + chunkPosL.z * two)); - // 放置结构体 - WorldGenerator::postProcessStructureFeatures(blockSource, random, chunkPosL.x, chunkPosL.z); - WorldGenerator::postProcessStructures(blockSource, random, chunkPosL.x, chunkPosL.z); - return true; -} - -void FeatureStructureGen::loadChunk(LevelChunk& levelchunk, bool forceImmediateReplacementDataLoad) { - auto chunkPos = levelchunk.getPosition(); - - auto blockPos = BlockPos(chunkPos, 0); - DividedPos2d<4> dividedPos2D; - dividedPos2D.x = (blockPos.x >> 31) - ((blockPos.x >> 31) - blockPos.x) / 4; - dividedPos2D.z = (blockPos.z >> 31) - ((blockPos.z >> 31) - blockPos.z) / 4; - WorldGenerator::preProcessStructures(getDimension(), chunkPos, getBiomeSource()); - // 准备要放置的结构 - WorldGenerator::prepareStructureFeatureBlueprints(getDimension(), chunkPos, getBiomeSource(), *this); - - // 后面的112意思是放置BlockVolume时,要向上第112层开始,比如最低y是-64的话,对应的y是-64+112=48 - levelchunk.setBlockVolume(mPrototype, 112); - - levelchunk.recomputeHeightMap(0); - ChunkLocalNoiseCache chunkLocalNoiseCache(dividedPos2D, 8); - mBiomeSource->fillBiomes(levelchunk, chunkLocalNoiseCache); - levelchunk.setSaved(); - levelchunk.changeState(ChunkState::Generating, ChunkState::Generated); -} - -std::optional FeatureStructureGen::getPreliminarySurfaceLevel(DividedPos2d<4> worldPos) const { - auto heightMap = mPrototype.computeHeightMap(); - auto pos_x = (worldPos.x % 16 + 16) % 16; - auto pos_z = (worldPos.z % 16 + 16) % 16; - short height = heightMap->at(pos_x + 16 * pos_z); - return height; -} - -void FeatureStructureGen::prepareAndComputeHeights( - BlockVolume& box, - ChunkPos const& chunkPos, - std::vector& ZXheights, - bool factorInBeardsAndShavers, - int skipTopN -) { - auto heightMap = mPrototype.computeHeightMap(); - ZXheights.assign(heightMap->begin(), heightMap->end()); -} - -void FeatureStructureGen::prepareHeights(BlockVolume& box, ChunkPos const& chunkPos, bool factorInBeardsAndShavers) { - box = mPrototype; -}; - -StructureFeatureType FeatureStructureGen::findStructureFeatureTypeAt(BlockPos const& blockPos) { - return WorldGenerator::findStructureFeatureTypeAt(blockPos); -}; - -bool FeatureStructureGen::isStructureFeatureTypeAt(const BlockPos& blockPos, ::StructureFeatureType type) const { - return WorldGenerator::isStructureFeatureTypeAt(blockPos, type); -} - -bool FeatureStructureGen::findNearestStructureFeature( - ::StructureFeatureType type, - BlockPos const& blockPos, - BlockPos& blockPos1, - bool mustBeInNewChunks, - std::optional hash -) { - return WorldGenerator::findNearestStructureFeature(type, blockPos, blockPos1, mustBeInNewChunks, hash); -}; - -void FeatureStructureGen::garbageCollectBlueprints(buffer_span activeChunks) { - return WorldGenerator::garbageCollectBlueprints(activeChunks); -}; - -BiomeArea FeatureStructureGen::getBiomeArea(BoundingBox const& area, uint scale) const { - return mBiomeSource->getBiomeArea(area, scale); -} - -WorldGenerator::BlockVolumeDimensions FeatureStructureGen::getBlockVolumeDimensions() const { - return {mPrototype.mWidth, mPrototype.mDepth, mPrototype.mHeight}; -} diff --git a/src/test/generator/generator-structure/FeatureStructureGen.h b/src/test/generator/generator-structure/FeatureStructureGen.h deleted file mode 100644 index 72ce111..0000000 --- a/src/test/generator/generator-structure/FeatureStructureGen.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include "mc/util/Random.h" -#include "mc/world/level/biome/source/BiomeArea.h" -#include "mc/world/level/biome/source/FixedBiomeSource.h" -#include "mc/world/level/block/BlockVolume.h" -#include "mc/world/level/levelgen/WorldGenerator.h" - -#include - -class ChunkViewSource; -class LevelChunk; -class ChunkPos; -class BlockVolumeTarget; -class BlockSource; -class Block; - -/* - * 这是一个关于功能性结构(FeatureStructure)生成相关的生成器示例 - * */ - -class FeatureStructureGen : public WorldGenerator { -public: - std::vector mPrototypeBlocks; // this+0x190 - BlockVolume mPrototype; // this+0x1A8 - Biome const* mBiome; // this+0x1D0 - std::unique_ptr mBiomeSource; // this+0x1D8 - uint mSeed; - Random random; - FeatureStructureGen(Dimension& dimension, uint seed); - - // 这里是处理中结构放置相关的,包括地物,结构,一些地形 - bool postProcess(ChunkViewSource& neighborhood); - - // 这里是初始处理新的单区块的方块生成相关的,比如一些大量的方块(石头,泥土) - void loadChunk(LevelChunk& levelchunk, bool forceImmediateReplacementDataLoad); - - StructureFeatureType findStructureFeatureTypeAt(BlockPos const&); - - bool isStructureFeatureTypeAt(BlockPos const&, ::StructureFeatureType) const; - - // 这里是获取某个坐标的最高方块 - std::optional getPreliminarySurfaceLevel(class DividedPos2d<4> worldPos) const; - - // 如意,以一个坐标,在一定范围内查找某个类型的结构 - bool - findNearestStructureFeature(::StructureFeatureType, BlockPos const&, BlockPos&, bool, std::optional); - - void garbageCollectBlueprints(buffer_span); - - // 处理地形 - void prepareHeights(BlockVolume& box, ChunkPos const& chunkPos, bool factorInBeardsAndShavers); - - // 与prepareHeights一样,不过与之不同的是,还会计算单区块内的高度 - void prepareAndComputeHeights( - BlockVolume& box, - ChunkPos const& chunkPos, - std::vector& ZXheights, - bool factorInBeardsAndShavers, - int skipTopN - ); - - BiomeArea getBiomeArea(BoundingBox const& area, uint scale) const; - - BiomeSource const& getBiomeSource() const { return *mBiomeSource; } - - WorldGenerator::BlockVolumeDimensions getBlockVolumeDimensions() const; - - BlockPos findSpawnPosition() const { return {0, 16, 0}; }; - - void decorateWorldGenLoadChunk( - Biome& biome, - LevelChunk& lc, - BlockVolumeTarget& target, - Random& random, - ChunkPos const& pos - ) const {}; - - void decorateWorldGenPostProcess(Biome& biome, LevelChunk& lc, BlockSource& source, Random& random) const {}; -}; diff --git a/xmake.lua b/xmake.lua index 0bc2c2f..6a7094c 100644 --- a/xmake.lua +++ b/xmake.lua @@ -49,5 +49,6 @@ target("more-dimensions") if has_config("tests") then add_files("src/test/TestCustomDimension.cpp", "src/test/generator/flat-gen-village/**.cpp", - "src/test/generator/generator-terrain/**.cpp") + "src/test/generator/generator-terrain/**.cpp", + "src/test/generator/generator-custom-structure/**.cpp") end \ No newline at end of file