Destroyable: Fix animated deaths (#1227)

Fixes #1222

addresses an issue where the death behavior of a destructible component was not being respected and enemies with destroyable components that had special death animations were not able to play the animation on death.  This pr adds in the hardcoded constant the client uses for the same metric of 12 seconds.

Tested that claiming Nimbus Rock and completing the property guards mission allows him to vacuum away and then network the destruction packet 12 seconds later.
This commit is contained in:
David Markowitz 2023-10-18 07:17:57 -07:00 committed by GitHub
parent 73e70badb7
commit ba91058736
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 2 deletions

View File

@ -373,6 +373,7 @@ void Entity::Initialize() {
comp->SetMaxHealth(destCompData[0].life); comp->SetMaxHealth(destCompData[0].life);
comp->SetMaxImagination(destCompData[0].imagination); comp->SetMaxImagination(destCompData[0].imagination);
comp->SetMaxArmor(destCompData[0].armor); comp->SetMaxArmor(destCompData[0].armor);
comp->SetDeathBehavior(destCompData[0].death_behavior);
comp->SetIsSmashable(destCompData[0].isSmashable); comp->SetIsSmashable(destCompData[0].isSmashable);
@ -1561,7 +1562,17 @@ void Entity::Kill(Entity* murderer) {
} }
if (!IsPlayer()) { if (!IsPlayer()) {
Game::entityManager->DestroyEntity(this); auto* destroyableComponent = GetComponent<DestroyableComponent>();
bool waitForDeathAnimation = false;
if (destroyableComponent) {
waitForDeathAnimation = destroyableComponent->GetDeathBehavior() == 0;
}
// Live waited a hard coded 12 seconds for death animations of type 0 before networking destruction!
constexpr float DelayDeathTime = 12.0f;
if (waitForDeathAnimation) AddCallbackTimer(DelayDeathTime, [this]() { Game::entityManager->DestroyEntity(this); });
else Game::entityManager->DestroyEntity(this);
} }
const auto& grpNameQBShowBricks = GetVar<std::string>(u"grpNameQBShowBricks"); const auto& grpNameQBShowBricks = GetVar<std::string>(u"grpNameQBShowBricks");

View File

@ -72,6 +72,7 @@ DestroyableComponent::DestroyableComponent(Entity* parent) : Component(parent) {
m_ImmuneToImaginationLossCount = 0; m_ImmuneToImaginationLossCount = 0;
m_ImmuneToQuickbuildInterruptCount = 0; m_ImmuneToQuickbuildInterruptCount = 0;
m_ImmuneToPullToPointCount = 0; m_ImmuneToPullToPointCount = 0;
m_DeathBehavior = -1;
} }
DestroyableComponent::~DestroyableComponent() { DestroyableComponent::~DestroyableComponent() {

View File

@ -416,6 +416,9 @@ public:
const bool GetImmuneToQuickbuildInterrupt() {return m_ImmuneToQuickbuildInterruptCount > 0;}; const bool GetImmuneToQuickbuildInterrupt() {return m_ImmuneToQuickbuildInterruptCount > 0;};
const bool GetImmuneToPullToPoint() {return m_ImmuneToPullToPointCount > 0;}; const bool GetImmuneToPullToPoint() {return m_ImmuneToPullToPointCount > 0;};
int32_t GetDeathBehavior() const { return m_DeathBehavior; }
void SetDeathBehavior(int32_t value) { m_DeathBehavior = value; }
/** /**
* Utility to reset all stats to the default stats based on items and completed missions * Utility to reset all stats to the default stats based on items and completed missions
*/ */
@ -597,6 +600,11 @@ private:
uint32_t m_ImmuneToImaginationLossCount; uint32_t m_ImmuneToImaginationLossCount;
uint32_t m_ImmuneToQuickbuildInterruptCount; uint32_t m_ImmuneToQuickbuildInterruptCount;
uint32_t m_ImmuneToPullToPointCount; uint32_t m_ImmuneToPullToPointCount;
/**
* Death behavior type. If 0, the client plays a death animation as opposed to a smash animation.
*/
int32_t m_DeathBehavior;
}; };
#endif // DESTROYABLECOMPONENT_H #endif // DESTROYABLECOMPONENT_H

View File

@ -18,7 +18,7 @@ void AgPropguards::OnMissionDialogueOK(Entity* self, Entity* target, int mission
&& !character->GetPlayerFlag(flag)) { && !character->GetPlayerFlag(flag)) {
// If the player just started the mission, play a cinematic highlighting the target // If the player just started the mission, play a cinematic highlighting the target
GameMessages::SendPlayCinematic(target->GetObjectID(), u"MissionCam", target->GetSystemAddress()); GameMessages::SendPlayCinematic(target->GetObjectID(), u"MissionCam", target->GetSystemAddress());
} else if (missionState == eMissionState::COMPLETE_READY_TO_COMPLETE) { } else if (missionState == eMissionState::READY_TO_COMPLETE) {
// Makes the guard disappear once the mission has been completed // Makes the guard disappear once the mission has been completed
const auto zoneControlID = Game::entityManager->GetZoneControlEntity()->GetObjectID(); const auto zoneControlID = Game::entityManager->GetZoneControlEntity()->GetObjectID();
GameMessages::SendNotifyClientObject(zoneControlID, u"GuardChat", 0, 0, self->GetObjectID(), GameMessages::SendNotifyClientObject(zoneControlID, u"GuardChat", 0, 0, self->GetObjectID(),