From 5b8610b34b61e5b587cc196205aa3bb1275d5967 Mon Sep 17 00:00:00 2001 From: rexelion Date: Wed, 1 Nov 2017 23:44:50 +0000 Subject: [PATCH 1/6] knocked out characters wait some time before getting up --- apps/openmw/mwmechanics/character.cpp | 6 +++++- apps/openmw/mwmechanics/character.hpp | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 03acfdaf2..c3ca8f512 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -248,12 +248,15 @@ void CharacterController::refreshHitRecoilAnims() bool knockdown = mPtr.getClass().getCreatureStats(mPtr).getKnockedDown(); bool block = mPtr.getClass().getCreatureStats(mPtr).getBlock(); bool isSwimming = MWBase::Environment::get().getWorld()->isSwimming(mPtr); + MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor(); if(mHitState == CharState_None) { if ((mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() < 0 || mPtr.getClass().getCreatureStats(mPtr).getFatigue().getBase() == 0) && mAnimation->hasAnimation("knockout")) { + mKnockoutTime = MWBase::Environment::get().getWorld()->getTimeStamp(); if (isSwimming && mAnimation->hasAnimation("swimknockout")) { mHitState = CharState_SwimKnockOut; @@ -338,7 +341,8 @@ void CharacterController::refreshHitRecoilAnims() mPtr.getClass().getCreatureStats(mPtr).setBlock(false); mHitState = CharState_None; } - else if (isKnockedOut() && mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() > 0) + else if (isKnockedOut() && mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() > 0 + && (currentTime - mKnockoutTime) > 3*timeScale/3600) //Wait 3 seconds before getting up { mHitState = isSwimming ? CharState_SwimKnockDown : CharState_KnockDown; mAnimation->disable(mCurrentHit); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index af90c18b8..0654b8534 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -7,6 +7,7 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/containerstore.hpp" +#include "../mwworld/timestamp.hpp" #include "../mwrender/animation.hpp" @@ -196,6 +197,8 @@ class CharacterController : public MWRender::Animation::TextKeyListener float mSecondsOfSwimming; float mSecondsOfRunning; + MWWorld::TimeStamp mKnockoutTime; + MWWorld::ConstPtr mHeadTrackTarget; float mTurnAnimationThreshold; // how long to continue playing turning animation after actor stopped turning From de83ad0116c434e8bf90ab4f330a93e50f392191 Mon Sep 17 00:00:00 2001 From: rexelion Date: Sat, 4 Nov 2017 00:24:09 +0000 Subject: [PATCH 2/6] use real time; wait random number of seconds --- apps/openmw/mwmechanics/character.cpp | 7 +++---- apps/openmw/mwmechanics/character.hpp | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index c3ca8f512..dffc095e9 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -248,15 +248,14 @@ void CharacterController::refreshHitRecoilAnims() bool knockdown = mPtr.getClass().getCreatureStats(mPtr).getKnockedDown(); bool block = mPtr.getClass().getCreatureStats(mPtr).getBlock(); bool isSwimming = MWBase::Environment::get().getWorld()->isSwimming(mPtr); - MWWorld::TimeStamp currentTime = MWBase::Environment::get().getWorld()->getTimeStamp(); - float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor(); if(mHitState == CharState_None) { if ((mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() < 0 || mPtr.getClass().getCreatureStats(mPtr).getFatigue().getBase() == 0) && mAnimation->hasAnimation("knockout")) { - mKnockoutTime = MWBase::Environment::get().getWorld()->getTimeStamp(); + mTimeToWake = time(NULL); + mTimeToWake += rand() % 2 + 1; // Wake up after 1 to 3 seconds if (isSwimming && mAnimation->hasAnimation("swimknockout")) { mHitState = CharState_SwimKnockOut; @@ -342,7 +341,7 @@ void CharacterController::refreshHitRecoilAnims() mHitState = CharState_None; } else if (isKnockedOut() && mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() > 0 - && (currentTime - mKnockoutTime) > 3*timeScale/3600) //Wait 3 seconds before getting up + && time(NULL) > mTimeToWake) { mHitState = isSwimming ? CharState_SwimKnockDown : CharState_KnockDown; mAnimation->disable(mCurrentHit); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 0654b8534..af8415e35 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -197,7 +197,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener float mSecondsOfSwimming; float mSecondsOfRunning; - MWWorld::TimeStamp mKnockoutTime; + time_t mTimeToWake; MWWorld::ConstPtr mHeadTrackTarget; From ee2f3db9a87abf24341f4247b7748d5aa935ef6e Mon Sep 17 00:00:00 2001 From: rexelion Date: Sat, 4 Nov 2017 01:31:15 +0000 Subject: [PATCH 3/6] fixed randomness --- apps/openmw/mwmechanics/character.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index dffc095e9..deb9daa93 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -255,7 +255,7 @@ void CharacterController::refreshHitRecoilAnims() && mAnimation->hasAnimation("knockout")) { mTimeToWake = time(NULL); - mTimeToWake += rand() % 2 + 1; // Wake up after 1 to 3 seconds + mTimeToWake += (int)( (float)rand() / (float)RAND_MAX * 2) + 1; // Wake up after 1 to 3 seconds if (isSwimming && mAnimation->hasAnimation("swimknockout")) { mHitState = CharState_SwimKnockOut; From ab66034ed17f045839f4fd16ac1fec4872e6afad Mon Sep 17 00:00:00 2001 From: rexelion Date: Sat, 4 Nov 2017 02:15:56 +0000 Subject: [PATCH 4/6] use uniform_int_distribution instead of rand() --- apps/openmw/mwmechanics/character.cpp | 6 +++++- apps/openmw/mwmechanics/character.hpp | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index deb9daa93..ade9d635b 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -20,6 +20,7 @@ #include "character.hpp" #include +#include #include @@ -254,8 +255,11 @@ void CharacterController::refreshHitRecoilAnims() || mPtr.getClass().getCreatureStats(mPtr).getFatigue().getBase() == 0) && mAnimation->hasAnimation("knockout")) { + std::random_device r; + std::mt19937 gen(r()); + std::uniform_int_distribution dist(1, 3); mTimeToWake = time(NULL); - mTimeToWake += (int)( (float)rand() / (float)RAND_MAX * 2) + 1; // Wake up after 1 to 3 seconds + mTimeToWake += dist(gen); // Wake up after 1 to 3 seconds if (isSwimming && mAnimation->hasAnimation("swimknockout")) { mHitState = CharState_SwimKnockOut; diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index af8415e35..12b4d6adc 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -7,7 +7,6 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/containerstore.hpp" -#include "../mwworld/timestamp.hpp" #include "../mwrender/animation.hpp" From 48ec680f233f2ea616569e77872d757df7a488a0 Mon Sep 17 00:00:00 2001 From: rexelion Date: Sat, 4 Nov 2017 19:37:20 +0000 Subject: [PATCH 5/6] use game time instead of real time --- apps/openmw/mwmechanics/character.cpp | 17 ++++++++++------- apps/openmw/mwmechanics/character.hpp | 4 +++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index ade9d635b..83d6cc1f3 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -20,7 +20,6 @@ #include "character.hpp" #include -#include #include @@ -243,6 +242,11 @@ std::string CharacterController::chooseRandomGroup (const std::string& prefix, i return prefix + toString(roll); } +void CharacterController::updateKnockoutTimer(float duration) +{ + mTimeUntilWake -= duration; +} + void CharacterController::refreshHitRecoilAnims() { bool recovery = mPtr.getClass().getCreatureStats(mPtr).getHitRecovery(); @@ -255,11 +259,7 @@ void CharacterController::refreshHitRecoilAnims() || mPtr.getClass().getCreatureStats(mPtr).getFatigue().getBase() == 0) && mAnimation->hasAnimation("knockout")) { - std::random_device r; - std::mt19937 gen(r()); - std::uniform_int_distribution dist(1, 3); - mTimeToWake = time(NULL); - mTimeToWake += dist(gen); // Wake up after 1 to 3 seconds + mTimeUntilWake = Misc::Rng::rollClosedProbability() * 2 + 1; // Wake up after 1 to 3 seconds if (isSwimming && mAnimation->hasAnimation("swimknockout")) { mHitState = CharState_SwimKnockOut; @@ -345,7 +345,7 @@ void CharacterController::refreshHitRecoilAnims() mHitState = CharState_None; } else if (isKnockedOut() && mPtr.getClass().getCreatureStats(mPtr).getFatigue().getCurrent() > 0 - && time(NULL) > mTimeToWake) + && mTimeUntilWake <= 0) { mHitState = isSwimming ? CharState_SwimKnockDown : CharState_KnockDown; mAnimation->disable(mCurrentHit); @@ -1635,6 +1635,9 @@ void CharacterController::update(float duration) float speed = 0.f; updateMagicEffects(); + + if (isKnockedOut()) + updateKnockoutTimer(duration); bool godmode = mPtr == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 12b4d6adc..0b9e60c11 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -196,7 +196,7 @@ class CharacterController : public MWRender::Animation::TextKeyListener float mSecondsOfSwimming; float mSecondsOfRunning; - time_t mTimeToWake; + float mTimeUntilWake; MWWorld::ConstPtr mHeadTrackTarget; @@ -226,6 +226,8 @@ class CharacterController : public MWRender::Animation::TextKeyListener void updateMagicEffects(); + void updateKnockoutTimer(float duration); + void playDeath(float startpoint, CharacterState death); CharacterState chooseRandomDeathState() const; void playRandomDeath(float startpoint = 0.0f); From de7a7d842bb6d90660c8da66c47ec30ec8091c06 Mon Sep 17 00:00:00 2001 From: rexelion Date: Sun, 5 Nov 2017 18:30:34 +0000 Subject: [PATCH 6/6] mTimeUntilWake is initialised in the constructor --- apps/openmw/mwmechanics/character.cpp | 8 ++------ apps/openmw/mwmechanics/character.hpp | 2 -- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 83d6cc1f3..0f99725fd 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -242,11 +242,6 @@ std::string CharacterController::chooseRandomGroup (const std::string& prefix, i return prefix + toString(roll); } -void CharacterController::updateKnockoutTimer(float duration) -{ - mTimeUntilWake -= duration; -} - void CharacterController::refreshHitRecoilAnims() { bool recovery = mPtr.getClass().getCreatureStats(mPtr).getHitRecovery(); @@ -766,6 +761,7 @@ CharacterController::CharacterController(const MWWorld::Ptr &ptr, MWRender::Anim , mSecondsOfRunning(0) , mTurnAnimationThreshold(0) , mAttackingOrSpell(false) + , mTimeUntilWake(0.f) { if(!mAnimation) return; @@ -1637,7 +1633,7 @@ void CharacterController::update(float duration) updateMagicEffects(); if (isKnockedOut()) - updateKnockoutTimer(duration); + mTimeUntilWake -= duration; bool godmode = mPtr == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 0b9e60c11..6de18fe62 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -226,8 +226,6 @@ class CharacterController : public MWRender::Animation::TextKeyListener void updateMagicEffects(); - void updateKnockoutTimer(float duration); - void playDeath(float startpoint, CharacterState death); CharacterState chooseRandomDeathState() const; void playRandomDeath(float startpoint = 0.0f);