Files
aetherbound-guild/runtime/p10_3/motion_presenter.gd
T

156 lines
5.1 KiB
GDScript

class_name P103MotionPresenter
extends "res://p10_2/motion_presenter.gd"
const CHANNEL_WIDOW_ID := "EN-R2-11"
const SLUICE_ELDER_ID := "EN-R2-12"
var thread_state := ""
var thread_pair: Array[String] = []
var thread_started := -100.0
var sluice_state := ""
var sluice_started := -100.0
var artifact_state := ""
var artifact_id := ""
var artifact_started := -100.0
var promotion_state := ""
var promotion_actor_id := ""
var promotion_started := -100.0
func reset(initial_order: Array, safe_index: int) -> void:
super.reset(initial_order, safe_index)
thread_state = ""
thread_pair.clear()
thread_started = -100.0
sluice_state = ""
sluice_started = -100.0
artifact_state = ""
artifact_id = ""
artifact_started = -100.0
promotion_state = ""
promotion_actor_id = ""
promotion_started = -100.0
func consume(event: Dictionary, now: float) -> Array:
super.consume(event, now)
var kind := String(event.get("kind", ""))
var source_id := String(event.get("source_id", ""))
var target_id := String(event.get("target_id", ""))
var payload: Dictionary = Dictionary(event.get("payload", {}))
match kind:
"channel_thread_bound":
thread_state = "bound"
thread_pair = _edge_pair()
thread_started = now
_add_visible_enemy(CHANNEL_WIDOW_ID)
_set_enemy_action(CHANNEL_WIDOW_ID, "telegraph", now, ACTION_DURATION)
for actor_id in thread_pair:
_set_actor_action(actor_id, "telegraph", now, ACTION_DURATION)
"channel_thread_adjacent":
thread_state = "adjacent"
thread_started = now
for actor_id in thread_pair:
_set_actor_action(actor_id, "resist", now, TIDE_DURATION)
"channel_healing_backlash":
thread_state = "backlash"
thread_started = now
for actor_id in thread_pair:
_set_actor_action(actor_id, "hit", now, HIT_DURATION)
_add_trauma(now, 0.58)
"safe_index_advanced":
sluice_state = "advanced"
sluice_started = now
current_safe_index = int(payload.get("to", current_safe_index))
_add_visible_enemy(SLUICE_ELDER_ID)
_set_enemy_action(SLUICE_ELDER_ID, "attack", now, ACTION_DURATION)
"wet_stack_applied":
sluice_state = "wet_three"
sluice_started = now
for actor_id in actor_order:
_set_actor_action(String(actor_id), "telegraph", now, ACTION_DURATION)
"wet_threshold_avoided":
sluice_state = "avoided"
sluice_started = now
for actor_id in actor_order:
_set_actor_action(String(actor_id), "resist", now, TIDE_DURATION)
"wet_pull_resolved":
sluice_state = "pulled"
sluice_started = now
for actor_id in actor_order:
_set_actor_action(String(actor_id), "hit", now, HIT_DURATION)
_add_trauma(now, 0.66)
"safe_index_reversed":
sluice_state = "reversed"
sluice_started = now
_set_enemy_action(SLUICE_ELDER_ID, "telegraph", now, ACTION_DURATION)
"narrow_vanguard_guard", "long_company_opening", "paired_duties_partition":
artifact_state = kind
artifact_id = source_id
artifact_started = now
for actor_id in actor_order:
_set_actor_action(String(actor_id), "resist", now, HIT_DURATION)
"fieldmender_patient_repositioned":
promotion_state = "fieldmender"
promotion_actor_id = source_id
promotion_started = now
_set_actor_action(source_id, "heal", now, ACTION_DURATION)
"aftercare_scheduled":
promotion_state = "aftercare_pending"
promotion_actor_id = source_id
promotion_started = now
_set_actor_action(source_id, "heal", now, ACTION_DURATION)
"aftercare_resolved":
promotion_state = "aftercare_resolved"
promotion_started = now
_set_actor_action(promotion_actor_id, "resist", now, HIT_DURATION)
prune(now)
return actor_order.duplicate()
func enemy_visual(enemy_id: String, now: float, reduced_motion: bool, low_power: bool) -> Dictionary:
var visual: Dictionary = super.enemy_visual(enemy_id, now, reduced_motion, low_power)
if enemy_id == CHANNEL_WIDOW_ID and not thread_state.is_empty():
var pulse := sin(clampf((now - thread_started) / 1.0, 0.0, 1.0) * PI)
visual.scale = Vector2.ONE * (1.0 + pulse * (0.03 if reduced_motion else 0.10))
visual.state = "attack" if thread_state == "backlash" else "telegraph"
elif enemy_id == SLUICE_ELDER_ID and not sluice_state.is_empty():
var pulse := sin(clampf((now - sluice_started) / 1.0, 0.0, 1.0) * PI)
visual.rotation = 0.0 if reduced_motion or low_power else pulse * 0.10
visual.state = "attack" if sluice_state == "pulled" else "telegraph"
return visual
func mechanic_effects(now: float) -> Dictionary:
var result: Dictionary = super.mechanic_effects(now)
result["thread"] = {
"state": thread_state,
"pair": thread_pair.duplicate(),
"age": maxf(0.0, now - thread_started),
}
result["sluice"] = {
"state": sluice_state,
"safe_index": current_safe_index,
"age": maxf(0.0, now - sluice_started),
}
result["artifact"] = {
"state": artifact_state,
"artifact_id": artifact_id,
"age": maxf(0.0, now - artifact_started),
}
result["promotion"] = {
"state": promotion_state,
"actor_id": promotion_actor_id,
"age": maxf(0.0, now - promotion_started),
}
return result
func _edge_pair() -> Array[String]:
var result: Array[String] = []
if not actor_order.is_empty():
result.append(String(actor_order[0]))
if actor_order.size() > 1:
result.append(String(actor_order[-1]))
return result