Route the bull's hits through the typed DamageEvent pipeline

Hitbox now builds a DamageEvent (cause + hit position + shaped knock-up) and
calls the bull's new receive_damage(), instead of two stringly Object.call()s.
receive_damage adapts over the existing pip/knock-up logic so behaviour is
identical -- the characterization test drives both the string and typed paths
and asserts the same outcomes. Wire fx/damage/harness tests into run_tests.sh
+ CLAUDE.md. All hitbox guard tests green (stab, bear hitbox, ram, charge).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmG3mQGVXZUPDVapmdbWZ1
This commit is contained in:
2026-09-05 00:17:04 +03:00
parent 973db7d8b8
commit 70274f1773
6 changed files with 68 additions and 5 deletions
+11 -5
View File
@@ -80,11 +80,17 @@ func _apply_hit(body: Node3D) -> void:
return
_hit_this_swing[body] = true
_did_hit = true
body.call(&"take_sword_hit", damage_cause)
if knock_up > 0.0:
var v := _knock_up_for(body)
if v > 0.0:
body.call(&"apply_knock_up", v)
if body.has_method(&"receive_damage"):
var event := DamageEvent.make(DamageEvent.cause_from(damage_cause), body.global_position, self)
if knock_up > 0.0:
event.knock_up = _knock_up_for(body)
body.call(&"receive_damage", event)
else:
body.call(&"take_sword_hit", damage_cause)
if knock_up > 0.0:
var v := _knock_up_for(body)
if v > 0.0:
body.call(&"apply_knock_up", v)
# Scale the pop by how far the body is from this hitbox's origin (planar). See the export docs.