Merge remote-tracking branch 'upstream/mc1.18/dev' into mc1.19/dev

Conflicts:
	src/main/java/com/simibubi/create/AllEntityDataSerializers.java
	src/main/java/com/simibubi/create/AllParticleTypes.java
	src/main/java/com/simibubi/create/AllRecipeTypes.java
	src/main/java/com/simibubi/create/AllSoundEvents.java
	src/main/java/com/simibubi/create/Create.java
	src/main/java/com/simibubi/create/events/CommonEvents.java
	src/main/java/com/simibubi/create/foundation/worldgen/AllWorldFeatures.java
	src/main/java/com/simibubi/create/foundation/worldgen/BiomeFilter.java
	src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenDecorator.java
	src/main/java/com/simibubi/create/foundation/worldgen/ConfigDrivenFeatureEntry.java
	src/main/java/com/simibubi/create/foundation/worldgen/LayeredOreFeature.java
	src/main/java/com/simibubi/create/foundation/worldgen/OreFeatureBase.java
	src/main/java/com/simibubi/create/foundation/worldgen/VanillaStyleOreFeature.java
This commit is contained in:
PepperCode1 2022-08-05 13:56:19 -07:00
commit 252aecabd5
42 changed files with 1347 additions and 954 deletions

View File

@ -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

View File

@ -1,11 +0,0 @@
{
"replace": false,
"values": [
"create:blaze_burner",
"create:lit_blaze_burner",
"#minecraft:fire",
"#minecraft:campfires",
"minecraft:magma_block",
"minecraft:lava"
]
}

View File

@ -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"
]
}

View File

@ -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()

View File

@ -2,17 +2,21 @@ package com.simibubi.create;
import com.simibubi.create.content.logistics.trains.entity.CarriageSyncDataSerializer;
import net.minecraft.network.syncher.EntityDataSerializer;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegisterEvent;
import net.minecraftforge.registries.RegistryObject;
public class AllEntityDataSerializers {
private static final DeferredRegister<EntityDataSerializer<?>> REGISTER = DeferredRegister.create(ForgeRegistries.Keys.ENTITY_DATA_SERIALIZERS, Create.ID);
public static final CarriageSyncDataSerializer CARRIAGE_DATA = new CarriageSyncDataSerializer();
public static void register(RegisterEvent event) {
event.register(ForgeRegistries.Keys.ENTITY_DATA_SERIALIZERS, helper -> {
helper.register(Create.asResource("carriage_data"), CARRIAGE_DATA);
});
}
public static final RegistryObject<CarriageSyncDataSerializer> CARRIAGE_DATA_ENTRY = REGISTER.register("carriage_data", () -> CARRIAGE_DATA);
public static void register(IEventBus modEventBus) {
REGISTER.register(modEventBus);
}
}

View File

@ -14,14 +14,15 @@ import com.simibubi.create.content.curiosities.bell.SoulBaseParticle;
import com.simibubi.create.content.curiosities.bell.SoulParticle;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.core.Registry;
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.RegisterParticleProvidersEvent;
import net.minecraftforge.registries.RegisterEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public enum AllParticleTypes {
@ -37,21 +38,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(RegisterEvent event) {
event.register(Registry.PARTICLE_TYPE_REGISTRY, helper -> {
for (AllParticleTypes particle : values())
particle.entry.register(helper);
});
public static void register(IEventBus modEventBus) {
ParticleEntry.REGISTER.register(modEventBus);
}
@OnlyIn(Dist.CLIENT)
@ -61,39 +58,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(RegisterEvent.RegisterHelper<ParticleType<?>> helper) {
helper.register(id, getOrCreateType());
}
ParticleType<D> getOrCreateType() {
if (type != null)
return type;
type = typeFactory.get()
.createType();
return type;
object = REGISTER.register(name, () -> this.typeFactory.get().createType());
}
@OnlyIn(Dist.CLIENT)
void registerFactory(RegisterParticleProvidersEvent event) {
public void registerFactory(RegisterParticleProvidersEvent event) {
typeFactory.get()
.register(getOrCreateType(), event);
.register(object.get(), event);
}
}

View File

@ -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.registries.RegisterEvent;
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,43 @@ 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, RecipeType<?> existingType) {
this(serializerSupplier, () -> existingType);
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) {
this.id = Create.asResource(Lang.asId(name()));
this.serializerSupplier = serializerSupplier;
this.typeSupplier = () -> RecipeType.simple(id);
String name = Lang.asId(name());
id = Create.asResource(name);
serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier);
typeObject = Registers.TYPE_REGISTER.register(name, () -> RecipeType.simple(id));
type = typeObject;
}
AllRecipeTypes(ProcessingRecipeFactory<?> processingFactory) {
this(processingSerializer(processingFactory));
this(() -> new ProcessingRecipeSerializer<>(processingFactory));
}
public static void register(IEventBus modEventBus) {
ShapedRecipe.setCraftingSize(9, 9);
Registers.SERIALIZER_REGISTER.register(modEventBus);
Registers.TYPE_REGISTER.register(modEventBus);
}
@Override
@ -99,13 +113,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,30 +127,6 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
.getRecipeFor(getType(), inv, world);
}
public static void register(RegisterEvent event) {
event.register(Registry.RECIPE_SERIALIZER_REGISTRY, helper -> {
ShapedRecipe.setCraftingSize(9, 9);
for (AllRecipeTypes r : AllRecipeTypes.values()) {
r.serializer = r.serializerSupplier.get();
helper.register(r.id, r.serializer);
}
});
event.register(Registry.RECIPE_TYPE_REGISTRY, helper -> {
for (AllRecipeTypes r : AllRecipeTypes.values()) {
r.type = r.typeSupplier.get();
if (r.type == RecipeType.CRAFTING)
continue;
helper.register(r.id, r.type);
}
});
}
private static Supplier<RecipeSerializer<?>> processingSerializer(ProcessingRecipeFactory<?> factory) {
return () -> new ProcessingRecipeSerializer<>(factory);
}
public static final Set<ResourceLocation> RECIPE_DENY_SET =
ImmutableSet.of(new ResourceLocation("occultism", "spirit_trade"), new ResourceLocation("occultism", "ritual"));
@ -149,4 +139,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);
}
}

View File

@ -6,12 +6,10 @@ 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.JsonArray;
import com.google.gson.JsonObject;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.core.Registry;
import net.minecraft.core.Vec3i;
@ -26,12 +24,15 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegisterEvent;
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")
@ -304,21 +305,21 @@ public class AllSoundEvents {
return new SoundEntryBuilder(id);
}
public static void prepare() {
for (SoundEntry entry : ALL.values())
entry.prepare();
}
public static void register(RegisterEvent event) {
event.register(Registry.SOUND_EVENT_REGISTRY, helper -> {
for (SoundEntry entry : entries.values())
for (SoundEntry entry : ALL.values())
entry.register(helper);
});
}
public static void prepare() {
for (SoundEntry entry : entries.values())
entry.prepare();
}
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;
@ -366,7 +367,7 @@ public class AllSoundEvents {
try {
JsonObject json = new JsonObject();
entries.entrySet()
ALL.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEach(entry -> {
@ -382,12 +383,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;
@ -426,11 +430,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);
}
@ -439,7 +447,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;
}
@ -528,52 +536,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);
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(RegisterEvent.RegisterHelper<SoundEvent> helper) {
for (Pair<SoundEvent, Couple<Float>> pair : compiledEvents) {
SoundEvent soundEvent = pair.getFirst();
helper.register(soundEvent.getLocation(), soundEvent);
for (CompiledSoundEvent compiledEvent : compiledEvents) {
ResourceLocation location = compiledEvent.event().getId();
helper.register(location, new SoundEvent(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");
@ -583,33 +592,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) {
@ -619,17 +630,18 @@ public class AllSoundEvents {
@Override
public void prepare() {
event = new SoundEvent(id);
event = RegistryObject.create(id, ForgeRegistries.SOUND_EVENTS);
}
@Override
public void register(RegisterEvent.RegisterHelper<SoundEvent> helper) {
helper.register(id, event);
ResourceLocation location = event.getId();
helper.register(location, new SoundEvent(location));
}
@Override
public SoundEvent getMainEvent() {
return event;
return event.get();
}
@Override
@ -661,12 +673,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);
}
}

View File

@ -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);
}
}

View File

@ -111,9 +111,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,
@ -121,10 +123,6 @@ public class AllTags {
WINDMILL_SAILS,
WINDOWABLE,
WRENCH_PICKUP,
CASING,
NON_MOVABLE,
PASSIVE_BOILER_HEATERS,
RELOCATION_NOT_SUPPORTED(FORGE),
WG_STONE(FORGE),
@ -207,10 +205,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,
@ -218,9 +219,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);

View File

@ -20,7 +20,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;
@ -37,7 +36,9 @@ 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.data.DataGenerator;
@ -92,6 +93,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();
@ -101,31 +106,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.addListener(AllWorldFeatures::registerOreFeatures);
modEventBus.addListener(AllRecipeTypes::register);
modEventBus.addListener(AllParticleTypes::register);
modEventBus.addListener(AllSoundEvents::register);
modEventBus.addListener(AllEntityDataSerializers::register);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus));
@ -141,23 +145,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(true, new AllAdvancements(gen));
gen.addProvider(true, new LangMerger(gen));
gen.addProvider(true, AllSoundEvents.provider(gen));
gen.addProvider(true, new StandardRecipeGen(gen));
gen.addProvider(true, new MechanicalCraftingRecipeGen(gen));
gen.addProvider(true, new SequencedAssemblyRecipeGen(gen));
ProcessingRecipeGen.registerAll(gen);
AllWorldFeatures.generateBiomeModifiers(event);
if (event.includeClient()) {
gen.addProvider(true, new LangMerger(gen));
gen.addProvider(true, AllSoundEvents.provider(gen));
}
if (event.includeServer()) {
gen.addProvider(true, new AllAdvancements(gen));
gen.addProvider(true, new StandardRecipeGen(gen));
gen.addProvider(true, new MechanicalCraftingRecipeGen(gen));
gen.addProvider(true, new SequencedAssemblyRecipeGen(gen));
ProcessingRecipeGen.registerAll(gen);
// AllOreFeatureConfigEntries.gatherData(event);
}
}
public static CreateRegistrate registrate() {

View File

@ -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());
}

View File

@ -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() {

View File

@ -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

View File

@ -59,17 +59,27 @@ public class StockpileSwitchTileEntity extends SmartTileEntity {
super.read(compound, clientPacket);
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
protected void writeCommon(CompoundTag compound) {
compound.putFloat("OnAbove", onWhenAbove);
compound.putFloat("OffBelow", offWhenBelow);
compound.putBoolean("Inverted", inverted);
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
writeCommon(compound);
compound.putFloat("Current", currentLevel);
compound.putBoolean("Powered", redstoneState);
compound.putBoolean("Inverted", inverted);
compound.putBoolean("PoweredAfterDelay", poweredAfterDelay);
super.write(compound, clientPacket);
}
@Override
public void writeSafe(CompoundTag compound) {
writeCommon(compound);
super.writeSafe(compound);
}
public float getStockLevel() {
return currentLevel;
}

View File

@ -5,6 +5,7 @@ import java.util.Optional;
import javax.annotation.Nullable;
import com.mojang.serialization.Codec;
import com.simibubi.create.AllStructureProcessorTypes;
import com.simibubi.create.foundation.utility.NBTProcessors;
import net.minecraft.core.BlockPos;
@ -21,18 +22,12 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProc
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
public class SchematicProcessor extends StructureProcessor {
public static final SchematicProcessor INSTANCE = new SchematicProcessor();
public static final Codec<SchematicProcessor> CODEC = Codec.unit(() -> {
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();
}
}

View File

@ -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 {

View File

@ -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);
}

View File

@ -31,7 +31,10 @@ public enum ContraptionMovementSetting {
public static ContraptionMovementSetting get(Block block) {
if (block instanceof IMovementSettingProvider provider)
return provider.getContraptionMovementSetting();
return SETTING_SUPPLIERS.get(block).get();
Supplier<ContraptionMovementSetting> supplier = SETTING_SUPPLIERS.get(block);
if (supplier == null)
return null;
return supplier.get();
}
public static boolean allAre(Collection<StructureTemplate.StructureBlockInfo> blocks, ContraptionMovementSetting are) {

View File

@ -0,0 +1,87 @@
package com.simibubi.create.foundation.data;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import com.google.gson.JsonElement;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.Encoder;
import com.mojang.serialization.JsonOps;
import com.simibubi.create.Create;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.RegistryAccess.RegistryData;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.DataProvider;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.common.ForgeHooks;
public class DynamicDataProvider<T> implements DataProvider {
private final DataGenerator generator;
private final String name;
private final RegistryAccess registryAccess;
private final RegistryAccess.RegistryData<T> registryData;
private final Map<ResourceLocation, T> values;
public DynamicDataProvider(DataGenerator generator, String name, RegistryAccess registryAccess, RegistryAccess.RegistryData<T> registryData, Map<ResourceLocation, T> values) {
this.generator = generator;
this.name = name;
this.registryAccess = registryAccess;
this.registryData = registryData;
this.values = values;
}
@Nullable
public static <T> DynamicDataProvider<T> create(DataGenerator generator, String name, RegistryAccess registryAccess, ResourceKey<? extends Registry<T>> registryKey, Map<ResourceLocation, T> values) {
@SuppressWarnings("unchecked")
RegistryAccess.RegistryData<T> registryData = (RegistryData<T>) RegistryAccess.REGISTRIES.get(registryKey);
if (registryData == null) {
return null;
}
return new DynamicDataProvider<>(generator, name, registryAccess, registryData, values);
}
@Override
public void run(CachedOutput cache) throws IOException {
Path path = generator.getOutputFolder();
DynamicOps<JsonElement> ops = RegistryOps.create(JsonOps.INSTANCE, registryAccess);
dumpValues(path, cache, ops, registryData.key(), values, registryData.codec());
}
private void dumpValues(Path rootPath, CachedOutput cache, DynamicOps<JsonElement> ops, ResourceKey<? extends Registry<T>> registryKey, Map<ResourceLocation, T> values, Encoder<T> encoder) {
DataGenerator.PathProvider pathProvider = generator.createPathProvider(DataGenerator.Target.DATA_PACK, ForgeHooks.prefixNamespace(registryKey.location()));
for (Entry<ResourceLocation, T> entry : values.entrySet()) {
dumpValue(pathProvider.json(entry.getKey()), cache, ops, encoder, entry.getValue());
}
}
// From WorldgenRegistryDumpReport
private void dumpValue(Path path, CachedOutput cache, DynamicOps<JsonElement> ops, Encoder<T> encoder, T value) {
try {
Optional<JsonElement> optional = encoder.encodeStart(ops, value).resultOrPartial((message) -> {
Create.LOGGER.error("Couldn't serialize element {}: {}", path, message);
});
if (optional.isPresent()) {
DataProvider.saveStable(cache, optional.get(), path);
}
} catch (IOException e) {
Create.LOGGER.error("Couldn't save element {}", path, e);
}
}
@Override
public String getName() {
return name;
}
}

View File

@ -133,7 +133,7 @@ public class PonderUI extends NavigatableSimiScreen {
return ui;
}
PonderUI(List<PonderScene> scenes) {
protected PonderUI(List<PonderScene> scenes) {
ResourceLocation component = scenes.get(0)
.getComponent();
if (ForgeRegistries.ITEMS.containsKey(component))
@ -567,65 +567,8 @@ public class PonderUI extends NavigatableSimiScreen {
noWidgetsHovered &= !child.isMouseOver(mouseX, mouseY);
int tooltipColor = Theme.i(Theme.Key.TEXT_DARKER);
{
// Chapter title
ms.pushPose();
ms.translate(0, 0, 400);
int x = 31 + 20 + 8;
int y = 31;
String title = activeScene.getTitle();
int wordWrappedHeight = font.wordWrapHeight(title, left.x - 51);
int streakHeight = 35 - 9 + wordWrappedHeight;
UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (150 * fade));
UIRenderHelper.streak(ms, 180, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (30 * fade));
new BoxElement().withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
.at(21, 21, 100)
.withBounds(30, 30)
.render(ms);
GuiGameElement.of(stack)
.scale(2)
.at(x - 39, y - 11)
.render(ms);
font.draw(ms, Lang.translateDirect(PONDERING), x, y - 6, tooltipColor);
y += 8;
x += 0;
ms.translate(x, y, 0);
ms.mulPose(Vector3f.XN.rotationDegrees(indexDiff * -75));
ms.translate(0, 0, 5);
FontHelper.drawSplitString(ms, font, title, 0, 0, left.x - 51, Theme.c(Theme.Key.TEXT)
.scaleAlpha(1 - indexDiff)
.getRGB());
ms.popPose();
if (chapter != null) {
ms.pushPose();
ms.translate(chap.x - 4 - 4, chap.y, 0);
UIRenderHelper.streak(ms, 180, 4, 10, 26, (int) (150 * fade));
drawRightAlignedString(font, ms, Lang.translateDirect(IN_CHAPTER)
.getString(), 0, 0, tooltipColor);
drawRightAlignedString(font, ms, chapter.getTitle(), 0, 12, Theme.i(Theme.Key.TEXT));
ms.popPose();
}
Color c1 = Theme.c(Theme.Key.PONDER_BACK_ARROW)
.setAlpha(0x40);
Color c2 = Theme.c(Theme.Key.PONDER_BACK_ARROW)
.setAlpha(0x20);
Color c3 = Theme.c(Theme.Key.PONDER_BACK_ARROW)
.setAlpha(0x10);
UIRenderHelper.breadcrumbArrow(ms, width / 2 - 20, height - 51, 0, 20, 20, 5, c1, c2);
UIRenderHelper.breadcrumbArrow(ms, width / 2 + 20, height - 51, 0, -20, 20, -5, c1, c2);
UIRenderHelper.breadcrumbArrow(ms, width / 2 - 90, height - 51, 0, 70, 20, 5, c1, c3);
UIRenderHelper.breadcrumbArrow(ms, width / 2 + 90, height - 51, 0, -70, 20, -5, c1, c3);
}
renderChapterTitle(ms, fade, indexDiff, activeScene, tooltipColor);
renderNavigationMenu(ms);
if (identifyMode) {
if (noWidgetsHovered && mouseY < height - 80) {
@ -637,17 +580,8 @@ public class PonderUI extends NavigatableSimiScreen {
((MutableComponent) minecraft.options.keyDrop.getTranslatedKeyMessage())
.withStyle(ChatFormatting.WHITE))
.withStyle(ChatFormatting.GRAY);
// renderOrderedTooltip(ms, textRenderer.wrapLines(text, width / 3), 0, 0);
renderComponentTooltip(ms, font.getSplitter()
.splitLines(text, width / 3, Style.EMPTY), 0, 0, font);
/*
* String tooltip = Lang .createTranslationTextComponent(IDENTIFY_MODE,
* client.gameSettings.keyBindDrop.getBoundKeyLocalizedText().applyTextStyle(
* TextFormatting.WHITE)) .applyTextStyle(TextFormatting.GRAY)
* .getFormattedText(); renderTooltip(font.listFormattedStringToWidth(tooltip,
* width / 3), 0, 0);
*/
} else
renderTooltip(ms, hoveredTooltipItem, 0, 0);
if (hoveredBlockPos != null && PonderIndex.editingModeActive() && !userViewMode) {
@ -677,30 +611,12 @@ public class PonderUI extends NavigatableSimiScreen {
else
slowMode.dim();
{
// Scene overlay
float scenePT = skipCooling > 0 ? 0 : partialTicks;
ms.pushPose();
ms.translate(0, 0, 100);
renderOverlay(ms, index, scenePT);
if (indexDiff > 1 / 512f)
renderOverlay(ms, lazyIndexValue < index ? index - 1 : index + 1, scenePT);
ms.popPose();
}
renderSceneOverlay(ms, partialTicks, lazyIndexValue, indexDiff);
boolean finished = activeScene.isFinished();
// Next up:
if (finished && nextScene != null && nextUp.getValue() > 1 / 16f && !nextScene.getId()
.equals(Create.asResource("creative_motor_mojang"))) {
ms.pushPose();
ms.translate(right.x + 10, right.y - 6 + nextUp.getValue(partialTicks) * 5, 400);
int boxWidth = (Math.max(font.width(nextScene.getTitle()), font.width(Lang.translateDirect(NEXT_UP))) + 5);
renderSpeechBox(ms, 0, 0, boxWidth, 20, right.isHoveredOrFocused(), Pointing.DOWN, false);
ms.translate(0, -29, 100);
drawCenteredString(ms, font, Lang.translateDirect(NEXT_UP), 0, 0, Theme.i(Theme.Key.TEXT_DARKER));
drawCenteredString(ms, font, nextScene.getTitle(), 0, 10, Theme.i(Theme.Key.TEXT));
ms.popPose();
if (finished) {
jumpToNextScene(ms, partialTicks, nextScene);
}
// Widgets
@ -725,6 +641,13 @@ public class PonderUI extends NavigatableSimiScreen {
nextUp.updateChaseTarget(0);
}
renderPonderTags(ms, mouseX, mouseY, partialTicks, fade, activeScene);
renderHoverTooltips(ms, tooltipColor);
RenderSystem.enableDepthTest();
}
protected void renderPonderTags(PoseStack ms, int mouseX, int mouseY, float partialTicks, float fade, PonderScene activeScene) {
// Tags
List<PonderTag> sceneTags = activeScene.getTags();
boolean highlightAll = sceneTags.contains(PonderTag.Highlight.ALL);
@ -765,7 +688,34 @@ public class PonderUI extends NavigatableSimiScreen {
ms.popPose();
});
}
protected void renderSceneOverlay(PoseStack ms, float partialTicks, float lazyIndexValue, float indexDiff) {
// Scene overlay
float scenePT = skipCooling > 0 ? 0 : partialTicks;
ms.pushPose();
ms.translate(0, 0, 100);
renderOverlay(ms, index, scenePT);
if (indexDiff > 1 / 512f)
renderOverlay(ms, lazyIndexValue < index ? index - 1 : index + 1, scenePT);
ms.popPose();
}
protected void jumpToNextScene(PoseStack ms, float partialTicks, PonderScene nextScene) {
if (nextScene != null && nextUp.getValue() > 1 / 16f && !nextScene.getId()
.equals(Create.asResource("creative_motor_mojang"))) {
ms.pushPose();
ms.translate(right.x + 10, right.y - 6 + nextUp.getValue(partialTicks) * 5, 400);
int boxWidth = (Math.max(font.width(nextScene.getTitle()), font.width(Lang.translateDirect(NEXT_UP))) + 5);
renderSpeechBox(ms, 0, 0, boxWidth, 20, right.isHoveredOrFocused(), Pointing.DOWN, false);
ms.translate(0, -29, 100);
drawCenteredString(ms, font, Lang.translateDirect(NEXT_UP), 0, 0, Theme.i(Theme.Key.TEXT_DARKER));
drawCenteredString(ms, font, nextScene.getTitle(), 0, 10, Theme.i(Theme.Key.TEXT));
ms.popPose();
}
}
protected void renderHoverTooltips(PoseStack ms, int tooltipColor) {
ms.pushPose();
ms.translate(0, 0, 500);
int tooltipY = height - 16;
@ -784,8 +734,67 @@ public class PonderUI extends NavigatableSimiScreen {
if (PonderIndex.editingModeActive() && userMode.isHoveredOrFocused())
drawCenteredString(ms, font, "Editor View", userMode.x + 10, tooltipY, tooltipColor);
ms.popPose();
}
RenderSystem.enableDepthTest();
protected void renderChapterTitle(PoseStack ms, float fade, float indexDiff, PonderScene activeScene, int tooltipColor) {
// Chapter title
ms.pushPose();
ms.translate(0, 0, 400);
int x = 31 + 20 + 8;
int y = 31;
String title = activeScene.getTitle();
int wordWrappedHeight = font.wordWrapHeight(title, left.x - 51);
int streakHeight = 35 - 9 + wordWrappedHeight;
UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (150 * fade));
UIRenderHelper.streak(ms, 180, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (30 * fade));
new BoxElement().withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
.at(21, 21, 100)
.withBounds(30, 30)
.render(ms);
GuiGameElement.of(stack)
.scale(2)
.at(x - 39f, y - 11f)
.render(ms);
font.draw(ms, Lang.translateDirect(PONDERING), x, y - 6, tooltipColor);
y += 8;
x += 0;
ms.translate(x, y, 0);
ms.mulPose(Vector3f.XN.rotationDegrees(indexDiff * -75));
ms.translate(0, 0, 5);
FontHelper.drawSplitString(ms, font, title, 0, 0, left.x - 51, Theme.c(Theme.Key.TEXT)
.scaleAlpha(1 - indexDiff)
.getRGB());
ms.popPose();
if (chapter != null) {
ms.pushPose();
ms.translate(chap.x - 8, chap.y, 0);
UIRenderHelper.streak(ms, 180, 4, 10, 26, (int) (150 * fade));
drawRightAlignedString(font, ms, Lang.translateDirect(IN_CHAPTER)
.getString(), 0, 0, tooltipColor);
drawRightAlignedString(font, ms, chapter.getTitle(), 0, 12, Theme.i(Theme.Key.TEXT));
ms.popPose();
}
}
protected void renderNavigationMenu(PoseStack ms) {
Color c1 = Theme.c(Theme.Key.PONDER_BACK_ARROW)
.setAlpha(0x40);
Color c2 = Theme.c(Theme.Key.PONDER_BACK_ARROW)
.setAlpha(0x20);
Color c3 = Theme.c(Theme.Key.PONDER_BACK_ARROW)
.setAlpha(0x10);
UIRenderHelper.breadcrumbArrow(ms, width / 2 - 20, height - 51, 0, 20, 20, 5, c1, c2);
UIRenderHelper.breadcrumbArrow(ms, width / 2 + 20, height - 51, 0, -20, 20, -5, c1, c2);
UIRenderHelper.breadcrumbArrow(ms, width / 2 - 90, height - 51, 0, 70, 20, 5, c1, c3);
UIRenderHelper.breadcrumbArrow(ms, width / 2 + 90, height - 51, 0, -70, 20, -5, c1, c3);
}
private void renderOverlay(PoseStack ms, int i, float partialTicks) {

View File

@ -1,36 +1,50 @@
package com.simibubi.create.foundation.utility;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.annotation.Nonnull;
import net.minecraft.world.level.LevelAccessor;
import net.minecraftforge.common.util.NonNullFunction;
public class WorldAttached<T> {
static List<Map<LevelAccessor, ?>> allMaps = new ArrayList<>();
Map<LevelAccessor, T> attached;
private final NonNullFunction<LevelAccessor, T> factory;
// weak references to prevent leaking hashmaps when a WorldAttached is GC'd during runtime
static List<WeakReference<Map<LevelAccessor, ?>>> allMaps = new ArrayList<>();
private final Map<LevelAccessor, T> attached;
private final Function<LevelAccessor, T> factory;
public WorldAttached(NonNullFunction<LevelAccessor, T> factory) {
public WorldAttached(Function<LevelAccessor, T> factory) {
this.factory = factory;
attached = new HashMap<>();
allMaps.add(attached);
allMaps.add(new WeakReference<>(attached));
}
public static void invalidateWorld(LevelAccessor world) {
allMaps.forEach(m -> m.remove(world));
var i = allMaps.iterator();
while (i.hasNext()) {
Map<LevelAccessor, ?> map = i.next()
.get();
if (map == null) {
// If the map has been GC'd, remove the weak reference
i.remove();
} else {
// Prevent leaks
map.remove(world);
}
}
}
@Nonnull
public T get(LevelAccessor world) {
T t = attached.get(world);
if (t != null)
return t;
if (t != null) return t;
T entry = factory.apply(world);
put(world, entry);
return entry;
@ -40,4 +54,47 @@ public class WorldAttached<T> {
attached.put(world, entry);
}
/**
* Replaces the entry with a new one from the factory and returns the new entry.
*/
@Nonnull
public T replace(LevelAccessor world) {
attached.remove(world);
return get(world);
}
/**
* Replaces the entry with a new one from the factory and returns the new entry.
*/
@Nonnull
public T replace(LevelAccessor world, Consumer<T> finalizer) {
T remove = attached.remove(world);
if (remove != null)
finalizer.accept(remove);
return get(world);
}
/**
* Deletes all entries after calling a function on them.
*
* @param finalizer Do something with all of the world-value pairs
*/
public void empty(BiConsumer<LevelAccessor, T> finalizer) {
attached.forEach(finalizer);
attached.clear();
}
/**
* Deletes all entries after calling a function on them.
*
* @param finalizer Do something with all of the values
*/
public void empty(Consumer<T> finalizer) {
attached.values()
.forEach(finalizer);
attached.clear();
}
}

View File

@ -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);
}
}

View File

@ -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())

View File

@ -0,0 +1,106 @@
package com.simibubi.create.foundation.worldgen;
import java.util.HashMap;
import java.util.Map;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.data.DynamicDataProvider;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.worldgen.OreFeatureConfigEntry.DatagenExtension;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.data.DataGenerator;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BiomeTags;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.data.event.GatherDataEvent;
public class AllOreFeatureConfigEntries {
public static final OreFeatureConfigEntry ZINC_ORE =
create("zinc_ore", 12, 8, -63, 70)
.standardDatagenExt()
.withBlocks(Couple.create(AllBlocks.ZINC_ORE, AllBlocks.DEEPSLATE_ZINC_ORE))
.biomeTag(BiomeTags.IS_OVERWORLD)
.parent();
public static final OreFeatureConfigEntry STRIATED_ORES_OVERWORLD =
create("striated_ores_overworld", 32, 1 / 12f, -30, 70)
.layeredDatagenExt()
.withLayerPattern(AllLayerPatterns.SCORIA)
.withLayerPattern(AllLayerPatterns.CINNABAR)
.withLayerPattern(AllLayerPatterns.MAGNETITE)
.withLayerPattern(AllLayerPatterns.MALACHITE)
.withLayerPattern(AllLayerPatterns.LIMESTONE)
.withLayerPattern(AllLayerPatterns.OCHRESTONE)
.biomeTag(BiomeTags.IS_OVERWORLD)
.parent();
public static final OreFeatureConfigEntry STRIATED_ORES_NETHER =
create("striated_ores_nether", 32, 1 / 12f, 40, 90)
.layeredDatagenExt()
.withLayerPattern(AllLayerPatterns.SCORIA_NETHER)
.withLayerPattern(AllLayerPatterns.SCORCHIA_NETHER)
.biomeTag(BiomeTags.IS_NETHER)
.parent();
//
private static OreFeatureConfigEntry create(String name, int clusterSize, float frequency,
int minHeight, int maxHeight) {
ResourceLocation id = Create.asResource(name);
OreFeatureConfigEntry configDrivenFeatureEntry = new OreFeatureConfigEntry(id, clusterSize, frequency, minHeight, maxHeight);
return configDrivenFeatureEntry;
}
public static void fillConfig(ForgeConfigSpec.Builder builder, String namespace) {
OreFeatureConfigEntry.ALL
.forEach((id, entry) -> {
if (id.getNamespace().equals(namespace)) {
builder.push(entry.getName());
entry.addToConfig(builder);
builder.pop();
}
});
}
public static void init() {}
public static void gatherData(GatherDataEvent event) {
DataGenerator generator = event.getGenerator();
RegistryAccess registryAccess = RegistryAccess.BUILTIN.get();
//
Map<ResourceLocation, ConfiguredFeature<?, ?>> configuredFeatures = new HashMap<>();
for (Map.Entry<ResourceLocation, OreFeatureConfigEntry> entry : OreFeatureConfigEntry.ALL.entrySet()) {
DatagenExtension datagenExt = entry.getValue().datagenExt();
if (datagenExt != null) {
configuredFeatures.put(entry.getKey(), datagenExt.getConfiguredFeature());
}
}
DynamicDataProvider<ConfiguredFeature<?, ?>> configuredFeatureProvider = DynamicDataProvider.create(generator, "Create's Configured Features", registryAccess, Registry.CONFIGURED_FEATURE_REGISTRY, configuredFeatures);
if (configuredFeatureProvider != null) {
generator.addProvider(true, configuredFeatureProvider);
}
//
Map<ResourceLocation, PlacedFeature> placedFeatures = new HashMap<>();
for (Map.Entry<ResourceLocation, OreFeatureConfigEntry> entry : OreFeatureConfigEntry.ALL.entrySet()) {
DatagenExtension datagenExt = entry.getValue().datagenExt();
if (datagenExt != null) {
placedFeatures.put(entry.getKey(), datagenExt.getPlacedFeature());
}
}
DynamicDataProvider<PlacedFeature> placedFeatureProvider = DynamicDataProvider.create(generator, "Create's Placed Features", registryAccess, Registry.PLACED_FEATURE_REGISTRY, placedFeatures);
if (placedFeatureProvider != null) {
generator.addProvider(true, placedFeatureProvider);
}
}
}

View File

@ -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);
}
}

View File

@ -1,129 +0,0 @@
package com.simibubi.create.foundation.worldgen;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.ImmutableList;
import com.google.gson.JsonElement;
import com.mojang.serialization.JsonOps;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.Couple;
import net.minecraft.core.HolderSet;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.data.DataGenerator;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BiomeTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.common.data.JsonCodecProvider;
import net.minecraftforge.common.world.BiomeModifier;
import net.minecraftforge.common.world.ForgeBiomeModifiers.AddFeaturesBiomeModifier;
import net.minecraftforge.data.event.GatherDataEvent;
import net.minecraftforge.registries.ForgeRegistries.Keys;
import net.minecraftforge.registries.RegisterEvent;
public class AllWorldFeatures {
public static final Map<ResourceLocation, ConfigDrivenFeatureEntry> ENTRIES = new HashMap<>();
//
public static final ConfigDrivenFeatureEntry ZINC_ORE =
register("zinc_ore", 12, 8, BiomeTags.IS_OVERWORLD).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, BiomeTags.IS_OVERWORLD).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, BiomeTags.IS_NETHER).between(40, 90)
.withLayerPattern(AllLayerPatterns.SCORIA_NETHER)
.withLayerPattern(AllLayerPatterns.SCORCHIA_NETHER);
//
private static ConfigDrivenFeatureEntry register(String id, int clusterSize, float frequency,
TagKey<Biome> biomeTag) {
ConfigDrivenFeatureEntry configDrivenFeatureEntry = new ConfigDrivenFeatureEntry(id, clusterSize, frequency);
configDrivenFeatureEntry.biomeTag = biomeTag;
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 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(RegisterEvent event) {
event.register(Registry.FEATURE_REGISTRY, helper -> {
helper.register(Create.asResource("config_driven_ore"), VanillaStyleOreFeature.INSTANCE);
helper.register(Create.asResource("config_driven_layered_ore"), LayeredOreFeature.INSTANCE);
});
}
public static void registerPlacementTypes() {
ConfigDrivenDecorator.TYPE =
Registry.register(Registry.PLACEMENT_MODIFIERS, "create_config_driven", () -> ConfigDrivenDecorator.CODEC);
}
public static void generateBiomeModifiers(GatherDataEvent event) {
Map<ResourceLocation, BiomeModifier> modifiers = new HashMap<>();
RegistryOps<JsonElement> ops = RegistryOps.create(JsonOps.INSTANCE, RegistryAccess.builtinCopy());
for (Entry<ResourceLocation, ConfigDrivenFeatureEntry> entry : ENTRIES.entrySet()) {
ConfigDrivenFeatureEntry feature = entry.getValue();
HolderSet<Biome> biomes = new HolderSet.Named<>(ops.registry(Registry.BIOME_REGISTRY)
.get(), feature.biomeTag);
modifiers.put(entry.getKey(), new AddFeaturesBiomeModifier(biomes, HolderSet.direct(feature.placedFeature),
Decoration.UNDERGROUND_ORES));
}
DataGenerator generator = event.getGenerator();
generator.addProvider(event.includeServer(), JsonCodecProvider.forDatapackRegistry(generator,
event.getExistingFileHelper(), Create.ID, ops, Keys.BIOME_MODIFIERS, modifiers));
}
}

View File

@ -2,24 +2,25 @@ package com.simibubi.create.foundation.worldgen;
import java.util.function.Function;
import com.mojang.serialization.Codec;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
public abstract class 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,
RandomSource pRandom, ConfigDrivenOreConfiguration pConfig, OreConfiguration.TargetBlockState pTargetState,
RandomSource 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);

View File

@ -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;
}
}

View File

@ -1,11 +0,0 @@
package com.simibubi.create.foundation.worldgen;
import java.util.function.Function;
import net.minecraft.core.HolderSet;
import net.minecraft.resources.RegistryOps;
import net.minecraft.world.level.biome.Biome;
public interface BiomeFilter extends Function<RegistryOps<?>, HolderSet<Biome>> {
}

View File

@ -0,0 +1,41 @@
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.common.world.BiomeModifier;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
public class BuiltinRegistration {
private static final DeferredRegister<ConfiguredFeature<?, ?>> CONFIGURED_FEATURE_REGISTER = DeferredRegister.create(Registry.CONFIGURED_FEATURE_REGISTRY, Create.ID);
private static final DeferredRegister<PlacedFeature> PLACED_FEATURE_REGISTER = DeferredRegister.create(Registry.PLACED_FEATURE_REGISTRY, Create.ID);
private static final DeferredRegister<BiomeModifier> BIOME_MODIFIER_REGISTER = DeferredRegister.create(ForgeRegistries.Keys.BIOME_MODIFIERS, Create.ID);
static {
for (Map.Entry<ResourceLocation, OreFeatureConfigEntry> entry : OreFeatureConfigEntry.ALL.entrySet()) {
ResourceLocation id = entry.getKey();
if (id.getNamespace().equals(Create.ID)) {
DatagenExtension datagenExt = entry.getValue().datagenExt();
if (datagenExt != null) {
CONFIGURED_FEATURE_REGISTER.register(id.getPath(), () -> datagenExt.getConfiguredFeature());
PLACED_FEATURE_REGISTER.register(id.getPath(), () -> datagenExt.getPlacedFeature());
BIOME_MODIFIER_REGISTER.register(id.getPath(), () -> datagenExt.getBiomeModifier());
}
}
}
}
public static void register(IEventBus modEventBus) {
CONFIGURED_FEATURE_REGISTER.register(modEventBus);
PLACED_FEATURE_REGISTER.register(modEventBus);
BIOME_MODIFIER_REGISTER.register(modEventBus);
}
}

