From 2a0e1697b6634387daa3e9c12091744eec150bd5 Mon Sep 17 00:00:00 2001
From: elsid <elsid.mail@gmail.com>
Date: Sun, 14 Jun 2020 18:01:22 +0200
Subject: [PATCH] Deduplicate swim speed formula implementation

---
 apps/openmw/mwclass/actor.hpp    | 11 +++++++++++
 apps/openmw/mwclass/creature.cpp |  6 +-----
 apps/openmw/mwclass/npc.cpp      | 14 +-------------
 3 files changed, 13 insertions(+), 18 deletions(-)

diff --git a/apps/openmw/mwclass/actor.hpp b/apps/openmw/mwclass/actor.hpp
index 886ffe4771..596bdf26ec 100644
--- a/apps/openmw/mwclass/actor.hpp
+++ b/apps/openmw/mwclass/actor.hpp
@@ -3,6 +3,8 @@
 
 #include "../mwworld/class.hpp"
 
+#include <components/esm/loadmgef.hpp>
+
 namespace ESM
 {
     struct GameSetting;
@@ -17,6 +19,15 @@ namespace MWClass
 
         Actor() = default;
 
+        template <class GMST>
+        float getSwimSpeedImpl(const MWWorld::Ptr& ptr, const GMST& gmst, const MWMechanics::MagicEffects& mageffects, float baseSpeed) const
+        {
+            return baseSpeed
+                * (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());
+        }
+
     public:
          ~Actor() override = default;
 
diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp
index c20a005724..dae2dedc54 100644
--- a/apps/openmw/mwclass/creature.cpp
+++ b/apps/openmw/mwclass/creature.cpp
@@ -891,12 +891,8 @@ namespace MWClass
     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());
+        return getSwimSpeedImpl(ptr, getGmst(), mageffects, getWalkSpeed(ptr));
     }
 }
diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp
index 59280a0f02..78d2f1ebd5 100644
--- a/apps/openmw/mwclass/npc.cpp
+++ b/apps/openmw/mwclass/npc.cpp
@@ -1476,7 +1476,6 @@ namespace MWClass
 
     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<const NpcCustomData*>(ptr.getRefData().getCustomData());
@@ -1486,17 +1485,6 @@ namespace MWClass
         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;
+        return getSwimSpeedImpl(ptr, getGmst(), mageffects, running ? getRunSpeed(ptr) : getWalkSpeed(ptr));
     }
 }