diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 751345e2f..306a249ea 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -5628,11 +5628,10 @@ ac265a674626e0e832330086fd18fe0be37fc327 data/create/recipes/weathered_copper_ti 5942a571f79c40524bbf408775cf91de4715f2b6 data/create/recipes/weathered_copper_tile_stairs_from_weathered_copper_tiles_stonecutting.json 2d549ea56fb226c0e31e66c0391996093f8bece9 data/create/tags/blocks/brittle.json d99d5c67bdffff60789a19bd51a5c5267c75e0a4 data/create/tags/blocks/casing.json -418c6da531d6206e3cbe4049dce3db23c4270bed data/create/tags/blocks/fan_heaters.json 443f75adbf3d2f6fb0aad4b344372669470065b8 data/create/tags/blocks/fan_transparent.json 6e5d3b2123fbb00e7f439c091623619502551bca data/create/tags/blocks/non_movable.json 10781e8cfcbb3486327aace3aa00e437fb44b331 data/create/tags/blocks/ore_override_stone.json -197ed7ee3b284045c005011d28c38ac5b2e44d8c data/create/tags/blocks/passive_boiler_heaters.json +418c6da531d6206e3cbe4049dce3db23c4270bed data/create/tags/blocks/passive_boiler_heaters.json 74f4ba5f6f61c30e27947c6fb4557e888d018285 data/create/tags/blocks/safe_nbt.json 6cdeeac1689f7b5bfd9bc40b462143d8eaf3ad0b data/create/tags/blocks/seats.json d063e12c9ef75f39518c6d129ea35d833464d547 data/create/tags/blocks/toolboxes.json diff --git a/src/generated/resources/data/create/tags/blocks/fan_heaters.json b/src/generated/resources/data/create/tags/blocks/fan_heaters.json deleted file mode 100644 index dc4ef4afb..000000000 --- a/src/generated/resources/data/create/tags/blocks/fan_heaters.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "replace": false, - "values": [ - "create:blaze_burner", - "create:lit_blaze_burner", - "#minecraft:fire", - "#minecraft:campfires", - "minecraft:magma_block", - "minecraft:lava" - ] -} \ No newline at end of file diff --git a/src/generated/resources/data/create/tags/blocks/passive_boiler_heaters.json b/src/generated/resources/data/create/tags/blocks/passive_boiler_heaters.json index 509d23e72..dc4ef4afb 100644 --- a/src/generated/resources/data/create/tags/blocks/passive_boiler_heaters.json +++ b/src/generated/resources/data/create/tags/blocks/passive_boiler_heaters.json @@ -1,6 +1,11 @@ { "replace": false, "values": [ - "#create:fan_heaters" + "create:blaze_burner", + "create:lit_blaze_burner", + "#minecraft:fire", + "#minecraft:campfires", + "minecraft:magma_block", + "minecraft:lava" ] } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index b4b1c0c4b..1ebce4f34 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -652,7 +652,7 @@ public class AllBlocks { .properties(p -> p.lightLevel(BlazeBurnerBlock::getLight)) .transform(pickaxeOnly()) .addLayer(() -> RenderType::cutoutMipped) - .tag(AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.FAN_HEATERS.tag) + .tag(AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.PASSIVE_BOILER_HEATERS.tag) .loot((lt, block) -> lt.add(block, BlazeBurnerBlock.buildLootTable())) .blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p))) .onRegister(movementBehaviour(new BlazeBurnerMovementBehaviour())) @@ -669,7 +669,7 @@ public class AllBlocks { .properties(p -> p.lightLevel(LitBlazeBurnerBlock::getLight)) .transform(pickaxeOnly()) .addLayer(() -> RenderType::cutoutMipped) - .tag(AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.FAN_HEATERS.tag) + .tag(AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.PASSIVE_BOILER_HEATERS.tag) .loot((lt, block) -> lt.dropOther(block, AllItems.EMPTY_BLAZE_BURNER.get())) .blockstate((c, p) -> p.getVariantBuilder(c.get()) .forAllStates(state -> ConfiguredModel.builder() diff --git a/src/main/java/com/simibubi/create/AllEntityDataSerializers.java b/src/main/java/com/simibubi/create/AllEntityDataSerializers.java index 9ef17ce66..b0d6b2343 100644 --- a/src/main/java/com/simibubi/create/AllEntityDataSerializers.java +++ b/src/main/java/com/simibubi/create/AllEntityDataSerializers.java @@ -2,17 +2,20 @@ package com.simibubi.create; import com.simibubi.create.content.logistics.trains.entity.CarriageSyncDataSerializer; -import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.registries.DataSerializerEntry; -import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; public class AllEntityDataSerializers { + private static final DeferredRegister REGISTER = DeferredRegister.create(ForgeRegistries.Keys.DATA_SERIALIZERS, Create.ID); public static final CarriageSyncDataSerializer CARRIAGE_DATA = new CarriageSyncDataSerializer(); - public static void register(RegistryEvent.Register event) { - IForgeRegistry registry = event.getRegistry(); - registry.register(new DataSerializerEntry(CARRIAGE_DATA).setRegistryName(Create.asResource("carriage_data"))); - } + public static final RegistryObject CARRIAGE_DATA_ENTRY = REGISTER.register("carriage_data", () -> new DataSerializerEntry(CARRIAGE_DATA)); + public static void register(IEventBus modEventBus) { + REGISTER.register(modEventBus); + } } diff --git a/src/main/java/com/simibubi/create/AllParticleTypes.java b/src/main/java/com/simibubi/create/AllParticleTypes.java index 722f1b5d2..8903f7894 100644 --- a/src/main/java/com/simibubi/create/AllParticleTypes.java +++ b/src/main/java/com/simibubi/create/AllParticleTypes.java @@ -18,12 +18,13 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.particle.ParticleEngine; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleType; -import net.minecraft.resources.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.ParticleFactoryRegisterEvent; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; public enum AllParticleTypes { @@ -39,19 +40,17 @@ public enum AllParticleTypes { SOUL(SoulParticle.Data::new), SOUL_BASE(SoulBaseParticle.Data::new), SOUL_PERIMETER(SoulParticle.PerimeterData::new), - SOUL_EXPANDING_PERIMETER(SoulParticle.ExpandingPerimeterData::new) - ; + SOUL_EXPANDING_PERIMETER(SoulParticle.ExpandingPerimeterData::new); - private ParticleEntry entry; + private final ParticleEntry entry; AllParticleTypes(Supplier> typeFactory) { - String asId = Lang.asId(this.name()); - entry = new ParticleEntry<>(new ResourceLocation(Create.ID, asId), typeFactory); + String name = Lang.asId(name()); + entry = new ParticleEntry<>(name, typeFactory); } - public static void register(RegistryEvent.Register> event) { - for (AllParticleTypes particle : values()) - particle.entry.register(event.getRegistry()); + public static void register(IEventBus modEventBus) { + ParticleEntry.REGISTER.register(modEventBus); } @OnlyIn(Dist.CLIENT) @@ -62,40 +61,31 @@ public enum AllParticleTypes { } public ParticleType get() { - return entry.getOrCreateType(); + return entry.object.get(); } public String parameter() { - return Lang.asId(name()); + return entry.name; } - private class ParticleEntry { - Supplier> typeFactory; - ParticleType type; - ResourceLocation id; + private static class ParticleEntry { + private static final DeferredRegister> REGISTER = DeferredRegister.create(ForgeRegistries.PARTICLE_TYPES, Create.ID); - public ParticleEntry(ResourceLocation id, Supplier> typeFactory) { - this.id = id; + private final String name; + private final Supplier> typeFactory; + private final RegistryObject> object; + + public ParticleEntry(String name, Supplier> typeFactory) { + this.name = name; this.typeFactory = typeFactory; - } - void register(IForgeRegistry> registry) { - registry.register(getOrCreateType()); - } - - ParticleType getOrCreateType() { - if (type != null) - return type; - type = typeFactory.get() - .createType(); - type.setRegistryName(id); - return type; + object = REGISTER.register(name, () -> this.typeFactory.get().createType()); } @OnlyIn(Dist.CLIENT) - void registerFactory(ParticleEngine particles) { + public void registerFactory(ParticleEngine particles) { typeFactory.get() - .register(getOrCreateType(), particles); + .register(object.get(), particles); } } diff --git a/src/main/java/com/simibubi/create/AllRecipeTypes.java b/src/main/java/com/simibubi/create/AllRecipeTypes.java index 21875a375..0a290dd36 100644 --- a/src/main/java/com/simibubi/create/AllRecipeTypes.java +++ b/src/main/java/com/simibubi/create/AllRecipeTypes.java @@ -4,6 +4,8 @@ import java.util.Optional; import java.util.Set; import java.util.function.Supplier; +import org.jetbrains.annotations.Nullable; + import com.google.common.collect.ImmutableSet; import com.simibubi.create.compat.jei.ConversionRecipe; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCraftingRecipe; @@ -38,7 +40,10 @@ import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.ShapedRecipe; import net.minecraft.world.item.crafting.SimpleRecipeSerializer; import net.minecraft.world.level.Level; -import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; public enum AllRecipeTypes implements IRecipeTypeInfo { @@ -61,34 +66,53 @@ public enum AllRecipeTypes implements IRecipeTypeInfo { MECHANICAL_CRAFTING(MechanicalCraftingRecipe.Serializer::new), SEQUENCED_ASSEMBLY(SequencedAssemblyRecipeSerializer::new), - TOOLBOX_DYEING(() -> new SimpleRecipeSerializer<>(ToolboxDyeingRecipe::new), RecipeType.CRAFTING); + TOOLBOX_DYEING(() -> new SimpleRecipeSerializer<>(ToolboxDyeingRecipe::new), () -> RecipeType.CRAFTING, false); - ; + private final ResourceLocation id; + private final RegistryObject> serializerObject; + @Nullable + private final RegistryObject> typeObject; + private final Supplier> type; - private ResourceLocation id; - private Supplier> serializerSupplier; - private Supplier> typeSupplier; - private RecipeSerializer serializer; - private RecipeType type; - - AllRecipeTypes(Supplier> serializerSupplier, Supplier> typeSupplier) { - this.id = Create.asResource(Lang.asId(name())); - this.serializerSupplier = serializerSupplier; - this.typeSupplier = typeSupplier; - } - - AllRecipeTypes(Supplier> serializerSupplier, RecipeType existingType) { - this(serializerSupplier, () -> existingType); + AllRecipeTypes(Supplier> serializerSupplier, Supplier> typeSupplier, boolean registerType) { + String name = Lang.asId(name()); + id = Create.asResource(name); + serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier); + if (registerType) { + typeObject = Registers.TYPE_REGISTER.register(name, typeSupplier); + type = typeObject; + } else { + typeObject = null; + type = typeSupplier; + } } AllRecipeTypes(Supplier> serializerSupplier) { - this.id = Create.asResource(Lang.asId(name())); - this.serializerSupplier = serializerSupplier; - this.typeSupplier = () -> simpleType(id); + String name = Lang.asId(name()); + id = Create.asResource(name); + serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier); + typeObject = Registers.TYPE_REGISTER.register(name, () -> simpleType(id)); + type = typeObject; } AllRecipeTypes(ProcessingRecipeFactory processingFactory) { - this(processingSerializer(processingFactory)); + this(() -> new ProcessingRecipeSerializer<>(processingFactory)); + } + + public static > RecipeType simpleType(ResourceLocation id) { + String stringId = id.toString(); + return new RecipeType() { + @Override + public String toString() { + return stringId; + } + }; + } + + public static void register(IEventBus modEventBus) { + ShapedRecipe.setCraftingSize(9, 9); + Registers.SERIALIZER_REGISTER.register(modEventBus); + Registers.TYPE_REGISTER.register(modEventBus); } @Override @@ -99,13 +123,13 @@ public enum AllRecipeTypes implements IRecipeTypeInfo { @SuppressWarnings("unchecked") @Override public > T getSerializer() { - return (T) serializer; + return (T) serializerObject.get(); } @SuppressWarnings("unchecked") @Override public > T getType() { - return (T) type; + return (T) type.get(); } public > Optional find(C inv, Level world) { @@ -113,32 +137,6 @@ public enum AllRecipeTypes implements IRecipeTypeInfo { .getRecipeFor(getType(), inv, world); } - public static void register(RegistryEvent.Register> event) { - ShapedRecipe.setCraftingSize(9, 9); - - for (AllRecipeTypes r : AllRecipeTypes.values()) { - r.serializer = r.serializerSupplier.get(); - r.type = r.typeSupplier.get(); - r.serializer.setRegistryName(r.id); - event.getRegistry() - .register(r.serializer); - } - } - - private static Supplier> processingSerializer(ProcessingRecipeFactory factory) { - return () -> new ProcessingRecipeSerializer<>(factory); - } - - public static > RecipeType simpleType(ResourceLocation id) { - String stringId = id.toString(); - return Registry.register(Registry.RECIPE_TYPE, id, new RecipeType() { - @Override - public String toString() { - return stringId; - } - }); - } - public static final Set RECIPE_DENY_SET = ImmutableSet.of(new ResourceLocation("occultism", "spirit_trade"), new ResourceLocation("occultism", "ritual")); @@ -151,4 +149,9 @@ public enum AllRecipeTypes implements IRecipeTypeInfo { .endsWith("_manual_only"); } + private static class Registers { + private static final DeferredRegister> SERIALIZER_REGISTER = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, Create.ID); + private static final DeferredRegister> TYPE_REGISTER = DeferredRegister.create(Registry.RECIPE_TYPE_REGISTRY, Create.ID); + } + } diff --git a/src/main/java/com/simibubi/create/AllSoundEvents.java b/src/main/java/com/simibubi/create/AllSoundEvents.java index 3835bf89e..2128825a6 100644 --- a/src/main/java/com/simibubi/create/AllSoundEvents.java +++ b/src/main/java/com/simibubi/create/AllSoundEvents.java @@ -6,14 +6,12 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Supplier; -import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import com.simibubi.create.foundation.utility.Couple; -import com.simibubi.create.foundation.utility.Pair; import net.minecraft.core.Vec3i; import net.minecraft.data.DataGenerator; @@ -28,12 +26,15 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.RegistryObject; //@EventBusSubscriber(bus = Bus.FORGE) public class AllSoundEvents { - public static final Map entries = new HashMap<>(); + public static final Map ALL = new HashMap<>(); + public static final SoundEntry SCHEMATICANNON_LAUNCH_BLOCK = create("schematicannon_launch_block").subtitle("Schematicannon fires") @@ -306,20 +307,20 @@ public class AllSoundEvents { return new SoundEntryBuilder(id); } - public static void register(RegistryEvent.Register event) { - IForgeRegistry registry = event.getRegistry(); - for (SoundEntry entry : entries.values()) - entry.register(registry); + public static void prepare() { + for (SoundEntry entry : ALL.values()) + entry.prepare(); } - public static void prepare() { - for (SoundEntry entry : entries.values()) - entry.prepare(); + public static void register(RegistryEvent.Register event) { + IForgeRegistry registry = event.getRegistry(); + for (SoundEntry entry : ALL.values()) + entry.register(registry); } public static JsonObject provideLangEntries() { JsonObject object = new JsonObject(); - for (SoundEntry entry : entries.values()) + for (SoundEntry entry : ALL.values()) if (entry.hasSubtitle()) object.addProperty(entry.getSubtitleKey(), entry.getSubtitle()); return object; @@ -370,7 +371,7 @@ public class AllSoundEvents { try { JsonObject json = new JsonObject(); - entries.entrySet() + ALL.entrySet() .stream() .sorted(Map.Entry.comparingByKey()) .forEach(entry -> { @@ -386,12 +387,15 @@ public class AllSoundEvents { } + public record ConfiguredSoundEvent(Supplier event, float volume, float pitch) { + } + public static class SoundEntryBuilder { protected ResourceLocation id; protected String subtitle = "unregistered"; protected SoundSource category = SoundSource.BLOCKS; - protected List>> wrappedEvents; + protected List wrappedEvents; protected List variants; protected int attenuationDistance; @@ -430,11 +434,15 @@ public class AllSoundEvents { return this; } - public SoundEntryBuilder playExisting(SoundEvent event, float volume, float pitch) { - wrappedEvents.add(Pair.of(event, Couple.create(volume, pitch))); + public SoundEntryBuilder playExisting(Supplier event, float volume, float pitch) { + wrappedEvents.add(new ConfiguredSoundEvent(event, volume, pitch)); return this; } + public SoundEntryBuilder playExisting(SoundEvent event, float volume, float pitch) { + return playExisting(() -> event, volume, pitch); + } + public SoundEntryBuilder playExisting(SoundEvent event) { return playExisting(event, 1, 1); } @@ -443,7 +451,7 @@ public class AllSoundEvents { SoundEntry entry = wrappedEvents.isEmpty() ? new CustomSoundEntry(id, variants, subtitle, category, attenuationDistance) : new WrappedSoundEntry(id, subtitle, wrappedEvents, category, attenuationDistance); - entries.put(entry.getId(), entry); + ALL.put(entry.getId(), entry); return entry; } @@ -532,50 +540,53 @@ public class AllSoundEvents { private static class WrappedSoundEntry extends SoundEntry { - private List>> wrappedEvents; - private List>> compiledEvents; + private List wrappedEvents; + private List compiledEvents; public WrappedSoundEntry(ResourceLocation id, String subtitle, - List>> wrappedEvents, SoundSource category, int attenuationDistance) { + List wrappedEvents, SoundSource category, int attenuationDistance) { super(id, subtitle, category, attenuationDistance); this.wrappedEvents = wrappedEvents; - compiledEvents = Lists.newArrayList(); + compiledEvents = new ArrayList<>(); } @Override public void prepare() { for (int i = 0; i < wrappedEvents.size(); i++) { - ResourceLocation location = Create.asResource(getIdOf(i)); - SoundEvent sound = new SoundEvent(location).setRegistryName(location); - compiledEvents.add(Pair.of(sound, wrappedEvents.get(i) - .getSecond())); + ConfiguredSoundEvent wrapped = wrappedEvents.get(i); + ResourceLocation location = getIdOf(i); + RegistryObject event = RegistryObject.create(location, ForgeRegistries.SOUND_EVENTS); + compiledEvents.add(new CompiledSoundEvent(event, wrapped.volume(), wrapped.pitch())); } } @Override public void register(IForgeRegistry registry) { - for (Pair> pair : compiledEvents) - registry.register(pair.getFirst()); + for (CompiledSoundEvent compiledEvent : compiledEvents) { + ResourceLocation location = compiledEvent.event().getId(); + registry.register(new SoundEvent(location).setRegistryName(location)); + } } @Override public SoundEvent getMainEvent() { return compiledEvents.get(0) - .getFirst(); + .event().get(); } - protected String getIdOf(int i) { - return i == 0 ? id.getPath() : id.getPath() + "_compounded_" + i; + protected ResourceLocation getIdOf(int i) { + return new ResourceLocation(id.getNamespace(), i == 0 ? id.getPath() : id.getPath() + "_compounded_" + i); } @Override public void write(JsonObject json) { for (int i = 0; i < wrappedEvents.size(); i++) { - Pair> pair = wrappedEvents.get(i); + ConfiguredSoundEvent event = wrappedEvents.get(i); JsonObject entry = new JsonObject(); JsonArray list = new JsonArray(); JsonObject s = new JsonObject(); - s.addProperty("name", pair.getFirst() + s.addProperty("name", event.event() + .get() .getLocation() .toString()); s.addProperty("type", "event"); @@ -585,33 +596,35 @@ public class AllSoundEvents { entry.add("sounds", list); if (i == 0 && hasSubtitle()) entry.addProperty("subtitle", getSubtitleKey()); - json.add(getIdOf(i), entry); + json.add(getIdOf(i).getPath(), entry); } } @Override public void play(Level world, Player entity, double x, double y, double z, float volume, float pitch) { - for (Pair> pair : compiledEvents) { - Couple volPitch = pair.getSecond(); - world.playSound(entity, x, y, z, pair.getFirst(), category, volPitch.getFirst() * volume, - volPitch.getSecond() * pitch); + for (CompiledSoundEvent event : compiledEvents) { + world.playSound(entity, x, y, z, event.event().get(), category, event.volume() * volume, + event.pitch() * pitch); } } @Override public void playAt(Level world, double x, double y, double z, float volume, float pitch, boolean fade) { - for (Pair> pair : compiledEvents) { - Couple volPitch = pair.getSecond(); - world.playLocalSound(x, y, z, pair.getFirst(), category, volPitch.getFirst() * volume, - volPitch.getSecond() * pitch, fade); + for (CompiledSoundEvent event : compiledEvents) { + world.playLocalSound(x, y, z, event.event().get(), category, event.volume() * volume, + event.pitch() * pitch, fade); } } + + private record CompiledSoundEvent(RegistryObject event, float volume, float pitch) { + } + } private static class CustomSoundEntry extends SoundEntry { protected List variants; - protected SoundEvent event; + protected RegistryObject event; public CustomSoundEntry(ResourceLocation id, List variants, String subtitle, SoundSource category, int attenuationDistance) { @@ -621,17 +634,18 @@ public class AllSoundEvents { @Override public void prepare() { - event = new SoundEvent(id).setRegistryName(id); + event = RegistryObject.create(id, ForgeRegistries.SOUND_EVENTS); } @Override public void register(IForgeRegistry registry) { - registry.register(event); + ResourceLocation location = event.getId(); + registry.register(new SoundEvent(location).setRegistryName(location)); } @Override public SoundEvent getMainEvent() { - return event; + return event.get(); } @Override @@ -663,12 +677,12 @@ public class AllSoundEvents { @Override public void play(Level world, Player entity, double x, double y, double z, float volume, float pitch) { - world.playSound(entity, x, y, z, event, category, volume, pitch); + world.playSound(entity, x, y, z, event.get(), category, volume, pitch); } @Override public void playAt(Level world, double x, double y, double z, float volume, float pitch, boolean fade) { - world.playLocalSound(x, y, z, event, category, volume, pitch, fade); + world.playLocalSound(x, y, z, event.get(), category, volume, pitch, fade); } } diff --git a/src/main/java/com/simibubi/create/AllStructureProcessorTypes.java b/src/main/java/com/simibubi/create/AllStructureProcessorTypes.java new file mode 100644 index 000000000..047f68f9a --- /dev/null +++ b/src/main/java/com/simibubi/create/AllStructureProcessorTypes.java @@ -0,0 +1,19 @@ +package com.simibubi.create; + +import com.simibubi.create.content.schematics.SchematicProcessor; + +import net.minecraft.core.Registry; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; + +public class AllStructureProcessorTypes { + private static final DeferredRegister> REGISTER = DeferredRegister.create(Registry.STRUCTURE_PROCESSOR_REGISTRY, Create.ID); + + public static final RegistryObject> SCHEMATIC = REGISTER.register("schematic", () -> () -> SchematicProcessor.CODEC); + + public static void register(IEventBus modEventBus) { + REGISTER.register(modEventBus); + } +} diff --git a/src/main/java/com/simibubi/create/AllTags.java b/src/main/java/com/simibubi/create/AllTags.java index f2fb70d00..f5c1153d9 100644 --- a/src/main/java/com/simibubi/create/AllTags.java +++ b/src/main/java/com/simibubi/create/AllTags.java @@ -112,9 +112,11 @@ public class AllTags { public enum AllBlockTags { BRITTLE, - FAN_HEATERS, + CASING, FAN_TRANSPARENT, + NON_MOVABLE, ORE_OVERRIDE_STONE, + PASSIVE_BOILER_HEATERS, SAFE_NBT, SEATS, TOOLBOXES, @@ -122,10 +124,6 @@ public class AllTags { WINDMILL_SAILS, WINDOWABLE, WRENCH_PICKUP, - CASING, - NON_MOVABLE, - - PASSIVE_BOILER_HEATERS, RELOCATION_NOT_SUPPORTED(FORGE), WG_STONE(FORGE), @@ -208,10 +206,13 @@ public class AllTags { BLAZE_BURNER_FUEL_REGULAR(MOD, "blaze_burner_fuel/regular"), BLAZE_BURNER_FUEL_SPECIAL(MOD, "blaze_burner_fuel/special"), + CASING, CREATE_INGOTS, CRUSHED_ORES, + PRESSURIZED_AIR_SOURCES, SANDPAPER, SEATS, + SLEEPERS, TOOLBOXES, UPRIGHT_ON_BELT, VALVE_HANDLES, @@ -219,9 +220,6 @@ public class AllTags { VANILLA_STRIPPED_WOOD, MODDED_STRIPPED_LOGS, MODDED_STRIPPED_WOOD, - CASING, - SLEEPERS, - PRESSURIZED_AIR_SOURCES, STRIPPED_LOGS(FORGE), STRIPPED_WOOD(FORGE), @@ -402,10 +400,9 @@ public class AllTags { AllBlockTags.FAN_TRANSPARENT.includeAll(BlockTags.CAMPFIRES); AllBlockTags.FAN_TRANSPARENT.add(Blocks.IRON_BARS); - AllBlockTags.FAN_HEATERS.includeAll(BlockTags.FIRE); - AllBlockTags.FAN_HEATERS.includeAll(BlockTags.CAMPFIRES); - AllBlockTags.FAN_HEATERS.add(Blocks.MAGMA_BLOCK, Blocks.LAVA); - AllBlockTags.FAN_HEATERS.includeIn(AllBlockTags.PASSIVE_BOILER_HEATERS); + AllBlockTags.PASSIVE_BOILER_HEATERS.includeAll(BlockTags.FIRE); + AllBlockTags.PASSIVE_BOILER_HEATERS.includeAll(BlockTags.CAMPFIRES); + AllBlockTags.PASSIVE_BOILER_HEATERS.add(Blocks.MAGMA_BLOCK, Blocks.LAVA); AllBlockTags.SAFE_NBT.includeAll(BlockTags.SIGNS); AllBlockTags.SAFE_NBT.includeAll(BlockTags.BANNERS); diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index 56c0b9b1a..bdfd20d23 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -21,7 +21,6 @@ import com.simibubi.create.content.logistics.block.mechanicalArm.AllArmInteracti import com.simibubi.create.content.logistics.trains.GlobalRailwayManager; import com.simibubi.create.content.palettes.AllPaletteBlocks; import com.simibubi.create.content.palettes.PalettesItemGroup; -import com.simibubi.create.content.schematics.SchematicProcessor; import com.simibubi.create.content.schematics.ServerSchematicLoader; import com.simibubi.create.content.schematics.filtering.SchematicInstances; import com.simibubi.create.foundation.advancement.AllAdvancements; @@ -38,18 +37,17 @@ import com.simibubi.create.foundation.data.recipe.SequencedAssemblyRecipeGen; 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.AllWorldFeatures; +import com.simibubi.create.foundation.worldgen.AllFeatures; +import com.simibubi.create.foundation.worldgen.AllPlacementModifiers; +import com.simibubi.create.foundation.worldgen.BuiltinRegistration; import com.tterrag.registrate.util.nullness.NonNullSupplier; -import net.minecraft.core.particles.ParticleType; import net.minecraft.data.DataGenerator; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.world.level.Level; -import net.minecraft.world.level.levelgen.feature.Feature; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.ForgeMod; import net.minecraftforge.common.MinecraftForge; @@ -61,7 +59,6 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.forge.event.lifecycle.GatherDataEvent; -import net.minecraftforge.registries.DataSerializerEntry; @Mod(Create.ID) public class Create { @@ -97,6 +94,10 @@ public class Create { public static void onCtor() { ModLoadingContext modLoadingContext = ModLoadingContext.get(); + IEventBus modEventBus = FMLJavaModLoadingContext.get() + .getModEventBus(); + IEventBus forgeEventBus = MinecraftForge.EVENT_BUS; + AllSoundEvents.prepare(); AllBlocks.register(); AllItems.register(); @@ -106,34 +107,33 @@ public class Create { AllContainerTypes.register(); AllEntityTypes.register(); AllTileEntities.register(); + AllEnchantments.register(); + AllRecipeTypes.register(modEventBus); + AllParticleTypes.register(modEventBus); + AllStructureProcessorTypes.register(modEventBus); + AllEntityDataSerializers.register(modEventBus); + AllFeatures.register(modEventBus); + AllPlacementModifiers.register(modEventBus); + BuiltinRegistration.register(modEventBus); + + AllConfigs.register(modLoadingContext); + AllMovementBehaviours.registerDefaults(); AllInteractionBehaviours.registerDefaults(); AllDisplayBehaviours.registerDefaults(); ContraptionMovementSetting.registerDefaults(); AllArmInteractionPointTypes.register(); - AllWorldFeatures.register(); - AllEnchantments.register(); - AllConfigs.register(modLoadingContext); - BlockSpoutingBehaviour.register(); + BlockSpoutingBehaviour.registerDefaults(); ForgeMod.enableMilkFluid(); - CopperRegistries.inject(); - IEventBus modEventBus = FMLJavaModLoadingContext.get() - .getModEventBus(); - IEventBus forgeEventBus = MinecraftForge.EVENT_BUS; - modEventBus.addListener(Create::init); modEventBus.addListener(EventPriority.LOWEST, Create::gatherData); - modEventBus.addGenericListener(Feature.class, AllWorldFeatures::registerOreFeatures); - modEventBus.addGenericListener(RecipeSerializer.class, AllRecipeTypes::register); - modEventBus.addGenericListener(ParticleType.class, AllParticleTypes::register); modEventBus.addGenericListener(SoundEvent.class, AllSoundEvents::register); - modEventBus.addGenericListener(DataSerializerEntry.class, AllEntityDataSerializers::register); forgeEventBus.addListener(EventPriority.HIGH, SlidingDoorBlock::stopItQuark); - + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus)); Mods.CURIOS.executeIfInstalled(() -> Curios::init); @@ -148,22 +148,24 @@ public class Create { event.enqueueWork(() -> { AllAdvancements.register(); AllTriggers.register(); - SchematicProcessor.register(); - AllWorldFeatures.registerFeatures(); - AllWorldFeatures.registerPlacementTypes(); BoilerHeaters.registerDefaults(); }); } public static void gatherData(GatherDataEvent event) { DataGenerator gen = event.getGenerator(); - gen.addProvider(new AllAdvancements(gen)); - gen.addProvider(new LangMerger(gen)); - gen.addProvider(AllSoundEvents.provider(gen)); - gen.addProvider(new StandardRecipeGen(gen)); - gen.addProvider(new MechanicalCraftingRecipeGen(gen)); - gen.addProvider(new SequencedAssemblyRecipeGen(gen)); - ProcessingRecipeGen.registerAll(gen); + if (event.includeClient()) { + gen.addProvider(new LangMerger(gen)); + gen.addProvider(AllSoundEvents.provider(gen)); + } + if (event.includeServer()) { + gen.addProvider(new AllAdvancements(gen)); + gen.addProvider(new StandardRecipeGen(gen)); + gen.addProvider(new MechanicalCraftingRecipeGen(gen)); + gen.addProvider(new SequencedAssemblyRecipeGen(gen)); + ProcessingRecipeGen.registerAll(gen); +// AllOreFeatureConfigEntries.gatherData(event); + } } public static CreateRegistrate registrate() { diff --git a/src/main/java/com/simibubi/create/api/behaviour/BlockSpoutingBehaviour.java b/src/main/java/com/simibubi/create/api/behaviour/BlockSpoutingBehaviour.java index f96d95176..8915492b8 100644 --- a/src/main/java/com/simibubi/create/api/behaviour/BlockSpoutingBehaviour.java +++ b/src/main/java/com/simibubi/create/api/behaviour/BlockSpoutingBehaviour.java @@ -46,7 +46,7 @@ public abstract class BlockSpoutingBehaviour { public abstract int fillBlock(Level world, BlockPos pos, SpoutTileEntity spout, FluidStack availableFluid, boolean simulate); - public static void register() { + public static void registerDefaults() { addCustomSpoutInteraction(Create.asResource("ticon_casting"), new SpoutCasting()); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java index f2549660a..32e2e3174 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java @@ -588,7 +588,7 @@ public class BasinTileEntity extends SmartTileEntity implements IHaveGoggleInfor public static HeatLevel getHeatLevelOf(BlockState state) { if (state.hasProperty(BlazeBurnerBlock.HEAT_LEVEL)) return state.getValue(BlazeBurnerBlock.HEAT_LEVEL); - return AllTags.AllBlockTags.FAN_HEATERS.matches(state) ? HeatLevel.SMOULDERING : HeatLevel.NONE; + return AllTags.AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) ? HeatLevel.SMOULDERING : HeatLevel.NONE; } public Couple getTanks() { diff --git a/src/main/java/com/simibubi/create/content/curiosities/armor/AllArmorMaterials.java b/src/main/java/com/simibubi/create/content/curiosities/armor/AllArmorMaterials.java index 677fad057..0937f2b7d 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/armor/AllArmorMaterials.java +++ b/src/main/java/com/simibubi/create/content/curiosities/armor/AllArmorMaterials.java @@ -13,7 +13,7 @@ import net.minecraft.world.item.crafting.Ingredient; public enum AllArmorMaterials implements ArmorMaterial { - COPPER("copper", 7, new int[] { 1, 3, 4, 2 }, 25, AllSoundEvents.COPPER_ARMOR_EQUIP.getMainEvent(), 0.0F, 0.0F, + COPPER("copper", 7, new int[] { 1, 3, 4, 2 }, 25, () -> AllSoundEvents.COPPER_ARMOR_EQUIP.getMainEvent(), 0.0F, 0.0F, () -> Ingredient.of(Items.COPPER_INGOT)) ; @@ -23,13 +23,13 @@ public enum AllArmorMaterials implements ArmorMaterial { private final int maxDamageFactor; private final int[] damageReductionAmountArray; private final int enchantability; - private final SoundEvent soundEvent; + private final Supplier soundEvent; private final float toughness; private final float knockbackResistance; private final Supplier repairMaterial; private AllArmorMaterials(String name, int maxDamageFactor, int[] damageReductionAmountArray, int enchantability, - SoundEvent soundEvent, float toughness, float knockbackResistance, Supplier repairMaterial) { + Supplier soundEvent, float toughness, float knockbackResistance, Supplier repairMaterial) { this.name = name; this.maxDamageFactor = maxDamageFactor; this.damageReductionAmountArray = damageReductionAmountArray; @@ -57,7 +57,7 @@ public enum AllArmorMaterials implements ArmorMaterial { @Override public SoundEvent getEquipSound() { - return this.soundEvent; + return this.soundEvent.get(); } @Override diff --git a/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java b/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java index a07359ac7..e5507d8e7 100644 --- a/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java +++ b/src/main/java/com/simibubi/create/content/schematics/SchematicProcessor.java @@ -5,6 +5,7 @@ import java.util.Optional; import javax.annotation.Nullable; import com.mojang.serialization.Codec; +import com.simibubi.create.AllStructureProcessorTypes; import com.simibubi.create.foundation.utility.NBTProcessors; import net.minecraft.core.BlockPos; @@ -21,18 +22,12 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProc import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; public class SchematicProcessor extends StructureProcessor { - + public static final SchematicProcessor INSTANCE = new SchematicProcessor(); public static final Codec CODEC = Codec.unit(() -> { return INSTANCE; }); - - public static StructureProcessorType TYPE; - - public static void register() { - TYPE = StructureProcessorType.register("schematic", CODEC); - } - + @Nullable @Override public StructureTemplate.StructureBlockInfo process(LevelReader world, BlockPos pos, BlockPos anotherPos, StructureTemplate.StructureBlockInfo rawInfo, @@ -65,7 +60,7 @@ public class SchematicProcessor extends StructureProcessor { @Override protected StructureProcessorType getType() { - return TYPE; + return AllStructureProcessorTypes.SCHEMATIC.get(); } } diff --git a/src/main/java/com/simibubi/create/events/CommonEvents.java b/src/main/java/com/simibubi/create/events/CommonEvents.java index fe6332c10..38156537a 100644 --- a/src/main/java/com/simibubi/create/events/CommonEvents.java +++ b/src/main/java/com/simibubi/create/events/CommonEvents.java @@ -20,7 +20,7 @@ import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.foundation.utility.WorldAttached; import com.simibubi.create.foundation.utility.recipe.RecipeFinder; -import com.simibubi.create.foundation.worldgen.AllWorldFeatures; +import com.simibubi.create.foundation.worldgen.AllOreFeatureConfigEntries; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -213,7 +213,7 @@ public class CommonEvents { @SubscribeEvent(priority = EventPriority.HIGH) public static void onBiomeLoad(BiomeLoadingEvent event) { - AllWorldFeatures.reload(event); + AllOreFeatureConfigEntries.modifyBiomes(event); } public static void leftClickEmpty(ServerPlayer player) { diff --git a/src/main/java/com/simibubi/create/foundation/config/CWorldGen.java b/src/main/java/com/simibubi/create/foundation/config/CWorldGen.java index 8220e50df..6f03e44c5 100644 --- a/src/main/java/com/simibubi/create/foundation/config/CWorldGen.java +++ b/src/main/java/com/simibubi/create/foundation/config/CWorldGen.java @@ -1,22 +1,30 @@ package com.simibubi.create.foundation.config; -import com.simibubi.create.foundation.worldgen.AllWorldFeatures; +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); - AllWorldFeatures.fillConfig(builder); + AllOreFeatureConfigEntries.fillConfig(builder, Create.ID); } @Override public String getName() { - return "worldgen.v" + AllWorldFeatures.forcedUpdateVersion; + return "worldgen.v" + FORCED_UPDATE_VERSION; } private static class Comments { diff --git a/src/main/java/com/simibubi/create/foundation/config/ConfigBase.java b/src/main/java/com/simibubi/create/foundation/config/ConfigBase.java index 5b8565da3..352975c79 100644 --- a/src/main/java/com/simibubi/create/foundation/config/ConfigBase.java +++ b/src/main/java/com/simibubi/create/foundation/config/ConfigBase.java @@ -63,6 +63,10 @@ public abstract class ConfigBase { return i(current, min, Integer.MAX_VALUE, name, comment); } + protected ConfigInt i(int current, String name, String... comment) { + return i(current, Integer.MIN_VALUE, Integer.MAX_VALUE, name, comment); + } + protected > ConfigEnum e(T defaultValue, String name, String... comment) { return new ConfigEnum<>(name, defaultValue, comment); } diff --git a/src/main/java/com/simibubi/create/foundation/data/DynamicDataProvider.java b/src/main/java/com/simibubi/create/foundation/data/DynamicDataProvider.java new file mode 100644 index 000000000..3ee8a1387 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/data/DynamicDataProvider.java @@ -0,0 +1,93 @@ +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.Gson; +import com.google.gson.GsonBuilder; +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.DataGenerator; +import net.minecraft.data.DataProvider; +import net.minecraft.data.HashCache; +import net.minecraft.resources.RegistryOps; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; + +public class DynamicDataProvider implements DataProvider { + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + private final DataGenerator generator; + private final String name; + private final RegistryAccess registryAccess; + private final RegistryAccess.RegistryData registryData; + private final Map values; + + public DynamicDataProvider(DataGenerator generator, String name, RegistryAccess registryAccess, RegistryAccess.RegistryData registryData, Map values) { + this.generator = generator; + this.name = name; + this.registryAccess = registryAccess; + this.registryData = registryData; + this.values = values; + } + + @Nullable + public static DynamicDataProvider create(DataGenerator generator, String name, RegistryAccess registryAccess, ResourceKey> registryKey, Map values) { + @SuppressWarnings("unchecked") + RegistryAccess.RegistryData registryData = (RegistryData) RegistryAccess.REGISTRIES.get(registryKey); + if (registryData == null) { + return null; + } + return new DynamicDataProvider<>(generator, name, registryAccess, registryData, values); + } + + @Override + public void run(HashCache cache) throws IOException { + Path path = generator.getOutputFolder(); + DynamicOps ops = RegistryOps.create(JsonOps.INSTANCE, registryAccess); + + dumpValues(path, cache, ops, registryData.key(), values, registryData.codec()); + } + + private void dumpValues(Path rootPath, HashCache cache, DynamicOps ops, ResourceKey> registryKey, Map values, Encoder encoder) { + for (Entry entry : values.entrySet()) { + Path path = createPath(rootPath, registryKey.location(), entry.getKey()); + dumpValue(path, cache, ops, encoder, entry.getValue()); + } + } + + // From WorldgenRegistryDumpReport + private void dumpValue(Path path, HashCache cache, DynamicOps ops, Encoder encoder, T value) { + try { + Optional optional = encoder.encodeStart(ops, value).resultOrPartial((message) -> { + Create.LOGGER.error("Couldn't serialize element {}: {}", path, message); + }); + if (optional.isPresent()) { + DataProvider.save(GSON, cache, optional.get(), path); + } + } catch (IOException e) { + Create.LOGGER.error("Couldn't save element {}", path, e); + } + } + + private Path createPath(Path path, ResourceLocation registry, ResourceLocation value) { + return path.resolve("data").resolve(value.getNamespace()).resolve(registry.getPath()).resolve(value.getPath() + ".json"); + } + + @Override + public String getName() { + return name; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/AllFeatures.java b/src/main/java/com/simibubi/create/foundation/worldgen/AllFeatures.java new file mode 100644 index 000000000..5fa2a98c2 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/worldgen/AllFeatures.java @@ -0,0 +1,20 @@ +package com.simibubi.create.foundation.worldgen; + +import com.simibubi.create.Create; + +import net.minecraft.world.level.levelgen.feature.Feature; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +public class AllFeatures { + private static final DeferredRegister> REGISTER = DeferredRegister.create(ForgeRegistries.FEATURES, Create.ID); + + public static final RegistryObject STANDARD_ORE = REGISTER.register("standard_ore", () -> new StandardOreFeature()); + public static final RegistryObject LAYERED_ORE = REGISTER.register("layered_ore", () -> new LayeredOreFeature()); + + public static void register(IEventBus modEventBus) { + REGISTER.register(modEventBus); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/AllLayerPatterns.java b/src/main/java/com/simibubi/create/foundation/worldgen/AllLayerPatterns.java index 4908780fe..395894742 100644 --- a/src/main/java/com/simibubi/create/foundation/worldgen/AllLayerPatterns.java +++ b/src/main/java/com/simibubi/create/foundation/worldgen/AllLayerPatterns.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.Blocks; public class AllLayerPatterns { - public static NonNullSupplier + public static final NonNullSupplier CINNABAR = () -> LayerPattern.builder() .layer(l -> l.weight(1) @@ -25,7 +25,7 @@ public class AllLayerPatterns { .block(AllPaletteStoneTypes.LIMESTONE.getBaseBlock())) .build(); - public static NonNullSupplier MAGNETITE = () -> LayerPattern.builder() + public static final NonNullSupplier MAGNETITE = () -> LayerPattern.builder() .layer(l -> l.weight(1) .passiveBlock()) .layer(l -> l.weight(2) @@ -41,7 +41,7 @@ public class AllLayerPatterns { .block(Blocks.CALCITE)) .build(); - public static NonNullSupplier OCHRESTONE = () -> LayerPattern.builder() + public static final NonNullSupplier OCHRESTONE = () -> LayerPattern.builder() .layer(l -> l.weight(1) .passiveBlock()) .layer(l -> l.weight(2) @@ -56,7 +56,7 @@ public class AllLayerPatterns { .size(1, 2)) .build(); - public static NonNullSupplier MALACHITE = () -> LayerPattern.builder() + public static final NonNullSupplier MALACHITE = () -> LayerPattern.builder() .layer(l -> l.weight(2) .passiveBlock()) .layer(l -> l.weight(4) @@ -72,7 +72,7 @@ public class AllLayerPatterns { .block(Blocks.SMOOTH_BASALT)) .build(); - public static NonNullSupplier SCORIA = () -> LayerPattern.builder() + public static final NonNullSupplier SCORIA = () -> LayerPattern.builder() .layer(l -> l.weight(1) .passiveBlock()) .layer(l -> l.weight(2) @@ -88,7 +88,7 @@ public class AllLayerPatterns { .block(Blocks.DIORITE)) .build(); - public static NonNullSupplier LIMESTONE = () -> LayerPattern.builder() + public static final NonNullSupplier LIMESTONE = () -> LayerPattern.builder() .layer(l -> l.weight(1) .passiveBlock()) .layer(l -> l.weight(2) @@ -100,7 +100,7 @@ public class AllLayerPatterns { .size(1, 4)) .build(); - public static NonNullSupplier SCORIA_NETHER = () -> LayerPattern.builder() + public static final NonNullSupplier SCORIA_NETHER = () -> LayerPattern.builder() .inNether() .layer(l -> l.weight(1) .passiveBlock()) @@ -115,7 +115,7 @@ public class AllLayerPatterns { .block(Blocks.SMOOTH_BASALT)) .build(); - public static NonNullSupplier SCORCHIA_NETHER = () -> LayerPattern.builder() + public static final NonNullSupplier SCORCHIA_NETHER = () -> LayerPattern.builder() .inNether() .layer(l -> l.weight(2) .passiveBlock()) diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/AllOreFeatureConfigEntries.java b/src/main/java/com/simibubi/create/foundation/worldgen/AllOreFeatureConfigEntries.java new file mode 100644 index 000000000..e0e778ed3 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/worldgen/AllOreFeatureConfigEntries.java @@ -0,0 +1,134 @@ +package com.simibubi.create.foundation.worldgen; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Predicate; + +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.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.data.BuiltinRegistries; +import net.minecraft.data.DataGenerator; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.Biome.BiomeCategory; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.placement.PlacedFeature; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.event.world.BiomeLoadingEvent; +import net.minecraftforge.forge.event.lifecycle.GatherDataEvent; + +public class AllOreFeatureConfigEntries { + private static final Predicate OVERWORLD_BIOMES = event -> { + Biome.BiomeCategory category = event.getCategory(); + return category != BiomeCategory.NETHER && category != BiomeCategory.THEEND && category != BiomeCategory.NONE; + }; + + private static final Predicate NETHER_BIOMES = event -> { + Biome.BiomeCategory category = event.getCategory(); + return category == BiomeCategory.NETHER; + }; + + // + + public static final OreFeatureConfigEntry ZINC_ORE = + create("zinc_ore", 12, 8, -63, 70) + .biomeExt() + .predicate(OVERWORLD_BIOMES) + .parent() + .standardDatagenExt() + .withBlocks(Couple.create(AllBlocks.ZINC_ORE, AllBlocks.DEEPSLATE_ZINC_ORE)) + .parent(); + + public static final OreFeatureConfigEntry STRIATED_ORES_OVERWORLD = + create("striated_ores_overworld", 32, 1 / 12f, -30, 70) + .biomeExt() + .predicate(OVERWORLD_BIOMES) + .parent() + .layeredDatagenExt() + .withLayerPattern(AllLayerPatterns.SCORIA) + .withLayerPattern(AllLayerPatterns.CINNABAR) + .withLayerPattern(AllLayerPatterns.MAGNETITE) + .withLayerPattern(AllLayerPatterns.MALACHITE) + .withLayerPattern(AllLayerPatterns.LIMESTONE) + .withLayerPattern(AllLayerPatterns.OCHRESTONE) + .parent(); + + public static final OreFeatureConfigEntry STRIATED_ORES_NETHER = + create("striated_ores_nether", 32, 1 / 12f, 40, 90) + .biomeExt() + .predicate(NETHER_BIOMES) + .parent() + .layeredDatagenExt() + .withLayerPattern(AllLayerPatterns.SCORIA_NETHER) + .withLayerPattern(AllLayerPatterns.SCORCHIA_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 modifyBiomes(BiomeLoadingEvent event) { + for (OreFeatureConfigEntry entry : OreFeatureConfigEntry.ALL.values()) { + entry.biomeExt().modifyBiomes(event, BuiltinRegistries.PLACED_FEATURE); + } + } + + public static void gatherData(GatherDataEvent event) { + DataGenerator generator = event.getGenerator(); + RegistryAccess registryAccess = RegistryAccess.BUILTIN.get(); + + // + + Map> configuredFeatures = new HashMap<>(); + for (Map.Entry entry : OreFeatureConfigEntry.ALL.entrySet()) { + DatagenExtension datagenExt = entry.getValue().datagenExt(); + if (datagenExt != null) { + configuredFeatures.put(entry.getKey(), datagenExt.getConfiguredFeature()); + } + } + + DynamicDataProvider> configuredFeatureProvider = DynamicDataProvider.create(generator, "Create's Configured Features", registryAccess, Registry.CONFIGURED_FEATURE_REGISTRY, configuredFeatures); + if (configuredFeatureProvider != null) { + generator.addProvider(configuredFeatureProvider); + } + + // + + Map placedFeatures = new HashMap<>(); + for (Map.Entry entry : OreFeatureConfigEntry.ALL.entrySet()) { + DatagenExtension datagenExt = entry.getValue().datagenExt(); + if (datagenExt != null) { + placedFeatures.put(entry.getKey(), datagenExt.getPlacedFeature()); + } + } + + DynamicDataProvider placedFeatureProvider = DynamicDataProvider.create(generator, "Create's Placed Features", registryAccess, Registry.PLACED_FEATURE_REGISTRY, placedFeatures); + if (placedFeatureProvider != null) { + generator.addProvider(placedFeatureProvider); + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/AllPlacementModifiers.java b/src/main/java/com/simibubi/create/foundation/worldgen/AllPlacementModifiers.java new file mode 100644 index 000000000..fd8ce11bc --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/worldgen/AllPlacementModifiers.java @@ -0,0 +1,19 @@ +package com.simibubi.create.foundation.worldgen; + +import com.simibubi.create.Create; + +import net.minecraft.core.Registry; +import net.minecraft.world.level.levelgen.placement.PlacementModifierType; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; + +public class AllPlacementModifiers { + private static final DeferredRegister> REGISTER = DeferredRegister.create(Registry.PLACEMENT_MODIFIER_REGISTRY, Create.ID); + + public static final RegistryObject> CONFIG_DRIVEN = REGISTER.register("config_driven", () -> () -> ConfigDrivenPlacement.CODEC); + + public static void register(IEventBus modEventBus) { + REGISTER.register(modEventBus); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/AllWorldFeatures.java b/src/main/java/com/simibubi/create/foundation/worldgen/AllWorldFeatures.java deleted file mode 100644 index 11a703644..000000000 --- a/src/main/java/com/simibubi/create/foundation/worldgen/AllWorldFeatures.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.simibubi.create.foundation.worldgen; - -import java.util.HashMap; -import java.util.Map; - -import com.google.common.collect.ImmutableList; -import com.simibubi.create.AllBlocks; -import com.simibubi.create.Create; -import com.simibubi.create.foundation.utility.Couple; - -import net.minecraft.core.Registry; -import net.minecraft.data.BuiltinRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome.BiomeCategory; -import net.minecraft.world.level.levelgen.GenerationStep; -import net.minecraft.world.level.levelgen.GenerationStep.Decoration; -import net.minecraft.world.level.levelgen.feature.Feature; -import net.minecraft.world.level.levelgen.placement.PlacedFeature; -import net.minecraftforge.common.ForgeConfigSpec; -import net.minecraftforge.common.world.BiomeGenerationSettingsBuilder; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.event.world.BiomeLoadingEvent; - -public class AllWorldFeatures { - - public static final Map ENTRIES = new HashMap<>(); - - private static final BiomeFilter OVERWORLD_BIOMES = - (r, b) -> b != BiomeCategory.NETHER && b != BiomeCategory.THEEND && b != BiomeCategory.NONE; - - private static final BiomeFilter NETHER_BIOMES = (r, b) -> b == BiomeCategory.NETHER; - - // - - public static final ConfigDrivenFeatureEntry ZINC_ORE = - register("zinc_ore", 12, 8, OVERWORLD_BIOMES).between(-63, 70) - .withBlocks(Couple.create(AllBlocks.ZINC_ORE, AllBlocks.DEEPSLATE_ZINC_ORE)); - - public static final ConfigDrivenFeatureEntry STRIATED_ORES_OVERWORLD = - register("striated_ores_overworld", 32, 1 / 12f, OVERWORLD_BIOMES).between(-30, 70) - .withLayerPattern(AllLayerPatterns.SCORIA) - .withLayerPattern(AllLayerPatterns.CINNABAR) - .withLayerPattern(AllLayerPatterns.MAGNETITE) - .withLayerPattern(AllLayerPatterns.MALACHITE) - .withLayerPattern(AllLayerPatterns.LIMESTONE) - .withLayerPattern(AllLayerPatterns.OCHRESTONE); - - public static final ConfigDrivenFeatureEntry STRIATED_ORES_NETHER = - register("striated_ores_nether", 32, 1 / 12f, NETHER_BIOMES).between(40, 90) - .withLayerPattern(AllLayerPatterns.SCORIA_NETHER) - .withLayerPattern(AllLayerPatterns.SCORCHIA_NETHER); - - // - - private static ConfigDrivenFeatureEntry register(String id, int clusterSize, float frequency, - BiomeFilter biomeFilter) { - ConfigDrivenFeatureEntry configDrivenFeatureEntry = new ConfigDrivenFeatureEntry(id, clusterSize, frequency); - configDrivenFeatureEntry.biomeFilter = biomeFilter; - ENTRIES.put(Create.asResource(id), configDrivenFeatureEntry); - return configDrivenFeatureEntry; - } - - /** - * Increment this number if all worldgen 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 forcedUpdateVersion = 2; - - public static void registerFeatures() { - ENTRIES.entrySet() - .forEach(entry -> { - String id = Create.ID + "_" + entry.getKey() - .getPath(); - ConfigDrivenFeatureEntry featureEntry = entry.getValue(); - featureEntry.configuredFeature = BuiltinRegistries.register(BuiltinRegistries.CONFIGURED_FEATURE, id, - featureEntry.factory.apply(featureEntry)); - featureEntry.placedFeature = - BuiltinRegistries.register(BuiltinRegistries.PLACED_FEATURE, id, new PlacedFeature( - featureEntry.configuredFeature, ImmutableList.of(new ConfigDrivenDecorator(featureEntry.id)))); - }); - } - - public static void reload(BiomeLoadingEvent event) { - BiomeGenerationSettingsBuilder generation = event.getGeneration(); - Decoration decoStep = GenerationStep.Decoration.UNDERGROUND_ORES; - ENTRIES.values() - .forEach(entry -> { - ConfigDrivenFeatureEntry value = entry; - if (value.biomeFilter.test(event.getName(), event.getCategory())) - generation.addFeature(decoStep, value.placedFeature); - }); - } - - public static void fillConfig(ForgeConfigSpec.Builder builder) { - ENTRIES.values() - .forEach(entry -> { - builder.push(entry.id); - entry.addToConfig(builder); - builder.pop(); - }); - } - - public static void register() {} - - public static void registerOreFeatures(RegistryEvent.Register> event) { - event.getRegistry() - .registerAll(VanillaStyleOreFeature.INSTANCE, LayeredOreFeature.INSTANCE); - } - - public static void registerPlacementTypes() { - ConfigDrivenDecorator.TYPE = - Registry.register(Registry.PLACEMENT_MODIFIERS, "create_config_driven", () -> ConfigDrivenDecorator.CODEC); - } - -} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/OreFeatureBase.java b/src/main/java/com/simibubi/create/foundation/worldgen/BaseConfigDrivenOreFeature.java similarity index 65% rename from src/main/java/com/simibubi/create/foundation/worldgen/OreFeatureBase.java rename to src/main/java/com/simibubi/create/foundation/worldgen/BaseConfigDrivenOreFeature.java index c886cd155..b55d2eea6 100644 --- a/src/main/java/com/simibubi/create/foundation/worldgen/OreFeatureBase.java +++ b/src/main/java/com/simibubi/create/foundation/worldgen/BaseConfigDrivenOreFeature.java @@ -3,23 +3,24 @@ package com.simibubi.create.foundation.worldgen; import java.util.Random; import java.util.function.Function; +import com.mojang.serialization.Codec; + import net.minecraft.core.BlockPos; 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 OreFeatureBase extends Feature { - - public OreFeatureBase() { - super(ConfigDrivenOreConfiguration.CODEC); +public abstract class BaseConfigDrivenOreFeature extends Feature { + public BaseConfigDrivenOreFeature(Codec configCodec) { + super(configCodec); } public boolean canPlaceOre(BlockState pState, Function pAdjacentStateAccessor, - Random pRandom, ConfigDrivenOreConfiguration pConfig, OreConfiguration.TargetBlockState pTargetState, + Random pRandom, BaseConfigDrivenOreFeatureConfiguration pConfig, OreConfiguration.TargetBlockState pTargetState, BlockPos.MutableBlockPos pMatablePos) { if (!pTargetState.target.test(pState, pRandom)) return false; - if (shouldSkipAirCheck(pRandom, pConfig.discardChanceOnAirExposure)) + if (shouldSkipAirCheck(pRandom, pConfig.getDiscardChanceOnAirExposure())) return true; return !isAdjacentToAir(pAdjacentStateAccessor, pMatablePos); diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/BaseConfigDrivenOreFeatureConfiguration.java b/src/main/java/com/simibubi/create/foundation/worldgen/BaseConfigDrivenOreFeatureConfiguration.java new file mode 100644 index 000000000..1c741236f --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/worldgen/BaseConfigDrivenOreFeatureConfiguration.java @@ -0,0 +1,25 @@ +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; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/BiomeFilter.java b/src/main/java/com/simibubi/create/foundation/worldgen/BiomeFilter.java deleted file mode 100644 index b3cd9e2c9..000000000 --- a/src/main/java/com/simibubi/create/foundation/worldgen/BiomeFilter.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.simibubi.create.foundation.worldgen; - -import java.util.function.BiPredicate; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome.BiomeCategory; - -public interface BiomeFilter extends BiPredicate { - -} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/BuiltinRegistration.java b/src/main/java/com/simibubi/create/foundation/worldgen/BuiltinRegistration.java new file mode 100644 index 000000000..df332d2a0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/worldgen/BuiltinRegistration.java @@ -0,0 +1,36 @@ +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.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.levelgen.placement.PlacedFeature; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; + +public class BuiltinRegistration { + private static final DeferredRegister> CONFIGURED_FEATURE_REGISTER = DeferredRegister.create(Registry.CONFIGURED_FEATURE_REGISTRY, Create.ID); + private static final DeferredRegister PLACED_FEATURE_REGISTER = DeferredRegister.create(Registry.PLACED_FEATURE_REGISTRY, Create.ID); + + static { + for (Map.Entry 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.getConfiguredFeature()); + PLACED_FEATURE_REGISTER.register(id.getPath(), () -> datagenExt.getPlacedFeature()); + } + } + } + } + + public static void register(IEventBus modEventBus) { + CONFIGURED_FEATURE_REGISTER.register(modEventBus); + PLACED_FEATURE_REGISTER.register(modEventBus); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenDecorator.java b/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenDecorator.java deleted file mode 100644 index a1af6270d..000000000 --- a/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenDecorator.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.simibubi.create.foundation.worldgen; - -import java.util.Random; -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.Create; - -import net.minecraft.core.BlockPos; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; -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 ConfigDrivenDecorator extends PlacementModifier { - - public static PlacementModifierType TYPE; - - public static final Codec CODEC = RecordCodecBuilder.create((p_67849_) -> { - return p_67849_.group(Codec.STRING.fieldOf("key") - .forGetter(t -> t.key.getPath())) - .apply(p_67849_, ConfigDrivenDecorator::new); - }); - - private ResourceLocation key; - - public ConfigDrivenDecorator(String key) { - this.key = Create.asResource(key); - } - - @Override - public PlacementModifierType type() { - return TYPE; - } - - @Override - public Stream getPositions(PlacementContext context, Random random, BlockPos pos) { - ConfigDrivenOreConfiguration config = (ConfigDrivenOreConfiguration) entry().configuredFeature.value() - .config(); - - float frequency = config.getFrequency(); - int floored = Mth.floor(frequency); - int count = floored + (random.nextFloat() < frequency - floored ? 1 : 0); - if (count == 0) - return Stream.empty(); - - int maxY = config.getMaxY(); - int minY = config.getMinY(); - - return IntStream.range(0, count) - .mapToObj($ -> pos) - .map(p -> { - int i = p.getX(); - int j = p.getZ(); - int k = random.nextInt(maxY - minY) + minY; - return new BlockPos(i, k, j); - }); - } - - protected ConfigDrivenFeatureEntry entry() { - return AllWorldFeatures.ENTRIES.get(key); - } - -} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenFeatureEntry.java b/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenFeatureEntry.java deleted file mode 100644 index b2b87db7c..000000000 --- a/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenFeatureEntry.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.simibubi.create.foundation.worldgen; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; - -import com.google.common.collect.ImmutableList; -import com.simibubi.create.Create; -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.data.worldgen.features.OreFeatures; -import net.minecraft.world.level.block.Block; -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; - -public class ConfigDrivenFeatureEntry extends ConfigBase { - - public final String id; - public BiomeFilter biomeFilter; - - private NonNullSupplier block; - private NonNullSupplier deepblock; - private NonNullSupplier netherblock; - - private List> layers = new ArrayList<>(); - - protected ConfigInt clusterSize; - protected ConfigInt minHeight; - protected ConfigInt maxHeight; - protected ConfigFloat frequency; - - Function> factory; - Holder> configuredFeature; - Holder placedFeature; - - public ConfigDrivenFeatureEntry(String id, int clusterSize, float frequency) { - this.id = id; - this.factory = this::standardFactory; - this.clusterSize = i(clusterSize, 0, "clusterSize"); - this.minHeight = i(0, 0, "minHeight"); - this.maxHeight = i(256, 0, "maxHeight"); - 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."); - } - - public ConfigDrivenFeatureEntry withLayerPattern(NonNullSupplier pattern) { - this.layers.add(pattern); - this.factory = this::layersFactory; - return this; - } - - public ConfigDrivenFeatureEntry withBlock(NonNullSupplier block) { - this.block = this.deepblock = block; - return this; - } - - public ConfigDrivenFeatureEntry withNetherBlock(NonNullSupplier block) { - this.netherblock = block; - return this; - } - - public ConfigDrivenFeatureEntry withBlocks(Couple> blocks) { - this.block = blocks.getFirst(); - this.deepblock = blocks.getSecond(); - return this; - } - - public ConfigDrivenFeatureEntry between(int minHeight, int maxHeight) { - allValues.remove(this.minHeight); - allValues.remove(this.maxHeight); - this.minHeight = i(minHeight, -64, "minHeight"); - this.maxHeight = i(maxHeight, -64, "maxHeight"); - return this; - } - - private ConfiguredFeature layersFactory(ConfigDrivenFeatureEntry entry) { - ConfigDrivenOreConfiguration config = new ConfigDrivenOreConfiguration(ImmutableList.of(), 0, id); - LayeredOreFeature.LAYER_PATTERNS.put(Create.asResource(id), layers.stream() - .map(NonNullSupplier::get) - .toList()); - return new ConfiguredFeature<>(LayeredOreFeature.INSTANCE, config); - } - - private ConfiguredFeature standardFactory(ConfigDrivenFeatureEntry entry) { - ConfigDrivenOreConfiguration config = new ConfigDrivenOreConfiguration(createTarget(), 0, id); - return new ConfiguredFeature<>(VanillaStyleOreFeature.INSTANCE, config); - } - - private List createTarget() { - List list = new ArrayList<>(); - if (block != null) - list.add(OreConfiguration.target(OreFeatures.STONE_ORE_REPLACEABLES, block.get() - .defaultBlockState())); - if (deepblock != null) - list.add(OreConfiguration.target(OreFeatures.DEEPSLATE_ORE_REPLACEABLES, deepblock.get() - .defaultBlockState())); - if (netherblock != null) - list.add(OreConfiguration.target(OreFeatures.NETHER_ORE_REPLACEABLES, netherblock.get() - .defaultBlockState())); - return list; - } - - public void addToConfig(ForgeConfigSpec.Builder builder) { - registerAll(builder); - } - - @Override - public String getName() { - return id; - } - -} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenLayeredOreFeatureConfiguration.java b/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenLayeredOreFeatureConfiguration.java new file mode 100644 index 000000000..4066b20b3 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenLayeredOreFeatureConfiguration.java @@ -0,0 +1,33 @@ +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 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 layerPatterns; + + public ConfigDrivenLayeredOreFeatureConfiguration(OreFeatureConfigEntry entry, float discardChance, List layerPatterns) { + super(entry, discardChance); + this.layerPatterns = layerPatterns; + } + + public List getLayerPatterns() { + return layerPatterns; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenOreConfiguration.java b/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenOreConfiguration.java deleted file mode 100644 index 7c567861f..000000000 --- a/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenOreConfiguration.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.simibubi.create.foundation.worldgen; - -import java.util.List; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import com.simibubi.create.Create; -import com.simibubi.create.foundation.config.AllConfigs; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration; -import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration.TargetBlockState; - -public class ConfigDrivenOreConfiguration implements FeatureConfiguration { - - public static final Codec CODEC = RecordCodecBuilder.create((p_67849_) -> { - return p_67849_.group(Codec.list(TargetBlockState.CODEC) - .fieldOf("targets") - .forGetter((p_161027_) -> { - return p_161027_.targetStates; - }), Codec.floatRange(0.0F, 1.0F) - .fieldOf("discard_chance_on_air_exposure") - .forGetter((p_161020_) -> { - return p_161020_.discardChanceOnAirExposure; - }), - Codec.STRING.fieldOf("key") - .forGetter(t -> t.key.getPath())) - .apply(p_67849_, ConfigDrivenOreConfiguration::new); - }); - - public final List targetStates; - public final float discardChanceOnAirExposure; - public final ResourceLocation key; - - public ConfigDrivenOreConfiguration(List targetStates, float discardChance, String key) { - this.targetStates = targetStates; - this.discardChanceOnAirExposure = discardChance; - this.key = Create.asResource(key); - } - - public int getSize() { - return entry().clusterSize.get(); - } - - public int getMinY() { - return entry().minHeight.get(); - } - - public int getMaxY() { - return entry().maxHeight.get(); - } - - public List getLayers() { - return LayeredOreFeature.LAYER_PATTERNS.get(key); - } - - public float getFrequency() { - if (AllConfigs.COMMON.worldGen.disable.get()) - return 0; - return entry().frequency.getF(); - } - - protected ConfigDrivenFeatureEntry entry() { - return AllWorldFeatures.ENTRIES.get(key); - } - -} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenOreFeatureConfiguration.java b/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenOreFeatureConfiguration.java new file mode 100644 index 000000000..d554cc139 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenOreFeatureConfiguration.java @@ -0,0 +1,35 @@ +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 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 targetStates; + + public ConfigDrivenOreFeatureConfiguration(OreFeatureConfigEntry entry, float discardChance, List targetStates) { + super(entry, discardChance); + this.targetStates = targetStates; + } + + public List getTargetStates() { + return targetStates; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenPlacement.java b/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenPlacement.java new file mode 100644 index 000000000..858f53930 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenPlacement.java @@ -0,0 +1,79 @@ +package com.simibubi.create.foundation.worldgen; + +import java.util.Random; +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.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 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 getPositions(PlacementContext context, Random 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, Random 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(); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/LayerPattern.java b/src/main/java/com/simibubi/create/foundation/worldgen/LayerPattern.java index 71ad7fd2e..dc4a53d1e 100644 --- a/src/main/java/com/simibubi/create/foundation/worldgen/LayerPattern.java +++ b/src/main/java/com/simibubi/create/foundation/worldgen/LayerPattern.java @@ -7,8 +7,9 @@ import java.util.Random; import javax.annotation.Nullable; import com.google.common.collect.ImmutableList; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import com.simibubi.create.foundation.utility.Couple; -import com.simibubi.create.foundation.worldgen.LayerPattern.Layer.LayerBuilder; import com.tterrag.registrate.util.nullness.NonNullSupplier; import net.minecraft.data.worldgen.features.OreFeatures; @@ -20,16 +21,13 @@ import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguratio import net.minecraftforge.common.util.NonNullConsumer; public class LayerPattern { + public static final Codec CODEC = Codec.list(Layer.CODEC) + .xmap(LayerPattern::new, pattern -> pattern.layers); - List layers; + public final List layers; - public LayerPattern() { - layers = new ArrayList<>(); - } - - public static Builder builder() { - LayerPattern ore = new LayerPattern(); - return ore.new Builder(); + public LayerPattern(List layers) { + this.layers = layers; } public Layer rollNext(@Nullable Layer previous, Random random) { @@ -49,42 +47,60 @@ public class LayerPattern { return null; } - class Builder { - + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private final List layers = new ArrayList<>(); private boolean netherMode; - public LayerPattern build() { - return LayerPattern.this; - } - public Builder inNether() { netherMode = true; return this; } - public Builder layer(NonNullConsumer builder) { - Layer layer = new Layer(); - LayerBuilder layerBuilder = layer.new LayerBuilder(); + public Builder layer(NonNullConsumer builder) { + Layer.Builder layerBuilder = new Layer.Builder(); layerBuilder.netherMode = netherMode; builder.accept(layerBuilder); layers.add(layerBuilder.build()); return this; } + public LayerPattern build() { + return new LayerPattern(layers); + } } - static class Layer { + public static class Layer { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> { + return instance.group( + Codec.list(Codec.list(TargetBlockState.CODEC)) + .fieldOf("targets") + .forGetter(layer -> layer.targets), + Codec.intRange(0, Integer.MAX_VALUE) + .fieldOf("min_size") + .forGetter(layer -> layer.minSize), + Codec.intRange(0, Integer.MAX_VALUE) + .fieldOf("max_size") + .forGetter(layer -> layer.maxSize), + Codec.intRange(0, Integer.MAX_VALUE) + .fieldOf("weight") + .forGetter(layer -> layer.weight) + ).apply(instance, Layer::new); + }); - public List> targets; - public int minSize; - public int maxSize; - public int weight; + public final List> targets; + public final int minSize; + public final int maxSize; + public final int weight; - public Layer() { - this.targets = new ArrayList<>(); - this.minSize = 1; - this.maxSize = 1; - this.weight = 1; + public Layer(List> targets, int minSize, int maxSize, int weight) { + this.targets = targets; + this.minSize = minSize; + this.maxSize = maxSize; + this.weight = weight; } public List rollBlock(Random random) { @@ -93,36 +109,35 @@ public class LayerPattern { return targets.get(random.nextInt(targets.size())); } - class LayerBuilder { - + public static class Builder { + private final List> targets = new ArrayList<>(); + private int minSize = 1; + private int maxSize = 1; + private int weight = 1; private boolean netherMode; - private Layer build() { - return Layer.this; - } - - public LayerBuilder block(NonNullSupplier block) { + public Builder block(NonNullSupplier block) { return block(block.get()); } - public LayerBuilder passiveBlock() { + public Builder passiveBlock() { return blocks(Blocks.STONE.defaultBlockState(), Blocks.DEEPSLATE.defaultBlockState()); } - public LayerBuilder block(Block block) { + public Builder block(Block block) { if (netherMode) { - Layer.this.targets.add(ImmutableList.of(OreConfiguration + this.targets.add(ImmutableList.of(OreConfiguration .target(OreFeatures.NETHER_ORE_REPLACEABLES, block.defaultBlockState()))); return this; } return blocks(block.defaultBlockState(), block.defaultBlockState()); } - public LayerBuilder blocks(Block block, Block deepblock) { + public Builder blocks(Block block, Block deepblock) { return blocks(block.defaultBlockState(), deepblock.defaultBlockState()); } - public LayerBuilder blocks(Couple> blocksByDepth) { + public Builder blocks(Couple> blocksByDepth) { return blocks(blocksByDepth.getFirst() .get() .defaultBlockState(), @@ -131,26 +146,27 @@ public class LayerPattern { .defaultBlockState()); } - private LayerBuilder blocks(BlockState stone, BlockState deepslate) { - Layer.this.targets.add( + 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))); return this; } - public LayerBuilder weight(int weight) { - Layer.this.weight = weight; + public Builder weight(int weight) { + this.weight = weight; return this; } - public LayerBuilder size(int min, int max) { - Layer.this.minSize = min; - Layer.this.maxSize = max; + public Builder size(int min, int max) { + this.minSize = min; + this.maxSize = max; return this; } + public Layer build() { + return new Layer(targets, minSize, maxSize, weight); + } } - } - } diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/LayeredOreFeature.java b/src/main/java/com/simibubi/create/foundation/worldgen/LayeredOreFeature.java index 36ccebded..00b1ca89e 100644 --- a/src/main/java/com/simibubi/create/foundation/worldgen/LayeredOreFeature.java +++ b/src/main/java/com/simibubi/create/foundation/worldgen/LayeredOreFeature.java @@ -1,9 +1,7 @@ package com.simibubi.create.foundation.worldgen; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Random; import com.simibubi.create.foundation.worldgen.LayerPattern.Layer; @@ -11,7 +9,6 @@ import com.simibubi.create.foundation.worldgen.LayerPattern.Layer; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; import net.minecraft.core.SectionPos; -import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.block.state.BlockState; @@ -22,23 +19,18 @@ 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 OreFeatureBase { - - public static final Map> LAYER_PATTERNS = new HashMap<>(); - - public static final LayeredOreFeature INSTANCE = new LayeredOreFeature(); - +public class LayeredOreFeature extends BaseConfigDrivenOreFeature { public LayeredOreFeature() { - setRegistryName("config_driven_layered_ore"); + super(ConfigDrivenLayeredOreFeatureConfiguration.CODEC); } - public boolean place(FeaturePlaceContext pContext) { - + @Override + public boolean place(FeaturePlaceContext pContext) { Random random = pContext.random(); BlockPos blockpos = pContext.origin(); WorldGenLevel worldgenlevel = pContext.level(); - ConfigDrivenOreConfiguration config = pContext.config(); - List patternPool = config.getLayers(); + ConfigDrivenLayeredOreFeatureConfiguration config = pContext.config(); + List patternPool = config.getLayerPatterns(); if (patternPool.isEmpty()) return false; @@ -46,8 +38,8 @@ public class LayeredOreFeature extends OreFeatureBase { LayerPattern layerPattern = patternPool.get(random.nextInt(patternPool.size())); int placedAmount = 0; - int size = config.getSize(); - int radius = Mth.ceil(config.getSize() / 2f); + int size = config.getClusterSize(); + int radius = Mth.ceil(config.getClusterSize() / 2f); int x0 = blockpos.getX() - radius; int y0 = blockpos.getY() - radius; int z0 = blockpos.getZ() - radius; @@ -150,5 +142,4 @@ public class LayeredOreFeature extends OreFeatureBase { bulksectionaccess.close(); return placedAmount > 0; } - } diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/OreFeatureConfigEntry.java b/src/main/java/com/simibubi/create/foundation/worldgen/OreFeatureConfigEntry.java new file mode 100644 index 000000000..0ef2b7582 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/worldgen/OreFeatureConfigEntry.java @@ -0,0 +1,233 @@ +package com.simibubi.create.foundation.worldgen; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; + +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.Registry; +import net.minecraft.data.worldgen.features.OreFeatures; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.levelgen.GenerationStep; +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.event.world.BiomeLoadingEvent; + +public class OreFeatureConfigEntry extends ConfigBase { + public static final Map ALL = new HashMap<>(); + + public static final Codec 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 BiomeExtension biomeExt; + 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); + } + + public BiomeExtension biomeExt() { + if (biomeExt == null) { + biomeExt = new BiomeExtension(); + } + return biomeExt; + } + + @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 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 class BiomeExtension { + public ResourceLocation placedFeatureLocation = id; + public Predicate biomePredicate = e -> false; + + public BiomeExtension feature(ResourceLocation placedFeature) { + this.placedFeatureLocation = placedFeature; + return this; + } + + public BiomeExtension predicate(Predicate predicate) { + this.biomePredicate = predicate; + return this; + } + + public void modifyBiomes(BiomeLoadingEvent event, Registry registry) { + if (biomePredicate.test(event)) { + Optional> optionalFeature = registry.getHolder(ResourceKey.create(Registry.PLACED_FEATURE_REGISTRY, placedFeatureLocation)); + if (optionalFeature.isPresent()) { + event.getGeneration().addFeature(GenerationStep.Decoration.UNDERGROUND_ORES, optionalFeature.get()); + } + } + } + + public OreFeatureConfigEntry parent() { + return OreFeatureConfigEntry.this; + } + } + + public abstract class DatagenExtension { + protected ConfiguredFeature configuredFeature; + protected PlacedFeature placedFeature; + + public abstract ConfiguredFeature getConfiguredFeature(); + + public PlacedFeature getPlacedFeature() { + if (placedFeature != null) { + return placedFeature; + } + + placedFeature = new PlacedFeature(Holder.direct(getConfiguredFeature()), List.of(new ConfigDrivenPlacement(OreFeatureConfigEntry.this))); + + return placedFeature; + } + + public OreFeatureConfigEntry parent() { + return OreFeatureConfigEntry.this; + } + } + + public class StandardDatagenExtension extends DatagenExtension { + public NonNullSupplier block; + public NonNullSupplier deepBlock; + public NonNullSupplier netherBlock; + + public StandardDatagenExtension withBlock(NonNullSupplier block) { + this.block = block; + this.deepBlock = block; + return this; + } + + public StandardDatagenExtension withBlocks(Couple> blocks) { + this.block = blocks.getFirst(); + this.deepBlock = blocks.getSecond(); + return this; + } + + public StandardDatagenExtension withNetherBlock(NonNullSupplier block) { + this.netherBlock = block; + return this; + } + + @Override + public ConfiguredFeature getConfiguredFeature() { + if (configuredFeature != null) { + return configuredFeature; + } + + List 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); + configuredFeature = new ConfiguredFeature<>(AllFeatures.STANDARD_ORE.get(), config); + + return configuredFeature; + } + } + + public class LayeredDatagenExtension extends DatagenExtension { + public final List> layerPatterns = new ArrayList<>(); + + public LayeredDatagenExtension withLayerPattern(NonNullSupplier pattern) { + this.layerPatterns.add(pattern); + return this; + } + + @Override + public ConfiguredFeature getConfiguredFeature() { + if (configuredFeature != null) { + return configuredFeature; + } + + List layerPatterns = this.layerPatterns.stream() + .map(NonNullSupplier::get) + .toList(); + + ConfigDrivenLayeredOreFeatureConfiguration config = new ConfigDrivenLayeredOreFeatureConfiguration(OreFeatureConfigEntry.this, 0, layerPatterns); + configuredFeature = new ConfiguredFeature<>(AllFeatures.LAYERED_ORE.get(), config); + + return configuredFeature; + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/StandardOreFeature.java b/src/main/java/com/simibubi/create/foundation/worldgen/StandardOreFeature.java new file mode 100644 index 000000000..58749166d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/worldgen/StandardOreFeature.java @@ -0,0 +1,168 @@ +package com.simibubi.create.foundation.worldgen; + +import java.util.BitSet; +import java.util.Random; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.SectionPos; +import net.minecraft.util.Mth; +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 { + + public StandardOreFeature() { + super(ConfigDrivenOreFeatureConfiguration.CODEC); + } + + // From OreFeature, slight adjustments + + @Override + public boolean place(FeaturePlaceContext pContext) { + Random 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, Random 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; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/worldgen/VanillaStyleOreFeature.java b/src/main/java/com/simibubi/create/foundation/worldgen/VanillaStyleOreFeature.java deleted file mode 100644 index 011ccda9d..000000000 --- a/src/main/java/com/simibubi/create/foundation/worldgen/VanillaStyleOreFeature.java +++ /dev/null @@ -1,176 +0,0 @@ -package com.simibubi.create.foundation.worldgen; - -import java.util.BitSet; -import java.util.Random; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.SectionPos; -import net.minecraft.util.Mth; -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 VanillaStyleOreFeature extends OreFeatureBase { - - public static final VanillaStyleOreFeature INSTANCE = new VanillaStyleOreFeature(); - - public VanillaStyleOreFeature() { - setRegistryName("config_driven_ore"); - } - - // From OreFeature, slight adjustments - - public boolean place(FeaturePlaceContext pContext) { - - Random random = pContext.random(); - BlockPos blockpos = pContext.origin(); - WorldGenLevel worldgenlevel = pContext.level(); - ConfigDrivenOreConfiguration oreconfiguration = pContext.config(); - - float f = random.nextFloat() * (float) Math.PI; - float diameter = (float) oreconfiguration.getSize() / 8.0F; - int centeringOffset = Mth.ceil(((float) oreconfiguration.getSize() / 8.0F + 1.0F) / 2.0F); - double d0 = blockpos.getX() + Math.sin(f) * diameter; - double d1 = blockpos.getX() - Math.sin(f) * diameter; - double d2 = blockpos.getZ() + Math.cos(f) * diameter; - double d3 = blockpos.getZ() - Math.cos(f) * diameter; - double d4 = (blockpos.getY() + random.nextInt(3) - 2); - double d5 = (blockpos.getY() + random.nextInt(3) - 2); - int k = blockpos.getX() - Mth.ceil(diameter) - centeringOffset; - int l = blockpos.getY() - 2 - centeringOffset; - int i1 = blockpos.getZ() - Mth.ceil(diameter) - centeringOffset; - int j1 = 2 * (Mth.ceil(diameter) + centeringOffset); - int k1 = 2 * (2 + centeringOffset); - - for (int x = k; x <= k + j1; ++x) - for (int z = i1; z <= i1 + j1; ++z) - if (l <= worldgenlevel.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, x, z)) - return this.doPlace(worldgenlevel, random, oreconfiguration, d0, d1, d2, d3, d4, d5, k, l, i1, j1, - k1); - - return false; - } - - protected boolean doPlace(WorldGenLevel pLevel, Random pRandom, ConfigDrivenOreConfiguration 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.getSize(); - double[] adouble = new double[j * 4]; - - for (int k = 0; k < j; ++k) { - float f = (float) k / (float) j; - double d0 = Mth.lerp(f, pMinX, pMaxX); - double d1 = Mth.lerp(f, pMinY, pMaxY); - double d2 = Mth.lerp(f, pMinZ, pMaxZ); - double d3 = pRandom.nextDouble() * j / 16.0D; - double d4 = ((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) - continue; - for (int i4 = l3 + 1; i4 < j; ++i4) { - if (adouble[i4 * 4 + 3] <= 0.0D) - continue; - - 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) - continue; - - 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) - continue; - - 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 = (i2 + 0.5D - d11) / d9; - if (d5 * d5 >= 1.0D) - continue; - for (int j2 = l; j2 <= k1; ++j2) { - double d6 = (j2 + 0.5D - d13) / d9; - if (d5 * d5 + d6 * d6 >= 1.0D) - continue; - for (int k2 = i1; k2 <= l1; ++k2) { - double d7 = (k2 + 0.5D - d15) / d9; - if (d5 * d5 + d6 * d6 + d7 * d7 >= 1.0D || pLevel.isOutsideBuildHeight(j2)) - continue; - - int l2 = i2 - pX + (j2 - pY) * pWidth + (k2 - pZ) * pWidth * pHeight; - if (bitset.get(l2)) - continue; - bitset.set(l2); - blockpos$mutableblockpos.set(i2, j2, k2); - if (!pLevel.ensureCanWrite(blockpos$mutableblockpos)) - continue; - LevelChunkSection levelchunksection = - bulksectionaccess.getSection(blockpos$mutableblockpos); - if (levelchunksection == null) - continue; - 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.targetStates) { - if (!canPlaceOre(blockstate, bulksectionaccess::getBlockState, pRandom, pConfig, - oreconfiguration$targetblockstate, blockpos$mutableblockpos)) - continue; - 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; - } - -}