diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/block/TypeGemClusterBlock.kt b/common/src/main/kotlin/com/cobblemon/mod/common/block/TypeGemClusterBlock.kt index 84b32ffe08..3fbe7f925c 100644 --- a/common/src/main/kotlin/com/cobblemon/mod/common/block/TypeGemClusterBlock.kt +++ b/common/src/main/kotlin/com/cobblemon/mod/common/block/TypeGemClusterBlock.kt @@ -34,7 +34,6 @@ import net.minecraft.world.level.block.Mirror import net.minecraft.world.level.block.Rotation import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.StateDefinition -import net.minecraft.world.level.block.state.properties.BooleanProperty import net.minecraft.world.level.block.state.properties.DirectionProperty import net.minecraft.world.level.block.state.properties.EnumProperty import net.minecraft.world.level.block.state.properties.IntegerProperty @@ -73,9 +72,9 @@ class TypeGemClusterBlock( } enum class GrowthType(private val label: String, val chance: Float): StringRepresentable { - FULL("full", 0.3f), - STUNTED("stunted", 0.3f), - DECORATION("none", 0.3f); + FULL("full", 0.5f), + STUNTED("stunted", 0.25f), + DECORATION("none", 0.25f); override fun getSerializedName(): String = label } diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/block/TypeGemCoreBlock.kt b/common/src/main/kotlin/com/cobblemon/mod/common/block/TypeGemCoreBlock.kt index a57dde21f4..26f7a282bd 100644 --- a/common/src/main/kotlin/com/cobblemon/mod/common/block/TypeGemCoreBlock.kt +++ b/common/src/main/kotlin/com/cobblemon/mod/common/block/TypeGemCoreBlock.kt @@ -54,29 +54,6 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) { ResourceLocation.parse("cobblemon:fairy_gem_block") to CobblemonBlocks.TYPE_GEM_CLUSTER_FAIRY ) } - /* - fun setStuntState(level: LevelAccessor, gemBlocks: List>, stunted: Boolean) { - for ((_, gemPos) in gemBlocks) { - for (dir in Direction.entries) { - val neighborPos = gemPos.relative(dir) - val neighborState = level.getBlockState(neighborPos) - - if (neighborState.block is TypeGemClusterBlock) { - if (neighborState.hasProperty(STUNTED) && neighborState.getValue(STUNTED) != stunted) { - - var updatedState = neighborState.setValue(STUNTED, stunted) - - if (updatedState.hasProperty(SHOULD_GROW)) { - updatedState = updatedState.setValue(SHOULD_GROW, !stunted) - } - - level.setBlock(neighborPos, updatedState, 3) - } - } - } - } - } - */ fun getConnectedGemBlocks(level: BlockGetter, pos: BlockPos): List> { val connectedGems = mutableListOf>() @@ -114,13 +91,6 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) { ?.setValue(GROWTH_TYPE, randomGrowthType) ?: return -// // if min growth hasnt been hit, force more growth -// val size = getConnectedGemBlocks(level, pos).size -// if (size < MIN_GROWTH && randomGrowthType != GrowthType.FULL) { -// println("Forced extra growth at size $size") -// newState.setValue(GROWTH_TYPE, GrowthType.FULL) -// } - if (faceState.`is`(Blocks.AIR)) { level.setBlock(pos.relative(it), newState, 3) } @@ -171,13 +141,11 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) { } override fun randomTick(state: BlockState, level: ServerLevel, pos: BlockPos, random: RandomSource) { + // should we tick at all? + if (random.nextFloat() >= Cobblemon.config.typeGemTickChance) { + return + } val gemCount = getConnectedGemBlocks(level, pos).size -// if (gemCount > Cobblemon.config.typeGemMaxConnected) { -// getConnectedGemBlocks(level, pos).forEach { -// if(!it.first.`is`(CobblemonBlocks.TYPE_GEM_CORE)) attachDecorativeClusters(level, it.second, random) -// } -// return -// } // if growth has stopped fully but min growth hasn't been reached, randomly set a stopped bud to GROWTH_TYPE full val clusters = getConnectedClusters(level, pos) @@ -194,19 +162,19 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) { } - expand(state, level, pos, random) + expand(level, pos, random) } - fun expand(state: BlockState, level: LevelAccessor, pos: BlockPos, random: RandomSource) { + fun expand(level: LevelAccessor, pos: BlockPos, random: RandomSource) { getConnectedGemBlocks(level, pos).forEach { val state = it.first val pos = it.second addClustersToBlock(state, pos, level, random) - growClusters(state, pos, level, random) + growClusters(pos, level, random) } } - private fun growClusters(state: BlockState, pos: BlockPos, level: LevelAccessor, random: RandomSource) { + private fun growClusters(pos: BlockPos, level: LevelAccessor, random: RandomSource) { Direction.entries.forEach { direction -> val relativePos = pos.relative(direction) val relativeState = level.getBlockState(relativePos) @@ -267,115 +235,4 @@ class TypeGemCoreBlock(properties: Properties) : Block(properties) { } } } - /* - fun forceGrow(level: WorldGenLevel, pos: BlockPos, random: RandomSource, percentage: Float) { - val desiredLength = MAX_CONNECTED_GEMS * percentage - - repeat(MAX_FORCE_GROW_ATTEMPTS) { - val (grown, clusterSize) = grow(level, pos, random, true) - if (!grown || clusterSize >= desiredLength) return - } - - Cobblemon.LOGGER.warn( - "Forced type gem growth at {} stopped after {} attempts without reaching its target size; keeping the partial formation.", - pos, - MAX_FORCE_GROW_ATTEMPTS - ) - */ - - /* - private fun grow( - level: WorldGenLevel, - pos: BlockPos, - random: RandomSource, - forced: Boolean = false - ): Pair { - val connectedGems = getConnectedGemBlocks(level, pos) // maybe we can store this and access it for better performance? check for changes in list rather than checking each time grow is called? idk - val gemCount = connectedGems.size - val overLimit = gemCount >= MAX_CONNECTED_GEMS - - if (overLimit) { - // if there is no open air pockets to grow any new clusters then exit early - if (!hasBreathingRoom(level, connectedGems)) { - return Pair(false, gemCount) - } - // max type gem block count met, tell clusters to grow but not turn into blocks - setStuntState(level, connectedGems, true) - //return Pair(false, gemCount) - } else { - // make sure connected clusters know they can grow and turn into blocks - setStuntState(level, connectedGems, false) - } - - val javaRandom = java.util.Random(random.nextLong()) - - for ((gemState, gemPos) in connectedGems.shuffled(javaRandom)) { - val registryKey = BuiltInRegistries.BLOCK.getKey(gemState.block) - val clusterBlock = BLOCK_TO_CLUSTER[registryKey] ?: continue // If there is no block to grow, skip the block - - for (dir in Direction.entries.shuffled(javaRandom)) { - val targetPos = gemPos.relative(dir) - val targetState = level.getBlockState(targetPos) - - if (!targetState.isAir) continue - if (!isPositionValidForGrowth(level, targetPos)) continue - - // Place gem cluster - val placeState = clusterBlock.defaultBlockState() - .setValue(DirectionalBlock.FACING, dir) - .setValue(TypeGemClusterBlock.STAGE, 0) - .setValue(SHOULD_GROW, true) - - level.setBlock(targetPos, placeState, UPDATE_ALL) - - // During world gen, the region silently discards writes into neighboring chunks that are already fully generated. - // Through ImposterProtoChunk with writes set to disabled. Checks if the block is still air after the write and skips if so as it can't be filled. - // Preventing infinite loops. - if (!level.getBlockState(targetPos).`is`(clusterBlock)) continue - - if (forced) { - forceAdvanceClusterGrowth(level, targetPos, random) - } - - val updatedGemCount = if (forced) getConnectedGemBlocks(level, pos).size else connectedGems.size - return Pair(true, updatedGemCount) - } - } - - // println("[TypeGemCoreBlock] No valid spot found for gem placement.") - return Pair(false, connectedGems.size) - } - - private fun forceAdvanceClusterGrowth(level: WorldGenLevel, clusterPos: BlockPos, random: RandomSource) { - repeat(5) { - val clusterState = level.getBlockState(clusterPos) - val clusterBlock = clusterState.block as? TypeGemClusterBlock ?: return - clusterBlock.advanceGrowth(clusterState, level, clusterPos, random) - } - } - - private fun hasBreathingRoom(level: WorldGenLevel, gems: List>): Boolean { - for ((_, gemPos) in gems) { - for (dir in Direction.entries) { - if (level.getBlockState(gemPos.relative(dir)).isAir) { - return true - } - } - } - return false - } - - private fun isPositionValidForGrowth(level: WorldGenLevel, pos: BlockPos): Boolean { - return Direction.entries.none { dir -> - val nearby = pos.relative(dir) - isGem(level.getBlockState(nearby)) && - pos.distManhattan(nearby) < MIN_DISTANCE_BETWEEN_GEMS - } - } - - private fun isGem(state: BlockState): Boolean { - return state.`is`(CobblemonBlockTags.TYPE_GEM_BLOCKS) - } - - */ diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/config/CobblemonConfig.kt b/common/src/main/kotlin/com/cobblemon/mod/common/config/CobblemonConfig.kt index 8d7ea6ba79..8086a7bea5 100644 --- a/common/src/main/kotlin/com/cobblemon/mod/common/config/CobblemonConfig.kt +++ b/common/src/main/kotlin/com/cobblemon/mod/common/config/CobblemonConfig.kt @@ -399,11 +399,14 @@ class CobblemonConfig { var typeGemMinGrowth = 5 @CobblemonConfigField(Category.World, lang = "type_gem_growth_chance", SERVER) - var typeGemGrowthChance = 0.5f + var typeGemGrowthChance = 0.1f @CobblemonConfigField(Category.World, lang = "type_gem_initial_expansion_cycles", SERVER) var typeGemInitialExpansionCycles = 20 + @CobblemonConfigField(Category.World, lang = "type_gem_tick_chance", SERVER) + var typeGemTickChance = 0.1f + fun clone(): CobblemonConfig { val newConfig = CobblemonConfig() CobblemonConfig::class.memberProperties.forEach { property -> diff --git a/common/src/main/kotlin/com/cobblemon/mod/common/world/feature/TypeGemFeature.kt b/common/src/main/kotlin/com/cobblemon/mod/common/world/feature/TypeGemFeature.kt index 09d46c2e50..00787f4115 100644 --- a/common/src/main/kotlin/com/cobblemon/mod/common/world/feature/TypeGemFeature.kt +++ b/common/src/main/kotlin/com/cobblemon/mod/common/world/feature/TypeGemFeature.kt @@ -53,7 +53,7 @@ class TypeGemFeature : Feature(BlockStateConfiguration. // Trigger forced growth with clusters val coreBlock = coreState.block as TypeGemCoreBlock repeat(Cobblemon.config.typeGemInitialExpansionCycles) { - coreBlock.expand(coreState, worldGenLevel, origin, random) + coreBlock.expand(worldGenLevel, origin, random) } // println("[TypeGemFeature] Placed ${gemId.path} at $chosenPos")