Skip to content

Commit cb6f308

Browse files
committed
Fixed azalea generation not behaving as expected
1 parent edbbed7 commit cb6f308

File tree

7 files changed

+108
-14
lines changed

7 files changed

+108
-14
lines changed

src/main/java/com/ferreusveritas/dynamictrees/data/provider/DTBlockTagsProvider.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ private void addDTOnlyTags() {
5656
.add(Blocks.BROWN_MUSHROOM)
5757
.add(Blocks.RED_MUSHROOM)
5858
.add(Blocks.LILY_PAD)
59+
.add(Blocks.AZALEA)
60+
.add(Blocks.FLOWERING_AZALEA)
61+
.add(Blocks.MOSS_CARPET)
5962
.addTag(BlockTags.FLOWERS)
6063
.addTag(BlockTags.REPLACEABLE_BY_TREES);
6164

src/main/java/com/ferreusveritas/dynamictrees/resources/loader/BiomePopulatorsResourceLoader.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ public void registerAppliers() {
9696

9797
this.caveRootedDataAppliers
9898
.register("generate_on_surface", Boolean.class, BiomeDatabase.CaveRootedData::setGenerateOnSurface)
99-
.register("max_dist_to_surface", Integer.class, BiomeDatabase.CaveRootedData::setMaxDistToSurface);
99+
.register("max_dist_to_surface", Integer.class, BiomeDatabase.CaveRootedData::setMaxDistToSurface)
100+
.register("species", JsonElement.class, this::applyCaveRootedSpecies)
101+
.register("chance", JsonElement.class, this::applyCaveRootedChance);
100102

101103
ApplierResourceLoader.postApplierEvent(new EntryApplierRegistryEvent<>(this.entryAppliers, ENTRY_APPLIERS));
102104
}
@@ -135,6 +137,20 @@ private void applyMultipass(BiomeDatabase.BaseEntry entry, Boolean multipass) {
135137
entry.enableDefaultMultipass();
136138
}
137139

140+
private PropertyApplierResult applyCaveRootedSpecies(BiomeDatabase.CaveRootedData entry, JsonElement jsonElement) {
141+
return PropertyApplierResult.from(JsonDeserialisers.SPECIES_SELECTOR.deserialise(jsonElement)
142+
.ifSuccess(speciesSelector ->
143+
entry.setCaveRootedSpeciesSelector(speciesSelector, getOperationOrWarn(jsonElement))
144+
));
145+
}
146+
147+
private PropertyApplierResult applyCaveRootedChance(BiomeDatabase.CaveRootedData entry, JsonElement jsonElement) {
148+
return PropertyApplierResult.from(JsonDeserialisers.CHANCE_SELECTOR.deserialise(jsonElement)
149+
.ifSuccess(chanceSelector ->
150+
entry.setCaveRootedChanceSelector(chanceSelector, getOperationOrWarn(jsonElement))
151+
));
152+
}
153+
138154
public static BiomeDatabase.Operation getOperationOrWarn(final JsonElement jsonElement) {
139155
return getOperation(jsonElement).orElse(BiomeDatabase.Operation.REPLACE, LOGGER::error, LOGGER::warn);
140156
}
@@ -251,7 +267,6 @@ private void applyCaveRootedPopulatorSection(BiomeDatabase database, JsonObject
251267
JsonObject caveRootedJson = json.getAsJsonObject(CAVE_ROOTED);
252268
JsonMapWrapper applyData = new JsonMapWrapper(caveRootedJson);
253269
var entry = database.getJsonEntry(biomes);
254-
this.entryAppliers.applyAll(applyData, entry);
255270
this.caveRootedDataAppliers.applyAll(applyData, entry.getOrCreateCaveRootedData());
256271
}
257272
}

src/main/java/com/ferreusveritas/dynamictrees/worldgen/BiomeDatabase.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ public void reset() {
349349
}
350350

