mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 20:26:48 +00:00 
			
		
		
		
	Store integer actor ID in AI packages (bug #4036)
This commit is contained in:
		
							parent
							
								
									9d0ce25052
								
							
						
					
					
						commit
						fed10e87aa
					
				
					 16 changed files with 93 additions and 72 deletions
				
			
		|  | @ -1,6 +1,7 @@ | |||
| 0.45.0 | ||||
| ------ | ||||
|     Bug #2835: Player able to slowly move when overencumbered | ||||
|     Bug #4036: Weird behaviour of AI packages if package target has non-unique ID | ||||
|     Bug #4221: Characters get stuck in V-shaped terrain | ||||
|     Bug #4293: Faction members are not aware of faction ownerships in barter | ||||
|     Bug #4327: Missing animations during spell/weapon stance switching | ||||
|  |  | |||
|  | @ -103,9 +103,10 @@ namespace MWMechanics | |||
|         bool isFleeing(); | ||||
|     }; | ||||
|      | ||||
|     AiCombat::AiCombat(const MWWorld::Ptr& actor) : | ||||
|         mTargetActorId(actor.getClass().getCreatureStats(actor).getActorId()) | ||||
|     {} | ||||
|     AiCombat::AiCombat(const MWWorld::Ptr& actor) | ||||
|     { | ||||
|         mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId(); | ||||
|     } | ||||
| 
 | ||||
|     AiCombat::AiCombat(const ESM::AiSequence::AiCombat *combat) | ||||
|     { | ||||
|  |  | |||
|  | @ -54,9 +54,6 @@ namespace MWMechanics | |||
|             virtual bool shouldCancelPreviousAi() const { return false; } | ||||
| 
 | ||||
|         private: | ||||
| 
 | ||||
|             int mTargetActorId; | ||||
| 
 | ||||
|             /// Returns true if combat should end
 | ||||
|             bool attack(const MWWorld::Ptr& actor, const MWWorld::Ptr& target, AiCombatStorage& storage, CharacterController& characterController); | ||||
| 
 | ||||
|  |  | |||
|  | @ -22,28 +22,32 @@ | |||
| namespace MWMechanics | ||||
| { | ||||
|     AiEscort::AiEscort(const std::string &actorId, int duration, float x, float y, float z) | ||||
|     : mActorId(actorId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast<float>(duration)) | ||||
|     : mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast<float>(duration)) | ||||
|     , mCellX(std::numeric_limits<int>::max()) | ||||
|     , mCellY(std::numeric_limits<int>::max()) | ||||
|     { | ||||
|         mTargetActorRefId = actorId; | ||||
|         mMaxDist = 450; | ||||
|     } | ||||
| 
 | ||||
|     AiEscort::AiEscort(const std::string &actorId, const std::string &cellId,int duration, float x, float y, float z) | ||||
|     : mActorId(actorId), mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast<float>(duration)) | ||||
|     AiEscort::AiEscort(const std::string &actorId, const std::string &cellId, int duration, float x, float y, float z) | ||||
|     : mCellId(cellId), mX(x), mY(y), mZ(z), mDuration(duration), mRemainingDuration(static_cast<float>(duration)) | ||||
|     , mCellX(std::numeric_limits<int>::max()) | ||||
|     , mCellY(std::numeric_limits<int>::max()) | ||||
|     { | ||||
|         mTargetActorRefId = actorId; | ||||
|         mMaxDist = 450; | ||||
|     } | ||||
| 
 | ||||
|     AiEscort::AiEscort(const ESM::AiSequence::AiEscort *escort) | ||||
|         : mActorId(escort->mTargetId), mCellId(escort->mCellId), mX(escort->mData.mX), mY(escort->mData.mY), mZ(escort->mData.mZ) | ||||
|         : mCellId(escort->mCellId), mX(escort->mData.mX), mY(escort->mData.mY), mZ(escort->mData.mZ) | ||||
|         , mMaxDist(450) | ||||
|         , mRemainingDuration(escort->mRemainingDuration) | ||||
|         , mCellX(std::numeric_limits<int>::max()) | ||||
|         , mCellY(std::numeric_limits<int>::max()) | ||||
|     { | ||||
|         mTargetActorRefId = escort->mTargetId; | ||||
|         mTargetActorId = escort->mTargetActorId; | ||||
|         // 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.
 | ||||
|         if (mRemainingDuration > 0) // Previously mRemainingDuration could be negative even when mDuration was 0. Checking for > 0 should fix old saves.
 | ||||
|  | @ -78,7 +82,7 @@ namespace MWMechanics | |||
|         actor.getClass().getCreatureStats(actor).setDrawState(DrawState_Nothing); | ||||
|         actor.getClass().getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, false); | ||||
| 
 | ||||
|         const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mActorId, false); | ||||
|         const MWWorld::Ptr follower = MWBase::Environment::get().getWorld()->getPtr(mTargetActorRefId, false); | ||||
|         const float* const leaderPos = actor.getRefData().getPosition().pos; | ||||
|         const float* const followerPos = follower.getRefData().getPosition().pos; | ||||
|         double differenceBetween[3]; | ||||
|  | @ -119,18 +123,14 @@ namespace MWMechanics | |||
|         return TypeIdEscort; | ||||
|     } | ||||
| 
 | ||||
|     MWWorld::Ptr AiEscort::getTarget() const | ||||
|     { | ||||
|         return MWBase::Environment::get().getWorld()->getPtr(mActorId, false); | ||||
|     } | ||||
| 
 | ||||
|     void AiEscort::writeState(ESM::AiSequence::AiSequence &sequence) const | ||||
|     { | ||||
|         std::unique_ptr<ESM::AiSequence::AiEscort> escort(new ESM::AiSequence::AiEscort()); | ||||
|         escort->mData.mX = mX; | ||||
|         escort->mData.mY = mY; | ||||
|         escort->mData.mZ = mZ; | ||||
|         escort->mTargetId = mActorId; | ||||
|         escort->mTargetId = mTargetActorRefId; | ||||
|         escort->mTargetActorId = mTargetActorId; | ||||
|         escort->mRemainingDuration = mRemainingDuration; | ||||
|         escort->mCellId = mCellId; | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,11 +24,11 @@ namespace MWMechanics | |||
|             /// Implementation of AiEscort
 | ||||
|             /** The Actor will escort the specified actor to the world position x, y, z until they reach their position, or they run out of time
 | ||||
|                 \implement AiEscort **/ | ||||
|             AiEscort(const std::string &actorId,int duration, float x, float y, float z); | ||||
|             AiEscort(const std::string &actorId, int duration, float x, float y, float z); | ||||
|             /// Implementation of AiEscortCell
 | ||||
|             /** The Actor will escort the specified actor to the cell position x, y, z until they reach their position, or they run out of time
 | ||||
|                 \implement AiEscortCell **/ | ||||
|             AiEscort(const std::string &actorId,const std::string &cellId,int duration, float x, float y, float z); | ||||
|             AiEscort(const std::string &actorId, const std::string &cellId, int duration, float x, float y, float z); | ||||
| 
 | ||||
|             AiEscort(const ESM::AiSequence::AiEscort* escort); | ||||
| 
 | ||||
|  | @ -38,7 +38,6 @@ namespace MWMechanics | |||
| 
 | ||||
|             virtual int getTypeId() const; | ||||
| 
 | ||||
|             MWWorld::Ptr getTarget() const; | ||||
|             virtual bool sideWithTarget() const { return true; } | ||||
| 
 | ||||
|             void writeState(ESM::AiSequence::AiSequence &sequence) const; | ||||
|  | @ -46,7 +45,6 @@ namespace MWMechanics | |||
|             void fastForward(const MWWorld::Ptr& actor, AiState& state); | ||||
| 
 | ||||
|         private: | ||||
|             std::string mActorId; | ||||
|             std::string mCellId; | ||||
|             float mX; | ||||
|             float mY; | ||||
|  |  | |||
|  | @ -35,32 +35,53 @@ struct AiFollowStorage : AiTemporaryBase | |||
| 
 | ||||
| int AiFollow::mFollowIndexCounter = 0; | ||||
| 
 | ||||
| AiFollow::AiFollow(const std::string &actorId,float duration, float x, float y, float z) | ||||
| AiFollow::AiFollow(const std::string &actorId, float duration, float x, float y, float z) | ||||
| : mAlwaysFollow(false), mCommanded(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z) | ||||
| , mActorRefId(actorId), mActorId(-1), mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++) | ||||
| , mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++) | ||||
| { | ||||
|     mTargetActorRefId = actorId; | ||||
| } | ||||
| 
 | ||||
| AiFollow::AiFollow(const std::string &actorId,const std::string &cellId,float duration, float x, float y, float z) | ||||
| AiFollow::AiFollow(const std::string &actorId, const std::string &cellId, float duration, float x, float y, float z) | ||||
| : mAlwaysFollow(false), mCommanded(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z) | ||||
| , mActorRefId(actorId), mActorId(-1), mCellId(cellId), mActive(false), mFollowIndex(mFollowIndexCounter++) | ||||
| , mCellId(cellId), mActive(false), mFollowIndex(mFollowIndexCounter++) | ||||
| { | ||||
|     mTargetActorRefId = actorId; | ||||
| } | ||||
| 
 | ||||
| AiFollow::AiFollow(const std::string &actorId, bool commanded) | ||||
| AiFollow::AiFollow(const MWWorld::Ptr& actor, float duration, float x, float y, float z) | ||||
| : mAlwaysFollow(false), mCommanded(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z) | ||||
| , mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++) | ||||
| { | ||||
|     mTargetActorRefId = actor.getCellRef().getRefId(); | ||||
|     mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId(); | ||||
| } | ||||
| 
 | ||||
| AiFollow::AiFollow(const MWWorld::Ptr& actor, const std::string &cellId, float duration, float x, float y, float z) | ||||
| : mAlwaysFollow(false), mCommanded(false), mDuration(duration), mRemainingDuration(duration), mX(x), mY(y), mZ(z) | ||||
| , mCellId(cellId), mActive(false), mFollowIndex(mFollowIndexCounter++) | ||||
| { | ||||
|     mTargetActorRefId = actor.getCellRef().getRefId(); | ||||
|     mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId(); | ||||
| } | ||||
| 
 | ||||
| AiFollow::AiFollow(const MWWorld::Ptr& actor, bool commanded) | ||||
| : mAlwaysFollow(true), mCommanded(commanded), mDuration(0), mRemainingDuration(0), mX(0), mY(0), mZ(0) | ||||
| , mActorRefId(actorId), mActorId(-1), mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++) | ||||
| , mCellId(""), mActive(false), mFollowIndex(mFollowIndexCounter++) | ||||
| { | ||||
|     mTargetActorRefId = actor.getCellRef().getRefId(); | ||||
|     mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId(); | ||||
| } | ||||
| 
 | ||||
| AiFollow::AiFollow(const ESM::AiSequence::AiFollow *follow) | ||||
|     : mAlwaysFollow(follow->mAlwaysFollow), mCommanded(follow->mCommanded), mRemainingDuration(follow->mRemainingDuration) | ||||
|     , mX(follow->mData.mX), mY(follow->mData.mY), mZ(follow->mData.mZ) | ||||
|     , mActorRefId(follow->mTargetId), mActorId(-1) | ||||
|     , mCellId(follow->mCellId), mActive(follow->mActive), mFollowIndex(mFollowIndexCounter++) | ||||
| { | ||||
| // mDuration isn't saved in the save file, so just giving it "1" for now if the package had a duration.
 | ||||
| // The exact value of mDuration only matters for repeating packages.
 | ||||
|     mTargetActorRefId = follow->mTargetId; | ||||
|     mTargetActorId = follow->mTargetActorId; | ||||
|     // mDuration isn't saved in the save file, so just giving it "1" for now if the package had a duration.
 | ||||
|     // The exact value of mDuration only matters for repeating packages.
 | ||||
|     if (mRemainingDuration > 0) // Previously mRemainingDuration could be negative even when mDuration was 0. Checking for > 0 should fix old saves.
 | ||||
|        mDuration = 1; | ||||
|     else | ||||
|  | @ -204,7 +225,7 @@ bool AiFollow::execute (const MWWorld::Ptr& actor, CharacterController& characte | |||
| 
 | ||||
| std::string AiFollow::getFollowedActor() | ||||
| { | ||||
|     return mActorRefId; | ||||
|     return mTargetActorRefId; | ||||
| } | ||||
| 
 | ||||
| AiFollow *MWMechanics::AiFollow::clone() const | ||||
|  | @ -228,7 +249,8 @@ void AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) const | |||
|     follow->mData.mX = mX; | ||||
|     follow->mData.mY = mY; | ||||
|     follow->mData.mZ = mZ; | ||||
|     follow->mTargetId = mActorRefId; | ||||
|     follow->mTargetId = mTargetActorRefId; | ||||
|     follow->mTargetActorId = mTargetActorId; | ||||
|     follow->mRemainingDuration = mRemainingDuration; | ||||
|     follow->mCellId = mCellId; | ||||
|     follow->mAlwaysFollow = mAlwaysFollow; | ||||
|  | @ -241,29 +263,6 @@ void AiFollow::writeState(ESM::AiSequence::AiSequence &sequence) const | |||
|     sequence.mPackages.push_back(package); | ||||
| } | ||||
| 
 | ||||
| MWWorld::Ptr AiFollow::getTarget() const | ||||
| { | ||||
|     if (mActorId == -2) | ||||
|         return MWWorld::Ptr(); | ||||
| 
 | ||||
|     if (mActorId == -1) | ||||
|     { | ||||
|         MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mActorRefId, false); | ||||
|         if (target.isEmpty()) | ||||
|         { | ||||
|             mActorId = -2; | ||||
|             return target; | ||||
|         } | ||||
|         else | ||||
|             mActorId = target.getClass().getCreatureStats(target).getActorId(); | ||||
|     } | ||||
| 
 | ||||
|     if (mActorId != -1) | ||||
|         return MWBase::Environment::get().getWorld()->searchPtrViaActorId(mActorId); | ||||
|     else | ||||
|         return MWWorld::Ptr(); | ||||
| } | ||||
| 
 | ||||
| int AiFollow::getFollowIndex() const | ||||
| { | ||||
|     return mFollowIndex; | ||||
|  |  | |||
|  | @ -25,16 +25,17 @@ namespace MWMechanics | |||
|     class AiFollow : public AiPackage | ||||
|     { | ||||
|         public: | ||||
|             AiFollow(const std::string &actorId, float duration, float x, float y, float z); | ||||
|             AiFollow(const std::string &actorId, const std::string &CellId, float duration, float x, float y, float z); | ||||
|             /// Follow Actor for duration or until you arrive at a world position
 | ||||
|             AiFollow(const std::string &ActorId,float duration, float X, float Y, float Z); | ||||
|             AiFollow(const MWWorld::Ptr& actor, float duration, float X, float Y, float Z); | ||||
|             /// Follow Actor for duration or until you arrive at a position in a cell
 | ||||
|             AiFollow(const std::string &ActorId,const std::string &CellId,float duration, float X, float Y, float Z); | ||||
|             AiFollow(const MWWorld::Ptr& actor, const std::string &CellId, float duration, float X, float Y, float Z); | ||||
|             /// Follow Actor indefinitively
 | ||||
|             AiFollow(const std::string &ActorId, bool commanded=false); | ||||
|             AiFollow(const MWWorld::Ptr& actor, bool commanded=false); | ||||
| 
 | ||||
|             AiFollow(const ESM::AiSequence::AiFollow* follow); | ||||
| 
 | ||||
|             MWWorld::Ptr getTarget() const; | ||||
|             virtual bool sideWithTarget() const { return true; } | ||||
|             virtual bool followTargetThroughDoors() const { return true; } | ||||
|             virtual bool shouldCancelPreviousAi() const { return !mCommanded; } | ||||
|  | @ -66,8 +67,6 @@ namespace MWMechanics | |||
|             float mX; | ||||
|             float mY; | ||||
|             float mZ; | ||||
|             std::string mActorRefId; | ||||
|             mutable int mActorId; | ||||
|             std::string mCellId; | ||||
|             bool mActive; // have we spotted the target?
 | ||||
|             int mFollowIndex; | ||||
|  |  | |||
|  | @ -27,15 +27,36 @@ MWMechanics::AiPackage::~AiPackage() {} | |||
| 
 | ||||
| MWMechanics::AiPackage::AiPackage() :  | ||||
|     mTimer(AI_REACTION_TIME + 1.0f), // to force initial pathbuild
 | ||||
|     mTargetActorRefId(""), | ||||
|     mTargetActorId(-1), | ||||
|     mRotateOnTheRunChecks(0), | ||||
|     mIsShortcutting(false), | ||||
|     mShortcutProhibited(false), mShortcutFailPos() | ||||
|     mShortcutProhibited(false), | ||||
|     mShortcutFailPos() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| MWWorld::Ptr MWMechanics::AiPackage::getTarget() const | ||||
| { | ||||
|     return MWWorld::Ptr(); | ||||
|     if (mTargetActorId == -2) | ||||
|         return MWWorld::Ptr(); | ||||
| 
 | ||||
|     if (mTargetActorId == -1) | ||||
|     { | ||||
|         MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(mTargetActorRefId, false); | ||||
|         if (target.isEmpty()) | ||||
|         { | ||||
|             mTargetActorId = -2; | ||||
|             return target; | ||||
|         } | ||||
|         else | ||||
|             mTargetActorId = target.getClass().getCreatureStats(target).getActorId(); | ||||
|     } | ||||
| 
 | ||||
|     if (mTargetActorId != -1) | ||||
|         return MWBase::Environment::get().getWorld()->searchPtrViaActorId(mTargetActorId); | ||||
|     else | ||||
|         return MWWorld::Ptr(); | ||||
| } | ||||
| 
 | ||||
| bool MWMechanics::AiPackage::sideWithTarget() const | ||||
|  |  | |||
|  | @ -128,6 +128,9 @@ namespace MWMechanics | |||
| 
 | ||||
|             float mTimer; | ||||
| 
 | ||||
|             std::string mTargetActorRefId; | ||||
|             mutable int mTargetActorId; | ||||
| 
 | ||||
|             osg::Vec3f mLastActorPos; | ||||
| 
 | ||||
|             short mRotateOnTheRunChecks; // attempts to check rotation to the pathpoint on the run possibility
 | ||||
|  |  | |||
|  | @ -15,13 +15,13 @@ namespace MWMechanics | |||
| { | ||||
| 
 | ||||
| AiPursue::AiPursue(const MWWorld::Ptr& actor) | ||||
|     : mTargetActorId(actor.getClass().getCreatureStats(actor).getActorId()) | ||||
| { | ||||
|     mTargetActorId = actor.getClass().getCreatureStats(actor).getActorId(); | ||||
| } | ||||
| 
 | ||||
| AiPursue::AiPursue(const ESM::AiSequence::AiPursue *pursue) | ||||
|     : mTargetActorId(pursue->mTargetActorId) | ||||
| { | ||||
|     mTargetActorId = pursue->mTargetActorId; | ||||
| } | ||||
| 
 | ||||
| AiPursue *MWMechanics::AiPursue::clone() const | ||||
|  |  | |||
|  | @ -40,10 +40,6 @@ namespace MWMechanics | |||
| 
 | ||||
|             virtual bool canCancel() const { return false; } | ||||
|             virtual bool shouldCancelPreviousAi() const { return false; } | ||||
| 
 | ||||
|         private: | ||||
| 
 | ||||
|             int mTargetActorId; // The actor to pursue
 | ||||
|     }; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -547,7 +547,7 @@ namespace MWMechanics | |||
|                         || (effectIt->mEffectID == ESM::MagicEffect::CommandCreature && target.getTypeName() == typeid(ESM::Creature).name())) | ||||
|                         && !caster.isEmpty() && caster.getClass().isActor() && target != getPlayer() && magnitude >= target.getClass().getCreatureStats(target).getLevel()) | ||||
|                         { | ||||
|                             MWMechanics::AiFollow package(caster.getCellRef().getRefId(), true); | ||||
|                             MWMechanics::AiFollow package(caster, true); | ||||
|                             target.getClass().getCreatureStats(target).getAiSequence().stack(package, target); | ||||
|                         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -59,7 +59,7 @@ namespace MWMechanics | |||
|                         MWMechanics::CreatureStats& summonedCreatureStats = ref.getPtr().getClass().getCreatureStats(ref.getPtr()); | ||||
| 
 | ||||
|                         // Make the summoned creature follow its master and help in fights
 | ||||
|                         AiFollow package(mActor.getCellRef().getRefId()); | ||||
|                         AiFollow package(mActor); | ||||
|                         summonedCreatureStats.getAiSequence().stack(package, ref.getPtr()); | ||||
|                         creatureActorId = summonedCreatureStats.getActorId(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -46,6 +46,7 @@ namespace AiSequence | |||
|     { | ||||
|         esm.getHNT (mData, "DATA"); | ||||
|         mTargetId = esm.getHNString("TARG"); | ||||
|         esm.getHNOT (mTargetActorId, "TAID"); | ||||
|         esm.getHNT (mRemainingDuration, "DURA"); | ||||
|         mCellId = esm.getHNOString ("CELL"); | ||||
|     } | ||||
|  | @ -54,6 +55,7 @@ namespace AiSequence | |||
|     { | ||||
|         esm.writeHNT ("DATA", mData); | ||||
|         esm.writeHNString ("TARG", mTargetId); | ||||
|         esm.writeHNT ("TAID", mTargetActorId); | ||||
|         esm.writeHNT ("DURA", mRemainingDuration); | ||||
|         if (!mCellId.empty()) | ||||
|             esm.writeHNString ("CELL", mCellId); | ||||
|  | @ -63,6 +65,7 @@ namespace AiSequence | |||
|     { | ||||
|         esm.getHNT (mData, "DATA"); | ||||
|         mTargetId = esm.getHNString("TARG"); | ||||
|         esm.getHNOT (mTargetActorId, "TAID"); | ||||
|         esm.getHNT (mRemainingDuration, "DURA"); | ||||
|         mCellId = esm.getHNOString ("CELL"); | ||||
|         esm.getHNT (mAlwaysFollow, "ALWY"); | ||||
|  | @ -76,6 +79,7 @@ namespace AiSequence | |||
|     { | ||||
|         esm.writeHNT ("DATA", mData); | ||||
|         esm.writeHNString("TARG", mTargetId); | ||||
|         esm.writeHNT ("TAID", mTargetActorId); | ||||
|         esm.writeHNT ("DURA", mRemainingDuration); | ||||
|         if (!mCellId.empty()) | ||||
|             esm.writeHNString ("CELL", mCellId); | ||||
|  |  | |||
|  | @ -89,6 +89,7 @@ namespace ESM | |||
|     { | ||||
|         AiEscortData mData; | ||||
| 
 | ||||
|         int mTargetActorId; | ||||
|         std::string mTargetId; | ||||
|         std::string mCellId; | ||||
|         float mRemainingDuration; | ||||
|  | @ -101,6 +102,7 @@ namespace ESM | |||
|     { | ||||
|         AiEscortData mData; | ||||
| 
 | ||||
|         int mTargetActorId; | ||||
|         std::string mTargetId; | ||||
|         std::string mCellId; | ||||
|         float mRemainingDuration; | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ | |||
| #include "defs.hpp" | ||||
| 
 | ||||
| unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE; | ||||
| int ESM::SavedGame::sCurrentFormat = 3; | ||||
| int ESM::SavedGame::sCurrentFormat = 4; | ||||
| 
 | ||||
| void ESM::SavedGame::load (ESMReader &esm) | ||||
| { | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue