Phase 7: practice-boss and guardian-reset commands; steadier spawn survey
Adrian (2026-11-02): a way to force-spawn the bosses. - /cobblesurvival boss <zone|end>: a practice copy next to you (same species, level, size, attacks; no drops, not the guardian's defeat). - /cobblesurvival guardians reset <zone>: despawns the zone's guardian and clears its defeat, so it appears again when someone comes near (Guardians.reset, formerly resetForTest). - Self-test practice_bosses_spawn. - spawn_survey stands on the ground below trees: on a mangrove's roots it found no natural ground and nothing could spawn at the Mire sample. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cd232bdf6a
commit
c451c58483
6 files changed
+116
-6
No files matched your search
@@ -32,8 +32,21 @@ object BossTests {
|
||||
SelfTestCase("boss_attacks_land_and_stop_with_the_battle", 400, ::landAndStop),
|
||||
SelfTestCase("boss_arena_leaving_loses", 400, ::arena),
|
||||
SelfTestCase("end_boss_replaces_the_dragon", 200, ::endBoss),
|
||||
SelfTestCase("practice_bosses_spawn", 20, ::practice),
|
||||
)
|
||||
|
||||
/** `/cobblesurvival boss <zone|end>`: a copy that fights like the real boss, for every guardian and the End. */
|
||||
private fun practice(s: Scenario) {
|
||||
for (which in Guardians.definitions.keys + "end") {
|
||||
val entity = dev.cobblesurvival.boss.BossCommands.spawnPractice(s.level, s.at(7.5, 1.0, 7.5), which)
|
||||
?: throw GameTestAssertException("no practice boss for $which")
|
||||
s.check(BossFights.defOf(entity) != null && entity.pokemon.isUncatchable()) { "the practice $which is no uncatchable boss" }
|
||||
s.check(entity.pokemon.persistentData.getString(Guardians.TAG).isEmpty()) { "the practice $which counts as the real guardian" }
|
||||
entity.discard()
|
||||
}
|
||||
s.helper.succeed()
|
||||
}
|
||||
|
||||
private fun implemented(species: String) = PokemonSpecies.getByName(species)?.implemented == true
|
||||
|
||||
private fun coverage(s: Scenario) {
|
||||
|
||||
@@ -26,8 +26,8 @@ object GuardianTests {
|
||||
val definition = Guardians.definitions[ZONE] ?: throw GameTestAssertException("no guardian defined for $ZONE")
|
||||
val sample = Zones.samples[ZONE] ?: throw GameTestAssertException("no sample point for $ZONE")
|
||||
val level = s.level
|
||||
Guardians.resetForTest(level, ZONE)
|
||||
s.afterTest { Guardians.resetForTest(level, ZONE) }
|
||||
Guardians.reset(level, ZONE)
|
||||
s.afterTest { Guardians.reset(level, ZONE) }
|
||||
|
||||
val player = s.player()
|
||||
s.give(player, s.pokemon("mewtwo", 100, "earthquake")) // a spread move needs no target
|
||||
|
||||
@@ -108,13 +108,29 @@ object ZoneTests {
|
||||
}.thenSucceed()
|
||||
}
|
||||
|
||||
/**
|
||||
* The ground at [x] [z], below any tree: standing on a mangrove's roots or logs, the survey once found no natural
|
||||
* ground around it, so nothing could spawn (2026-11-02).
|
||||
*/
|
||||
private fun ground(level: net.minecraft.server.level.ServerLevel, x: Int, z: Int): BlockPos {
|
||||
var y = level.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, x, z)
|
||||
while (y > level.minBuildHeight) {
|
||||
val below = level.getBlockState(BlockPos(x, y - 1, z))
|
||||
val tree = below.`is`(net.minecraft.tags.BlockTags.LOGS) || below.`is`(net.minecraft.tags.BlockTags.LEAVES) ||
|
||||
below.`is`(net.minecraft.world.level.block.Blocks.MANGROVE_ROOTS)
|
||||
if (below.blocksMotion() && !tree) break
|
||||
y--
|
||||
}
|
||||
return BlockPos(x, y, z)
|
||||
}
|
||||
|
||||
/** What can spawn around the sample right now, and how many spawnable positions Cobblemon found there. */
|
||||
private fun survey(s: Scenario, player: ServerPlayer, zoneId: String, sample: ZoneSample): Pair<Set<SpawnDetail>, Int> {
|
||||
val level = s.level
|
||||
// Generate the chunks around the sample, then find where to stand.
|
||||
for (dx in -2..2) for (dz in -2..2) level.getChunk((sample.x shr 4) + dx, (sample.z shr 4) + dz)
|
||||
val stand = if (sample.y == null) {
|
||||
BlockPos(sample.x, level.getHeight(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, sample.x, sample.z), sample.z)
|
||||
ground(level, sample.x, sample.z)
|
||||
} else {
|
||||
caveFloor(s, zoneId, sample, sample.y)
|
||||
?: throw GameTestAssertException("no open $zoneId cave near ${sample.x} ${sample.y} ${sample.z}")
|
||||
|
||||
Reference in new issue
Block a user