OneOf number provider, improve dilithium ore generation further

This commit is contained in:
DBotThePony 2025-03-02 11:21:30 +07:00
parent cd38e1a154
commit c0812687cb
Signed by: DBot
GPG Key ID: DCC23B5715498507
6 changed files with 198 additions and 7 deletions

View File

@ -26,6 +26,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.OneOfFloatProvider
import ru.dbotthepony.mc.otm.worldgen.placement.StandardDeviationHeightProvider
import ru.dbotthepony.mc.otm.registry.game.MBlocks
import ru.dbotthepony.mc.otm.registry.data.MWorldGenFeatures
@ -109,6 +110,11 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
run {
val ore = configured.getOrThrow(ConfiguredFeatures.DILITHIUM)
val ringularity = OneOfFloatProvider.of(
ClampedNormalFloat.of(0.4f, 0.2f, -2f, 2f),
ClampedNormalFloat.of(-0.4f, 0.2f, -2f, 2f),
)
context.register(PlacedFeatures.DILITHIUM, PlacedFeature(
ore,
listOf(
@ -116,18 +122,18 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
parameters = AbstractEnormousPlacement.Parameters(
chunkScanRange = 5,
placementModifiers = listOf(
RarityFilter.onAverageOnceEvery(60),
RarityFilter.onAverageOnceEvery(120),
InSquarePlacement.spread(),
HeightRangePlacement.of(StandardDeviationHeightProvider(VerticalAnchor.absolute(0), 15.0)),
)
),
x = ClampedNormalFloat.of(0f, 0.3f, -2f, 2f),
y = ClampedNormalFloat.of(0f, 0.3f, -2f, 2f),
z = ClampedNormalFloat.of(0f, 0.3f, -2f, 2f),
count = UniformInt.of(8000, 24000),
xLength = UniformFloat.of(30f, 60f),
x = ringularity,
y = ringularity,
z = ringularity,
count = UniformInt.of(8000, 28000),
xLength = UniformFloat.of(30f, 70f),
yLength = UniformFloat.of(40f, 90f),
zLength = UniformFloat.of(30f, 60f),
zLength = UniformFloat.of(30f, 70f),
)
)
))

View File

