Capricorn
Unit #077
| HP | PWR | CP | Speed | Range | Tier |
|---|---|---|---|---|---|
| 12 (+6) | 2 | 3 (+2) | Normal | Any | C |
Abilities
Collective Unconscious — 0 AP
i: Collective Unconscious: 0 AP - b: This action's performer performs the last action without q that was resolved this Main Phase (with cost). e: Collective Unconscious cannot be performed.
Engine Implementation
def _capricorn_collective_unconscious(
state: GameState, demon: DemonInstance, targets, choices, rng
) -> GameState:
"""#077 Capricorn — Collective Unconscious
Allied, 0 AP, (ready): This action's performer performs the last action without
Familiar that was resolved this Main Phase (with cost). Status: Collective
Unconscious cannot be performed.
The performer re-executes the last non-familiar action resolved this phase,
paying its full costs (AP + exhaust). "with cost" means the performer must
pay whatever the original action cost.
Status expires end of current main phase.
(ready) = performer must be READIED; does NOT exhaust them (for THIS ability).
The REPLAYED action may exhaust the performer if it has tap_required.
"""
from engine.status_effects import apply_status, get_stat_modifier
# Guard: check if Collective Unconscious is already locked this phase.
# The lock is global — if ANY demon has used it, no one can use it again.
# Check the Capricorn card owner AND the performer for the lock status.
capricorn_card = next(
(d for d in state.demons if d.unit_id == "077" and d.owner == demon.owner), None
)
if capricorn_card and get_stat_modifier(state, capricorn_card, "collective_unconscious_used") > 0:
return state # Already used this phase — no-op
if get_stat_modifier(state, demon, "collective_unconscious_used") > 0:
return state # Already used this phase — no-op
# "Status: Collective Unconscious cannot be performed" — global lock on the
# ability itself (not per-performer). Apply to the Capricorn card on field so
# any Allied performer check sees the lock.
capricorn_on_field = next(
(d for d in state.demons if d.unit_id == "077" and d.owner == demon.owner), None
)
if capricorn_on_field:
state = apply_status(
state, capricorn_on_field, demon, "collective_unconscious_used", 1
)
elif demon.unit_id != "077":
# Capricorn not on field — apply to performer as fallback
state = apply_status(state, demon, demon, "collective_unconscious_used", 1)
# Replay the last resolved action
last = state.last_resolved_action
if last is None:
return state # No action to replay — no-op
replay_handler = last["handler"]
replay_data = last["ability_data"]
replay_targets = last["targets"]
replay_choices = last["choices"]
# "With cost" — the performer pays the replayed action's AP cost
ap_cost_raw = replay_data.get("ap_cost", None)
base_ap_cost = 0
if ap_cost_raw == "X":
base_ap_cost = (replay_choices or {}).get("x", 0)
elif ap_cost_raw is not None:
try:
base_ap_cost = int(ap_cost_raw)
except (TypeError, ValueError):
base_ap_cost = 0
from engine.operations import get_effective_ap_cost
ap_cost = get_effective_ap_cost(state, demon, base_ap_cost)
available_ap = state.players[demon.owner].ap
if ap_cost > available_ap:
return state # Can't afford — no-op
# Deduct AP
new_state = copy.deepcopy(state)
new_state.players[demon.owner].ap = max(0, new_state.players[demon.owner].ap - ap_cost)
# If the replayed action has tap_required, exhaust the performer
if replay_data.get("tap_required", False):
performer_in = next(
(d for d in new_state.demons if d.instance_id == demon.instance_id), None
)
if performer_in:
performer_in.state = DemonState.EXHAUSTED
# Re-locate the performer in new state
performer = next(
(d for d in new_state.demons if d.instance_id == demon.instance_id), None
)
if performer is None:
return new_state
# Re-locate targets in new state (they may have changed)
new_targets = None
if replay_targets:
new_targets = []
for t in replay_targets:
t_in = next(
(d for d in new_state.demons if d.instance_id == t.instance_id), None
)
if t_in:
new_targets.append(t_in)
if not new_targets:
new_targets = None
# Execute the replayed handler with the performer
new_state = replay_handler(new_state, performer, new_targets, replay_choices, rng)
return new_state
register_ability("077", 0, _capricorn_collective_unconscious)
Reminder
(1x actions are restricted to once per Demon, not per action use.)