Use sets for block positions instead of lists
it makes no sense to give same position twice
This commit is contained in:
parent
18f9bc2654
commit
bc81103e38
@ -0,0 +1,30 @@
|
||||
package ru.dbotthepony.mc.otm.core.collect
|
||||
|
||||
import it.unimi.dsi.fastutil.Hash
|
||||
import it.unimi.dsi.fastutil.HashCommon
|
||||
import net.minecraft.core.BlockPos
|
||||
|
||||
object BlockPosHashStrategy : Hash.Strategy<BlockPos>, Comparator<BlockPos> {
|
||||
override fun equals(a: BlockPos?, b: BlockPos?): Boolean {
|
||||
return a == b
|
||||
}
|
||||
|
||||
override fun hashCode(o: BlockPos?): Int {
|
||||
o ?: return 0
|
||||
return HashCommon.murmurHash3(o.x.toLong().and(1 shl 26 - 1) or o.z.toLong().and(1 shl 26 - 1).shl(26) or o.y.toLong().and(1 shl 12 - 1).shl(52)).toInt()
|
||||
}
|
||||
|
||||
override fun compare(o1: BlockPos?, o2: BlockPos?): Int {
|
||||
if (o1 == null && o2 == null)
|
||||
return 0
|
||||
else if (o1 == null)
|
||||
return -1 // nulls come first
|
||||
else if (o2 == null)
|
||||
return 1
|
||||
|
||||
var cmp = o1.x.compareTo(o2.x)
|
||||
if (cmp == 0) cmp = o1.z.compareTo(o2.z)
|
||||
if (cmp == 0) cmp = o1.y.compareTo(o2.y)
|
||||
return cmp
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import com.mojang.serialization.DataResult
|
||||
import com.mojang.serialization.DynamicOps
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||
import net.minecraft.Util
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Holder
|
||||
@ -111,10 +112,10 @@ object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
||||
) {
|
||||
class Node(val children: List<Node>, val contents: Either<EnhancedPlacementModifier, Holder<EnhancedFeature.Configured<*, *>>>){
|
||||
fun evaluate(context: EnhancedPlacementContext) {
|
||||
evaluate(context, listOf(BlockPos(context.origin.minBlockX, 0, context.origin.minBlockZ)))
|
||||
evaluate(context, setOf(BlockPos(context.origin.minBlockX, 0, context.origin.minBlockZ)))
|
||||
}
|
||||
|
||||
private fun evaluate(context: EnhancedPlacementContext, positions: List<BlockPos>) {
|
||||
private fun evaluate(context: EnhancedPlacementContext, positions: Set<BlockPos>) {
|
||||
val actualPositions = if (contents.left().isPresent) {
|
||||
contents.left().get().evaluate(context, positions)
|
||||
} else {
|
||||
@ -137,12 +138,12 @@ object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
||||
val root: Node,
|
||||
) : FeatureConfiguration {
|
||||
private class GeneratedChunk : EnhancedPlacementContext.Placer {
|
||||
private data class Placement(val context: EnhancedPlacementContext, val positions: List<BlockPos>, val feature: EnhancedFeature.Configured<*, *>)
|
||||
private data class Placement(val context: EnhancedPlacementContext, val positions: Set<BlockPos>, val feature: EnhancedFeature.Configured<*, *>)
|
||||
|
||||
// TODO: extremely inefficient
|
||||
private val placed = ArrayList<Placement>()
|
||||
|
||||
override fun place(context: EnhancedPlacementContext, positions: List<BlockPos>, feature: EnhancedFeature.Configured<*, *>) {
|
||||
override fun place(context: EnhancedPlacementContext, positions: Set<BlockPos>, feature: EnhancedFeature.Configured<*, *>) {
|
||||
placed.add(Placement(context, positions, feature))
|
||||
}
|
||||
|
||||
@ -151,10 +152,10 @@ object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
||||
val pos = ChunkPos(context.origin())
|
||||
|
||||
for ((eContext, positions, feature) in placed) {
|
||||
val filtered = positions.filter { SectionPos.blockToSectionCoord(it.x) == pos.x && SectionPos.blockToSectionCoord(it.z) == pos.z }
|
||||
val filtered = positions.filter { SectionPos.blockToSectionCoord(it.x) == pos.x && SectionPos.blockToSectionCoord(it.z) == pos.z }.toTypedArray()
|
||||
|
||||
if (filtered.isNotEmpty()) {
|
||||
any = feature.place(eContext, filtered, positions) || any
|
||||
any = feature.place(eContext, ObjectArraySet.ofUnchecked(*filtered), positions) || any
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ import kotlin.collections.HashMap
|
||||
|
||||
class EnhancedPlacementContext {
|
||||
fun interface Placer {
|
||||
fun place(context: EnhancedPlacementContext, positions: List<BlockPos>, feature: EnhancedFeature.Configured<*, *>)
|
||||
fun place(context: EnhancedPlacementContext, positions: Set<BlockPos>, feature: EnhancedFeature.Configured<*, *>)
|
||||
}
|
||||
|
||||
val level: WorldGenLevel
|
||||
@ -79,7 +79,7 @@ class EnhancedPlacementContext {
|
||||
return EnhancedPlacementContext(this)
|
||||
}
|
||||
|
||||
fun place(positions: List<BlockPos>, feature: EnhancedFeature.Configured<*, *>) {
|
||||
fun place(positions: Set<BlockPos>, feature: EnhancedFeature.Configured<*, *>) {
|
||||
placer.place(this, positions, feature)
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,10 @@ import ru.dbotthepony.mc.otm.registry.MRegistries
|
||||
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
||||
|
||||
abstract class EnhancedFeature<FC>(codec: Codec<FC>) {
|
||||
abstract fun place(context: EnhancedPlacementContext, config: FC, positions: List<BlockPos>, allPositions: List<BlockPos>): Boolean
|
||||
abstract fun place(context: EnhancedPlacementContext, config: FC, positions: Set<BlockPos>, allPositions: Set<BlockPos>): Boolean
|
||||
|
||||
data class Configured<F : EnhancedFeature<FC>, FC>(val feature: F, val config: FC) {
|
||||
fun place(context: EnhancedPlacementContext, positions: List<BlockPos>, allPositions: List<BlockPos>): Boolean {
|
||||
fun place(context: EnhancedPlacementContext, positions: Set<BlockPos>, allPositions: Set<BlockPos>): Boolean {
|
||||
return feature.place(context, config, positions, allPositions)
|
||||
}
|
||||
}
|
||||
@ -29,8 +29,8 @@ abstract class EnhancedFeature<FC>(codec: Codec<FC>) {
|
||||
override fun place(
|
||||
context: EnhancedPlacementContext,
|
||||
config: Holder<ConfiguredFeature<*, *>>,
|
||||
positions: List<BlockPos>,
|
||||
allPositions: List<BlockPos>
|
||||
positions: Set<BlockPos>,
|
||||
allPositions: Set<BlockPos>
|
||||
): Boolean {
|
||||
var any = false
|
||||
positions.forEach { any = config.value().place(context.level, context.generator, context.random, it) || any }
|
||||
|
@ -2,25 +2,31 @@ package ru.dbotthepony.mc.otm.worldgen.placement
|
||||
|
||||
import com.mojang.serialization.Codec
|
||||
import com.mojang.serialization.MapCodec
|
||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenCustomHashSet
|
||||
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
||||
import net.neoforged.bus.api.IEventBus
|
||||
import ru.dbotthepony.mc.otm.core.collect.BlockPosHashStrategy
|
||||
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
|
||||
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
|
||||
import ru.dbotthepony.mc.otm.registry.MRegistries
|
||||
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
||||
import java.util.stream.Collectors
|
||||
|
||||
interface EnhancedPlacementModifier {
|
||||
interface Type<T : EnhancedPlacementModifier> {
|
||||
val codec: MapCodec<T>
|
||||
}
|
||||
|
||||
fun evaluate(context: EnhancedPlacementContext, positions: List<BlockPos>): List<BlockPos>
|
||||
fun evaluate(context: EnhancedPlacementContext, positions: Set<BlockPos>): Set<BlockPos>
|
||||
val type: Type<*>
|
||||
|
||||
class Wrapper(val parent: PlacementModifier) : EnhancedPlacementModifier {
|
||||
override fun evaluate(context: EnhancedPlacementContext, positions: List<BlockPos>): List<BlockPos> {
|
||||
return positions.stream().flatMap { parent.getPositions(context.vanillaContext, context.random, it) }.toList()
|
||||
override fun evaluate(context: EnhancedPlacementContext, positions: Set<BlockPos>): Set<BlockPos> {
|
||||
return positions.stream()
|
||||
.flatMap { parent.getPositions(context.vanillaContext, context.random, it) }
|
||||
.collect(Collectors.toCollection { ObjectLinkedOpenCustomHashSet(BlockPosHashStrategy) })
|
||||
}
|
||||
|
||||
override val type: Type<*>
|
||||
|
Loading…
Reference in New Issue
Block a user