1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 18:35:20 +00:00

Merge pull request #2457 from Capostrophic/sneak

Sneaking consistency fixes (bug #5103)
This commit is contained in:
Andrei Kortunov 2019-08-18 08:57:22 +04:00 committed by GitHub
commit ed8828d3bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 16 additions and 31 deletions

View File

@ -121,6 +121,7 @@
Bug #5092: NPCs with enchanted weapons play sound when out of charges Bug #5092: NPCs with enchanted weapons play sound when out of charges
Bug #5093: Hand to hand sound plays on knocked out enemies Bug #5093: Hand to hand sound plays on knocked out enemies
Bug #5099: Non-swimming enemies will enter water if player is water walking Bug #5099: Non-swimming enemies will enter water if player is water walking
Bug #5103: Sneaking state behavior is still inconsistent
Bug #5104: Black Dart's enchantment doesn't trigger at low Enchant levels Bug #5104: Black Dart's enchantment doesn't trigger at low Enchant levels
Bug #5105: NPCs start combat with werewolves from any distance Bug #5105: NPCs start combat with werewolves from any distance
Bug #5106: Still can jump even when encumbered Bug #5106: Still can jump even when encumbered

View File

@ -940,10 +940,9 @@ namespace MWClass
const float normalizedEncumbrance = getNormalizedEncumbrance(ptr); const float normalizedEncumbrance = getNormalizedEncumbrance(ptr);
bool swimming = world->isSwimming(ptr); bool swimming = world->isSwimming(ptr);
bool sneaking = MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr);
bool running = stats.getStance(MWMechanics::CreatureStats::Stance_Run);
bool inair = !world->isOnGround(ptr) && !swimming && !world->isFlying(ptr); bool inair = !world->isOnGround(ptr) && !swimming && !world->isFlying(ptr);
bool sneaking = stats.getStance(MWMechanics::CreatureStats::Stance_Sneak);
sneaking = sneaking && (inair || MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr));
bool running = stats.getStance(MWMechanics::CreatureStats::Stance_Run);
running = running && (inair || MWBase::Environment::get().getMechanicsManager()->isRunning(ptr)); running = running && (inair || MWBase::Environment::get().getMechanicsManager()->isRunning(ptr));
float walkSpeed = gmst.fMinWalkSpeed->mValue.getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()* float walkSpeed = gmst.fMinWalkSpeed->mValue.getFloat() + 0.01f*npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified()*

View File

