From 374982180931025cc06709c36e2e5a2508d643af Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 19 May 2016 21:37:24 +0200 Subject: [PATCH] Choose a random death animation for actors that start the game as dead (Fixes #3397) --- apps/openmw/mwmechanics/character.cpp | 18 ++++++++++++++---- apps/openmw/mwmechanics/character.hpp | 1 + apps/openmw/mwmechanics/creaturestats.cpp | 6 +++--- apps/openmw/mwmechanics/creaturestats.hpp | 8 ++++---- components/esm/creaturestats.cpp | 6 +++--- components/esm/creaturestats.hpp | 2 +- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 82c289200..5ab195e64 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -629,6 +629,13 @@ void CharacterController::playDeath(float startpoint, CharacterState death) false, 1.0f, "start", "stop", startpoint, 0); } +CharacterState CharacterController::chooseRandomDeathState() +{ + int selected=0; + chooseRandomGroup("death", &selected); + return static_cast(CharState_Death1 + (selected-1)); +} + void CharacterController::playRandomDeath(float startpoint) { if (mPtr == getPlayer()) @@ -652,9 +659,7 @@ void CharacterController::playRandomDeath(float startpoint) } else { - int selected=0; - chooseRandomGroup("death", &selected); - mDeathState = static_cast(CharState_Death1 + (selected-1)); + mDeathState = chooseRandomDeathState(); } playDeath(startpoint, mDeathState); } @@ -716,7 +721,12 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim { // Set the death state, but don't play it yet // We will play it in the first frame, but only if no script set the skipAnim flag - mDeathState = static_cast(CharState_Death1 + mPtr.getClass().getCreatureStats(mPtr).getDeathAnimation()); + signed char deathanim = mPtr.getClass().getCreatureStats(mPtr).getDeathAnimation(); + if (deathanim == -1) + mDeathState = chooseRandomDeathState(); + else + mDeathState = static_cast(CharState_Death1 + deathanim); + mFloatToSurface = false; } } diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 6fab04d64..685bdf1cb 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -207,6 +207,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener void updateMagicEffects(); void playDeath(float startpoint, CharacterState death); + CharacterState chooseRandomDeathState(); void playRandomDeath(float startpoint = 0.0f); /// choose a random animation group with \a prefix and numeric suffix diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 13396e3fa..7d1dc4d2f 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -22,7 +22,7 @@ namespace MWMechanics mKnockdown(false), mKnockdownOneFrame(false), mKnockdownOverOneFrame(false), mHitRecovery(false), mBlock(false), mMovementFlags(0), mFallHeight(0), mRecalcMagicka(false), mLastRestock(0,0), mGoldPool(0), mActorId(-1), - mDeathAnimation(0), mTimeOfDeath(), mLevel (0) + mDeathAnimation(-1), mTimeOfDeath(), mLevel (0) { for (int i=0; i<4; ++i) mAiSettings[i] = 0; @@ -617,12 +617,12 @@ namespace MWMechanics esm.getHNT(sActorId, "COUN"); } - unsigned char CreatureStats::getDeathAnimation() const + signed char CreatureStats::getDeathAnimation() const { return mDeathAnimation; } - void CreatureStats::setDeathAnimation(unsigned char index) + void CreatureStats::setDeathAnimation(signed char index) { mDeathAnimation = index; } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 734e87319..8965dedac 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -62,8 +62,8 @@ namespace MWMechanics int mActorId; - // The index of the death animation that was played - unsigned char mDeathAnimation; + // The index of the death animation that was played, or -1 if none played + signed char mDeathAnimation; MWWorld::TimeStamp mTimeOfDeath; @@ -258,8 +258,8 @@ namespace MWMechanics void setGoldPool(int pool); int getGoldPool() const; - unsigned char getDeathAnimation() const; - void setDeathAnimation(unsigned char index); + signed char getDeathAnimation() const; // -1 means not decided + void setDeathAnimation(signed char index); MWWorld::TimeStamp getTimeOfDeath() const; diff --git a/components/esm/creaturestats.cpp b/components/esm/creaturestats.cpp index 9b60382e9..a48ce5472 100644 --- a/components/esm/creaturestats.cpp +++ b/components/esm/creaturestats.cpp @@ -84,7 +84,7 @@ void ESM::CreatureStats::load (ESMReader &esm) mActorId = -1; esm.getHNOT (mActorId, "ACID"); - mDeathAnimation = 0; + mDeathAnimation = -1; esm.getHNOT (mDeathAnimation, "DANM"); mTimeOfDeath.mDay = 0; @@ -194,7 +194,7 @@ void ESM::CreatureStats::save (ESMWriter &esm) const if (mActorId != -1) esm.writeHNT ("ACID", mActorId); - if (mDeathAnimation) + if (mDeathAnimation != -1) esm.writeHNT ("DANM", mDeathAnimation); if (mTimeOfDeath.mHour != 0 && mTimeOfDeath.mDay != 0) @@ -247,6 +247,6 @@ void ESM::CreatureStats::blank() mFallHeight = 0.f; mRecalcDynamicStats = false; mDrawState = 0; - mDeathAnimation = 0; + mDeathAnimation = -1; mLevel = 1; } diff --git a/components/esm/creaturestats.hpp b/components/esm/creaturestats.hpp index 66b708e27..a99cca944 100644 --- a/components/esm/creaturestats.hpp +++ b/components/esm/creaturestats.hpp @@ -56,7 +56,7 @@ namespace ESM std::string mLastHitAttemptObject; bool mRecalcDynamicStats; int mDrawState; - unsigned char mDeathAnimation; + signed char mDeathAnimation; ESM::TimeStamp mTimeOfDeath; int mLevel;