Cleanup worldgen code, should fix a lot of issues with other mods. Configuration will come later.
This commit is contained in:
parent
838bb9b114
commit
548c12eee8
4 changed files with 8 additions and 257 deletions
|
@ -1,89 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of RebornCore, licensed under the MIT License (MIT).
|
|
||||||
*
|
|
||||||
* Copyright (c) 2021 TeamReborn
|
|
||||||
*
|
|
||||||
* 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 reborncore.common.util;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.function.BiConsumer;
|
|
||||||
|
|
||||||
public class BiObseravable<A, B> {
|
|
||||||
@Nullable
|
|
||||||
private A a;
|
|
||||||
@Nullable
|
|
||||||
private B b;
|
|
||||||
|
|
||||||
private final List<BiConsumer<A, B>> listeners = new LinkedList<>();
|
|
||||||
|
|
||||||
public void pushA(A a) {
|
|
||||||
this.a = a;
|
|
||||||
fireListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pushB(B b) {
|
|
||||||
this.b = b;
|
|
||||||
fireListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public A getA() {
|
|
||||||
Objects.requireNonNull(a);
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public B getB() {
|
|
||||||
Objects.requireNonNull(b);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasA() {
|
|
||||||
return a != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasB() {
|
|
||||||
return b != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasBoth() {
|
|
||||||
return hasA() && hasB();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void fireListeners() {
|
|
||||||
if (a == null || b == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (BiConsumer<A, B> listener : listeners) {
|
|
||||||
listener.accept(a, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void listen(@NotNull BiConsumer<@NotNull A, @NotNull B> consumer) {
|
|
||||||
listeners.add(consumer);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -26,6 +26,7 @@ package techreborn.world;
|
||||||
|
|
||||||
import net.minecraft.block.sapling.SaplingGenerator;
|
import net.minecraft.block.sapling.SaplingGenerator;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.BuiltinRegistries;
|
||||||
import net.minecraft.util.registry.MutableRegistry;
|
import net.minecraft.util.registry.MutableRegistry;
|
||||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||||
import net.minecraft.world.gen.feature.DecoratedFeatureConfig;
|
import net.minecraft.world.gen.feature.DecoratedFeatureConfig;
|
||||||
|
@ -42,13 +43,7 @@ public class RubberSaplingGenerator extends SaplingGenerator {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
protected ConfiguredFeature<TreeFeatureConfig, ?> getTreeFeature(Random random, boolean bl) {
|
protected ConfiguredFeature<TreeFeatureConfig, ?> getTreeFeature(Random random, boolean bl) {
|
||||||
MutableRegistry<ConfiguredFeature<?, ?>> registry = WorldGenerator.worldGenObseravable.getA();
|
DecoratedFeatureConfig decoratedFeatureConfig = (DecoratedFeatureConfig) BuiltinRegistries.CONFIGURED_FEATURE.get(IDENTIFIER).getConfig();
|
||||||
if (!registry.getIds().contains(IDENTIFIER)) {
|
|
||||||
LOGGER.debug("Rubber tree feature not found. Are you in the rendering thread?");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
DecoratedFeatureConfig decoratedFeatureConfig = (DecoratedFeatureConfig) registry.get(IDENTIFIER).getConfig();
|
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
return (ConfiguredFeature<TreeFeatureConfig, ?>) decoratedFeatureConfig.feature.get();
|
return (ConfiguredFeature<TreeFeatureConfig, ?>) decoratedFeatureConfig.feature.get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,117 +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.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 reborncore.common.crafting.ConditionManager;
|
|
||||||
|
|
||||||
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<Void> 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<DataDrivenFeature> loadConfig(ResourceManager manager) {
|
|
||||||
final Collection<Identifier> featureResources = manager.findResources("techreborn/features", s -> s.endsWith(".json"));
|
|
||||||
final List<DataDrivenFeature> 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> T parse(BiFunction<Identifier, JsonObject, T> deserialiser, Identifier resource, ResourceManager manager) {
|
|
||||||
try(InputStreamReader inputStreamReader = new InputStreamReader(manager.getResource(resource).getInputStream(), StandardCharsets.UTF_8)) {
|
|
||||||
JsonElement jsonElement = new JsonParser().parse(inputStreamReader);
|
|
||||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
|
||||||
|
|
||||||
if (!ConditionManager.shouldLoadRecipe(jsonObject)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return deserialiser.apply(resource, jsonObject);
|
|
||||||
} catch (JsonParseException |IOException e) {
|
|
||||||
LOGGER.error("Failed to parse " + resource.toString());
|
|
||||||
LOGGER.error(e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Void apply(List<DataDrivenFeature> features) {
|
|
||||||
WorldGenerator.worldGenObseravable.pushB(features);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Identifier getFabricId() {
|
|
||||||
return new Identifier("techreborn", "worldgenerator");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<DataDrivenFeature> getActiveFeatures() {
|
|
||||||
return WorldGenerator.worldGenObseravable.getB();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Identifier> getFabricDependencies() {
|
|
||||||
// Load before tags, so we are soon enough to get into the world gen
|
|
||||||
return Collections.singletonList(ResourceReloadListenerKeys.TAGS);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,60 +24,38 @@
|
||||||
|
|
||||||
package techreborn.world;
|
package techreborn.world;
|
||||||
|
|
||||||
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.BiomeModifications;
|
||||||
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
|
import net.fabricmc.fabric.api.biome.v1.BiomeSelectors;
|
||||||
import net.fabricmc.fabric.api.biome.v1.ModificationPhase;
|
import net.fabricmc.fabric.api.biome.v1.ModificationPhase;
|
||||||
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.BuiltinRegistries;
|
import net.minecraft.util.registry.BuiltinRegistries;
|
||||||
import net.minecraft.util.registry.MutableRegistry;
|
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
import net.minecraft.world.gen.decorator.ChanceDecoratorConfig;
|
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.Feature;
|
||||||
import net.minecraft.world.gen.feature.TreeFeatureConfig;
|
import net.minecraft.world.gen.feature.TreeFeatureConfig;
|
||||||
import net.minecraft.world.gen.foliage.FoliagePlacerType;
|
import net.minecraft.world.gen.foliage.FoliagePlacerType;
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import reborncore.common.util.BiObseravable;
|
|
||||||
import reborncore.mixin.common.AccessorFoliagePlacerType;
|
import reborncore.mixin.common.AccessorFoliagePlacerType;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class WorldGenerator {
|
public class WorldGenerator {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger();
|
|
||||||
|
|
||||||
public static Feature<TreeFeatureConfig> RUBBER_TREE_FEATURE;
|
public static Feature<TreeFeatureConfig> RUBBER_TREE_FEATURE;
|
||||||
public static RubberTreeDecorator RUBBER_TREE_DECORATOR;
|
public static RubberTreeDecorator RUBBER_TREE_DECORATOR;
|
||||||
public static FoliagePlacerType<RubberTreeFeature.FoliagePlacer> RUBBER_TREE_FOLIAGE_PLACER_TYPE;
|
public static FoliagePlacerType<RubberTreeFeature.FoliagePlacer> RUBBER_TREE_FOLIAGE_PLACER_TYPE;
|
||||||
|
|
||||||
public static BiObseravable<MutableRegistry<ConfiguredFeature<?, ?>>, List<DataDrivenFeature>> worldGenObseravable = new BiObseravable<>();
|
|
||||||
|
|
||||||
private static final IntArrayList modifiedRegistries = new IntArrayList();
|
|
||||||
|
|
||||||
public static void initWorldGen() {
|
public static void initWorldGen() {
|
||||||
registerTreeDecorators();
|
registerTreeDecorators();
|
||||||
|
|
||||||
// DefaultWorldGen.export();
|
List<DataDrivenFeature> features = DefaultWorldGen.getDefaultFeatures();
|
||||||
|
//TODO modify list with a config
|
||||||
|
|
||||||
worldGenObseravable.listen(WorldGenerator::applyToActiveRegistry);
|
for (DataDrivenFeature feature : features) {
|
||||||
|
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, feature.getRegistryKey().getValue(), feature.getConfiguredFeature());
|
||||||
|
}
|
||||||
// FIXME 1.17 datadriven worldgen, for now we just use the default
|
|
||||||
//ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new WorldGenConfigReloader());
|
|
||||||
worldGenObseravable.pushB(DefaultWorldGen.getDefaultFeatures());
|
|
||||||
|
|
||||||
|
|
||||||
DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
|
|
||||||
worldGenObseravable.pushA(registryManager.getMutable(BuiltinRegistries.CONFIGURED_FEATURE.getKey()));
|
|
||||||
});
|
|
||||||
|
|
||||||
BiomeModifications.create(new Identifier("techreborn", "features")).add(ModificationPhase.ADDITIONS, BiomeSelectors.all(),
|
BiomeModifications.create(new Identifier("techreborn", "features")).add(ModificationPhase.ADDITIONS, BiomeSelectors.all(),
|
||||||
(biomeSelectionContext, biomeModificationContext) -> {
|
(biomeSelectionContext, biomeModificationContext) -> {
|
||||||
for (DataDrivenFeature feature : worldGenObseravable.getB()) {
|
for (DataDrivenFeature feature : features) {
|
||||||
if (feature.getBiomeSelector().test(biomeSelectionContext)) {
|
if (feature.getBiomeSelector().test(biomeSelectionContext)) {
|
||||||
biomeModificationContext.getGenerationSettings().addFeature(feature.getGenerationStep(), feature.getRegistryKey());
|
biomeModificationContext.getGenerationSettings().addFeature(feature.getGenerationStep(), feature.getRegistryKey());
|
||||||
}
|
}
|
||||||
|
@ -85,25 +63,9 @@ public class WorldGenerator {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void applyToActiveRegistry(MutableRegistry<ConfiguredFeature<?, ?>> registry, List<DataDrivenFeature> 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() {
|
private static void registerTreeDecorators() {
|
||||||
RUBBER_TREE_FEATURE = Registry.register(Registry.FEATURE, new Identifier("techreborn:rubber_tree"), new RubberTreeFeature(TreeFeatureConfig.CODEC));
|
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_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);
|
RUBBER_TREE_FOLIAGE_PLACER_TYPE = AccessorFoliagePlacerType.register("techreborn:rubber_tree", RubberTreeFeature.FoliagePlacer.CODEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue