Possible fix for missing SurfaceRules in Datapack worlds

This commit is contained in:
Frank 2021-12-13 16:33:18 +01:00
parent ff49e1325c
commit 835f4895b3
4 changed files with 82 additions and 32 deletions

View file

@ -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.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
import net.minecraft.world.level.levelgen.SurfaceRules; 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.carver.ConfiguredWorldCarver;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature;
@ -483,15 +484,9 @@ public class BiomeAPI {
} }
if (generator != null) { if (generator != null) {
List<SurfaceRules.RuleSource> rules = getRuleSources(biomes, level.dimension()); List<SurfaceRules.RuleSource> rules = getRuleSources(biomes);
SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(generator); SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(generator);
if (rules.size() > 0) { changeSurfaceRules(rules, provider);
rules.add(provider.getSurfaceRule());
provider.setSurfaceRule(SurfaceRules.sequence(rules.toArray(new SurfaceRules.RuleSource[rules.size()])));
}
else {
provider.setSurfaceRule(null);
}
} }
List<BiConsumer<ResourceLocation, Biome>> modifications = MODIFICATIONS.get(level.dimension()); List<BiConsumer<ResourceLocation, Biome>> modifications = MODIFICATIONS.get(level.dimension());
@ -532,8 +527,14 @@ public class BiomeAPI {
accessor.bclib_setFeatures(featureList); accessor.bclib_setFeatures(featureList);
} }
private static List<SurfaceRules.RuleSource> getRuleSources(Set<Biome> biomes, ResourceKey<Level> dimensionType) { private static List<SurfaceRules.RuleSource> getRuleSources(Set<Biome> biomes) {
Set<ResourceLocation> biomeIDs = biomes.stream().map(biome -> getBiomeID(biome)).collect(Collectors.toSet()); Set<ResourceLocation> biomeIDs = biomes.stream()
.map(biome -> getBiomeID(biome))
.collect(Collectors.toSet());
return getRuleSourcesFromIDs(biomeIDs);
}
private static List<SurfaceRules.RuleSource> getRuleSourcesFromIDs(Set<ResourceLocation> biomeIDs) {
List<SurfaceRules.RuleSource> rules = Lists.newArrayList(); List<SurfaceRules.RuleSource> rules = Lists.newArrayList();
SURFACE_RULES.forEach((biomeID, rule) -> { SURFACE_RULES.forEach((biomeID, rule) -> {
if (biomeIDs.contains(biomeID)) { if (biomeIDs.contains(biomeID)) {
@ -792,13 +793,31 @@ public class BiomeAPI {
.event(v.get()) .event(v.get())
.register((rawId, id, object) -> { .register((rawId, id, object) -> {
//BCLib.LOGGER.info(" #### " + rawId + ", " + object + ", " + id); //BCLib.LOGGER.info(" #### " + rawId + ", " + object + ", " + id);
//add back modded structures
StructureSettingsAccessor a = (StructureSettingsAccessor)object.structureSettings(); StructureSettingsAccessor a = (StructureSettingsAccessor)object.structureSettings();
structureStarts.forEach(modifier -> changeStructureStarts(a, modifier)); structureStarts.forEach(modifier -> changeStructureStarts(a, modifier));
//add surface rules
if (biomeRegistry!=null) {
List<SurfaceRules.RuleSource> rules = getRuleSourcesFromIDs(biomeRegistry.keySet());
SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(object);
changeSurfaceRules(rules, provider);
}
}); });
} }
}); });
} }
private static void changeSurfaceRules(List<RuleSource> rules, SurfaceRuleProvider provider) {
if (rules.size() > 0) {
provider.addCustomRules(rules);
}
else {
provider.clearCustomRules();
}
}
public static void clearStructureStarts(){ public static void clearStructureStarts(){
structureStarts.clear(); structureStarts.clear();
} }

View file

@ -1,9 +1,10 @@
package ru.bclib.interfaces; 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 { public interface SurfaceRuleProvider {
void setSurfaceRule(SurfaceRules.RuleSource surfaceRule); void clearCustomRules();
void addCustomRules(List<RuleSource> rules);
SurfaceRules.RuleSource getSurfaceRule();
} }

View file

@ -3,36 +3,65 @@ package ru.bclib.mixin.common;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
import net.minecraft.world.level.levelgen.SurfaceRules; import net.minecraft.world.level.levelgen.SurfaceRules;
import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource; 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.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow; 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 ru.bclib.interfaces.SurfaceRuleProvider;
import java.util.List;
import java.util.stream.Collectors;
@Mixin(NoiseGeneratorSettings.class) @Mixin(NoiseGeneratorSettings.class)
public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider { public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider {
@Mutable
@Final @Final
@Shadow @Shadow
private SurfaceRules.RuleSource surfaceRule; private SurfaceRules.RuleSource surfaceRule;
private SurfaceRules.RuleSource bclib_surfaceRule; private SurfaceRules.RuleSource bclib_originalSurfaceRule;
@Override @Override
public void setSurfaceRule(SurfaceRules.RuleSource surfaceRule) { public void clearCustomRules() {
bclib_surfaceRule = surfaceRule; if (bclib_originalSurfaceRule != null){
} this.surfaceRule = bclib_originalSurfaceRule;
bclib_originalSurfaceRule = null;
@Override
public RuleSource getSurfaceRule() {
return surfaceRule;
}
@Inject(method = "surfaceRule", at = @At("HEAD"), cancellable = true)
private void bclib_surfaceRule(CallbackInfoReturnable<SurfaceRules.RuleSource> info) {
if (bclib_surfaceRule != null) {
info.setReturnValue(bclib_surfaceRule);
} }
} }
@Override
public void addCustomRules(List<RuleSource> rules) {
RuleSource org = getOriginalSurfaceRule();
if (org instanceof SurfaceRules.SequenceRuleSource sequenceRule){
List<RuleSource> 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<SurfaceRules.RuleSource> info) {
// if (bclib_surfaceRule != null) {
// info.setReturnValue(bclib_surfaceRule);
// }
// }
} }

View file

@ -6,3 +6,4 @@ 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$Condition
accessible class net/minecraft/world/level/levelgen/SurfaceRules$LazyXZCondition accessible class net/minecraft/world/level/levelgen/SurfaceRules$LazyXZCondition
accessible class net/minecraft/world/level/levelgen/SurfaceRules$LazyCondition accessible class net/minecraft/world/level/levelgen/SurfaceRules$LazyCondition
accessible class net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSource