Phase 5: soft gates instead of guardian flags, shoulder passives

Adrian (2026-10-31): HMs abilities stay open; the ones that get around
zone hazards get soft gates (materials or a high-level Pokemon, never
flags; gifted Pokemon and materials count the same); party passives from
shoulder Pokemon; Cobblebase skills and the Power Block move to soft
gates too.

- Gates: a zone gate passes at the top of the zone's band or while the
  Pokemon holds the zone's material (or a harder zone's). Cobblebase
  skills check the pastured Pokemon and tell the owner once what it needs.
- Progress record, guardian unlock messages, the Power Block placement
  gate and /cobblesurvival progress removed; the Power Block's recipe
  already needs Jungle redstone.
- HmsGate: switches off gated HMs auras (Flash, Dive, Mist, Rock Climb,
  Magnet Rise, Lucky Chant, Lava Plume) whose Pokemon doesn't pass.
- ShoulderPassives: type-based effects from shoulder Pokemon, hazard
  ones (warmth, frigidness, water breathing, night vision) gated.
- Self-tests for all of it; docs, balance table, Phase 5 checklist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
claudeandClaude Opus 5.5 committed 2026-10-31 13:41:04 +01:00
1 parent 56ffdd9f2e
commit 70cc2cad50
21 files changed
+578 -206

No files matched your search

@@ -2,7 +2,6 @@ package dev.cobblesurvival.progress
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import dev.cobblesurvival.CobbleSurvival
import net.minecraft.world.level.Level
import net.neoforged.fml.ModList
import java.lang.reflect.InvocationHandler
import java.lang.reflect.InvocationTargetException
@@ -11,8 +10,8 @@ import java.lang.reflect.Proxy
/**
* Puts [Gates] in front of Cobblebase's skills, by reflection (Cobblebase is not a compile dependency): every skill
* executor in Cobblebase's `ExecutorRegistry` is replaced by a proxy that runs it only when the pastured Pokémon's owner
* has unlocked that skill. Cobblebase looks the executor up on every tick, so the proxies take effect at once. One
* executor in Cobblebase's `ExecutorRegistry` is replaced by a proxy that runs it only when the pastured Pokémon passes
* that skill's soft gate (level or held material); otherwise its owner is told what it needs. Cobblebase looks the executor up on every tick, so the proxies take effect at once. One
* executor can serve several skills (all the finders), so the check is per skill, not per executor.
*/
object CobblebaseGate {
@@ -68,11 +67,12 @@ object CobblebaseGate {
private class Gate(private val original: Any) : InvocationHandler {
override fun invoke(proxy: Any, method: Method, args: Array<out Any?>?): Any? {
if (method.name == "tick" && args != null && args.size == 5) {
val level = args[0] as Level
val owner = (args[2] as PokemonEntity).pokemon.getOwnerUUID()
val entity = args[2] as PokemonEntity
val skill = skillId.invoke(args[3]) as String
val server = level.server ?: return null
if (!Gates.skillOpen(Progress.of(server), owner, skill)) return null
if (!Gates.skillOpen(entity.pokemon, skill)) {
Gates.noticeIdle(entity, skill)
return null
}
}
return try {
method.invoke(original, *(args ?: emptyArray()))