Defer registration, datagen worldgen
- Use DeferredRegister/RegistryObject where possible - Refactor worldgen code to be cleaner and support datagen - Fix zinc ore only generating on chunk corners - Remove fan_heaters block tag
This commit is contained in:
parent
ded8667ae8
commit
42ffe443ac
39 changed files with 1204 additions and 847 deletions
|
@ -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
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"create:blaze_burner",
|
||||
"create:lit_blaze_burner",
|
||||
"#minecraft:fire",
|
||||
"#minecraft:campfires",
|
||||
"minecraft:magma_block",
|
||||
"minecraft:lava"
|
||||
]
|
||||
}
|
|
@ -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"
|
||||
]
|
||||
}
|
|
@ -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()
|
||||
|
|
|
@ -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<DataSerializerEntry> REGISTER = DeferredRegister.create(ForgeRegistries.Keys.DATA_SERIALIZERS, Create.ID);
|
||||
|
||||
public static final CarriageSyncDataSerializer CARRIAGE_DATA = new CarriageSyncDataSerializer();
|
||||
|
||||
public static void register(RegistryEvent.Register<DataSerializerEntry> event) {
|
||||
IForgeRegistry<DataSerializerEntry> registry = event.getRegistry();
|
||||
registry.register(new DataSerializerEntry(CARRIAGE_DATA).setRegistryName(Create.asResource("carriage_data")));
|
||||
}
|
||||
public static final RegistryObject<DataSerializerEntry> CARRIAGE_DATA_ENTRY = REGISTER.register("carriage_data", () -> new DataSerializerEntry(CARRIAGE_DATA));
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
REGISTER.register(modEventBus);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
<D extends ParticleOptions> AllParticleTypes(Supplier<? extends ICustomParticleData<D>> 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<ParticleType<?>> 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<D extends ParticleOptions> {
|
||||
Supplier<? extends ICustomParticleData<D>> typeFactory;
|
||||
ParticleType<D> type;
|
||||
ResourceLocation id;
|
||||
private static class ParticleEntry<D extends ParticleOptions> {
|
||||
private static final DeferredRegister<ParticleType<?>> REGISTER = DeferredRegister.create(ForgeRegistries.PARTICLE_TYPES, Create.ID);
|
||||
|
||||
public ParticleEntry(ResourceLocation id, Supplier<? extends ICustomParticleData<D>> typeFactory) {
|
||||
this.id = id;
|
||||
private final String name;
|
||||
private final Supplier<? extends ICustomParticleData<D>> typeFactory;
|
||||
private final RegistryObject<ParticleType<D>> object;
|
||||
|
||||
public ParticleEntry(String name, Supplier<? extends ICustomParticleData<D>> typeFactory) {
|
||||
this.name = name;
|
||||
this.typeFactory = typeFactory;
|
||||
}
|
||||
|
||||
void register(IForgeRegistry<ParticleType<?>> registry) {
|
||||
registry.register(getOrCreateType());
|
||||
}
|
||||
|
||||
ParticleType<D> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<RecipeSerializer<?>> serializerObject;
|
||||
@Nullable
|
||||
private final RegistryObject<RecipeType<?>> typeObject;
|
||||
private final Supplier<RecipeType<?>> type;
|
||||
|
||||
private ResourceLocation id;
|
||||
private Supplier<RecipeSerializer<?>> serializerSupplier;
|
||||
private Supplier<RecipeType<?>> typeSupplier;
|
||||
private RecipeSerializer<?> serializer;
|
||||
private RecipeType<?> type;
|
||||
|
||||
AllRecipeTypes(Supplier<RecipeSerializer<?>> serializerSupplier, Supplier<RecipeType<?>> typeSupplier) {
|
||||
this.id = Create.asResource(Lang.asId(name()));
|
||||
this.serializerSupplier = serializerSupplier;
|
||||
this.typeSupplier = typeSupplier;
|
||||
AllRecipeTypes(Supplier<RecipeSerializer<?>> serializerSupplier, Supplier<RecipeType<?>> 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<RecipeSerializer<?>> serializerSupplier, RecipeType<?> existingType) {
|
||||
this(serializerSupplier, () -> existingType);
|
||||
}
|
||||
|
||||
AllRecipeTypes(Supplier<RecipeSerializer<?>> 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 <T extends Recipe<?>> RecipeType<T> simpleType(ResourceLocation id) {
|
||||
String stringId = id.toString();
|
||||
return new RecipeType<T>() {
|
||||
@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 extends RecipeSerializer<?>> T getSerializer() {
|
||||
return (T) serializer;
|
||||
return (T) serializerObject.get();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends RecipeType<?>> T getType() {
|
||||
return (T) type;
|
||||
return (T) type.get();
|
||||
}
|
||||
|
||||
public <C extends Container, T extends Recipe<C>> Optional<T> find(C inv, Level world) {
|
||||
|
@ -113,32 +137,6 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
|
|||
.getRecipeFor(getType(), inv, world);
|
||||
}
|
||||
|
||||
public static void register(RegistryEvent.Register<RecipeSerializer<?>> 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<RecipeSerializer<?>> processingSerializer(ProcessingRecipeFactory<?> factory) {
|
||||
return () -> new ProcessingRecipeSerializer<>(factory);
|
||||
}
|
||||
|
||||
public static <T extends Recipe<?>> RecipeType<T> simpleType(ResourceLocation id) {
|
||||
String stringId = id.toString();
|
||||
return Registry.register(Registry.RECIPE_TYPE, id, new RecipeType<T>() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return stringId;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static final Set<ResourceLocation> 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<RecipeSerializer<?>> SERIALIZER_REGISTER = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, Create.ID);
|
||||
private static final DeferredRegister<RecipeType<?>> TYPE_REGISTER = DeferredRegister.create(Registry.RECIPE_TYPE_REGISTRY, Create.ID);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<ResourceLocation, SoundEntry> entries = new HashMap<>();
|
||||
public static final Map<ResourceLocation, SoundEntry> 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<SoundEvent> event) {
|
||||
IForgeRegistry<SoundEvent> 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<SoundEvent> event) {
|
||||
IForgeRegistry<SoundEvent> 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<SoundEvent> event, float volume, float pitch) {
|
||||
}
|
||||
|
||||
public static class SoundEntryBuilder {
|
||||
|
||||
protected ResourceLocation id;
|
||||
protected String subtitle = "unregistered";
|
||||
protected SoundSource category = SoundSource.BLOCKS;
|
||||
protected List<Pair<SoundEvent, Couple<Float>>> wrappedEvents;
|
||||
protected List<ConfiguredSoundEvent> wrappedEvents;
|
||||
protected List<ResourceLocation> 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<SoundEvent> 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<Pair<SoundEvent, Couple<Float>>> wrappedEvents;
|
||||
private List<Pair<SoundEvent, Couple<Float>>> compiledEvents;
|
||||
private List<ConfiguredSoundEvent> wrappedEvents;
|
||||
private List<CompiledSoundEvent> compiledEvents;
|
||||
|
||||
public WrappedSoundEntry(ResourceLocation id, String subtitle,
|
||||
List<Pair<SoundEvent, Couple<Float>>> wrappedEvents, SoundSource category, int attenuationDistance) {
|
||||
List<ConfiguredSoundEvent> 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<SoundEvent> event = RegistryObject.create(location, ForgeRegistries.SOUND_EVENTS);
|
||||
compiledEvents.add(new CompiledSoundEvent(event, wrapped.volume(), wrapped.pitch()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(IForgeRegistry<SoundEvent> registry) {
|
||||
for (Pair<SoundEvent, Couple<Float>> 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<SoundEvent, Couple<Float>> 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<SoundEvent, Couple<Float>> pair : compiledEvents) {
|
||||
Couple<Float> 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<SoundEvent, Couple<Float>> pair : compiledEvents) {
|
||||
Couple<Float> 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<SoundEvent> event, float volume, float pitch) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class CustomSoundEntry extends SoundEntry {
|
||||
|
||||
protected List<ResourceLocation> variants;
|
||||
protected SoundEvent event;
|
||||
protected RegistryObject<SoundEvent> event;
|
||||
|
||||
public CustomSoundEntry(ResourceLocation id, List<ResourceLocation> 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<SoundEvent> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<StructureProcessorType<?>> REGISTER = DeferredRegister.create(Registry.STRUCTURE_PROCESSOR_REGISTRY, Create.ID);
|
||||
|
||||
public static final RegistryObject<StructureProcessorType<SchematicProcessor>> SCHEMATIC = REGISTER.register("schematic", () -> () -> SchematicProcessor.CODEC);
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
REGISTER.register(modEventBus);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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,31 +107,30 @@ 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);
|
||||
|
||||
|
@ -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));
|
||||
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() {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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<SmartFluidTankBehaviour> getTanks() {
|
||||
|
|
|
@ -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> soundEvent;
|
||||
private final float toughness;
|
||||
private final float knockbackResistance;
|
||||
private final Supplier<Ingredient> repairMaterial;
|
||||
|
||||
private AllArmorMaterials(String name, int maxDamageFactor, int[] damageReductionAmountArray, int enchantability,
|
||||
SoundEvent soundEvent, float toughness, float knockbackResistance, Supplier<Ingredient> repairMaterial) {
|
||||
Supplier<SoundEvent> soundEvent, float toughness, float knockbackResistance, Supplier<Ingredient> 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
|
||||
|
|
|
@ -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;
|
||||
|
@ -27,12 +28,6 @@ public class SchematicProcessor extends StructureProcessor {
|
|||
return INSTANCE;
|
||||
});
|
||||
|
||||
public static StructureProcessorType<SchematicProcessor> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 <T extends Enum<T>> ConfigEnum<T> e(T defaultValue, String name, String... comment) {
|
||||
return new ConfigEnum<>(name, defaultValue, comment);
|
||||
}
|
||||
|
|
|
@ -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<T> 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<T> registryData;
|
||||
private final Map<ResourceLocation, T> values;
|
||||
|
||||
public DynamicDataProvider(DataGenerator generator, String name, RegistryAccess registryAccess, RegistryAccess.RegistryData<T> registryData, Map<ResourceLocation, T> values) {
|
||||
this.generator = generator;
|
||||
this.name = name;
|
||||
this.registryAccess = registryAccess;
|
||||
this.registryData = registryData;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <T> DynamicDataProvider<T> create(DataGenerator generator, String name, RegistryAccess registryAccess, ResourceKey<? extends Registry<T>> registryKey, Map<ResourceLocation, T> values) {
|
||||
@SuppressWarnings("unchecked")
|
||||
RegistryAccess.RegistryData<T> registryData = (RegistryData<T>) RegistryAccess.REGISTRIES.get(registryKey);
|
||||
if (registryData == null) {
|
||||
return null;
|
||||
}
|
||||
return new DynamicDataProvider<>(generator, name, registryAccess, registryData, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(HashCache cache) throws IOException {
|
||||
Path path = generator.getOutputFolder();
|
||||
DynamicOps<JsonElement> ops = RegistryOps.create(JsonOps.INSTANCE, registryAccess);
|
||||
|
||||
dumpValues(path, cache, ops, registryData.key(), values, registryData.codec());
|
||||
}
|
||||
|
||||
private void dumpValues(Path rootPath, HashCache cache, DynamicOps<JsonElement> ops, ResourceKey<? extends Registry<T>> registryKey, Map<ResourceLocation, T> values, Encoder<T> encoder) {
|
||||
for (Entry<ResourceLocation, T> 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<JsonElement> ops, Encoder<T> encoder, T value) {
|
||||
try {
|
||||
Optional<JsonElement> optional = encoder.encodeStart(ops, value).resultOrPartial((message) -> {
|
||||
Create.LOGGER.error("Couldn't serialize element {}: {}", path, message);
|
||||
});
|
||||
if (optional.isPresent()) {
|
||||
DataProvider.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;
|
||||
}
|
||||
}
|
|
@ -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<Feature<?>> REGISTER = DeferredRegister.create(ForgeRegistries.FEATURES, Create.ID);
|
||||
|
||||
public static final RegistryObject<StandardOreFeature> STANDARD_ORE = REGISTER.register("standard_ore", () -> new StandardOreFeature());
|
||||
public static final RegistryObject<LayeredOreFeature> LAYERED_ORE = REGISTER.register("layered_ore", () -> new LayeredOreFeature());
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
REGISTER.register(modEventBus);
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ import net.minecraft.world.level.block.Blocks;
|
|||
|
||||
public class AllLayerPatterns {
|
||||
|
||||
public static NonNullSupplier<LayerPattern>
|
||||
public static final NonNullSupplier<LayerPattern>
|
||||
|
||||
CINNABAR = () -> LayerPattern.builder()
|
||||
.layer(l -> l.weight(1)
|
||||
|
@ -25,7 +25,7 @@ public class AllLayerPatterns {
|
|||
.block(AllPaletteStoneTypes.LIMESTONE.getBaseBlock()))
|
||||
.build();
|
||||
|
||||
public static NonNullSupplier<LayerPattern> MAGNETITE = () -> LayerPattern.builder()
|
||||
public static final NonNullSupplier<LayerPattern> 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<LayerPattern> OCHRESTONE = () -> LayerPattern.builder()
|
||||
public static final NonNullSupplier<LayerPattern> 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<LayerPattern> MALACHITE = () -> LayerPattern.builder()
|
||||
public static final NonNullSupplier<LayerPattern> 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<LayerPattern> SCORIA = () -> LayerPattern.builder()
|
||||
public static final NonNullSupplier<LayerPattern> 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<LayerPattern> LIMESTONE = () -> LayerPattern.builder()
|
||||
public static final NonNullSupplier<LayerPattern> 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<LayerPattern> SCORIA_NETHER = () -> LayerPattern.builder()
|
||||
public static final NonNullSupplier<LayerPattern> 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<LayerPattern> SCORCHIA_NETHER = () -> LayerPattern.builder()
|
||||
public static final NonNullSupplier<LayerPattern> SCORCHIA_NETHER = () -> LayerPattern.builder()
|
||||
.inNether()
|
||||
.layer(l -> l.weight(2)
|
||||
.passiveBlock())
|
||||
|
|
|
@ -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<BiomeLoadingEvent> OVERWORLD_BIOMES = event -> {
|
||||
Biome.BiomeCategory category = event.getCategory();
|
||||
return category != BiomeCategory.NETHER && category != BiomeCategory.THEEND && category != BiomeCategory.NONE;
|
||||
};
|
||||
|
||||
private static final Predicate<BiomeLoadingEvent> 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<ResourceLocation, ConfiguredFeature<?, ?>> configuredFeatures = new HashMap<>();
|
||||
for (Map.Entry<ResourceLocation, OreFeatureConfigEntry> entry : OreFeatureConfigEntry.ALL.entrySet()) {
|
||||
DatagenExtension datagenExt = entry.getValue().datagenExt();
|
||||
if (datagenExt != null) {
|
||||
configuredFeatures.put(entry.getKey(), datagenExt.getConfiguredFeature());
|
||||
}
|
||||
}
|
||||
|
||||
DynamicDataProvider<ConfiguredFeature<?, ?>> configuredFeatureProvider = DynamicDataProvider.create(generator, "Create's Configured Features", registryAccess, Registry.CONFIGURED_FEATURE_REGISTRY, configuredFeatures);
|
||||
if (configuredFeatureProvider != null) {
|
||||
generator.addProvider(configuredFeatureProvider);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Map<ResourceLocation, PlacedFeature> placedFeatures = new HashMap<>();
|
||||
for (Map.Entry<ResourceLocation, OreFeatureConfigEntry> entry : OreFeatureConfigEntry.ALL.entrySet()) {
|
||||
DatagenExtension datagenExt = entry.getValue().datagenExt();
|
||||
if (datagenExt != null) {
|
||||
placedFeatures.put(entry.getKey(), datagenExt.getPlacedFeature());
|
||||
}
|
||||
}
|
||||
|
||||
DynamicDataProvider<PlacedFeature> placedFeatureProvider = DynamicDataProvider.create(generator, "Create's Placed Features", registryAccess, Registry.PLACED_FEATURE_REGISTRY, placedFeatures);
|
||||
if (placedFeatureProvider != null) {
|
||||
generator.addProvider(placedFeatureProvider);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<PlacementModifierType<?>> REGISTER = DeferredRegister.create(Registry.PLACEMENT_MODIFIER_REGISTRY, Create.ID);
|
||||
|
||||
public static final RegistryObject<PlacementModifierType<ConfigDrivenPlacement>> CONFIG_DRIVEN = REGISTER.register("config_driven", () -> () -> ConfigDrivenPlacement.CODEC);
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
REGISTER.register(modEventBus);
|
||||
}
|
||||
}
|
|
@ -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<ResourceLocation, ConfigDrivenFeatureEntry> 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<Feature<?>> event) {
|
||||
event.getRegistry()
|
||||
.registerAll(VanillaStyleOreFeature.INSTANCE, LayeredOreFeature.INSTANCE);
|
||||
}
|
||||
|
||||
public static void registerPlacementTypes() {
|
||||
ConfigDrivenDecorator.TYPE =
|
||||
Registry.register(Registry.PLACEMENT_MODIFIERS, "create_config_driven", () -> ConfigDrivenDecorator.CODEC);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<ConfigDrivenOreConfiguration> {
|
||||
|
||||
public OreFeatureBase() {
|
||||
super(ConfigDrivenOreConfiguration.CODEC);
|
||||
public abstract class BaseConfigDrivenOreFeature<FC extends BaseConfigDrivenOreFeatureConfiguration> extends Feature<FC> {
|
||||
public BaseConfigDrivenOreFeature(Codec<FC> configCodec) {
|
||||
super(configCodec);
|
||||
}
|
||||
|
||||
public boolean canPlaceOre(BlockState pState, Function<BlockPos, BlockState> pAdjacentStateAccessor,
|
||||
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);
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<ResourceLocation, BiomeCategory> {
|
||||
|
||||
}
|
|
@ -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<ConfiguredFeature<?, ?>> CONFIGURED_FEATURE_REGISTER = DeferredRegister.create(Registry.CONFIGURED_FEATURE_REGISTRY, Create.ID);
|
||||
private static final DeferredRegister<PlacedFeature> PLACED_FEATURE_REGISTER = DeferredRegister.create(Registry.PLACED_FEATURE_REGISTRY, Create.ID);
|
||||
|
||||
static {
|
||||
for (Map.Entry<ResourceLocation, OreFeatureConfigEntry> entry : OreFeatureConfigEntry.ALL.entrySet()) {
|
||||
ResourceLocation id = entry.getKey();
|
||||
if (id.getNamespace().equals(Create.ID)) {
|
||||
DatagenExtension datagenExt = entry.getValue().datagenExt();
|
||||
if (datagenExt != null) {
|
||||
CONFIGURED_FEATURE_REGISTER.register(id.getPath(), () -> datagenExt.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);
|
||||
}
|
||||
}
|
|
@ -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<ConfigDrivenDecorator> TYPE;
|
||||
|
||||
public static final Codec<ConfigDrivenDecorator> 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<BlockPos> 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<? extends Block> block;
|
||||
private NonNullSupplier<? extends Block> deepblock;
|
||||
private NonNullSupplier<? extends Block> netherblock;
|
||||
|
||||
private List<NonNullSupplier<LayerPattern>> layers = new ArrayList<>();
|
||||
|
||||
protected ConfigInt clusterSize;
|
||||
protected ConfigInt minHeight;
|
||||
protected ConfigInt maxHeight;
|
||||
protected ConfigFloat frequency;
|
||||
|
||||
Function<ConfigDrivenFeatureEntry, ? extends ConfiguredFeature<?, ?>> factory;
|
||||
Holder<ConfiguredFeature<?, ?>> configuredFeature;
|
||||
Holder<PlacedFeature> 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<LayerPattern> pattern) {
|
||||
this.layers.add(pattern);
|
||||
this.factory = this::layersFactory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigDrivenFeatureEntry withBlock(NonNullSupplier<? extends Block> block) {
|
||||
this.block = this.deepblock = block;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigDrivenFeatureEntry withNetherBlock(NonNullSupplier<? extends Block> block) {
|
||||
this.netherblock = block;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigDrivenFeatureEntry withBlocks(Couple<NonNullSupplier<? extends Block>> 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<TargetBlockState> createTarget() {
|
||||
List<TargetBlockState> 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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<ConfigDrivenLayeredOreFeatureConfiguration> CODEC = RecordCodecBuilder.create(instance -> {
|
||||
return instance.group(
|
||||
OreFeatureConfigEntry.CODEC
|
||||
.fieldOf("entry")
|
||||
.forGetter(config -> config.entry),
|
||||
Codec.floatRange(0.0F, 1.0F)
|
||||
.fieldOf("discard_chance_on_air_exposure")
|
||||
.forGetter(config -> config.discardChanceOnAirExposure),
|
||||
Codec.list(LayerPattern.CODEC)
|
||||
.fieldOf("layer_patterns")
|
||||
.forGetter(config -> config.layerPatterns)
|
||||
).apply(instance, ConfigDrivenLayeredOreFeatureConfiguration::new);
|
||||
});
|
||||
|
||||
private final List<LayerPattern> layerPatterns;
|
||||
|
||||
public ConfigDrivenLayeredOreFeatureConfiguration(OreFeatureConfigEntry entry, float discardChance, List<LayerPattern> layerPatterns) {
|
||||
super(entry, discardChance);
|
||||
this.layerPatterns = layerPatterns;
|
||||
}
|
||||
|
||||
public List<LayerPattern> getLayerPatterns() {
|
||||
return layerPatterns;
|
||||
}
|
||||
}
|
|
@ -1,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<ConfigDrivenOreConfiguration> 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<TargetBlockState> targetStates;
|
||||
public final float discardChanceOnAirExposure;
|
||||
public final ResourceLocation key;
|
||||
|
||||
public ConfigDrivenOreConfiguration(List<TargetBlockState> 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<LayerPattern> 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<ConfigDrivenOreFeatureConfiguration> CODEC = RecordCodecBuilder.create(instance -> {
|
||||
return instance.group(
|
||||
OreFeatureConfigEntry.CODEC
|
||||
.fieldOf("entry")
|
||||
.forGetter(config -> config.entry),
|
||||
Codec.floatRange(0.0F, 1.0F)
|
||||
.fieldOf("discard_chance_on_air_exposure")
|
||||
.forGetter(config -> config.discardChanceOnAirExposure),
|
||||
Codec.list(TargetBlockState.CODEC)
|
||||
.fieldOf("targets")
|
||||
.forGetter(config -> config.targetStates)
|
||||
).apply(instance, ConfigDrivenOreFeatureConfiguration::new);
|
||||
});
|
||||
|
||||
private final List<TargetBlockState> targetStates;
|
||||
|
||||
public ConfigDrivenOreFeatureConfiguration(OreFeatureConfigEntry entry, float discardChance, List<TargetBlockState> targetStates) {
|
||||
super(entry, discardChance);
|
||||
this.targetStates = targetStates;
|
||||
}
|
||||
|
||||
public List<TargetBlockState> getTargetStates() {
|
||||
return targetStates;
|
||||
}
|
||||
}
|
|
@ -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<ConfigDrivenPlacement> CODEC = RecordCodecBuilder.create(instance -> {
|
||||
return instance.group(
|
||||
OreFeatureConfigEntry.CODEC
|
||||
.fieldOf("entry")
|
||||
.forGetter(ConfigDrivenPlacement::getEntry)
|
||||
).apply(instance, ConfigDrivenPlacement::new);
|
||||
});
|
||||
|
||||
private final OreFeatureConfigEntry entry;
|
||||
|
||||
public ConfigDrivenPlacement(OreFeatureConfigEntry entry) {
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<BlockPos> getPositions(PlacementContext context, 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();
|
||||
}
|
||||
}
|
|
@ -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<LayerPattern> CODEC = Codec.list(Layer.CODEC)
|
||||
.xmap(LayerPattern::new, pattern -> pattern.layers);
|
||||
|
||||
List<Layer> layers;
|
||||
public final List<Layer> layers;
|
||||
|
||||
public LayerPattern() {
|
||||
layers = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
LayerPattern ore = new LayerPattern();
|
||||
return ore.new Builder();
|
||||
public LayerPattern(List<Layer> layers) {
|
||||
this.layers = layers;
|
||||
}
|
||||
|
||||
public Layer rollNext(@Nullable Layer previous, Random random) {
|
||||
|
@ -49,42 +47,60 @@ public class LayerPattern {
|
|||
return null;
|
||||
}
|
||||
|
||||
class Builder {
|
||||
|
||||
private boolean netherMode;
|
||||
|
||||
public LayerPattern build() {
|
||||
return LayerPattern.this;
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final List<Layer> layers = new ArrayList<>();
|
||||
private boolean netherMode;
|
||||
|
||||
public Builder inNether() {
|
||||
netherMode = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder layer(NonNullConsumer<LayerBuilder> builder) {
|
||||
Layer layer = new Layer();
|
||||
LayerBuilder layerBuilder = layer.new LayerBuilder();
|
||||
public Builder layer(NonNullConsumer<Layer.Builder> 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<Layer> 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<List<TargetBlockState>> targets;
|
||||
public int minSize;
|
||||
public int maxSize;
|
||||
public int weight;
|
||||
public final List<List<TargetBlockState>> 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<List<TargetBlockState>> targets, int minSize, int maxSize, int weight) {
|
||||
this.targets = targets;
|
||||
this.minSize = minSize;
|
||||
this.maxSize = maxSize;
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public List<TargetBlockState> 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<List<TargetBlockState>> 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<? extends Block> block) {
|
||||
public Builder block(NonNullSupplier<? extends Block> 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<NonNullSupplier<? extends Block>> blocksByDepth) {
|
||||
public Builder blocks(Couple<NonNullSupplier<? extends Block>> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<ResourceLocation, List<LayerPattern>> LAYER_PATTERNS = new HashMap<>();
|
||||
|
||||
public static final LayeredOreFeature INSTANCE = new LayeredOreFeature();
|
||||
|
||||
public class LayeredOreFeature extends BaseConfigDrivenOreFeature<ConfigDrivenLayeredOreFeatureConfiguration> {
|
||||
public LayeredOreFeature() {
|
||||
setRegistryName("config_driven_layered_ore");
|
||||
super(ConfigDrivenLayeredOreFeatureConfiguration.CODEC);
|
||||
}
|
||||
|
||||
public boolean place(FeaturePlaceContext<ConfigDrivenOreConfiguration> pContext) {
|
||||
|
||||
@Override
|
||||
public boolean place(FeaturePlaceContext<ConfigDrivenLayeredOreFeatureConfiguration> pContext) {
|
||||
Random random = pContext.random();
|
||||
BlockPos blockpos = pContext.origin();
|
||||
WorldGenLevel worldgenlevel = pContext.level();
|
||||
ConfigDrivenOreConfiguration config = pContext.config();
|
||||
List<LayerPattern> patternPool = config.getLayers();
|
||||
ConfigDrivenLayeredOreFeatureConfiguration config = pContext.config();
|
||||
List<LayerPattern> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<ResourceLocation, OreFeatureConfigEntry> ALL = new HashMap<>();
|
||||
|
||||
public static final Codec<OreFeatureConfigEntry> CODEC = ResourceLocation.CODEC
|
||||
.comapFlatMap(OreFeatureConfigEntry::read, entry -> entry.id);
|
||||
|
||||
public final ResourceLocation id;
|
||||
public final ConfigInt clusterSize;
|
||||
public final ConfigFloat frequency;
|
||||
public final ConfigInt minHeight;
|
||||
public final ConfigInt maxHeight;
|
||||
|
||||
private 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<OreFeatureConfigEntry> read(ResourceLocation id) {
|
||||
OreFeatureConfigEntry entry = ALL.get(id);
|
||||
if (entry != null) {
|
||||
return DataResult.success(entry);
|
||||
} else {
|
||||
return DataResult.error("Not a valid OreFeatureConfigEntry: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
public class BiomeExtension {
|
||||
public ResourceLocation placedFeatureLocation = id;
|
||||
public Predicate<BiomeLoadingEvent> biomePredicate = e -> false;
|
||||
|
||||
public BiomeExtension feature(ResourceLocation placedFeature) {
|
||||
this.placedFeatureLocation = placedFeature;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BiomeExtension predicate(Predicate<BiomeLoadingEvent> predicate) {
|
||||
this.biomePredicate = predicate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void modifyBiomes(BiomeLoadingEvent event, Registry<PlacedFeature> registry) {
|
||||
if (biomePredicate.test(event)) {
|
||||
Optional<Holder<PlacedFeature>> 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<? extends Block> block;
|
||||
public NonNullSupplier<? extends Block> deepBlock;
|
||||
public NonNullSupplier<? extends Block> netherBlock;
|
||||
|
||||
public StandardDatagenExtension withBlock(NonNullSupplier<? extends Block> block) {
|
||||
this.block = block;
|
||||
this.deepBlock = block;
|
||||
return this;
|
||||
}
|
||||
|
||||
public StandardDatagenExtension withBlocks(Couple<NonNullSupplier<? extends Block>> blocks) {
|
||||
this.block = blocks.getFirst();
|
||||
this.deepBlock = blocks.getSecond();
|
||||
return this;
|
||||
}
|
||||
|
||||
public StandardDatagenExtension withNetherBlock(NonNullSupplier<? extends Block> block) {
|
||||
this.netherBlock = block;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredFeature<?, ?> getConfiguredFeature() {
|
||||
if (configuredFeature != null) {
|
||||
return configuredFeature;
|
||||
}
|
||||
|
||||
List<TargetBlockState> targetStates = new ArrayList<>();
|
||||
if (block != null)
|
||||
targetStates.add(OreConfiguration.target(OreFeatures.STONE_ORE_REPLACEABLES, block.get()
|
||||
.defaultBlockState()));
|
||||
if (deepBlock != null)
|
||||
targetStates.add(OreConfiguration.target(OreFeatures.DEEPSLATE_ORE_REPLACEABLES, deepBlock.get()
|
||||
.defaultBlockState()));
|
||||
if (netherBlock != null)
|
||||
targetStates.add(OreConfiguration.target(OreFeatures.NETHER_ORE_REPLACEABLES, netherBlock.get()
|
||||
.defaultBlockState()));
|
||||
|
||||
ConfigDrivenOreFeatureConfiguration config = new ConfigDrivenOreFeatureConfiguration(OreFeatureConfigEntry.this, 0, targetStates);
|
||||
configuredFeature = new ConfiguredFeature<>(AllFeatures.STANDARD_ORE.get(), config);
|
||||
|
||||
return configuredFeature;
|
||||
}
|
||||
}
|
||||
|
||||
public class LayeredDatagenExtension extends DatagenExtension {
|
||||
public final List<NonNullSupplier<LayerPattern>> layerPatterns = new ArrayList<>();
|
||||
|
||||
public LayeredDatagenExtension withLayerPattern(NonNullSupplier<LayerPattern> pattern) {
|
||||
this.layerPatterns.add(pattern);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfiguredFeature<?, ?> getConfiguredFeature() {
|
||||
if (configuredFeature != null) {
|
||||
return configuredFeature;
|
||||
}
|
||||
|
||||
List<LayerPattern> 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<ConfigDrivenOreFeatureConfiguration> {
|
||||
|
||||
public StandardOreFeature() {
|
||||
super(ConfigDrivenOreFeatureConfiguration.CODEC);
|
||||
}
|
||||
|
||||
// From OreFeature, slight adjustments
|
||||
|
||||
@Override
|
||||
public boolean place(FeaturePlaceContext<ConfigDrivenOreFeatureConfiguration> 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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<ConfigDrivenOreConfiguration> 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;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue