diff --git a/damage_event.gd b/damage_event.gd new file mode 100644 index 0000000..c731717 --- /dev/null +++ b/damage_event.gd @@ -0,0 +1,43 @@ +class_name DamageEvent +extends RefCounted +## The one typed payload for every hit in the game โ€” a bull goring a matador, a bear slam popping +## the bull, a thrown spear landing. It replaces the scattered, stringly Object.call(&"take_sword_hit", +## "gored") paths: an emitter (a Hitbox) fills one of these and hands it to the target's +## receive_damage(event). One shape to read, log and type-check, instead of four call conventions. +## +## It serves both victim models the game already has: the bull, which dies on one clean hit +## (lethal + cause + hit_position), and an enemy, which is launched/ragdolled by an impulse +## (knockback_dir ยท knockback_strength + knock_up). A given hit just leaves the fields it doesn't +## use at their defaults. + +enum Cause { GENERIC, GORED, MAULED, THROWN, SLAMMED, KICKED, DASHED } + +## Who dealt the hit โ€” for attribution and for ignoring self-overlap. May be null. +var source: Node = null +## What kind of hit; drives the victim's reaction (blood/vignette/FX) and any future resistances. +var cause: Cause = Cause.GENERIC +## World contact point, so impact FX spawn where the hit actually landed. +var hit_position: Vector3 = Vector3.ZERO +## Planar push direction (need not be normalised). Vector3.ZERO = no horizontal knockback. +var knockback_dir: Vector3 = Vector3.ZERO +## Impulse magnitude behind knockback_dir โ€” the enemy launch/ragdoll strength. +var knockback_strength: float = 0.0 +## Upward launch in m/s (an overhead smash pop, a leap-slam outer ring). 0 = a grounded hit. +var knock_up: float = 0.0 +## One clean hit ends the run for the bull; most enemy-dealt hits are lethal to it. Enemies that +## are merely launched (not killed) by the bull's abilities set this false. +var lethal: bool = true + + +static func make(kind: Cause, at: Vector3, src: Node = null) -> DamageEvent: + var e := DamageEvent.new() + e.cause = kind + e.hit_position = at + e.source = src + return e + + +## Lower-case name of the cause, for logs and for the bull's existing cause-keyed reactions +## ("gored" / "mauled" / "thrown") during the migration off string causes. +func cause_name() -> String: + return String(Cause.keys()[cause]).to_lower()