feat(combat): Die carries the killing attack's smash direction

Live filled Die's direction_relative_angle_xz, _angle_y and _force on
11,606 of 19,428 deaths. The values are the dir_angle_xz, dir_angle_y
(degrees, sent as radians) and dir_force parameters of the BasicAttack
that dealt the killing blow: per killing skill the triple is constant
(skill 1210: -25 degrees, force 12 on 540 of 549 kills; skill 10:
force 7 on 1,830 of 1,835), and deaths with no killer (5,948) never
have one. BasicAttack is the only behavior with these parameters apart
from one Grab. The client passes them to PerformSmashableDeath, which
throws the smashable's pieces that way; DLU sent 0.

The radians are rounded the way live did (-25 is 0xbedf66f3, 20 is
0x3eb2b8c3). Not covered: use_caster_velocity (one behavior, racing).

Check: smash crates and enemies with different weapons; the pieces fly
off to the side/up per weapon instead of straight out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 02:39:56 -05:00
parent 65acc19978
commit f7bb178c2d
5 changed files with 91 additions and 8 deletions

View File

@@ -548,7 +548,12 @@ void DestroyableComponent::Repair(const uint32_t armor) {
}
void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32_t skillID, bool echo) {
float DeathDirection::DegreesToRadians(const float degrees) {
constexpr double PI_AS_FLOAT = static_cast<double>(3.14159265358979323846f);
return static_cast<float>(static_cast<double>(degrees) * PI_AS_FLOAT / 180.0);
}
void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32_t skillID, bool echo, const DeathDirection& deathDirection) {
if (GetHealth() <= 0) {
return;
}
@@ -649,7 +654,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
return;
}
Smash(source, eKillType::VIOLENT, u"", skillID);
Smash(source, eKillType::VIOLENT, u"", skillID, deathDirection);
}
void DestroyableComponent::Subscribe(LWOOBJID scriptObjId, CppScripts::Script* scriptToAdd) {
@@ -675,7 +680,7 @@ void DestroyableComponent::NotifySubscribers(Entity* attacker, uint32_t damage)
}
}
void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType, const std::u16string& deathType, uint32_t skillID) {
void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType, const std::u16string& deathType, uint32_t skillID, const DeathDirection& deathDirection) {
if (m_IsDead) return;
//check if hardcore mode is enabled
@@ -751,6 +756,9 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
die.bClientDeath = false;
die.bSpawnLoot = true;
die.deathType = deathType;
die.directionRelative_AngleXZ = deathDirection.angleXZ;
die.directionRelative_AngleY = deathDirection.angleY;
die.directionRelative_Force = deathDirection.force;
die.killType = killType;
die.killerID = source;
die.lootOwnerID = source;