351351
public static class CaveRootedData {
352+
353+
SpeciesSelector speciesSelector = (pos, dirt, rnd) -> new SpeciesSelection();
354+
ChanceSelector chanceSelector = (rnd, spc, rad) -> Chance.UNHANDLED;
352355
/**
353356
* If {@code true}, the tree will always be generated on the surface. Otherwise, it will be
354357
* generated on the next available ground position.
@@ -376,6 +379,45 @@ public int getMaxDistToSurface() {
376379
public void setMaxDistToSurface(int maxDistToSurface) {
377380
this.maxDistToSurface = maxDistToSurface;
378381
}
382+
383+
public SpeciesSelector getCaveRootedSpeciesSelector() {
384+
return speciesSelector;
385+
}
386+
387+
public ChanceSelector getCaveRootedChanceSelector(){
388+
return chanceSelector;
389+
}
390+
391+
public void setCaveRootedSpeciesSelector(SpeciesSelector selector, Operation op) {
392+
SpeciesSelector existing = speciesSelector;
393+
switch (op) {
394+
case REPLACE -> speciesSelector = selector;
395+
case SPLICE_BEFORE -> speciesSelector = (pos, dirt, rnd) -> {
396+
SpeciesSelection ss = selector.getSpecies(pos, dirt, rnd);
397+
return ss.isHandled() ? ss : existing.getSpecies(pos, dirt, rnd);
398+
};
399+
case SPLICE_AFTER -> speciesSelector = (pos, dirt, rnd) -> {
400+
SpeciesSelection ss = existing.getSpecies(pos, dirt, rnd);
401+
return ss.isHandled() ? ss : selector.getSpecies(pos, dirt, rnd);
402+
};
403+
}
404+
}
405+
406+
public void setCaveRootedChanceSelector(ChanceSelector selector, Operation op) {
407+
ChanceSelector existing = chanceSelector;
408+
switch (op) {
409+
case REPLACE -> chanceSelector = selector;
410+
case SPLICE_BEFORE -> chanceSelector = (rnd, spc, rad) -> {
411+
Chance c = selector.getChance(rnd, spc, rad);
412+
return c != Chance.UNHANDLED ? c : existing.getChance(rnd, spc, rad);
413+
};
414+
case SPLICE_AFTER -> chanceSelector = (rnd, spc, rad) -> {
415+
Chance c = existing.getChance(rnd, spc, rad);
416+
return c != Chance.UNHANDLED ? c : selector.getChance(rnd, spc, rad);
417+
};
418+
}
419+
}
420+
379421
}
380422

381423
/**

src/main/java/com/ferreusveritas/dynamictrees/worldgen/CaveRootedTreeFeature.java

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
package com.ferreusveritas.dynamictrees.worldgen;
22

3+
import com.ferreusveritas.dynamictrees.api.worldgen.BiomePropertySelectors;
34
import com.ferreusveritas.dynamictrees.api.worldgen.GroundFinder;
45
import com.ferreusveritas.dynamictrees.systems.poissondisc.PoissonDisc;
56
import com.ferreusveritas.dynamictrees.util.LevelContext;
67
import com.ferreusveritas.dynamictrees.util.SafeChunkBounds;
78
import net.minecraft.core.BlockPos;
9+
import net.minecraft.core.Vec3i;
810
import net.minecraft.resources.ResourceLocation;
911
import net.minecraft.world.level.ChunkPos;
1012
import net.minecraft.world.level.WorldGenLevel;
1113
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
1214
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
1315

16+
import java.util.Comparator;
1417
import java.util.List;
1518
import java.util.Optional;
19+
import java.util.concurrent.atomic.AtomicBoolean;
1620

1721
public class CaveRootedTreeFeature extends DynamicTreeFeature {
1822

@@ -41,18 +45,41 @@ public boolean place(FeaturePlaceContext<NoneFeatureConfiguration> context) {
4145
}
4246

4347
BiomeDatabase.Entry biomeEntry = BiomeDatabases.getDefault().getEntry(level.getLevel().getBiome(originPos));
44-
if (!biomeEntry.hasCaveRootedData())
48+
if (biomeEntry.getCaveRootedData() == null)
4549
return false;
4650

4751
BiomeDatabase.CaveRootedData caveRootedData = biomeEntry.getCaveRootedData();
48-
BlockPos groundPos = caveRootedData.shouldGenerateOnSurface() ? groundPositions.get(groundPositions.size() - 1)
49-
: getNextGroundPos(originPos, groundPositions).orElse(null);
50-
if (groundPos == null || groundPos.getY() - originPos.getY() > caveRootedData.getMaxDistToSurface()) {
51-
return false;
52+
53+
groundPositions = groundPositions.stream()
54+
.filter(pos-> pos != BlockPos.ZERO)
55+
//.filter(pos-> pos.getY() - originPos.getY() < caveRootedData.getMaxDistToSurface())
56+
.sorted(Comparator.comparingInt(Vec3i::getY)).toList();
57+
58+
if (groundPositions.isEmpty()) return false;
59+
60+
if (caveRootedData.shouldGenerateOnSurface()){
61+
groundPositions = List.of(groundPositions.get(groundPositions.size() - 1));
5262
}
5363

54-
GeneratorResult result = this.generateTree(levelContext, biomeEntry, disc, originPos, groundPos, SafeChunkBounds.ANY_WG);
55-
return result == GeneratorResult.GENERATED;
64+
AtomicBoolean generated = new AtomicBoolean(false);
65+
groundPositions.forEach(groundPos -> {
66+
GeneratorResult result = this.generateTree(levelContext, biomeEntry, disc, originPos, groundPos, SafeChunkBounds.ANY_WG);
67+
if (result == GeneratorResult.GENERATED) generated.set(true);
68+
});
69+
70+
return generated.get();
71+
}
72+
73+
protected BiomePropertySelectors.SpeciesSelector getSpeciesSelector (BiomeDatabase.EntryReader biomeEntry){
74+
if (biomeEntry instanceof BiomeDatabase.Entry entry && entry.getCaveRootedData() != null)
75+
return entry.getCaveRootedData().getCaveRootedSpeciesSelector();
76+
return biomeEntry.getSpeciesSelector();
77+
}
78+
79+
protected BiomePropertySelectors.ChanceSelector getChanceSelector (BiomeDatabase.EntryReader biomeEntry){
80+
if (biomeEntry instanceof BiomeDatabase.Entry entry && entry.getCaveRootedData() != null)
81+
return entry.getCaveRootedData().getCaveRootedChanceSelector();
82+
return biomeEntry.getChanceSelector();
5683
}
5784

5885
private Optional<PoissonDisc> getDisc(LevelContext levelContext, ChunkPos chunkPos, BlockPos originPos) {

src/main/java/com/ferreusveritas/dynamictrees/worldgen/DynamicTreeFeature.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ protected void generateTrees(LevelContext levelContext, BiomeDatabase biomeDatab
7979
Holder<Biome> biome = levelContext.accessor().getBiome(basePos);
8080
Heightmap.Types heightmap = Heightmap.Types.valueOf(biomeDatabase.getHeightmap(biome).toUpperCase());
8181
for (BlockPos groundPos : GroundFinder.getGroundFinder(levelContext.level()).findGround(levelContext.accessor(), basePos, heightmap)) {
82-
BiomeDatabase.EntryReader entry = biomeDatabase.getEntry(levelContext.accessor().getBiome(groundPos));
82+
BiomeDatabase.Entry entry = biomeDatabase.getEntry(levelContext.accessor().getBiome(groundPos));
8383
generateTree(levelContext, entry, disc, originPos, groundPos, safeBounds);
8484
}
8585
}
@@ -105,14 +105,14 @@ protected GeneratorResult generateTree(LevelContext levelContext, BiomeDatabase.
105105

106106
GeneratorResult result = GeneratorResult.GENERATED;
107107

108-
BiomePropertySelectors.SpeciesSelector speciesSelector = biomeEntry.getSpeciesSelector();
108+
BiomePropertySelectors.SpeciesSelector speciesSelector = getSpeciesSelector(biomeEntry);
109109
BiomePropertySelectors.SpeciesSelection speciesSelection = speciesSelector.getSpecies(groundPos, dirtState, RANDOM);
110110

111111
if (!biomeEntry.isBlacklisted() && speciesSelection.isHandled()) {
112112
Species species = speciesSelection.getSpecies();
113113
if (species.isValid()) {
114114
if (species.isAcceptableSoilForWorldgen(levelContext.accessor(), groundPos, dirtState)) {
115-
if (biomeEntry.getChanceSelector().getChance(RANDOM, species, circle.radius) == BiomePropertySelectors.Chance.OK) {
115+
if (getChanceSelector(biomeEntry).getChance(RANDOM, species, circle.radius) == BiomePropertySelectors.Chance.OK) {
116116
Holder<Biome> biome = levelContext.level().getBiome(groundPos);
117117
if (!species.generate(new GenerationContext(levelContext, species, originPos, groundPos.mutable(), biome, CoordUtils.getRandomDir(RANDOM), circle.radius, safeBounds))) {
118118
result = GeneratorResult.FAIL_GENERATION;
@@ -138,6 +138,13 @@ protected GeneratorResult generateTree(LevelContext levelContext, BiomeDatabase.
138138
return result;
139139
}
140140

141+
protected BiomePropertySelectors.SpeciesSelector getSpeciesSelector (BiomeDatabase.EntryReader biomeEntry){
142+
return biomeEntry.getSpeciesSelector();
143+
}
144+
protected BiomePropertySelectors.ChanceSelector getChanceSelector (BiomeDatabase.EntryReader biomeEntry){
145+
return biomeEntry.getChanceSelector();
146+
}
147+
141148
private void generateConcreteCircle(LevelAccessor level, PoissonDisc circle, int h, GeneratorResult resultType, SafeChunkBounds safeBounds) {
142149
generateConcreteCircle(level, circle, h, resultType, safeBounds, 0);
143150
}

src/main/java/com/ferreusveritas/dynamictrees/worldgen/biomemodifiers/AddDynamicTreesBiomeModifier.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public void modify(Holder<Biome> biome, Phase phase, ModifiableBiomeInfo.BiomeIn
2121
if (phase == Phase.ADD && DTConfigs.WORLD_GEN.get()) {
2222
BiomeGenerationSettingsBuilder generationSettings = builder.getGenerationSettings();
2323
var placedFeatures = ServerLifecycleHooks.getCurrentServer().registryAccess().registryOrThrow(Registries.PLACED_FEATURE);
24-
generationSettings.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, placedFeatures.getHolderOrThrow(DTFeatures.DYNAMIC_TREE_PLACED_FEATURE));
2524
generationSettings.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, placedFeatures.getHolderOrThrow(DTFeatures.CAVE_ROOTED_TREE_PLACED_FEATURE));
25+
generationSettings.addFeature(GenerationStep.Decoration.VEGETAL_DECORATION, placedFeatures.getHolderOrThrow(DTFeatures.DYNAMIC_TREE_PLACED_FEATURE));
2626
}
2727
}
2828

src/main/resources/trees/dynamictrees/world_gen/default.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@
260260
"apply": {
261261
"cave_rooted": {
262262
"species": "azalea",
263-
"chance": 0.66
263+
"chance": 1.0
264264
}
265265
}
266266
},

0 commit comments

Comments
 (0)