1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-23 15:40:42 +00:00

Merge branch 'ESSImporter-ACDT-fix' into 'master'

ESSImporter - Fix/workaround for Issue #3246

See merge request OpenMW/openmw!1150
This commit is contained in:
psi29a 2021-08-17 08:17:48 +00:00
commit 76d867bb23
6 changed files with 51 additions and 18 deletions

View File

@ -1,6 +1,7 @@
0.48.0
------
Bug #3246: ESSImporter: Most NPCs are dead on save load
Bug #3514: Editing a reference's position after loading an esp file makes the reference disappear
Bug #3737: Scripts from The Underground 2 .esp do not play (all patched versions)
Bug #3846: Strings starting with "-" fail to compile if not enclosed in quotes

View File

@ -2,6 +2,7 @@
#include <stdexcept>
#include <algorithm>
#include <climits> // INT_MIN
#include <osgDB/WriteFile>
@ -369,6 +370,8 @@ namespace ESSImport
// from the ESM with default values
if (cellref.mHasACDT)
convertACDT(cellref.mACDT, objstate.mCreatureStats);
else
objstate.mCreatureStats.mGoldPool = INT_MIN; // HACK: indicates no ACDT
if (cellref.mHasACSC)
convertACSC(cellref.mACSC, objstate.mCreatureStats);
convertNpcData(cellref, objstate.mNpcStats);
@ -410,6 +413,8 @@ namespace ESSImport
// from the ESM with default values
if (cellref.mHasACDT)
convertACDT(cellref.mACDT, objstate.mCreatureStats);
else
objstate.mCreatureStats.mGoldPool = INT_MIN; // HACK: indicates no ACDT
if (cellref.mHasACSC)
convertACSC(cellref.mACSC, objstate.mCreatureStats);
convertCREC(crecIt->second, objstate);

View File

@ -1,5 +1,7 @@
#include "creature.hpp"
#include <climits> // INT_MIN
#include <components/misc/rng.hpp>
#include <components/debug/debuglog.hpp>
#include <components/esm/loadcrea.hpp>
@ -748,26 +750,35 @@ namespace MWClass
if (!state.mHasCustomState)
return;
const ESM::CreatureState& creatureState = state.asCreatureState();
if (state.mVersion > 0)
{
if (!ptr.getRefData().getCustomData())
{
// Create a CustomData, but don't fill it from ESM records (not needed)
std::unique_ptr<CreatureCustomData> data (new CreatureCustomData);
if (hasInventoryStore(ptr))
data->mContainerStore = std::make_unique<MWWorld::InventoryStore>();
// 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)
ensureCustomData(ptr);
else
data->mContainerStore = std::make_unique<MWWorld::ContainerStore>();
{
// Create a CustomData, but don't fill it from ESM records (not needed)
std::unique_ptr<CreatureCustomData> data (new CreatureCustomData);
ptr.getRefData().setCustomData (std::move(data));
if (hasInventoryStore(ptr))
data->mContainerStore = std::make_unique<MWWorld::InventoryStore>();
else
data->mContainerStore = std::make_unique<MWWorld::ContainerStore>();
ptr.getRefData().setCustomData (std::move(data));
}
}
}
else
ensureCustomData(ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless.
CreatureCustomData& customData = ptr.getRefData().getCustomData()->asCreatureCustomData();
const ESM::CreatureState& creatureState = state.asCreatureState();
customData.mContainerStore->readState (creatureState.mInventory);
bool spellsInitialised = customData.mCreatureStats.getSpells().setSpells(ptr.get<ESM::Creature>()->mBase->mId);
if(spellsInitialised)

View File

@ -1,6 +1,7 @@
#include "npc.hpp"
#include <memory>
#include <climits> // INT_MIN
#include <components/misc/constants.hpp>
#include <components/misc/rng.hpp>
@ -1291,19 +1292,26 @@ namespace MWClass
if (!state.mHasCustomState)
return;
const ESM::NpcState& npcState = state.asNpcState();
if (state.mVersion > 0)
{
if (!ptr.getRefData().getCustomData())
{
// Create a CustomData, but don't fill it from ESM records (not needed)
ptr.getRefData().setCustomData(std::make_unique<NpcCustomData>());
// 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)
ensureCustomData(ptr);
else
// Create a CustomData, but don't fill it from ESM records (not needed)
ptr.getRefData().setCustomData(std::make_unique<NpcCustomData>());
}
}
else
ensureCustomData(ptr); // in openmw 0.30 savegames not all state was saved yet, so need to load it regardless.
NpcCustomData& customData = ptr.getRefData().getCustomData()->asNpcCustomData();
const ESM::NpcState& npcState = state.asNpcState();
customData.mInventoryStore.readState (npcState.mInventory);
customData.mNpcStats.readState (npcState.mNpcStats);
bool spellsInitialised = customData.mNpcStats.getSpells().setSpells(ptr.get<ESM::NPC>()->mBase->mId);

View File

@ -1,6 +1,7 @@
#include "creaturestats.hpp"
#include <algorithm>
#include <climits>
#include <components/esm/creaturestats.hpp>
#include <components/esm/esmreader.hpp>
@ -562,22 +563,27 @@ namespace MWMechanics
void CreatureStats::readState (const ESM::CreatureStats& state)
{
for (int i=0; i<ESM::Attribute::Length; ++i)
mAttributes[i].readState (state.mAttributes[i]);
// HACK: using mGoldPool as an indicator for lack of ACDT during .ess import
if (state.mGoldPool != INT_MIN)
{
for (int i=0; i<ESM::Attribute::Length; ++i)
mAttributes[i].readState (state.mAttributes[i]);
for (int i=0; i<3; ++i)
mDynamic[i].readState (state.mDynamic[i]);
for (int i=0; i<3; ++i)
mDynamic[i].readState (state.mDynamic[i]);
mGoldPool = state.mGoldPool;
mTalkedTo = state.mTalkedTo;
mAttacked = state.mAttacked;
}
mLastRestock = MWWorld::TimeStamp(state.mTradeTime);
mGoldPool = state.mGoldPool;
mDead = state.mDead;
mDeathAnimationFinished = state.mDeathAnimationFinished;
mDied = state.mDied;
mMurdered = state.mMurdered;
mTalkedTo = state.mTalkedTo;
mAlarmed = state.mAlarmed;
mAttacked = state.mAttacked;
// TODO: rewrite. does this really need 3 separate bools?
mKnockdown = state.mKnockdown;
mKnockdownOneFrame = state.mKnockdownOneFrame;

View File

@ -70,6 +70,8 @@ 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;