Better tritanium ore placement
This commit is contained in:
parent
c8c8e75b62
commit
77821768bc
@ -11,6 +11,7 @@ import net.minecraft.world.level.levelgen.VerticalAnchor
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature
|
||||
import net.minecraft.world.level.levelgen.feature.Feature
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.OreConfiguration
|
||||
import net.minecraft.world.level.levelgen.heightproviders.VeryBiasedToBottomHeight
|
||||
import net.minecraft.world.level.levelgen.placement.CountPlacement
|
||||
import net.minecraft.world.level.levelgen.placement.HeightRangePlacement
|
||||
import net.minecraft.world.level.levelgen.placement.InSquarePlacement
|
||||
@ -19,6 +20,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.TagMatchTest
|
||||
import net.neoforged.neoforge.common.world.BiomeModifier
|
||||
import net.neoforged.neoforge.registries.NeoForgeRegistries
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.data.world.StandardDeviationHeightProvider
|
||||
import ru.dbotthepony.mc.otm.registry.MBlocks
|
||||
import ru.dbotthepony.mc.otm.registry.MWorldGenFeatures
|
||||
import ru.dbotthepony.mc.otm.worldgen.feature.BlackHolePlacerFeature
|
||||
@ -63,18 +65,18 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
|
||||
context.register(PlacedFeatures.NORMAL_TRITANIUM, PlacedFeature(
|
||||
ore,
|
||||
listOf(
|
||||
CountPlacement.of(8),
|
||||
CountPlacement.of(6),
|
||||
InSquarePlacement.spread(),
|
||||
HeightRangePlacement.triangle(VerticalAnchor.absolute(0), VerticalAnchor.absolute(50))
|
||||
HeightRangePlacement.of(StandardDeviationHeightProvider(VerticalAnchor.absolute(10), 15.0))
|
||||
)
|
||||
))
|
||||
|
||||
context.register(PlacedFeatures.DEEP_TRITANIUM, PlacedFeature(
|
||||
ore,
|
||||
listOf(
|
||||
CountPlacement.of(10),
|
||||
CountPlacement.of(12),
|
||||
InSquarePlacement.spread(),
|
||||
HeightRangePlacement.uniform(VerticalAnchor.aboveBottom(8), VerticalAnchor.absolute(0))
|
||||
HeightRangePlacement.of(VeryBiasedToBottomHeight.of(VerticalAnchor.aboveBottom(4), VerticalAnchor.absolute(0), 16))
|
||||
)
|
||||
))
|
||||
|
||||
@ -83,7 +85,7 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
|
||||
context.register(PlacedFeatures.BLACK_HOLE, PlacedFeature(
|
||||
blackHole,
|
||||
listOf(
|
||||
CountPlacement.of(1),
|
||||
InSquarePlacement.spread(),
|
||||
HeightRangePlacement.uniform(VerticalAnchor.absolute(64), VerticalAnchor.absolute(128))
|
||||
)
|
||||
))
|
||||
|
@ -98,6 +98,7 @@ object OverdriveThatMatters {
|
||||
MStats.register(MOD_BUS)
|
||||
MWorldGenFeatures.register(MOD_BUS)
|
||||
CommandArgumentTypes.register(MOD_BUS)
|
||||
MHeightProviders.register(MOD_BUS)
|
||||
|
||||
StorageStack.Companion.register(MOD_BUS)
|
||||
MatteryChestMenu.Companion.register(MOD_BUS)
|
||||
|
@ -65,6 +65,8 @@ import java.util.stream.Stream
|
||||
import java.util.stream.StreamSupport
|
||||
import kotlin.NoSuchElementException
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import kotlin.math.ln
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
operator fun RecipeInput.get(index: Int): ItemStack = getItem(index)
|
||||
@ -592,3 +594,45 @@ infix fun FluidStack.isSameAs(other: FluidStack): Boolean {
|
||||
infix fun FluidStack.isNotSameAs(other: FluidStack): Boolean {
|
||||
return !FluidStack.isSameFluidSameComponents(this, other) && amount == other.amount
|
||||
}
|
||||
|
||||
data class DoublePair(val first: Double, val second: Double)
|
||||
|
||||
// normal distribution via Box-Muller
|
||||
fun RandomGenerator.nextNormalDouble(stddev: Double, mean: Double): DoublePair {
|
||||
var rand1: Double
|
||||
var rand2: Double
|
||||
var distSqr: Double
|
||||
|
||||
do {
|
||||
rand1 = 2.0 * nextDouble() - 1.0
|
||||
rand2 = 2.0 * nextDouble() - 1.0
|
||||
distSqr = rand1 * rand1 + rand2 * rand2
|
||||
} while (distSqr >= 1)
|
||||
|
||||
val mapping = sqrt(-2.0 * ln(distSqr) / distSqr)
|
||||
|
||||
return DoublePair(
|
||||
rand1 * mapping * stddev + mean,
|
||||
rand2 * mapping * stddev + mean
|
||||
)
|
||||
}
|
||||
|
||||
// this kinda exists in form of nextGaussian, but it doesn't allow to specify deviation and mean
|
||||
fun RandomSource.nextNormalDouble(stddev: Double, mean: Double): DoublePair {
|
||||
var rand1: Double
|
||||
var rand2: Double
|
||||
var distSqr: Double
|
||||
|
||||
do {
|
||||
rand1 = 2.0 * nextDouble() - 1.0
|
||||
rand2 = 2.0 * nextDouble() - 1.0
|
||||
distSqr = rand1 * rand1 + rand2 * rand2
|
||||
} while (distSqr >= 1)
|
||||
|
||||
val mapping = sqrt(-2.0 * ln(distSqr) / distSqr)
|
||||
|
||||
return DoublePair(
|
||||
rand1 * mapping * stddev + mean,
|
||||
rand2 * mapping * stddev + mean
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
package ru.dbotthepony.mc.otm.data.world
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.MapCodec
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.level.levelgen.VerticalAnchor
|
||||
import net.minecraft.world.level.levelgen.WorldGenerationContext
|
||||
import net.minecraft.world.level.levelgen.heightproviders.HeightProvider
|
||||
import net.minecraft.world.level.levelgen.heightproviders.HeightProviderType
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.core.nextNormalDouble
|
||||
import ru.dbotthepony.mc.otm.data.minRange
|
||||
import ru.dbotthepony.mc.otm.registry.MHeightProviders
|
||||
|
||||
/**
|
||||
* Doubles generated are rounded into integers towards negative infinity
|
||||
*/
|
||||
data class StandardDeviationHeightProvider(
|
||||
val mean: VerticalAnchor,
|
||||
val deviation: Double,
|
||||
) : HeightProvider() {
|
||||
override fun sample(random: RandomSource, context: WorldGenerationContext): Int {
|
||||
val y = mean.resolveY(context)
|
||||
val yd = y.toDouble()
|
||||
var i = 100
|
||||
|
||||
while (i-- > 0) {
|
||||
val (r0, r1) = random.nextNormalDouble(deviation, yd)
|
||||
val i0 = r0.toInt()
|
||||
val i1 = r1.toInt()
|
||||
|
||||
if (i0 in context.minGenY .. context.genDepth) {
|
||||
return i0
|
||||
} else if (i1 in context.minGenY .. context.genDepth) {
|
||||
return i1
|
||||
}
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled) {
|
||||
LOGGER.debug("StandardDeviationHeightProvider couldn't find proper height value for mean $mean with deviation of $deviation")
|
||||
}
|
||||
|
||||
// failsafe
|
||||
return y
|
||||
}
|
||||
|
||||
override fun getType(): HeightProviderType<*> {
|
||||
return MHeightProviders.STANDARD_DEVIATION
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
|
||||
val CODEC: MapCodec<StandardDeviationHeightProvider> by lazy {
|
||||
RecordCodecBuilder.mapCodec {
|
||||
it.group(
|
||||
VerticalAnchor.CODEC.fieldOf("mean").forGetter(StandardDeviationHeightProvider::mean),
|
||||
Codec.DOUBLE.minRange(1.0).fieldOf("deviation").forGetter(StandardDeviationHeightProvider::deviation),
|
||||
).apply(it, ::StandardDeviationHeightProvider)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package ru.dbotthepony.mc.otm.registry
|
||||
|
||||
import net.minecraft.core.registries.BuiltInRegistries
|
||||
import net.minecraft.world.level.levelgen.heightproviders.HeightProviderType
|
||||
import net.neoforged.bus.api.IEventBus
|
||||
import ru.dbotthepony.mc.otm.data.world.StandardDeviationHeightProvider
|
||||
|
||||
object MHeightProviders {
|
||||
private val registry = MDeferredRegister(BuiltInRegistries.HEIGHT_PROVIDER_TYPE)
|
||||
|
||||
fun register(bus: IEventBus) {
|
||||
registry.register(bus)
|
||||
}
|
||||
|
||||
val STANDARD_DEVIATION by registry.register("standard_deviation") { HeightProviderType { StandardDeviationHeightProvider.CODEC } }
|
||||
}
|
Loading…
Reference in New Issue
Block a user