View File

@ -1,67 +0,0 @@
package com.simibubi.create.foundation.worldgen;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.simibubi.create.Create;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.levelgen.placement.PlacementContext;
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
public class 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, RandomSource 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);
}
}

View File

@ -1,120 +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.tags.TagKey;
import net.minecraft.world.level.biome.Biome;
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 TagKey<Biome> biomeTag;
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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,79 @@
package com.simibubi.create.foundation.worldgen;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.simibubi.create.foundation.config.AllConfigs;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.levelgen.placement.PlacementContext;
import net.minecraft.world.level.levelgen.placement.PlacementModifier;
import net.minecraft.world.level.levelgen.placement.PlacementModifierType;
public class ConfigDrivenPlacement extends PlacementModifier {
public static final Codec<ConfigDrivenPlacement> CODEC = RecordCodecBuilder.create(instance -> {
return instance.group(
OreFeatureConfigEntry.CODEC
.fieldOf("entry")
.forGetter(ConfigDrivenPlacement::getEntry)
).apply(instance, ConfigDrivenPlacement::new);
});
private final OreFeatureConfigEntry entry;
public ConfigDrivenPlacement(OreFeatureConfigEntry entry) {
this.entry = entry;
}
@Override
public Stream<BlockPos> getPositions(PlacementContext context, RandomSource random, BlockPos pos) {
int count = getCount(getFrequency(), random);
if (count == 0) {
return Stream.empty();
}
int minY = getMinY();
int maxY = getMaxY();
return IntStream.range(0, count)
.mapToObj(i -> pos)
.map(p -> {
int x = random.nextInt(16) + p.getX();
int z = random.nextInt(16) + p.getZ();
int y = Mth.randomBetweenInclusive(random, minY, maxY);
return new BlockPos(x, y, z);
});
}
public int getCount(float frequency, RandomSource random) {
int floored = Mth.floor(frequency);
return floored + (random.nextFloat() < (frequency - floored) ? 1 : 0);
}
@Override
public PlacementModifierType<?> type() {
return AllPlacementModifiers.CONFIG_DRIVEN.get();
}
public OreFeatureConfigEntry getEntry() {
return entry;
}
public float getFrequency() {
if (AllConfigs.COMMON.worldGen.disable.get())
return 0;
return entry.frequency.getF();
}
public int getMinY() {
return entry.minHeight.get();
}
public int getMaxY() {
return entry.maxHeight.get();
}
}

View File

@ -6,8 +6,9 @@ import java.util.List;
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, RandomSource random) {
@ -49,42 +47,60 @@ public class LayerPattern {
return null;
}
class Builder {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private final List<Layer> layers = new ArrayList<>();
private boolean netherMode;
public LayerPattern build() {
return LayerPattern.this;
}
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(RandomSource 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);
}
}
}
}

View File

@ -1,16 +1,13 @@
package com.simibubi.create.foundation.worldgen;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
@ -22,19 +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 boolean place(FeaturePlaceContext<ConfigDrivenOreConfiguration> pContext) {
public class LayeredOreFeature extends BaseConfigDrivenOreFeature<ConfigDrivenLayeredOreFeatureConfiguration> {
public LayeredOreFeature() {
super(ConfigDrivenLayeredOreFeatureConfiguration.CODEC);
}
@Override
public boolean place(FeaturePlaceContext<ConfigDrivenLayeredOreFeatureConfiguration> pContext) {
RandomSource 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;
@ -42,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;
@ -146,5 +142,4 @@ public class LayeredOreFeature extends OreFeatureBase {
bulksectionaccess.close();
return placedAmount > 0;
}
}

View File

@ -0,0 +1,234 @@
package com.simibubi.create.foundation.worldgen;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.Nullable;
import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import com.simibubi.create.foundation.config.ConfigBase;
import com.simibubi.create.foundation.utility.Couple;
import com.tterrag.registrate.util.nullness.NonNullSupplier;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderSet;
import net.minecraft.core.Registry;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.data.worldgen.features.OreFeatures;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.levelgen.GenerationStep.Decoration;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration.TargetBlockState;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.common.world.BiomeModifier;
import net.minecraftforge.common.world.ForgeBiomeModifiers.AddFeaturesBiomeModifier;
public class OreFeatureConfigEntry extends ConfigBase {
public static final Map<ResourceLocation, OreFeatureConfigEntry> ALL = new HashMap<>();
public static final Codec<OreFeatureConfigEntry> CODEC = ResourceLocation.CODEC
.comapFlatMap(OreFeatureConfigEntry::read, entry -> entry.id);
public final ResourceLocation id;
public final ConfigInt clusterSize;
public final ConfigFloat frequency;
public final ConfigInt minHeight;
public final ConfigInt maxHeight;
private DatagenExtension datagenExt;
public OreFeatureConfigEntry(ResourceLocation id, int clusterSize, float frequency, int minHeight, int maxHeight) {
this.id = id;
this.clusterSize = i(clusterSize, 0, "clusterSize");
this.frequency = f(frequency, 0, 512, "frequency", "Amount of clusters generated per Chunk.",
" >1 to spawn multiple.", " <1 to make it a chance.", " 0 to disable.");
this.minHeight = i(minHeight, "minHeight");
this.maxHeight = i(maxHeight, "maxHeight");
ALL.put(id, this);
}
@Nullable
public StandardDatagenExtension standardDatagenExt() {
if (datagenExt == null) {
datagenExt = new StandardDatagenExtension();
}
if (datagenExt instanceof StandardDatagenExtension standard) {
return standard;
}
return null;
}
@Nullable
public LayeredDatagenExtension layeredDatagenExt() {
if (datagenExt == null) {
datagenExt = new LayeredDatagenExtension();
}
if (datagenExt instanceof LayeredDatagenExtension layered) {
return layered;
}
return null;
}
@Nullable
public DatagenExtension datagenExt() {
if (datagenExt != null) {
return datagenExt;
}
return null;
}
public void addToConfig(ForgeConfigSpec.Builder builder) {
registerAll(builder);
}
@Override
public String getName() {
return id.getPath();
}
public static DataResult<OreFeatureConfigEntry> read(ResourceLocation id) {
OreFeatureConfigEntry entry = ALL.get(id);
if (entry != null) {
return DataResult.success(entry);
} else {
return DataResult.error("Not a valid OreFeatureConfigEntry: " + id);
}
}
public abstract class DatagenExtension {
public TagKey<Biome> biomeTag;
protected ConfiguredFeature<?, ?> configuredFeature;
protected PlacedFeature placedFeature;
protected BiomeModifier biomeModifier;
public DatagenExtension biomeTag(TagKey<Biome> biomes) {
this.biomeTag = biomes;
return this;
}
public abstract ConfiguredFeature<?, ?> getConfiguredFeature();
public PlacedFeature getPlacedFeature() {
if (placedFeature != null) {
return placedFeature;
}
Holder<ConfiguredFeature<?, ?>> featureHolder = BuiltinRegistries.CONFIGURED_FEATURE.getOrCreateHolderOrThrow(ResourceKey.create(Registry.CONFIGURED_FEATURE_REGISTRY, id));
placedFeature = new PlacedFeature(featureHolder, List.of(new ConfigDrivenPlacement(OreFeatureConfigEntry.this)));
return placedFeature;
}
public BiomeModifier getBiomeModifier() {
if (biomeModifier != null) {
return biomeModifier;
}
@SuppressWarnings("deprecation")
HolderSet<Biome> biomes = new HolderSet.Named<>(BuiltinRegistries.BIOME, biomeTag);
Holder<PlacedFeature> featureHolder = BuiltinRegistries.PLACED_FEATURE.getOrCreateHolderOrThrow(ResourceKey.create(Registry.PLACED_FEATURE_REGISTRY, id));
biomeModifier = new AddFeaturesBiomeModifier(biomes, HolderSet.direct(featureHolder), Decoration.UNDERGROUND_ORES);
return biomeModifier;
}
public OreFeatureConfigEntry parent() {
return OreFeatureConfigEntry.this;
}
}
public class StandardDatagenExtension extends DatagenExtension {
public NonNullSupplier<? extends Block> block;
public NonNullSupplier<? extends Block> deepBlock;
public NonNullSupplier<? extends Block> netherBlock;
public StandardDatagenExtension withBlock(NonNullSupplier<? extends Block> block) {
this.block = block;
this.deepBlock = block;
return this;
}
public StandardDatagenExtension withBlocks(Couple<NonNullSupplier<? extends Block>> blocks) {
this.block = blocks.getFirst();
this.deepBlock = blocks.getSecond();
return this;
}
public StandardDatagenExtension withNetherBlock(NonNullSupplier<? extends Block> block) {
this.netherBlock = block;
return this;
}
@Override
public StandardDatagenExtension biomeTag(TagKey<Biome> biomes) {
super.biomeTag(biomes);
return this;
}
@Override
public ConfiguredFeature<?, ?> 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 LayeredDatagenExtension biomeTag(TagKey<Biome> biomes) {
super.biomeTag(biomes);
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;
}
}
}

View File

@ -0,0 +1,168 @@
package com.simibubi.create.foundation.worldgen;
import java.util.BitSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.BulkSectionAccess;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
public class StandardOreFeature extends BaseConfigDrivenOreFeature<ConfigDrivenOreFeatureConfiguration> {
public StandardOreFeature() {
super(ConfigDrivenOreFeatureConfiguration.CODEC);
}
// From OreFeature, slight adjustments
@Override
public boolean place(FeaturePlaceContext<ConfigDrivenOreFeatureConfiguration> pContext) {
RandomSource random = pContext.random();
BlockPos blockpos = pContext.origin();
WorldGenLevel worldgenlevel = pContext.level();
ConfigDrivenOreFeatureConfiguration oreconfiguration = pContext.config();
float f = random.nextFloat() * (float)Math.PI;
float f1 = (float)oreconfiguration.getClusterSize() / 8.0F;
int i = Mth.ceil(((float)oreconfiguration.getClusterSize() / 16.0F * 2.0F + 1.0F) / 2.0F);
double d0 = (double)blockpos.getX() + Math.sin((double)f) * (double)f1;
double d1 = (double)blockpos.getX() - Math.sin((double)f) * (double)f1;
double d2 = (double)blockpos.getZ() + Math.cos((double)f) * (double)f1;
double d3 = (double)blockpos.getZ() - Math.cos((double)f) * (double)f1;
double d4 = (double)(blockpos.getY() + random.nextInt(3) - 2);
double d5 = (double)(blockpos.getY() + random.nextInt(3) - 2);
int k = blockpos.getX() - Mth.ceil(f1) - i;
int l = blockpos.getY() - 2 - i;
int i1 = blockpos.getZ() - Mth.ceil(f1) - i;
int j1 = 2 * (Mth.ceil(f1) + i);
int k1 = 2 * (2 + i);
for(int l1 = k; l1 <= k + j1; ++l1) {
for(int i2 = i1; i2 <= i1 + j1; ++i2) {
if (l <= worldgenlevel.getHeight(Heightmap.Types.OCEAN_FLOOR_WG, l1, i2)) {
return this.doPlace(worldgenlevel, random, oreconfiguration, d0, d1, d2, d3, d4, d5, k, l, i1, j1, k1);
}
}
}
return false;
}
protected boolean doPlace(WorldGenLevel pLevel, RandomSource pRandom, ConfigDrivenOreFeatureConfiguration pConfig, double pMinX,
double pMaxX, double pMinZ, double pMaxZ, double pMinY, double pMaxY, int pX, int pY, int pZ, int pWidth,
int pHeight) {
int i = 0;
BitSet bitset = new BitSet(pWidth * pHeight * pWidth);
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
int j = pConfig.getClusterSize();
double[] adouble = new double[j * 4];
for(int k = 0; k < j; ++k) {
float f = (float)k / (float)j;
double d0 = Mth.lerp((double)f, pMinX, pMaxX);
double d1 = Mth.lerp((double)f, pMinY, pMaxY);
double d2 = Mth.lerp((double)f, pMinZ, pMaxZ);
double d3 = pRandom.nextDouble() * (double)j / 16.0D;
double d4 = ((double)(Mth.sin((float)Math.PI * f) + 1.0F) * d3 + 1.0D) / 2.0D;
adouble[k * 4 + 0] = d0;
adouble[k * 4 + 1] = d1;
adouble[k * 4 + 2] = d2;
adouble[k * 4 + 3] = d4;
}
for(int l3 = 0; l3 < j - 1; ++l3) {
if (!(adouble[l3 * 4 + 3] <= 0.0D)) {
for(int i4 = l3 + 1; i4 < j; ++i4) {
if (!(adouble[i4 * 4 + 3] <= 0.0D)) {
double d8 = adouble[l3 * 4 + 0] - adouble[i4 * 4 + 0];
double d10 = adouble[l3 * 4 + 1] - adouble[i4 * 4 + 1];
double d12 = adouble[l3 * 4 + 2] - adouble[i4 * 4 + 2];
double d14 = adouble[l3 * 4 + 3] - adouble[i4 * 4 + 3];
if (d14 * d14 > d8 * d8 + d10 * d10 + d12 * d12) {
if (d14 > 0.0D) {
adouble[i4 * 4 + 3] = -1.0D;
} else {
adouble[l3 * 4 + 3] = -1.0D;
}
}
}
}
}
}
BulkSectionAccess bulksectionaccess = new BulkSectionAccess(pLevel);
try {
for(int j4 = 0; j4 < j; ++j4) {
double d9 = adouble[j4 * 4 + 3];
if (!(d9 < 0.0D)) {
double d11 = adouble[j4 * 4 + 0];
double d13 = adouble[j4 * 4 + 1];
double d15 = adouble[j4 * 4 + 2];
int k4 = Math.max(Mth.floor(d11 - d9), pX);
int l = Math.max(Mth.floor(d13 - d9), pY);
int i1 = Math.max(Mth.floor(d15 - d9), pZ);
int j1 = Math.max(Mth.floor(d11 + d9), k4);
int k1 = Math.max(Mth.floor(d13 + d9), l);
int l1 = Math.max(Mth.floor(d15 + d9), i1);
for(int i2 = k4; i2 <= j1; ++i2) {
double d5 = ((double)i2 + 0.5D - d11) / d9;
if (d5 * d5 < 1.0D) {
for(int j2 = l; j2 <= k1; ++j2) {
double d6 = ((double)j2 + 0.5D - d13) / d9;
if (d5 * d5 + d6 * d6 < 1.0D) {
for(int k2 = i1; k2 <= l1; ++k2) {
double d7 = ((double)k2 + 0.5D - d15) / d9;
if (d5 * d5 + d6 * d6 + d7 * d7 < 1.0D && !pLevel.isOutsideBuildHeight(j2)) {
int l2 = i2 - pX + (j2 - pY) * pWidth + (k2 - pZ) * pWidth * pHeight;
if (!bitset.get(l2)) {
bitset.set(l2);
blockpos$mutableblockpos.set(i2, j2, k2);
if (pLevel.ensureCanWrite(blockpos$mutableblockpos)) {
LevelChunkSection levelchunksection = bulksectionaccess.getSection(blockpos$mutableblockpos);
if (levelchunksection != null) {
int i3 = SectionPos.sectionRelative(i2);
int j3 = SectionPos.sectionRelative(j2);
int k3 = SectionPos.sectionRelative(k2);
BlockState blockstate = levelchunksection.getBlockState(i3, j3, k3);
for(OreConfiguration.TargetBlockState oreconfiguration$targetblockstate : pConfig.getTargetStates()) {
if (canPlaceOre(blockstate, bulksectionaccess::getBlockState, pRandom, pConfig, oreconfiguration$targetblockstate, blockpos$mutableblockpos)) {
levelchunksection.setBlockState(i3, j3, k3, oreconfiguration$targetblockstate.state, false);
++i;
break;
}
}
}
}
}
}
}
}
}
}
}
}
}
} catch (Throwable throwable1) {
try {
bulksectionaccess.close();
} catch (Throwable throwable) {
throwable1.addSuppressed(throwable);
}
throw throwable1;
}
bulksectionaccess.close();
return i > 0;
}
}

View File

@ -1,172 +0,0 @@
package com.simibubi.create.foundation.worldgen;
import java.util.BitSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.BulkSectionAccess;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration;
public class VanillaStyleOreFeature extends OreFeatureBase {
public static final VanillaStyleOreFeature INSTANCE = new VanillaStyleOreFeature();
// From OreFeature, slight adjustments
public boolean place(FeaturePlaceContext<ConfigDrivenOreConfiguration> pContext) {
RandomSource 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, RandomSource 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;
}
}