From 374b85a00d2f5e1e40b7ca9bc84ac9804236ba77 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 13 Jun 2020 01:04:55 +0200 Subject: [PATCH] Add Class methods to get walk, run, swim speed --- apps/openmw/mwclass/creature.cpp | 43 +++++++++++++----- apps/openmw/mwclass/creature.hpp | 6 +++ apps/openmw/mwclass/npc.cpp | 76 +++++++++++++++++++++++--------- apps/openmw/mwclass/npc.hpp | 6 +++ apps/openmw/mwworld/class.cpp | 15 +++++++ apps/openmw/mwworld/class.hpp | 6 +++ 6 files changed, 119 insertions(+), 33 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 470a28b7e..88defbaa0 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -507,15 +507,13 @@ namespace MWClass float Creature::getSpeed(const MWWorld::Ptr &ptr) const { - MWMechanics::CreatureStats& stats = getCreatureStats(ptr); + const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); + if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead()) return 0.f; const GMST& gmst = getGmst(); - const float walkSpeed = gmst.fMinWalkSpeedCreature->mValue.getFloat() + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified() - * (gmst.fMaxWalkSpeedCreature->mValue.getFloat() - gmst.fMinWalkSpeedCreature->mValue.getFloat()); - const MWBase::World *world = MWBase::Environment::get().getWorld(); const MWMechanics::MagicEffects &mageffects = stats.getMagicEffects(); @@ -535,15 +533,9 @@ namespace MWClass moveSpeed = flySpeed; } else if(world->isSwimming(ptr)) - { - float swimSpeed = walkSpeed; - swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude(); - swimSpeed *= gmst.fSwimRunBase->mValue.getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics) * - gmst.fSwimRunAthleticsMult->mValue.getFloat(); - moveSpeed = swimSpeed; - } + moveSpeed = getSwimSpeed(ptr); else - moveSpeed = walkSpeed; + moveSpeed = getWalkSpeed(ptr); if(getMovementSettings(ptr).mPosition[0] != 0 && getMovementSettings(ptr).mPosition[1] == 0) moveSpeed *= 0.75f; @@ -880,4 +872,31 @@ namespace MWClass { MWMechanics::setBaseAISetting(id, setting, value); } + + float Creature::getWalkSpeed(const MWWorld::Ptr& ptr) const + { + const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); + const GMST& gmst = getGmst(); + + return gmst.fMinWalkSpeedCreature->mValue.getFloat() + + 0.01f * stats.getAttribute(ESM::Attribute::Speed).getModified() + * (gmst.fMaxWalkSpeedCreature->mValue.getFloat() - gmst.fMinWalkSpeedCreature->mValue.getFloat()); + } + + float Creature::getRunSpeed(const MWWorld::Ptr& ptr) const + { + return getWalkSpeed(ptr); + } + + float Creature::getSwimSpeed(const MWWorld::Ptr& ptr) const + { + const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); + const GMST& gmst = getGmst(); + const MWMechanics::MagicEffects& mageffects = stats.getMagicEffects(); + + return getWalkSpeed(ptr) + * (1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude()) + * (gmst.fSwimRunBase->mValue.getFloat() + + 0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fSwimRunAthleticsMult->mValue.getFloat()); + } } diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index 3288c0d11..9071b9a33 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -131,6 +131,12 @@ namespace MWClass /// @param rendering Indicates if the scale to adjust is for the rendering mesh, or for the collision mesh virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const; + + float getWalkSpeed(const MWWorld::Ptr& ptr) const final; + + float getRunSpeed(const MWWorld::Ptr& ptr) const final; + + float getSwimSpeed(const MWWorld::Ptr& ptr) const final; }; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 3b9c46c8f..319d5f014 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -947,16 +947,6 @@ namespace MWClass bool inair = !world->isOnGround(ptr) && !swimming && !world->isFlying(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()* - (gmst.fMaxWalkSpeed->mValue.getFloat() - gmst.fMinWalkSpeed->mValue.getFloat()); - walkSpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat()*normalizedEncumbrance; - walkSpeed = std::max(0.0f, walkSpeed); - if(sneaking) - walkSpeed *= gmst.fSneakSpeedMultiplier->mValue.getFloat(); - - float runSpeed = walkSpeed*(0.01f * getSkill(ptr, ESM::Skill::Athletics) * - gmst.fAthleticsRunBonus->mValue.getFloat() + gmst.fBaseRunMultiplier->mValue.getFloat()); - float moveSpeed; if(getEncumbrance(ptr) > getCapacity(ptr)) moveSpeed = 0.0f; @@ -971,19 +961,11 @@ namespace MWClass moveSpeed = flySpeed; } else if (swimming) - { - float swimSpeed = walkSpeed; - if(running) - swimSpeed = runSpeed; - swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude(); - swimSpeed *= gmst.fSwimRunBase->mValue.getFloat() + 0.01f*getSkill(ptr, ESM::Skill::Athletics)* - gmst.fSwimRunAthleticsMult->mValue.getFloat(); - moveSpeed = swimSpeed; - } + moveSpeed = getSwimSpeed(ptr); else if (running && !sneaking) - moveSpeed = runSpeed; + moveSpeed = getRunSpeed(ptr); else - moveSpeed = walkSpeed; + moveSpeed = getWalkSpeed(ptr); if(getMovementSettings(ptr).mPosition[0] != 0 && getMovementSettings(ptr).mPosition[1] == 0) moveSpeed *= 0.75f; @@ -1448,4 +1430,56 @@ namespace MWClass { MWMechanics::setBaseAISetting(id, setting, value); } + + float Npc::getWalkSpeed(const MWWorld::Ptr& ptr) const + { + const GMST& gmst = getGmst(); + const NpcCustomData* npcdata = static_cast(ptr.getRefData().getCustomData()); + const float normalizedEncumbrance = getNormalizedEncumbrance(ptr); + const bool sneaking = MWBase::Environment::get().getMechanicsManager()->isSneaking(ptr); + + float walkSpeed = gmst.fMinWalkSpeed->mValue.getFloat() + + 0.01f * npcdata->mNpcStats.getAttribute(ESM::Attribute::Speed).getModified() + * (gmst.fMaxWalkSpeed->mValue.getFloat() - gmst.fMinWalkSpeed->mValue.getFloat()); + walkSpeed *= 1.0f - gmst.fEncumberedMoveEffect->mValue.getFloat()*normalizedEncumbrance; + walkSpeed = std::max(0.0f, walkSpeed); + if(sneaking) + walkSpeed *= gmst.fSneakSpeedMultiplier->mValue.getFloat(); + + return walkSpeed; + } + + float Npc::getRunSpeed(const MWWorld::Ptr& ptr) const + { + const GMST& gmst = getGmst(); + return getWalkSpeed(ptr) + * (0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fAthleticsRunBonus->mValue.getFloat() + + gmst.fBaseRunMultiplier->mValue.getFloat()); + } + + float Npc::getSwimSpeed(const MWWorld::Ptr& ptr) const + { + const GMST& gmst = getGmst(); + const MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWMechanics::CreatureStats& stats = getCreatureStats(ptr); + const NpcCustomData* npcdata = static_cast(ptr.getRefData().getCustomData()); + const MWMechanics::MagicEffects& mageffects = npcdata->mNpcStats.getMagicEffects(); + const bool swimming = world->isSwimming(ptr); + const bool inair = !world->isOnGround(ptr) && !swimming && !world->isFlying(ptr); + const bool running = stats.getStance(MWMechanics::CreatureStats::Stance_Run) + && (inair || MWBase::Environment::get().getMechanicsManager()->isRunning(ptr)); + + float swimSpeed; + + if (running) + swimSpeed = getRunSpeed(ptr); + else + swimSpeed = getWalkSpeed(ptr); + + swimSpeed *= 1.0f + 0.01f * mageffects.get(ESM::MagicEffect::SwiftSwim).getMagnitude(); + swimSpeed *= gmst.fSwimRunBase->mValue.getFloat() + + 0.01f * getSkill(ptr, ESM::Skill::Athletics) * gmst.fSwimRunAthleticsMult->mValue.getFloat(); + + return swimSpeed; + } } diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index ae4f32d13..d92293acb 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -166,6 +166,12 @@ namespace MWClass virtual int getPrimaryFactionRank(const MWWorld::ConstPtr &ptr) const; virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const; + + float getWalkSpeed(const MWWorld::Ptr& ptr) const final; + + float getRunSpeed(const MWWorld::Ptr& ptr) const final; + + float getSwimSpeed(const MWWorld::Ptr& ptr) const final; }; } diff --git a/apps/openmw/mwworld/class.cpp b/apps/openmw/mwworld/class.cpp index d7ee59ee2..b59532f2a 100644 --- a/apps/openmw/mwworld/class.cpp +++ b/apps/openmw/mwworld/class.cpp @@ -521,4 +521,19 @@ namespace MWWorld { throw std::runtime_error ("class does not have creature stats"); } + + float Class::getWalkSpeed(const Ptr& /*ptr*/) const + { + return 0; + } + + float Class::getRunSpeed(const Ptr& /*ptr*/) const + { + return 0; + } + + float Class::getSwimSpeed(const Ptr& /*ptr*/) const + { + return 0; + } } diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index fd679c43f..f92dc0373 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -362,6 +362,12 @@ namespace MWWorld virtual osg::Vec4f getEnchantmentColor(const MWWorld::ConstPtr& item) const; virtual void setBaseAISetting(const std::string& id, MWMechanics::CreatureStats::AiSetting setting, int value) const; + + virtual float getWalkSpeed(const Ptr& ptr) const; + + virtual float getRunSpeed(const Ptr& ptr) const; + + virtual float getSwimSpeed(const Ptr& ptr) const; }; }