@ -86,6 +86,7 @@ import ru.dbotthepony.mc.otm.registry.data.MHeightProviders
import ru.dbotthepony.mc.otm.registry.data.MItemFunctionTypes
import ru.dbotthepony.mc.otm.registry.data.MLootItemConditions
import ru.dbotthepony.mc.otm.registry.data.MLootNumberProviders
import ru.dbotthepony.mc.otm.registry.data.MNumberProviders
import ru.dbotthepony.mc.otm.registry.data.MPlacementModifiers
import ru.dbotthepony.mc.otm.registry.data.MWorldGenFeatures
import ru.dbotthepony.mc.otm.server.MCommands
@ -124,6 +125,7 @@ object OverdriveThatMatters {
CommandArgumentTypes.register(MOD_BUS)
MHeightProviders.register(MOD_BUS)
MPlacementModifiers.register(MOD_BUS)
MNumberProviders.register(MOD_BUS)
MLootNumberProviders.register(MOD_BUS)
StorageStack.register(MOD_BUS)

View File

@ -0,0 +1,38 @@
package ru.dbotthepony.mc.otm.data.world
import net.minecraft.util.RandomSource
import net.minecraft.util.valueproviders.FloatProvider
import net.minecraft.util.valueproviders.FloatProviderType
import ru.dbotthepony.mc.otm.registry.data.MNumberProviders
class OneOfFloatProvider(private val provider: OneOfProvider<FloatProvider>) : FloatProvider() {
override fun sample(random: RandomSource): Float {
return provider.select(random).sample(random)
}
override fun getMinValue(): Float {
return provider.children.minOf { it.minValue }
}
override fun getMaxValue(): Float {
return provider.children.minOf { it.maxValue }
}
override fun getType(): FloatProviderType<*> {
return MNumberProviders.ONE_OF_FLOAT
}
companion object {
@JvmStatic
fun of(vararg providers: FloatProvider): OneOfFloatProvider {
return OneOfFloatProvider(OneOfProvider.of(*providers))
}
@JvmStatic
fun of(providers: Collection<FloatProvider>): OneOfFloatProvider {
return OneOfFloatProvider(OneOfProvider.of(providers))
}
val CODEC = OneOfProvider.createCodec(FloatProvider.CODEC, ::OneOfFloatProvider, OneOfFloatProvider::provider)
}
}

View File

@ -0,0 +1,38 @@
package ru.dbotthepony.mc.otm.data.world
import net.minecraft.util.RandomSource
import net.minecraft.util.valueproviders.IntProvider
import net.minecraft.util.valueproviders.IntProviderType
import ru.dbotthepony.mc.otm.registry.data.MNumberProviders
class OneOfIntProvider(private val provider: OneOfProvider<IntProvider>) : IntProvider() {
override fun sample(random: RandomSource): Int {
return provider.select(random).sample(random)
}
override fun getMinValue(): Int {
return provider.children.minOf { it.minValue }
}
override fun getMaxValue(): Int {
return provider.children.minOf { it.maxValue }
}
override fun getType(): IntProviderType<*> {
return MNumberProviders.ONE_OF_INT
}
companion object {
@JvmStatic
fun of(vararg providers: IntProvider): OneOfIntProvider {
return OneOfIntProvider(OneOfProvider.of(*providers))
}
@JvmStatic
fun of(providers: Collection<IntProvider>): OneOfIntProvider {
return OneOfIntProvider(OneOfProvider.of(providers))
}
val CODEC = OneOfProvider.createCodec(IntProvider.CODEC, ::OneOfIntProvider, OneOfIntProvider::provider)
}
}

View File

@ -0,0 +1,85 @@
package ru.dbotthepony.mc.otm.data.world
import com.google.common.collect.ImmutableList
import com.mojang.serialization.Codec
import com.mojang.serialization.DataResult
import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder
import net.minecraft.util.RandomSource
import net.minecraft.util.valueproviders.IntProvider
import ru.dbotthepony.mc.otm.core.random
import java.util.Optional
class OneOfProvider<T> private constructor(val children: List<T>, val selector: Optional<IntProvider> = Optional.empty()) {
fun select(random: RandomSource): T {
if (selector.isEmpty) {
return children.random(random)
}
val index = selector.get().sample(random)
if (index !in children.indices) {
throw RuntimeException("Provided selector ($selector) provided index out of bounds: $index (bounds: ${children.indices})")
}
return children[index]
}
class Builder<T> {
private var selector: IntProvider? = null
private val inputs = ArrayList<T>()
fun indexSelector(selector: IntProvider): Builder<T> {
this.selector = selector
return this
}
fun add(vararg provider: T): Builder<T> {
inputs.addAll(provider)
return this
}
fun copy(): Builder<T> {
val new = Builder<T>()
new.selector = selector
new.inputs.addAll(inputs)
return new
}
fun build(): OneOfProvider<T> {
return OneOfProvider(ImmutableList.copyOf(inputs), Optional.ofNullable(selector))
}
}
companion object {
@JvmStatic
fun <T> of(vararg providers: T): OneOfProvider<T> {
return OneOfProvider(ImmutableList.copyOf(providers))
}
@JvmStatic
fun <T> of(providers: Collection<T>): OneOfProvider<T> {
return OneOfProvider(ImmutableList.copyOf(providers))
}
@JvmStatic
fun <T> createCodec(childrenCodec: Codec<T>): MapCodec<OneOfProvider<T>> {
return RecordCodecBuilder.mapCodec {
it.group(
Codec.list(childrenCodec, 1, Int.MAX_VALUE).fieldOf("children").forGetter<OneOfProvider<T>> { it.children },
IntProvider.POSITIVE_CODEC.optionalFieldOf("selector").forGetter<OneOfProvider<T>> { it.selector },
).apply(it, ::OneOfProvider)
}.validate {
if (it.selector.isEmpty || it.selector.get().minValue in it.children.indices && it.selector.get().maxValue in it.children.indices) {
return@validate DataResult.success(it)
} else {
return@validate DataResult.error { "Provided number sampler ${it.selector.get()} can produce values outside of children list index range (list size: ${it.children.size})" }
}
}
}
fun <S, T> createCodec(childrenCodec: Codec<T>, to: (OneOfProvider<T>) -> S, from: (S) -> OneOfProvider<T>): MapCodec<S> {
return createCodec(childrenCodec).xmap(to, from)
}
}
}

View File

@ -0,0 +1,22 @@
package ru.dbotthepony.mc.otm.registry.data
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.util.valueproviders.FloatProviderType
import net.minecraft.util.valueproviders.IntProviderType
import net.neoforged.bus.api.IEventBus
import ru.dbotthepony.mc.otm.data.world.OneOfFloatProvider
import ru.dbotthepony.mc.otm.data.world.OneOfIntProvider
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
object MNumberProviders {
private val floats = MDeferredRegister(BuiltInRegistries.FLOAT_PROVIDER_TYPE)
private val ints = MDeferredRegister(BuiltInRegistries.INT_PROVIDER_TYPE)
fun register(bus: IEventBus) {
floats.register(bus)
ints.register(bus)
}
val ONE_OF_FLOAT by floats.register("one_of_float") { FloatProviderType { OneOfFloatProvider.CODEC } }
val ONE_OF_INT by ints.register("one_of_int") { IntProviderType { OneOfIntProvider.CODEC } }
}