Commit 5d209068 authored by Allofich's avatar Allofich

Store mHitAttemptActorId in save files

parent 25c64dbb
......@@ -343,16 +343,16 @@ namespace MWClass
{
MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker);
// First handle the attacked actor
if (stats.getHitAttemptActor().isEmpty()
if ((stats.getHitAttemptActorId() == -1)
&& (statsAttacker.getAiSequence().isInCombat(ptr)
|| attacker == MWMechanics::getPlayer()))
stats.setHitAttemptActor(attacker);
stats.setHitAttemptActorId(statsAttacker.getActorId());
// Next handle the attacking actor
if (statsAttacker.getHitAttemptActor().isEmpty()
if ((statsAttacker.getHitAttemptActorId() == -1)
&& (statsAttacker.getAiSequence().isInCombat(ptr)
|| attacker == MWMechanics::getPlayer()))
statsAttacker.setHitAttemptActor(ptr);
statsAttacker.setHitAttemptActorId(stats.getActorId());
}
if (!object.isEmpty())
......
......@@ -672,16 +672,16 @@ namespace MWClass
{
MWMechanics::CreatureStats& statsAttacker = attacker.getClass().getCreatureStats(attacker);
// First handle the attacked actor
if (stats.getHitAttemptActor().isEmpty()
if ((stats.getHitAttemptActorId() == -1)
&& (statsAttacker.getAiSequence().isInCombat(ptr)
|| attacker == MWMechanics::getPlayer()))
stats.setHitAttemptActor(attacker);
stats.setHitAttemptActorId(statsAttacker.getActorId());
// Next handle the attacking actor
if (statsAttacker.getHitAttemptActor().isEmpty()
if ((statsAttacker.getHitAttemptActorId() == -1)
&& (statsAttacker.getAiSequence().isInCombat(ptr)
|| attacker == MWMechanics::getPlayer()))
statsAttacker.setHitAttemptActor(ptr);
statsAttacker.setHitAttemptActorId(stats.getActorId());
}
if (!object.isEmpty())
......
......@@ -314,13 +314,12 @@ namespace MWMechanics
if (creatureStats1.getAiSequence().isInCombat(*it))
continue;
if (!it->getClass().getCreatureStats(*it).getHitAttemptActor().isEmpty()
&& it->getClass().getCreatureStats(*it).getHitAttemptActor() == actor2)
if (creatureStats2.matchesActorId(it->getClass().getCreatureStats(*it).getHitAttemptActorId()))
{
MWBase::Environment::get().getMechanicsManager()->startCombat(actor1, actor2);
// Also set the same hit attempt actor. Otherwise, if fighting the player, they may stop combat
// if the player gets out of reach, while the ally would continue combat with the player
creatureStats1.setHitAttemptActor(actor2);
creatureStats1.setHitAttemptActorId(it->getClass().getCreatureStats(*it).getHitAttemptActorId());
return;
}
......@@ -963,7 +962,7 @@ namespace MWMechanics
if (player.getClass().getNpcStats(player).getBounty() >= cutoff * iCrimeThresholdMultiplier)
{
MWBase::Environment::get().getMechanicsManager()->startCombat(ptr, player);
creatureStats.setHitAttemptActor(player); // Stops the guard from quitting combat if player is unreachable
creatureStats.setHitAttemptActorId(player.getClass().getCreatureStats(player).getActorId()); // Stops the guard from quitting combat if player is unreachable
}
else
creatureStats.getAiSequence().stack(AiPursue(player), ptr);
......@@ -1092,9 +1091,9 @@ namespace MWMechanics
|| !iter->first.getClass().getCreatureStats(iter->first).getAiSequence().isInCombat()
|| !inProcessingRange))
{
iter->first.getClass().getCreatureStats(iter->first).setHitAttemptActor(NULL);
if (player.getClass().getCreatureStats(player).getHitAttemptActor() == iter->first)
player.getClass().getCreatureStats(player).setHitAttemptActor(NULL);
iter->first.getClass().getCreatureStats(iter->first).setHitAttemptActorId(-1);
if (player.getClass().getCreatureStats(player).getHitAttemptActorId() == iter->first.getClass().getCreatureStats(iter->first).getActorId())
player.getClass().getCreatureStats(player).setHitAttemptActorId(-1);
}
const MWWorld::Ptr playerHitAttemptActor = MWBase::Environment::get().getWorld()->searchPtrViaActorId(player.getClass().getCreatureStats(player).getHitAttemptActorId());
......
......@@ -238,8 +238,8 @@ namespace MWMechanics
const std::list<MWWorld::Ptr>& playerFollowersAndEscorters = MWBase::Environment::get().getMechanicsManager()->getActorsSidingWith(MWMechanics::getPlayer());
bool targetSidesWithPlayer = (std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), target) != playerFollowersAndEscorters.end());
if ((target == MWMechanics::getPlayer() || targetSidesWithPlayer)
&& ((actor.getClass().getCreatureStats(actor).getHitAttemptActor() == target)
|| (target.getClass().getCreatureStats(target).getHitAttemptActor() == actor)))
&& ((actor.getClass().getCreatureStats(actor).getHitAttemptActorId() == target.getClass().getCreatureStats(target).getActorId())
|| (target.getClass().getCreatureStats(target).getHitAttemptActorId() == actor.getClass().getCreatureStats(actor).getActorId())))
forceFlee = true;
else // Otherwise end combat
return true;
......
......@@ -21,7 +21,7 @@ namespace MWMechanics
mTalkedTo (false), mAlarmed (false), mAttacked (false),
mKnockdown(false), mKnockdownOneFrame(false), mKnockdownOverOneFrame(false),
mHitRecovery(false), mBlock(false), mMovementFlags(0),
mFallHeight(0), mRecalcMagicka(false), mLastRestock(0,0), mGoldPool(0), mActorId(-1),
mFallHeight(0), mRecalcMagicka(false), mLastRestock(0,0), mGoldPool(0), mActorId(-1), mHitAttemptActorId(-1),
mDeathAnimation(-1), mTimeOfDeath(), mLevel (0)
{
for (int i=0; i<4; ++i)
......@@ -371,14 +371,14 @@ namespace MWMechanics
return mLastHitAttemptObject;
}
void CreatureStats::setHitAttemptActor(const MWWorld::Ptr& actor)
void CreatureStats::setHitAttemptActorId(int actorId)
{
mHitAttemptActor = actor;
mHitAttemptActorId = actorId;
}
const MWWorld::Ptr &CreatureStats::getHitAttemptActor() const
int CreatureStats::getHitAttemptActorId() const
{
return mHitAttemptActor;
return mHitAttemptActorId;
}
void CreatureStats::addToFallHeight(float height)
......@@ -531,6 +531,7 @@ namespace MWMechanics
state.mActorId = mActorId;
state.mDeathAnimation = mDeathAnimation;
state.mTimeOfDeath = mTimeOfDeath.toEsm();
state.mHitAttemptActorId = mHitAttemptActorId;
mSpells.writeState(state.mSpells);
mActiveSpells.writeState(state.mActiveSpells);
......@@ -579,6 +580,7 @@ namespace MWMechanics
mActorId = state.mActorId;
mDeathAnimation = state.mDeathAnimation;
mTimeOfDeath = MWWorld::TimeStamp(state.mTimeOfDeath);
mHitAttemptActorId = state.mHitAttemptActorId;
mSpells.readState(state.mSpells);
mActiveSpells.readState(state.mActiveSpells);
......
......@@ -53,9 +53,6 @@ namespace MWMechanics
std::string mLastHitObject; // The last object to hit this actor
std::string mLastHitAttemptObject; // The last object to attempt to hit this actor
MWWorld::Ptr mHitAttemptActor; // Stores an actor that attacked this actor. Only one is stored at a time,
// and it is not changed if a different actor attacks. It is cleared when combat ends.
bool mRecalcMagicka;
// For merchants: the last time items were restocked and gold pool refilled.
......@@ -65,6 +62,8 @@ namespace MWMechanics
int mGoldPool;
int mActorId;
int mHitAttemptActorId; // Stores an actor that attacked this actor. Only one is stored at a time,
// and it is not changed if a different actor attacks. It is cleared when combat ends.
// The index of the death animation that was played, or -1 if none played
signed char mDeathAnimation;
......@@ -247,8 +246,8 @@ namespace MWMechanics
const std::string &getLastHitObject() const;
void setLastHitAttemptObject(const std::string &objectid);
const std::string &getLastHitAttemptObject() const;
void setHitAttemptActor(const MWWorld::Ptr &actor);
const MWWorld::Ptr &getHitAttemptActor() const;
void setHitAttemptActorId(const int actorId);
int getHitAttemptActorId() const;
// Note, this is just a cache to avoid checking the whole container store every frame. We don't need to store it in saves.
// TODO: Put it somewhere else?
......
......@@ -1368,7 +1368,7 @@ namespace MWMechanics
// if guard starts combat with player, guards pursuing player should do the same
if (ptr.getClass().isClass(ptr, "Guard"))
{
ptr.getClass().getCreatureStats(ptr).setHitAttemptActor(target); // Stops guard from ending combat if player is unreachable
ptr.getClass().getCreatureStats(ptr).setHitAttemptActorId(target.getClass().getCreatureStats(target).getActorId()); // Stops guard from ending combat if player is unreachable
for (Actors::PtrActorMap::const_iterator iter = mActors.begin(); iter != mActors.end(); ++iter)
{
if (iter->first.getClass().isClass(iter->first, "Guard"))
......@@ -1378,7 +1378,7 @@ namespace MWMechanics
{
aiSeq.stopPursuit();
aiSeq.stack(MWMechanics::AiCombat(target), ptr);
iter->first.getClass().getCreatureStats(iter->first).setHitAttemptActor(target); // Stops guard from ending combat if player is unreachable
iter->first.getClass().getCreatureStats(iter->first).setHitAttemptActorId(target.getClass().getCreatureStats(target).getActorId()); // Stops guard from ending combat if player is unreachable
}
}
}
......
......@@ -90,6 +90,9 @@ void ESM::CreatureStats::load (ESMReader &esm)
mActorId = -1;
esm.getHNOT (mActorId, "ACID");
mHitAttemptActorId = -1;
esm.getHNOT(mHitAttemptActorId, "HAID");
mDeathAnimation = -1;
esm.getHNOT (mDeathAnimation, "DANM");
......@@ -203,6 +206,9 @@ void ESM::CreatureStats::save (ESMWriter &esm) const
if (mActorId != -1)
esm.writeHNT ("ACID", mActorId);
if (mHitAttemptActorId != -1)
esm.writeHNT("HAID", mHitAttemptActorId);
if (mDeathAnimation != -1)
esm.writeHNT ("DANM", mDeathAnimation);
......@@ -240,6 +246,7 @@ void ESM::CreatureStats::blank()
mTradeTime.mDay = 0;
mGoldPool = 0;
mActorId = -1;
mHitAttemptActorId = -1;
mHasAiSettings = false;
mDead = false;
mDeathAnimationFinished = false;
......
......@@ -38,6 +38,7 @@ namespace ESM
ESM::TimeStamp mTradeTime;
int mGoldPool;
int mActorId;
int mHitAttemptActorId;
bool mDead;
bool mDeathAnimationFinished;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment