From 98857f51199122b78d1f324c5fc53e179bb8ece1 Mon Sep 17 00:00:00 2001 From: modmuss50 Date: Sun, 1 Nov 2020 20:08:19 +0000 Subject: [PATCH] First pass on data driven worldgen --- src/main/java/techreborn/init/TRContent.java | 10 +- .../world/BiomeSelectorDeserialiser.java | 62 +++++++++ .../techreborn/world/DataDrivenFeature.java | 129 ++++++++++++++++++ .../techreborn/world/DefaultWorldGen.java | 84 ++++++++---- .../world/RubberSaplingGenerator.java | 12 +- .../java/techreborn/world/TechRebornOre.java | 103 -------------- .../java/techreborn/world/WorldGenCodecs.java | 62 +++++++++ .../java/techreborn/world/WorldGenConfig.java | 58 -------- .../world/WorldGenConfigReloader.java | 110 +++++++++++++++ .../java/techreborn/world/WorldGenerator.java | 121 +++++++--------- .../techreborn/world/WorldTargetType.java | 63 --------- .../techreborn/features/bauxite_ore.json | 50 +++++++ .../techreborn/features/cinnabar_ore.json | 50 +++++++ .../techreborn/features/copper_ore.json | 50 +++++++ .../techreborn/features/galena_ore.json | 50 +++++++ .../techreborn/features/iridium_ore.json | 50 +++++++ .../techreborn/features/lead_ore.json | 50 +++++++ .../techreborn/features/peridot_ore.json | 52 +++++++ .../techreborn/features/pyrite_ore.json | 50 +++++++ .../techreborn/features/rubber_tree.json | 129 ++++++++++++++++++ .../techreborn/features/ruby_ore.json | 50 +++++++ .../techreborn/features/sapphire_ore.json | 50 +++++++ .../techreborn/features/sheldonite_ore.json | 52 +++++++ .../techreborn/features/silver_ore.json | 50 +++++++ .../techreborn/features/sodalite_ore.json | 52 +++++++ .../techreborn/features/sphalerite_ore.json | 50 +++++++ .../techreborn/features/tin_ore.json | 50 +++++++ .../techreborn/features/tungsten_ore.json | 52 +++++++ src/main/resources/fabric.mod.json | 3 +- 29 files changed, 1424 insertions(+), 330 deletions(-) create mode 100644 src/main/java/techreborn/world/BiomeSelectorDeserialiser.java create mode 100644 src/main/java/techreborn/world/DataDrivenFeature.java delete mode 100644 src/main/java/techreborn/world/TechRebornOre.java create mode 100644 src/main/java/techreborn/world/WorldGenCodecs.java delete mode 100644 src/main/java/techreborn/world/WorldGenConfig.java create mode 100644 src/main/java/techreborn/world/WorldGenConfigReloader.java delete mode 100644 src/main/java/techreborn/world/WorldTargetType.java create mode 100644 src/main/resources/data/techreborn/techreborn/features/bauxite_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/cinnabar_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/copper_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/galena_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/iridium_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/lead_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/peridot_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/pyrite_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/rubber_tree.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/ruby_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/sapphire_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/sheldonite_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/silver_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/sodalite_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/sphalerite_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/tin_ore.json create mode 100644 src/main/resources/data/techreborn/techreborn/features/tungsten_ore.json diff --git a/src/main/java/techreborn/init/TRContent.java b/src/main/java/techreborn/init/TRContent.java index cb91b00c4..4b2d6cf49 100644 --- a/src/main/java/techreborn/init/TRContent.java +++ b/src/main/java/techreborn/init/TRContent.java @@ -24,6 +24,7 @@ package techreborn.init; +import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags; import net.minecraft.block.*; @@ -33,6 +34,7 @@ import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.sound.BlockSoundGroup; import net.minecraft.structure.rule.RuleTest; +import net.minecraft.util.Identifier; import reborncore.api.blockentity.IUpgrade; import reborncore.common.fluid.FluidValue; import reborncore.common.powerSystem.PowerAcceptorBlockEntity; @@ -83,11 +85,11 @@ import techreborn.items.tool.MiningLevel; import techreborn.utils.InitUtils; import org.jetbrains.annotations.Nullable; -import techreborn.world.TechRebornOre; -import techreborn.world.WorldTargetType; +import techreborn.world.DataDrivenFeature; import java.util.*; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Stream; public class TRContent { @@ -418,8 +420,8 @@ public class TRContent { return block.asItem(); } - public TechRebornOre asNewOres(WorldTargetType targetType, RuleTest ruleTest) { - return new TechRebornOre(targetType, ruleTest, block.getDefaultState(), maxY, veinSize, veinsPerChunk); + public DataDrivenFeature asNewOres(Identifier identifier, Predicate targetType, RuleTest ruleTest) { + return new DataDrivenFeature(identifier, targetType, ruleTest, block.getDefaultState(), maxY, veinSize, veinsPerChunk); } } diff --git a/src/main/java/techreborn/world/BiomeSelectorDeserialiser.java b/src/main/java/techreborn/world/BiomeSelectorDeserialiser.java new file mode 100644 index 000000000..8d3483aed --- /dev/null +++ b/src/main/java/techreborn/world/BiomeSelectorDeserialiser.java @@ -0,0 +1,62 @@ +package techreborn.world; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext; +import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; +import net.minecraft.util.Util; +import net.minecraft.world.biome.Biome; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; + +public class BiomeSelectorDeserialiser { + + private static final Map> SIMPLE_SELECTOR_MAP = Util.make(new HashMap<>(), map -> { + map.put("all", BiomeSelectors.all()); + map.put("overworld", BiomeSelectors.foundInOverworld()); + map.put("end", BiomeSelectors.foundInTheEnd()); + map.put("nether", BiomeSelectors.foundInTheNether()); + }); + + public static Predicate deserialise(JsonElement jsonElement) { + if (jsonElement.isJsonPrimitive() && jsonElement.getAsJsonPrimitive().isString()) { + Predicate selector = SIMPLE_SELECTOR_MAP.get(jsonElement.getAsString().toLowerCase(Locale.ROOT)); + if (selector == null) { + throw new JsonParseException("Could not find selector for " + jsonElement.getAsString()); + } + return selector; + } + + + if (jsonElement.isJsonArray()) { + JsonArray jsonArray = jsonElement.getAsJsonArray(); + + Set categorySet = EnumSet.noneOf(Biome.Category.class); + + for (JsonElement element : jsonArray) { + if (!(element.isJsonPrimitive() && element.getAsJsonPrimitive().isString())) { + throw new JsonParseException("json array must only contain strings"); + } + Biome.Category category = Biome.Category.byName(element.getAsString()); + + if (category == null) { + throw new JsonParseException("Could not find biome category: " + element.getAsString()); + } + + categorySet.add(category); + } + + return context -> categorySet.contains(context.getBiome().getCategory()); + } + + // TODO support more complex selectors here + + throw new JsonParseException("Could not parse biome selector"); + } +} diff --git a/src/main/java/techreborn/world/DataDrivenFeature.java b/src/main/java/techreborn/world/DataDrivenFeature.java new file mode 100644 index 000000000..a6c36e12a --- /dev/null +++ b/src/main/java/techreborn/world/DataDrivenFeature.java @@ -0,0 +1,129 @@ +/* + * This file is part of TechReborn, licensed under the MIT License (MIT). + * + * Copyright (c) 2020 TechReborn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package techreborn.world; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.Dynamic; +import com.mojang.serialization.JsonOps; +import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext; +import net.minecraft.block.BlockState; +import net.minecraft.structure.rule.RuleTest; +import net.minecraft.util.Identifier; +import net.minecraft.util.JsonHelper; +import net.minecraft.util.registry.BuiltinRegistries; +import net.minecraft.util.registry.RegistryKey; +import net.minecraft.world.gen.GenerationStep; +import net.minecraft.world.gen.feature.ConfiguredFeature; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.OreFeatureConfig; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.function.Predicate; + +public class DataDrivenFeature { + private static final Logger LOGGER = LogManager.getLogger(); + + private final Predicate biomeSelector; + private final ConfiguredFeature configuredFeature; + private final GenerationStep.Feature generationStep; + private final Identifier identifier; + + public DataDrivenFeature(Identifier identifier, Predicate biomeSelector, ConfiguredFeature configuredFeature, GenerationStep.Feature generationStep) { + this.identifier = identifier; + this.biomeSelector = biomeSelector; + this.configuredFeature = configuredFeature; + this.generationStep = generationStep; + } + + @Deprecated + public DataDrivenFeature(Identifier identifier, Predicate biomeSelector, RuleTest ruleTest, BlockState blockState, int maxY, int veinSize, int veinCount) { + this(identifier, biomeSelector, Feature.ORE.configure( + new OreFeatureConfig(ruleTest, blockState, veinSize) + ) + .method_30377(maxY) + .spreadHorizontally() + .repeat(veinCount), GenerationStep.Feature.UNDERGROUND_ORES); + } + + public static DataDrivenFeature deserialise(Identifier identifier, JsonObject jsonObject) { + if (!JsonHelper.hasElement(jsonObject, "biomeSelector")) { + throw new JsonParseException("Could not find biomeSelector element"); + } + Predicate biomeSelector = BiomeSelectorDeserialiser.deserialise(jsonObject.get("biomeSelector")); + + if (!JsonHelper.hasElement(jsonObject, "configuredFeature")) { + throw new JsonParseException("Could not find configuredFeature element"); + } + + DataResult> dataResult = ConfiguredFeature.CODEC.parse(new Dynamic<>(JsonOps.INSTANCE, jsonObject.get("configuredFeature"))); + + ConfiguredFeature configuredFeature = dataResult.getOrThrow(true, s -> { + throw new JsonParseException(s); + }); + + if (!JsonHelper.hasElement(jsonObject, "generationStep")) { + throw new JsonParseException("Could not find generationStep element"); + } + + DataResult genStepDataResult = WorldGenCodecs.GenerationStepFeature.CODEC.parse(new Dynamic<>(JsonOps.INSTANCE, jsonObject.get("generationStep"))); + + GenerationStep.Feature generationStep = genStepDataResult.getOrThrow(true, s -> { + throw new JsonParseException(s); + }).getFeature(); + + return new DataDrivenFeature(identifier, biomeSelector, configuredFeature, generationStep); + } + + public JsonObject serialise() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("biomeSelector", "overworld"); + jsonObject.add("generationStep", WorldGenCodecs.GenerationStepFeature.CODEC.encodeStart(JsonOps.INSTANCE, WorldGenCodecs.GenerationStepFeature.byFeature(generationStep)).getOrThrow(true, LOGGER::error)); + jsonObject.add("configuredFeature", ConfiguredFeature.CODEC.encodeStart(JsonOps.INSTANCE, configuredFeature).getOrThrow(true, LOGGER::error)); + return jsonObject; + } + + public ConfiguredFeature getConfiguredFeature() { + return configuredFeature; + } + + public RegistryKey> getRegistryKey() { + return RegistryKey.of(BuiltinRegistries.CONFIGURED_FEATURE.getKey(), identifier); + } + + public Identifier getIdentifier() { + return identifier; + } + + public GenerationStep.Feature getGenerationStep() { + return generationStep; + } + + public Predicate getBiomeSelector() { + return biomeSelector; + } +} diff --git a/src/main/java/techreborn/world/DefaultWorldGen.java b/src/main/java/techreborn/world/DefaultWorldGen.java index 23ca59a23..451159ce0 100644 --- a/src/main/java/techreborn/world/DefaultWorldGen.java +++ b/src/main/java/techreborn/world/DefaultWorldGen.java @@ -24,11 +24,18 @@ package techreborn.world; +import com.google.gson.JsonElement; +import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext; +import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; import net.minecraft.block.Blocks; import net.minecraft.structure.rule.BlockStateMatchRuleTest; import net.minecraft.structure.rule.RuleTest; +import net.minecraft.util.Identifier; +import net.minecraft.util.Pair; import net.minecraft.util.math.Direction; +import net.minecraft.util.registry.Registry; import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.GenerationStep; import net.minecraft.world.gen.UniformIntDistribution; import net.minecraft.world.gen.decorator.ChanceDecoratorConfig; import net.minecraft.world.gen.feature.ConfiguredFeature; @@ -39,23 +46,25 @@ import net.minecraft.world.gen.stateprovider.SimpleBlockStateProvider; import net.minecraft.world.gen.stateprovider.WeightedBlockStateProvider; import net.minecraft.world.gen.trunk.StraightTrunkPlacer; import org.apache.logging.log4j.util.TriConsumer; +import reborncore.common.util.IdentifiableObject; import techreborn.blocks.misc.BlockRubberLog; -import techreborn.config.TechRebornConfig; import techreborn.init.TRContent; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; public class DefaultWorldGen { private static final RuleTest END_STONE = new BlockStateMatchRuleTest(Blocks.END_STONE.getDefaultState()); - public static WorldGenConfig getDefaultWorldGen() { - return new WorldGenConfig(getOres(), getRubberTree()); - } - private static ConfiguredFeature getRubberTree() { WeightedBlockStateProvider logProvider = new WeightedBlockStateProvider(); logProvider.addState(TRContent.RUBBER_LOG.getDefaultState(), 10); @@ -83,30 +92,53 @@ public class DefaultWorldGen { )); } - private static List getOres() { - List ores = new ArrayList<>(); - TriConsumer addOre = (worldTargetType, ruleTest, ore) -> ores.add(ore.asNewOres(worldTargetType, ruleTest)); + public static List getDefaultFeatures() { + List features = new ArrayList<>(); + TriConsumer, RuleTest, TRContent.Ores> addOre = (worldTargetType, ruleTest, ore) -> + features.add(ore.asNewOres(new Identifier("techreborn", Registry.BLOCK.getId(ore.block).getPath()), worldTargetType, ruleTest)); - addOre.accept(WorldTargetType.NETHER, OreFeatureConfig.Rules.BASE_STONE_NETHER, TRContent.Ores.CINNABAR); - addOre.accept(WorldTargetType.NETHER, OreFeatureConfig.Rules.BASE_STONE_NETHER, TRContent.Ores.PYRITE); - addOre.accept(WorldTargetType.NETHER, OreFeatureConfig.Rules.BASE_STONE_NETHER, TRContent.Ores.SPHALERITE); + addOre.accept(BiomeSelectors.foundInTheNether(), OreFeatureConfig.Rules.BASE_STONE_NETHER, TRContent.Ores.CINNABAR); + addOre.accept(BiomeSelectors.foundInTheNether(), OreFeatureConfig.Rules.BASE_STONE_NETHER, TRContent.Ores.PYRITE); + addOre.accept(BiomeSelectors.foundInTheNether(), OreFeatureConfig.Rules.BASE_STONE_NETHER, TRContent.Ores.SPHALERITE); - addOre.accept(WorldTargetType.END, END_STONE, TRContent.Ores.PERIDOT); - addOre.accept(WorldTargetType.END, END_STONE, TRContent.Ores.SHELDONITE); - addOre.accept(WorldTargetType.END, END_STONE, TRContent.Ores.SODALITE); - addOre.accept(WorldTargetType.END, END_STONE, TRContent.Ores.TUNGSTEN); + addOre.accept(BiomeSelectors.foundInTheEnd(), END_STONE, TRContent.Ores.PERIDOT); + addOre.accept(BiomeSelectors.foundInTheEnd(), END_STONE, TRContent.Ores.SHELDONITE); + addOre.accept(BiomeSelectors.foundInTheEnd(), END_STONE, TRContent.Ores.SODALITE); + addOre.accept(BiomeSelectors.foundInTheEnd(), END_STONE, TRContent.Ores.TUNGSTEN); - addOre.accept(WorldTargetType.DEFAULT, OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.BAUXITE); - addOre.accept(WorldTargetType.DEFAULT, OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.COPPER); - addOre.accept(WorldTargetType.DEFAULT, OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.GALENA); - addOre.accept(WorldTargetType.DEFAULT, OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.IRIDIUM); - addOre.accept(WorldTargetType.DEFAULT, OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.LEAD); - addOre.accept(WorldTargetType.DEFAULT, OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.RUBY); - addOre.accept(WorldTargetType.DEFAULT, OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.SAPPHIRE); - addOre.accept(WorldTargetType.DEFAULT, OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.SILVER); - addOre.accept(WorldTargetType.DEFAULT, OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.TIN); + addOre.accept(BiomeSelectors.foundInOverworld(), OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.BAUXITE); + addOre.accept(BiomeSelectors.foundInOverworld(), OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.COPPER); + addOre.accept(BiomeSelectors.foundInOverworld(), OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.GALENA); + addOre.accept(BiomeSelectors.foundInOverworld(), OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.IRIDIUM); + addOre.accept(BiomeSelectors.foundInOverworld(), OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.LEAD); + addOre.accept(BiomeSelectors.foundInOverworld(), OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.RUBY); + addOre.accept(BiomeSelectors.foundInOverworld(), OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.SAPPHIRE); + addOre.accept(BiomeSelectors.foundInOverworld(), OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.SILVER); + addOre.accept(BiomeSelectors.foundInOverworld(), OreFeatureConfig.Rules.BASE_STONE_OVERWORLD, TRContent.Ores.TIN); - return Collections.unmodifiableList(ores); + + features.add(new DataDrivenFeature( + new Identifier("techreborn", "rubber_tree"), + BiomeSelectors.categories(Biome.Category.FOREST, Biome.Category.TAIGA, Biome.Category.SWAMP), + getRubberTree(), + GenerationStep.Feature.VEGETAL_DECORATION + )); + + return features; } + // Used to export the worldgen jsons + public static void export() { + for (DataDrivenFeature defaultFeature : getDefaultFeatures()) { + JsonElement jsonElement = defaultFeature.serialise(); + String json = jsonElement.toString(); + + Path dir = Paths.get("..\\src\\main\\resources\\data\\techreborn\\techreborn\\features"); + try { + Files.write(dir.resolve(defaultFeature.getIdentifier().getPath() + ".json"), json.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } + } + } } diff --git a/src/main/java/techreborn/world/RubberSaplingGenerator.java b/src/main/java/techreborn/world/RubberSaplingGenerator.java index 49cda941b..ed8a443cd 100644 --- a/src/main/java/techreborn/world/RubberSaplingGenerator.java +++ b/src/main/java/techreborn/world/RubberSaplingGenerator.java @@ -25,6 +25,8 @@ package techreborn.world; import net.minecraft.block.sapling.SaplingGenerator; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.MutableRegistry; import net.minecraft.world.gen.feature.ConfiguredFeature; import net.minecraft.world.gen.feature.DecoratedFeatureConfig; import net.minecraft.world.gen.feature.TreeFeatureConfig; @@ -33,12 +35,18 @@ import org.jetbrains.annotations.Nullable; import java.util.Random; public class RubberSaplingGenerator extends SaplingGenerator { + private final Identifier identifier = new Identifier("techreborn", "rubber_tree"); + @Nullable @Override protected ConfiguredFeature createTreeFeature(Random random, boolean bl) { - DecoratedFeatureConfig decoratedFeatureConfig = (DecoratedFeatureConfig) WorldGenerator.activeConfig.getRubberTree().getConfig(); + MutableRegistry> registry = WorldGenerator.worldGenObseravable.getA(); + if (!registry.containsId(identifier)) { + throw new RuntimeException("Could not find registered rubber tree feature!"); + } + + DecoratedFeatureConfig decoratedFeatureConfig = (DecoratedFeatureConfig) registry.get(identifier).getConfig(); //noinspection unchecked return (ConfiguredFeature) decoratedFeatureConfig.feature.get(); } - } diff --git a/src/main/java/techreborn/world/TechRebornOre.java b/src/main/java/techreborn/world/TechRebornOre.java deleted file mode 100644 index d5e56ea1b..000000000 --- a/src/main/java/techreborn/world/TechRebornOre.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of TechReborn, licensed under the MIT License (MIT). - * - * Copyright (c) 2020 TechReborn - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package techreborn.world; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.block.BlockState; -import net.minecraft.structure.rule.RuleTest; -import net.minecraft.util.Identifier; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.gen.feature.ConfiguredFeature; -import net.minecraft.world.gen.feature.Feature; -import net.minecraft.world.gen.feature.OreFeatureConfig; - -public class TechRebornOre { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> - instance.group( - WorldTargetType.CODEC.fieldOf("target").forGetter(TechRebornOre::getTargetType), - RuleTest.field_25012.fieldOf("rule").forGetter(TechRebornOre::getRuleTest), - BlockState.CODEC.fieldOf("blockState").forGetter(TechRebornOre::getBlockState), - Codec.INT.fieldOf("maxY").forGetter(TechRebornOre::getMaxY), - Codec.INT.fieldOf("veinSize").forGetter(TechRebornOre::getVeinCount), - Codec.INT.fieldOf("veinCount").forGetter(TechRebornOre::getVeinCount) - ).apply(instance, TechRebornOre::new) - ); - - private final WorldTargetType targetType; - private final RuleTest ruleTest; - private final BlockState blockState; - private final int maxY; - private final int veinSize; - private final int veinCount; - private final ConfiguredFeature configuredFeature; - - public TechRebornOre(WorldTargetType targetType, RuleTest ruleTest, BlockState blockState, int maxY, int veinSize, int veinCount) { - this.targetType = targetType; - this.ruleTest = ruleTest; - this.blockState = blockState; - this.maxY = maxY; - this.veinSize = veinSize; - this.veinCount = veinCount; - this.configuredFeature = Feature.ORE.configure( - new OreFeatureConfig(ruleTest, blockState, veinSize) - ) - .method_30377(maxY) - .spreadHorizontally() - .repeat(veinCount); - } - - public ConfiguredFeature getConfiguredFeature() { - return configuredFeature; - } - - public Identifier getIdentifier() { - return new Identifier("techreborn", "ore_" + Registry.BLOCK.getId(blockState.getBlock()).toString().replace(":", "_")); - } - - public WorldTargetType getTargetType() { - return targetType; - } - - public RuleTest getRuleTest() { - return ruleTest; - } - - public BlockState getBlockState() { - return blockState; - } - - public int getMaxY() { - return maxY; - } - - public int getVeinSize() { - return veinSize; - } - - public int getVeinCount() { - return veinCount; - } -} diff --git a/src/main/java/techreborn/world/WorldGenCodecs.java b/src/main/java/techreborn/world/WorldGenCodecs.java new file mode 100644 index 000000000..62fcafc2e --- /dev/null +++ b/src/main/java/techreborn/world/WorldGenCodecs.java @@ -0,0 +1,62 @@ +package techreborn.world; + +import com.mojang.serialization.Codec; +import net.minecraft.util.StringIdentifiable; +import net.minecraft.world.gen.GenerationStep; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.Map; +import java.util.stream.Collectors; + +public class WorldGenCodecs { + + // just a wrapper around GenerationStep.Feature with a codec + public static enum GenerationStepFeature implements StringIdentifiable { + RAW_GENERATION("RAW_GENERATION", GenerationStep.Feature.RAW_GENERATION), + LAKES("LAKES", GenerationStep.Feature.LAKES), + LOCAL_MODIFICATIONS("LOCAL_MODIFICATIONS", GenerationStep.Feature.LOCAL_MODIFICATIONS), + UNDERGROUND_STRUCTURES("UNDERGROUND_STRUCTURES", GenerationStep.Feature.UNDERGROUND_STRUCTURES), + SURFACE_STRUCTURES("SURFACE_STRUCTURES", GenerationStep.Feature.SURFACE_STRUCTURES), + STRONGHOLDS("STRONGHOLDS", GenerationStep.Feature.STRONGHOLDS), + UNDERGROUND_ORES("UNDERGROUND_ORES", GenerationStep.Feature.UNDERGROUND_ORES), + UNDERGROUND_DECORATION("UNDERGROUND_DECORATION", GenerationStep.Feature.UNDERGROUND_DECORATION), + VEGETAL_DECORATION("VEGETAL_DECORATION", GenerationStep.Feature.VEGETAL_DECORATION), + TOP_LAYER_MODIFICATION("TOP_LAYER_MODIFICATION", GenerationStep.Feature.TOP_LAYER_MODIFICATION); + + public static final Codec CODEC = StringIdentifiable.createCodec(GenerationStepFeature::values, GenerationStepFeature::byName); + private static final Map BY_NAME = Arrays.stream(values()).collect(Collectors.toMap(GenerationStepFeature::getName, (carver) -> carver)); + private static final Map BY_FEATURE = Arrays.stream(values()).collect(Collectors.toMap(GenerationStepFeature::getFeature, (carver) -> carver)); + + private final String name; + private final GenerationStep.Feature feature; + + GenerationStepFeature(String name, GenerationStep.Feature feature) { + this.name = name; + this.feature = feature; + } + + public GenerationStep.Feature getFeature() { + return feature; + } + + public String getName() { + return this.name; + } + + @Nullable + public static WorldGenCodecs.GenerationStepFeature byName(String name) { + return BY_NAME.get(name); + } + + @Nullable + public static WorldGenCodecs.GenerationStepFeature byFeature(GenerationStep.Feature feature) { + return BY_FEATURE.get(feature); + } + + @Override + public String asString() { + return name; + } + } +} diff --git a/src/main/java/techreborn/world/WorldGenConfig.java b/src/main/java/techreborn/world/WorldGenConfig.java deleted file mode 100644 index e547a4d36..000000000 --- a/src/main/java/techreborn/world/WorldGenConfig.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of TechReborn, licensed under the MIT License (MIT). - * - * Copyright (c) 2020 TechReborn - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package techreborn.world; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.world.gen.feature.ConfiguredFeature; -import net.minecraft.world.gen.feature.TreeFeatureConfig; - -import java.util.List; - -public class WorldGenConfig { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> - instance.group( - Codec.list(TechRebornOre.CODEC).fieldOf("ores").forGetter(WorldGenConfig::getOres), - ConfiguredFeature.CODEC.fieldOf("rubberTree").forGetter(WorldGenConfig::getRubberTree) - ) - .apply(instance, WorldGenConfig::new) - ); - - private final List ores; - private final ConfiguredFeature rubberTree; - - public WorldGenConfig(List ores, ConfiguredFeature rubberTree) { - this.ores = ores; - this.rubberTree = rubberTree; - } - - public ConfiguredFeature getRubberTree() { - return rubberTree; - } - - public List getOres() { - return ores; - } -} diff --git a/src/main/java/techreborn/world/WorldGenConfigReloader.java b/src/main/java/techreborn/world/WorldGenConfigReloader.java new file mode 100644 index 000000000..ed7414961 --- /dev/null +++ b/src/main/java/techreborn/world/WorldGenConfigReloader.java @@ -0,0 +1,110 @@ +/* + * This file is part of TechReborn, licensed under the MIT License (MIT). + * + * Copyright (c) 2020 TechReborn + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package techreborn.world; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; +import net.fabricmc.fabric.api.resource.ResourceReloadListenerKeys; +import net.minecraft.resource.ResourceManager; +import net.minecraft.util.Identifier; +import net.minecraft.util.profiler.Profiler; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.function.BiFunction; + +public class WorldGenConfigReloader implements IdentifiableResourceReloadListener { + + private static final Logger LOGGER = LogManager.getLogger(); + + @Override + public CompletableFuture reload(Synchronizer synchronizer, ResourceManager manager, Profiler prepareProfiler, Profiler applyProfiler, Executor prepareExecutor, Executor applyExecutor) { + return CompletableFuture.supplyAsync(() -> loadConfig(manager), prepareExecutor) + .thenCompose(synchronizer::whenPrepared) + .thenApplyAsync(this::apply, applyExecutor); + } + + private List loadConfig(ResourceManager manager) { + final Collection featureResources = manager.findResources("techreborn/features", s -> s.endsWith(".json")); + final List features = new LinkedList<>(); + + for (Identifier resource : featureResources) { + DataDrivenFeature identifiableObject = parse(DataDrivenFeature::deserialise, resource, manager); + + if (identifiableObject != null) { + features.add(identifiableObject); + } + } + + LOGGER.info("Loaded " + features.size() + " features"); + + return features; + } + + @Nullable + private T parse(BiFunction deserialiser, Identifier resource, ResourceManager manager) { + try(InputStreamReader inputStreamReader = new InputStreamReader(manager.getResource(resource).getInputStream(), StandardCharsets.UTF_8)) { + JsonElement jsonElement = new JsonParser().parse(inputStreamReader); + return deserialiser.apply(resource, jsonElement.getAsJsonObject()); + } catch (JsonParseException |IOException e) { + LOGGER.error("Failed to parse " + resource.toString()); + LOGGER.error(e); + } + return null; + } + + private Void apply(List features) { + WorldGenerator.worldGenObseravable.pushB(features); + return null; + } + + @Override + public Identifier getFabricId() { + return new Identifier("techreborn", "worldgenerator"); + } + + public static List getActiveFeatures() { + return WorldGenerator.worldGenObseravable.getB(); + } + + @Override + public Collection getFabricDependencies() { + // Load before tags, so we are soon enough to get into the world gen + return Collections.singletonList(ResourceReloadListenerKeys.TAGS); + } +} diff --git a/src/main/java/techreborn/world/WorldGenerator.java b/src/main/java/techreborn/world/WorldGenerator.java index e50bc5d8d..58a5a837c 100644 --- a/src/main/java/techreborn/world/WorldGenerator.java +++ b/src/main/java/techreborn/world/WorldGenerator.java @@ -24,107 +24,82 @@ package techreborn.world; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.gson.JsonElement; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.JsonOps; -import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback; +import com.mojang.serialization.Lifecycle; + +import it.unimi.dsi.fastutil.ints.IntArrayList; +import net.fabricmc.fabric.api.biome.v1.BiomeModifications; +import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; +import net.fabricmc.fabric.api.biome.v1.ModificationPhase; +import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; import net.minecraft.util.registry.BuiltinRegistries; +import net.minecraft.util.registry.MutableRegistry; import net.minecraft.util.registry.Registry; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.Biome.Category; -import net.minecraft.world.gen.GenerationStep; import net.minecraft.world.gen.decorator.ChanceDecoratorConfig; import net.minecraft.world.gen.feature.ConfiguredFeature; import net.minecraft.world.gen.feature.Feature; import net.minecraft.world.gen.feature.TreeFeatureConfig; import net.minecraft.world.gen.foliage.FoliagePlacerType; -import org.jetbrains.annotations.Nullable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import reborncore.common.util.BiObseravable; import reborncore.mixin.common.AccessorFoliagePlacerType; -import techreborn.config.TechRebornConfig; -import java.util.ArrayList; import java.util.List; -import java.util.function.Supplier; -/** - * @author drcrazy - */ public class WorldGenerator { + private static final Logger LOGGER = LogManager.getLogger(); + public static Feature RUBBER_TREE_FEATURE; public static RubberTreeDecorator RUBBER_TREE_DECORATOR; public static FoliagePlacerType RUBBER_TREE_FOLIAGE_PLACER_TYPE; - @Nullable - public static WorldGenConfig activeConfig; - private static final List checkedBiomes = new ArrayList<>(); + public static BiObseravable>, List> worldGenObseravable = new BiObseravable<>(); + + private static final IntArrayList modifiedRegistries = new IntArrayList(); public static void initWorldGen() { - setupTrees(); + registerTreeDecorators(); - activeConfig = DefaultWorldGen.getDefaultWorldGen(); +// DefaultWorldGen.export(); - DataResult result = WorldGenConfig.CODEC.encodeStart(JsonOps.INSTANCE, activeConfig); - JsonElement jsonElement = result.getOrThrow(true, System.out::println); - String json = jsonElement.toString(); + worldGenObseravable.listen(WorldGenerator::applyToActiveRegistry); + ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new WorldGenConfigReloader()); + DynamicRegistrySetupCallback.EVENT.register(registryManager -> { + worldGenObseravable.pushA(registryManager.get(BuiltinRegistries.CONFIGURED_FEATURE.getKey())); + }); - for (Biome biome : BuiltinRegistries.BIOME) { - populateBiome(biome, activeConfig); - } - - //Handles modded biomes - RegistryEntryAddedCallback.event(BuiltinRegistries.BIOME).register((i, identifier, biome) -> populateBiome(biome, activeConfig)); + BiomeModifications.create(new Identifier("techreborn", "features")).add(ModificationPhase.ADDITIONS, BiomeSelectors.all(), (biomeSelectionContext, biomeModificationContext) -> { + for (DataDrivenFeature feature : worldGenObseravable.getB()) { + if (feature.getBiomeSelector().test(biomeSelectionContext)) { + biomeModificationContext.getGenerationSettings().addFeature(feature.getGenerationStep(), feature.getRegistryKey()); + } + } + }); } - private static void setupTrees() { + public static void applyToActiveRegistry(MutableRegistry> registry, List features) { + int hashCode = registry.hashCode(); + if (modifiedRegistries.contains(hashCode)){ + LOGGER.debug("Already modified world gen on this registry"); + return; + } + modifiedRegistries.add(registry.hashCode()); + + LOGGER.debug("Applying " + features.size() + " features to active registry: " + registry); + + for (DataDrivenFeature feature : features) { + registry.add(feature.getRegistryKey(), feature.getConfiguredFeature(), Lifecycle.stable()); + } + } + + private static void registerTreeDecorators() { RUBBER_TREE_FEATURE = Registry.register(Registry.FEATURE, new Identifier("techreborn:rubber_tree"), new RubberTreeFeature(TreeFeatureConfig.CODEC)); RUBBER_TREE_DECORATOR = Registry.register(Registry.DECORATOR, new Identifier("techreborn:rubber_tree"), new RubberTreeDecorator(ChanceDecoratorConfig.CODEC)); RUBBER_TREE_FOLIAGE_PLACER_TYPE = AccessorFoliagePlacerType.register("techreborn:rubber_tree", RubberTreeFeature.FoliagePlacer.CODEC); } - private static void populateBiome(Biome biome, WorldGenConfig config) { - if (checkedBiomes.contains(biome)) { - //Just to be sure we dont add the stuff twice to the same biome - return; - } - checkedBiomes.add(biome); - - for (TechRebornOre ore : config.getOres()) { - if (ore.getTargetType().isApplicable(biome.getCategory())) { - addFeature(biome, ore.getIdentifier(), GenerationStep.Feature.UNDERGROUND_ORES, ore.getConfiguredFeature()); - } - } - - if (biome.getCategory() == Category.FOREST || biome.getCategory() == Category.TAIGA || biome.getCategory() == Category.SWAMP) { - addFeature(biome, new Identifier("techreborn:rubber_tree"), GenerationStep.Feature.VEGETAL_DECORATION, config.getRubberTree()); - } - } - - private static void addFeature(Biome biome, Identifier identifier, GenerationStep.Feature feature, ConfiguredFeature configuredFeature) { - List>>> features = biome.getGenerationSettings().getFeatures(); - - int stepIndex = feature.ordinal(); - - while (features.size() <= stepIndex) { - features.add(Lists.newArrayList()); - } - - List>> stepList = features.get(feature.ordinal()); - if (stepList instanceof ImmutableList) { - features.set(feature.ordinal(), stepList = new ArrayList<>(stepList)); - } - - if (!BuiltinRegistries.CONFIGURED_FEATURE.getKey(configuredFeature).isPresent()) { - if (BuiltinRegistries.CONFIGURED_FEATURE.getOrEmpty(identifier).isPresent()) { - throw new RuntimeException("Duplicate feature: " + identifier.toString()); - } - - BuiltinRegistries.add(BuiltinRegistries.CONFIGURED_FEATURE, identifier, configuredFeature); - } - - stepList.add(() -> configuredFeature); - } } \ No newline at end of file diff --git a/src/main/java/techreborn/world/WorldTargetType.java b/src/main/java/techreborn/world/WorldTargetType.java deleted file mode 100644 index 613e2f5f7..000000000 --- a/src/main/java/techreborn/world/WorldTargetType.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of TechReborn, licensed under the MIT License (MIT). - * - * Copyright (c) 2020 TechReborn - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package techreborn.world; - -import com.mojang.serialization.Codec; -import net.minecraft.util.StringIdentifiable; -import net.minecraft.world.biome.Biome; - -import java.util.function.Predicate; - -public enum WorldTargetType implements StringIdentifiable { - DEFAULT("default", category -> category != Biome.Category.NETHER && category != Biome.Category.THEEND), - NETHER("nether", category -> category == Biome.Category.NETHER), - END("end", category -> category == Biome.Category.THEEND); - - private final String name; - private final Predicate biomeCategoryPredicate; - public static final Codec CODEC = StringIdentifiable.createCodec(WorldTargetType::values, WorldTargetType::getByName); - - WorldTargetType(String name, Predicate biomeCategoryPredicate) { - this.name = name; - this.biomeCategoryPredicate = biomeCategoryPredicate; - } - - public String getName() { - return name; - } - - public boolean isApplicable(Biome.Category biomeCategory) { - return biomeCategoryPredicate.test(biomeCategory); - } - - public static WorldTargetType getByName(String name) { - return null; - } - - @Override - public String asString() { - return name; - } -} diff --git a/src/main/resources/data/techreborn/techreborn/features/bauxite_ore.json b/src/main/resources/data/techreborn/techreborn/features/bauxite_ore.json new file mode 100644 index 000000000..86fd63f3d --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/bauxite_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "overworld", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_overworld", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:bauxite_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 60 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 10 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/cinnabar_ore.json b/src/main/resources/data/techreborn/techreborn/features/cinnabar_ore.json new file mode 100644 index 000000000..9513d01f4 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/cinnabar_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "nether", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_nether", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:cinnabar_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 126 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 3 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/copper_ore.json b/src/main/resources/data/techreborn/techreborn/features/copper_ore.json new file mode 100644 index 000000000..6a58d28d6 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/copper_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "overworld", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_overworld", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:copper_ore" + }, + "size": 8 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 60 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 16 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/galena_ore.json b/src/main/resources/data/techreborn/techreborn/features/galena_ore.json new file mode 100644 index 000000000..6f0357d3a --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/galena_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "overworld", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_overworld", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:galena_ore" + }, + "size": 8 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 60 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 16 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/iridium_ore.json b/src/main/resources/data/techreborn/techreborn/features/iridium_ore.json new file mode 100644 index 000000000..3fb0bcee0 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/iridium_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "overworld", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_overworld", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:iridium_ore" + }, + "size": 3 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 60 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 3 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/lead_ore.json b/src/main/resources/data/techreborn/techreborn/features/lead_ore.json new file mode 100644 index 000000000..d2517014e --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/lead_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "overworld", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_overworld", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:lead_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 60 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 16 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/peridot_ore.json b/src/main/resources/data/techreborn/techreborn/features/peridot_ore.json new file mode 100644 index 000000000..b7d57f341 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/peridot_ore.json @@ -0,0 +1,52 @@ +{ + "biomeSelector": "end", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "block_state": { + "Name": "minecraft:end_stone" + }, + "predicate_type": "minecraft:blockstate_match" + }, + "state": { + "Name": "techreborn:peridot_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 250 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 3 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/pyrite_ore.json b/src/main/resources/data/techreborn/techreborn/features/pyrite_ore.json new file mode 100644 index 000000000..0476266fe --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/pyrite_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "nether", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_nether", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:pyrite_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 126 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 3 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/rubber_tree.json b/src/main/resources/data/techreborn/techreborn/features/rubber_tree.json new file mode 100644 index 000000000..6b62a0534 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/rubber_tree.json @@ -0,0 +1,129 @@ +{ + "biomeSelector": [ + "forest", + "taiga", + "swamp" + ], + "generationStep": "VEGETAL_DECORATION", + "configuredFeature": { + "config": { + "feature": { + "config": { + "max_water_depth": 0, + "ignore_vines": false, + "heightmap": "OCEAN_FLOOR", + "minimum_size": { + "limit": 1, + "lower_size": 0, + "upper_size": 1, + "type": "minecraft:two_layers_feature_size" + }, + "decorators": [], + "trunk_provider": { + "entries": [ + { + "weight": 10, + "data": { + "Properties": { + "shouldsap": "true", + "hassap": "false", + "facing": "north", + "axis": "y" + }, + "Name": "techreborn:rubber_log" + } + }, + { + "weight": 1, + "data": { + "Properties": { + "shouldsap": "true", + "hassap": "true", + "facing": "north", + "axis": "y" + }, + "Name": "techreborn:rubber_log" + } + }, + { + "weight": 1, + "data": { + "Properties": { + "shouldsap": "true", + "hassap": "true", + "facing": "south", + "axis": "y" + }, + "Name": "techreborn:rubber_log" + } + }, + { + "weight": 1, + "data": { + "Properties": { + "shouldsap": "true", + "hassap": "true", + "facing": "west", + "axis": "y" + }, + "Name": "techreborn:rubber_log" + } + }, + { + "weight": 1, + "data": { + "Properties": { + "shouldsap": "true", + "hassap": "true", + "facing": "east", + "axis": "y" + }, + "Name": "techreborn:rubber_log" + } + } + ], + "type": "minecraft:weighted_state_provider" + }, + "leaves_provider": { + "state": { + "Properties": { + "persistent": "false", + "distance": "7" + }, + "Name": "techreborn:rubber_leaves" + }, + "type": "minecraft:simple_state_provider" + }, + "foliage_placer": { + "height": 3, + "spireHeight": 3, + "spireBlockState": { + "Properties": { + "persistent": "false", + "distance": "7" + }, + "Name": "techreborn:rubber_leaves" + }, + "radius": 2, + "offset": 0, + "type": "techreborn:rubber_tree" + }, + "trunk_placer": { + "base_height": 6, + "height_rand_a": 3, + "height_rand_b": 0, + "type": "minecraft:straight_trunk_placer" + } + }, + "type": "techreborn:rubber_tree" + }, + "decorator": { + "config": { + "chance": 50 + }, + "type": "techreborn:rubber_tree" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/ruby_ore.json b/src/main/resources/data/techreborn/techreborn/features/ruby_ore.json new file mode 100644 index 000000000..48965b696 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/ruby_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "overworld", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_overworld", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:ruby_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 60 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 3 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/sapphire_ore.json b/src/main/resources/data/techreborn/techreborn/features/sapphire_ore.json new file mode 100644 index 000000000..8efe483bc --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/sapphire_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "overworld", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_overworld", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:sapphire_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 60 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 3 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/sheldonite_ore.json b/src/main/resources/data/techreborn/techreborn/features/sheldonite_ore.json new file mode 100644 index 000000000..d8cb523c5 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/sheldonite_ore.json @@ -0,0 +1,52 @@ +{ + "biomeSelector": "end", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "block_state": { + "Name": "minecraft:end_stone" + }, + "predicate_type": "minecraft:blockstate_match" + }, + "state": { + "Name": "techreborn:sheldonite_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 250 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 3 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/silver_ore.json b/src/main/resources/data/techreborn/techreborn/features/silver_ore.json new file mode 100644 index 000000000..721000b31 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/silver_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "overworld", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_overworld", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:silver_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 60 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 16 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/sodalite_ore.json b/src/main/resources/data/techreborn/techreborn/features/sodalite_ore.json new file mode 100644 index 000000000..2c063a2d6 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/sodalite_ore.json @@ -0,0 +1,52 @@ +{ + "biomeSelector": "end", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "block_state": { + "Name": "minecraft:end_stone" + }, + "predicate_type": "minecraft:blockstate_match" + }, + "state": { + "Name": "techreborn:sodalite_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 250 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 3 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/sphalerite_ore.json b/src/main/resources/data/techreborn/techreborn/features/sphalerite_ore.json new file mode 100644 index 000000000..5343f3715 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/sphalerite_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "nether", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_nether", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:sphalerite_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 126 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 3 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/tin_ore.json b/src/main/resources/data/techreborn/techreborn/features/tin_ore.json new file mode 100644 index 000000000..d544c3620 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/tin_ore.json @@ -0,0 +1,50 @@ +{ + "biomeSelector": "overworld", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "tag": "minecraft:base_stone_overworld", + "predicate_type": "minecraft:tag_match" + }, + "state": { + "Name": "techreborn:tin_ore" + }, + "size": 8 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 60 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 16 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/data/techreborn/techreborn/features/tungsten_ore.json b/src/main/resources/data/techreborn/techreborn/features/tungsten_ore.json new file mode 100644 index 000000000..2d7de2c06 --- /dev/null +++ b/src/main/resources/data/techreborn/techreborn/features/tungsten_ore.json @@ -0,0 +1,52 @@ +{ + "biomeSelector": "end", + "generationStep": "UNDERGROUND_ORES", + "configuredFeature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "feature": { + "config": { + "target": { + "block_state": { + "Name": "minecraft:end_stone" + }, + "predicate_type": "minecraft:blockstate_match" + }, + "state": { + "Name": "techreborn:tungsten_ore" + }, + "size": 6 + }, + "type": "minecraft:ore" + }, + "decorator": { + "config": { + "bottom_offset": 0, + "top_offset": 0, + "maximum": 250 + }, + "type": "minecraft:range" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": {}, + "type": "minecraft:square" + } + }, + "type": "minecraft:decorated" + }, + "decorator": { + "config": { + "count": 3 + }, + "type": "minecraft:count" + } + }, + "type": "minecraft:decorated" + } +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index c84ec2dcf..07c3492ff 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -30,7 +30,8 @@ "fabricloader": ">=0.6.3", "fabric": "*", "reborncore": "*", - "team_reborn_energy": ">=0.1.0" + "team_reborn_energy": ">=0.1.0", + "fabric-biome-api-v1": ">=3.0.0" }, "authors": [ "Team Reborn",