Guardian boss bars; Phase 7 approved

Adrian, 2026-11-03: guardians get a boss health bar like the Wither's, which
also leads players to them. Every player within 128 blocks of a living
guardian sees a red bar of their own (GuardianBars): name, zone, how many
blocks away, and HP. The End boss keeps the dragon's bar.
guardian_appears_and_returns checks the bar appears and goes once beaten.
Self-tests and the island check pass.

Phase 7 approved ("Then begin with the next phase"); README status updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-11-03 10:26:26 +01:00
1 parent 120c664cb0
commit fe6b8dfe57
7 files changed
+72 -1

No files matched your search

@@ -4,6 +4,7 @@ import com.cobblemon.mod.common.battles.BattleBuilder
import com.cobblemon.mod.common.battles.MoveActionResponse
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.isInBattle
import dev.cobblesurvival.zone.GuardianBars
import dev.cobblesurvival.zone.Guardians
import dev.cobblesurvival.zone.Zones
import net.minecraft.core.registries.BuiltInRegistries
@@ -49,6 +50,12 @@ object GuardianTests {
s.check(pokemon.isUncatchable()) { "the guardian can be caught" }
s.check(abs(pokemon.scaleModifier - definition.scale) < 0.01f) { "the guardian is size ${pokemon.scaleModifier}, not ${definition.scale}" }
s.check(expectedLevel == null || pokemon.level == expectedLevel) { "the guardian is level ${pokemon.level}, not $expectedLevel" }
// Adrian, 2026-11-03: a boss bar like the Wither's, with how far it is, leads the player to it.
GuardianBars.update(level)
val bar = GuardianBars.barFor(ZONE, player) ?: throw GameTestAssertException("no boss bar for the guardian 6 blocks away")
s.check(player in bar.players && bar.progress == 1f && bar.name.string.contains(pokemon.species.name)) {
"the guardian's bar is wrong: '${bar.name.string}' at ${bar.progress}"
}
s.moveTo(player, guardian.x + 3, guardian.y, guardian.z)
}
.thenWaitUntil { s.check(guardian.pokemon.entity === guardian) { "the guardian has not ticked yet" } }
@@ -65,6 +72,7 @@ object GuardianTests {
.thenIdle(100)
.thenExecute {
s.check(Guardians.guardianOf(level, ZONE) == null) { "the guardian came back right away" }
s.check(GuardianBars.barFor(ZONE, player) == null) { "the beaten guardian's bar is still shown" }
Guardians.expireDefeatForTest(level, ZONE)
}
.thenWaitUntil {