diff --git a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java index 17f4b745..633f4330 100644 --- a/src/main/java/ru/bclib/api/biomes/BiomeAPI.java +++ b/src/main/java/ru/bclib/api/biomes/BiomeAPI.java @@ -40,6 +40,7 @@ import net.minecraft.world.level.levelgen.GenerationStep.Decoration; import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.SurfaceRules; +import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource; import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; @@ -483,15 +484,9 @@ public class BiomeAPI { } if (generator != null) { - List rules = getRuleSources(biomes, level.dimension()); + List rules = getRuleSources(biomes); SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(generator); - if (rules.size() > 0) { - rules.add(provider.getSurfaceRule()); - provider.setSurfaceRule(SurfaceRules.sequence(rules.toArray(new SurfaceRules.RuleSource[rules.size()]))); - } - else { - provider.setSurfaceRule(null); - } + changeSurfaceRules(rules, provider); } List> modifications = MODIFICATIONS.get(level.dimension()); @@ -532,8 +527,14 @@ public class BiomeAPI { accessor.bclib_setFeatures(featureList); } - private static List getRuleSources(Set biomes, ResourceKey dimensionType) { - Set biomeIDs = biomes.stream().map(biome -> getBiomeID(biome)).collect(Collectors.toSet()); + private static List getRuleSources(Set biomes) { + Set biomeIDs = biomes.stream() + .map(biome -> getBiomeID(biome)) + .collect(Collectors.toSet()); + return getRuleSourcesFromIDs(biomeIDs); + } + + private static List getRuleSourcesFromIDs(Set biomeIDs) { List rules = Lists.newArrayList(); SURFACE_RULES.forEach((biomeID, rule) -> { if (biomeIDs.contains(biomeID)) { @@ -792,13 +793,31 @@ public class BiomeAPI { .event(v.get()) .register((rawId, id, object) -> { //BCLib.LOGGER.info(" #### " + rawId + ", " + object + ", " + id); + + //add back modded structures StructureSettingsAccessor a = (StructureSettingsAccessor)object.structureSettings(); structureStarts.forEach(modifier -> changeStructureStarts(a, modifier)); + + //add surface rules + if (biomeRegistry!=null) { + List rules = getRuleSourcesFromIDs(biomeRegistry.keySet()); + SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(object); + changeSurfaceRules(rules, provider); + } }); } }); } + private static void changeSurfaceRules(List rules, SurfaceRuleProvider provider) { + if (rules.size() > 0) { + provider.addCustomRules(rules); + } + else { + provider.clearCustomRules(); + } + } + public static void clearStructureStarts(){ structureStarts.clear(); } diff --git a/src/main/java/ru/bclib/interfaces/SurfaceRuleProvider.java b/src/main/java/ru/bclib/interfaces/SurfaceRuleProvider.java index 214fd851..fe40c99a 100644 --- a/src/main/java/ru/bclib/interfaces/SurfaceRuleProvider.java +++ b/src/main/java/ru/bclib/interfaces/SurfaceRuleProvider.java @@ -1,9 +1,10 @@ package ru.bclib.interfaces; -import net.minecraft.world.level.levelgen.SurfaceRules; +import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource; + +import java.util.List; public interface SurfaceRuleProvider { - void setSurfaceRule(SurfaceRules.RuleSource surfaceRule); - - SurfaceRules.RuleSource getSurfaceRule(); + void clearCustomRules(); + void addCustomRules(List rules); } diff --git a/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java b/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java index 267df1f6..144eacc2 100644 --- a/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java +++ b/src/main/java/ru/bclib/mixin/common/NoiseGeneratorSettingsMixin.java @@ -3,36 +3,65 @@ package ru.bclib.mixin.common; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.SurfaceRules; import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource; +import org.apache.commons.codec.language.bm.Rule; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import ru.bclib.interfaces.SurfaceRuleProvider; +import java.util.List; +import java.util.stream.Collectors; + @Mixin(NoiseGeneratorSettings.class) public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider { + @Mutable @Final @Shadow private SurfaceRules.RuleSource surfaceRule; - private SurfaceRules.RuleSource bclib_surfaceRule; + private SurfaceRules.RuleSource bclib_originalSurfaceRule; @Override - public void setSurfaceRule(SurfaceRules.RuleSource surfaceRule) { - bclib_surfaceRule = surfaceRule; - } - - @Override - public RuleSource getSurfaceRule() { - return surfaceRule; - } - - @Inject(method = "surfaceRule", at = @At("HEAD"), cancellable = true) - private void bclib_surfaceRule(CallbackInfoReturnable info) { - if (bclib_surfaceRule != null) { - info.setReturnValue(bclib_surfaceRule); + public void clearCustomRules() { + if (bclib_originalSurfaceRule != null){ + this.surfaceRule = bclib_originalSurfaceRule; + bclib_originalSurfaceRule = null; } } + + @Override + public void addCustomRules(List rules) { + RuleSource org = getOriginalSurfaceRule(); + if (org instanceof SurfaceRules.SequenceRuleSource sequenceRule){ + List currentSequence = sequenceRule.sequence(); + rules = rules.stream().filter(r -> currentSequence.indexOf(r)<0).collect(Collectors.toList()); + rules.addAll(sequenceRule.sequence()); + } else { + rules.add(org); + } + setSurfaceRule(SurfaceRules.sequence(rules.toArray(new RuleSource[rules.size()]))); + } + + void setSurfaceRule(SurfaceRules.RuleSource surfaceRule) { + if (bclib_originalSurfaceRule == null){ + bclib_originalSurfaceRule = this.surfaceRule; + } + this.surfaceRule = surfaceRule; + } + + RuleSource getOriginalSurfaceRule() { + if (bclib_originalSurfaceRule ==null) { + return surfaceRule; + } + + return bclib_originalSurfaceRule; + } + +// @Inject(method = "surfaceRule", at = @At("HEAD"), cancellable = true) +// private void bclib_surfaceRule(CallbackInfoReturnable info) { +// if (bclib_surfaceRule != null) { +// info.setReturnValue(bclib_surfaceRule); +// } +// } } diff --git a/src/main/resources/bclib.accesswidener b/src/main/resources/bclib.accesswidener index f29e3ed9..26921210 100644 --- a/src/main/resources/bclib.accesswidener +++ b/src/main/resources/bclib.accesswidener @@ -5,4 +5,5 @@ accessible class net/minecraft/client/Minecraft$ExperimentalDialogType accessible class net/minecraft/world/level/levelgen/SurfaceRules$Context accessible class net/minecraft/world/level/levelgen/SurfaceRules$Condition accessible class net/minecraft/world/level/levelgen/SurfaceRules$LazyXZCondition -accessible class net/minecraft/world/level/levelgen/SurfaceRules$LazyCondition \ No newline at end of file +accessible class net/minecraft/world/level/levelgen/SurfaceRules$LazyCondition +accessible class net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSource \ No newline at end of file