From c1f59b1221cdad439909bfedbc742a7228eee485 Mon Sep 17 00:00:00 2001
From: Evil Eye <malusluminis@hotmail.com>
Date: Fri, 24 Dec 2021 23:17:50 +0100
Subject: [PATCH] Automatically drop workaround when the format is next updated

---
 apps/essimporter/converter.cpp            |  5 ++---
 apps/openmw/mwclass/creature.cpp          |  6 +-----
 apps/openmw/mwclass/npc.cpp               |  5 +----
 apps/openmw/mwmechanics/creaturestats.cpp |  6 +++---
 apps/openmw/mwmechanics/creaturestats.hpp |  2 --
 components/esm/creaturestats.cpp          | 19 +++++++++++++++++--
 components/esm/creaturestats.hpp          |  1 +
 7 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/apps/essimporter/converter.cpp b/apps/essimporter/converter.cpp
index 874b936baf..6e79e27f18 100644
--- a/apps/essimporter/converter.cpp
+++ b/apps/essimporter/converter.cpp
@@ -2,7 +2,6 @@
 
 #include <stdexcept>
 #include <algorithm>
-#include <climits> // INT_MIN
 
 #include <osgDB/WriteFile>
 
@@ -371,7 +370,7 @@ namespace ESSImport
                     if (cellref.mHasACDT)
                         convertACDT(cellref.mACDT, objstate.mCreatureStats);
                     else
-                        objstate.mCreatureStats.mGoldPool = INT_MIN; // HACK: indicates no ACDT
+                        objstate.mCreatureStats.mMissingACDT = true;
                     if (cellref.mHasACSC)
                         convertACSC(cellref.mACSC, objstate.mCreatureStats);
                     convertNpcData(cellref, objstate.mNpcStats);
@@ -414,7 +413,7 @@ namespace ESSImport
                     if (cellref.mHasACDT)
                         convertACDT(cellref.mACDT, objstate.mCreatureStats);
                     else
-                        objstate.mCreatureStats.mGoldPool = INT_MIN; // HACK: indicates no ACDT
+                        objstate.mCreatureStats.mMissingACDT = true;
                     if (cellref.mHasACSC)
                         convertACSC(cellref.mACSC, objstate.mCreatureStats);
                     convertCREC(crecIt->second, objstate);
diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp
index 0b3ffa924f..03b7cfb069 100644
--- a/apps/openmw/mwclass/creature.cpp
+++ b/apps/openmw/mwclass/creature.cpp
@@ -1,7 +1,5 @@
 #include "creature.hpp"
 
-#include <climits> // INT_MIN
-
 #include <components/misc/rng.hpp>
 #include <components/debug/debuglog.hpp>
 #include <components/esm/loadcrea.hpp>
