Unify placement modifier and feature under single "placement" interface, greatly simplifying and empowering things at the same time
This commit is contained in:
parent
2e104dcbce
commit
e2369b3a24
@ -34,22 +34,20 @@ 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.EnhancedPlacedFeature
|
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacedFeature
|
||||||
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.feature.EnhancedFeature
|
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.ChainPlacement
|
import ru.dbotthepony.mc.otm.worldgen.placement
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.EllipsoidPlacement
|
import ru.dbotthepony.mc.otm.worldgen.placement.EllipsoidPlacement
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedChainPlacement
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedChainPlacement
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedCountPlacement
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedCountPlacement
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacementModifier
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacement
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedSplitPlacement
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedSplitPlacement
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.SplitPlacement
|
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.WormPlacement
|
import ru.dbotthepony.mc.otm.worldgen.placement.WormPlacement
|
||||||
import ru.dbotthepony.mc.otm.worldgen.wrap
|
import ru.dbotthepony.mc.otm.worldgen.wrap
|
||||||
|
|
||||||
private object ConfiguredFeatures {
|
private object ConfiguredFeatures {
|
||||||
val TRITANIUM_ORE = key("tritanium_ore")
|
val TRITANIUM_ORE = key("tritanium_ore")
|
||||||
val TRITANIUM_ORE_SMALL = key("tritanium_ore_small")
|
val TRITANIUM_ORE_SMALL = key("tritanium_ore_small")
|
||||||
val DILITHIUM = ekey("dilithium")
|
val DILITHIUM = key("dilithium")
|
||||||
val BLACK_HOLE = key("black_hole")
|
val BLACK_HOLE = key("black_hole")
|
||||||
|
|
||||||
private fun key(name: String): ResourceKey<ConfiguredFeature<*, *>> {
|
private fun key(name: String): ResourceKey<ConfiguredFeature<*, *>> {
|
||||||
@ -62,17 +60,6 @@ private object ConfiguredFeatures {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun registerEnhancedConfiguredFeatures(context: BootstrapContext<EnhancedFeature.Configured<*, *>>) {
|
fun registerEnhancedConfiguredFeatures(context: BootstrapContext<EnhancedFeature.Configured<*, *>>) {
|
||||||
val stone = TagMatchTest(BlockTags.STONE_ORE_REPLACEABLES)
|
|
||||||
val deepslate = TagMatchTest(BlockTags.DEEPSLATE_ORE_REPLACEABLES)
|
|
||||||
|
|
||||||
run {
|
|
||||||
val target = listOf(
|
|
||||||
OreConfiguration.target(stone, MBlocks.DILITHIUM_ORE.defaultBlockState()),
|
|
||||||
OreConfiguration.target(deepslate, MBlocks.DEEPSLATE_DILITHIUM_ORE.defaultBlockState()),
|
|
||||||
)
|
|
||||||
|
|
||||||
context.register(ConfiguredFeatures.DILITHIUM, EnhancedFeature.Wrapper.configure(ConfiguredFeature(Feature.REPLACE_SINGLE_BLOCK, ReplaceBlockConfiguration(target))))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun registerConfiguredFeatures(context: BootstrapContext<ConfiguredFeature<*, *>>) {
|
fun registerConfiguredFeatures(context: BootstrapContext<ConfiguredFeature<*, *>>) {
|
||||||
@ -90,6 +77,15 @@ fun registerConfiguredFeatures(context: BootstrapContext<ConfiguredFeature<*, *>
|
|||||||
//context.register(ConfiguredFeatures.TRITANIUM_ORE_SMALL, ConfiguredFeature(MWorldGenFeatures.DEBUG_PLACEMENT, DebugPlacerFeature.Config(MBlocks.TRITANIUM_ORE.defaultBlockState())))
|
//context.register(ConfiguredFeatures.TRITANIUM_ORE_SMALL, ConfiguredFeature(MWorldGenFeatures.DEBUG_PLACEMENT, DebugPlacerFeature.Config(MBlocks.TRITANIUM_ORE.defaultBlockState())))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run {
|
||||||
|
val target = listOf(
|
||||||
|
OreConfiguration.target(stone, MBlocks.DILITHIUM_ORE.defaultBlockState()),
|
||||||
|
OreConfiguration.target(deepslate, MBlocks.DEEPSLATE_DILITHIUM_ORE.defaultBlockState()),
|
||||||
|
)
|
||||||
|
|
||||||
|
context.register(ConfiguredFeatures.DILITHIUM, ConfiguredFeature(Feature.REPLACE_SINGLE_BLOCK, ReplaceBlockConfiguration(target)))
|
||||||
|
}
|
||||||
|
|
||||||
context.register(ConfiguredFeatures.BLACK_HOLE, ConfiguredFeature(
|
context.register(ConfiguredFeatures.BLACK_HOLE, ConfiguredFeature(
|
||||||
MWorldGenFeatures.BLACK_HOLE_PLACER,
|
MWorldGenFeatures.BLACK_HOLE_PLACER,
|
||||||
BlackHolePlacerFeature.Config(Decimal("0.25"), Decimal(1))))
|
BlackHolePlacerFeature.Config(Decimal("0.25"), Decimal(1))))
|
||||||
@ -134,11 +130,16 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
|
|||||||
|
|
||||||
context.register(
|
context.register(
|
||||||
PlacedFeatures.WORM_TRITANIUM,
|
PlacedFeatures.WORM_TRITANIUM,
|
||||||
EnhancedPlacedFeature.Builder(RarityFilter.onAverageOnceEvery(140))
|
EnhancedPlacedFeature.configure(
|
||||||
.then(InSquarePlacement.spread())
|
chunkScanRange = 24,
|
||||||
.then(HeightRangePlacement.of(StandardDeviationHeightProvider(VerticalAnchor.absolute(-40), 15.0)))
|
seedMix = 9284343575495L,
|
||||||
.then(
|
root = EnhancedChainPlacement(
|
||||||
|
RarityFilter.onAverageOnceEvery(140).wrap(),
|
||||||
|
InSquarePlacement.spread().wrap(),
|
||||||
|
HeightRangePlacement.of(StandardDeviationHeightProvider(VerticalAnchor.absolute(-40), 15.0)).wrap(),
|
||||||
|
|
||||||
EnhancedSplitPlacement(
|
EnhancedSplitPlacement(
|
||||||
|
EnhancedSplitPlacement.Mode.COMBINE,
|
||||||
// "heart"
|
// "heart"
|
||||||
EllipsoidPlacement(
|
EllipsoidPlacement(
|
||||||
count = UniformInt.of(600, 900),
|
count = UniformInt.of(600, 900),
|
||||||
@ -174,18 +175,16 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
|
|||||||
z = ClampedNormalFloat.of(0f, 0.2f, -1f, 1f),
|
z = ClampedNormalFloat.of(0f, 0.2f, -1f, 1f),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
configured.getOrThrow(ConfiguredFeatures.TRITANIUM_ORE_SMALL).placement()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.then(configured.getOrThrow(ConfiguredFeatures.TRITANIUM_ORE_SMALL))
|
|
||||||
.build(
|
|
||||||
chunkScanRange = 24,
|
|
||||||
seedMix = 9284343575495L,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
run {
|
run {
|
||||||
val ore = econfigured.getOrThrow(ConfiguredFeatures.DILITHIUM)
|
val ore = configured.getOrThrow(ConfiguredFeatures.DILITHIUM)
|
||||||
|
|
||||||
val ringularity = OneOfFloatProvider.of(
|
val ringularity = OneOfFloatProvider.of(
|
||||||
ClampedNormalFloat.of(0.4f, 0.2f, -2f, 2f),
|
ClampedNormalFloat.of(0.4f, 0.2f, -2f, 2f),
|
||||||
@ -194,10 +193,13 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
|
|||||||
|
|
||||||
context.register(
|
context.register(
|
||||||
PlacedFeatures.DILITHIUM,
|
PlacedFeatures.DILITHIUM,
|
||||||
EnhancedPlacedFeature.Builder(RarityFilter.onAverageOnceEvery(120))
|
EnhancedPlacedFeature.configure(
|
||||||
.then(InSquarePlacement.spread())
|
chunkScanRange = 6,
|
||||||
.then(HeightRangePlacement.of(StandardDeviationHeightProvider(VerticalAnchor.absolute(0), 15.0)))
|
seedMix = 237483209523709234L,
|
||||||
.then(
|
root = EnhancedChainPlacement(
|
||||||
|
RarityFilter.onAverageOnceEvery(120).wrap(),
|
||||||
|
InSquarePlacement.spread().wrap(),
|
||||||
|
HeightRangePlacement.of(StandardDeviationHeightProvider(VerticalAnchor.absolute(0), 15.0)).wrap(),
|
||||||
EllipsoidPlacement(
|
EllipsoidPlacement(
|
||||||
x = ringularity,
|
x = ringularity,
|
||||||
y = ringularity,
|
y = ringularity,
|
||||||
@ -206,12 +208,9 @@ fun registerPlacedFeatures(context: BootstrapContext<PlacedFeature>) {
|
|||||||
xLength = UniformFloat.of(30f, 70f),
|
xLength = UniformFloat.of(30f, 70f),
|
||||||
yLength = UniformFloat.of(40f, 90f),
|
yLength = UniformFloat.of(40f, 90f),
|
||||||
zLength = UniformFloat.of(30f, 70f),
|
zLength = UniformFloat.of(30f, 70f),
|
||||||
) as EnhancedPlacementModifier
|
),
|
||||||
|
ore.placement()
|
||||||
)
|
)
|
||||||
.then(ore)
|
|
||||||
.build(
|
|
||||||
chunkScanRange = 6,
|
|
||||||
seedMix = 237483209523709234L,
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,8 @@ import net.neoforged.bus.api.EventPriority
|
|||||||
import net.neoforged.fml.common.Mod
|
import net.neoforged.fml.common.Mod
|
||||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
|
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent
|
||||||
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent
|
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent
|
||||||
import ru.dbotthepony.mc.otm.player.android.AndroidResearchDescription
|
|
||||||
import ru.dbotthepony.mc.otm.player.android.AndroidResearchDescriptions
|
import ru.dbotthepony.mc.otm.player.android.AndroidResearchDescriptions
|
||||||
import ru.dbotthepony.mc.otm.player.android.AndroidResearchManager
|
import ru.dbotthepony.mc.otm.player.android.AndroidResearchManager
|
||||||
import ru.dbotthepony.mc.otm.player.android.AndroidResearchResult
|
|
||||||
import ru.dbotthepony.mc.otm.player.android.AndroidResearchResults
|
import ru.dbotthepony.mc.otm.player.android.AndroidResearchResults
|
||||||
import ru.dbotthepony.mc.otm.player.android.feature.EnderTeleporterFeature
|
import ru.dbotthepony.mc.otm.player.android.feature.EnderTeleporterFeature
|
||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
||||||
@ -93,7 +91,7 @@ import ru.dbotthepony.mc.otm.server.MCommands
|
|||||||
import ru.dbotthepony.mc.otm.storage.StorageStack
|
import ru.dbotthepony.mc.otm.storage.StorageStack
|
||||||
import ru.dbotthepony.mc.otm.triggers.KillAsAndroidTrigger
|
import ru.dbotthepony.mc.otm.triggers.KillAsAndroidTrigger
|
||||||
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacementModifier
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacement
|
||||||
import thedarkcolour.kotlinforforge.neoforge.forge.DIST
|
import thedarkcolour.kotlinforforge.neoforge.forge.DIST
|
||||||
import thedarkcolour.kotlinforforge.neoforge.forge.FORGE_BUS
|
import thedarkcolour.kotlinforforge.neoforge.forge.FORGE_BUS
|
||||||
import thedarkcolour.kotlinforforge.neoforge.forge.LOADING_CONTEXT
|
import thedarkcolour.kotlinforforge.neoforge.forge.LOADING_CONTEXT
|
||||||
@ -142,7 +140,7 @@ object OverdriveThatMatters {
|
|||||||
DecimalProvider.register(MOD_BUS)
|
DecimalProvider.register(MOD_BUS)
|
||||||
BooleanProvider.register(MOD_BUS)
|
BooleanProvider.register(MOD_BUS)
|
||||||
EnhancedFeature.register(MOD_BUS)
|
EnhancedFeature.register(MOD_BUS)
|
||||||
EnhancedPlacementModifier.register(MOD_BUS)
|
EnhancedPlacement.register(MOD_BUS)
|
||||||
AndroidResearchDescriptions.register(MOD_BUS)
|
AndroidResearchDescriptions.register(MOD_BUS)
|
||||||
AndroidResearchResults.register(MOD_BUS)
|
AndroidResearchResults.register(MOD_BUS)
|
||||||
|
|
||||||
|
@ -13,9 +13,8 @@ import ru.dbotthepony.mc.otm.player.android.AndroidFeatureType
|
|||||||
import ru.dbotthepony.mc.otm.player.android.AndroidResearchDescription
|
import ru.dbotthepony.mc.otm.player.android.AndroidResearchDescription
|
||||||
import ru.dbotthepony.mc.otm.player.android.AndroidResearchResult
|
import ru.dbotthepony.mc.otm.player.android.AndroidResearchResult
|
||||||
import ru.dbotthepony.mc.otm.storage.StorageStack
|
import ru.dbotthepony.mc.otm.storage.StorageStack
|
||||||
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacedFeature
|
|
||||||
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacementModifier
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacement
|
||||||
|
|
||||||
object MRegistries {
|
object MRegistries {
|
||||||
private fun <T> k(name: String): ResourceKey<Registry<T>> {
|
private fun <T> k(name: String): ResourceKey<Registry<T>> {
|
||||||
@ -33,5 +32,5 @@ object MRegistries {
|
|||||||
val BOOLEAN_PROVIDER = k<BooleanProvider.Type<*>>("boolean_provider")
|
val BOOLEAN_PROVIDER = k<BooleanProvider.Type<*>>("boolean_provider")
|
||||||
val FEATURE = k<EnhancedFeature<*>>("feature")
|
val FEATURE = k<EnhancedFeature<*>>("feature")
|
||||||
val CONFIGURED_FEATURE = k<EnhancedFeature.Configured<*, *>>("configured_feature")
|
val CONFIGURED_FEATURE = k<EnhancedFeature.Configured<*, *>>("configured_feature")
|
||||||
val PLACEMENT_MODIFIER = k<EnhancedPlacementModifier.Type<*>>("placement_modifier")
|
val PLACEMENT_MODIFIER = k<EnhancedPlacement.Type<*>>("placement_modifier")
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ 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.registry.MRegistries
|
import ru.dbotthepony.mc.otm.registry.MRegistries
|
||||||
|
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.ChainPlacement
|
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.EnhancedChainPlacement
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedChainPlacement
|
||||||
@ -28,6 +29,7 @@ object MPlacementModifiers {
|
|||||||
val CHAIN by registry.register("chain") { PlacementModifierType { ChainPlacement.CODEC } }
|
val CHAIN by registry.register("chain") { PlacementModifierType { ChainPlacement.CODEC } }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
enhancedRegistry.register("feature") { EnhancedFeature.ConfiguredWrapper.Companion }
|
||||||
enhancedRegistry.register("ellipsoid") { EllipsoidPlacement.Companion }
|
enhancedRegistry.register("ellipsoid") { EllipsoidPlacement.Companion }
|
||||||
enhancedRegistry.register("worm") { WormPlacement.Companion }
|
enhancedRegistry.register("worm") { WormPlacement.Companion }
|
||||||
enhancedRegistry.register("split") { EnhancedSplitPlacement.Companion }
|
enhancedRegistry.register("split") { EnhancedSplitPlacement.Companion }
|
||||||
|
@ -10,7 +10,6 @@ import com.mojang.serialization.DataResult
|
|||||||
import com.mojang.serialization.DynamicOps
|
import com.mojang.serialization.DynamicOps
|
||||||
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.ObjectArraySet
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet
|
import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet
|
||||||
import net.minecraft.Util
|
import net.minecraft.Util
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
@ -26,122 +25,38 @@ import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfigur
|
|||||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
||||||
import ru.dbotthepony.kommons.util.XXHash64
|
import ru.dbotthepony.kommons.util.XXHash64
|
||||||
import ru.dbotthepony.mc.otm.core.collect.BlockPosSet
|
|
||||||
import ru.dbotthepony.mc.otm.core.collect.Vec3iHashStrategy
|
|
||||||
import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource
|
import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource
|
||||||
import ru.dbotthepony.mc.otm.data.codec.minRange
|
import ru.dbotthepony.mc.otm.data.codec.minRange
|
||||||
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacementModifier
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacement
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.LinkedList
|
import java.util.LinkedList
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
private object NodeCodec : Codec<EnhancedPlacedFeature.Node> {
|
|
||||||
private val list = Codec.list(this)
|
|
||||||
|
|
||||||
override fun <T : Any?> encode(input: EnhancedPlacedFeature.Node, ops: DynamicOps<T>, prefix: T): DataResult<T> {
|
|
||||||
val result = HashMap<T, T>()
|
|
||||||
|
|
||||||
if (input.children.isNotEmpty()) {
|
|
||||||
val re = list.encodeStart(ops, input.children)
|
|
||||||
|
|
||||||
if (re.isError)
|
|
||||||
return re
|
|
||||||
|
|
||||||
result[ops.createString("children")] = re.resultOrPartial().get()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input.contents.left().isPresent) {
|
|
||||||
val re = EnhancedPlacementModifier.CODEC.encodeStart(ops, input.contents.left().get())
|
|
||||||
|
|
||||||
if (re.isError)
|
|
||||||
return DataResult.error { "Failed to serialize placement modifier: ${re.error().get().message()}" }
|
|
||||||
|
|
||||||
result[ops.createString("modifier")] = re.resultOrPartial().get()
|
|
||||||
} else {
|
|
||||||
val re = EnhancedFeature.CODEC.encodeStart(ops, input.contents.right().get())
|
|
||||||
|
|
||||||
if (re.isError)
|
|
||||||
return DataResult.error { "Failed to serialize feature: ${re.error().get().message()}" }
|
|
||||||
|
|
||||||
result[ops.createString("feature")] = re.resultOrPartial().get()
|
|
||||||
}
|
|
||||||
|
|
||||||
return ops.mergeToMap(prefix, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun <T : Any?> decode(ops: DynamicOps<T>, input: T): DataResult<Pair<EnhancedPlacedFeature.Node, T>> {
|
|
||||||
return ops.getMap(input).flatMap {
|
|
||||||
val children = it.get("children")
|
|
||||||
val modifier = it.get("modifier")
|
|
||||||
val feature = it.get("feature")
|
|
||||||
|
|
||||||
if (modifier != null && feature != null) {
|
|
||||||
return@flatMap DataResult.error { "Enhanced feature placement node should have either modifier or feature, but both are present" }
|
|
||||||
} else if (modifier == null && feature == null) {
|
|
||||||
return@flatMap DataResult.error { "Enhanced feature placement node contains no modifier and no feature" }
|
|
||||||
}
|
|
||||||
|
|
||||||
val deserializeChildren: List<EnhancedPlacedFeature.Node>
|
|
||||||
|
|
||||||
if (children != null) {
|
|
||||||
val result = list.decode(ops, children)
|
|
||||||
|
|
||||||
if (result.isError)
|
|
||||||
return@flatMap DataResult.error { result.error().get().message() }
|
|
||||||
|
|
||||||
deserializeChildren = result.map { it.first }.getOrThrow()
|
|
||||||
} else {
|
|
||||||
deserializeChildren = emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modifier != null) {
|
|
||||||
return@flatMap EnhancedPlacementModifier.CODEC.decode(ops, modifier).map { Pair(EnhancedPlacedFeature.Node(deserializeChildren, Either.left(it.first)), ops.empty()) }
|
|
||||||
} else {
|
|
||||||
return@flatMap EnhancedFeature.CODEC.decode(ops, feature).map { Pair(EnhancedPlacedFeature.Node(deserializeChildren, Either.right(it.first)), ops.empty()) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
||||||
RecordCodecBuilder.create {
|
RecordCodecBuilder.create {
|
||||||
it.group(
|
it.group(
|
||||||
Codec.INT.minRange(0).fieldOf("chunk_scan_range").forGetter(Config::chunkScanRange),
|
Codec.INT.minRange(0).fieldOf("chunk_scan_range").forGetter(Config::chunkScanRange),
|
||||||
Codec.LONG.fieldOf("seed_mix").forGetter(Config::seedMix),
|
Codec.LONG.fieldOf("seed_mix").forGetter(Config::seedMix),
|
||||||
NodeCodec.fieldOf("root").forGetter(Config::root),
|
EnhancedPlacement.CODEC.fieldOf("root").forGetter(Config::root),
|
||||||
).apply(it, ::Config)
|
).apply(it, ::Config)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
class Node(val children: List<Node>, val contents: Either<EnhancedPlacementModifier, Holder<EnhancedFeature.Configured<*, *>>>){
|
|
||||||
fun evaluate(context: EnhancedPlacementContext) {
|
|
||||||
evaluate(context, listOf(PlacementPos(BlockPos(context.origin.minBlockX, 0, context.origin.minBlockZ), PlacementVariableMap())))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>) {
|
|
||||||
val actualPositions = if (contents.left().isPresent) {
|
|
||||||
contents.left().get().evaluate(context, positions)
|
|
||||||
} else {
|
|
||||||
positions
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contents.right().isPresent) {
|
|
||||||
context.place(actualPositions, contents.right().get().value())
|
|
||||||
}
|
|
||||||
|
|
||||||
children.forEach {
|
|
||||||
it.evaluate(context.push(), actualPositions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val emptyVariableMap = PlacementVariableMap()
|
private val emptyVariableMap = PlacementVariableMap()
|
||||||
|
|
||||||
|
fun configure(
|
||||||
|
chunkScanRange: Int,
|
||||||
|
seedMix: Long,
|
||||||
|
root: EnhancedPlacement
|
||||||
|
): PlacedFeature {
|
||||||
|
return PlacedFeature(Holder.direct(ConfiguredFeature(EnhancedPlacedFeature, Config(chunkScanRange, seedMix, root))), listOf())
|
||||||
|
}
|
||||||
|
|
||||||
class Config(
|
class Config(
|
||||||
val chunkScanRange: Int,
|
val chunkScanRange: Int,
|
||||||
val seedMix: Long,
|
val seedMix: Long,
|
||||||
val root: Node,
|
val root: EnhancedPlacement,
|
||||||
) : FeatureConfiguration {
|
) : FeatureConfiguration {
|
||||||
private class GeneratedChunk : EnhancedPlacementContext.Placer {
|
private class GeneratedChunk : EnhancedPlacementContext.Placer {
|
||||||
private data class Placement(val context: EnhancedPlacementContext, val positions: ObjectRBTreeSet<PlacementPos>, val feature: EnhancedFeature.Configured<*, *>)
|
private data class Placement(val context: EnhancedPlacementContext, val positions: ObjectRBTreeSet<PlacementPos>, val feature: EnhancedFeature.Configured<*, *>)
|
||||||
@ -215,7 +130,7 @@ object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
|||||||
|
|
||||||
val chunk = GeneratedChunk()
|
val chunk = GeneratedChunk()
|
||||||
val enhancedContext = EnhancedPlacementContext(context.level(), context.chunkGenerator(), random, chunkPos, chunk)
|
val enhancedContext = EnhancedPlacementContext(context.level(), context.chunkGenerator(), random, chunkPos, chunk)
|
||||||
root.evaluate(enhancedContext)
|
root.evaluate(enhancedContext, listOf(PlacementPos(BlockPos(chunkPos.minBlockX, 0, chunkPos.minBlockZ), PlacementVariableMap())))
|
||||||
return chunk
|
return chunk
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,91 +160,4 @@ object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
|||||||
override fun place(context: FeaturePlaceContext<Config>): Boolean {
|
override fun place(context: FeaturePlaceContext<Config>): Boolean {
|
||||||
return context.config().place(context)
|
return context.config().place(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Builder {
|
|
||||||
private val root: Builder?
|
|
||||||
private val children = ArrayList<Builder>()
|
|
||||||
private val contents: Either<EnhancedPlacementModifier, Holder<EnhancedFeature.Configured<*, *>>>
|
|
||||||
|
|
||||||
constructor() : this(EnhancedPlacementModifier.Passthrough)
|
|
||||||
|
|
||||||
constructor(root: EnhancedPlacementModifier) {
|
|
||||||
this.root = null
|
|
||||||
this.contents = Either.left(root)
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(root: PlacementModifier) : this(EnhancedPlacementModifier.Wrapper(root))
|
|
||||||
|
|
||||||
constructor(root: Holder<EnhancedFeature.Configured<*, *>>) {
|
|
||||||
this.root = null
|
|
||||||
this.contents = Either.right(root)
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(root: EnhancedFeature.Configured<*, *>) {
|
|
||||||
this.root = null
|
|
||||||
this.contents = Either.right(Holder.direct(root))
|
|
||||||
}
|
|
||||||
|
|
||||||
private constructor(parent: Builder, root: PlacementModifier) : this(parent, EnhancedPlacementModifier.Wrapper(root))
|
|
||||||
|
|
||||||
private constructor(parent: Builder, root: EnhancedPlacementModifier) {
|
|
||||||
this.root = parent
|
|
||||||
this.contents = Either.left(root)
|
|
||||||
}
|
|
||||||
|
|
||||||
private constructor(parent: Builder, root: Holder<EnhancedFeature.Configured<*, *>>) {
|
|
||||||
this.root = parent
|
|
||||||
this.contents = Either.right(root)
|
|
||||||
}
|
|
||||||
|
|
||||||
private constructor(parent: Builder, root: EnhancedFeature.Configured<*, *>) {
|
|
||||||
this.root = parent
|
|
||||||
this.contents = Either.right(Holder.direct(root))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun then(action: PlacementModifier): Builder {
|
|
||||||
return Builder(root ?: this, action).also(children::add)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun then(action: EnhancedPlacementModifier): Builder {
|
|
||||||
return Builder(root ?: this, action).also(children::add)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun then(action: EnhancedFeature.Configured<*, *>): Builder {
|
|
||||||
return Builder(root ?: this, action).also(children::add)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun then(action: Holder<EnhancedFeature.Configured<*, *>>): Builder {
|
|
||||||
return Builder(root ?: this, action).also(children::add)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmName("thenVanilla")
|
|
||||||
fun then(action: ConfiguredFeature<*, *>): Builder {
|
|
||||||
return then(EnhancedFeature.Wrapper.configure(action))
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmName("thenVanilla")
|
|
||||||
fun then(action: Holder<ConfiguredFeature<*, *>>): Builder {
|
|
||||||
return then(EnhancedFeature.Wrapper.configure(action))
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun fork(configurator: Builder.() -> Unit): Builder {
|
|
||||||
configurator(this)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildNode(): Node {
|
|
||||||
return Node(children.map { it.buildNode() }, contents)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun build(
|
|
||||||
chunkScanRange: Int,
|
|
||||||
seedMix: Long,
|
|
||||||
): PlacedFeature {
|
|
||||||
if (root != null)
|
|
||||||
return root.build(chunkScanRange, seedMix)
|
|
||||||
|
|
||||||
return PlacedFeature(Holder.direct(ConfiguredFeature(EnhancedPlacedFeature, Config(chunkScanRange, seedMix, buildNode()))), listOf())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package ru.dbotthepony.mc.otm.worldgen
|
package ru.dbotthepony.mc.otm.worldgen
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.util.RandomSource
|
import net.minecraft.util.RandomSource
|
||||||
import net.minecraft.world.level.ChunkPos
|
import net.minecraft.world.level.ChunkPos
|
||||||
@ -9,10 +8,8 @@ import net.minecraft.world.level.chunk.ChunkGenerator
|
|||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext
|
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementContext
|
import net.minecraft.world.level.levelgen.placement.PlacementContext
|
||||||
import ru.dbotthepony.kommons.util.KOptional
|
|
||||||
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.HashMap
|
|
||||||
|
|
||||||
class EnhancedPlacementContext {
|
class EnhancedPlacementContext {
|
||||||
fun interface Placer {
|
fun interface Placer {
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package ru.dbotthepony.mc.otm.worldgen
|
package ru.dbotthepony.mc.otm.worldgen
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
|
import net.minecraft.core.Holder
|
||||||
|
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
||||||
import ru.dbotthepony.mc.otm.core.collect.Vec3iHashStrategy
|
import ru.dbotthepony.mc.otm.core.collect.Vec3iHashStrategy
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacementModifier
|
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
||||||
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacement
|
||||||
|
|
||||||
fun PlacementModifier.wrap(): EnhancedPlacementModifier {
|
fun PlacementModifier.wrap(): EnhancedPlacement {
|
||||||
return EnhancedPlacementModifier.Wrapper(this)
|
return EnhancedPlacement.Wrapper(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PlacementPos(val pos: BlockPos, val variables: PlacementVariableMap) : Comparable<PlacementPos> {
|
data class PlacementPos(val pos: BlockPos, val variables: PlacementVariableMap) : Comparable<PlacementPos> {
|
||||||
@ -14,3 +17,9 @@ data class PlacementPos(val pos: BlockPos, val variables: PlacementVariableMap)
|
|||||||
return Vec3iHashStrategy.compare(pos, other.pos)
|
return Vec3iHashStrategy.compare(pos, other.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmName("placement")
|
||||||
|
fun Holder<EnhancedFeature.Configured<*, *>>.placement() = EnhancedFeature.ConfiguredWrapper(this)
|
||||||
|
@JvmName("vanillaPlacement")
|
||||||
|
fun Holder<ConfiguredFeature<*, *>>.placement() = EnhancedFeature.Wrapper.configure(this)
|
||||||
|
fun ConfiguredFeature<*, *>.placement() = EnhancedFeature.Wrapper.configure(this)
|
||||||
|
@ -13,6 +13,7 @@ import ru.dbotthepony.mc.otm.registry.MDeferredRegister
|
|||||||
import ru.dbotthepony.mc.otm.registry.MRegistries
|
import ru.dbotthepony.mc.otm.registry.MRegistries
|
||||||
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
||||||
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
||||||
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacement
|
||||||
|
|
||||||
abstract class EnhancedFeature<FC>(codec: Codec<FC>) {
|
abstract class EnhancedFeature<FC>(codec: Codec<FC>) {
|
||||||
abstract fun place(context: EnhancedPlacementContext, config: FC, positions: Set<PlacementPos>, allPositions: Set<PlacementPos>): Boolean
|
abstract fun place(context: EnhancedPlacementContext, config: FC, positions: Set<PlacementPos>, allPositions: Set<PlacementPos>): Boolean
|
||||||
@ -21,10 +22,30 @@ abstract class EnhancedFeature<FC>(codec: Codec<FC>) {
|
|||||||
fun place(context: EnhancedPlacementContext, positions: Set<PlacementPos>, allPositions: Set<PlacementPos>): Boolean {
|
fun place(context: EnhancedPlacementContext, positions: Set<PlacementPos>, allPositions: Set<PlacementPos>): Boolean {
|
||||||
return feature.place(context, config, positions, allPositions)
|
return feature.place(context, config, positions, allPositions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun placement(): ConfiguredWrapper {
|
||||||
|
return ConfiguredWrapper(Holder.direct(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ConfiguredWrapper(val configured: Holder<Configured<*, *>>) : EnhancedPlacement {
|
||||||
|
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
||||||
|
context.place(positions, configured.value())
|
||||||
|
return positions
|
||||||
|
}
|
||||||
|
|
||||||
|
override val type: EnhancedPlacement.Type<*>
|
||||||
|
get() = Companion
|
||||||
|
|
||||||
|
companion object : EnhancedPlacement.Type<ConfiguredWrapper> {
|
||||||
|
override val codec: MapCodec<ConfiguredWrapper> by lazy {
|
||||||
|
CODEC.xmap(::ConfiguredWrapper, ConfiguredWrapper::configured).fieldOf("feature")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val codec: MapCodec<Configured<*, FC>> = codec.fieldOf("config").xmap({ Configured(this, it) }, { it.config })
|
val codec: MapCodec<Configured<*, FC>> = codec.fieldOf("config").xmap({ Configured(this, it) }, { it.config })
|
||||||
fun configure(config: FC) = Configured(this, config)
|
fun configure(config: FC) = Configured(this, config).placement()
|
||||||
|
|
||||||
object Wrapper : EnhancedFeature<Holder<ConfiguredFeature<*, *>>>(ConfiguredFeature.CODEC) {
|
object Wrapper : EnhancedFeature<Holder<ConfiguredFeature<*, *>>>(ConfiguredFeature.CODEC) {
|
||||||
override fun place(
|
override fun place(
|
||||||
|
@ -14,7 +14,6 @@ import ru.dbotthepony.mc.otm.core.collect.Vec3iHashStrategy
|
|||||||
import ru.dbotthepony.mc.otm.registry.data.MPlacementModifiers
|
import ru.dbotthepony.mc.otm.registry.data.MPlacementModifiers
|
||||||
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
||||||
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
||||||
import ru.dbotthepony.mc.otm.worldgen.PlacementVariableMap
|
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,7 +54,7 @@ data class EllipsoidPlacement(
|
|||||||
* Ellipsoid size sampler on Y axis
|
* Ellipsoid size sampler on Y axis
|
||||||
*/
|
*/
|
||||||
val yLength: FloatProvider,
|
val yLength: FloatProvider,
|
||||||
) : PlacementModifier(), EnhancedPlacementModifier {
|
) : PlacementModifier(), EnhancedPlacement {
|
||||||
init {
|
init {
|
||||||
require(xLength.minValue >= 1f) { "Bad ellipsoid x minimal size: $xLength" }
|
require(xLength.minValue >= 1f) { "Bad ellipsoid x minimal size: $xLength" }
|
||||||
require(zLength.minValue >= 1f) { "Bad ellipsoid z minimal size: $zLength" }
|
require(zLength.minValue >= 1f) { "Bad ellipsoid z minimal size: $zLength" }
|
||||||
@ -113,14 +112,14 @@ data class EllipsoidPlacement(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override val type: EnhancedPlacementModifier.Type<*>
|
override val type: EnhancedPlacement.Type<*>
|
||||||
get() = Companion
|
get() = Companion
|
||||||
|
|
||||||
override fun type(): PlacementModifierType<*> {
|
override fun type(): PlacementModifierType<*> {
|
||||||
return MPlacementModifiers.ELLIPSOID_PLACEMENT
|
return MPlacementModifiers.ELLIPSOID_PLACEMENT
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : EnhancedPlacementModifier.Type<EllipsoidPlacement> {
|
companion object : EnhancedPlacement.Type<EllipsoidPlacement> {
|
||||||
val CODEC: MapCodec<EllipsoidPlacement> by lazy {
|
val CODEC: MapCodec<EllipsoidPlacement> by lazy {
|
||||||
RecordCodecBuilder.mapCodec {
|
RecordCodecBuilder.mapCodec {
|
||||||
it.group(
|
it.group(
|
||||||
|
@ -3,31 +3,37 @@ package ru.dbotthepony.mc.otm.worldgen.placement
|
|||||||
import com.google.common.collect.ImmutableList
|
import com.google.common.collect.ImmutableList
|
||||||
import com.mojang.serialization.Codec
|
import com.mojang.serialization.Codec
|
||||||
import com.mojang.serialization.MapCodec
|
import com.mojang.serialization.MapCodec
|
||||||
import net.minecraft.core.BlockPos
|
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
|
||||||
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
||||||
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Daisy-chaining placements. Required only when using placement modifiers which operate on children list
|
* Chains placements, feeding results from one placement into next
|
||||||
|
*
|
||||||
|
* Each placement gets its own, new [EnhancedPlacementContext], so variables can be pushed safely into it
|
||||||
*/
|
*/
|
||||||
class EnhancedChainPlacement(
|
class EnhancedChainPlacement(
|
||||||
val children: List<EnhancedPlacementModifier>
|
val children: List<EnhancedPlacement>
|
||||||
) : EnhancedPlacementModifier {
|
) : EnhancedPlacement {
|
||||||
constructor(vararg children: EnhancedPlacementModifier) : this(ImmutableList.copyOf(children))
|
constructor(vararg children: EnhancedPlacement) : this(ImmutableList.copyOf(children))
|
||||||
|
|
||||||
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
||||||
|
var currentContext = context
|
||||||
var current = positions
|
var current = positions
|
||||||
children.forEach { current = it.evaluate(context, current) }
|
|
||||||
|
children.forEach {
|
||||||
|
current = it.evaluate(context, current)
|
||||||
|
currentContext = currentContext.push()
|
||||||
|
}
|
||||||
|
|
||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
|
|
||||||
override val type: EnhancedPlacementModifier.Type<*>
|
override val type: EnhancedPlacement.Type<*>
|
||||||
get() = Companion
|
get() = Companion
|
||||||
|
|
||||||
companion object : EnhancedPlacementModifier.Type<EnhancedChainPlacement> {
|
companion object : EnhancedPlacement.Type<EnhancedChainPlacement> {
|
||||||
override val codec: MapCodec<EnhancedChainPlacement> by lazy {
|
override val codec: MapCodec<EnhancedChainPlacement> by lazy {
|
||||||
Codec.list(EnhancedPlacementModifier.CODEC).xmap(::EnhancedChainPlacement, EnhancedChainPlacement::children).fieldOf("children")
|
Codec.list(EnhancedPlacement.CODEC).xmap(::EnhancedChainPlacement, EnhancedChainPlacement::children).fieldOf("children")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import net.minecraft.util.valueproviders.IntProvider
|
|||||||
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
||||||
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
||||||
|
|
||||||
class EnhancedCountPlacement(val provider: IntProvider) : EnhancedPlacementModifier {
|
class EnhancedCountPlacement(val provider: IntProvider) : EnhancedPlacement {
|
||||||
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
||||||
val count = provider.sample(context.random)
|
val count = provider.sample(context.random)
|
||||||
|
|
||||||
@ -21,10 +21,10 @@ class EnhancedCountPlacement(val provider: IntProvider) : EnhancedPlacementModif
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val type: EnhancedPlacementModifier.Type<*>
|
override val type: EnhancedPlacement.Type<*>
|
||||||
get() = Companion
|
get() = Companion
|
||||||
|
|
||||||
companion object : EnhancedPlacementModifier.Type<EnhancedCountPlacement> {
|
companion object : EnhancedPlacement.Type<EnhancedCountPlacement> {
|
||||||
override val codec: MapCodec<EnhancedCountPlacement> = IntProvider.CODEC.xmap(::EnhancedCountPlacement, EnhancedCountPlacement::provider).fieldOf("count")
|
override val codec: MapCodec<EnhancedCountPlacement> = IntProvider.CODEC.xmap(::EnhancedCountPlacement, EnhancedCountPlacement::provider).fieldOf("count")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@ package ru.dbotthepony.mc.otm.worldgen.placement
|
|||||||
|
|
||||||
import com.mojang.serialization.Codec
|
import com.mojang.serialization.Codec
|
||||||
import com.mojang.serialization.MapCodec
|
import com.mojang.serialization.MapCodec
|
||||||
import net.minecraft.core.BlockPos
|
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementContext
|
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
||||||
import net.neoforged.bus.api.IEventBus
|
import net.neoforged.bus.api.IEventBus
|
||||||
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
|
import ru.dbotthepony.mc.otm.registry.MBuiltInRegistries
|
||||||
@ -11,18 +9,17 @@ import ru.dbotthepony.mc.otm.registry.MDeferredRegister
|
|||||||
import ru.dbotthepony.mc.otm.registry.MRegistries
|
import ru.dbotthepony.mc.otm.registry.MRegistries
|
||||||
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
||||||
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
||||||
import ru.dbotthepony.mc.otm.worldgen.PlacementVariableMap
|
|
||||||
import java.util.stream.Collectors
|
import java.util.stream.Collectors
|
||||||
|
|
||||||
interface EnhancedPlacementModifier {
|
interface EnhancedPlacement {
|
||||||
interface Type<T : EnhancedPlacementModifier> {
|
interface Type<T : EnhancedPlacement> {
|
||||||
val codec: MapCodec<T>
|
val codec: MapCodec<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos>
|
fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos>
|
||||||
val type: Type<*>
|
val type: Type<*>
|
||||||
|
|
||||||
class Wrapper(val parent: PlacementModifier) : EnhancedPlacementModifier {
|
class Wrapper(val parent: PlacementModifier) : EnhancedPlacement {
|
||||||
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
||||||
return positions.stream()
|
return positions.stream()
|
||||||
.flatMap { (pos, vars) -> parent.getPositions(context.vanillaContext, context.random, pos).map { PlacementPos(it, vars) } }
|
.flatMap { (pos, vars) -> parent.getPositions(context.vanillaContext, context.random, pos).map { PlacementPos(it, vars) } }
|
||||||
@ -37,7 +34,7 @@ interface EnhancedPlacementModifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object Passthrough : EnhancedPlacementModifier, Type<Passthrough> {
|
object Passthrough : EnhancedPlacement, Type<Passthrough> {
|
||||||
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
||||||
return positions
|
return positions
|
||||||
}
|
}
|
||||||
@ -56,7 +53,7 @@ interface EnhancedPlacementModifier {
|
|||||||
registrar.register("passthrough") { Passthrough }
|
registrar.register("passthrough") { Passthrough }
|
||||||
}
|
}
|
||||||
|
|
||||||
val CODEC: Codec<EnhancedPlacementModifier> by lazy {
|
val CODEC: Codec<EnhancedPlacement> by lazy {
|
||||||
MBuiltInRegistries.PLACEMENT_MODIFIER.byNameCodec().dispatch({ it.type }, { it.codec })
|
MBuiltInRegistries.PLACEMENT_MODIFIER.byNameCodec().dispatch({ it.type }, { it.codec })
|
||||||
}
|
}
|
||||||
|
|
@ -3,16 +3,11 @@ package ru.dbotthepony.mc.otm.worldgen.placement
|
|||||||
import com.google.common.collect.ImmutableList
|
import com.google.common.collect.ImmutableList
|
||||||
import com.mojang.serialization.Codec
|
import com.mojang.serialization.Codec
|
||||||
import com.mojang.serialization.MapCodec
|
import com.mojang.serialization.MapCodec
|
||||||
import net.minecraft.core.BlockPos
|
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||||
import net.minecraft.util.RandomSource
|
import net.minecraft.util.StringRepresentable
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementContext
|
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
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 ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
import ru.dbotthepony.mc.otm.worldgen.EnhancedPlacementContext
|
||||||
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
import ru.dbotthepony.mc.otm.worldgen.PlacementPos
|
||||||
import java.util.stream.Collectors
|
|
||||||
import java.util.stream.Stream
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Or "shard" placement, if you will.
|
* Or "shard" placement, if you will.
|
||||||
@ -20,22 +15,48 @@ import java.util.stream.Stream
|
|||||||
* Basically, allows multiple [PlacementModifier]s to split/branch off from provided point.
|
* Basically, allows multiple [PlacementModifier]s to split/branch off from provided point.
|
||||||
*/
|
*/
|
||||||
class EnhancedSplitPlacement(
|
class EnhancedSplitPlacement(
|
||||||
val children: List<EnhancedPlacementModifier>
|
val mode: Mode,
|
||||||
) : EnhancedPlacementModifier {
|
val children: List<EnhancedPlacement>,
|
||||||
constructor(vararg children: EnhancedPlacementModifier) : this(ImmutableList.copyOf(children))
|
) : EnhancedPlacement {
|
||||||
|
constructor(mode: Mode, vararg children: EnhancedPlacement) : this(mode, ImmutableList.copyOf(children))
|
||||||
|
|
||||||
|
enum class Mode : StringRepresentable {
|
||||||
|
COMBINE,
|
||||||
|
FORK;
|
||||||
|
|
||||||
|
private val lname = name.lowercase()
|
||||||
|
|
||||||
|
override fun getSerializedName(): String {
|
||||||
|
return lname
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val CODEC: Codec<Mode> = StringRepresentable.fromEnum(::values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
override fun evaluate(context: EnhancedPlacementContext, positions: List<PlacementPos>): List<PlacementPos> {
|
||||||
|
if (mode == Mode.COMBINE) {
|
||||||
val result = ArrayList<PlacementPos>()
|
val result = ArrayList<PlacementPos>()
|
||||||
children.forEach { result.addAll(it.evaluate(context, positions)) }
|
children.forEach { result.addAll(it.evaluate(context.push(), positions)) }
|
||||||
return result
|
return result
|
||||||
|
} else {
|
||||||
|
children.forEach { it.evaluate(context.push(), positions) }
|
||||||
|
return positions
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val type: EnhancedPlacementModifier.Type<*>
|
override val type: EnhancedPlacement.Type<*>
|
||||||
get() = Companion
|
get() = Companion
|
||||||
|
|
||||||
companion object : EnhancedPlacementModifier.Type<EnhancedSplitPlacement> {
|
companion object : EnhancedPlacement.Type<EnhancedSplitPlacement> {
|
||||||
override val codec: MapCodec<EnhancedSplitPlacement> by lazy {
|
override val codec: MapCodec<EnhancedSplitPlacement> by lazy {
|
||||||
Codec.list(EnhancedPlacementModifier.CODEC).xmap(::EnhancedSplitPlacement, EnhancedSplitPlacement::children).fieldOf("children")
|
RecordCodecBuilder.mapCodec {
|
||||||
|
it.group(
|
||||||
|
Mode.CODEC.fieldOf("mode").forGetter(EnhancedSplitPlacement::mode),
|
||||||
|
Codec.list(EnhancedPlacement.CODEC).fieldOf("children").forGetter(EnhancedSplitPlacement::children),
|
||||||
|
).apply(it, ::EnhancedSplitPlacement)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import net.minecraft.util.valueproviders.UniformFloat
|
|||||||
import net.minecraft.world.level.levelgen.placement.PlacementContext
|
import net.minecraft.world.level.levelgen.placement.PlacementContext
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifierType
|
import net.minecraft.world.level.levelgen.placement.PlacementModifierType
|
||||||
import ru.dbotthepony.mc.otm.core.addAll
|
|
||||||
import ru.dbotthepony.mc.otm.core.math.Vector
|
import ru.dbotthepony.mc.otm.core.math.Vector
|
||||||
import ru.dbotthepony.mc.otm.core.math.angleDifference
|
import ru.dbotthepony.mc.otm.core.math.angleDifference
|
||||||
import ru.dbotthepony.mc.otm.core.math.normalizeAngle
|
import ru.dbotthepony.mc.otm.core.math.normalizeAngle
|
||||||
@ -46,7 +45,7 @@ class WormPlacement(
|
|||||||
val initialAngleXY: FloatProvider = DEFAULT_INITIAL_ANGLE_XY,
|
val initialAngleXY: FloatProvider = DEFAULT_INITIAL_ANGLE_XY,
|
||||||
val maxTravelDown: Int = Int.MAX_VALUE,
|
val maxTravelDown: Int = Int.MAX_VALUE,
|
||||||
val maxTravelUp: Int = Int.MAX_VALUE,
|
val maxTravelUp: Int = Int.MAX_VALUE,
|
||||||
) : PlacementModifier(), EnhancedPlacementModifier {
|
) : PlacementModifier(), EnhancedPlacement {
|
||||||
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, PI)
|
||||||
@ -165,7 +164,7 @@ class WormPlacement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val type: EnhancedPlacementModifier.Type<*>
|
override val type: EnhancedPlacement.Type<*>
|
||||||
get() = Companion
|
get() = Companion
|
||||||
|
|
||||||
override fun getPositions(context: PlacementContext, random: RandomSource, center: BlockPos): Stream<BlockPos> {
|
override fun getPositions(context: PlacementContext, random: RandomSource, center: BlockPos): Stream<BlockPos> {
|
||||||
@ -176,7 +175,7 @@ class WormPlacement(
|
|||||||
return MPlacementModifiers.WORM_PLACEMENT
|
return MPlacementModifiers.WORM_PLACEMENT
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : EnhancedPlacementModifier.Type<WormPlacement> {
|
companion object : EnhancedPlacement.Type<WormPlacement> {
|
||||||
private fun increment(value: Float): Float {
|
private fun increment(value: Float): Float {
|
||||||
var i = 1f
|
var i = 1f
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user