Compare commits

..

No commits in common. "ed04a8c4d2b9d7ade1291007774cd7afdd7e7d39" and "674c8752492142e0ec9e4f8ac8cda6e831ec2bb4" have entirely different histories.

8 changed files with 44 additions and 174 deletions

View File

@ -32,11 +32,8 @@ import ru.dbotthepony.mc.otm.worldgen.placement.StandardDeviationHeightProvider
import ru.dbotthepony.mc.otm.registry.game.MBlocks import ru.dbotthepony.mc.otm.registry.game.MBlocks
import ru.dbotthepony.mc.otm.registry.data.MWorldGenFeatures import ru.dbotthepony.mc.otm.registry.data.MWorldGenFeatures
import ru.dbotthepony.mc.otm.worldgen.feature.BlackHolePlacerFeature import ru.dbotthepony.mc.otm.worldgen.feature.BlackHolePlacerFeature
import ru.dbotthepony.mc.otm.worldgen.feature.DebugPlacerFeature
import ru.dbotthepony.mc.otm.worldgen.placement.ChainPlacement
import ru.dbotthepony.mc.otm.worldgen.placement.EnormousPlacement import ru.dbotthepony.mc.otm.worldgen.placement.EnormousPlacement
import ru.dbotthepony.mc.otm.worldgen.placement.EllipsoidPlacement import ru.dbotthepony.mc.otm.worldgen.placement.EllipsoidPlacement
import ru.dbotthepony.mc.otm.worldgen.placement.SplitPlacement
import ru.dbotthepony.mc.otm.worldgen.placement.WormPlacement import ru.dbotthepony.mc.otm.worldgen.placement.WormPlacement
private object ConfiguredFeatures { private object ConfiguredFeatures {
@ -100,7 +97,7 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
context.register(PlacedFeatures.NORMAL_TRITANIUM, PlacedFeature( context.register(PlacedFeatures.NORMAL_TRITANIUM, PlacedFeature(
ore, ore,
listOf( listOf(
CountPlacement.of(UniformInt.of(1, 3)), CountPlacement.of(UniformInt.of(2, 6)),
InSquarePlacement.spread(), InSquarePlacement.spread(),
HeightRangePlacement.of(StandardDeviationHeightProvider(VerticalAnchor.absolute(10), 15.0)) HeightRangePlacement.of(StandardDeviationHeightProvider(VerticalAnchor.absolute(10), 15.0))
) )
@ -109,7 +106,7 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
context.register(PlacedFeatures.DEEP_TRITANIUM, PlacedFeature( context.register(PlacedFeatures.DEEP_TRITANIUM, PlacedFeature(
ore, ore,
listOf( listOf(
CountPlacement.of(UniformInt.of(3, 5)), CountPlacement.of(UniformInt.of(4, 8)),
InSquarePlacement.spread(), InSquarePlacement.spread(),
HeightRangePlacement.of(VeryBiasedToBottomHeight.of(VerticalAnchor.aboveBottom(4), VerticalAnchor.absolute(0), 16)) HeightRangePlacement.of(VeryBiasedToBottomHeight.of(VerticalAnchor.aboveBottom(4), VerticalAnchor.absolute(0), 16))
) )
@ -122,45 +119,28 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
chunkScanRange = 24, chunkScanRange = 24,
seedMix = 9284343575495L, seedMix = 9284343575495L,
children = listOf( children = listOf(
RarityFilter.onAverageOnceEvery(140), RarityFilter.onAverageOnceEvery(300),
InSquarePlacement.spread(), InSquarePlacement.spread(),
HeightRangePlacement.of(StandardDeviationHeightProvider(VerticalAnchor.absolute(-40), 15.0)), HeightRangePlacement.of(StandardDeviationHeightProvider(VerticalAnchor.absolute(-40), 15.0)),
SplitPlacement( WormPlacement(
// "heart" length = UniformInt.of(120, 400),
EllipsoidPlacement( turnRateXY = WormPlacement.normalDistributedTurnRate(10f),
count = UniformInt.of(600, 900), turnRateXZ = WormPlacement.normalDistributedTurnRate(60f),
xLength = UniformFloat.of(9f, 12f), turnSpeedXZ = WormPlacement.constantTurnRate(10f),
yLength = UniformFloat.of(9f, 12f), turnSpeedXY = WormPlacement.constantTurnRate(4f),
zLength = UniformFloat.of(9f, 12f), turnChanceXY = BooleanProvider.Unbiased(6),
x = ClampedNormalFloat.of(0f, 0.4f, -1f, 1f), turnChanceXZ = BooleanProvider.BiasedLinear(0.6f, 5),
y = ClampedNormalFloat.of(0f, 0.4f, -1f, 1f), maxTravelUp = 16,
z = ClampedNormalFloat.of(0f, 0.4f, -1f, 1f), maxTravelDown = 16,
), ),
// "branches" EllipsoidPlacement(
ChainPlacement( count = UniformInt.of(15, 30),
CountPlacement.of(UniformInt.of(2, 7)), xLength = ConstantFloat.of(14f),
WormPlacement( yLength = ConstantFloat.of(14f),
length = UniformInt.of(60, 120), zLength = ConstantFloat.of(14f),
turnRateXY = WormPlacement.normalDistributedTurnRate(2f, 3f), x = ClampedNormalFloat.of(0f, 0.4f, -1f, 1f),
initialAngleXY = WormPlacement.normalDistributedTurnRate(3f, 4f), y = ClampedNormalFloat.of(0f, 0.4f, -1f, 1f),
turnRateXZ = WormPlacement.normalDistributedTurnRate(30f), z = ClampedNormalFloat.of(0f, 0.4f, -1f, 1f),
turnSpeedXZ = WormPlacement.constantTurnRate(10f),
turnSpeedXY = WormPlacement.constantTurnRate(4f),
turnChanceXY = BooleanProvider.Unbiased(6),
turnChanceXZ = BooleanProvider.BiasedLinear(0.6f, 5),
maxTravelUp = 90,
maxTravelDown = 10,
),
EllipsoidPlacement(
count = UniformInt.of(3, 6),
xLength = ConstantFloat.of(4f),
yLength = ConstantFloat.of(4f),
zLength = ConstantFloat.of(4f),
x = ClampedNormalFloat.of(0f, 0.2f, -1f, 1f),
y = ClampedNormalFloat.of(0f, 0.2f, -1f, 1f),
z = ClampedNormalFloat.of(0f, 0.2f, -1f, 1f),
)
)
) )
) )
) )

View File

@ -92,36 +92,6 @@ interface BooleanProvider {
} }
} }
object AlwaysTrue : BooleanProvider, Instance, Type<AlwaysTrue> {
override fun instance(): Instance {
return this
}
override fun sample(random: RandomSource): Boolean {
return true
}
override val type: Type<*>
get() = this
override val codec: MapCodec<AlwaysTrue> = MapCodec.unit(this)
}
object AlwaysFalse : BooleanProvider, Instance, Type<AlwaysFalse> {
override fun instance(): Instance {
return this
}
override fun sample(random: RandomSource): Boolean {
return false
}
override val type: Type<*>
get() = this
override val codec: MapCodec<AlwaysFalse> = MapCodec.unit(this)
}
companion object { companion object {
private val registryHolder = RegistryDelegate<Type<*>>("boolean_provider") { private val registryHolder = RegistryDelegate<Type<*>>("boolean_provider") {
defaultKey(ResourceLocation(OverdriveThatMatters.MOD_ID, "zero")) defaultKey(ResourceLocation(OverdriveThatMatters.MOD_ID, "zero"))
@ -135,8 +105,6 @@ interface BooleanProvider {
init { init {
registrar.register("unbiased") { Unbiased.Companion } registrar.register("unbiased") { Unbiased.Companion }
registrar.register("linear_bias") { BiasedLinear.Companion } registrar.register("linear_bias") { BiasedLinear.Companion }
registrar.register("true") { AlwaysTrue }
registrar.register("false") { AlwaysFalse }
} }
val CODEC: Codec<BooleanProvider> by lazy { val CODEC: Codec<BooleanProvider> by lazy {

View File

@ -4,10 +4,8 @@ import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.world.level.levelgen.placement.PlacementModifierType import net.minecraft.world.level.levelgen.placement.PlacementModifierType
import net.neoforged.bus.api.IEventBus import net.neoforged.bus.api.IEventBus
import ru.dbotthepony.mc.otm.registry.MDeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.worldgen.placement.ChainPlacement
import ru.dbotthepony.mc.otm.worldgen.placement.EllipsoidPlacement import ru.dbotthepony.mc.otm.worldgen.placement.EllipsoidPlacement
import ru.dbotthepony.mc.otm.worldgen.placement.EnormousPlacement import ru.dbotthepony.mc.otm.worldgen.placement.EnormousPlacement
import ru.dbotthepony.mc.otm.worldgen.placement.SplitPlacement
import ru.dbotthepony.mc.otm.worldgen.placement.WormPlacement import ru.dbotthepony.mc.otm.worldgen.placement.WormPlacement
object MPlacementModifiers { object MPlacementModifiers {
@ -20,6 +18,4 @@ object MPlacementModifiers {
val ENORMOUS by registry.register("enormous") { PlacementModifierType { EnormousPlacement.CODEC } } val ENORMOUS by registry.register("enormous") { PlacementModifierType { EnormousPlacement.CODEC } }
val ELLIPSOID_PLACEMENT by registry.register("ellipsoid") { PlacementModifierType { EllipsoidPlacement.CODEC } } val ELLIPSOID_PLACEMENT by registry.register("ellipsoid") { PlacementModifierType { EllipsoidPlacement.CODEC } }
val WORM_PLACEMENT by registry.register("worm") { PlacementModifierType { WormPlacement.CODEC } } val WORM_PLACEMENT by registry.register("worm") { PlacementModifierType { WormPlacement.CODEC } }
val SPLIT by registry.register("split") { PlacementModifierType { SplitPlacement.CODEC} }
val CHAIN by registry.register("chain") { PlacementModifierType { ChainPlacement.CODEC} }
} }

View File

@ -1,35 +0,0 @@
package ru.dbotthepony.mc.otm.worldgen.placement
import com.google.common.collect.ImmutableList
import com.mojang.serialization.Codec
import com.mojang.serialization.MapCodec
import net.minecraft.core.BlockPos
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
import ru.dbotthepony.mc.otm.registry.data.MPlacementModifiers
import java.util.stream.Stream
/**
* Daisy-chaining placements. Required only when using placement modifiers which operate on children list
*/
class ChainPlacement(
val children: List<PlacementModifier>
) : PlacementModifier() {
constructor(vararg children: PlacementModifier) : this(ImmutableList.copyOf(children))
override fun getPositions(context: PlacementContext, random: RandomSource, pos: BlockPos): Stream<BlockPos> {
var stream = Stream.of(pos)
children.forEach { c -> stream = stream.flatMap { c.getPositions(context, random, it) } }
return stream
}
override fun type(): PlacementModifierType<*> {
return MPlacementModifiers.CHAIN
}
companion object {
val CODEC: MapCodec<ChainPlacement> = Codec.list(PlacementModifier.CODEC).xmap(::ChainPlacement, ChainPlacement::children).fieldOf("children")
}
}

View File

@ -20,7 +20,9 @@ import kotlin.math.PI
import kotlin.math.roundToInt import kotlin.math.roundToInt
/** /**
* Ellipsoid ("cloud") placement * Regular ellipsoid ("cloud") placement, suitable to be used as non-primary placement modifier
*
* This placement modifier is designed to be terminal; other placement modifiers after this MUST NOT be placed
*/ */
data class EllipsoidPlacement( data class EllipsoidPlacement(
/** /**

View File

@ -7,7 +7,6 @@ import com.mojang.serialization.Codec
import com.mojang.serialization.MapCodec import com.mojang.serialization.MapCodec
import com.mojang.serialization.codecs.RecordCodecBuilder import com.mojang.serialization.codecs.RecordCodecBuilder
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import net.minecraft.Util import net.minecraft.Util
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.SectionPos import net.minecraft.core.SectionPos
@ -51,7 +50,7 @@ class EnormousPlacement(
) : PlacementModifier() { ) : PlacementModifier() {
private class GeneratedChunk(positions: Stream<BlockPos>) { private class GeneratedChunk(positions: Stream<BlockPos>) {
// TODO: memory inefficient // TODO: memory inefficient
private val positions = ObjectOpenHashSet<BlockPos>() private val positions = ArrayList<BlockPos>()
init { init {
positions.forEach { this.positions.add(it) } positions.forEach { this.positions.add(it) }
@ -66,22 +65,20 @@ class EnormousPlacement(
} }
} }
private val level2cache = Caffeine.newBuilder() private val level2cache = WeakHashMap<WorldGenLevel, Cache<ChunkPos, GeneratedChunk>>()
.scheduler(Scheduler.systemScheduler()) private val lock = ReentrantLock()
.executor(Util.backgroundExecutor())
.expireAfterAccess(Duration.ofMinutes(10))
.weakKeys()
.build<WorldGenLevel, Cache<ChunkPos, GeneratedChunk>>()
private fun getCache(level: WorldGenLevel): Cache<ChunkPos, GeneratedChunk> { private fun getCache(level: WorldGenLevel): Cache<ChunkPos, GeneratedChunk> {
return level2cache.get(level) { return lock.withLock {
Caffeine.newBuilder() level2cache.computeIfAbsent(level) {
.scheduler(Scheduler.systemScheduler()) Caffeine.newBuilder()
.executor(Util.backgroundExecutor()) .scheduler(Scheduler.systemScheduler())
.maximumSize(16384L) .executor(Util.backgroundExecutor())
.expireAfterWrite(Duration.ofMinutes(5)) .maximumSize(16384L)
.softValues() .expireAfterWrite(Duration.ofMinutes(5))
.build() .softValues()
.build()
}
} }
} }

View File

@ -1,35 +0,0 @@
package ru.dbotthepony.mc.otm.worldgen.placement
import com.google.common.collect.ImmutableList
import com.mojang.serialization.Codec
import com.mojang.serialization.MapCodec
import net.minecraft.core.BlockPos
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
import ru.dbotthepony.mc.otm.registry.data.MPlacementModifiers
import java.util.stream.Stream
/**
* Or "shard" placement, if you will.
*
* Basically, allows multiple [PlacementModifier]s to split/branch off from provided point.
*/
class SplitPlacement(
val children: List<PlacementModifier>
) : PlacementModifier() {
constructor(vararg children: PlacementModifier) : this(ImmutableList.copyOf(children))
override fun getPositions(context: PlacementContext, random: RandomSource, pos: BlockPos): Stream<BlockPos> {
return children.stream().flatMap { it.getPositions(context, random, pos) }
}
override fun type(): PlacementModifierType<*> {
return MPlacementModifiers.SPLIT
}
companion object {
val CODEC: MapCodec<SplitPlacement> = Codec.list(PlacementModifier.CODEC).xmap(::SplitPlacement, SplitPlacement::children).fieldOf("children")
}
}

View File

@ -29,9 +29,6 @@ import kotlin.math.cos
import kotlin.math.sign import kotlin.math.sign
import kotlin.math.sin import kotlin.math.sin
/**
* Creates one block thick "worm" positions which twists and turns
*/
class WormPlacement( class WormPlacement(
val length: IntProvider, val length: IntProvider,
val turnChanceXZ: BooleanProvider, val turnChanceXZ: BooleanProvider,
@ -46,9 +43,9 @@ class WormPlacement(
) : PlacementModifier() { ) : PlacementModifier() {
private inner class Worm(private val random: RandomSource, private var position: Vector) { private inner class Worm(private val random: RandomSource, private var position: Vector) {
private var remainingDistance = length.sample(random) private var remainingDistance = length.sample(random)
private var xzRotation = random.nextDouble(-PI, PI) private var xzRotation = random.nextDouble(-PI / 2.0, PI / 2.0)
private var xyRotation = normalizeAngle(initialAngleXY.sample(random).toDouble()) private var xyRotation = normalizeAngle(initialAngleXY.sample(random).toDouble())
private var xzTargetRotation = random.nextDouble(-PI, PI) private var xzTargetRotation = random.nextDouble(-PI / 2.0, PI / 2.0)
private var xyTargetRotation = normalizeAngle(initialAngleXY.sample(random).toDouble()) private var xyTargetRotation = normalizeAngle(initialAngleXY.sample(random).toDouble())
private var xzSin = sin(xzRotation) private var xzSin = sin(xzRotation)
@ -190,14 +187,14 @@ class WormPlacement(
return UniformFloat.of(-rad, increment(rad)) return UniformFloat.of(-rad, increment(rad))
} }
fun normalDistributedTurnRate(deviation: Float, mean: Float = 0f): FloatProvider { fun normalDistributedTurnRate(deviation: Float): FloatProvider {
return normalDistributedTurnRateRadians(deviation * DEGREES_TO_RADIANS, mean * DEGREES_TO_RADIANS) return normalDistributedTurnRateRadians(deviation * DEGREES_TO_RADIANS)
} }
fun normalDistributedTurnRateRadians(deviation: Float, mean: Float = 0f): FloatProvider { fun normalDistributedTurnRateRadians(deviation: Float): FloatProvider {
require(deviation >= 0f) { "Provided value must be non-negative, $deviation given" } require(deviation >= 0f) { "Provided value must be non-negative, $deviation given" }
if (deviation == 0f) return ConstantFloat.ZERO if (deviation == 0f) return ConstantFloat.ZERO
return ClampedNormalFloat.of(mean, deviation, -PI.toFloat() * 2f, PI.toFloat() * 2f) return ClampedNormalFloat.of(0f, deviation, -PI.toFloat() * 2f, PI.toFloat() * 2f)
} }
private const val DEGREES_TO_RADIANS = PI.toFloat() / 180f private const val DEGREES_TO_RADIANS = PI.toFloat() / 180f