Files
aetherbound-guild/runtime/domain/trait_hooks.gd
T

80 lines
6.4 KiB
GDScript

class_name ABGTraitHooks
extends RefCounted
## M80-B2b trait hook data for all 36 catalog traits.
##
## Every row names one legal hook from `docs/02_GAMEPLAY_AND_BALANCE.md` section
## 17 and a declarative effect derived from the trait's catalog `benefit`. The
## simulation fires the hooks it can already observe and applies the effects
## whose kinds it implements; rows that need later systems (constructs, summons,
## sound tags, region hazards, equipment cooldowns) carry `implemented: false`
## and are skipped by the row scan until their system lands.
const REACH_BONUS := "reach_bonus"
const DAMAGE_BONUS := "damage_bonus"
const GUARD_BONUS := "guard_bonus"
const HEAL_BONUS := "heal_bonus"
const RESOURCE_GAIN := "resource_gain"
const HASTE := "haste"
static func table() -> Dictionary:
return {
"TR-001": {"hook": "before_target", "effect": {"kind": REACH_BONUS, "value": 1, "scope": "next_action"}, "implemented": true},
"TR-002": {"hook": "on_resource_gain", "effect": {"kind": RESOURCE_GAIN, "value": 1, "scope": "after_two_allied_actions"}, "implemented": false},
"TR-003": {"hook": "on_protection_change", "effect": {"kind": GUARD_BONUS, "value": 1, "scope": "single_neighbor"}, "implemented": false},
"TR-004": {"hook": "on_status_apply", "effect": {"kind": DAMAGE_BONUS, "value": 1, "scope": "repeat_target"}, "implemented": false},
"TR-005": {"hook": "on_summon", "effect": {"kind": DAMAGE_BONUS, "value": 0, "scope": "carry_footprint"}, "implemented": false},
"TR-006": {"hook": "on_push", "effect": {"kind": DAMAGE_BONUS, "value": 2, "scope": "counter_after_displacement"}, "implemented": false},
"TR-007": {"hook": "on_cast_complete", "effect": {"kind": DAMAGE_BONUS, "value": 0, "scope": "consumable_repeat"}, "implemented": false},
"TR-008": {"hook": "before_target", "effect": {"kind": DAMAGE_BONUS, "value": 0, "scope": "sound_tag_immunity"}, "implemented": false},
"TR-009": {"hook": "on_pull", "effect": {"kind": DAMAGE_BONUS, "value": 0, "scope": "pull_transfer"}, "implemented": false},
"TR-010": {"hook": "after_heal", "effect": {"kind": HEAL_BONUS, "value": 3, "scope": "lowest_vitality_neighbor"}, "implemented": true},
"TR-011": {"hook": "before_target", "effect": {"kind": GUARD_BONUS, "value": 1, "scope": "preferred_target"}, "implemented": false},
"TR-012": {"hook": "after_collapse", "effect": {"kind": HASTE, "value": 1, "scope": "late_step"}, "implemented": false},
"TR-013": {"hook": "on_resource_gain", "effect": {"kind": RESOURCE_GAIN, "value": 0, "scope": "cooldown_shorten"}, "implemented": false},
"TR-014": {"hook": "on_interrupt", "effect": {"kind": DAMAGE_BONUS, "value": 0, "scope": "interrupt_to_delay"}, "implemented": false},
"TR-015": {"hook": "before_target", "effect": {"kind": REACH_BONUS, "value": 1, "scope": "receive_enable"}, "implemented": false},
"TR-016": {"hook": "on_fallen", "effect": {"kind": RESOURCE_GAIN, "value": 1, "scope": "hindered_enemy_defeat"}, "implemented": false},
"TR-017": {"hook": "before_target", "effect": {"kind": REACH_BONUS, "value": 1, "scope": "first_action"}, "implemented": true},
"TR-018": {"hook": "after_damage", "effect": {"kind": HASTE, "value": 1, "scope": "after_area_damage"}, "implemented": true},
"TR-019": {"hook": "on_advance", "effect": {"kind": DAMAGE_BONUS, "value": 0, "scope": "rear_intruder_mark"}, "implemented": false},
"TR-020": {"hook": "on_cast_complete", "effect": {"kind": DAMAGE_BONUS, "value": 1, "scope": "item_trigger_priority"}, "implemented": false},
"TR-021": {"hook": "on_advance", "effect": {"kind": RESOURCE_GAIN, "value": 1, "scope": "profession_swap"}, "implemented": false},
"TR-022": {"hook": "after_damage", "effect": {"kind": GUARD_BONUS, "value": 2, "scope": "third_hit_same_enemy"}, "implemented": true},
"TR-023": {"hook": "on_advance", "effect": {"kind": HASTE, "value": 1, "scope": "borrowed_cadence"}, "implemented": false},
"TR-024": {"hook": "on_status_expire", "effect": {"kind": RESOURCE_GAIN, "value": 1, "scope": "cleanse_bonus"}, "implemented": false},
"TR-025": {"hook": "after_damage", "effect": {"kind": RESOURCE_GAIN, "value": 1, "scope": "survive_exposed"}, "implemented": true},
"TR-026": {"hook": "before_target", "effect": {"kind": DAMAGE_BONUS, "value": 0, "scope": "pass_summon_footprint"}, "implemented": false},
"TR-027": {"hook": "on_interrupt", "effect": {"kind": DAMAGE_BONUS, "value": 0, "scope": "sound_uninterruptible"}, "implemented": false},
"TR-028": {"hook": "on_status_apply", "effect": {"kind": DAMAGE_BONUS, "value": 0, "scope": "shorter_self_hindrance"}, "implemented": false},
"TR-029": {"hook": "before_target", "effect": {"kind": REACH_BONUS, "value": 1, "scope": "share_through_ally"}, "implemented": false},
"TR-030": {"hook": "on_push", "effect": {"kind": HASTE, "value": 1, "scope": "return_from_rearmost"}, "implemented": false},
"TR-031": {"hook": "on_cast_complete", "effect": {"kind": RESOURCE_GAIN, "value": 1, "scope": "enemy_major_windup"}, "implemented": false},
"TR-032": {"hook": "after_damage", "effect": {"kind": HEAL_BONUS, "value": 3, "scope": "overkill_to_remedy"}, "implemented": false},
"TR-033": {"hook": "on_status_apply", "effect": {"kind": DAMAGE_BONUS, "value": 0, "scope": "two_marks"}, "implemented": false},
"TR-034": {"hook": "on_barrier_break", "effect": {"kind": GUARD_BONUS, "value": 1, "scope": "first_hazard_ignored"}, "implemented": false},
"TR-035": {"hook": "before_target", "effect": {"kind": DAMAGE_BONUS, "value": 1, "scope": "no_armament_alternate"}, "implemented": false},
"TR-036": {"hook": "after_target", "effect": {"kind": HASTE, "value": 1, "scope": "solo_band_reveal"}, "implemented": false},
}
static func for_actor(trait_ids: Array) -> Array[Dictionary]:
var rows: Array[Dictionary] = []
var catalog := table()
for trait_id in trait_ids:
var key := String(trait_id)
if catalog.has(key):
rows.append({"id": key, "hook": String(Dictionary(catalog[key]).get("hook", "")), "effect": Dictionary(Dictionary(catalog[key]).get("effect", {})), "implemented": bool(Dictionary(catalog[key]).get("implemented", false))})
return rows
static func hook_names() -> Array[String]:
return [
"before_target", "after_target", "before_cast", "on_cast_complete", "on_interrupt",
"before_damage", "after_damage", "on_critical", "before_heal", "after_heal",
"on_barrier_break", "on_status_apply", "on_status_expire",
"on_advance", "on_withdraw", "on_push", "on_pull", "on_protection_change",
"on_resource_gain", "on_signature", "on_summon", "on_fallen", "after_collapse",
]