Complete the DamageEvent migration: one deal() entry point for every attacker
The bull's Hitbox already routed through DamageEvent, but the spear, the bear's maul, and the matador's reach-gore still did raw Object.call(&"take_sword_hit", ...) — the exact scattered string paths DamageEvent was meant to retire. Add a single static DamageEvent.deal(target, cause, at, source, knock_up) that builds the typed event and hands it to receive_damage(), falling back to the legacy string call for any not-yet-migrated victim, and route all four attackers (Hitbox included) through it. The damage_pipeline characterization test proves the bull's outcomes are unchanged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pq1VX2o1ZfiNRdCjD294wf
This commit is contained in:
@@ -630,7 +630,7 @@ func _try_hit(reach: float) -> bool:
|
|||||||
return false
|
return false
|
||||||
if _facing().dot(to_bull / dist) < cos(deg_to_rad(DP.f("bear_hit_arc"))):
|
if _facing().dot(to_bull / dist) < cos(deg_to_rad(DP.f("bear_hit_arc"))):
|
||||||
return false
|
return false
|
||||||
_bull.call(&"take_sword_hit", "mauled")
|
DamageEvent.deal(_bull, DamageEvent.Cause.MAULED, _bull.global_position, self)
|
||||||
_shake(0.55)
|
_shake(0.55)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,24 @@ static func make(kind: Cause, at: Vector3, src: Node = null) -> DamageEvent:
|
|||||||
return e
|
return e
|
||||||
|
|
||||||
|
|
||||||
|
## The single entry point every attacker uses to wound a target: build the typed event and hand it
|
||||||
|
## to receive_damage(). Falls back to the legacy string call for any target not yet migrated, so a
|
||||||
|
## caller never has to branch on which contract the victim speaks. `knock_up_v` is the already-shaped
|
||||||
|
## pop (0 = grounded); callers that scale it by distance compute it before calling.
|
||||||
|
static func deal(target: Node, kind: Cause, at: Vector3, src: Node = null, knock_up_v: float = 0.0) -> void:
|
||||||
|
if target == null:
|
||||||
|
return
|
||||||
|
if target.has_method(&"receive_damage"):
|
||||||
|
var event := make(kind, at, src)
|
||||||
|
event.knock_up = knock_up_v
|
||||||
|
target.call(&"receive_damage", event)
|
||||||
|
return
|
||||||
|
if target.has_method(&"take_sword_hit"):
|
||||||
|
target.call(&"take_sword_hit", make(kind, at, src).cause_name(), at)
|
||||||
|
if knock_up_v > 0.0 and target.has_method(&"apply_knock_up"):
|
||||||
|
target.call(&"apply_knock_up", knock_up_v)
|
||||||
|
|
||||||
|
|
||||||
## Lower-case name of the cause, for logs and for the bull's existing cause-keyed reactions
|
## 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.
|
## ("gored" / "mauled" / "thrown") during the migration off string causes.
|
||||||
func cause_name() -> String:
|
func cause_name() -> String:
|
||||||
|
|||||||
@@ -80,17 +80,8 @@ func _apply_hit(body: Node3D) -> void:
|
|||||||
return
|
return
|
||||||
_hit_this_swing[body] = true
|
_hit_this_swing[body] = true
|
||||||
_did_hit = true
|
_did_hit = true
|
||||||
if body.has_method(&"receive_damage"):
|
var ku := _knock_up_for(body) if knock_up > 0.0 else 0.0
|
||||||
var event := DamageEvent.make(DamageEvent.cause_from(damage_cause), body.global_position, self)
|
DamageEvent.deal(body, DamageEvent.cause_from(damage_cause), body.global_position, self, ku)
|
||||||
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.
|
# Scale the pop by how far the body is from this hitbox's origin (planar). See the export docs.
|
||||||
|
|||||||
+1
-1
@@ -955,7 +955,7 @@ func _try_melee_hit(reach: float) -> void:
|
|||||||
if facing.dot(to_bull / dist) < cos(deg_to_rad(DP.f("mat_stab_arc"))):
|
if facing.dot(to_bull / dist) < cos(deg_to_rad(DP.f("mat_stab_arc"))):
|
||||||
return
|
return
|
||||||
_blade_hit_cd = DP.f("mat_stab_cooldown")
|
_blade_hit_cd = DP.f("mat_stab_cooldown")
|
||||||
_bull.call(&"take_sword_hit", "gored")
|
DamageEvent.deal(_bull, DamageEvent.Cause.GORED, _bull.global_position, self)
|
||||||
|
|
||||||
|
|
||||||
func _enter_ragdoll(hit_dir: Vector3, bull_speed: float, up_boost: float = 0.0) -> void:
|
func _enter_ragdoll(hit_dir: Vector3, bull_speed: float, up_boost: float = 0.0) -> void:
|
||||||
|
|||||||
+1
-1
@@ -223,7 +223,7 @@ func _embed(other: Object, contact: Vector3, flight: Vector3) -> void:
|
|||||||
var pose := Transform3D(_aim_basis(f), contact + f * (_EMBED_DEPTH - _TIP_Z))
|
var pose := Transform3D(_aim_basis(f), contact + f * (_EMBED_DEPTH - _TIP_Z))
|
||||||
var bull := other as Node
|
var bull := other as Node
|
||||||
if bull != null and bull.is_in_group(&"player"):
|
if bull != null and bull.is_in_group(&"player"):
|
||||||
bull.call(&"take_sword_hit", "thrown", contact)
|
DamageEvent.deal(bull, DamageEvent.Cause.THROWN, contact, self)
|
||||||
if is_instance_valid(_mesh) and is_instance_valid(bull):
|
if is_instance_valid(_mesh) and is_instance_valid(bull):
|
||||||
_mesh.reparent(_spear_anchor(bull), false)
|
_mesh.reparent(_spear_anchor(bull), false)
|
||||||
_mesh.global_transform = pose
|
_mesh.global_transform = pose
|
||||||
|
|||||||
Reference in New Issue
Block a user