Phase 8 approved (2026-11-09). Adrian's Phase 9 answers: left-out Pokemon rare in fitting zones; legendaries from crafted summons; no public release. - Ore veins more sporadic but bigger: nodes about 40 % rarer, veins about 30 % further apart, each one block larger in radius. 1.5-3x the ore overall; a new island is needed to see it. World check on the regenerated island passes. - The respawn block (Regenerating Ore Veins' regenerator): the aim passes through it unless sneaking (mixin, the pack's first), so ore behind it can be mined; much fainter glass through KubeJS assets. Self-test regenerator_lets_the_aim_through casts a real ray. - 31 lines (67 species) with no matching island biome, or no spawn data (Rotom), get rare homes in fitting zones (world/zones.json -> homeless). Existing spawns and guardians don't change. JEI data and quests regenerated. - surface_nodes_lie_in_the_ground checks the node's centre column: a wider node's edge can lie under a tree or a slope. - Roadmap: every implemented Pokemon obtainable; Iris and Complementary Reimagined as the default shader. Self-tests and the island check pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
57 lines
3.5 KiB
Kotlin
57 lines
3.5 KiB
Kotlin
package dev.cobblesurvival.selftest
|
|
|
|
import dev.cobblesurvival.dev.OreVeins
|
|
import dev.cobblesurvival.ore.OreNodes
|
|
import dev.cobblesurvival.zone.Zones
|
|
import net.minecraft.core.BlockPos
|
|
import net.minecraft.core.Direction
|
|
import net.minecraft.gametest.framework.GameTestAssertException
|
|
import net.minecraft.world.level.ChunkPos
|
|
import net.minecraft.world.level.levelgen.Heightmap
|
|
|
|
/**
|
|
* Ore nodes on the island (Adrian, 2026-10-30): a surface node is a small lump of ore in the ground of its zone with
|
|
* open air above it; a cave node lies on the floor of its cave biome, touching the cave's air, not buried in a wall.
|
|
* Each test places one node on purpose near its zone's sample point and checks it as Regenerating Ore Veins tracks it.
|
|
*/
|
|
object OreNodeTests {
|
|
fun all() = listOf(
|
|
SelfTestCase("surface_nodes_lie_in_the_ground", 20, { s -> nodeTest(s, "button_isle", cave = false) }, islandOnly = true),
|
|
SelfTestCase("cave_nodes_lie_on_the_cave_floor", 20, { s -> nodeTest(s, "deep_dark", cave = true) }, islandOnly = true),
|
|
)
|
|
|
|
private fun nodeTest(s: Scenario, zone: String, cave: Boolean) {
|
|
val level = s.level
|
|
val node = OreNodes.nodes.firstOrNull { it.zone == zone && it.cave == cave }
|
|
?: throw GameTestAssertException("no ${if (cave) "cave" else "surface"} node kind in $zone")
|
|
val sample = Zones.samples[zone] ?: throw GameTestAssertException("no sample point for $zone")
|
|
val home = ChunkPos(BlockPos(sample.x, 0, sample.z))
|
|
// Next to the sample chunk first (the guardian stands on the sample point), then around it.
|
|
val chunks = listOf(ChunkPos(home.x + 2, home.z)) + (-1..1).flatMap { dx -> (-1..1).map { dz -> ChunkPos(home.x + dx, home.z + dz) } }
|
|
val grounds = chunks.asSequence()
|
|
.onEach { level.getChunk(it.x, it.z) }
|
|
.map { OreNodes.fill(level, it, only = node, force = true) }
|
|
.firstOrNull { it.isNotEmpty() }
|
|
?: throw GameTestAssertException("no spot for a ${node.vein} near $zone's sample point")
|
|
|
|
for (ground in grounds) {
|
|
val blocks = BlockPos.betweenClosed(ground.offset(-node.radius - 1, -node.radius - 1, -node.radius - 1),
|
|
ground.offset(node.radius + 1, node.radius + 1, node.radius + 1))
|
|
.map { it.immutable() }
|
|
.filter { OreVeins.veinAt(level, it) == node.vein }
|
|
s.check(blocks.isNotEmpty()) { "the ${node.vein} at ${ground.toShortString()} isn't tracked by Regenerating Ore Veins" }
|
|
val exposed = blocks.any { block -> Direction.entries.any { level.getBlockState(block.relative(it)).isAir } }
|
|
s.check(exposed) { "the ${node.vein} at ${ground.toShortString()} touches no air: it's buried" }
|
|
if (cave) {
|
|
s.check(level.getBiome(ground.above()).`is`(node.biome!!)) { "the ${node.vein} at ${ground.toShortString()} isn't in ${node.biome}" }
|
|
} else {
|
|
// Open ground over the node's centre (leaves don't count): a wide node's edge may lie under a tree or a slope.
|
|
val surface = level.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, ground.x, ground.z)
|
|
s.check(surface <= ground.y + 2) { "the ${node.vein} at ${ground.toShortString()} is under cover (ground at $surface)" }
|
|
s.check(blocks.all { Zones.at(level, it)?.id == zone }) { "the ${node.vein} at ${ground.toShortString()} reaches out of $zone" }
|
|
}
|
|
}
|
|
s.helper.succeed()
|
|
}
|
|
}
|