@ -1785,14 +1785,7 @@ namespace MWMechanics
MWWorld::Ptr player = getPlayer(); MWWorld::Ptr player = getPlayer();
CreatureStats& stats = player.getClass().getCreatureStats(player); if (!MWBase::Environment::get().getMechanicsManager()->isSneaking(player))
MWBase::World* world = MWBase::Environment::get().getWorld();
bool sneaking = stats.getStance(MWMechanics::CreatureStats::Stance_Sneak);
bool inair = !world->isOnGround(player) && !world->isSwimming(player) && !world->isFlying(player);
sneaking = sneaking && (ctrl->isSneaking() || inair);
if (!sneaking)
{ {
MWBase::Environment::get().getWindowManager()->setSneakVisibility(false); MWBase::Environment::get().getWindowManager()->setSneakVisibility(false);
return; return;
@ -1800,6 +1793,7 @@ namespace MWMechanics
static float sneakSkillTimer = 0.f; // Times sneak skill progress from "avoid notice" static float sneakSkillTimer = 0.f; // Times sneak skill progress from "avoid notice"
MWBase::World* world = MWBase::Environment::get().getWorld();
const MWWorld::Store<ESM::GameSetting>& gmst = world->getStore().get<ESM::GameSetting>(); const MWWorld::Store<ESM::GameSetting>& gmst = world->getStore().get<ESM::GameSetting>();
static const float fSneakUseDist = gmst.find("fSneakUseDist")->mValue.getFloat(); static const float fSneakUseDist = gmst.find("fSneakUseDist")->mValue.getFloat();
static const float fSneakUseDelay = gmst.find("fSneakUseDelay")->mValue.getFloat(); static const float fSneakUseDelay = gmst.find("fSneakUseDelay")->mValue.getFloat();

View File

@ -568,10 +568,6 @@ void CharacterController::refreshMovementAnims(const std::string& weapShortGroup
mCurrentMovement = movementAnimName; mCurrentMovement = movementAnimName;
if(!mCurrentMovement.empty()) if(!mCurrentMovement.empty())
{ {
bool isflying = MWBase::Environment::get().getWorld()->isFlying(mPtr);
bool isrunning = mPtr.getClass().getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Run) && !isflying;
bool issneaking = mPtr.getClass().getCreatureStats(mPtr).getStance(MWMechanics::CreatureStats::Stance_Sneak) && !isflying;
// For non-flying creatures, MW uses the Walk animation to calculate the animation velocity // For non-flying creatures, MW uses the Walk animation to calculate the animation velocity
// even if we are running. This must be replicated, otherwise the observed speed would differ drastically. // even if we are running. This must be replicated, otherwise the observed speed would differ drastically.
std::string anim = mCurrentMovement; std::string anim = mCurrentMovement;
@ -604,7 +600,7 @@ void CharacterController::refreshMovementAnims(const std::string& weapShortGroup
// The first person anims don't have any velocity to calculate a speed multiplier from. // The first person anims don't have any velocity to calculate a speed multiplier from.
// We use the third person velocities instead. // We use the third person velocities instead.
// FIXME: should be pulled from the actual animation, but it is not presently loaded. // FIXME: should be pulled from the actual animation, but it is not presently loaded.
mMovementAnimSpeed = (issneaking ? 33.5452f : (isrunning ? 222.857f : 154.064f)); mMovementAnimSpeed = (isSneaking() ? 33.5452f : (isRunning() ? 222.857f : 154.064f));
mMovementAnimationControlled = false; mMovementAnimationControlled = false;
} }
} }

View File

@ -477,7 +477,12 @@ namespace MWMechanics
bool MechanicsManager::isSneaking(const MWWorld::Ptr& ptr) bool MechanicsManager::isSneaking(const MWWorld::Ptr& ptr)
{ {
return mActors.isSneaking(ptr); CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
MWBase::World* world = MWBase::Environment::get().getWorld();
bool animActive = mActors.isSneaking(ptr);
bool stanceOn = stats.getStance(MWMechanics::CreatureStats::Stance_Sneak);
bool inair = !world->isOnGround(ptr) && !world->isSwimming(ptr) && !world->isFlying(ptr);
return stanceOn && (animActive || inair);
} }
void MechanicsManager::rest(double hours, bool sleep) void MechanicsManager::rest(double hours, bool sleep)
@ -965,8 +970,7 @@ namespace MWMechanics
return true; return true;
// check if a player tries to pickpocket a target NPC // check if a player tries to pickpocket a target NPC
if(ptr.getClass().getCreatureStats(ptr).getStance(MWMechanics::CreatureStats::Stance_Sneak) if (target.getClass().getCreatureStats(target).getKnockedDown() || isSneaking(ptr))
|| target.getClass().getCreatureStats(target).getKnockedDown())
return false; return false;
return true; return true;
@ -1586,9 +1590,7 @@ namespace MWMechanics
return false; return false;
float sneakTerm = 0; float sneakTerm = 0;
if (ptr.getClass().getCreatureStats(ptr).getStance(CreatureStats::Stance_Sneak) if (isSneaking(ptr))
&& !MWBase::Environment::get().getWorld()->isSwimming(ptr)
&& MWBase::Environment::get().getWorld()->isOnGround(ptr))
{ {
static float fSneakSkillMult = store.find("fSneakSkillMult")->mValue.getFloat(); static float fSneakSkillMult = store.find("fSneakSkillMult")->mValue.getFloat();
static float fSneakBootMult = store.find("fSneakBootMult")->mValue.getFloat(); static float fSneakBootMult = store.find("fSneakBootMult")->mValue.getFloat();
@ -1596,7 +1598,7 @@ namespace MWMechanics
int agility = stats.getAttribute(ESM::Attribute::Agility).getModified(); int agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
int luck = stats.getAttribute(ESM::Attribute::Luck).getModified(); int luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
float bootWeight = 0; float bootWeight = 0;
if (ptr.getClass().isNpc()) if (ptr.getClass().isNpc() && MWBase::Environment::get().getWorld()->isOnGround(ptr))
{ {
const MWWorld::InventoryStore& inv = ptr.getClass().getInventoryStore(ptr); const MWWorld::InventoryStore& inv = ptr.getClass().getInventoryStore(ptr);
MWWorld::ConstContainerStoreIterator it = inv.getSlot(MWWorld::InventoryStore::Slot_Boots); MWWorld::ConstContainerStoreIterator it = inv.getSlot(MWWorld::InventoryStore::Slot_Boots);

View File

@ -186,14 +186,7 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr();
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); runtime.push(MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr));
MWBase::World* world = MWBase::Environment::get().getWorld();
bool stanceOn = stats.getStance(MWMechanics::CreatureStats::Stance_Sneak);
bool sneaking = MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr);
bool inair = !world->isOnGround(ptr) && !world->isSwimming(ptr) && !world->isFlying(ptr);
runtime.push(stanceOn && (sneaking || inair));
} }
}; };