@@ -758,9 +756,7 @@ namespace MWClass
         {
             if (!ptr.getRefData().getCustomData())
             {
-                // FIXME: the use of mGoldPool can be replaced with another flag the next time
-                // the save file format is changed
-                if (creatureState.mCreatureStats.mGoldPool == INT_MIN)
+                if (creatureState.mCreatureStats.mMissingACDT)
                     ensureCustomData(ptr);
                 else
                 {
diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp
index 5d50ba558f..c46e3c0534 100644
--- a/apps/openmw/mwclass/npc.cpp
+++ b/apps/openmw/mwclass/npc.cpp
@@ -1,7 +1,6 @@
 #include "npc.hpp"
 
 #include <memory>
-#include <climits> // INT_MIN
 
 #include <components/misc/constants.hpp>
 #include <components/misc/rng.hpp>
@@ -1302,9 +1301,7 @@ namespace MWClass
         {
             if (!ptr.getRefData().getCustomData())
             {
-                // FIXME: the use of mGoldPool can be replaced with another flag the next time
-                // the save file format is changed
-                if (npcState.mCreatureStats.mGoldPool == INT_MIN)
+                if (npcState.mCreatureStats.mMissingACDT)
                     ensureCustomData(ptr);
                 else
                     // Create a CustomData, but don't fill it from ESM records (not needed)
diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp
index d832c47c87..c99f87e833 100644
--- a/apps/openmw/mwmechanics/creaturestats.cpp
+++ b/apps/openmw/mwmechanics/creaturestats.cpp
@@ -1,7 +1,6 @@
 #include "creaturestats.hpp"
 
 #include <algorithm>
-#include <climits>
 
 #include <components/esm/creaturestats.hpp>
 #include <components/esm/esmreader.hpp>
@@ -558,12 +557,13 @@ namespace MWMechanics
         state.mHasAiSettings = true;
         for (int i=0; i<4; ++i)
             mAiSettings[i].writeState (state.mAiSettings[i]);
+
+        state.mMissingACDT = false;
     }
 
     void CreatureStats::readState (const ESM::CreatureStats& state)
     {
-        // HACK: using mGoldPool as an indicator for lack of ACDT during .ess import
-        if (state.mGoldPool != INT_MIN)
+        if (!state.mMissingACDT)
         {
             for (int i=0; i<ESM::Attribute::Length; ++i)
                 mAttributes[i].readState (state.mAttributes[i]);
diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp
index e5c4f6fa41..0543a31ba2 100644
--- a/apps/openmw/mwmechanics/creaturestats.hpp
+++ b/apps/openmw/mwmechanics/creaturestats.hpp
@@ -69,8 +69,6 @@ namespace MWMechanics
         MWWorld::TimeStamp mLastRestock;
 
         // The pool of merchant gold (not in inventory)
-        // HACK: value of INT_MIN has a special meaning: indicates a converted .ess file
-        //       (this is a workaround to avoid changing the save file format)
         int mGoldPool;
 
         int mActorId;
diff --git a/components/esm/creaturestats.cpp b/components/esm/creaturestats.cpp
index d5030a6580..ee4b0ad092 100644
--- a/components/esm/creaturestats.cpp
+++ b/components/esm/creaturestats.cpp
@@ -1,6 +1,9 @@
 #include "creaturestats.hpp"
 #include "esmreader.hpp"
 #include "esmwriter.hpp"
+#include "savedgame.hpp"
+
+#include <limits>
 
 void ESM::CreatureStats::load (ESMReader &esm)
 {
@@ -163,6 +166,13 @@ void ESM::CreatureStats::load (ESMReader &esm)
 
         mCorprusSpells[id] = stats;
     }
+    if(esm.getFormat() <= 18)
+        mMissingACDT = mGoldPool == std::numeric_limits<int>::min();
+    else
+    {
+        mMissingACDT = false;
+        esm.getHNOT(mMissingACDT, "NOAC");
+    }
 }
 
 void ESM::CreatureStats::save (ESMWriter &esm) const
@@ -173,8 +183,10 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
     for (int i=0; i<3; ++i)
         mDynamic[i].save (esm);
 
-    if (mGoldPool)
-        esm.writeHNT ("GOLD", mGoldPool);
+    if (ESM::SavedGame::sCurrentFormat <= 18 && mMissingACDT)
+        esm.writeHNT("GOLD", std::numeric_limits<int>::min());
+    else if(mGoldPool)
+        esm.writeHNT("GOLD", mGoldPool);
 
     if (mTradeTime.mDay != 0 || mTradeTime.mHour != 0)
         esm.writeHNT ("TIME", mTradeTime);
@@ -246,6 +258,8 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
         for (int i=0; i<4; ++i)
             mAiSettings[i].save(esm);
     }
+    if(ESM::SavedGame::sCurrentFormat > 18 && mMissingACDT)
+        esm.writeHNT("NOAC", mMissingACDT);
 }
 
 void ESM::CreatureStats::blank()
@@ -274,4 +288,5 @@ void ESM::CreatureStats::blank()
     mDeathAnimation = -1;
     mLevel = 1;
     mCorprusSpells.clear();
+    mMissingACDT = false;
 }
diff --git a/components/esm/creaturestats.hpp b/components/esm/creaturestats.hpp
index 651b126d0e..7b261e3dd3 100644
--- a/components/esm/creaturestats.hpp
+++ b/components/esm/creaturestats.hpp
@@ -85,6 +85,7 @@ namespace ESM
         signed char mDeathAnimation;
         ESM::TimeStamp mTimeOfDeath;
         int mLevel;
+        bool mMissingACDT;
 
         std::map<std::string, CorprusStats> mCorprusSpells;
         SpellState mSpells;