mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-11 04:22:00 +01:00
Register world features properlyTM
- Refactored Create's config-driven worldgen to better work with the feature infrastructure of 1.16. Adresses #539
This commit is contained in:
parent
01a83722cf
commit
dc13ea6485
10 changed files with 370 additions and 260 deletions
|
@ -84,6 +84,7 @@ public class Create {
|
||||||
AllEntityTypes.register();
|
AllEntityTypes.register();
|
||||||
AllTileEntities.register();
|
AllTileEntities.register();
|
||||||
AllMovementBehaviours.register();
|
AllMovementBehaviours.register();
|
||||||
|
AllWorldFeatures.register();
|
||||||
|
|
||||||
modEventBus.addListener(Create::init);
|
modEventBus.addListener(Create::init);
|
||||||
MinecraftForge.EVENT_BUS.addListener(EventPriority.HIGH, Create::onBiomeLoad);
|
MinecraftForge.EVENT_BUS.addListener(EventPriority.HIGH, Create::onBiomeLoad);
|
||||||
|
@ -118,6 +119,7 @@ public class Create {
|
||||||
|
|
||||||
event.enqueueWork(() -> {
|
event.enqueueWork(() -> {
|
||||||
SchematicProcessor.register();
|
SchematicProcessor.register();
|
||||||
|
AllWorldFeatures.registerFeatures();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,90 +1,93 @@
|
||||||
package com.simibubi.create.foundation.worldgen;
|
package com.simibubi.create.foundation.worldgen;
|
||||||
|
|
||||||
import static net.minecraft.world.biome.Biome.Category.DESERT;
|
import java.util.HashMap;
|
||||||
import static net.minecraft.world.biome.Biome.Category.OCEAN;
|
import java.util.Map;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.content.palettes.AllPaletteBlocks;
|
import com.simibubi.create.content.palettes.AllPaletteBlocks;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.tterrag.registrate.util.nullness.NonNullSupplier;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.util.registry.WorldGenRegistries;
|
||||||
import net.minecraft.world.biome.Biome.Category;
|
import net.minecraft.world.biome.Biome.Category;
|
||||||
import net.minecraft.world.biome.Biomes;
|
import net.minecraft.world.biome.Biomes;
|
||||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
import net.minecraft.world.gen.GenerationStage;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec;
|
import net.minecraftforge.common.ForgeConfigSpec;
|
||||||
import net.minecraftforge.event.world.BiomeLoadingEvent;
|
import net.minecraftforge.event.world.BiomeLoadingEvent;
|
||||||
|
import net.minecraftforge.registries.ForgeRegistries;
|
||||||
|
|
||||||
public enum AllWorldFeatures {
|
public class AllWorldFeatures {
|
||||||
|
|
||||||
COPPER_ORE(new CountedOreFeature(AllBlocks.COPPER_ORE, 18, 2).between(40, 86)),
|
static Map<String, ConfigDrivenFeatureEntry> entries = new HashMap<>();
|
||||||
COPPER_ORE_OCEAN(new CountedOreFeature(AllBlocks.COPPER_ORE, 15, 4).between(20, 55).inBiomes(OCEAN)),
|
|
||||||
|
|
||||||
ZINC_ORE(new CountedOreFeature(AllBlocks.ZINC_ORE, 14, 4).between(15, 70)),
|
static final ConfigDrivenFeatureEntry
|
||||||
ZINC_ORE_DESERT(new CountedOreFeature(AllBlocks.ZINC_ORE, 17, 5).between(10, 85).inBiomes(DESERT)),
|
|
||||||
|
|
||||||
LIMESTONE(new ChanceOreFeature(AllPaletteBlocks.LIMESTONE, 128, 1 / 32f).between(30, 70)),
|
COPPER = register("copper_ore", AllBlocks.COPPER_ORE, 18, 2).between(40, 85),
|
||||||
WEATHERED_LIMESTONE(new ChanceOreFeature(AllPaletteBlocks.WEATHERED_LIMESTONE, 128, 1 / 32f).between(10, 30)),
|
|
||||||
DOLOMITE(new ChanceOreFeature(AllPaletteBlocks.DOLOMITE, 128, 1 / 64f).between(20, 70)),
|
ZINC = register("zinc_ore", AllBlocks.ZINC_ORE, 14, 4).between(15, 70),
|
||||||
GABBRO(new ChanceOreFeature(AllPaletteBlocks.GABBRO, 128, 1 / 64f).between(20, 70)),
|
|
||||||
SCORIA(new ChanceOreFeature(AllPaletteBlocks.NATURAL_SCORIA, 128, 1 / 32f).between(0, 10)),
|
LIMESTONE = register("limestone", AllPaletteBlocks.LIMESTONE, 128, 1 / 64f).between(30, 70),
|
||||||
|
|
||||||
|
WEATHERED_LIMESTONE =
|
||||||
|
register("weathered_limestone", AllPaletteBlocks.WEATHERED_LIMESTONE, 128, 1 / 64f).between(10, 30),
|
||||||
|
|
||||||
|
DOLOMITE = register("dolomite", AllPaletteBlocks.DOLOMITE, 128, 1 / 64f).between(20, 70),
|
||||||
|
|
||||||
|
GABBRO = register("gabbro", AllPaletteBlocks.GABBRO, 128, 1 / 64f).between(20, 70),
|
||||||
|
|
||||||
|
SCORIA = register("scoria", AllPaletteBlocks.NATURAL_SCORIA, 128, 1 / 32f).between(0, 10)
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
private static ConfigDrivenFeatureEntry register(String id, NonNullSupplier<? extends Block> block, int clusterSize,
|
||||||
|
float frequency) {
|
||||||
|
ConfigDrivenFeatureEntry configDrivenFeatureEntry =
|
||||||
|
new ConfigDrivenFeatureEntry(id, block, clusterSize, frequency);
|
||||||
|
entries.put(id, configDrivenFeatureEntry);
|
||||||
|
return configDrivenFeatureEntry;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increment this number if all worldgen entries should be overwritten in this
|
* Increment this number if all worldgen entries should be overwritten in this
|
||||||
* update. Worlds from the previous version will overwrite potentially changed
|
* update. Worlds from the previous version will overwrite potentially changed
|
||||||
* values with the new defaults.
|
* values with the new defaults.
|
||||||
*/
|
*/
|
||||||
public static final int forcedUpdateVersion = 1;
|
public static final int forcedUpdateVersion = 2;
|
||||||
|
|
||||||
public IFeature feature;
|
public static void registerFeatures() {
|
||||||
|
ForgeRegistries.FEATURES.register(ConfigDrivenOreFeature.INSTANCE);
|
||||||
AllWorldFeatures(IFeature feature) {
|
ForgeRegistries.DECORATORS.register(ConfigDrivenDecorator.INSTANCE);
|
||||||
this.feature = feature;
|
entries.entrySet()
|
||||||
this.feature.setId(Lang.asId(name()));
|
.forEach((entry) -> {
|
||||||
|
Registry.register(WorldGenRegistries.CONFIGURED_FEATURE, Create.ID + "_" + entry.getKey(),
|
||||||
|
entry.getValue()
|
||||||
|
.getFeature());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reload(BiomeLoadingEvent event) {
|
public static void reload(BiomeLoadingEvent event) {
|
||||||
for (AllWorldFeatures entry : AllWorldFeatures.values()) {
|
entries.values()
|
||||||
|
.forEach(entry -> {
|
||||||
if (event.getName() == Biomes.THE_VOID.getRegistryName())
|
if (event.getName() == Biomes.THE_VOID.getRegistryName())
|
||||||
continue;
|
return;
|
||||||
if (event.getCategory() == Category.NETHER)
|
if (event.getCategory() == Category.NETHER)
|
||||||
continue;
|
return;
|
||||||
|
event.getGeneration()
|
||||||
Optional<ConfiguredFeature<?, ?>> createFeature = entry.feature.createFeature(event);
|
.feature(GenerationStage.Decoration.UNDERGROUND_ORES, entry.getFeature());
|
||||||
if (!createFeature.isPresent())
|
});
|
||||||
continue;
|
|
||||||
|
|
||||||
event.getGeneration().feature(entry.feature.getGenerationStage(), createFeature.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Debug contained ore features
|
|
||||||
// for (Biome biome : ForgeRegistries.BIOMES) {
|
|
||||||
// Debug.markTemporary();
|
|
||||||
// System.out.println(biome.getRegistryName().getPath() + " has the following features:");
|
|
||||||
// for (ConfiguredFeature<?> configuredFeature : biome.getFeatures(Decoration.UNDERGROUND_ORES)) {
|
|
||||||
// IFeatureConfig config = configuredFeature.config;
|
|
||||||
// if (!(config instanceof DecoratedFeatureConfig))
|
|
||||||
// continue;
|
|
||||||
// DecoratedFeatureConfig decoConf = (DecoratedFeatureConfig) config;
|
|
||||||
// if (!(decoConf.feature.config instanceof OreFeatureConfig))
|
|
||||||
// continue;
|
|
||||||
// OreFeatureConfig oreConf = (OreFeatureConfig) decoConf.feature.config;
|
|
||||||
// System.out.println(configuredFeature.feature.getRegistryName().getPath());
|
|
||||||
// System.out.println(oreConf.state.getBlock().getRegistryName().getPath());
|
|
||||||
// System.out.println("--");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void fillConfig(ForgeConfigSpec.Builder builder) {
|
public static void fillConfig(ForgeConfigSpec.Builder builder) {
|
||||||
Arrays.stream(values()).forEach(entry -> {
|
entries.values()
|
||||||
builder.push(Lang.asId(entry.name()));
|
.forEach(entry -> {
|
||||||
entry.feature.addToConfig(builder);
|
builder.push(entry.id);
|
||||||
|
entry.addToConfig(builder);
|
||||||
builder.pop();
|
builder.pop();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void register() {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
package com.simibubi.create.foundation.worldgen;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import com.tterrag.registrate.util.nullness.NonNullSupplier;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.world.gen.placement.ChanceConfig;
|
|
||||||
import net.minecraft.world.gen.placement.Placement;
|
|
||||||
|
|
||||||
public class ChanceOreFeature extends OreFeature<ChanceConfig> {
|
|
||||||
|
|
||||||
private ConfigFloat clusterChance;
|
|
||||||
|
|
||||||
public ChanceOreFeature(NonNullSupplier<? extends Block> block, int clusterSize, float clusterChance) {
|
|
||||||
super(block, clusterSize);
|
|
||||||
this.clusterChance = f(clusterChance, 0, 1, "clusterChance");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean canGenerate() {
|
|
||||||
return super.canGenerate() && clusterChance.get() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Pair<Placement<ChanceConfig>, ChanceConfig> getPlacement() {
|
|
||||||
return Pair.of(Placement.CHANCE,
|
|
||||||
// TODO 1.16 worldgen verify this
|
|
||||||
new ChanceConfig((int) (1 / clusterChance.getF())));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.simibubi.create.foundation.worldgen;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.world.gen.placement.SimplePlacement;
|
||||||
|
|
||||||
|
public class ConfigDrivenDecorator extends SimplePlacement<ConfigDrivenOreFeatureConfig> {
|
||||||
|
|
||||||
|
public static final ConfigDrivenDecorator INSTANCE = new ConfigDrivenDecorator();
|
||||||
|
|
||||||
|
public ConfigDrivenDecorator() {
|
||||||
|
super(ConfigDrivenOreFeatureConfig.CODEC);
|
||||||
|
setRegistryName("create_config_driven_decorator");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Stream<BlockPos> getPositions(Random r, ConfigDrivenOreFeatureConfig config, BlockPos pos) {
|
||||||
|
float frequency = config.getFrequency();
|
||||||
|
|
||||||
|
int floored = MathHelper.floor(frequency);
|
||||||
|
int count = floored + (r.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 = r.nextInt(maxY - minY) + minY;
|
||||||
|
return new BlockPos(i, k, j);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.simibubi.create.foundation.worldgen;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.config.ConfigBase;
|
||||||
|
import com.tterrag.registrate.util.nullness.NonNullSupplier;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||||
|
import net.minecraft.world.gen.feature.OreFeatureConfig.FillerBlockType;
|
||||||
|
import net.minecraftforge.common.ForgeConfigSpec;
|
||||||
|
|
||||||
|
public class ConfigDrivenFeatureEntry extends ConfigBase {
|
||||||
|
|
||||||
|
public final String id;
|
||||||
|
public final NonNullSupplier<? extends Block> block;
|
||||||
|
|
||||||
|
protected ConfigInt clusterSize;
|
||||||
|
protected ConfigInt minHeight;
|
||||||
|
protected ConfigInt maxHeight;
|
||||||
|
protected ConfigFloat frequency;
|
||||||
|
|
||||||
|
Optional<ConfiguredFeature<?, ?>> feature = Optional.empty();
|
||||||
|
|
||||||
|
public ConfigDrivenFeatureEntry(String id, NonNullSupplier<? extends Block> block, int clusterSize,
|
||||||
|
float frequency) {
|
||||||
|
this.id = id;
|
||||||
|
this.block = block;
|
||||||
|
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 between(int minHeight, int maxHeight) {
|
||||||
|
allValues.remove(this.minHeight);
|
||||||
|
allValues.remove(this.maxHeight);
|
||||||
|
this.minHeight = i(minHeight, 0, "minHeight");
|
||||||
|
this.maxHeight = i(maxHeight, 0, "maxHeight");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfiguredFeature<?, ?> getFeature() {
|
||||||
|
if (!feature.isPresent())
|
||||||
|
feature = Optional.of(createFeature());
|
||||||
|
return feature.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfiguredFeature<?, ?> createFeature() {
|
||||||
|
ConfigDrivenOreFeatureConfig config =
|
||||||
|
new ConfigDrivenOreFeatureConfig(FillerBlockType.BASE_STONE_OVERWORLD, block.get()
|
||||||
|
.getDefaultState(), id);
|
||||||
|
|
||||||
|
return ConfigDrivenOreFeature.INSTANCE.configure(config)
|
||||||
|
.decorate(ConfigDrivenDecorator.INSTANCE.configure(config));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToConfig(ForgeConfigSpec.Builder builder) {
|
||||||
|
registerAll(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
package com.simibubi.create.foundation.worldgen;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.world.ISeedReader;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
|
import net.minecraft.world.gen.ChunkGenerator;
|
||||||
|
import net.minecraft.world.gen.Heightmap;
|
||||||
|
import net.minecraft.world.gen.feature.Feature;
|
||||||
|
|
||||||
|
public class ConfigDrivenOreFeature extends Feature<ConfigDrivenOreFeatureConfig> {
|
||||||
|
|
||||||
|
public static final ConfigDrivenOreFeature INSTANCE = new ConfigDrivenOreFeature();
|
||||||
|
|
||||||
|
public ConfigDrivenOreFeature() {
|
||||||
|
super(ConfigDrivenOreFeatureConfig.CODEC);
|
||||||
|
setRegistryName("create_config_driven_ore");
|
||||||
|
}
|
||||||
|
|
||||||
|
// From OreFeature, slight adjustments
|
||||||
|
|
||||||
|
public boolean generate(ISeedReader p_241855_1_, ChunkGenerator p_241855_2_, Random p_241855_3_,
|
||||||
|
BlockPos p_241855_4_, ConfigDrivenOreFeatureConfig p_241855_5_) {
|
||||||
|
float f = p_241855_3_.nextFloat() * (float) Math.PI;
|
||||||
|
float size = p_241855_5_.getSize();
|
||||||
|
float f1 = size / 8.0F;
|
||||||
|
int i = MathHelper.ceil((size / 16.0F * 2.0F + 1.0F) / 2.0F);
|
||||||
|
double d0 = (double) p_241855_4_.getX() + Math.sin((double) f) * (double) f1;
|
||||||
|
double d1 = (double) p_241855_4_.getX() - Math.sin((double) f) * (double) f1;
|
||||||
|
double d2 = (double) p_241855_4_.getZ() + Math.cos((double) f) * (double) f1;
|
||||||
|
double d3 = (double) p_241855_4_.getZ() - Math.cos((double) f) * (double) f1;
|
||||||
|
double d4 = (double) (p_241855_4_.getY() + p_241855_3_.nextInt(3) - 2);
|
||||||
|
double d5 = (double) (p_241855_4_.getY() + p_241855_3_.nextInt(3) - 2);
|
||||||
|
int k = p_241855_4_.getX() - MathHelper.ceil(f1) - i;
|
||||||
|
int l = p_241855_4_.getY() - 2 - i;
|
||||||
|
int i1 = p_241855_4_.getZ() - MathHelper.ceil(f1) - i;
|
||||||
|
int j1 = 2 * (MathHelper.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 <= p_241855_1_.getHeight(Heightmap.Type.OCEAN_FLOOR_WG, l1, i2)) {
|
||||||
|
return this.func_207803_a(p_241855_1_, p_241855_3_, p_241855_5_, d0, d1, d2, d3, d4, d5, k, l, i1,
|
||||||
|
j1, k1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean func_207803_a(IWorld p_207803_1_, Random p_207803_2_, ConfigDrivenOreFeatureConfig p_207803_3_,
|
||||||
|
double p_207803_4_, double p_207803_6_, double p_207803_8_, double p_207803_10_, double p_207803_12_,
|
||||||
|
double p_207803_14_, int p_207803_16_, int p_207803_17_, int p_207803_18_, int p_207803_19_, int p_207803_20_) {
|
||||||
|
int i = 0;
|
||||||
|
BitSet bitset = new BitSet(p_207803_19_ * p_207803_20_ * p_207803_19_);
|
||||||
|
BlockPos.Mutable blockpos$mutable = new BlockPos.Mutable();
|
||||||
|
int j = p_207803_3_.getSize();
|
||||||
|
double[] adouble = new double[j * 4];
|
||||||
|
|
||||||
|
for (int k = 0; k < j; ++k) {
|
||||||
|
float f = (float) k / (float) j;
|
||||||
|
double d0 = MathHelper.lerp((double) f, p_207803_4_, p_207803_6_);
|
||||||
|
double d2 = MathHelper.lerp((double) f, p_207803_12_, p_207803_14_);
|
||||||
|
double d4 = MathHelper.lerp((double) f, p_207803_8_, p_207803_10_);
|
||||||
|
double d6 = p_207803_2_.nextDouble() * (double) j / 16.0D;
|
||||||
|
double d7 = ((double) (MathHelper.sin((float) Math.PI * f) + 1.0F) * d6 + 1.0D) / 2.0D;
|
||||||
|
adouble[k * 4 + 0] = d0;
|
||||||
|
adouble[k * 4 + 1] = d2;
|
||||||
|
adouble[k * 4 + 2] = d4;
|
||||||
|
adouble[k * 4 + 3] = d7;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i3 = 0; i3 < j - 1; ++i3) {
|
||||||
|
if (!(adouble[i3 * 4 + 3] <= 0.0D)) {
|
||||||
|
for (int k3 = i3 + 1; k3 < j; ++k3) {
|
||||||
|
if (!(adouble[k3 * 4 + 3] <= 0.0D)) {
|
||||||
|
double d12 = adouble[i3 * 4 + 0] - adouble[k3 * 4 + 0];
|
||||||
|
double d13 = adouble[i3 * 4 + 1] - adouble[k3 * 4 + 1];
|
||||||
|
double d14 = adouble[i3 * 4 + 2] - adouble[k3 * 4 + 2];
|
||||||
|
double d15 = adouble[i3 * 4 + 3] - adouble[k3 * 4 + 3];
|
||||||
|
if (d15 * d15 > d12 * d12 + d13 * d13 + d14 * d14) {
|
||||||
|
if (d15 > 0.0D) {
|
||||||
|
adouble[k3 * 4 + 3] = -1.0D;
|
||||||
|
} else {
|
||||||
|
adouble[i3 * 4 + 3] = -1.0D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j3 = 0; j3 < j; ++j3) {
|
||||||
|
double d11 = adouble[j3 * 4 + 3];
|
||||||
|
if (!(d11 < 0.0D)) {
|
||||||
|
double d1 = adouble[j3 * 4 + 0];
|
||||||
|
double d3 = adouble[j3 * 4 + 1];
|
||||||
|
double d5 = adouble[j3 * 4 + 2];
|
||||||
|
int l = Math.max(MathHelper.floor(d1 - d11), p_207803_16_);
|
||||||
|
int l3 = Math.max(MathHelper.floor(d3 - d11), p_207803_17_);
|
||||||
|
int i1 = Math.max(MathHelper.floor(d5 - d11), p_207803_18_);
|
||||||
|
int j1 = Math.max(MathHelper.floor(d1 + d11), l);
|
||||||
|
int k1 = Math.max(MathHelper.floor(d3 + d11), l3);
|
||||||
|
int l1 = Math.max(MathHelper.floor(d5 + d11), i1);
|
||||||
|
|
||||||
|
for (int i2 = l; i2 <= j1; ++i2) {
|
||||||
|
double d8 = ((double) i2 + 0.5D - d1) / d11;
|
||||||
|
if (d8 * d8 < 1.0D) {
|
||||||
|
for (int j2 = l3; j2 <= k1; ++j2) {
|
||||||
|
double d9 = ((double) j2 + 0.5D - d3) / d11;
|
||||||
|
if (d8 * d8 + d9 * d9 < 1.0D) {
|
||||||
|
for (int k2 = i1; k2 <= l1; ++k2) {
|
||||||
|
double d10 = ((double) k2 + 0.5D - d5) / d11;
|
||||||
|
if (d8 * d8 + d9 * d9 + d10 * d10 < 1.0D) {
|
||||||
|
int l2 = i2 - p_207803_16_ + (j2 - p_207803_17_) * p_207803_19_
|
||||||
|
+ (k2 - p_207803_18_) * p_207803_19_ * p_207803_20_;
|
||||||
|
if (!bitset.get(l2)) {
|
||||||
|
bitset.set(l2);
|
||||||
|
blockpos$mutable.setPos(i2, j2, k2);
|
||||||
|
if (p_207803_3_.target.test(p_207803_1_.getBlockState(blockpos$mutable),
|
||||||
|
p_207803_2_)) {
|
||||||
|
p_207803_1_.setBlockState(blockpos$mutable, p_207803_3_.state, 2);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i > 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.simibubi.create.foundation.worldgen;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.world.gen.feature.IFeatureConfig;
|
||||||
|
import net.minecraft.world.gen.feature.template.RuleTest;
|
||||||
|
import net.minecraft.world.gen.placement.IPlacementConfig;
|
||||||
|
|
||||||
|
public class ConfigDrivenOreFeatureConfig implements IFeatureConfig, IPlacementConfig {
|
||||||
|
|
||||||
|
public static final Codec<ConfigDrivenOreFeatureConfig> CODEC = RecordCodecBuilder.create((p_236568_0_) -> {
|
||||||
|
return p_236568_0_.group(RuleTest.field_25012.fieldOf("target")
|
||||||
|
.forGetter((p_236570_0_) -> {
|
||||||
|
return p_236570_0_.target;
|
||||||
|
}), BlockState.CODEC.fieldOf("state")
|
||||||
|
.forGetter((p_236569_0_) -> {
|
||||||
|
return p_236569_0_.state;
|
||||||
|
}),
|
||||||
|
Codec.STRING.fieldOf("key")
|
||||||
|
.forGetter(t -> t.key))
|
||||||
|
.apply(p_236568_0_, ConfigDrivenOreFeatureConfig::new);
|
||||||
|
});
|
||||||
|
|
||||||
|
public final RuleTest target;
|
||||||
|
public final BlockState state;
|
||||||
|
public final String key;
|
||||||
|
|
||||||
|
public ConfigDrivenOreFeatureConfig(RuleTest target, BlockState state, String key) {
|
||||||
|
this.target = target;
|
||||||
|
this.state = state;
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return entry().clusterSize.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinY() {
|
||||||
|
return entry().minHeight.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxY() {
|
||||||
|
return entry().maxHeight.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getFrequency() {
|
||||||
|
return entry().frequency.getF();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ConfigDrivenFeatureEntry entry() {
|
||||||
|
return AllWorldFeatures.entries.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,41 +0,0 @@
|
||||||
package com.simibubi.create.foundation.worldgen;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import com.tterrag.registrate.util.nullness.NonNullSupplier;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
|
||||||
import net.minecraft.world.gen.placement.IPlacementConfig;
|
|
||||||
import net.minecraft.world.gen.placement.NoPlacementConfig;
|
|
||||||
import net.minecraft.world.gen.placement.Placement;
|
|
||||||
import net.minecraftforge.event.world.BiomeLoadingEvent;
|
|
||||||
|
|
||||||
public class CountedOreFeature extends OreFeature<NoPlacementConfig> {
|
|
||||||
|
|
||||||
private ConfigInt clusterCount;
|
|
||||||
|
|
||||||
public CountedOreFeature(NonNullSupplier<? extends Block> block, int clusterSize, int clusterCount) {
|
|
||||||
super(block, clusterSize);
|
|
||||||
this.clusterCount = i(clusterCount, 0, "clusterCount");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean canGenerate() {
|
|
||||||
return super.canGenerate() && clusterCount.get() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Pair<Placement<NoPlacementConfig>, NoPlacementConfig> getPlacement() {
|
|
||||||
return Pair.of(Placement.NOPE, IPlacementConfig.NO_PLACEMENT_CONFIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<ConfiguredFeature<?, ?>> createFeature(BiomeLoadingEvent biome) {
|
|
||||||
return super.createFeature(biome)
|
|
||||||
// TODO 1.16 worldgen verify this
|
|
||||||
.map(cf -> cf.repeat(clusterCount.get()));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package com.simibubi.create.foundation.worldgen;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import net.minecraft.world.gen.GenerationStage.Decoration;
|
|
||||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
|
||||||
import net.minecraftforge.common.ForgeConfigSpec;
|
|
||||||
import net.minecraftforge.event.world.BiomeLoadingEvent;
|
|
||||||
|
|
||||||
public interface IFeature {
|
|
||||||
|
|
||||||
public void setId(String id);
|
|
||||||
|
|
||||||
public void addToConfig(ForgeConfigSpec.Builder builder);
|
|
||||||
|
|
||||||
public Optional<ConfiguredFeature<?, ?>> createFeature(BiomeLoadingEvent biome);
|
|
||||||
|
|
||||||
public Decoration getGenerationStage();
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
package com.simibubi.create.foundation.worldgen;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
|
||||||
import com.simibubi.create.foundation.config.ConfigBase;
|
|
||||||
import com.tterrag.registrate.util.nullness.NonNullSupplier;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.world.biome.Biome;
|
|
||||||
import net.minecraft.world.gen.GenerationStage;
|
|
||||||
import net.minecraft.world.gen.GenerationStage.Decoration;
|
|
||||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
|
||||||
import net.minecraft.world.gen.feature.Feature;
|
|
||||||
import net.minecraft.world.gen.feature.OreFeatureConfig;
|
|
||||||
import net.minecraft.world.gen.placement.IPlacementConfig;
|
|
||||||
import net.minecraft.world.gen.placement.Placement;
|
|
||||||
import net.minecraft.world.gen.placement.TopSolidRangeConfig;
|
|
||||||
import net.minecraftforge.common.ForgeConfigSpec.Builder;
|
|
||||||
import net.minecraftforge.event.world.BiomeLoadingEvent;
|
|
||||||
|
|
||||||
public abstract class OreFeature<T extends IPlacementConfig> extends ConfigBase implements IFeature {
|
|
||||||
|
|
||||||
public String id;
|
|
||||||
|
|
||||||
protected ConfigBool enable;
|
|
||||||
protected ConfigInt clusterSize;
|
|
||||||
protected ConfigInt minHeight;
|
|
||||||
protected ConfigInt maxHeight;
|
|
||||||
|
|
||||||
private NonNullSupplier<? extends Block> block;
|
|
||||||
private Biome.Category specificCategory;
|
|
||||||
|
|
||||||
public OreFeature(NonNullSupplier<? extends Block> block, int clusterSize) {
|
|
||||||
this.block = block;
|
|
||||||
this.enable = b(true, "enable", "Whether to spawn this in your World");
|
|
||||||
this.clusterSize = i(clusterSize, 0, "clusterSize");
|
|
||||||
this.minHeight = i(0, 0, "minHeight");
|
|
||||||
this.maxHeight = i(256, 0, "maxHeight");
|
|
||||||
}
|
|
||||||
|
|
||||||
public OreFeature<T> between(int minHeight, int maxHeight) {
|
|
||||||
allValues.remove(this.minHeight);
|
|
||||||
allValues.remove(this.maxHeight);
|
|
||||||
this.minHeight = i(minHeight, 0, "minHeight");
|
|
||||||
this.maxHeight = i(maxHeight, 0, "maxHeight");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OreFeature<T> inBiomes(Biome.Category category) {
|
|
||||||
specificCategory = category;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReload() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<ConfiguredFeature<?, ?>> createFeature(BiomeLoadingEvent biome) {
|
|
||||||
if (specificCategory != null && biome.getCategory() != specificCategory)
|
|
||||||
return Optional.empty();
|
|
||||||
if (!canGenerate())
|
|
||||||
return Optional.empty();
|
|
||||||
|
|
||||||
Pair<Placement<T>, T> placement = getPlacement();
|
|
||||||
ConfiguredFeature<?, ?> createdFeature = Feature.ORE
|
|
||||||
.configure(new OreFeatureConfig(OreFeatureConfig.FillerBlockType.BASE_STONE_OVERWORLD, block.get()
|
|
||||||
.getDefaultState(), clusterSize.get()))
|
|
||||||
.decorate(placement.getKey()
|
|
||||||
.configure(placement.getValue()))
|
|
||||||
.decorate(Placement.RANGE
|
|
||||||
// TODO 1.16 worldgen verify this
|
|
||||||
.configure(new TopSolidRangeConfig(minHeight.get(), 0, maxHeight.get() - minHeight.get())))
|
|
||||||
.spreadHorizontally();
|
|
||||||
|
|
||||||
return Optional.of(createdFeature);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Decoration getGenerationStage() {
|
|
||||||
return GenerationStage.Decoration.UNDERGROUND_ORES;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean canGenerate() {
|
|
||||||
return minHeight.get() < maxHeight.get() && clusterSize.get() > 0 && enable.get()
|
|
||||||
&& !AllConfigs.COMMON.worldGen.disable.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Pair<Placement<T>, T> getPlacement();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addToConfig(Builder builder) {
|
|
||||||
registerAll(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setId(String id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue