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.util.Identifier;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.MutableRegistry;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.DecoratedFeatureConfig;
|
||||
|
@ -42,13 +43,7 @@ public class RubberSaplingGenerator extends SaplingGenerator {
|
|||
@Nullable
|
||||
@Override
|
||||
protected ConfiguredFeature<TreeFeatureConfig, ?> getTreeFeature(Random random, boolean bl) {
|
||||
MutableRegistry<ConfiguredFeature<?, ?>> registry = WorldGenerator.worldGenObseravable.getA();
|
||||
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();
|
||||
DecoratedFeatureConfig decoratedFeatureConfig = (DecoratedFeatureConfig) BuiltinRegistries.CONFIGURED_FEATURE.get(IDENTIFIER).getConfig();
|
||||
//noinspection unchecked
|
||||
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;
|
||||
|
||||
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.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.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.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import reborncore.common.util.BiObseravable;
|
||||
import reborncore.mixin.common.AccessorFoliagePlacerType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WorldGenerator {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public static Feature<TreeFeatureConfig> RUBBER_TREE_FEATURE;
|
||||
public static RubberTreeDecorator RUBBER_TREE_DECORATOR;
|
||||
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() {
|
||||
registerTreeDecorators();
|
||||
|
||||
// DefaultWorldGen.export();
|
||||
List<DataDrivenFeature> features = DefaultWorldGen.getDefaultFeatures();
|
||||
//TODO modify list with a config
|
||||
|
||||
worldGenObseravable.listen(WorldGenerator::applyToActiveRegistry);
|
||||
|
||||
|
||||
// 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()));
|
||||
});
|
||||
for (DataDrivenFeature feature : features) {
|
||||
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, feature.getRegistryKey().getValue(), feature.getConfiguredFeature());
|
||||
}
|
||||
|
||||
BiomeModifications.create(new Identifier("techreborn", "features")).add(ModificationPhase.ADDITIONS, BiomeSelectors.all(),
|
||||
(biomeSelectionContext, biomeModificationContext) -> {
|
||||
for (DataDrivenFeature feature : worldGenObseravable.getB()) {
|
||||
for (DataDrivenFeature feature : features) {
|
||||
if (feature.getBiomeSelector().test(biomeSelectionContext)) {
|
||||
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() {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue