diff --git a/Common/src/main/java/terrablender/api/EndBiomeRegistry.java b/Common/src/main/java/terrablender/api/EndBiomeRegistry.java deleted file mode 100644 index 5c89fd6..0000000 --- a/Common/src/main/java/terrablender/api/EndBiomeRegistry.java +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Copyright (C) Glitchfiend - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package terrablender.api; - -import com.google.common.collect.ImmutableList; -import net.minecraft.resources.ResourceKey; -import net.minecraft.util.random.WeightedEntry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.Biomes; -import terrablender.core.TerraBlender; - -import java.util.ArrayList; -import java.util.List; - -public class EndBiomeRegistry -{ - private static final List>> highlandsBiomes = new ArrayList<>(); - private static final List>> midlandsBiomes = new ArrayList<>(); - private static final List>> edgeBiomes = new ArrayList<>(); - private static final List>> islandBiomes = new ArrayList<>(); - - /** - * Registers a biome to generate in the highlands of the end. - * @param biome the biome to register. - * @param weight the biome weight. - */ - public static void registerHighlandsBiome(ResourceKey biome, int weight) - { - highlandsBiomes.add(WeightedEntry.wrap(biome, weight)); - } - - /** - * Registers a biome to generate in the midlands of the end. - * @param biome the biome to register. - * @param weight the biome weight. - */ - public static void registerMidlandsBiome(ResourceKey biome, int weight) - { - midlandsBiomes.add(WeightedEntry.wrap(biome, weight)); - } - - /** - * Registers a biome to generate in the outer edges of islands in the end. - * @param biome the biome to register. - * @param weight the biome weight. - */ - public static void registerEdgeBiome(ResourceKey biome, int weight) - { - edgeBiomes.add(WeightedEntry.wrap(biome, weight)); - } - - /** - * Registers a biome to generate as a small island of the end. - * @param biome the biome to register. - * @param weight the biome weight. - */ - public static void registerIslandBiome(ResourceKey biome, int weight) - { - islandBiomes.add(WeightedEntry.wrap(biome, weight)); - } - - /** - * Gets the biomes to generate in the highlands of the end. - * @return the biomes to generate. - */ - public static List>> getHighlandsBiomes() - { - return ImmutableList.copyOf(highlandsBiomes); - } - - /** - * Gets the biomes to generate in the midlands of the end. - * @return the biomes to generate. - */ - public static List>> getMidlandsBiomes() - { - return ImmutableList.copyOf(midlandsBiomes); - } - - /** - * Gets the biomes to generate in the outer edges of islands in the end. - * @return the biomes to generate. - */ - public static List>> getEdgeBiomes() - { - return ImmutableList.copyOf(edgeBiomes); - } - - /** - * Gets the biomes to generate as a small island of the end. - * @return the biomes to generate. - */ - public static List>> getIslandBiomes() - { - return ImmutableList.copyOf(islandBiomes); - } - - static - { - registerHighlandsBiome(Biomes.END_HIGHLANDS, TerraBlender.CONFIG.vanillaEndHighlandsWeight); - registerMidlandsBiome(Biomes.END_MIDLANDS, TerraBlender.CONFIG.vanillaEndMidlandsWeight); - registerEdgeBiome(Biomes.END_BARRENS, TerraBlender.CONFIG.vanillaEndBarrensWeight); - registerIslandBiome(Biomes.SMALL_END_ISLANDS, TerraBlender.CONFIG.vanillaSmallEndIslandsWeight); - } -} diff --git a/Common/src/main/java/terrablender/api/SurfaceRuleManager.java b/Common/src/main/java/terrablender/api/SurfaceRuleManager.java index 124d6b6..58b1016 100644 --- a/Common/src/main/java/terrablender/api/SurfaceRuleManager.java +++ b/Common/src/main/java/terrablender/api/SurfaceRuleManager.java @@ -116,9 +116,6 @@ public static SurfaceRules.RuleSource getDefaultSurfaceRules(RuleCategory catego if (category == RuleCategory.NETHER) return TBSurfaceRuleData.nether(); - else if (category == RuleCategory.END) { - return TBSurfaceRuleData.end(); - } return TBSurfaceRuleData.overworld(); } @@ -128,7 +125,7 @@ else if (category == RuleCategory.END) { */ public enum RuleCategory { - OVERWORLD, NETHER, END + OVERWORLD, NETHER } /** diff --git a/Common/src/main/java/terrablender/config/Config.java b/Common/src/main/java/terrablender/config/Config.java index 94fb81c..9421664 100644 --- a/Common/src/main/java/terrablender/config/Config.java +++ b/Common/src/main/java/terrablender/config/Config.java @@ -17,218 +17,171 @@ */ package terrablender.config; -import com.electronwill.nightconfig.core.*; +import com.electronwill.nightconfig.core.CommentedConfig; +import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.io.WritingMode; import com.electronwill.nightconfig.toml.TomlFormat; -import com.google.common.base.Predicates; -import terrablender.core.TerraBlender; +import com.electronwill.nightconfig.toml.TomlWriter; +import net.minecraft.util.StringRepresentable; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Comparator; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.function.Predicate; +import java.util.Objects; +import java.util.stream.Collectors; -public abstract class Config implements UnmodifiableConfig, CommentedConfig +public class Config { - private CommentedConfig config; - private final Path path; + private final CommentedConfig config; - protected Config(Path path) + public Config(CommentedConfig config) { - this(path, readToml(path)); + this.config = config; } - protected Config(Path path, String toml) + public List addList(String comment, String key, List defaultValue) { - this.parse(toml); - this.path = path; - this.load(); - this.write(); - } + if (config.get(key) == null) + { + config.set(key, defaultValue); + } - public T add(String key, T defaultValue, String comment) - { - return this.add(key, defaultValue, comment, Predicates.alwaysTrue()); + if (config.getComment(key) == null) + { + config.setComment(key, comment); + } + return config.get(key); } - public T add(String key, T defaultValue, String comment, Predicate validator) + public Config addSubConfig(String comment, String key, Config defaultValue) { - var value = config.getOrElse(key, defaultValue); + if (config.get(key) == null) + { + config.set(key, sortConfig(defaultValue.config)); + } - // Revert to default if validation fails - if (!validator.test(value)) + CommentedConfig subConfig = config.get(key); + String commentValue = config.getComment(key); + if (commentValue == null) { - TerraBlender.LOGGER.warn("Invalid value {} for key {}. Reverting to default", value, key); - value = defaultValue; + config.setComment(key, comment); } - config.set(key, value); - config.setComment(key, comment); - return value; + return new Config(subConfig); } - public > T addNumber(String key, T defaultValue, T min, T max, String comment) + public Map addMap(String comment, String key, Map defaultValue) { - return this.add(key, defaultValue, comment, (v) -> v.compareTo(max) <= 0 && v.compareTo(min) >= 0); - } + if (config.get(key) == null) + { + CommentedConfig subConfig = config.createSubConfig(); + defaultValue.forEach((a, b) -> { + String subConfigKey = a.toString(); + if (subConfig.get(a.toString()) == null) + { + subConfig.set(subConfigKey, b); + } + }); + config.set(key, subConfig); + } - public abstract void load(); + CommentedConfig subConfig = config.get(key); + String commentValue = config.getComment(key); + if (commentValue == null) + { + config.setComment(key, comment); + } - public void parse(String toml) - { - this.config = TomlFormat.instance().createParser().parse(toml); + return subConfig.valueMap(); } - public void read() + public T add(String comment, String key, T defaultValue) { - this.parse(readToml(this.path)); - } + if (config.get(key) == null) + { + config.set(key, defaultValue); + } - public void write() - { - TomlFormat.instance().createWriter().write(this.config, this.path, WritingMode.REPLACE); + if (config.getComment(key) == null) + { + config.setComment(key, comment); + } + return config.get(key); } - public String encode() + public > T addNumber(String comment, String key, T defaultValue, T min, T max) { - return TomlFormat.instance().createWriter().writeToString(this.config); - } + if (config.get(key) == null) + { + config.set(key, defaultValue); + } - public Path getPath() - { - return this.path; + if (config.getComment(key) == null) + { + config.setComment(key, comment + String.format("\nRange: %s-%s", min, max)); + } + T value = config.get(key); + return value.compareTo(max) > 0 ? max : value.compareTo(min) < 0 ? min : value; } - private static String readToml(Path path) + public > T addEnum(String comment, String key, T defaultValue) { - // Create parent directories as needed - path.getParent().toFile().mkdirs(); - - try { - return Files.readString(path); - } catch (Exception ignored) {} - return ""; - } - - @Override - public T getRaw(List path) { - return config.getRaw(path); - } - - @Override - public Map valueMap() { - return config.valueMap(); - } - - @Override - public boolean contains(List path) { - return config.contains(path); - } - - @Override - public int size() { - return config.size(); - } - - @Override - public boolean isEmpty() { - return config.isEmpty(); - } - - @Override - public boolean equals(Object obj) { - return config.equals(obj); - } - - @Override - public int hashCode() { - return config.hashCode(); - } - - @Override - public ConfigFormat configFormat() { - return config.configFormat(); - } - - @Override - public T set(List path, Object value) { - return config.set(path, value); - } - - @Override - public boolean add(List path, Object value) { - return config.add(path, value); - } - - @Override - public T remove(List path) { - return config.remove(path); - } - - @Override - public void clear() { - config.clear(); - } - - @Override - public String getComment(List path) { - return config.getComment(path); - } - - @Override - public boolean containsComment(List path) { - return config.containsComment(path); - } - - @Override - public String setComment(List path, String comment) { - return config.setComment(path, comment); - } - - @Override - public String removeComment(List path) { - return config.removeComment(path); - } + if (config.get(key) == null) + { + config.set(key, defaultValue); + } - @Override - public Map commentMap() { - return config.commentMap(); - } + if (config.getComment(key) == null) + { + StringBuilder builder = new StringBuilder().append("Values: ").append(defaultValue instanceof StringRepresentable ? "\n" : ""); + for (T value : defaultValue.getDeclaringClass().getEnumConstants()) + { + if (defaultValue instanceof StringRepresentable) + { + builder.append(((StringRepresentable) value).getSerializedName()).append("\n"); + } + else + { + builder.append(value.name()).append(", "); + } + } + + config.setComment(key, comment + "\n" + builder.toString()); + } - @Override - public Set entrySet() { - return config.entrySet(); + String value = config.get(key).toString(); + return T.valueOf(defaultValue.getDeclaringClass(), value); } - @Override - public void clearComments() { - config.clearComments(); + public T getValue(String key) + { + return this.config.get(key); } - @Override - public void putAllComments(Map comments) { - config.putAllComments(comments); + public Config getSubConfig(String key) + { + CommentedConfig sub = this.config.get(key); + return new Config(sub != null ? sub : CommentedConfig.inMemory()); } - @Override - public void putAllComments(UnmodifiableCommentedConfig commentedConfig) { - config.putAllComments(commentedConfig); + protected CommentedConfig getConfig() + { + return this.config; } - @Override - public Map getComments() { - return config.getComments(); - } + protected static CommentedConfig sortConfig(CommentedConfig config) + { + CommentedConfig newConfig = CommentedConfig.of(com.electronwill.nightconfig.core.Config.getDefaultMapCreator(false, true), TomlFormat.instance()); - @Override - public CommentedConfig createSubConfig() { - return config.createSubConfig(); - } + List> organizedCollection = config.valueMap().entrySet().stream().sorted(Comparator.comparing(Objects::toString)).collect(Collectors.toList()); + organizedCollection.forEach((stringObjectEntry -> { + newConfig.add(stringObjectEntry.getKey(), stringObjectEntry.getValue()); + })); - @Override - public String toString() { - return getClass().getSimpleName() + ':' + config; + newConfig.commentMap().putAll(config.commentMap()); + return newConfig; } -} \ No newline at end of file +} diff --git a/Common/src/main/java/terrablender/worldgen/IExtendedTheEndBiomeSource.java b/Common/src/main/java/terrablender/config/ConfigFile.java similarity index 54% rename from Common/src/main/java/terrablender/worldgen/IExtendedTheEndBiomeSource.java rename to Common/src/main/java/terrablender/config/ConfigFile.java index ebc0b9e..9255b6f 100644 --- a/Common/src/main/java/terrablender/worldgen/IExtendedTheEndBiomeSource.java +++ b/Common/src/main/java/terrablender/config/ConfigFile.java @@ -1,27 +1,41 @@ /** * Copyright (C) Glitchfiend - *

+ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. - *

+ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - *

+ * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package terrablender.worldgen; +package terrablender.config; -import net.minecraft.core.RegistryAccess; -import net.minecraft.world.level.biome.Climate; -import terrablender.api.RegionType; +import com.electronwill.nightconfig.core.file.CommentedFileConfig; +import com.electronwill.nightconfig.core.io.WritingMode; +import com.electronwill.nightconfig.toml.TomlWriter; -public interface IExtendedTheEndBiomeSource +import java.nio.file.Path; + +public class ConfigFile extends Config { - void initializeForTerraBlender(RegistryAccess registryAccess, long seed); -} \ No newline at end of file + private final Path path; + + public ConfigFile(Path path) + { + super(CommentedFileConfig.builder(path).sync().autosave().build()); + this.path = path; + ((CommentedFileConfig)this.getConfig()).load(); + } + + public void save() + { + (new TomlWriter()).write(sortConfig(this.getConfig()), this.path.toFile(), WritingMode.REPLACE); + } +} diff --git a/Common/src/main/java/terrablender/config/TerraBlenderConfig.java b/Common/src/main/java/terrablender/config/TerraBlenderConfig.java index b33028f..e00fdb1 100644 --- a/Common/src/main/java/terrablender/config/TerraBlenderConfig.java +++ b/Common/src/main/java/terrablender/config/TerraBlenderConfig.java @@ -19,42 +19,27 @@ import java.nio.file.Path; -public class TerraBlenderConfig extends Config +public class TerraBlenderConfig extends ConfigFile { - public int overworldRegionSize; - public int netherRegionSize; - public int vanillaOverworldRegionWeight; - public int vanillaNetherRegionWeight; - - public int endHighlandsBiomeSize; - public int endMidlandsBiomeSize; - public int endEdgeBiomeSize; - public int endIslandBiomeSize; - public int vanillaEndHighlandsWeight; - public int vanillaEndMidlandsWeight; - public int vanillaEndBarrensWeight; - public int vanillaSmallEndIslandsWeight; + public final int overworldRegionSize; + public final int netherRegionSize; + public final int vanillaOverworldRegionWeight; + public final int vanillaNetherRegionWeight; public TerraBlenderConfig(Path path) { super(path); - } - @Override - public void load() - { - this.overworldRegionSize = addNumber("general.overworld_region_size", 3, 2, 6, "The size of overworld biome regions from each mod that uses TerraBlender."); - this.netherRegionSize = addNumber("general.nether_region_size", 2, 2, 6, "The size of nether biome regions from each mod that uses TerraBlender."); - this.vanillaOverworldRegionWeight = addNumber("general.vanilla_overworld_region_weight", 10, 0, Integer.MAX_VALUE, "The weighting of vanilla biome regions in the overworld."); - this.vanillaNetherRegionWeight = addNumber("general.vanilla_nether_region_weight", 10, 0, Integer.MAX_VALUE, "The weighting of vanilla biome regions in the nether."); + Config generalConfig = this.getSubConfig("general"); + this.addSubConfig("General settings", "general", generalConfig); + + Config generationSettings = this.getSubConfig("generation_settings"); + this.overworldRegionSize = generationSettings.addNumber("The size of overworld biome regions from each mod that uses TerraBlender.", "overworld_region_size", 3, 2, 6); + this.netherRegionSize = generationSettings.addNumber("The size of nether biome regions from each mod that uses TerraBlender.", "nether_region_size", 2, 2, 6); + this.vanillaOverworldRegionWeight = generationSettings.addNumber("The weighting of vanilla biome regions in the overworld.", "vanilla_overworld_region_weight", 10, 0, Integer.MAX_VALUE); + this.vanillaNetherRegionWeight = generationSettings.addNumber("The weighting of vanilla biome regions in the nether.", "vanilla_nether_region_weight", 10, 0, Integer.MAX_VALUE); + this.addSubConfig("Generation settings", "generation_settings", generationSettings); - this.endHighlandsBiomeSize = addNumber("end.highlands_biome_size", 4, 2, 6, "The size of highlands end biomes."); - this.endMidlandsBiomeSize = addNumber("end.midlands_biome_size", 4, 2, 6, "The size of midlands end biomes."); - this.endEdgeBiomeSize = addNumber("end.edge_biome_size", 3, 2, 6, "The size of edge end biomes."); - this.endIslandBiomeSize = addNumber("end.island_biome_size", 2, 2, 6, "The size of island end biomes."); - this.vanillaEndHighlandsWeight = addNumber("end.vanilla_end_highlands_weight", 10, 0, Integer.MAX_VALUE, "The weight of Vanilla end highlands biomes."); - this.vanillaEndMidlandsWeight = addNumber("end.vanilla_end_midlands_weight", 10, 0, Integer.MAX_VALUE, "The weight of Vanilla end midlands biomes."); - this.vanillaEndBarrensWeight = addNumber("end.vanilla_end_barrens_weight", 10, 0, Integer.MAX_VALUE, "The weight of Vanilla end barrens biomes."); - this.vanillaSmallEndIslandsWeight = addNumber("end.vanilla_small_end_islands_weight", 10, 0, Integer.MAX_VALUE, "The weight of Vanilla small end islands biomes."); + this.save(); } } diff --git a/Common/src/main/java/terrablender/mixin/MixinBiomeSource.java b/Common/src/main/java/terrablender/mixin/MixinBiomeSource.java index 4c26c4a..30df4d4 100644 --- a/Common/src/main/java/terrablender/mixin/MixinBiomeSource.java +++ b/Common/src/main/java/terrablender/mixin/MixinBiomeSource.java @@ -17,21 +17,23 @@ */ package terrablender.mixin; +import com.google.common.collect.ImmutableList; import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; import net.minecraft.core.Holder; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeResolver; import net.minecraft.world.level.biome.BiomeSource; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import terrablender.worldgen.IExtendedBiomeSource; -import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.function.Supplier; -import java.util.stream.Collectors; @Mixin(BiomeSource.class) public abstract class MixinBiomeSource implements BiomeResolver, IExtendedBiomeSource @@ -39,7 +41,6 @@ public abstract class MixinBiomeSource implements BiomeResolver, IExtendedBiomeS @Shadow public Supplier>> possibleBiomes; - @Unique private boolean hasAppended = false; @Override @@ -50,11 +51,12 @@ public void appendDeferredBiomesList(List> biomesToAppend) return; } - List> possibleBiomes = new ArrayList<>(); - possibleBiomes.addAll(this.possibleBiomes.get()); - possibleBiomes.addAll(biomesToAppend); + ImmutableList.Builder> builder = ImmutableList.builder(); + builder.addAll(this.possibleBiomes.get()); + builder.addAll(biomesToAppend); + ImmutableList> biomeList = builder.build().stream().distinct().collect(ImmutableList.toImmutableList()); - this.possibleBiomes = () -> new ObjectLinkedOpenHashSet<>(possibleBiomes.stream().distinct().collect(Collectors.toList())); + this.possibleBiomes = () -> new ObjectLinkedOpenHashSet<>(biomeList); this.hasAppended = true; } } diff --git a/Common/src/main/java/terrablender/mixin/MixinNoiseGeneratorSettings.java b/Common/src/main/java/terrablender/mixin/MixinNoiseGeneratorSettings.java index eedf02d..fe7916b 100644 --- a/Common/src/main/java/terrablender/mixin/MixinNoiseGeneratorSettings.java +++ b/Common/src/main/java/terrablender/mixin/MixinNoiseGeneratorSettings.java @@ -21,7 +21,6 @@ import net.minecraft.world.level.levelgen.SurfaceRules; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -36,26 +35,30 @@ public class MixinNoiseGeneratorSettings implements IExtendedNoiseGeneratorSetti @Shadow private SurfaceRules.RuleSource surfaceRule; - @Unique - private SurfaceRuleManager.RuleCategory ruleCategory = null; - @Unique + private RegionType regionType = null; private SurfaceRules.RuleSource namespacedSurfaceRuleSource = null; @Inject(method = "surfaceRule", at = @At("HEAD"), cancellable = true) private void surfaceRule(CallbackInfoReturnable cir) { - if (this.ruleCategory != null) + if (this.regionType != null) { if (this.namespacedSurfaceRuleSource == null) - this.namespacedSurfaceRuleSource = SurfaceRuleManager.getNamespacedRules(this.ruleCategory, this.surfaceRule); + this.namespacedSurfaceRuleSource = regionType == RegionType.NETHER ? SurfaceRuleManager.getNamespacedRules(SurfaceRuleManager.RuleCategory.NETHER, this.surfaceRule) : SurfaceRuleManager.getNamespacedRules(SurfaceRuleManager.RuleCategory.OVERWORLD, this.surfaceRule); cir.setReturnValue(this.namespacedSurfaceRuleSource); } } @Override - public void setRuleCategory(SurfaceRuleManager.RuleCategory ruleCategory) + public void setRegionType(RegionType regionType) { - this.ruleCategory = ruleCategory; + this.regionType = regionType; + } + + @Override + public RegionType getRegionType() + { + return this.regionType; } } diff --git a/Common/src/main/java/terrablender/mixin/MixinParameterList.java b/Common/src/main/java/terrablender/mixin/MixinParameterList.java index a8602d2..4d941f3 100644 --- a/Common/src/main/java/terrablender/mixin/MixinParameterList.java +++ b/Common/src/main/java/terrablender/mixin/MixinParameterList.java @@ -28,7 +28,6 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import terrablender.api.Region; import terrablender.api.RegionType; import terrablender.api.Regions; @@ -48,13 +47,9 @@ public abstract class MixinParameterList implements IExtendedParameterList @Shadow public abstract T findValue(Climate.TargetPoint target); - @Unique private boolean initialized = false; - @Unique private boolean treesPopulated = false; - @Unique private Area uniqueness; - @Unique private Climate.RTree[] uniqueTrees; @Override diff --git a/Common/src/main/java/terrablender/mixin/MixinTheEndBiomeSource.java b/Common/src/main/java/terrablender/mixin/MixinTheEndBiomeSource.java deleted file mode 100644 index 669b228..0000000 --- a/Common/src/main/java/terrablender/mixin/MixinTheEndBiomeSource.java +++ /dev/null @@ -1,159 +0,0 @@ -/** - * Copyright (C) Glitchfiend - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package terrablender.mixin; - - -import com.google.common.collect.ImmutableSet; -import net.minecraft.core.*; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.util.random.WeightedEntry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.Biomes; -import net.minecraft.world.level.biome.Climate; -import net.minecraft.world.level.biome.TheEndBiomeSource; -import net.minecraft.world.level.levelgen.DensityFunction; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import terrablender.api.EndBiomeRegistry; -import terrablender.core.TerraBlender; -import terrablender.worldgen.IExtendedTheEndBiomeSource; -import terrablender.worldgen.noise.Area; -import terrablender.worldgen.noise.LayeredNoiseUtil; - -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -@Mixin(TheEndBiomeSource.class) -public class MixinTheEndBiomeSource implements IExtendedTheEndBiomeSource -{ - @Shadow - @Final - private Holder end; - - @Unique - private boolean tbInitialized = false; - - @Unique - private Registry biomeRegistry; - @Unique - private Set> tbPossibleBiomes; - @Unique - private Area highlandsArea; - @Unique - private Area midlandsArea; - @Unique - private Area edgeArea; - @Unique - private Area islandsArea; - - @Override - public void initializeForTerraBlender(RegistryAccess registryAccess, long seed) - { - this.biomeRegistry = registryAccess.registryOrThrow(Registries.BIOME); - - var highlands = EndBiomeRegistry.getHighlandsBiomes(); - var midlands = EndBiomeRegistry.getMidlandsBiomes(); - var edge = EndBiomeRegistry.getEdgeBiomes(); - var islands = EndBiomeRegistry.getIslandBiomes(); - - // Create a set of all biomes - var builder = ImmutableSet.>builder(); - builder.addAll(highlands.stream().map(WeightedEntry.Wrapper::getData).toList()); - builder.addAll(midlands.stream().map(WeightedEntry.Wrapper::getData).toList()); - builder.addAll(edge.stream().map(WeightedEntry.Wrapper::getData).toList()); - builder.addAll(islands.stream().map(WeightedEntry.Wrapper::getData).toList()); - builder.add(Biomes.THE_END); - Set> allBiomes = builder.build(); - - // Ensure all biomes are registered - allBiomes.forEach(key -> { - if (!biomeRegistry.containsKey(key)) - throw new RuntimeException("Biome " + key + " has not been registered!"); - }); - - this.tbPossibleBiomes = allBiomes.stream().map(biomeRegistry::getHolderOrThrow).collect(Collectors.toSet()); - this.highlandsArea = LayeredNoiseUtil.biomeArea(registryAccess, seed, TerraBlender.CONFIG.endHighlandsBiomeSize, highlands); - this.midlandsArea = LayeredNoiseUtil.biomeArea(registryAccess, seed, TerraBlender.CONFIG.endMidlandsBiomeSize, midlands); - this.edgeArea = LayeredNoiseUtil.biomeArea(registryAccess, seed, TerraBlender.CONFIG.endEdgeBiomeSize, edge); - this.islandsArea = LayeredNoiseUtil.biomeArea(registryAccess, seed, TerraBlender.CONFIG.endIslandBiomeSize, edge); - - // This may not be initialized with e.g. BCLib - this.tbInitialized = true; - } - - @Inject(method = "collectPossibleBiomes", at=@At("RETURN"), cancellable = true) - protected void onCollectPossibleBiomes(CallbackInfoReturnable>> cir) - { - if (!this.tbInitialized) - return; - - var builder = ImmutableSet.>builder(); - builder.addAll(cir.getReturnValue().collect(Collectors.toSet())); - builder.addAll(this.tbPossibleBiomes); - cir.setReturnValue(builder.build().stream()); - } - - @Inject(method = "getNoiseBiome", at=@At("HEAD"), cancellable = true) - public void onGetNoiseBiome(int x, int y, int z, Climate.Sampler sampler, CallbackInfoReturnable> cir) - { - if (!this.tbInitialized) - return; - - int blockX = QuartPos.toBlock(x); - int blockY = QuartPos.toBlock(y); - int blockZ = QuartPos.toBlock(z); - - int sectionX = SectionPos.blockToSectionCoord(blockX); - int sectionZ = SectionPos.blockToSectionCoord(blockZ); - - if ((long)sectionX * (long)sectionX + (long)sectionZ * (long)sectionZ <= 4096L) - { - cir.setReturnValue(this.end); - } - else - { - double heightNoise = sampler.erosion().compute(new DensityFunction.SinglePointContext(blockX, blockY, blockZ)); - - if (heightNoise > 0.25) - { - cir.setReturnValue(this.getBiomeHolder(this.highlandsArea.get(x, z))); - } - else if (heightNoise >= -0.0625) - { - cir.setReturnValue(this.getBiomeHolder(this.midlandsArea.get(x, z))); - } - else - { - cir.setReturnValue(heightNoise < -0.21875 ? this.getBiomeHolder(this.islandsArea.get(x, z)) : this.getBiomeHolder(this.edgeArea.get(x, z))); - } - } - } - - @Unique - private Holder getBiomeHolder(int id) - { - return this.biomeRegistry.getHolder(id).orElseThrow(); - } -} diff --git a/Common/src/main/java/terrablender/util/LevelUtils.java b/Common/src/main/java/terrablender/util/LevelUtils.java index 10e6fdc..0c9e5f9 100644 --- a/Common/src/main/java/terrablender/util/LevelUtils.java +++ b/Common/src/main/java/terrablender/util/LevelUtils.java @@ -24,7 +24,10 @@ import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; -import net.minecraft.world.level.biome.*; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.biome.MultiNoiseBiomeSource; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; @@ -33,12 +36,10 @@ import terrablender.DimensionTypeTags; import terrablender.api.RegionType; import terrablender.api.Regions; -import terrablender.api.SurfaceRuleManager; import terrablender.core.TerraBlender; import terrablender.worldgen.IExtendedBiomeSource; import terrablender.worldgen.IExtendedNoiseGeneratorSettings; import terrablender.worldgen.IExtendedParameterList; -import terrablender.worldgen.IExtendedTheEndBiomeSource; import java.util.Map; @@ -76,20 +77,12 @@ public static RegionType getRegionTypeForDimension(Holder dimensi public static void initializeBiomes(RegistryAccess registryAccess, Holder dimensionType, ResourceKey levelResourceKey, ChunkGenerator chunkGenerator, long seed) { - if (!(chunkGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator)) + if (!shouldApplyToChunkGenerator(chunkGenerator)) return; - NoiseGeneratorSettings generatorSettings = noiseBasedChunkGenerator.generatorSettings().value(); - - if (chunkGenerator.getBiomeSource() instanceof TheEndBiomeSource) - { - ((IExtendedTheEndBiomeSource)chunkGenerator.getBiomeSource()).initializeForTerraBlender(registryAccess, seed); - ((IExtendedNoiseGeneratorSettings)(Object)generatorSettings).setRuleCategory(SurfaceRuleManager.RuleCategory.END); - return; - } - else if (!shouldApplyToBiomeSource(chunkGenerator.getBiomeSource())) return; - RegionType regionType = getRegionTypeForDimension(dimensionType); + NoiseBasedChunkGenerator noiseBasedChunkGenerator = (NoiseBasedChunkGenerator)chunkGenerator; + NoiseGeneratorSettings generatorSettings = noiseBasedChunkGenerator.generatorSettings().value(); MultiNoiseBiomeSource biomeSource = (MultiNoiseBiomeSource)chunkGenerator.getBiomeSource(); IExtendedBiomeSource biomeSourceEx = (IExtendedBiomeSource)biomeSource; @@ -98,12 +91,7 @@ public static void initializeBiomes(RegistryAccess registryAccess, Holder SurfaceRuleManager.RuleCategory.OVERWORLD; - case NETHER -> SurfaceRuleManager.RuleCategory.NETHER; - default -> throw new IllegalArgumentException("Attempted to get surface rule category for unsupported region type " + regionType); - }; - ((IExtendedNoiseGeneratorSettings)(Object)generatorSettings).setRuleCategory(ruleCategory); + ((IExtendedNoiseGeneratorSettings)(Object)generatorSettings).setRegionType(regionType); Climate.ParameterList parameters = biomeSource.parameters(); IExtendedParameterList parametersEx = (IExtendedParameterList)parameters; diff --git a/Common/src/main/java/terrablender/util/WeightedRandomList.java b/Common/src/main/java/terrablender/util/WeightedRandomList.java deleted file mode 100644 index e13ca19..0000000 --- a/Common/src/main/java/terrablender/util/WeightedRandomList.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright 2024, the Glitchfiend Team. - * All rights reserved. - ******************************************************************************/ -package terrablender.util; - -import com.google.common.collect.ImmutableList; -import net.minecraft.util.random.WeightedEntry; -import net.minecraft.util.random.WeightedRandom; -import terrablender.worldgen.noise.AreaContext; -import terrablender.worldgen.noise.WeightedRandomLayer; - -import java.util.List; -import java.util.Optional; - -public class WeightedRandomList -{ - private final int totalWeight; - private final ImmutableList items; - - WeightedRandomList(List items) - { - this.items = ImmutableList.copyOf(items); - this.totalWeight = WeightedRandom.getTotalWeight(items); - } - - public static WeightedRandomList create() - { - return new WeightedRandomList<>(ImmutableList.of()); - } - - @SafeVarargs - public static WeightedRandomList create(E... entries) - { - return new WeightedRandomList<>(ImmutableList.copyOf(entries)); - } - - public static WeightedRandomList create(List entries) - { - return new WeightedRandomList<>(entries); - } - - public Optional getRandom(AreaContext context) - { - if (this.totalWeight == 0) { - return Optional.empty(); - } else { - int i = context.nextRandom(this.totalWeight); - return WeightedRandom.getWeightedItem(this.items, i); - } - } -} diff --git a/Common/src/main/java/terrablender/worldgen/IExtendedNoiseGeneratorSettings.java b/Common/src/main/java/terrablender/worldgen/IExtendedNoiseGeneratorSettings.java index 5c37325..f7afb72 100644 --- a/Common/src/main/java/terrablender/worldgen/IExtendedNoiseGeneratorSettings.java +++ b/Common/src/main/java/terrablender/worldgen/IExtendedNoiseGeneratorSettings.java @@ -1,3 +1,7 @@ +package terrablender.worldgen; + +import terrablender.api.RegionType; + /** * Copyright (C) Glitchfiend *

@@ -15,11 +19,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package terrablender.worldgen; - -import terrablender.api.SurfaceRuleManager; - public interface IExtendedNoiseGeneratorSettings { - void setRuleCategory(SurfaceRuleManager.RuleCategory ruleCategory); + void setRegionType(RegionType regionType); + RegionType getRegionType(); } diff --git a/Common/src/main/java/terrablender/worldgen/TBSurfaceRuleData.java b/Common/src/main/java/terrablender/worldgen/TBSurfaceRuleData.java index 3c8290f..c36e853 100644 --- a/Common/src/main/java/terrablender/worldgen/TBSurfaceRuleData.java +++ b/Common/src/main/java/terrablender/worldgen/TBSurfaceRuleData.java @@ -650,11 +650,6 @@ public static SurfaceRules.RuleSource nether() return SurfaceRules.sequence(builder.build().toArray(SurfaceRules.RuleSource[]::new)); } - public static SurfaceRules.RuleSource end() - { - return ENDSTONE; - } - public static SurfaceRules.RuleSource air() { return AIR; diff --git a/Common/src/main/java/terrablender/worldgen/noise/BiomeInitialLayer.java b/Common/src/main/java/terrablender/worldgen/noise/BiomeInitialLayer.java deleted file mode 100644 index aeca98f..0000000 --- a/Common/src/main/java/terrablender/worldgen/noise/BiomeInitialLayer.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright 2024, the Glitchfiend Team. - * All rights reserved. - ******************************************************************************/ -package terrablender.worldgen.noise; - -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.util.random.WeightedEntry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.Biomes; - -import java.util.List; - -public class BiomeInitialLayer extends WeightedRandomLayer>> -{ - private final Registry biomeRegistry; - - public BiomeInitialLayer(RegistryAccess registryAccess, List>> entries) - { - super(entries); - this.biomeRegistry = registryAccess.registryOrThrow(Registries.BIOME); - } - - @Override - protected int getEntryIndex(WeightedEntry.Wrapper> entry) - { - return this.resolveId(entry.getData()); - } - - @Override - protected int getDefaultIndex() - { - return this.resolveId(Biomes.OCEAN); - } - - private int resolveId(ResourceKey key) - { - if (!this.biomeRegistry.containsKey(key)) - throw new RuntimeException("Attempted to resolve id for unregistered biome " + key); - - return this.biomeRegistry.getId(this.biomeRegistry.get(key)); - } -} diff --git a/Common/src/main/java/terrablender/worldgen/noise/InitialLayer.java b/Common/src/main/java/terrablender/worldgen/noise/InitialLayer.java index 916c5ed..bbdc35b 100644 --- a/Common/src/main/java/terrablender/worldgen/noise/InitialLayer.java +++ b/Common/src/main/java/terrablender/worldgen/noise/InitialLayer.java @@ -32,31 +32,65 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; -public class InitialLayer extends WeightedRandomLayer> +public class InitialLayer implements AreaTransformer0 { private final RegionType regionType; + private final WeightedRandomList> weightedEntries; - public InitialLayer(RegistryAccess registryAccess, RegionType regionType) + public InitialLayer(RegistryAccess registryAccess, RegionType type) { - super(createEntries(registryAccess, regionType)); - this.regionType = regionType; + Registry biomeRegistry = registryAccess.registryOrThrow(Registries.BIOME); + this.regionType = type; + this.weightedEntries = WeightedRandomList.create(Regions.get(this.regionType).stream().filter(region -> { + AtomicBoolean biomesAdded = new AtomicBoolean(false); + region.addBiomes(biomeRegistry, pair -> biomesAdded.set(true)); + + // Filter out irrelevant regions or regions without any biomes + return region.getType() == type && biomesAdded.get(); + }).map(region -> WeightedEntry.wrap(region, region.getWeight())).collect(ImmutableList.toImmutableList())); } @Override - protected int getEntryIndex(WeightedEntry.Wrapper entry) + public int apply(AreaContext context, int x, int y) { - return Regions.getIndex(this.regionType, entry.getData().getName()); + Optional> entry = weightedEntries.getRandom(context); + return entry.isPresent() ? Regions.getIndex(this.regionType, entry.get().getData().getName()) : 0; } - private static List> createEntries(RegistryAccess registryAccess, RegionType regionType) + private static class WeightedRandomList { - Registry biomeRegistry = registryAccess.registryOrThrow(Registries.BIOME); - return Regions.get(regionType).stream().filter(region -> { - AtomicBoolean biomesAdded = new AtomicBoolean(false); - region.addBiomes(biomeRegistry, pair -> biomesAdded.set(true)); + private final int totalWeight; + private final ImmutableList items; - // Filter out irrelevant regions or regions without any biomes - return region.getType() == regionType && biomesAdded.get(); - }).map(region -> WeightedEntry.wrap(region, region.getWeight())).collect(ImmutableList.toImmutableList()); + WeightedRandomList(List items) + { + this.items = ImmutableList.copyOf(items); + this.totalWeight = WeightedRandom.getTotalWeight(items); + } + + public static WeightedRandomList create() { + return new WeightedRandomList<>(ImmutableList.of()); + } + + @SafeVarargs + public static WeightedRandomList create(E... entries) + { + return new WeightedRandomList<>(ImmutableList.copyOf(entries)); + } + + public static WeightedRandomList create(List entries) + { + return new WeightedRandomList<>(entries); + } + + public Optional getRandom(AreaContext context) + { + if (this.totalWeight == 0) { + return Optional.empty(); + } else { + int i = context.nextRandom(this.totalWeight); + return WeightedRandom.getWeightedItem(this.items, i); + } + } } -} \ No newline at end of file +} diff --git a/Common/src/main/java/terrablender/worldgen/noise/LayeredNoiseUtil.java b/Common/src/main/java/terrablender/worldgen/noise/LayeredNoiseUtil.java index cbc870d..0389f77 100644 --- a/Common/src/main/java/terrablender/worldgen/noise/LayeredNoiseUtil.java +++ b/Common/src/main/java/terrablender/worldgen/noise/LayeredNoiseUtil.java @@ -18,39 +18,25 @@ package terrablender.worldgen.noise; import net.minecraft.core.RegistryAccess; -import net.minecraft.resources.ResourceKey; -import net.minecraft.util.random.WeightedEntry; -import net.minecraft.world.level.biome.Biome; import terrablender.api.RegionType; import terrablender.core.TerraBlender; -import java.util.List; import java.util.function.LongFunction; public class LayeredNoiseUtil { - public static Area uniqueness(RegistryAccess registryAccess, RegionType regionType, long seed) + public static Area uniqueness(RegistryAccess registryAccess, RegionType regionType, long worldSeed) { int numZooms = TerraBlender.CONFIG.overworldRegionSize; if (regionType == RegionType.NETHER) numZooms = TerraBlender.CONFIG.netherRegionSize; - return createZoomedArea(seed, numZooms, new InitialLayer(registryAccess, regionType)); - } - - public static Area biomeArea(RegistryAccess registryAccess, long seed, int size, List>> entries) - { - return createZoomedArea(seed, size, new BiomeInitialLayer(registryAccess, entries)); - } - - public static Area createZoomedArea(long seed, int zooms, AreaTransformer0 initialTransformer) - { - LongFunction contextFactory = (seedModifier) -> new AreaContext(25, seed, seedModifier); - AreaFactory factory = initialTransformer.run(contextFactory.apply(1L)); + LongFunction contextFactory = (seedModifier) -> new AreaContext(25, worldSeed, seedModifier); + AreaFactory factory = new InitialLayer(registryAccess, regionType).run(contextFactory.apply(1L)); factory = ZoomLayer.FUZZY.run(contextFactory.apply(2000L), factory); factory = zoom(2001L, ZoomLayer.NORMAL, factory, 3, contextFactory); - factory = zoom(1001L, ZoomLayer.NORMAL, factory, zooms, contextFactory); + factory = zoom(1001L, ZoomLayer.NORMAL, factory, numZooms, contextFactory); return factory.make(); } diff --git a/Common/src/main/java/terrablender/worldgen/noise/WeightedRandomLayer.java b/Common/src/main/java/terrablender/worldgen/noise/WeightedRandomLayer.java deleted file mode 100644 index c260a75..0000000 --- a/Common/src/main/java/terrablender/worldgen/noise/WeightedRandomLayer.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (C) Glitchfiend - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package terrablender.worldgen.noise; - -import net.minecraft.util.random.WeightedEntry; -import terrablender.util.WeightedRandomList; - -import java.util.List; - -public abstract class WeightedRandomLayer implements AreaTransformer0 -{ - private final WeightedRandomList weightedEntries; - - public WeightedRandomLayer(List entries) - { - this.weightedEntries = WeightedRandomList.create(entries); - } - - @Override - public int apply(AreaContext context, int x, int y) - { - return this.weightedEntries.getRandom(context).map(this::getEntryIndex).orElse(getDefaultIndex()); - } - - protected abstract int getEntryIndex(T entry); - - protected int getDefaultIndex() - { - return 0; - } -} diff --git a/Common/src/main/resources/terrablender.mixins.json b/Common/src/main/resources/terrablender.mixins.json index 135d086..0ee92dc 100644 --- a/Common/src/main/resources/terrablender.mixins.json +++ b/Common/src/main/resources/terrablender.mixins.json @@ -9,8 +9,7 @@ "MixinMultiNoiseBiomeSource", "MixinNoiseGeneratorSettings", "MixinParameterList", - "MixinPrimaryLevelData", - "MixinTheEndBiomeSource" + "MixinPrimaryLevelData" ], "client": [ "MixinWorldOpenFlows" diff --git a/gradle.properties b/gradle.properties index 3aee4ea..1d891d2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ forge_ats_enabled=true # Fabric fabric_version=0.83.1+1.20.1 -fabric_loader_version=0.15.0 +fabric_loader_version=0.14.21 # Mod options mod_name=TerraBlender