Skip to main content

Sharur

Unit #068

HPPWRCPSpeedRangeTier
15 (+9)4 (+2)4 (+3)SlowDistantC

Abilities

Passive

After Sharur resolves an action targeting Any Other Demon(s), move the targeted Demon(s) 1 Lane Away From Sharur.
Engine Implementation
def _sharur_post_action_push(
state: GameState, event: GameEvent, demon: DemonInstance, depth: int
):
"""#068 Sharur idx=0 — Field Passive: Post-Action Push.

After Sharur resolves an action targeting Any Other Demon(s), move the
targeted Demon(s) 1 Lane Away From Sharur.

Fires on ABILITY_USED. Checks event.source is this Sharur instance.
Determines push direction based on Sharur's lane vs each target's lane.
Clamps lane to [0, 2]. Skips fatally_wounded targets.
"""
from engine.constants import LANE_COUNT

# Only fire if this Sharur is the ability user
if event.source is None or event.source.instance_id != demon.instance_id:
return None

# Re-fetch Sharur from current state
sharur_current = next(
(d for d in state.demons if d.instance_id == demon.instance_id), None
)
if sharur_current is None or sharur_current.fatally_wounded:
return None

# The event.target holds the triggered target (single target); for multi-target
# abilities, the engine may fire ABILITY_USED once per target or with a list.
# We handle event.target as a single target here (standard engine behavior).
if event.target is None:
return None
if event.target.instance_id == demon.instance_id:
return None # Cannot push Sharur itself

target_current = next(
(d for d in state.demons if d.instance_id == event.target.instance_id), None
)
if target_current is None or target_current.fatally_wounded:
return None # Target gone or dying

# Determine push direction: away from Sharur
if target_current.lane > sharur_current.lane:
new_lane = min(target_current.lane + 1, LANE_COUNT - 1)
elif target_current.lane < sharur_current.lane:
new_lane = max(target_current.lane - 1, 0)
else:
# Same lane — no clear push direction; do not push
return None

if new_lane == target_current.lane:
return None # Already at boundary — no movement

import copy as _copy
new_state = _copy.deepcopy(state)
t = next(d for d in new_state.demons if d.instance_id == target_current.instance_id)
t.lane = new_lane
return new_state

register_trigger("068", 0, _sharur_post_action_push)

Heavy Impact — 1 AP

g: Heavy Impact: 1 AP - a, 1x: Deal 2 damage to Target Local Demon. e: Sharur's next action ignores a and b costs.
Engine Implementation
def _sharur_heavy_impact(
state: GameState, demon: DemonInstance, targets, choices, rng
) -> GameState:
"""#068 Sharur — Heavy Impact
Quick, 1 AP, (exhaust), 1x: Deal 2 damage to Target Local Demon.
Status: Sharur's next action ignores (exhaust) and (ready) costs.
Status expires end of current main phase.

Quick timing, (exhaust) — exhausts Sharur on use.
Deals 2 damage reduced by DEF (deal_damage, NOT fixed).
After damage, Sharur gets "ignore_exhaust" and "ignore_ready" status.

Targets: [target_local_demon]
"""
target = targets[0]
state = deal_damage(state, demon, target, 2)
sharur_in_new = next(
(d for d in state.demons if d.instance_id == demon.instance_id), None
)
if sharur_in_new is not None:
state = apply_status(state, sharur_in_new, sharur_in_new, "ignore_exhaust", 1)
state = apply_status(state, sharur_in_new, sharur_in_new, "ignore_ready", 1)
return state

register_ability("068", 1, _sharur_heavy_impact)
Sharur