mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-05 01:45:00 +01:00
World Generation^2
- Datagen all worldgen data - Remove all individual config values for configured and placed features
This commit is contained in:
parent
f7987570ab
commit
db681959b6
22 changed files with 294 additions and 870 deletions
|
@ -39,9 +39,8 @@ import com.simibubi.create.foundation.data.recipe.StandardRecipeGen;
|
|||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.CreateRegistry;
|
||||
import com.simibubi.create.foundation.worldgen.AllFeatures;
|
||||
import com.simibubi.create.foundation.worldgen.AllOreFeatureConfigEntries;
|
||||
import com.simibubi.create.foundation.worldgen.AllPlacementModifiers;
|
||||
import com.simibubi.create.foundation.worldgen.BuiltinRegistration;
|
||||
import com.simibubi.create.foundation.worldgen.WorldgenDataProvider;
|
||||
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -115,10 +114,8 @@ public class Create {
|
|||
AllParticleTypes.register(modEventBus);
|
||||
AllStructureProcessorTypes.register(modEventBus);
|
||||
AllEntityDataSerializers.register(modEventBus);
|
||||
AllOreFeatureConfigEntries.init();
|
||||
AllFeatures.register(modEventBus);
|
||||
AllPlacementModifiers.register(modEventBus);
|
||||
BuiltinRegistration.register(modEventBus);
|
||||
|
||||
AllConfigs.register(modLoadingContext);
|
||||
|
||||
|
@ -168,7 +165,7 @@ public class Create {
|
|||
gen.addProvider(true, new MechanicalCraftingRecipeGen(gen));
|
||||
gen.addProvider(true, new SequencedAssemblyRecipeGen(gen));
|
||||
ProcessingRecipeGen.registerAll(gen);
|
||||
// AllOreFeatureConfigEntries.gatherData(event);
|
||||
gen.addProvider(true, WorldgenDataProvider.makeFactory(event.getLookupProvider()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,12 @@
|
|||
package com.simibubi.create.foundation.config;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.worldgen.AllOreFeatureConfigEntries;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec.Builder;
|
||||
|
||||
public class CWorldGen extends ConfigBase {
|
||||
|
||||
/**
|
||||
* Increment this number if all worldgen config entries should be overwritten
|
||||
* in this update. Worlds from the previous version will overwrite potentially
|
||||
* changed values with the new defaults.
|
||||
*/
|
||||
public static final int FORCED_UPDATE_VERSION = 2;
|
||||
|
||||
public final ConfigBool disable = b(false, "disableWorldGen", Comments.disable);
|
||||
|
||||
@Override
|
||||
protected void registerAll(Builder builder) {
|
||||
super.registerAll(builder);
|
||||
AllOreFeatureConfigEntries.fillConfig(builder, Create.ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "worldgen.v" + FORCED_UPDATE_VERSION;
|
||||
return "worldgen";
|
||||
}
|
||||
|
||||
private static class Comments {
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
package com.simibubi.create.foundation.data;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.Encoder;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.RegistryAccess.RegistryData;
|
||||
import net.minecraft.data.CachedOutput;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
|
||||
public class DynamicDataProvider<T> implements DataProvider {
|
||||
private final DataGenerator generator;
|
||||
private final String name;
|
||||
private final RegistryAccess registryAccess;
|
||||
private final RegistryAccess.RegistryData<T> registryData;
|
||||
private final Map<ResourceLocation, T> values;
|
||||
|
||||
public DynamicDataProvider(DataGenerator generator, String name, RegistryAccess registryAccess, RegistryAccess.RegistryData<T> registryData, Map<ResourceLocation, T> values) {
|
||||
this.generator = generator;
|
||||
this.name = name;
|
||||
this.registryAccess = registryAccess;
|
||||
this.registryData = registryData;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <T> DynamicDataProvider<T> create(DataGenerator generator, String name, RegistryAccess registryAccess, ResourceKey<? extends Registry<T>> registryKey, Map<ResourceLocation, T> values) {
|
||||
@SuppressWarnings("unchecked")
|
||||
RegistryAccess.RegistryData<T> registryData = (RegistryData<T>) RegistryAccess.REGISTRIES.get(registryKey);
|
||||
if (registryData == null) {
|
||||
return null;
|
||||
}
|
||||
return new DynamicDataProvider<>(generator, name, registryAccess, registryData, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CachedOutput cache) throws IOException {
|
||||
Path path = generator.getOutputFolder();
|
||||
DynamicOps<JsonElement> ops = RegistryOps.create(JsonOps.INSTANCE, registryAccess);
|
||||
|
||||
dumpValues(path, cache, ops, registryData.key(), values, registryData.codec());
|
||||
}
|
||||
|
||||
private void dumpValues(Path rootPath, CachedOutput cache, DynamicOps<JsonElement> ops, ResourceKey<? extends Registry<T>> registryKey, Map<ResourceLocation, T> values, Encoder<T> encoder) {
|
||||
DataGenerator.PathProvider pathProvider = generator.createPathProvider(DataGenerator.Target.DATA_PACK, ForgeHooks.prefixNamespace(registryKey.location()));
|
||||
|
||||
for (Entry<ResourceLocation, T> entry : values.entrySet()) {
|
||||
dumpValue(pathProvider.json(entry.getKey()), cache, ops, encoder, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// From WorldgenRegistryDumpReport
|
||||
private void dumpValue(Path path, CachedOutput cache, DynamicOps<JsonElement> ops, Encoder<T> encoder, T value) {
|
||||
try {
|
||||
Optional<JsonElement> optional = encoder.encodeStart(ops, value).resultOrPartial((message) -> {
|
||||
Create.LOGGER.error("Couldn't serialize element {}: {}", path, message);
|
||||
});
|
||||
if (optional.isPresent()) {
|
||||
DataProvider.saveStable(cache, optional.get(), path);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Create.LOGGER.error("Couldn't save element {}", path, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.worldgen.BootstapContext;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.tags.BiomeTags;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraftforge.common.world.BiomeModifier;
|
||||
import net.minecraftforge.common.world.ForgeBiomeModifiers.AddFeaturesBiomeModifier;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class AllBiomeModifiers {
|
||||
public static final ResourceKey<BiomeModifier>
|
||||
ZINC_ORE = key("zinc_ore"),
|
||||
STRIATED_ORES_OVERWORLD = key("striated_ores_overworld"),
|
||||
STRIATED_ORES_NETHER = key("striated_ores_nether");
|
||||
|
||||
private static ResourceKey<BiomeModifier> key(String name) {
|
||||
return ResourceKey.create(ForgeRegistries.Keys.BIOME_MODIFIERS, Create.asResource(name));
|
||||
}
|
||||
|
||||
public static void bootstrap(BootstapContext<BiomeModifier> ctx) {
|
||||
HolderGetter<Biome> biomeLookup = ctx.lookup(Registries.BIOME);
|
||||
HolderSet<Biome> isOverworld = biomeLookup.getOrThrow(BiomeTags.IS_OVERWORLD);
|
||||
HolderSet<Biome> isNether = biomeLookup.getOrThrow(BiomeTags.IS_NETHER);
|
||||
|
||||
HolderGetter<PlacedFeature> featureLookup = ctx.lookup(Registries.PLACED_FEATURE);
|
||||
Holder<PlacedFeature> zincOre = featureLookup.getOrThrow(AllPlacedFeatures.ZINC_ORE);
|
||||
Holder<PlacedFeature> striatedOresOverworld = featureLookup.getOrThrow(AllPlacedFeatures.STRIATED_ORES_OVERWORLD);
|
||||
Holder<PlacedFeature> striatedOresNether = featureLookup.getOrThrow(AllPlacedFeatures.STRIATED_ORES_NETHER);
|
||||
|
||||
ctx.register(ZINC_ORE, addOre(isOverworld, zincOre));
|
||||
ctx.register(STRIATED_ORES_OVERWORLD, addOre(isOverworld, striatedOresOverworld));
|
||||
ctx.register(STRIATED_ORES_NETHER, addOre(isNether, striatedOresNether));
|
||||
}
|
||||
|
||||
private static AddFeaturesBiomeModifier addOre(HolderSet<Biome> biomes, Holder<PlacedFeature> feature) {
|
||||
return new AddFeaturesBiomeModifier(biomes, HolderSet.direct(feature), Decoration.UNDERGROUND_ORES);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import static net.minecraft.data.worldgen.features.FeatureUtils.register;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.worldgen.BootstapContext;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration.TargetBlockState;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.RuleTest;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.TagMatchTest;
|
||||
|
||||
public class AllConfiguredFeatures {
|
||||
public static final ResourceKey<ConfiguredFeature<?, ?>>
|
||||
ZINC_ORE = key("zinc_ore"),
|
||||
STRIATED_ORES_OVERWORLD = key("striated_ores_overworld"),
|
||||
STRIATED_ORES_NETHER = key("striated_ores_nether");
|
||||
|
||||
private static ResourceKey<ConfiguredFeature<?, ?>> key(String name) {
|
||||
return ResourceKey.create(Registries.CONFIGURED_FEATURE, Create.asResource(name));
|
||||
}
|
||||
|
||||
public static void bootstrap(BootstapContext<ConfiguredFeature<?, ?>> ctx) {
|
||||
RuleTest stoneOreReplaceables = new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES);
|
||||
RuleTest deepslateOreReplaceables = new TagMatchTest(BlockTags.DEEPSLATE_ORE_REPLACEABLES);
|
||||
|
||||
List<TargetBlockState> zincTargetStates = List.of(
|
||||
OreConfiguration.target(stoneOreReplaceables, AllBlocks.ZINC_ORE.get()
|
||||
.defaultBlockState()),
|
||||
OreConfiguration.target(deepslateOreReplaceables, AllBlocks.DEEPSLATE_ZINC_ORE.get()
|
||||
.defaultBlockState())
|
||||
);
|
||||
|
||||
register(ctx, ZINC_ORE, Feature.ORE, new OreConfiguration(zincTargetStates, 12));
|
||||
|
||||
List<LayerPattern> overworldLayerPatterns = List.of(
|
||||
AllLayerPatterns.SCORIA.get(),
|
||||
AllLayerPatterns.CINNABAR.get(),
|
||||
AllLayerPatterns.MAGNETITE.get(),
|
||||
AllLayerPatterns.MALACHITE.get(),
|
||||
AllLayerPatterns.LIMESTONE.get(),
|
||||
AllLayerPatterns.OCHRESTONE.get()
|
||||
);
|
||||
|
||||
register(ctx, STRIATED_ORES_OVERWORLD, AllFeatures.LAYERED_ORE.get(), new LayeredOreConfiguration(overworldLayerPatterns, 32, 0));
|
||||
|
||||
List<LayerPattern> netherLayerPatterns = List.of(
|
||||
AllLayerPatterns.SCORIA_NETHER.get(),
|
||||
AllLayerPatterns.SCORCHIA_NETHER.get()
|
||||
);
|
||||
|
||||
register(ctx, STRIATED_ORES_NETHER, AllFeatures.LAYERED_ORE.get(), new LayeredOreConfiguration(netherLayerPatterns, 32, 0));
|
||||
}
|
||||
}
|
|
@ -11,7 +11,6 @@ import net.minecraftforge.registries.RegistryObject;
|
|||
public class AllFeatures {
|
||||
private static final DeferredRegister<Feature<?>> REGISTER = DeferredRegister.create(ForgeRegistries.FEATURES, Create.ID);
|
||||
|
||||
public static final RegistryObject<StandardOreFeature> STANDARD_ORE = REGISTER.register("standard_ore", () -> new StandardOreFeature());
|
||||
public static final RegistryObject<LayeredOreFeature> LAYERED_ORE = REGISTER.register("layered_ore", () -> new LayeredOreFeature());
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.data.DynamicDataProvider;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.worldgen.OreFeatureConfigEntry.DatagenExtension;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.BiomeTags;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.common.world.BiomeModifier;
|
||||
import net.minecraftforge.data.event.GatherDataEvent;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class AllOreFeatureConfigEntries {
|
||||
public static final OreFeatureConfigEntry ZINC_ORE =
|
||||
create("zinc_ore", 12, 8, -63, 70)
|
||||
.standardDatagenExt()
|
||||
.withBlocks(Couple.create(AllBlocks.ZINC_ORE, AllBlocks.DEEPSLATE_ZINC_ORE))
|
||||
.biomeTag(BiomeTags.IS_OVERWORLD)
|
||||
.parent();
|
||||
|
||||
public static final OreFeatureConfigEntry STRIATED_ORES_OVERWORLD =
|
||||
create("striated_ores_overworld", 32, 1 / 12f, -30, 70)
|
||||
.layeredDatagenExt()
|
||||
.withLayerPattern(AllLayerPatterns.SCORIA)
|
||||
.withLayerPattern(AllLayerPatterns.CINNABAR)
|
||||
.withLayerPattern(AllLayerPatterns.MAGNETITE)
|
||||
.withLayerPattern(AllLayerPatterns.MALACHITE)
|
||||
.withLayerPattern(AllLayerPatterns.LIMESTONE)
|
||||
.withLayerPattern(AllLayerPatterns.OCHRESTONE)
|
||||
.biomeTag(BiomeTags.IS_OVERWORLD)
|
||||
.parent();
|
||||
|
||||
public static final OreFeatureConfigEntry STRIATED_ORES_NETHER =
|
||||
create("striated_ores_nether", 32, 1 / 12f, 40, 90)
|
||||
.layeredDatagenExt()
|
||||
.withLayerPattern(AllLayerPatterns.SCORIA_NETHER)
|
||||
.withLayerPattern(AllLayerPatterns.SCORCHIA_NETHER)
|
||||
.biomeTag(BiomeTags.IS_NETHER)
|
||||
.parent();
|
||||
|
||||
//
|
||||
|
||||
private static OreFeatureConfigEntry create(String name, int clusterSize, float frequency,
|
||||
int minHeight, int maxHeight) {
|
||||
ResourceLocation id = Create.asResource(name);
|
||||
OreFeatureConfigEntry configDrivenFeatureEntry = new OreFeatureConfigEntry(id, clusterSize, frequency, minHeight, maxHeight);
|
||||
return configDrivenFeatureEntry;
|
||||
}
|
||||
|
||||
public static void fillConfig(ForgeConfigSpec.Builder builder, String namespace) {
|
||||
OreFeatureConfigEntry.ALL
|
||||
.forEach((id, entry) -> {
|
||||
if (id.getNamespace().equals(namespace)) {
|
||||
builder.push(entry.getName());
|
||||
entry.addToConfig(builder);
|
||||
builder.pop();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void init() {}
|
||||
|
||||
public static void gatherData(GatherDataEvent event) {
|
||||
DataGenerator generator = event.getGenerator();
|
||||
RegistryAccess registryAccess = RegistryAccess.BUILTIN.get();
|
||||
|
||||
//
|
||||
|
||||
Map<ResourceLocation, ConfiguredFeature<?, ?>> configuredFeatures = new HashMap<>();
|
||||
for (Map.Entry<ResourceLocation, OreFeatureConfigEntry> entry : OreFeatureConfigEntry.ALL.entrySet()) {
|
||||
DatagenExtension datagenExt = entry.getValue().datagenExt();
|
||||
if (datagenExt != null) {
|
||||
configuredFeatures.put(entry.getKey(), datagenExt.createConfiguredFeature(registryAccess));
|
||||
}
|
||||
}
|
||||
|
||||
DynamicDataProvider<ConfiguredFeature<?, ?>> configuredFeatureProvider = DynamicDataProvider.create(generator, "Create's Configured Features", registryAccess, Registries.CONFIGURED_FEATURE, configuredFeatures);
|
||||
if (configuredFeatureProvider != null) {
|
||||
generator.addProvider(true, configuredFeatureProvider);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Map<ResourceLocation, PlacedFeature> placedFeatures = new HashMap<>();
|
||||
for (Map.Entry<ResourceLocation, OreFeatureConfigEntry> entry : OreFeatureConfigEntry.ALL.entrySet()) {
|
||||
DatagenExtension datagenExt = entry.getValue().datagenExt();
|
||||
if (datagenExt != null) {
|
||||
placedFeatures.put(entry.getKey(), datagenExt.createPlacedFeature(registryAccess));
|
||||
}
|
||||
}
|
||||
|
||||
DynamicDataProvider<PlacedFeature> placedFeatureProvider = DynamicDataProvider.create(generator, "Create's Placed Features", registryAccess, Registries.PLACED_FEATURE, placedFeatures);
|
||||
if (placedFeatureProvider != null) {
|
||||
generator.addProvider(true, placedFeatureProvider);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Map<ResourceLocation, BiomeModifier> biomeModifiers = new HashMap<>();
|
||||
for (Map.Entry<ResourceLocation, OreFeatureConfigEntry> entry : OreFeatureConfigEntry.ALL.entrySet()) {
|
||||
DatagenExtension datagenExt = entry.getValue().datagenExt();
|
||||
if (datagenExt != null) {
|
||||
biomeModifiers.put(entry.getKey(), datagenExt.createBiomeModifier(registryAccess));
|
||||
}
|
||||
}
|
||||
|
||||
DynamicDataProvider<BiomeModifier> biomeModifierProvider = DynamicDataProvider.create(generator, "Create's Biome Modifiers", registryAccess, ForgeRegistries.Keys.BIOME_MODIFIERS, biomeModifiers);
|
||||
if (biomeModifierProvider != null) {
|
||||
generator.addProvider(true, biomeModifierProvider);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import static net.minecraft.data.worldgen.placement.PlacementUtils.register;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.worldgen.BootstapContext;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.levelgen.VerticalAnchor;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.CountPlacement;
|
||||
import net.minecraft.world.level.levelgen.placement.HeightRangePlacement;
|
||||
import net.minecraft.world.level.levelgen.placement.InSquarePlacement;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||
import net.minecraft.world.level.levelgen.placement.RarityFilter;
|
||||
|
||||
public class AllPlacedFeatures {
|
||||
public static final ResourceKey<PlacedFeature>
|
||||
ZINC_ORE = key("zinc_ore"),
|
||||
STRIATED_ORES_OVERWORLD = key("striated_ores_overworld"),
|
||||
STRIATED_ORES_NETHER = key("striated_ores_nether");
|
||||
|
||||
private static ResourceKey<PlacedFeature> key(String name) {
|
||||
return ResourceKey.create(Registries.PLACED_FEATURE, Create.asResource(name));
|
||||
}
|
||||
|
||||
public static void bootstrap(BootstapContext<PlacedFeature> ctx) {
|
||||
HolderGetter<ConfiguredFeature<?, ?>> featureLookup = ctx.lookup(Registries.CONFIGURED_FEATURE);
|
||||
Holder<ConfiguredFeature<?, ?>> zincOre = featureLookup.getOrThrow(AllConfiguredFeatures.ZINC_ORE);
|
||||
Holder<ConfiguredFeature<?, ?>> striatedOresOverworld = featureLookup.getOrThrow(AllConfiguredFeatures.STRIATED_ORES_OVERWORLD);
|
||||
Holder<ConfiguredFeature<?, ?>> striatedOresNether = featureLookup.getOrThrow(AllConfiguredFeatures.STRIATED_ORES_NETHER);
|
||||
|
||||
register(ctx, ZINC_ORE, zincOre, placement(CountPlacement.of(8), -63, 70));
|
||||
register(ctx, STRIATED_ORES_OVERWORLD, striatedOresOverworld, placement(RarityFilter.onAverageOnceEvery(12), -30, 70));
|
||||
register(ctx, STRIATED_ORES_NETHER, striatedOresNether, placement(RarityFilter.onAverageOnceEvery(12), 40, 90));
|
||||
}
|
||||
|
||||
private static List<PlacementModifier> placement(PlacementModifier frequency, int minHeight, int maxHeight) {
|
||||
return List.of(
|
||||
frequency,
|
||||
InSquarePlacement.spread(),
|
||||
HeightRangePlacement.uniform(VerticalAnchor.absolute(minHeight), VerticalAnchor.absolute(maxHeight)),
|
||||
ConfigPlacementFilter.INSTANCE
|
||||
);
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ import net.minecraftforge.registries.RegistryObject;
|
|||
public class AllPlacementModifiers {
|
||||
private static final DeferredRegister<PlacementModifierType<?>> REGISTER = DeferredRegister.create(Registries.PLACEMENT_MODIFIER_TYPE, Create.ID);
|
||||
|
||||
public static final RegistryObject<PlacementModifierType<ConfigDrivenPlacement>> CONFIG_DRIVEN = REGISTER.register("config_driven", () -> () -> ConfigDrivenPlacement.CODEC);
|
||||
public static final RegistryObject<PlacementModifierType<ConfigPlacementFilter>> CONFIG_FILTER = REGISTER.register("config_filter", () -> () -> ConfigPlacementFilter.CODEC);
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
REGISTER.register(modEventBus);
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
|
||||
|
||||
public abstract class BaseConfigDrivenOreFeature<FC extends BaseConfigDrivenOreFeatureConfiguration> extends Feature<FC> {
|
||||
public BaseConfigDrivenOreFeature(Codec<FC> configCodec) {
|
||||
super(configCodec);
|
||||
}
|
||||
|
||||
public boolean canPlaceOre(BlockState pState, Function<BlockPos, BlockState> pAdjacentStateAccessor,
|
||||
RandomSource pRandom, BaseConfigDrivenOreFeatureConfiguration pConfig, OreConfiguration.TargetBlockState pTargetState,
|
||||
BlockPos.MutableBlockPos pMatablePos) {
|
||||
if (!pTargetState.target.test(pState, pRandom))
|
||||
return false;
|
||||
if (shouldSkipAirCheck(pRandom, pConfig.getDiscardChanceOnAirExposure()))
|
||||
return true;
|
||||
|
||||
return !isAdjacentToAir(pAdjacentStateAccessor, pMatablePos);
|
||||
}
|
||||
|
||||
protected boolean shouldSkipAirCheck(RandomSource pRandom, float pChance) {
|
||||
return pChance <= 0 ? true : pChance >= 1 ? false : pRandom.nextFloat() >= pChance;
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
|
||||
public class BaseConfigDrivenOreFeatureConfiguration implements FeatureConfiguration {
|
||||
protected final OreFeatureConfigEntry entry;
|
||||
protected final float discardChanceOnAirExposure;
|
||||
|
||||
public BaseConfigDrivenOreFeatureConfiguration(OreFeatureConfigEntry entry, float discardChance) {
|
||||
this.entry = entry;
|
||||
this.discardChanceOnAirExposure = discardChance;
|
||||
}
|
||||
|
||||
public OreFeatureConfigEntry getEntry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
public int getClusterSize() {
|
||||
return entry.clusterSize.get();
|
||||
}
|
||||
|
||||
public float getDiscardChanceOnAirExposure() {
|
||||
return discardChanceOnAirExposure;
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.worldgen.OreFeatureConfigEntry.DatagenExtension;
|
||||
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraftforge.common.world.BiomeModifier;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class BuiltinRegistration {
|
||||
private static final DeferredRegister<ConfiguredFeature<?, ?>> CONFIGURED_FEATURE_REGISTER = DeferredRegister.create(Registries.CONFIGURED_FEATURE, Create.ID);
|
||||
private static final DeferredRegister<PlacedFeature> PLACED_FEATURE_REGISTER = DeferredRegister.create(Registries.PLACED_FEATURE, Create.ID);
|
||||
private static final DeferredRegister<BiomeModifier> BIOME_MODIFIER_REGISTER = DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIERS, Create.ID);
|
||||
|
||||
static {
|
||||
for (Map.Entry<ResourceLocation, OreFeatureConfigEntry> entry : OreFeatureConfigEntry.ALL.entrySet()) {
|
||||
ResourceLocation id = entry.getKey();
|
||||
if (id.getNamespace().equals(Create.ID)) {
|
||||
DatagenExtension datagenExt = entry.getValue().datagenExt();
|
||||
if (datagenExt != null) {
|
||||
CONFIGURED_FEATURE_REGISTER.register(id.getPath(), () -> datagenExt.createConfiguredFeature(BuiltinRegistries.ACCESS));
|
||||
PLACED_FEATURE_REGISTER.register(id.getPath(), () -> datagenExt.createPlacedFeature(BuiltinRegistries.ACCESS));
|
||||
BIOME_MODIFIER_REGISTER.register(id.getPath(), () -> datagenExt.createBiomeModifier(BuiltinRegistries.ACCESS));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
CONFIGURED_FEATURE_REGISTER.register(modEventBus);
|
||||
PLACED_FEATURE_REGISTER.register(modEventBus);
|
||||
BIOME_MODIFIER_REGISTER.register(modEventBus);
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
public class ConfigDrivenLayeredOreFeatureConfiguration extends BaseConfigDrivenOreFeatureConfiguration {
|
||||
public static final Codec<ConfigDrivenLayeredOreFeatureConfiguration> CODEC = RecordCodecBuilder.create(instance -> {
|
||||
return instance.group(
|
||||
OreFeatureConfigEntry.CODEC
|
||||
.fieldOf("entry")
|
||||
.forGetter(config -> config.entry),
|
||||
Codec.floatRange(0.0F, 1.0F)
|
||||
.fieldOf("discard_chance_on_air_exposure")
|
||||
.forGetter(config -> config.discardChanceOnAirExposure),
|
||||
Codec.list(LayerPattern.CODEC)
|
||||
.fieldOf("layer_patterns")
|
||||
.forGetter(config -> config.layerPatterns)
|
||||
).apply(instance, ConfigDrivenLayeredOreFeatureConfiguration::new);
|
||||
});
|
||||
|
||||
private final List<LayerPattern> layerPatterns;
|
||||
|
||||
public ConfigDrivenLayeredOreFeatureConfiguration(OreFeatureConfigEntry entry, float discardChance, List<LayerPattern> layerPatterns) {
|
||||
super(entry, discardChance);
|
||||
this.layerPatterns = layerPatterns;
|
||||
}
|
||||
|
||||
public List<LayerPattern> getLayerPatterns() {
|
||||
return layerPatterns;
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration.TargetBlockState;
|
||||
|
||||
public class ConfigDrivenOreFeatureConfiguration extends BaseConfigDrivenOreFeatureConfiguration {
|
||||
public static final Codec<ConfigDrivenOreFeatureConfiguration> CODEC = RecordCodecBuilder.create(instance -> {
|
||||
return instance.group(
|
||||
OreFeatureConfigEntry.CODEC
|
||||
.fieldOf("entry")
|
||||
.forGetter(config -> config.entry),
|
||||
Codec.floatRange(0.0F, 1.0F)
|
||||
.fieldOf("discard_chance_on_air_exposure")
|
||||
.forGetter(config -> config.discardChanceOnAirExposure),
|
||||
Codec.list(TargetBlockState.CODEC)
|
||||
.fieldOf("targets")
|
||||
.forGetter(config -> config.targetStates)
|
||||
).apply(instance, ConfigDrivenOreFeatureConfiguration::new);
|
||||
});
|
||||
|
||||
private final List<TargetBlockState> targetStates;
|
||||
|
||||
public ConfigDrivenOreFeatureConfiguration(OreFeatureConfigEntry entry, float discardChance, List<TargetBlockState> targetStates) {
|
||||
super(entry, discardChance);
|
||||
this.targetStates = targetStates;
|
||||
}
|
||||
|
||||
public List<TargetBlockState> getTargetStates() {
|
||||
return targetStates;
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||
|
||||
public class ConfigDrivenPlacement extends PlacementModifier {
|
||||
public static final Codec<ConfigDrivenPlacement> CODEC = RecordCodecBuilder.create(instance -> {
|
||||
return instance.group(
|
||||
OreFeatureConfigEntry.CODEC
|
||||
.fieldOf("entry")
|
||||
.forGetter(ConfigDrivenPlacement::getEntry)
|
||||
).apply(instance, ConfigDrivenPlacement::new);
|
||||
});
|
||||
|
||||
private final OreFeatureConfigEntry entry;
|
||||
|
||||
public ConfigDrivenPlacement(OreFeatureConfigEntry entry) {
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<BlockPos> getPositions(PlacementContext context, RandomSource random, BlockPos pos) {
|
||||
int count = getCount(getFrequency(), random);
|
||||
if (count == 0) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
int minY = getMinY();
|
||||
int maxY = getMaxY();
|
||||
|
||||
return IntStream.range(0, count)
|
||||
.mapToObj(i -> pos)
|
||||
.map(p -> {
|
||||
int x = random.nextInt(16) + p.getX();
|
||||
int z = random.nextInt(16) + p.getZ();
|
||||
int y = Mth.randomBetweenInclusive(random, minY, maxY);
|
||||
return new BlockPos(x, y, z);
|
||||
});
|
||||
}
|
||||
|
||||
public int getCount(float frequency, RandomSource random) {
|
||||
int floored = Mth.floor(frequency);
|
||||
return floored + (random.nextFloat() < (frequency - floored) ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlacementModifierType<?> type() {
|
||||
return AllPlacementModifiers.CONFIG_DRIVEN.get();
|
||||
}
|
||||
|
||||
public OreFeatureConfigEntry getEntry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
public float getFrequency() {
|
||||
if (AllConfigs.COMMON.worldGen.disable.get())
|
||||
return 0;
|
||||
return entry.frequency.getF();
|
||||
}
|
||||
|
||||
public int getMinY() {
|
||||
return entry.minHeight.get();
|
||||
}
|
||||
|
||||
public int getMaxY() {
|
||||
return entry.maxHeight.get();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementContext;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementFilter;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
|
||||
|
||||
public class ConfigPlacementFilter extends PlacementFilter {
|
||||
public static final ConfigPlacementFilter INSTANCE = new ConfigPlacementFilter();
|
||||
public static final Codec<ConfigPlacementFilter> CODEC = Codec.unit(() -> INSTANCE);
|
||||
|
||||
@Override
|
||||
protected boolean shouldPlace(PlacementContext context, RandomSource random, BlockPos pos) {
|
||||
return !AllConfigs.COMMON.worldGen.disable.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlacementModifierType<?> type() {
|
||||
return AllPlacementModifiers.CONFIG_FILTER.get();
|
||||
}
|
||||
}
|
|
@ -11,13 +11,15 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.tterrag.registrate.util.nullness.NonNullSupplier;
|
||||
|
||||
import net.minecraft.data.worldgen.features.OreFeatures;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration.TargetBlockState;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.RuleTest;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.TagMatchTest;
|
||||
import net.minecraftforge.common.util.NonNullConsumer;
|
||||
|
||||
public class LayerPattern {
|
||||
|
@ -110,6 +112,10 @@ public class LayerPattern {
|
|||
}
|
||||
|
||||
public static class Builder {
|
||||
private static final RuleTest STONE_ORE_REPLACEABLES = new TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES);
|
||||
private static final RuleTest DEEPSLATE_ORE_REPLACEABLES = new TagMatchTest(BlockTags.DEEPSLATE_ORE_REPLACEABLES);
|
||||
private static final RuleTest NETHER_ORE_REPLACEABLES = new TagMatchTest(BlockTags.BASE_STONE_NETHER);
|
||||
|
||||
private final List<List<TargetBlockState>> targets = new ArrayList<>();
|
||||
private int minSize = 1;
|
||||
private int maxSize = 1;
|
||||
|
@ -127,7 +133,7 @@ public class LayerPattern {
|
|||
public Builder block(Block block) {
|
||||
if (netherMode) {
|
||||
this.targets.add(ImmutableList.of(OreConfiguration
|
||||
.target(OreFeatures.NETHER_ORE_REPLACEABLES, block.defaultBlockState())));
|
||||
.target(NETHER_ORE_REPLACEABLES, block.defaultBlockState())));
|
||||
return this;
|
||||
}
|
||||
return blocks(block.defaultBlockState(), block.defaultBlockState());
|
||||
|
@ -148,8 +154,8 @@ public class LayerPattern {
|
|||
|
||||
private Builder blocks(BlockState stone, BlockState deepslate) {
|
||||
this.targets.add(
|
||||
ImmutableList.of(OreConfiguration.target(OreFeatures.STONE_ORE_REPLACEABLES, stone),
|
||||
OreConfiguration.target(OreFeatures.DEEPSLATE_ORE_REPLACEABLES, deepslate)));
|
||||
ImmutableList.of(OreConfiguration.target(STONE_ORE_REPLACEABLES, stone),
|
||||
OreConfiguration.target(DEEPSLATE_ORE_REPLACEABLES, deepslate)));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
|
||||
|
||||
public class LayeredOreConfiguration implements FeatureConfiguration {
|
||||
public static final Codec<LayeredOreConfiguration> CODEC = RecordCodecBuilder.create(instance -> {
|
||||
return instance.group(
|
||||
Codec.list(LayerPattern.CODEC)
|
||||
.fieldOf("layer_patterns")
|
||||
.forGetter(config -> config.layerPatterns),
|
||||
Codec.intRange(0, 64)
|
||||
.fieldOf("size")
|
||||
.forGetter(config -> config.size),
|
||||
Codec.floatRange(0.0F, 1.0F)
|
||||
.fieldOf("discard_chance_on_air_exposure")
|
||||
.forGetter(config -> config.discardChanceOnAirExposure)
|
||||
).apply(instance, LayeredOreConfiguration::new);
|
||||
});
|
||||
|
||||
public final List<LayerPattern> layerPatterns;
|
||||
public final int size;
|
||||
public final float discardChanceOnAirExposure;
|
||||
|
||||
public LayeredOreConfiguration(List<LayerPattern> layerPatterns, int size, float discardChanceOnAirExposure) {
|
||||
this.layerPatterns = layerPatterns;
|
||||
this.size = size;
|
||||
this.discardChanceOnAirExposure = discardChanceOnAirExposure;
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.foundation.worldgen;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.simibubi.create.foundation.worldgen.LayerPattern.Layer;
|
||||
|
||||
|
@ -15,22 +16,23 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
import net.minecraft.world.level.chunk.BulkSectionAccess;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration.TargetBlockState;
|
||||
|
||||
public class LayeredOreFeature extends BaseConfigDrivenOreFeature<ConfigDrivenLayeredOreFeatureConfiguration> {
|
||||
public class LayeredOreFeature extends Feature<LayeredOreConfiguration> {
|
||||
public LayeredOreFeature() {
|
||||
super(ConfigDrivenLayeredOreFeatureConfiguration.CODEC);
|
||||
super(LayeredOreConfiguration.CODEC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean place(FeaturePlaceContext<ConfigDrivenLayeredOreFeatureConfiguration> pContext) {
|
||||
public boolean place(FeaturePlaceContext<LayeredOreConfiguration> pContext) {
|
||||
RandomSource random = pContext.random();
|
||||
BlockPos blockpos = pContext.origin();
|
||||
WorldGenLevel worldgenlevel = pContext.level();
|
||||
ConfigDrivenLayeredOreFeatureConfiguration config = pContext.config();
|
||||
List<LayerPattern> patternPool = config.getLayerPatterns();
|
||||
LayeredOreConfiguration config = pContext.config();
|
||||
List<LayerPattern> patternPool = config.layerPatterns;
|
||||
|
||||
if (patternPool.isEmpty())
|
||||
return false;
|
||||
|
@ -38,8 +40,8 @@ public class LayeredOreFeature extends BaseConfigDrivenOreFeature<ConfigDrivenLa
|
|||
LayerPattern layerPattern = patternPool.get(random.nextInt(patternPool.size()));
|
||||
|
||||
int placedAmount = 0;
|
||||
int size = config.getClusterSize();
|
||||
int radius = Mth.ceil(config.getClusterSize() / 2f);
|
||||
int size = config.size;
|
||||
int radius = Mth.ceil(config.size / 2f);
|
||||
int x0 = blockpos.getX() - radius;
|
||||
int y0 = blockpos.getY() - radius;
|
||||
int z0 = blockpos.getZ() - radius;
|
||||
|
@ -142,4 +144,19 @@ public class LayeredOreFeature extends BaseConfigDrivenOreFeature<ConfigDrivenLa
|
|||
bulksectionaccess.close();
|
||||
return placedAmount > 0;
|
||||
}
|
||||
|
||||
public boolean canPlaceOre(BlockState pState, Function<BlockPos, BlockState> pAdjacentStateAccessor,
|
||||
RandomSource pRandom, LayeredOreConfiguration pConfig, OreConfiguration.TargetBlockState pTargetState,
|
||||
BlockPos.MutableBlockPos pMatablePos) {
|
||||
if (!pTargetState.target.test(pState, pRandom))
|
||||
return false;
|
||||
if (shouldSkipAirCheck(pRandom, pConfig.discardChanceOnAirExposure))
|
||||
return true;
|
||||
|
||||
return !isAdjacentToAir(pAdjacentStateAccessor, pMatablePos);
|
||||
}
|
||||
|
||||
protected boolean shouldSkipAirCheck(RandomSource pRandom, float pChance) {
|
||||
return pChance <= 0 ? true : pChance >= 1 ? false : pRandom.nextFloat() >= pChance;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,209 +0,0 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.simibubi.create.foundation.config.ConfigBase;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.tterrag.registrate.util.nullness.NonNullSupplier;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.worldgen.features.OreFeatures;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration.TargetBlockState;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.common.world.BiomeModifier;
|
||||
import net.minecraftforge.common.world.ForgeBiomeModifiers.AddFeaturesBiomeModifier;
|
||||
|
||||
public class OreFeatureConfigEntry extends ConfigBase {
|
||||
public static final Map<ResourceLocation, OreFeatureConfigEntry> ALL = new HashMap<>();
|
||||
|
||||
public static final Codec<OreFeatureConfigEntry> CODEC = ResourceLocation.CODEC
|
||||
.comapFlatMap(OreFeatureConfigEntry::read, entry -> entry.id);
|
||||
|
||||
public final ResourceLocation id;
|
||||
public final ConfigInt clusterSize;
|
||||
public final ConfigFloat frequency;
|
||||
public final ConfigInt minHeight;
|
||||
public final ConfigInt maxHeight;
|
||||
|
||||
private DatagenExtension datagenExt;
|
||||
|
||||
public OreFeatureConfigEntry(ResourceLocation id, int clusterSize, float frequency, int minHeight, int maxHeight) {
|
||||
this.id = id;
|
||||
|
||||
this.clusterSize = i(clusterSize, 0, "clusterSize");
|
||||
this.frequency = f(frequency, 0, 512, "frequency", "Amount of clusters generated per Chunk.",
|
||||
" >1 to spawn multiple.", " <1 to make it a chance.", " 0 to disable.");
|
||||
this.minHeight = i(minHeight, "minHeight");
|
||||
this.maxHeight = i(maxHeight, "maxHeight");
|
||||
|
||||
ALL.put(id, this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public StandardDatagenExtension standardDatagenExt() {
|
||||
if (datagenExt == null) {
|
||||
datagenExt = new StandardDatagenExtension();
|
||||
}
|
||||
if (datagenExt instanceof StandardDatagenExtension standard) {
|
||||
return standard;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public LayeredDatagenExtension layeredDatagenExt() {
|
||||
if (datagenExt == null) {
|
||||
datagenExt = new LayeredDatagenExtension();
|
||||
}
|
||||
if (datagenExt instanceof LayeredDatagenExtension layered) {
|
||||
return layered;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DatagenExtension datagenExt() {
|
||||
if (datagenExt != null) {
|
||||
return datagenExt;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addToConfig(ForgeConfigSpec.Builder builder) {
|
||||
registerAll(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return id.getPath();
|
||||
}
|
||||
|
||||
public static DataResult<OreFeatureConfigEntry> read(ResourceLocation id) {
|
||||
OreFeatureConfigEntry entry = ALL.get(id);
|
||||
if (entry != null) {
|
||||
return DataResult.success(entry);
|
||||
} else {
|
||||
return DataResult.error("Not a valid OreFeatureConfigEntry: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class DatagenExtension {
|
||||
public TagKey<Biome> biomeTag;
|
||||
|
||||
public DatagenExtension biomeTag(TagKey<Biome> biomes) {
|
||||
this.biomeTag = biomes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public abstract ConfiguredFeature<?, ?> createConfiguredFeature(RegistryAccess registryAccess);
|
||||
|
||||
public PlacedFeature createPlacedFeature(RegistryAccess registryAccess) {
|
||||
Registry<ConfiguredFeature<?, ?>> featureRegistry = registryAccess.registryOrThrow(Registries.CONFIGURED_FEATURE);
|
||||
Holder<ConfiguredFeature<?, ?>> featureHolder = featureRegistry.getHolderOrThrow(ResourceKey.create(Registries.CONFIGURED_FEATURE, id));
|
||||
return new PlacedFeature(featureHolder, List.of(new ConfigDrivenPlacement(OreFeatureConfigEntry.this)));
|
||||
}
|
||||
|
||||
public BiomeModifier createBiomeModifier(RegistryAccess registryAccess) {
|
||||
Registry<Biome> biomeRegistry = registryAccess.registryOrThrow(Registries.BIOME);
|
||||
Registry<PlacedFeature> featureRegistry = registryAccess.registryOrThrow(Registries.PLACED_FEATURE);
|
||||
HolderSet<Biome> biomes = biomeRegistry.getOrCreateTag(biomeTag);
|
||||
Holder<PlacedFeature> featureHolder = featureRegistry.getHolderOrThrow(ResourceKey.create(Registries.PLACED_FEATURE, id));
|
||||
return new AddFeaturesBiomeModifier(biomes, HolderSet.direct(featureHolder), Decoration.UNDERGROUND_ORES);
|
||||
}
|
||||
|
||||
public OreFeatureConfigEntry parent() {
|
||||
return OreFeatureConfigEntry.this;
|
||||
}
|
||||
}
|
||||
|
||||
public class StandardDatagenExtension extends DatagenExtension {
|
||||
public NonNullSupplier<? extends Block> block;
|
||||
public NonNullSupplier<? extends Block> deepBlock;
|
||||
public NonNullSupplier<? extends Block> netherBlock;
|
||||
|
||||
public StandardDatagenExtension withBlock(NonNullSupplier<? extends Block> block) {
|
||||
this.block = block;
|
||||
this.deepBlock = block;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StandardDatagenExtension withBlocks(Couple<NonNullSupplier<? extends Block>> blocks) {
|
||||
this.block = blocks.getFirst();
|
||||
this.deepBlock = blocks.getSecond();
|
||||
return this;
|
||||
}
|
||||
|
||||
public StandardDatagenExtension withNetherBlock(NonNullSupplier<? extends Block> block) {
|
||||
this.netherBlock = block;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StandardDatagenExtension biomeTag(TagKey<Biome> biomes) {
|
||||
super.biomeTag(biomes);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredFeature<?, ?> createConfiguredFeature(RegistryAccess registryAccess) {
|
||||
List<TargetBlockState> targetStates = new ArrayList<>();
|
||||
if (block != null)
|
||||
targetStates.add(OreConfiguration.target(OreFeatures.STONE_ORE_REPLACEABLES, block.get()
|
||||
.defaultBlockState()));
|
||||
if (deepBlock != null)
|
||||
targetStates.add(OreConfiguration.target(OreFeatures.DEEPSLATE_ORE_REPLACEABLES, deepBlock.get()
|
||||
.defaultBlockState()));
|
||||
if (netherBlock != null)
|
||||
targetStates.add(OreConfiguration.target(OreFeatures.NETHER_ORE_REPLACEABLES, netherBlock.get()
|
||||
.defaultBlockState()));
|
||||
|
||||
ConfigDrivenOreFeatureConfiguration config = new ConfigDrivenOreFeatureConfiguration(OreFeatureConfigEntry.this, 0, targetStates);
|
||||
return new ConfiguredFeature<>(AllFeatures.STANDARD_ORE.get(), config);
|
||||
}
|
||||
}
|
||||
|
||||
public class LayeredDatagenExtension extends DatagenExtension {
|
||||
public final List<NonNullSupplier<LayerPattern>> layerPatterns = new ArrayList<>();
|
||||
|
||||
public LayeredDatagenExtension withLayerPattern(NonNullSupplier<LayerPattern> pattern) {
|
||||
this.layerPatterns.add(pattern);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayeredDatagenExtension biomeTag(TagKey<Biome> biomes) {
|
||||
super.biomeTag(biomes);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredFeature<?, ?> createConfiguredFeature(RegistryAccess registryAccess) {
|
||||
List<LayerPattern> layerPatterns = this.layerPatterns.stream()
|
||||
.map(NonNullSupplier::get)
|
||||
.toList();
|
||||
|
||||
ConfigDrivenLayeredOreFeatureConfiguration config = new ConfigDrivenLayeredOreFeatureConfiguration(OreFeatureConfigEntry.this, 0, layerPatterns);
|
||||
return new ConfiguredFeature<>(AllFeatures.LAYERED_ORE.get(), config);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.BulkSectionAccess;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
|
||||
|
||||
public class StandardOreFeature extends BaseConfigDrivenOreFeature<ConfigDrivenOreFeatureConfiguration> {
|
||||
|
||||
public StandardOreFeature() {
|
||||
super(ConfigDrivenOreFeatureConfiguration.CODEC);
|
||||
}
|
||||
|
||||
// From OreFeature, slight adjustments
|
||||
|
||||
@Override
|
||||
public boolean place(FeaturePlaceContext<ConfigDrivenOreFeatureConfiguration> pContext) {
|
||||
RandomSource random = pContext.random();
|
||||
BlockPos blockpos = pContext.origin();
|
||||
WorldGenLevel worldgenlevel = pContext.level();
|
||||
ConfigDrivenOreFeatureConfiguration oreconfiguration = pContext.config();
|
||||
float f = random.nextFloat() * (float)Math.PI;
|
||||
float f1 = (float)oreconfiguration.getClusterSize() / 8.0F;
|
||||
int i = Mth.ceil(((float)oreconfiguration.getClusterSize() / 16.0F * 2.0F + 1.0F) / 2.0F);
|
||||
double d0 = (double)blockpos.getX() + Math.sin((double)f) * (double)f1;
|
||||
double d1 = (double)blockpos.getX() - Math.sin((double)f) * (double)f1;
|
||||
double d2 = (double)blockpos.getZ() + Math.cos((double)f) * (double)f1;
|
||||
double d3 = (double)blockpos.getZ() - Math.cos((double)f) * (double)f1;
|
||||
double d4 = (double)(blockpos.getY() + random.nextInt(3) - 2);
|
||||
double d5 = (double)(blockpos.getY() + random.nextInt(3) - 2);
|
||||
int k = blockpos.getX() - Mth.ceil(f1) - i;
|
||||
int l = blockpos.getY() - 2 - i;
|
||||
int i1 = blockpos.getZ() - Mth.ceil(f1) - i;
|
||||
int j1 = 2 * (Mth.ceil(f1) + i);
|
||||
int k1 = 2 * (2 + i);
|
||||
|
||||
for(int l1 = k; l1 <= k + j1; ++l1) {
|
||||
for(int i2 = i1; i2 <= i1 + j1; ++i2) {
|
||||
if (l <= worldgenlevel.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, l1, i2)) {
|
||||
return this.doPlace(worldgenlevel, random, oreconfiguration, d0, d1, d2, d3, d4, d5, k, l, i1, j1, k1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean doPlace(WorldGenLevel pLevel, RandomSource pRandom, ConfigDrivenOreFeatureConfiguration pConfig, double pMinX,
|
||||
double pMaxX, double pMinZ, double pMaxZ, double pMinY, double pMaxY, int pX, int pY, int pZ, int pWidth,
|
||||
int pHeight) {
|
||||
int i = 0;
|
||||
BitSet bitset = new BitSet(pWidth * pHeight * pWidth);
|
||||
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
|
||||
int j = pConfig.getClusterSize();
|
||||
double[] adouble = new double[j * 4];
|
||||
|
||||
for(int k = 0; k < j; ++k) {
|
||||
float f = (float)k / (float)j;
|
||||
double d0 = Mth.lerp((double)f, pMinX, pMaxX);
|
||||
double d1 = Mth.lerp((double)f, pMinY, pMaxY);
|
||||
double d2 = Mth.lerp((double)f, pMinZ, pMaxZ);
|
||||
double d3 = pRandom.nextDouble() * (double)j / 16.0D;
|
||||
double d4 = ((double)(Mth.sin((float)Math.PI * f) + 1.0F) * d3 + 1.0D) / 2.0D;
|
||||
adouble[k * 4 + 0] = d0;
|
||||
adouble[k * 4 + 1] = d1;
|
||||
adouble[k * 4 + 2] = d2;
|
||||
adouble[k * 4 + 3] = d4;
|
||||
}
|
||||
|
||||
for(int l3 = 0; l3 < j - 1; ++l3) {
|
||||
if (!(adouble[l3 * 4 + 3] <= 0.0D)) {
|
||||
for(int i4 = l3 + 1; i4 < j; ++i4) {
|
||||
if (!(adouble[i4 * 4 + 3] <= 0.0D)) {
|
||||
double d8 = adouble[l3 * 4 + 0] - adouble[i4 * 4 + 0];
|
||||
double d10 = adouble[l3 * 4 + 1] - adouble[i4 * 4 + 1];
|
||||
double d12 = adouble[l3 * 4 + 2] - adouble[i4 * 4 + 2];
|
||||
double d14 = adouble[l3 * 4 + 3] - adouble[i4 * 4 + 3];
|
||||
if (d14 * d14 > d8 * d8 + d10 * d10 + d12 * d12) {
|
||||
if (d14 > 0.0D) {
|
||||
adouble[i4 * 4 + 3] = -1.0D;
|
||||
} else {
|
||||
adouble[l3 * 4 + 3] = -1.0D;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BulkSectionAccess bulksectionaccess = new BulkSectionAccess(pLevel);
|
||||
|
||||
try {
|
||||
for(int j4 = 0; j4 < j; ++j4) {
|
||||
double d9 = adouble[j4 * 4 + 3];
|
||||
if (!(d9 < 0.0D)) {
|
||||
double d11 = adouble[j4 * 4 + 0];
|
||||
double d13 = adouble[j4 * 4 + 1];
|
||||
double d15 = adouble[j4 * 4 + 2];
|
||||
int k4 = Math.max(Mth.floor(d11 - d9), pX);
|
||||
int l = Math.max(Mth.floor(d13 - d9), pY);
|
||||
int i1 = Math.max(Mth.floor(d15 - d9), pZ);
|
||||
int j1 = Math.max(Mth.floor(d11 + d9), k4);
|
||||
int k1 = Math.max(Mth.floor(d13 + d9), l);
|
||||
int l1 = Math.max(Mth.floor(d15 + d9), i1);
|
||||
|
||||
for(int i2 = k4; i2 <= j1; ++i2) {
|
||||
double d5 = ((double)i2 + 0.5D - d11) / d9;
|
||||
if (d5 * d5 < 1.0D) {
|
||||
for(int j2 = l; j2 <= k1; ++j2) {
|
||||
double d6 = ((double)j2 + 0.5D - d13) / d9;
|
||||
if (d5 * d5 + d6 * d6 < 1.0D) {
|
||||
for(int k2 = i1; k2 <= l1; ++k2) {
|
||||
double d7 = ((double)k2 + 0.5D - d15) / d9;
|
||||
if (d5 * d5 + d6 * d6 + d7 * d7 < 1.0D && !pLevel.isOutsideBuildHeight(j2)) {
|
||||
int l2 = i2 - pX + (j2 - pY) * pWidth + (k2 - pZ) * pWidth * pHeight;
|
||||
if (!bitset.get(l2)) {
|
||||
bitset.set(l2);
|
||||
blockpos$mutableblockpos.set(i2, j2, k2);
|
||||
if (pLevel.ensureCanWrite(blockpos$mutableblockpos)) {
|
||||
LevelChunkSection levelchunksection = bulksectionaccess.getSection(blockpos$mutableblockpos);
|
||||
if (levelchunksection != null) {
|
||||
int i3 = SectionPos.sectionRelative(i2);
|
||||
int j3 = SectionPos.sectionRelative(j2);
|
||||
int k3 = SectionPos.sectionRelative(k2);
|
||||
BlockState blockstate = levelchunksection.getBlockState(i3, j3, k3);
|
||||
|
||||
for(OreConfiguration.TargetBlockState oreconfiguration$targetblockstate : pConfig.getTargetStates()) {
|
||||
if (canPlaceOre(blockstate, bulksectionaccess::getBlockState, pRandom, pConfig, oreconfiguration$targetblockstate, blockpos$mutableblockpos)) {
|
||||
levelchunksection.setBlockState(i3, j3, k3, oreconfiguration$targetblockstate.state, false);
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable throwable1) {
|
||||
try {
|
||||
bulksectionaccess.close();
|
||||
} catch (Throwable throwable) {
|
||||
throwable1.addSuppressed(throwable);
|
||||
}
|
||||
|
||||
throw throwable1;
|
||||
}
|
||||
|
||||
bulksectionaccess.close();
|
||||
return i > 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.simibubi.create.foundation.worldgen;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.RegistrySetBuilder;
|
||||
import net.minecraft.core.RegistrySetBuilder.RegistryBootstrap;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraftforge.common.data.DatapackBuiltinEntriesProvider;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class WorldgenDataProvider extends DatapackBuiltinEntriesProvider {
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private static final RegistrySetBuilder BUILDER = new RegistrySetBuilder()
|
||||
.add(Registries.CONFIGURED_FEATURE, (RegistryBootstrap) AllConfiguredFeatures::bootstrap)
|
||||
.add(Registries.PLACED_FEATURE, AllPlacedFeatures::bootstrap)
|
||||
.add(ForgeRegistries.Keys.BIOME_MODIFIERS, AllBiomeModifiers::bootstrap);
|
||||
|
||||
public WorldgenDataProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> registries) {
|
||||
super(output, registries, BUILDER, Set.of(Create.ID));
|
||||
}
|
||||
|
||||
public static DataProvider.Factory<WorldgenDataProvider> makeFactory(CompletableFuture<HolderLookup.Provider> registries) {
|
||||
return output -> new WorldgenDataProvider(output, registries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Create's Worldgen Data";
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue