Skip to content

Commit b115bc4

Browse files
committed
test: add custom structure test
1 parent 397c40b commit b115bc4

24 files changed

+802
-223
lines changed

src/test/TestCustomDimension.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "test/generator/flat-gen-village/FlatVillageDimension.h"
2+
#include "test/generator/generator-custom-structure/dimension/CustomStructureDimension.h"
23
#include "test/generator/generator-terrain/NxnBorderTerrainDimension.h"
34

45
#include "ll/api/event/EventBus.h"
@@ -10,21 +11,40 @@
1011
static bool reg = [] {
1112
using namespace ll::event;
1213
EventBus::getInstance().emplaceListener<ServerStartedEvent>([](ServerStartedEvent&) {
14+
// simplate dimension test
15+
// vanilla overworld type dimension test
1316
more_dimensions::CustomDimensionManager::getInstance().addDimension<more_dimensions::SimpleCustomDimension>(
1417
"testNewDimension"
1518
);
19+
20+
// vanilla flat type dimension test
1621
more_dimensions::CustomDimensionManager::getInstance()
1722
.addDimension<more_dimensions::SimpleCustomDimension>("testNewFlatDimension", 345, GeneratorType::Flat);
23+
24+
// vanilla nether type dimension test
1825
more_dimensions::CustomDimensionManager::getInstance()
1926
.addDimension<more_dimensions::SimpleCustomDimension>("testNewNetherDimension", 345, GeneratorType::Nether);
27+
28+
// vanilla the end type dimension test
2029
more_dimensions::CustomDimensionManager::getInstance()
2130
.addDimension<more_dimensions::SimpleCustomDimension>("testNewTheEndDimension", 345, GeneratorType::TheEnd);
31+
32+
// vanilla void dimension test
2233
more_dimensions::CustomDimensionManager::getInstance()
2334
.addDimension<more_dimensions::SimpleCustomDimension>("testNewVoidDimension", 345, GeneratorType::Void);
35+
36+
// custom diomension test
37+
// flat type generator village dimension test
2438
more_dimensions::CustomDimensionManager::getInstance()
2539
.addDimension<flat_village_dimension::FlatVillageDimension>("testFlatVillage");
40+
41+
// flat type custom terrain dimension test
2642
more_dimensions::CustomDimensionManager::getInstance()
2743
.addDimension<nxn_border_terrain::NxnBorderTerrainDimension>("testFlatTerrain", 5);
44+
45+
// flat type custom structure dimension test
46+
more_dimensions::CustomDimensionManager::getInstance()
47+
.addDimension<custom_structure_dimension::CustomStructureDimension>("testCustomStructure");
2848
});
2949
return true;
3050
}();
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#include "CustomStructure.h"
2+
3+
#include "ll/api/memory/Hook.h"
4+
5+
#include "mc/deps/core/threading/WorkerPool.h"
6+
#include "mc/resources/BaseGameVersion.h"
7+
#include "mc/world/level/block/VanillaBlockTypeIds.h"
8+
#include "mc/world/level/block/registry/BlockTypeRegistry.h"
9+
#include "mc/world/level/levelgen/feature/registry/FeatureRegistry.h"
10+
#include "mc/world/level/levelgen/structure/Projection.h"
11+
#include "mc/world/level/levelgen/structure/StructureManager.h"
12+
#include "mc/world/level/levelgen/structure/registry/JigsawStructureBlockRulesRegistry.h"
13+
#include "mc/world/level/levelgen/structure/registry/JigsawStructureElementRegistry.h"
14+
#include "mc/world/level/levelgen/structure/registry/JigsawStructureRegistry.h"
15+
#include "mc/world/level/levelgen/structure/registry/StructurePools.h"
16+
#include "mc/world/level/levelgen/structure/structurepools/StructurePoolActorRule.h"
17+
#include "mc/world/level/levelgen/structure/structurepools/StructurePoolBlockPredicateAlwaysTrue.h"
18+
#include "mc/world/level/levelgen/structure/structurepools/StructurePoolBlockPredicateBlockMatchRandom.h"
19+
#include "mc/world/level/levelgen/structure/structurepools/StructurePoolBlockRule.h"
20+
#include "mc/world/level/levelgen/structure/structurepools/StructurePoolBlockTagRule.h"
21+
#include "mc/world/level/levelgen/structure/structurepools/StructurePoolElement.h"
22+
#include "mc/world/level/levelgen/structure/structurepools/StructureTemplatePool.h"
23+
#include "mc/world/level/storage/Experiments.h"
24+
25+
#include <memory>
26+
27+
namespace custom_structure {
28+
29+
void CustomJigsawStructureBlockRules::initialize(JigsawStructureRegistry& registry) {
30+
auto& jigsawBlockRulesRegistry = registry.getJigsawStructureBlockRulesRegistry();
31+
// auto& DefaultBlockState =
32+
// BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::PolishedBlackstoneBricks(), 1);
33+
auto& resultBlock = BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::RedstoneBlock(), 1);
34+
auto& block = BlockTypeRegistry::getDefaultBlockState(VanillaBlockTypeIds::Blackstone(), 1);
35+
36+
std::unique_ptr<IStructurePoolBlockPredicate> sourceBlock =
37+
std::make_unique<StructurePoolBlockPredicateBlockMatchRandom>(block, 0.3);
38+
std::unique_ptr<IStructurePoolBlockPredicate> targetBlock =
39+
std::make_unique<StructurePoolBlockPredicateAlwaysTrue>();
40+
41+
auto blockRule =
42+
std::make_unique<StructurePoolBlockRule>(std::move(sourceBlock), std::move(targetBlock), &resultBlock);
43+
44+
auto ruleList = std::make_unique<std::vector<std::unique_ptr<StructurePoolBlockRule>>>();
45+
46+
ruleList->push_back(std::move(blockRule));
47+
48+
jigsawBlockRulesRegistry.registerBlockRules("custom:custom_structure_block_rule", std::move(ruleList));
49+
}
50+
51+
void CustomJigsawStructureElements::initialize(
52+
gsl::not_null<Bedrock::NonOwnerPointer<StructureManager>> manager,
53+
FeatureRegistry& featureRegistry,
54+
JigsawStructureRegistry& jigsawRegistry
55+
) {
56+
auto& jigsawBlockRulesRegistry = jigsawRegistry.getJigsawStructureBlockRulesRegistry();
57+
auto& jigsawStructureElementRegistry = jigsawRegistry.getJigsawStructureElementRegistry();
58+
auto ruleList = jigsawBlockRulesRegistry.lookupByName("custom:custom_structure_block_rule");
59+
std::vector<std::unique_ptr<StructurePoolBlockTagRule>> blockTag{};
60+
std::vector<std::unique_ptr<StructurePoolActorRule>> actorRule{};
61+
// blockTag.push_back(nullptr);
62+
// actorRule.push_back(nullptr);
63+
64+
// 每一个结构nbt文件都得这样注册进来,多个nbt结构文件的可以使用同一个Block Rule
65+
jigsawStructureElementRegistry.registerStructureElement(
66+
"mike:21room",
67+
std::make_unique<StructurePoolElement>(
68+
manager,
69+
"custom/21room",
70+
ruleList,
71+
nullptr,
72+
nullptr,
73+
Projection::Rigid,
74+
PostProcessSettings::None
75+
)
76+
);
77+
78+
jigsawStructureElementRegistry.registerStructureElement(
79+
"mike:ew7x4",
80+
std::make_unique<StructurePoolElement>(
81+
manager,
82+
"custom/ewhall",
83+
ruleList,
84+
nullptr,
85+
nullptr,
86+
Projection::Rigid,
87+
PostProcessSettings::None
88+
)
89+
);
90+
91+
jigsawStructureElementRegistry.registerStructureElement(
92+
"mike:ns7x4",
93+
std::make_unique<StructurePoolElement>(
94+
manager,
95+
"custom/nshall",
96+
ruleList,
97+
nullptr,
98+
nullptr,
99+
Projection::Rigid,
100+
PostProcessSettings::None
101+
)
102+
);
103+
}
104+
105+
void CustomJigsawStructure::initialize(
106+
Bedrock::NotNullNonOwnerPtr<::StructureManager> manager,
107+
FeatureRegistry& featureRegistry,
108+
JigsawStructureRegistry& registry
109+
) {
110+
CustomJigsawStructureBlockRules::initialize(registry);
111+
CustomJigsawStructureElements::initialize(manager, featureRegistry, registry);
112+
auto& jigsawStructureElementRegistry = registry.getJigsawStructureElementRegistry();
113+
114+
std::vector<std::pair<StructurePoolElement const*, int>> templates_room{
115+
{jigsawStructureElementRegistry.lookupByName("mike:21room"), 1}
116+
};
117+
std::vector<std::pair<StructurePoolElement const*, int>> templates_ew{
118+
{jigsawStructureElementRegistry.lookupByName("mike:ew7x4"), 1}
119+
};
120+
std::vector<std::pair<StructurePoolElement const*, int>> templates_ns{
121+
{jigsawStructureElementRegistry.lookupByName("mike:ns7x4"), 1}
122+
};
123+
124+
registry.registerPool(std::make_unique<StructureTemplatePool>("mike:21room", "empty", templates_room));
125+
registry.registerPool(std::make_unique<StructureTemplatePool>("mike:ew7x4", "empty", templates_ew));
126+
registry.registerPool(std::make_unique<StructureTemplatePool>("mike:ns7x4", "empty", templates_ns));
127+
}
128+
129+
} // namespace custom_structure
130+
131+
LL_AUTO_TYPE_STATIC_HOOK(
132+
InitStructure,
133+
HookPriority::Normal,
134+
br::worldgen::StructurePools,
135+
br::worldgen::StructurePools::bootstrap,
136+
void,
137+
Bedrock::NotNullNonOwnerPtr<StructureManager> structureManager,
138+
FeatureRegistry& featureRegistry,
139+
JigsawStructureRegistry& jigsawStructureRegistry,
140+
BaseGameVersion const& baseGameVersion,
141+
Experiments const& experiments
142+
) {
143+
origin(structureManager, featureRegistry, jigsawStructureRegistry, baseGameVersion, experiments);
144+
custom_structure::CustomJigsawStructure::initialize(structureManager, featureRegistry, jigsawStructureRegistry);
145+
return;
146+
};
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#pragma once
2+
3+
#include "mc/deps/core/utility/NonOwnerPointer.h"
4+
5+
#include "gsl/pointers"
6+
7+
class FeatureRegistry;
8+
class JigsawStructureRegistry;
9+
class WorkerPool;
10+
class StructureManager;
11+
12+
namespace custom_structure {
13+
14+
namespace CustomJigsawStructure {
15+
16+
// 总注册初始化函数
17+
void initialize(
18+
Bedrock::NotNullNonOwnerPtr<::StructureManager> manager,
19+
FeatureRegistry& featureRegistry,
20+
JigsawStructureRegistry& registry
21+
);
22+
23+
} // namespace CustomJigsawStructure
24+
25+
namespace CustomJigsawStructureBlockRules {
26+
27+
void initialize(JigsawStructureRegistry& registry);
28+
29+
}
30+
31+
namespace CustomJigsawStructureElements {
32+
33+
void initialize(
34+
gsl::not_null<Bedrock::NonOwnerPointer<StructureManager>> manager,
35+
FeatureRegistry& featureRegistry,
36+
JigsawStructureRegistry& jigsawRegistry
37+
);
38+
39+
}
40+
41+
} // namespace custom_structure
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## You need to copy the files in the `structure-files` folder to this path
2+
3+
```
4+
behavior_packs\vanilla\structures\
5+
```
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#include "CustomStructureDimension.h"
2+
3+
#include "test/generator/generator-custom-structure/generator/CustomStructureGenerator.h"
4+
#include "test/generator/generator-custom-structure/structure/CustomStructureFeature.h"
5+
6+
#include "mc/common/Brightness.h"
7+
#include "mc/common/BrightnessPair.h"
8+
#include "mc/deps/core/math/Vec3.h"
9+
#include "mc/world/level/BlockSource.h"
10+
#include "mc/world/level/DimensionConversionData.h"
11+
#include "mc/world/level/Level.h"
12+
#include "mc/world/level/LevelSeed64.h"
13+
#include "mc/world/level/chunk/vanilla_level_chunk_upgrade/VanillaLevelChunkUpgrade.h"
14+
#include "mc/world/level/dimension/DimensionBrightnessRamp.h"
15+
#include "mc/world/level/dimension/DimensionHeightRange.h"
16+
#include "mc/world/level/dimension/OverworldBrightnessRamp.h"
17+
#include "mc/world/level/dimension/VanillaDimensions.h"
18+
#include "mc/world/level/levelgen/structure/StructureFeatureRegistry.h"
19+
#include "mc/world/level/levelgen/structure/VillageFeature.h"
20+
#include "mc/world/level/levelgen/structure/registry/StructureSetRegistry.h"
21+
#include "mc/world/level/levelgen/v2/ChunkGeneratorStructureState.h"
22+
#include "mc/world/level/storage/LevelData.h"
23+
24+
25+
namespace custom_structure_dimension {
26+
27+
CustomStructureDimension::CustomStructureDimension(
28+
std::string const& name,
29+
more_dimensions::DimensionFactoryInfo const& info
30+
)
31+
: Dimension(info.level, info.dimId, {-64, 320}, info.scheduler, name) {
32+
// 这里说明下,在DimensionFactoryInfo里面more-dimensions会提供维度id,请不要使用固定维度id,避免id冲突导致维度注册出现异常
33+
mDefaultBrightness->sky = Brightness::MAX();
34+
mSeaLevel = -61;
35+
mHasWeather = true;
36+
mDimensionBrightnessRamp = std::make_unique<OverworldBrightnessRamp>();
37+
mDimensionBrightnessRamp->buildBrightnessRamp();
38+
}
39+
40+
CompoundTag CustomStructureDimension::generateNewData() { return {}; }
41+
42+
std::unique_ptr<WorldGenerator>
43+
CustomStructureDimension::createGenerator(br::worldgen::StructureSetRegistry const& structureSetRegistry) {
44+
std::unique_ptr<WorldGenerator> worldGenerator;
45+
uint seed = 2024;
46+
auto& levelData = getLevel().getLevelData();
47+
48+
// 实例化我们写的Generator类
49+
worldGenerator = std::make_unique<custom_structure_generator::CustomStructureGenerator>(
50+
*this,
51+
seed,
52+
levelData.getFlatWorldGeneratorOptions()
53+
);
54+
// structureSetRegistry里面仅有的土径结构村庄生成需要用到,所以我们拿一下
55+
std::vector<std::shared_ptr<const br::worldgen::StructureSet>> structureMap;
56+
for (auto iter = structureSetRegistry.mStructureSets->begin(); iter != structureSetRegistry.mStructureSets->end(); iter++) {
57+
structureMap.emplace_back(iter->second);
58+
}
59+
worldGenerator->getStructureFeatureRegistry().mGeneratorState->mSeed = seed;
60+
worldGenerator->getStructureFeatureRegistry().mGeneratorState->mSeed64 =
61+
LevelSeed64(seed);
62+
63+
// 这个就相当于在这个生成器里注册结构了
64+
// VillageFeature的第二第三个参数是村庄之间的最大间隔与最小间隔
65+
worldGenerator->getStructureFeatureRegistry().mStructureFeatures->emplace_back(
66+
std::make_unique<VillageFeature>(seed, 34, 8)
67+
);
68+
worldGenerator->getStructureFeatureRegistry().mStructureFeatures->emplace_back(
69+
std::make_unique<custom_structure::CustomStructureFeature>(seed)
70+
);
71+
// 此为必须,一些结构生成相关
72+
worldGenerator->getStructureFeatureRegistry().mGeneratorState =
73+
br::worldgen::ChunkGeneratorStructureState::createFlat(seed, worldGenerator->getBiomeSource(), structureMap);
74+
75+
return std::move(worldGenerator);
76+
}
77+
78+
void CustomStructureDimension::upgradeLevelChunk(ChunkSource& cs, LevelChunk& lc, LevelChunk& generatedChunk) {
79+
auto blockSource = BlockSource(getLevel(), *this, cs, false, true, false);
80+
VanillaLevelChunkUpgrade::_upgradeLevelChunkViaMetaData(lc, generatedChunk, blockSource);
81+
VanillaLevelChunkUpgrade::_upgradeLevelChunkLegacy(lc, blockSource);
82+
}
83+
84+
void CustomStructureDimension::fixWallChunk(ChunkSource& cs, LevelChunk& lc) {
85+
auto blockSource = BlockSource(getLevel(), *this, cs, false, true, false);
86+
VanillaLevelChunkUpgrade::fixWallChunk(lc, blockSource);
87+
}
88+
89+
bool CustomStructureDimension::levelChunkNeedsUpgrade(LevelChunk const& lc) const {
90+
return VanillaLevelChunkUpgrade::levelChunkNeedsUpgrade(lc);
91+
}
92+
void CustomStructureDimension::_upgradeOldLimboEntity(CompoundTag& tag, ::LimboEntitiesVersion vers) {
93+
auto isTemplate = getLevel().getLevelData().isFromWorldTemplate();
94+
return VanillaLevelChunkUpgrade::upgradeOldLimboEntity(tag, vers, isTemplate);
95+
}
96+
97+
std::unique_ptr<ChunkSource> CustomStructureDimension::
98+
_wrapStorageForVersionCompatibility(std::unique_ptr<ChunkSource> cs, ::StorageVersion /*ver*/) {
99+
return cs;
100+
}
101+
102+
Vec3 CustomStructureDimension::translatePosAcrossDimension(Vec3 const& fromPos, DimensionType fromId) const {
103+
Vec3 topos;
104+
VanillaDimensions::convertPointBetweenDimensions(
105+
fromPos,
106+
topos,
107+
fromId,
108+
mId,
109+
getLevel().getDimensionConversionData()
110+
);
111+
constexpr auto clampVal = 32000000.0f - 128.0f;
112+
113+
topos.x = std::clamp(topos.x, -clampVal, clampVal);
114+
topos.z = std::clamp(topos.z, -clampVal, clampVal);
115+
116+
return topos;
117+
}
118+
119+
short CustomStructureDimension::getCloudHeight() const { return 192; }
120+
121+
bool CustomStructureDimension::hasPrecipitationFog() const { return true; }
122+
123+
} // namespace custom_structure_dimension

0 commit comments

Comments
 (0)