Merge branch 'reset' into 'master'

AI reset argument

Closes #6177 and #1465

See merge request OpenMW/openmw!1405
This commit is contained in:
psi29a 2021-11-21 09:39:55 +00:00
commit 53e14eb238
22 changed files with 153 additions and 112 deletions

View file

@ -37,7 +37,8 @@ namespace ESM
struct AITravel
{
float mX, mY, mZ;
int mUnk;
unsigned char mShouldRepeat;
unsigned char mPadding[3];
};
struct AITarget
@ -45,13 +46,14 @@ namespace ESM
float mX, mY, mZ;
short mDuration;
NAME32 mId;
short mUnk;
unsigned char mShouldRepeat;
unsigned char mPadding;
};
struct AIActivate
{
NAME32 mName;
unsigned char mUnk;
unsigned char mShouldRepeat;
};
#pragma pack(pop)

View file

@ -3,6 +3,7 @@
#include "esmreader.hpp"
#include "esmwriter.hpp"
#include <algorithm>
#include <memory>
namespace ESM
@ -34,12 +35,16 @@ namespace AiSequence
{
esm.getHNT (mData, "DATA");
esm.getHNOT (mHidden, "HIDD");
mRepeat = false;
esm.getHNOT(mRepeat, "REPT");
}
void AiTravel::save(ESMWriter &esm) const
{
esm.writeHNT ("DATA", mData);
esm.writeHNT ("HIDD", mHidden);
if(mRepeat)
esm.writeHNT("REPT", mRepeat);
}
void AiEscort::load(ESMReader &esm)
@ -50,6 +55,15 @@ namespace AiSequence
esm.getHNOT (mTargetActorId, "TAID");
esm.getHNT (mRemainingDuration, "DURA");
mCellId = esm.getHNOString ("CELL");
mRepeat = false;
esm.getHNOT(mRepeat, "REPT");
if(esm.getFormat() < 18)
{
// mDuration isn't saved in the save file, so just giving it "1" for now if the package has a duration.
// The exact value of mDuration only matters for repeating packages.
// Previously mRemainingDuration could be negative even when mDuration was 0. Checking for > 0 should fix old saves.
mData.mDuration = std::max<float>(mRemainingDuration > 0, mRemainingDuration);
}
}
void AiEscort::save(ESMWriter &esm) const
@ -60,6 +74,8 @@ namespace AiSequence
esm.writeHNT ("DURA", mRemainingDuration);
if (!mCellId.empty())
esm.writeHNString ("CELL", mCellId);
if(mRepeat)
esm.writeHNT("REPT", mRepeat);
}
void AiFollow::load(ESMReader &esm)
@ -75,6 +91,15 @@ namespace AiSequence
esm.getHNOT (mCommanded, "CMND");
mActive = false;
esm.getHNOT (mActive, "ACTV");
mRepeat = false;
esm.getHNOT(mRepeat, "REPT");
if(esm.getFormat() < 18)
{
// mDuration isn't saved in the save file, so just giving it "1" for now if the package has a duration.
// The exact value of mDuration only matters for repeating packages.
// Previously mRemainingDuration could be negative even when mDuration was 0. Checking for > 0 should fix old saves.
mData.mDuration = std::max<float>(mRemainingDuration > 0, mRemainingDuration);
}
}
void AiFollow::save(ESMWriter &esm) const
@ -89,16 +114,22 @@ namespace AiSequence
esm.writeHNT ("CMND", mCommanded);
if (mActive)
esm.writeHNT("ACTV", mActive);
if(mRepeat)
esm.writeHNT("REPT", mRepeat);
}
void AiActivate::load(ESMReader &esm)
{
mTargetId = esm.getHNString("TARG");
mRepeat = false;
esm.getHNOT(mRepeat, "REPT");
}
void AiActivate::save(ESMWriter &esm) const
{
esm.writeHNString("TARG", mTargetId);
if(mRepeat)
esm.writeHNT("REPT", mRepeat);
}
void AiCombat::load(ESMReader &esm)
@ -166,6 +197,7 @@ namespace AiSequence
void AiSequence::load(ESMReader &esm)
{
int count = 0;
while (esm.isNextSub("AIPK"))
{
int type;
@ -181,6 +213,7 @@ namespace AiSequence
std::unique_ptr<AiWander> ptr = std::make_unique<AiWander>();
ptr->load(esm);
mPackages.back().mPackage = ptr.release();
++count;
break;
}
case Ai_Travel:
@ -188,6 +221,7 @@ namespace AiSequence
std::unique_ptr<AiTravel> ptr = std::make_unique<AiTravel>();
ptr->load(esm);
mPackages.back().mPackage = ptr.release();
++count;
break;
}
case Ai_Escort:
@ -195,6 +229,7 @@ namespace AiSequence
std::unique_ptr<AiEscort> ptr = std::make_unique<AiEscort>();
ptr->load(esm);
mPackages.back().mPackage = ptr.release();
++count;
break;
}
case Ai_Follow:
@ -202,6 +237,7 @@ namespace AiSequence
std::unique_ptr<AiFollow> ptr = std::make_unique<AiFollow>();
ptr->load(esm);
mPackages.back().mPackage = ptr.release();
++count;
break;
}
case Ai_Activate:
@ -209,6 +245,7 @@ namespace AiSequence
std::unique_ptr<AiActivate> ptr = std::make_unique<AiActivate>();
ptr->load(esm);
mPackages.back().mPackage = ptr.release();
++count;
break;
}
case Ai_Combat:
@ -231,6 +268,23 @@ namespace AiSequence
}
esm.getHNOT (mLastAiPackage, "LAST");
if(count > 1 && esm.getFormat() < 18)
{
for(auto& pkg : mPackages)
{
if(pkg.mType == Ai_Wander)
static_cast<AiWander*>(pkg.mPackage)->mData.mShouldRepeat = true;
else if(pkg.mType == Ai_Travel)
static_cast<AiTravel*>(pkg.mPackage)->mRepeat = true;
else if(pkg.mType == Ai_Escort)
static_cast<AiEscort*>(pkg.mPackage)->mRepeat = true;
else if(pkg.mType == Ai_Follow)
static_cast<AiFollow*>(pkg.mPackage)->mRepeat = true;
else if(pkg.mType == Ai_Activate)
static_cast<AiActivate*>(pkg.mPackage)->mRepeat = true;
}
}
}
}
}

View file

@ -81,6 +81,7 @@ namespace ESM
{
AiTravelData mData;
bool mHidden;
bool mRepeat;
void load(ESMReader &esm);
void save(ESMWriter &esm) const;
@ -94,6 +95,7 @@ namespace ESM
std::string mTargetId;
std::string mCellId;
float mRemainingDuration;
bool mRepeat;
void load(ESMReader &esm);
void save(ESMWriter &esm) const;
@ -112,6 +114,7 @@ namespace ESM
bool mCommanded;
bool mActive;
bool mRepeat;
void load(ESMReader &esm);
void save(ESMWriter &esm) const;
@ -120,6 +123,7 @@ namespace ESM
struct AiActivate : AiPackage
{
std::string mTargetId;
bool mRepeat;
void load(ESMReader &esm);
void save(ESMWriter &esm) const;

View file

@ -4,7 +4,7 @@
#include "esmwriter.hpp"
unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE;
int ESM::SavedGame::sCurrentFormat = 17;
int ESM::SavedGame::sCurrentFormat = 18;
void ESM::SavedGame::load (ESMReader &esm)
{