Cleanup and Speed Improvement of SurfaceRules/Structures (paulevsGitch/BetterNether#485, paulevsGitch/BetterEnd#420)
This commit is contained in:
parent
01f728c282
commit
baf1e0f4b1
10 changed files with 144 additions and 189 deletions
|
@ -48,8 +48,6 @@ public class BCLib implements ModInitializer {
|
||||||
Chunker.DESCRIPTOR
|
Chunker.DESCRIPTOR
|
||||||
));
|
));
|
||||||
|
|
||||||
BiomeAPI.registerStructureEvents();
|
|
||||||
|
|
||||||
BCLibPatch.register();
|
BCLibPatch.register();
|
||||||
Configs.save();
|
Configs.save();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
package ru.bclib.api.biomes;
|
package ru.bclib.api.biomes;
|
||||||
|
|
||||||
import com.google.common.collect.HashMultimap;
|
import com.google.common.collect.*;
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
|
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
|
||||||
|
@ -28,11 +22,7 @@ import net.minecraft.world.entity.MobCategory;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.*;
|
||||||
import net.minecraft.world.level.biome.BiomeGenerationSettings;
|
|
||||||
import net.minecraft.world.level.biome.BiomeSource;
|
|
||||||
import net.minecraft.world.level.biome.Biomes;
|
|
||||||
import net.minecraft.world.level.biome.Climate;
|
|
||||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
@ -43,6 +33,7 @@ import net.minecraft.world.level.levelgen.GenerationStep.Carving;
|
||||||
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
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.StructureSettings;
|
||||||
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 net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
|
import net.minecraft.world.level.levelgen.carver.ConfiguredWorldCarver;
|
||||||
|
@ -56,10 +47,7 @@ import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import ru.bclib.BCLib;
|
import ru.bclib.BCLib;
|
||||||
import ru.bclib.entity.BCLEntityWrapper;
|
import ru.bclib.entity.BCLEntityWrapper;
|
||||||
import ru.bclib.interfaces.BiomeSourceAccessor;
|
import ru.bclib.interfaces.*;
|
||||||
import ru.bclib.interfaces.SurfaceMaterialProvider;
|
|
||||||
import ru.bclib.interfaces.SurfaceProvider;
|
|
||||||
import ru.bclib.interfaces.SurfaceRuleProvider;
|
|
||||||
import ru.bclib.mixin.common.BiomeGenerationSettingsAccessor;
|
import ru.bclib.mixin.common.BiomeGenerationSettingsAccessor;
|
||||||
import ru.bclib.mixin.common.BiomeSourceMixin;
|
import ru.bclib.mixin.common.BiomeSourceMixin;
|
||||||
import ru.bclib.mixin.common.MobSpawnSettingsAccessor;
|
import ru.bclib.mixin.common.MobSpawnSettingsAccessor;
|
||||||
|
@ -73,16 +61,8 @@ import ru.bclib.world.features.BCLFeature;
|
||||||
import ru.bclib.world.generator.BiomePicker;
|
import ru.bclib.world.generator.BiomePicker;
|
||||||
import ru.bclib.world.structures.BCLStructureFeature;
|
import ru.bclib.world.structures.BCLStructureFeature;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -108,8 +88,8 @@ public class BiomeAPI {
|
||||||
private final static Map<StructureID, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>>> STRUCTURE_STARTS = new HashMap<>();
|
private final static Map<StructureID, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>>> STRUCTURE_STARTS = new HashMap<>();
|
||||||
private static final Map<ResourceKey, List<BiConsumer<ResourceLocation, Biome>>> MODIFICATIONS = Maps.newHashMap();
|
private static final Map<ResourceKey, List<BiConsumer<ResourceLocation, Biome>>> MODIFICATIONS = Maps.newHashMap();
|
||||||
private static final Map<ResourceLocation, SurfaceRules.RuleSource> SURFACE_RULES = Maps.newHashMap();
|
private static final Map<ResourceLocation, SurfaceRules.RuleSource> SURFACE_RULES = Maps.newHashMap();
|
||||||
private static final Set<NoiseGeneratorSettings> NOISE_GENERATOR_SETTINGS = new HashSet<>();
|
private static final Set<SurfaceRuleProvider> MODIFIED_SURFACE_PROVIDERS = new HashSet<>(8);
|
||||||
|
|
||||||
public static final BCLBiome NETHER_WASTES_BIOME = registerNetherBiome(getFromRegistry(Biomes.NETHER_WASTES));
|
public static final BCLBiome NETHER_WASTES_BIOME = registerNetherBiome(getFromRegistry(Biomes.NETHER_WASTES));
|
||||||
public static final BCLBiome CRIMSON_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.CRIMSON_FOREST));
|
public static final BCLBiome CRIMSON_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.CRIMSON_FOREST));
|
||||||
public static final BCLBiome WARPED_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.WARPED_FOREST));
|
public static final BCLBiome WARPED_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.WARPED_FOREST));
|
||||||
|
@ -155,42 +135,18 @@ public class BiomeAPI {
|
||||||
CLIENT.clear();
|
CLIENT.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Set<BiomeSource> worldSources = new HashSet<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For internal use only.
|
|
||||||
*
|
|
||||||
* Used by {@link BiomeSourceMixin} to add new BiomeSources to the BiomeAPI. We need to know all
|
|
||||||
* created Sources in order to rebuild their feature set whenever biomes get recreated
|
|
||||||
* through a datapack.
|
|
||||||
* @param source The new {@link BiomeSource}
|
|
||||||
*/
|
|
||||||
public static void registerBiomeSource(BiomeSource source){
|
|
||||||
worldSources.add(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static WorldData worldData;
|
|
||||||
public static void registerWorldData(WorldData w){
|
|
||||||
worldData = w;
|
|
||||||
if (worldData!=null){
|
|
||||||
worldData.worldGenSettings().dimensions().forEach(dim->{
|
|
||||||
StructureSettingsAccessor a = (StructureSettingsAccessor)dim.generator().getSettings();
|
|
||||||
STRUCTURE_STARTS.entrySet().forEach(entry -> applyStructureStarts(a, entry.getValue()));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For internal use only.
|
* For internal use only.
|
||||||
*
|
*
|
||||||
* This method gets called before a world is loaded/created to flush cashes we build. The Method is
|
* This method gets called before a world is loaded/created to flush cashes we build. The Method is
|
||||||
* called from {@link ru.bclib.mixin.client.MinecraftMixin}
|
* called from {@link ru.bclib.mixin.client.MinecraftMixin}
|
||||||
*/
|
*/
|
||||||
public static void prepareWorldData(){
|
public static void prepareNewLevel(){
|
||||||
STRUCTURE_STARTS.clear();
|
STRUCTURE_STARTS.clear();
|
||||||
worldSources.clear();
|
|
||||||
NOISE_GENERATOR_SETTINGS.clear();
|
MODIFIED_SURFACE_PROVIDERS.forEach(p->p.bclib_clearBiomeSources());
|
||||||
|
MODIFIED_SURFACE_PROVIDERS.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -517,34 +473,60 @@ public class BiomeAPI {
|
||||||
* @param level
|
* @param level
|
||||||
*/
|
*/
|
||||||
public static void applyModifications(ServerLevel level) {
|
public static void applyModifications(ServerLevel level) {
|
||||||
BiomeSource source = level.getChunkSource().getGenerator().getBiomeSource();
|
final BiomeSource source = level.getChunkSource().getGenerator().getBiomeSource();
|
||||||
Set<Biome> biomes = source.possibleBiomes();
|
final StructureSettings settings = level.getChunkSource().getGenerator().getSettings();
|
||||||
|
final Set<Biome> biomes = source.possibleBiomes();
|
||||||
NoiseGeneratorSettings generator = null;
|
|
||||||
if (level.dimension() == Level.NETHER) {
|
NoiseGeneratorSettings generator = level
|
||||||
generator = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.NETHER);
|
.getServer()
|
||||||
|
.getWorldData()
|
||||||
|
.worldGenSettings()
|
||||||
|
.dimensions()
|
||||||
|
.stream()
|
||||||
|
.filter(dim->dim.generator().getSettings()==settings)
|
||||||
|
.map(dim->((NoiseGeneratorSettingsProvider)dim.generator()).bclib_getNoiseGeneratorSettings()).findFirst().orElse(null);;
|
||||||
|
|
||||||
|
// Datapacks (like Amplified Nether)will change the GeneratorSettings upon load, so we will
|
||||||
|
// only use the default Setting for Nether/End if we were unable to find a settings object
|
||||||
|
if (generator==null){
|
||||||
|
if (level.dimension() == Level.NETHER) {
|
||||||
|
generator = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.NETHER);
|
||||||
|
} else if (level.dimension() == Level.END) {
|
||||||
|
generator = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.END);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (level.dimension() == Level.END) {
|
|
||||||
generator = BuiltinRegistries.NOISE_GENERATOR_SETTINGS.get(NoiseGeneratorSettings.END);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (generator != null) {
|
|
||||||
List<SurfaceRules.RuleSource> rules = getRuleSources(biomes);
|
|
||||||
SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(generator);
|
|
||||||
changeSurfaceRules(rules, provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<BiConsumer<ResourceLocation, Biome>> modifications = MODIFICATIONS.get(level.dimension());
|
List<BiConsumer<ResourceLocation, Biome>> modifications = MODIFICATIONS.get(level.dimension());
|
||||||
if (modifications == null) {
|
if (modifications == null) {
|
||||||
biomes.forEach(biome -> sortBiomeFeatures(biome));
|
biomes.forEach(biome -> sortBiomeFeatures(biome));
|
||||||
((BiomeSourceAccessor) source).bclRebuildFeatures();
|
} else {
|
||||||
return;
|
biomes.forEach(biome -> {
|
||||||
|
applyModificationsToBiome(modifications, biome);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
biomes.forEach(biome -> {
|
if (generator != null) {
|
||||||
applyModificationsToBiome(modifications, biome);
|
final SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(generator);
|
||||||
});
|
// Multiple Biomes can use the same generator. So we need to keep track of all Biomes that are
|
||||||
|
// Provided by all the BiomeSources that use the same generator.
|
||||||
|
// This happens for example when using the MiningDimensions, which reuses the generator for the
|
||||||
|
// Nethering Dimension
|
||||||
|
MODIFIED_SURFACE_PROVIDERS.add(provider);
|
||||||
|
provider.bclib_addBiomeSource(source);
|
||||||
|
} else {
|
||||||
|
BCLib.LOGGER.warning("No generator for " + source);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings!=null){
|
||||||
|
final StructureSettingsAccessor settingsAccessor = (StructureSettingsAccessor)settings;
|
||||||
|
final Set<ResourceLocation> biomeIDs = biomes.stream().map(BiomeAPI::getBiomeID).collect(Collectors.toSet());
|
||||||
|
for (Entry<StructureID, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>>> e : STRUCTURE_STARTS.entrySet()) {
|
||||||
|
if (biomeIDs.contains(e.getKey().biomeID)) {
|
||||||
|
applyStructureStarts(settingsAccessor, e.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
((BiomeSourceAccessor) source).bclRebuildFeatures();
|
((BiomeSourceAccessor) source).bclRebuildFeatures();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,6 +544,10 @@ public class BiomeAPI {
|
||||||
sortBiomeFeatures(biome);
|
sortBiomeFeatures(biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a unique sort order for all Features of the Biome
|
||||||
|
* @param biome The {@link Biome} to sort the features for
|
||||||
|
*/
|
||||||
public static void sortBiomeFeatures(Biome biome) {
|
public static void sortBiomeFeatures(Biome biome) {
|
||||||
BiomeGenerationSettings settings = biome.getGenerationSettings();
|
BiomeGenerationSettings settings = biome.getGenerationSettings();
|
||||||
BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) settings;
|
BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) settings;
|
||||||
|
@ -575,7 +561,7 @@ public class BiomeAPI {
|
||||||
accessor.bclib_setFeatures(featureList);
|
accessor.bclib_setFeatures(featureList);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<SurfaceRules.RuleSource> getRuleSources(Set<Biome> biomes) {
|
private static List<SurfaceRules.RuleSource> getRuleSourcesForBiomes(Set<Biome> biomes) {
|
||||||
Set<ResourceLocation> biomeIDs = biomes
|
Set<ResourceLocation> biomeIDs = biomes
|
||||||
.stream()
|
.stream()
|
||||||
.map(biome -> getBiomeID(biome))
|
.map(biome -> getBiomeID(biome))
|
||||||
|
@ -583,12 +569,23 @@ public class BiomeAPI {
|
||||||
return getRuleSourcesFromIDs(biomeIDs);
|
return getRuleSourcesFromIDs(biomeIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<SurfaceRules.RuleSource> getAllRuleSources() {
|
/**
|
||||||
List<SurfaceRules.RuleSource> rules = Lists.newArrayList();
|
* Creates a list of SurfaceRules for all Biomes that are managed by the passed {@link BiomeSource}.
|
||||||
SURFACE_RULES.forEach((biomeID, rule) -> {
|
* If we have Surface rules for any of the Biomes from the given set of {@link BiomeSource}, they
|
||||||
rules.add(rule);
|
* will be added to the result
|
||||||
});
|
*
|
||||||
return rules;
|
* Note: This Method is used in the {@link ru.bclib.mixin.common.NoiseGeneratorSettingsMixin} which in turn
|
||||||
|
* is called from {@link #applyModifications(ServerLevel)}.
|
||||||
|
* @param sources The Set of {@link BiomeSource} we want to consider
|
||||||
|
* @return A list of {@link RuleSource}-Objects that are needed to create those Biomes
|
||||||
|
*/
|
||||||
|
public static List<SurfaceRules.RuleSource> getRuleSources(Set<BiomeSource> sources) {
|
||||||
|
final Set<Biome> biomes = new HashSet<>();
|
||||||
|
for (BiomeSource s : sources) {
|
||||||
|
biomes.addAll(s.possibleBiomes());
|
||||||
|
}
|
||||||
|
|
||||||
|
return getRuleSourcesForBiomes(biomes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<SurfaceRules.RuleSource> getRuleSourcesFromIDs(Set<ResourceLocation> biomeIDs) {
|
private static List<SurfaceRules.RuleSource> getRuleSourcesFromIDs(Set<ResourceLocation> biomeIDs) {
|
||||||
|
@ -643,11 +640,12 @@ public class BiomeAPI {
|
||||||
/**
|
/**
|
||||||
* For internal use only!
|
* For internal use only!
|
||||||
*
|
*
|
||||||
* Adds new features to existing biome. Called from {@link BCLBiome#setFeatures(Map)} when the Biome is first built
|
* Adds new features to existing biome. Called from {@link #applyModificationsToBiome(List, Biome)} when the Biome is
|
||||||
|
* present in any {@link BiomeSource}
|
||||||
* @param biome {@link Biome} to add features in.
|
* @param biome {@link Biome} to add features in.
|
||||||
* @param featureMap Map of {@link ConfiguredFeature} to add.
|
* @param featureMap Map of {@link ConfiguredFeature} to add.
|
||||||
*/
|
*/
|
||||||
public static void addStepFeaturesToBiome(Biome biome, Map<Decoration, List<Supplier<PlacedFeature>>> featureMap) {
|
private static void addStepFeaturesToBiome(Biome biome, Map<Decoration, List<Supplier<PlacedFeature>>> featureMap) {
|
||||||
BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings();
|
BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) biome.getGenerationSettings();
|
||||||
List<List<Supplier<PlacedFeature>>> allFeatures = CollectionsUtil.getMutable(accessor.bclib_getFeatures());
|
List<List<Supplier<PlacedFeature>>> allFeatures = CollectionsUtil.getMutable(accessor.bclib_getFeatures());
|
||||||
Set<PlacedFeature> set = CollectionsUtil.getMutable(accessor.bclib_getFeatureSet());
|
Set<PlacedFeature> set = CollectionsUtil.getMutable(accessor.bclib_getFeatureSet());
|
||||||
|
@ -685,7 +683,12 @@ public class BiomeAPI {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an existing StructureFeature to a Biome
|
||||||
|
* @param biome The {@link Biome} you want to add teh feature to
|
||||||
|
* @param structure The {@link ConfiguredStructureFeature} to add
|
||||||
|
*/
|
||||||
public static void addBiomeStructure(Biome biome, ConfiguredStructureFeature structure) {
|
public static void addBiomeStructure(Biome biome, ConfiguredStructureFeature structure) {
|
||||||
changeStructureStarts(BiomeAPI.getBiomeID(biome), structure, (structureMap, configMap) -> {
|
changeStructureStarts(BiomeAPI.getBiomeID(biome), structure, (structureMap, configMap) -> {
|
||||||
Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>> configuredMap = structureMap.computeIfAbsent(structure.feature, k -> HashMultimap.create());
|
Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>> configuredMap = structureMap.computeIfAbsent(structure.feature, k -> HashMultimap.create());
|
||||||
|
@ -744,7 +747,7 @@ public class BiomeAPI {
|
||||||
*/
|
*/
|
||||||
public static void addSurfaceRule(ResourceLocation biomeID, SurfaceRules.RuleSource source) {
|
public static void addSurfaceRule(ResourceLocation biomeID, SurfaceRules.RuleSource source) {
|
||||||
SURFACE_RULES.put(biomeID, source);
|
SURFACE_RULES.put(biomeID, source);
|
||||||
NOISE_GENERATOR_SETTINGS.forEach(BiomeAPI::changeSurfaceRulesForGenerator);
|
//NOISE_GENERATOR_SETTINGS.forEach(BiomeAPI::changeSurfaceRulesForGenerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -859,17 +862,17 @@ public class BiomeAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
static class StructureID {
|
static class StructureID {
|
||||||
public final ResourceLocation id;
|
public final ResourceLocation biomeID;
|
||||||
public final ConfiguredStructureFeature structure;
|
public final ConfiguredStructureFeature structure;
|
||||||
|
|
||||||
StructureID(ResourceLocation id, ConfiguredStructureFeature structure){
|
StructureID(ResourceLocation biomeID, ConfiguredStructureFeature structure){
|
||||||
this.id = id;
|
this.biomeID = biomeID;
|
||||||
this.structure = structure;
|
this.structure = structure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "StructureID{" + "id=" + id + ", structure=" + structure + '}';
|
return "StructureID{" + "id=" + biomeID + ", structure=" + structure + '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -877,91 +880,19 @@ public class BiomeAPI {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
StructureID that = (StructureID) o;
|
StructureID that = (StructureID) o;
|
||||||
return id.equals(that.id) && structure.equals(that.structure);
|
return biomeID.equals(that.biomeID) && structure.equals(that.structure);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(id, structure);
|
return Objects.hash(biomeID, structure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void registerNoiseGeneratorAndChangeSurfaceRules(NoiseGeneratorSettings settings){
|
private static void changeStructureStarts(ResourceLocation biomeID, ConfiguredStructureFeature structure, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>> modifier) {
|
||||||
NOISE_GENERATOR_SETTINGS.add(settings);
|
STRUCTURE_STARTS.put(new StructureID(biomeID, structure), modifier);
|
||||||
changeSurfaceRulesForGenerator(settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerStructureEvents(){
|
|
||||||
DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
|
|
||||||
Optional<? extends Registry<NoiseGeneratorSettings>> oGeneratorRegistry = registryManager.registry(Registry.NOISE_GENERATOR_SETTINGS_REGISTRY);
|
|
||||||
// Optional<? extends Registry<Codec<? extends BiomeSource>>> oBiomeSourceRegistry = registryManager.registry(Registry.BIOME_SOURCE_REGISTRY);
|
|
||||||
//
|
|
||||||
// if (oBiomeSourceRegistry.isPresent()) {
|
|
||||||
// RegistryEntryAddedCallback
|
|
||||||
// .event(oBiomeSourceRegistry.get())
|
|
||||||
// .register((rawId, id, source) -> {
|
|
||||||
// BCLib.LOGGER.info(" #### " + rawId + ", " + source + ", " + id);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (oGeneratorRegistry.isPresent()) {
|
|
||||||
oGeneratorRegistry.get().forEach(BiomeAPI::registerNoiseGeneratorAndChangeSurfaceRules);
|
|
||||||
RegistryEntryAddedCallback
|
|
||||||
.event(oGeneratorRegistry.get())
|
|
||||||
.register((rawId, id, settings) -> {
|
|
||||||
//BCLib.LOGGER.info(" #### " + rawId + ", " + object + ", " + id);
|
|
||||||
|
|
||||||
//add back modded structures
|
|
||||||
StructureSettingsAccessor a = (StructureSettingsAccessor)settings.structureSettings();
|
|
||||||
STRUCTURE_STARTS.entrySet().forEach(entry -> applyStructureStarts(a, entry.getValue()));
|
|
||||||
|
|
||||||
//add surface rules
|
|
||||||
registerNoiseGeneratorAndChangeSurfaceRules(settings);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void changeSurfaceRulesForGenerator(NoiseGeneratorSettings settings){
|
|
||||||
List<SurfaceRules.RuleSource> rules;
|
|
||||||
if (biomeRegistry!=null) {
|
|
||||||
rules = getRuleSourcesFromIDs(biomeRegistry.keySet());
|
|
||||||
} else {
|
|
||||||
rules = getAllRuleSources();
|
|
||||||
}
|
|
||||||
SurfaceRuleProvider provider = SurfaceRuleProvider.class.cast(settings);
|
|
||||||
changeSurfaceRules(rules, provider);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void changeSurfaceRules(List<RuleSource> rules, SurfaceRuleProvider provider) {
|
|
||||||
if (rules.size() > 0) {
|
|
||||||
provider.addCustomRules(rules);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
provider.clearCustomRules();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void changeStructureStarts(ResourceLocation id, ConfiguredStructureFeature structure, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>> modifier) {
|
|
||||||
STRUCTURE_STARTS.put(new StructureID(id, structure), modifier);
|
|
||||||
Registry<NoiseGeneratorSettings> chunkGenSettingsRegistry = BuiltinRegistries.NOISE_GENERATOR_SETTINGS;
|
|
||||||
|
|
||||||
for (Map.Entry<ResourceKey<NoiseGeneratorSettings>, NoiseGeneratorSettings> entry : chunkGenSettingsRegistry.entrySet()) {
|
|
||||||
final StructureSettingsAccessor access = (StructureSettingsAccessor) entry.getValue().structureSettings();
|
|
||||||
applyStructureStarts(access, modifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (worldData!=null){
|
|
||||||
worldData.worldGenSettings().dimensions().forEach(dim->{
|
|
||||||
StructureSettingsAccessor access = (StructureSettingsAccessor)dim.generator().getSettings();
|
|
||||||
applyStructureStarts(access, modifier);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void applyStructureStarts(StructureSettingsAccessor access, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>> modifier) {
|
private static void applyStructureStarts(StructureSettingsAccessor access, BiConsumer<Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>>, Map<StructureFeature<?>, StructureFeatureConfiguration>> modifier) {
|
||||||
Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> structureMap;
|
Map<StructureFeature<?>, Multimap<ConfiguredStructureFeature<?, ?>, ResourceKey<Biome>>> structureMap;
|
||||||
Map<StructureFeature<?>, StructureFeatureConfiguration> configMap;
|
Map<StructureFeature<?>, StructureFeatureConfiguration> configMap;
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package ru.bclib.interfaces;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||||
|
|
||||||
|
public interface NoiseGeneratorSettingsProvider {
|
||||||
|
NoiseGeneratorSettings bclib_getNoiseGeneratorSettings();
|
||||||
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
package ru.bclib.interfaces;
|
package ru.bclib.interfaces;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource;
|
import net.minecraft.world.level.levelgen.SurfaceRules.RuleSource;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface SurfaceRuleProvider {
|
public interface SurfaceRuleProvider {
|
||||||
void clearCustomRules();
|
void bclib_addBiomeSource(BiomeSource source);
|
||||||
void addCustomRules(List<RuleSource> rules);
|
void bclib_clearBiomeSources();
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ public abstract class MinecraftMixin {
|
||||||
@Inject(method = "loadLevel", cancellable = true, at = @At("HEAD"))
|
@Inject(method = "loadLevel", cancellable = true, at = @At("HEAD"))
|
||||||
private void bclib_callFixerOnLoad(String levelID, CallbackInfo ci) {
|
private void bclib_callFixerOnLoad(String levelID, CallbackInfo ci) {
|
||||||
DataExchangeAPI.prepareServerside();
|
DataExchangeAPI.prepareServerside();
|
||||||
BiomeAPI.prepareWorldData();
|
BiomeAPI.prepareNewLevel();
|
||||||
|
|
||||||
if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> {
|
if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> {
|
||||||
LifeCycleAPI._runBeforeLevelLoad();
|
LifeCycleAPI._runBeforeLevelLoad();
|
||||||
|
@ -84,7 +84,7 @@ public abstract class MinecraftMixin {
|
||||||
@Inject(method = "createLevel", at = @At("HEAD"))
|
@Inject(method = "createLevel", at = @At("HEAD"))
|
||||||
private void bclib_initPatchData(String levelID, LevelSettings levelSettings, RegistryHolder registryHolder, WorldGenSettings worldGenSettings, CallbackInfo ci) {
|
private void bclib_initPatchData(String levelID, LevelSettings levelSettings, RegistryHolder registryHolder, WorldGenSettings worldGenSettings, CallbackInfo ci) {
|
||||||
DataExchangeAPI.prepareServerside();
|
DataExchangeAPI.prepareServerside();
|
||||||
BiomeAPI.prepareWorldData();
|
BiomeAPI.prepareNewLevel();
|
||||||
|
|
||||||
DataFixerAPI.initializeWorldData(this.levelSource, levelID, true);
|
DataFixerAPI.initializeWorldData(this.levelSource, levelID, true);
|
||||||
LifeCycleAPI._runBeforeLevelLoad();
|
LifeCycleAPI._runBeforeLevelLoad();
|
||||||
|
|
|
@ -30,9 +30,4 @@ public abstract class BiomeSourceMixin implements BiomeSourceAccessor {
|
||||||
BCLib.LOGGER.info("Rebuilding features in BiomeSource " + this.getClass());
|
BCLib.LOGGER.info("Rebuilding features in BiomeSource " + this.getClass());
|
||||||
featuresPerStep = buildFeaturesPerStep(this.possibleBiomes().stream().toList(), true);
|
featuresPerStep = buildFeaturesPerStep(this.possibleBiomes().stream().toList(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method="<init>(Ljava/util/List;)V", at=@At(value="INVOKE", shift = Shift.AFTER, target="Lnet/minecraft/world/level/biome/BiomeSource;buildFeaturesPerStep(Ljava/util/List;Z)Ljava/util/List;"))
|
|
||||||
private void bcl_Init(List list, CallbackInfo ci){
|
|
||||||
BiomeAPI.registerBiomeSource((BiomeSource)(Object)this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ public class MinecraftServerMixin {
|
||||||
@Inject(method = "<init>*", at = @At("TAIL"))
|
@Inject(method = "<init>*", at = @At("TAIL"))
|
||||||
private void bclib_onServerInit(Thread thread, RegistryHolder registryHolder, LevelStorageAccess levelStorageAccess, WorldData worldData, PackRepository packRepository, Proxy proxy, DataFixer dataFixer, ServerResources serverResources, MinecraftSessionService minecraftSessionService, GameProfileRepository gameProfileRepository, GameProfileCache gameProfileCache, ChunkProgressListenerFactory chunkProgressListenerFactory, CallbackInfo ci) {
|
private void bclib_onServerInit(Thread thread, RegistryHolder registryHolder, LevelStorageAccess levelStorageAccess, WorldData worldData, PackRepository packRepository, Proxy proxy, DataFixer dataFixer, ServerResources serverResources, MinecraftSessionService minecraftSessionService, GameProfileRepository gameProfileRepository, GameProfileCache gameProfileCache, ChunkProgressListenerFactory chunkProgressListenerFactory, CallbackInfo ci) {
|
||||||
DataExchangeAPI.prepareServerside();
|
DataExchangeAPI.prepareServerside();
|
||||||
BiomeAPI.registerWorldData(worldData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "reloadResources", at = @At(value = "RETURN"), cancellable = true)
|
@Inject(method = "reloadResources", at = @At(value = "RETURN"), cancellable = true)
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import ru.bclib.BCLib;
|
import ru.bclib.BCLib;
|
||||||
|
import ru.bclib.interfaces.NoiseGeneratorSettingsProvider;
|
||||||
import ru.bclib.interfaces.SurfaceProvider;
|
import ru.bclib.interfaces.SurfaceProvider;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
|
@ -26,7 +27,7 @@ import java.util.Optional;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@Mixin(NoiseBasedChunkGenerator.class)
|
@Mixin(NoiseBasedChunkGenerator.class)
|
||||||
public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider {
|
public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider, NoiseGeneratorSettingsProvider {
|
||||||
@Final
|
@Final
|
||||||
@Shadow
|
@Shadow
|
||||||
private NoiseSampler sampler;
|
private NoiseSampler sampler;
|
||||||
|
@ -41,6 +42,11 @@ public abstract class NoiseBasedChunkGeneratorMixin implements SurfaceProvider {
|
||||||
|
|
||||||
private static BlockState bclib_air = Blocks.AIR.defaultBlockState();
|
private static BlockState bclib_air = Blocks.AIR.defaultBlockState();
|
||||||
private static Constructor<?> bclib_constructor;
|
private static Constructor<?> bclib_constructor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NoiseGeneratorSettings bclib_getNoiseGeneratorSettings(){
|
||||||
|
return settings.get();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package ru.bclib.mixin.common;
|
package ru.bclib.mixin.common;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.biome.BiomeSource;
|
||||||
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;
|
||||||
|
@ -7,9 +8,12 @@ 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.Mutable;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import ru.bclib.api.biomes.BiomeAPI;
|
||||||
import ru.bclib.interfaces.SurfaceRuleProvider;
|
import ru.bclib.interfaces.SurfaceRuleProvider;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Mixin(NoiseGeneratorSettings.class)
|
@Mixin(NoiseGeneratorSettings.class)
|
||||||
|
@ -20,17 +24,32 @@ public class NoiseGeneratorSettingsMixin implements SurfaceRuleProvider {
|
||||||
private SurfaceRules.RuleSource surfaceRule;
|
private SurfaceRules.RuleSource surfaceRule;
|
||||||
|
|
||||||
private SurfaceRules.RuleSource bclib_originalSurfaceRule;
|
private SurfaceRules.RuleSource bclib_originalSurfaceRule;
|
||||||
|
private Set<BiomeSource> bclib_biomeSources = new HashSet<>();
|
||||||
|
|
||||||
|
private void bclib_updateCutomRules(){
|
||||||
|
bclib_setCustomRules(BiomeAPI.getRuleSources(bclib_biomeSources));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearCustomRules() {
|
public void bclib_addBiomeSource(BiomeSource source) {
|
||||||
|
bclib_biomeSources.add(source);
|
||||||
|
bclib_updateCutomRules();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bclib_clearBiomeSources(){
|
||||||
|
bclib_biomeSources.clear();
|
||||||
|
bclib_clearCustomRules();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bclib_clearCustomRules() {
|
||||||
if (bclib_originalSurfaceRule != null){
|
if (bclib_originalSurfaceRule != null){
|
||||||
this.surfaceRule = bclib_originalSurfaceRule;
|
this.surfaceRule = bclib_originalSurfaceRule;
|
||||||
bclib_originalSurfaceRule = null;
|
bclib_originalSurfaceRule = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void bclib_setCustomRules(List<RuleSource> rules) {
|
||||||
public void addCustomRules(List<RuleSource> rules) {
|
|
||||||
RuleSource org = getOriginalSurfaceRule();
|
RuleSource org = getOriginalSurfaceRule();
|
||||||
if (org instanceof SurfaceRules.SequenceRuleSource sequenceRule){
|
if (org instanceof SurfaceRules.SequenceRuleSource sequenceRule){
|
||||||
List<RuleSource> currentSequence = sequenceRule.sequence();
|
List<RuleSource> currentSequence = sequenceRule.sequence();
|
||||||
|
|
|
@ -288,7 +288,7 @@ public class BCLBiome extends BCLBiomeSettings {
|
||||||
this.surfaceInit = (actualBiome) -> {
|
this.surfaceInit = (actualBiome) -> {
|
||||||
ResourceKey key = BiomeAPI.getBiomeKey(actualBiome);
|
ResourceKey key = BiomeAPI.getBiomeKey(actualBiome);
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
BCLib.LOGGER.warning("BCL Biome " + biomeID + " don't have registry key!");
|
BCLib.LOGGER.warning("BCL Biome " + biomeID + " does not have registry key!");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BiomeAPI.addSurfaceRule(biomeID, SurfaceRules.ifTrue(SurfaceRules.isBiome(key), surface));
|
BiomeAPI.addSurfaceRule(biomeID, SurfaceRules.ifTrue(SurfaceRules.isBiome(key), surface));
|
||||||
|
@ -304,7 +304,6 @@ public class BCLBiome extends BCLBiomeSettings {
|
||||||
*/
|
*/
|
||||||
public void setFeatures(Map<Decoration, List<Supplier<PlacedFeature>>> features) {
|
public void setFeatures(Map<Decoration, List<Supplier<PlacedFeature>>> features) {
|
||||||
this.features = features;
|
this.features = features;
|
||||||
BiomeAPI.addStepFeaturesToBiome(getBiome(), features);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue