2012-07-22 14:29:54 +00:00
|
|
|
#include "creaturestats.hpp"
|
|
|
|
|
2012-09-13 08:45:32 +00:00
|
|
|
#include <algorithm>
|
|
|
|
|
2014-02-16 14:56:36 +00:00
|
|
|
#include <components/esm/creaturestats.hpp>
|
|
|
|
|
2012-10-01 15:17:04 +00:00
|
|
|
#include "../mwworld/esmstore.hpp"
|
2012-09-13 08:45:32 +00:00
|
|
|
|
|
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
#include "../mwbase/world.hpp"
|
2014-07-21 18:37:14 +00:00
|
|
|
#include "../mwbase/mechanicsmanager.hpp"
|
2012-09-13 08:45:32 +00:00
|
|
|
|
2012-07-22 14:29:54 +00:00
|
|
|
namespace MWMechanics
|
2012-11-15 19:00:27 +00:00
|
|
|
{
|
2014-04-29 13:27:49 +00:00
|
|
|
int CreatureStats::sActorId = 0;
|
|
|
|
|
2012-09-15 15:12:42 +00:00
|
|
|
CreatureStats::CreatureStats()
|
2014-06-17 01:54:41 +00:00
|
|
|
: mLevel (0), mDead (false), mDied (false), mMurdered(false), mFriendlyHits (0),
|
2013-03-18 09:46:45 +00:00
|
|
|
mTalkedTo (false), mAlarmed (false),
|
2014-07-28 14:41:12 +00:00
|
|
|
mAttacked (false),
|
2014-04-03 20:13:14 +00:00
|
|
|
mAttackingOrSpell(false),
|
2013-12-27 20:21:18 +00:00
|
|
|
mIsWerewolf(false),
|
2014-11-28 13:45:35 +00:00
|
|
|
mFallHeight(0), mRecalcMagicka(false), mKnockdown(false), mKnockdownOneFrame(false),
|
2014-05-12 19:04:02 +00:00
|
|
|
mKnockdownOverOneFrame(false), mHitRecovery(false), mBlock(false),
|
|
|
|
mMovementFlags(0), mDrawState (DrawState_Nothing), mAttackStrength(0.f),
|
2014-05-26 17:56:32 +00:00
|
|
|
mLastRestock(0,0), mGoldPool(0), mActorId(-1),
|
|
|
|
mDeathAnimation(0)
|
2012-09-15 15:12:42 +00:00
|
|
|
{
|
2012-11-10 10:38:37 +00:00
|
|
|
for (int i=0; i<4; ++i)
|
|
|
|
mAiSettings[i] = 0;
|
2012-09-15 15:12:42 +00:00
|
|
|
}
|
|
|
|
|
2012-09-04 11:32:35 +00:00
|
|
|
const AiSequence& CreatureStats::getAiSequence() const
|
|
|
|
{
|
|
|
|
return mAiSequence;
|
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2012-09-04 11:32:35 +00:00
|
|
|
AiSequence& CreatureStats::getAiSequence()
|
|
|
|
{
|
2012-11-15 19:00:27 +00:00
|
|
|
return mAiSequence;
|
2012-09-04 11:32:35 +00:00
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
|
|
|
float CreatureStats::getFatigueTerm() const
|
2012-09-13 08:45:32 +00:00
|
|
|
{
|
|
|
|
int max = getFatigue().getModified();
|
|
|
|
int current = getFatigue().getCurrent();
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2012-09-13 08:45:32 +00:00
|
|
|
float normalised = max==0 ? 1 : std::max (0.0f, static_cast<float> (current)/max);
|
|
|
|
|
2012-11-05 17:19:22 +00:00
|
|
|
const MWWorld::Store<ESM::GameSetting> &gmst =
|
|
|
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2012-11-05 17:19:22 +00:00
|
|
|
return gmst.find ("fFatigueBase")->getFloat()
|
|
|
|
- gmst.find ("fFatigueMult")->getFloat() * (1-normalised);
|
2012-09-13 08:45:32 +00:00
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2014-01-03 00:59:15 +00:00
|
|
|
const AttributeValue &CreatureStats::getAttribute(int index) const
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
|
|
|
if (index < 0 || index > 7) {
|
|
|
|
throw std::runtime_error("attribute index is out of range");
|
|
|
|
}
|
2013-08-09 12:14:58 +00:00
|
|
|
return (!mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index]);
|
2012-09-13 08:52:34 +00:00
|
|
|
}
|
|
|
|
|
2012-09-15 15:12:42 +00:00
|
|
|
const DynamicStat<float> &CreatureStats::getHealth() const
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
|
|
|
return mDynamic[0];
|
|
|
|
}
|
|
|
|
|
2012-09-15 15:12:42 +00:00
|
|
|
const DynamicStat<float> &CreatureStats::getMagicka() const
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
|
|
|
return mDynamic[1];
|
|
|
|
}
|
|
|
|
|
2012-09-15 15:12:42 +00:00
|
|
|
const DynamicStat<float> &CreatureStats::getFatigue() const
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
|
|
|
return mDynamic[2];
|
|
|
|
}
|
|
|
|
|
|
|
|
const Spells &CreatureStats::getSpells() const
|
|
|
|
{
|
|
|
|
return mSpells;
|
|
|
|
}
|
|
|
|
|
|
|
|
const ActiveSpells &CreatureStats::getActiveSpells() const
|
|
|
|
{
|
|
|
|
return mActiveSpells;
|
|
|
|
}
|
|
|
|
|
|
|
|
const MagicEffects &CreatureStats::getMagicEffects() const
|
|
|
|
{
|
|
|
|
return mMagicEffects;
|
|
|
|
}
|
|
|
|
|
2013-08-04 02:29:44 +00:00
|
|
|
bool CreatureStats::getAttackingOrSpell() const
|
2013-07-13 21:24:52 +00:00
|
|
|
{
|
|
|
|
return mAttackingOrSpell;
|
|
|
|
}
|
|
|
|
|
2012-09-13 08:52:34 +00:00
|
|
|
int CreatureStats::getLevel() const
|
|
|
|
{
|
|
|
|
return mLevel;
|
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2014-01-05 00:34:35 +00:00
|
|
|
Stat<int> CreatureStats::getAiSetting (AiSetting index) const
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
2012-11-10 10:38:37 +00:00
|
|
|
return mAiSettings[index];
|
2012-09-13 08:52:34 +00:00
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2012-10-19 11:10:06 +00:00
|
|
|
const DynamicStat<float> &CreatureStats::getDynamic(int index) const
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
|
|
|
if (index < 0 || index > 2) {
|
|
|
|
throw std::runtime_error("dynamic stat index is out of range");
|
|
|
|
}
|
|
|
|
return mDynamic[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
Spells &CreatureStats::getSpells()
|
|
|
|
{
|
|
|
|
return mSpells;
|
|
|
|
}
|
|
|
|
|
|
|
|
ActiveSpells &CreatureStats::getActiveSpells()
|
|
|
|
{
|
|
|
|
return mActiveSpells;
|
|
|
|
}
|
|
|
|
|
|
|
|
MagicEffects &CreatureStats::getMagicEffects()
|
|
|
|
{
|
|
|
|
return mMagicEffects;
|
|
|
|
}
|
|
|
|
|
2013-12-28 16:19:35 +00:00
|
|
|
void CreatureStats::setAttribute(int index, int base)
|
|
|
|
{
|
2014-01-03 00:59:15 +00:00
|
|
|
AttributeValue current = getAttribute(index);
|
2013-12-28 16:19:35 +00:00
|
|
|
current.setBase(base);
|
|
|
|
setAttribute(index, current);
|
|
|
|
}
|
|
|
|
|
2014-01-03 00:59:15 +00:00
|
|
|
void CreatureStats::setAttribute(int index, const AttributeValue &value)
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
|
|
|
if (index < 0 || index > 7) {
|
|
|
|
throw std::runtime_error("attribute index is out of range");
|
|
|
|
}
|
2013-12-28 16:19:35 +00:00
|
|
|
|
2014-01-03 00:59:15 +00:00
|
|
|
const AttributeValue& currentValue = !mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index];
|
2013-12-28 16:19:35 +00:00
|
|
|
|
2014-01-03 00:59:15 +00:00
|
|
|
if (value != currentValue)
|
2013-12-28 16:19:35 +00:00
|
|
|
{
|
2014-11-28 13:45:35 +00:00
|
|
|
if (index == ESM::Attribute::Intelligence)
|
|
|
|
mRecalcMagicka = true;
|
|
|
|
else if (index == ESM::Attribute::Strength ||
|
|
|
|
index == ESM::Attribute::Willpower ||
|
|
|
|
index == ESM::Attribute::Agility ||
|
|
|
|
index == ESM::Attribute::Endurance)
|
|
|
|
{
|
|
|
|
int strength = getAttribute(ESM::Attribute::Strength).getModified();
|
|
|
|
int willpower = getAttribute(ESM::Attribute::Willpower).getModified();
|
|
|
|
int agility = getAttribute(ESM::Attribute::Agility).getModified();
|
|
|
|
int endurance = getAttribute(ESM::Attribute::Endurance).getModified();
|
|
|
|
DynamicStat<float> fatigue = getFatigue();
|
|
|
|
float diff = (strength+willpower+agility+endurance) - fatigue.getBase();
|
|
|
|
fatigue.modify(diff);
|
|
|
|
setFatigue(fatigue);
|
|
|
|
}
|
2013-12-28 16:19:35 +00:00
|
|
|
}
|
|
|
|
|
2013-08-09 12:14:58 +00:00
|
|
|
if(!mIsWerewolf)
|
|
|
|
mAttributes[index] = value;
|
|
|
|
else
|
|
|
|
mWerewolfAttributes[index] = value;
|
2012-09-13 08:52:34 +00:00
|
|
|
}
|
|
|
|
|
2012-09-15 15:12:42 +00:00
|
|
|
void CreatureStats::setHealth(const DynamicStat<float> &value)
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
2012-10-19 16:56:22 +00:00
|
|
|
setDynamic (0, value);
|
2012-09-13 08:52:34 +00:00
|
|
|
}
|
|
|
|
|
2012-09-15 15:12:42 +00:00
|
|
|
void CreatureStats::setMagicka(const DynamicStat<float> &value)
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
2012-10-19 16:56:22 +00:00
|
|
|
setDynamic (1, value);
|
2012-09-13 08:52:34 +00:00
|
|
|
}
|
|
|
|
|
2012-09-15 15:12:42 +00:00
|
|
|
void CreatureStats::setFatigue(const DynamicStat<float> &value)
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
2012-10-19 16:56:22 +00:00
|
|
|
setDynamic (2, value);
|
2012-09-13 08:52:34 +00:00
|
|
|
}
|
|
|
|
|
2012-10-19 11:10:06 +00:00
|
|
|
void CreatureStats::setDynamic (int index, const DynamicStat<float> &value)
|
|
|
|
{
|
|
|
|
if (index < 0 || index > 2)
|
|
|
|
throw std::runtime_error("dynamic stat index is out of range");
|
2012-10-23 11:54:36 +00:00
|
|
|
|
2012-10-19 11:10:06 +00:00
|
|
|
mDynamic[index] = value;
|
2012-10-23 11:54:36 +00:00
|
|
|
|
2012-10-25 10:22:48 +00:00
|
|
|
if (index==0 && mDynamic[index].getCurrent()<1)
|
2013-03-18 09:46:45 +00:00
|
|
|
{
|
2012-10-19 16:56:22 +00:00
|
|
|
mDead = true;
|
2014-07-21 18:37:14 +00:00
|
|
|
|
2014-09-05 15:17:45 +00:00
|
|
|
if (MWBase::Environment::get().getWorld()->getGodModeState())
|
|
|
|
MWBase::Environment::get().getMechanicsManager()->keepPlayerAlive();
|
2013-03-18 09:46:45 +00:00
|
|
|
}
|
2012-10-19 11:10:06 +00:00
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2012-09-13 08:52:34 +00:00
|
|
|
void CreatureStats::setLevel(int level)
|
|
|
|
{
|
|
|
|
mLevel = level;
|
|
|
|
}
|
|
|
|
|
2014-08-17 01:57:26 +00:00
|
|
|
void CreatureStats::modifyMagicEffects(const MagicEffects &effects)
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
2014-08-17 01:57:26 +00:00
|
|
|
if (effects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier()
|
|
|
|
!= mMagicEffects.get(ESM::MagicEffect::FortifyMaximumMagicka).getModifier())
|
2014-11-28 13:45:35 +00:00
|
|
|
mRecalcMagicka = true;
|
2013-12-28 16:19:35 +00:00
|
|
|
|
2014-08-17 01:57:26 +00:00
|
|
|
mMagicEffects.setModifiers(effects);
|
2012-09-13 08:52:34 +00:00
|
|
|
}
|
|
|
|
|
2013-08-04 02:29:44 +00:00
|
|
|
void CreatureStats::setAttackingOrSpell(bool attackingOrSpell)
|
2013-07-13 21:24:52 +00:00
|
|
|
{
|
|
|
|
mAttackingOrSpell = attackingOrSpell;
|
|
|
|
}
|
|
|
|
|
2014-01-05 00:34:35 +00:00
|
|
|
void CreatureStats::setAiSetting (AiSetting index, Stat<int> value)
|
2012-09-13 08:52:34 +00:00
|
|
|
{
|
2012-11-10 10:38:37 +00:00
|
|
|
mAiSettings[index] = value;
|
2012-09-13 08:52:34 +00:00
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2014-01-05 00:34:35 +00:00
|
|
|
void CreatureStats::setAiSetting (AiSetting index, int base)
|
|
|
|
{
|
2014-01-08 00:24:06 +00:00
|
|
|
Stat<int> stat = getAiSetting(index);
|
|
|
|
stat.setBase(base);
|
2014-01-05 00:34:35 +00:00
|
|
|
setAiSetting(index, stat);
|
|
|
|
}
|
|
|
|
|
2012-10-19 16:56:22 +00:00
|
|
|
bool CreatureStats::isDead() const
|
|
|
|
{
|
|
|
|
return mDead;
|
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2014-09-05 15:17:45 +00:00
|
|
|
void CreatureStats::notifyDied()
|
|
|
|
{
|
|
|
|
mDied = true;
|
|
|
|
}
|
|
|
|
|
2013-03-18 09:46:45 +00:00
|
|
|
bool CreatureStats::hasDied() const
|
|
|
|
{
|
|
|
|
return mDied;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::clearHasDied()
|
|
|
|
{
|
|
|
|
mDied = false;
|
|
|
|
}
|
|
|
|
|
2014-06-17 01:54:41 +00:00
|
|
|
bool CreatureStats::hasBeenMurdered() const
|
|
|
|
{
|
|
|
|
return mMurdered;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::notifyMurder()
|
|
|
|
{
|
|
|
|
mMurdered = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::clearHasBeenMurdered()
|
|
|
|
{
|
|
|
|
mMurdered = false;
|
|
|
|
}
|
|
|
|
|
2012-10-19 16:56:22 +00:00
|
|
|
void CreatureStats::resurrect()
|
|
|
|
{
|
|
|
|
if (mDead)
|
|
|
|
{
|
2014-09-13 18:50:49 +00:00
|
|
|
mDynamic[0].setCurrent(mDynamic[0].getModified());
|
2012-10-19 16:56:22 +00:00
|
|
|
if (mDynamic[0].getCurrent()>=1)
|
|
|
|
mDead = false;
|
|
|
|
}
|
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2012-11-09 17:16:29 +00:00
|
|
|
bool CreatureStats::hasCommonDisease() const
|
|
|
|
{
|
|
|
|
return mSpells.hasCommonDisease();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CreatureStats::hasBlightDisease() const
|
|
|
|
{
|
|
|
|
return mSpells.hasBlightDisease();
|
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2012-11-10 12:20:41 +00:00
|
|
|
int CreatureStats::getFriendlyHits() const
|
|
|
|
{
|
|
|
|
return mFriendlyHits;
|
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2012-11-10 12:20:41 +00:00
|
|
|
void CreatureStats::friendlyHit()
|
|
|
|
{
|
|
|
|
++mFriendlyHits;
|
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2012-11-10 12:20:41 +00:00
|
|
|
bool CreatureStats::hasTalkedToPlayer() const
|
|
|
|
{
|
|
|
|
return mTalkedTo;
|
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
2012-11-10 12:20:41 +00:00
|
|
|
void CreatureStats::talkedToPlayer()
|
|
|
|
{
|
|
|
|
mTalkedTo = true;
|
|
|
|
}
|
2012-11-15 19:00:27 +00:00
|
|
|
|
|
|
|
bool CreatureStats::isAlarmed() const
|
|
|
|
{
|
|
|
|
return mAlarmed;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::setAlarmed (bool alarmed)
|
|
|
|
{
|
|
|
|
mAlarmed = alarmed;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CreatureStats::getAttacked() const
|
|
|
|
{
|
|
|
|
return mAttacked;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::setAttacked (bool attacked)
|
|
|
|
{
|
|
|
|
mAttacked = attacked;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CreatureStats::getCreatureTargetted() const
|
|
|
|
{
|
2014-05-18 16:13:46 +00:00
|
|
|
MWWorld::Ptr targetPtr;
|
|
|
|
if (mAiSequence.getCombatTarget(targetPtr))
|
2014-01-25 23:16:56 +00:00
|
|
|
{
|
|
|
|
return targetPtr.getTypeName() == typeid(ESM::Creature).name();
|
|
|
|
}
|
|
|
|
return false;
|
2012-11-15 19:00:27 +00:00
|
|
|
}
|
2013-07-26 15:08:52 +00:00
|
|
|
|
2013-07-31 19:25:14 +00:00
|
|
|
float CreatureStats::getEvasion() const
|
|
|
|
{
|
|
|
|
float evasion = (getAttribute(ESM::Attribute::Agility).getModified() / 5.0f) +
|
|
|
|
(getAttribute(ESM::Attribute::Luck).getModified() / 10.0f);
|
|
|
|
evasion *= getFatigueTerm();
|
2014-08-16 20:38:22 +00:00
|
|
|
evasion += mMagicEffects.get(ESM::MagicEffect::Sanctuary).getMagnitude();
|
2013-07-31 19:25:14 +00:00
|
|
|
|
|
|
|
return evasion;
|
|
|
|
}
|
|
|
|
|
2013-07-26 15:08:52 +00:00
|
|
|
void CreatureStats::setLastHitObject(const std::string& objectid)
|
|
|
|
{
|
|
|
|
mLastHitObject = objectid;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string &CreatureStats::getLastHitObject() const
|
|
|
|
{
|
|
|
|
return mLastHitObject;
|
|
|
|
}
|
2013-11-10 14:40:31 +00:00
|
|
|
|
2013-12-27 20:21:18 +00:00
|
|
|
void CreatureStats::addToFallHeight(float height)
|
|
|
|
{
|
|
|
|
mFallHeight += height;
|
|
|
|
}
|
|
|
|
|
|
|
|
float CreatureStats::land()
|
|
|
|
{
|
|
|
|
float height = mFallHeight;
|
|
|
|
mFallHeight = 0;
|
|
|
|
return height;
|
|
|
|
}
|
2013-12-28 16:19:35 +00:00
|
|
|
|
|
|
|
bool CreatureStats::needToRecalcDynamicStats()
|
|
|
|
{
|
2014-11-28 13:45:35 +00:00
|
|
|
if (mRecalcMagicka)
|
2013-12-28 16:19:35 +00:00
|
|
|
{
|
2014-11-28 13:45:35 +00:00
|
|
|
mRecalcMagicka = false;
|
2013-12-28 16:19:35 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2014-01-13 00:42:19 +00:00
|
|
|
|
2014-09-18 01:47:45 +00:00
|
|
|
void CreatureStats::setNeedRecalcDynamicStats(bool val)
|
|
|
|
{
|
2014-11-28 13:45:35 +00:00
|
|
|
mRecalcMagicka = val;
|
2014-09-18 01:47:45 +00:00
|
|
|
}
|
|
|
|
|
2014-01-13 00:42:19 +00:00
|
|
|
void CreatureStats::setKnockedDown(bool value)
|
|
|
|
{
|
|
|
|
mKnockdown = value;
|
2014-04-28 00:54:22 +00:00
|
|
|
if(!value) //Resets the "OverOneFrame" flag
|
|
|
|
setKnockedDownOverOneFrame(false);
|
2014-01-13 00:42:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CreatureStats::getKnockedDown() const
|
|
|
|
{
|
|
|
|
return mKnockdown;
|
|
|
|
}
|
|
|
|
|
2014-04-28 00:54:22 +00:00
|
|
|
void CreatureStats::setKnockedDownOneFrame(bool value)
|
|
|
|
{
|
|
|
|
mKnockdownOneFrame = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CreatureStats::getKnockedDownOneFrame() const
|
|
|
|
{
|
|
|
|
return mKnockdownOneFrame;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::setKnockedDownOverOneFrame(bool value) {
|
|
|
|
mKnockdownOverOneFrame = value;
|
|
|
|
}
|
|
|
|
bool CreatureStats::getKnockedDownOverOneFrame() const {
|
|
|
|
return mKnockdownOverOneFrame;
|
|
|
|
}
|
|
|
|
|
2014-01-13 00:42:19 +00:00
|
|
|
void CreatureStats::setHitRecovery(bool value)
|
|
|
|
{
|
|
|
|
mHitRecovery = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CreatureStats::getHitRecovery() const
|
|
|
|
{
|
|
|
|
return mHitRecovery;
|
|
|
|
}
|
2014-01-15 06:47:21 +00:00
|
|
|
|
2014-01-21 00:01:21 +00:00
|
|
|
void CreatureStats::setBlock(bool value)
|
|
|
|
{
|
|
|
|
mBlock = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CreatureStats::getBlock() const
|
|
|
|
{
|
|
|
|
return mBlock;
|
|
|
|
}
|
|
|
|
|
2014-01-15 06:47:21 +00:00
|
|
|
bool CreatureStats::getMovementFlag (Flag flag) const
|
|
|
|
{
|
|
|
|
return mMovementFlags & flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::setMovementFlag (Flag flag, bool state)
|
|
|
|
{
|
|
|
|
if (state)
|
|
|
|
mMovementFlags |= flag;
|
|
|
|
else
|
|
|
|
mMovementFlags &= ~flag;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CreatureStats::getStance(Stance flag) const
|
|
|
|
{
|
|
|
|
switch (flag)
|
|
|
|
{
|
|
|
|
case Stance_Run:
|
|
|
|
return getMovementFlag (Flag_Run) || getMovementFlag (Flag_ForceRun);
|
|
|
|
case Stance_Sneak:
|
|
|
|
return getMovementFlag (Flag_Sneak) || getMovementFlag (Flag_ForceSneak);
|
2014-04-04 12:10:35 +00:00
|
|
|
default:
|
|
|
|
return false;
|
2014-01-15 06:47:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-19 08:43:41 +00:00
|
|
|
DrawState_ CreatureStats::getDrawState() const
|
|
|
|
{
|
|
|
|
return mDrawState;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::setDrawState(DrawState_ state)
|
|
|
|
{
|
|
|
|
mDrawState = state;
|
|
|
|
}
|
|
|
|
|
2014-01-19 12:31:17 +00:00
|
|
|
float CreatureStats::getAttackStrength() const
|
|
|
|
{
|
|
|
|
return mAttackStrength;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::setAttackStrength(float value)
|
|
|
|
{
|
|
|
|
mAttackStrength = value;
|
|
|
|
}
|
|
|
|
|
2014-02-16 14:56:36 +00:00
|
|
|
void CreatureStats::writeState (ESM::CreatureStats& state) const
|
|
|
|
{
|
2014-05-12 19:04:02 +00:00
|
|
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
2014-02-16 14:56:36 +00:00
|
|
|
mAttributes[i].writeState (state.mAttributes[i]);
|
|
|
|
|
|
|
|
for (int i=0; i<3; ++i)
|
|
|
|
mDynamic[i].writeState (state.mDynamic[i]);
|
2014-05-12 19:04:02 +00:00
|
|
|
|
2014-05-17 12:30:31 +00:00
|
|
|
state.mTradeTime = mLastRestock.toEsm();
|
2014-05-12 19:04:02 +00:00
|
|
|
state.mGoldPool = mGoldPool;
|
|
|
|
|
|
|
|
state.mDead = mDead;
|
|
|
|
state.mDied = mDied;
|
2014-06-17 01:54:41 +00:00
|
|
|
state.mMurdered = mMurdered;
|
2014-05-12 19:04:02 +00:00
|
|
|
state.mFriendlyHits = mFriendlyHits;
|
|
|
|
state.mTalkedTo = mTalkedTo;
|
|
|
|
state.mAlarmed = mAlarmed;
|
|
|
|
state.mAttacked = mAttacked;
|
|
|
|
state.mAttackingOrSpell = mAttackingOrSpell;
|
|
|
|
// TODO: rewrite. does this really need 3 separate bools?
|
|
|
|
state.mKnockdown = mKnockdown;
|
|
|
|
state.mKnockdownOneFrame = mKnockdownOneFrame;
|
|
|
|
state.mKnockdownOverOneFrame = mKnockdownOverOneFrame;
|
|
|
|
state.mHitRecovery = mHitRecovery;
|
|
|
|
state.mBlock = mBlock;
|
|
|
|
state.mMovementFlags = mMovementFlags;
|
|
|
|
state.mAttackStrength = mAttackStrength;
|
2014-05-14 20:16:39 +00:00
|
|
|
state.mFallHeight = mFallHeight; // TODO: vertical velocity (move from PhysicActor to CreatureStats?)
|
2014-05-12 19:04:02 +00:00
|
|
|
state.mLastHitObject = mLastHitObject;
|
2014-11-28 13:45:35 +00:00
|
|
|
state.mRecalcDynamicStats = mRecalcMagicka;
|
2014-05-12 19:04:02 +00:00
|
|
|
state.mDrawState = mDrawState;
|
|
|
|
state.mLevel = mLevel;
|
2014-05-14 07:47:49 +00:00
|
|
|
state.mActorId = mActorId;
|
2014-05-26 17:56:32 +00:00
|
|
|
state.mDeathAnimation = mDeathAnimation;
|
2014-05-12 19:04:02 +00:00
|
|
|
|
|
|
|
mSpells.writeState(state.mSpells);
|
2014-05-14 20:16:39 +00:00
|
|
|
mActiveSpells.writeState(state.mActiveSpells);
|
2014-06-12 21:27:04 +00:00
|
|
|
mAiSequence.writeState(state.mAiSequence);
|
2014-08-17 02:58:58 +00:00
|
|
|
mMagicEffects.writeState(state.mMagicEffects);
|
2014-06-15 19:19:37 +00:00
|
|
|
|
|
|
|
state.mSummonedCreatureMap = mSummonedCreatures;
|
|
|
|
state.mSummonGraveyard = mSummonGraveyard;
|
|
|
|
|
|
|
|
state.mHasAiSettings = true;
|
|
|
|
for (int i=0; i<4; ++i)
|
|
|
|
mAiSettings[i].writeState (state.mAiSettings[i]);
|
2014-02-16 14:56:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::readState (const ESM::CreatureStats& state)
|
|
|
|
{
|
2014-05-12 19:04:02 +00:00
|
|
|
for (int i=0; i<ESM::Attribute::Length; ++i)
|
2014-02-16 14:56:36 +00:00
|
|
|
mAttributes[i].readState (state.mAttributes[i]);
|
|
|
|
|
|
|
|
for (int i=0; i<3; ++i)
|
|
|
|
mDynamic[i].readState (state.mDynamic[i]);
|
2014-05-12 19:04:02 +00:00
|
|
|
|
2014-05-17 12:30:31 +00:00
|
|
|
mLastRestock = MWWorld::TimeStamp(state.mTradeTime);
|
2014-05-12 19:04:02 +00:00
|
|
|
mGoldPool = state.mGoldPool;
|
|
|
|
|
|
|
|
mDead = state.mDead;
|
|
|
|
mDied = state.mDied;
|
2014-06-17 01:54:41 +00:00
|
|
|
mMurdered = state.mMurdered;
|
2014-05-12 19:04:02 +00:00
|
|
|
mFriendlyHits = state.mFriendlyHits;
|
|
|
|
mTalkedTo = state.mTalkedTo;
|
|
|
|
mAlarmed = state.mAlarmed;
|
|
|
|
mAttacked = state.mAttacked;
|
|
|
|
mAttackingOrSpell = state.mAttackingOrSpell;
|
|
|
|
// TODO: rewrite. does this really need 3 separate bools?
|
|
|
|
mKnockdown = state.mKnockdown;
|
|
|
|
mKnockdownOneFrame = state.mKnockdownOneFrame;
|
|
|
|
mKnockdownOverOneFrame = state.mKnockdownOverOneFrame;
|
|
|
|
mHitRecovery = state.mHitRecovery;
|
|
|
|
mBlock = state.mBlock;
|
|
|
|
mMovementFlags = state.mMovementFlags;
|
|
|
|
mAttackStrength = state.mAttackStrength;
|
|
|
|
mFallHeight = state.mFallHeight;
|
|
|
|
mLastHitObject = state.mLastHitObject;
|
2014-11-28 13:45:35 +00:00
|
|
|
mRecalcMagicka = state.mRecalcDynamicStats;
|
2014-05-12 19:04:02 +00:00
|
|
|
mDrawState = DrawState_(state.mDrawState);
|
|
|
|
mLevel = state.mLevel;
|
2014-05-14 07:47:49 +00:00
|
|
|
mActorId = state.mActorId;
|
2014-05-26 17:56:32 +00:00
|
|
|
mDeathAnimation = state.mDeathAnimation;
|
2014-05-12 19:04:02 +00:00
|
|
|
|
|
|
|
mSpells.readState(state.mSpells);
|
2014-05-14 20:16:39 +00:00
|
|
|
mActiveSpells.readState(state.mActiveSpells);
|
2014-06-12 21:27:04 +00:00
|
|
|
mAiSequence.readState(state.mAiSequence);
|
2014-08-17 02:58:58 +00:00
|
|
|
mMagicEffects.readState(state.mMagicEffects);
|
2014-06-15 19:19:37 +00:00
|
|
|
|
|
|
|
mSummonedCreatures = state.mSummonedCreatureMap;
|
|
|
|
mSummonGraveyard = state.mSummonGraveyard;
|
|
|
|
|
|
|
|
if (state.mHasAiSettings)
|
|
|
|
for (int i=0; i<4; ++i)
|
|
|
|
mAiSettings[i].readState(state.mAiSettings[i]);
|
2014-02-16 14:56:36 +00:00
|
|
|
}
|
2014-03-27 05:23:56 +00:00
|
|
|
|
2014-05-17 12:30:31 +00:00
|
|
|
void CreatureStats::setLastRestockTime(MWWorld::TimeStamp tradeTime)
|
2014-03-27 05:23:56 +00:00
|
|
|
{
|
2014-05-17 12:30:31 +00:00
|
|
|
mLastRestock = tradeTime;
|
2014-03-27 05:23:56 +00:00
|
|
|
}
|
|
|
|
|
2014-05-17 12:30:31 +00:00
|
|
|
MWWorld::TimeStamp CreatureStats::getLastRestockTime() const
|
2014-03-27 05:23:56 +00:00
|
|
|
{
|
2014-05-17 12:30:31 +00:00
|
|
|
return mLastRestock;
|
2014-03-27 05:23:56 +00:00
|
|
|
}
|
|
|
|
|
2014-04-28 00:54:22 +00:00
|
|
|
void CreatureStats::setGoldPool(int pool)
|
2014-03-27 05:23:56 +00:00
|
|
|
{
|
|
|
|
mGoldPool = pool;
|
|
|
|
}
|
2014-04-28 00:54:22 +00:00
|
|
|
int CreatureStats::getGoldPool() const
|
2014-03-27 05:23:56 +00:00
|
|
|
{
|
|
|
|
return mGoldPool;
|
|
|
|
}
|
2014-04-29 13:27:49 +00:00
|
|
|
|
|
|
|
int CreatureStats::getActorId()
|
|
|
|
{
|
|
|
|
if (mActorId==-1)
|
|
|
|
mActorId = sActorId++;
|
|
|
|
|
|
|
|
return mActorId;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CreatureStats::matchesActorId (int id) const
|
|
|
|
{
|
|
|
|
return mActorId!=-1 && id==mActorId;
|
|
|
|
}
|
2014-04-29 17:56:33 +00:00
|
|
|
|
|
|
|
void CreatureStats::cleanup()
|
|
|
|
{
|
|
|
|
sActorId = 0;
|
|
|
|
}
|
2014-05-14 07:47:49 +00:00
|
|
|
|
|
|
|
void CreatureStats::writeActorIdCounter (ESM::ESMWriter& esm)
|
|
|
|
{
|
|
|
|
esm.startRecord(ESM::REC_ACTC);
|
|
|
|
esm.writeHNT("COUN", sActorId);
|
|
|
|
esm.endRecord(ESM::REC_ACTC);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::readActorIdCounter (ESM::ESMReader& esm)
|
|
|
|
{
|
|
|
|
esm.getHNT(sActorId, "COUN");
|
|
|
|
}
|
2014-05-26 17:56:32 +00:00
|
|
|
|
|
|
|
unsigned char CreatureStats::getDeathAnimation() const
|
|
|
|
{
|
|
|
|
return mDeathAnimation;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreatureStats::setDeathAnimation(unsigned char index)
|
|
|
|
{
|
|
|
|
mDeathAnimation = index;
|
|
|
|
}
|
2014-06-15 19:19:37 +00:00
|
|
|
|
|
|
|
std::map<int, int>& CreatureStats::getSummonedCreatureMap()
|
|
|
|
{
|
|
|
|
return mSummonedCreatures;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<int>& CreatureStats::getSummonedCreatureGraveyard()
|
|
|
|
{
|
|
|
|
return mSummonGraveyard;
|
|
|
|
}
|
2012-07-22 14:29:54 +00:00
|
|
|
}
|