mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 14:23:53 +00:00
Bug #951: Only recalculate derived stats when attributes change
This commit is contained in:
parent
27b45dd3cd
commit
2a8ab932ef
8 changed files with 85 additions and 55 deletions
|
@ -68,14 +68,14 @@ namespace MWClass
|
|||
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
|
||||
|
||||
// creature stats
|
||||
data->mCreatureStats.getAttribute(0).set (ref->mBase->mData.mStrength);
|
||||
data->mCreatureStats.getAttribute(1).set (ref->mBase->mData.mIntelligence);
|
||||
data->mCreatureStats.getAttribute(2).set (ref->mBase->mData.mWillpower);
|
||||
data->mCreatureStats.getAttribute(3).set (ref->mBase->mData.mAgility);
|
||||
data->mCreatureStats.getAttribute(4).set (ref->mBase->mData.mSpeed);
|
||||
data->mCreatureStats.getAttribute(5).set (ref->mBase->mData.mEndurance);
|
||||
data->mCreatureStats.getAttribute(6).set (ref->mBase->mData.mPersonality);
|
||||
data->mCreatureStats.getAttribute(7).set (ref->mBase->mData.mLuck);
|
||||
data->mCreatureStats.setAttribute(ESM::Attribute::Strength, ref->mBase->mData.mStrength);
|
||||
data->mCreatureStats.setAttribute(ESM::Attribute::Intelligence, ref->mBase->mData.mIntelligence);
|
||||
data->mCreatureStats.setAttribute(ESM::Attribute::Willpower, ref->mBase->mData.mWillpower);
|
||||
data->mCreatureStats.setAttribute(ESM::Attribute::Agility, ref->mBase->mData.mAgility);
|
||||
data->mCreatureStats.setAttribute(ESM::Attribute::Speed, ref->mBase->mData.mSpeed);
|
||||
data->mCreatureStats.setAttribute(ESM::Attribute::Endurance, ref->mBase->mData.mEndurance);
|
||||
data->mCreatureStats.setAttribute(ESM::Attribute::Personality, ref->mBase->mData.mPersonality);
|
||||
data->mCreatureStats.setAttribute(ESM::Attribute::Luck, ref->mBase->mData.mLuck);
|
||||
data->mCreatureStats.setHealth (ref->mBase->mData.mHealth);
|
||||
data->mCreatureStats.setMagicka (ref->mBase->mData.mMana);
|
||||
data->mCreatureStats.setFatigue (ref->mBase->mData.mFatigue);
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace
|
|||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||
{
|
||||
const ESM::Race::MaleFemale& attribute = race->mData.mAttributeValues[i];
|
||||
creatureStats.getAttribute(i).setBase (male ? attribute.mMale : attribute.mFemale);
|
||||
creatureStats.setAttribute(i, male ? attribute.mMale : attribute.mFemale);
|
||||
}
|
||||
|
||||
// class bonus
|
||||
|
@ -78,7 +78,7 @@ namespace
|
|||
int attribute = class_->mData.mAttribute[i];
|
||||
if (attribute>=0 && attribute<8)
|
||||
{
|
||||
creatureStats.getAttribute(attribute).setBase (
|
||||
creatureStats.setAttribute(attribute,
|
||||
creatureStats.getAttribute(attribute).getBase() + 10);
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ namespace
|
|||
}
|
||||
modifierSum += add;
|
||||
}
|
||||
creatureStats.getAttribute(attribute).setBase ( std::min(creatureStats.getAttribute(attribute).getBase()
|
||||
creatureStats.setAttribute(attribute, std::min(creatureStats.getAttribute(attribute).getBase()
|
||||
+ static_cast<int>((level-1) * modifierSum+0.5), 100) );
|
||||
}
|
||||
|
||||
|
@ -274,14 +274,15 @@ namespace MWClass
|
|||
for (unsigned int i=0; i< ESM::Skill::Length; ++i)
|
||||
data->mNpcStats.getSkill (i).setBase (ref->mBase->mNpdt52.mSkills[i]);
|
||||
|
||||
data->mNpcStats.getAttribute(0).set (ref->mBase->mNpdt52.mStrength);
|
||||
data->mNpcStats.getAttribute(1).set (ref->mBase->mNpdt52.mIntelligence);
|
||||
data->mNpcStats.getAttribute(2).set (ref->mBase->mNpdt52.mWillpower);
|
||||
data->mNpcStats.getAttribute(3).set (ref->mBase->mNpdt52.mAgility);
|
||||
data->mNpcStats.getAttribute(4).set (ref->mBase->mNpdt52.mSpeed);
|
||||
data->mNpcStats.getAttribute(5).set (ref->mBase->mNpdt52.mEndurance);
|
||||
data->mNpcStats.getAttribute(6).set (ref->mBase->mNpdt52.mPersonality);
|
||||
data->mNpcStats.getAttribute(7).set (ref->mBase->mNpdt52.mLuck);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Strength, ref->mBase->mNpdt52.mStrength);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Intelligence, ref->mBase->mNpdt52.mIntelligence);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Willpower, ref->mBase->mNpdt52.mWillpower);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Agility, ref->mBase->mNpdt52.mAgility);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Speed, ref->mBase->mNpdt52.mSpeed);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Endurance, ref->mBase->mNpdt52.mEndurance);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Personality, ref->mBase->mNpdt52.mPersonality);
|
||||
data->mNpcStats.setAttribute(ESM::Attribute::Luck, ref->mBase->mNpdt52.mLuck);
|
||||
|
||||
data->mNpcStats.setHealth (ref->mBase->mNpdt52.mHealth);
|
||||
data->mNpcStats.setMagicka (ref->mBase->mNpdt52.mMana);
|
||||
data->mNpcStats.setFatigue (ref->mBase->mNpdt52.mFatigue);
|
||||
|
|
|
@ -166,11 +166,12 @@ namespace MWGui
|
|||
// increase attributes
|
||||
for (int i=0; i<3; ++i)
|
||||
{
|
||||
MWMechanics::Stat<int>& attribute = creatureStats.getAttribute(mSpentAttributes[i]);
|
||||
MWMechanics::Stat<int> attribute = creatureStats.getAttribute(mSpentAttributes[i]);
|
||||
attribute.setBase (attribute.getBase () + pcStats.getLevelupAttributeMultiplier (mSpentAttributes[i]));
|
||||
|
||||
if (attribute.getBase() >= 100)
|
||||
attribute.setBase(100);
|
||||
creatureStats.setAttribute(mSpentAttributes[i], attribute);
|
||||
}
|
||||
|
||||
creatureStats.levelUp();
|
||||
|
|
|
@ -54,7 +54,8 @@ namespace MWMechanics
|
|||
{
|
||||
// magic effects
|
||||
adjustMagicEffects (ptr);
|
||||
calculateDynamicStats (ptr);
|
||||
if (ptr.getClass().getCreatureStats(ptr).needToRecalcDynamicStats())
|
||||
calculateDynamicStats (ptr);
|
||||
calculateCreatureStatModifiers (ptr, duration);
|
||||
|
||||
if(!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace MWMechanics
|
|||
mAttacked (false), mHostile (false),
|
||||
mAttackingOrSpell(false), mAttackType(AT_Chop),
|
||||
mIsWerewolf(false),
|
||||
mFallHeight(0)
|
||||
mFallHeight(0), mRecalcDynamicStats(false)
|
||||
{
|
||||
for (int i=0; i<4; ++i)
|
||||
mAiSettings[i] = 0;
|
||||
|
@ -128,14 +128,6 @@ namespace MWMechanics
|
|||
return mAiSettings[index];
|
||||
}
|
||||
|
||||
Stat<int> &CreatureStats::getAttribute(int index)
|
||||
{
|
||||
if (index < 0 || index > 7) {
|
||||
throw std::runtime_error("attribute index is out of range");
|
||||
}
|
||||
return (!mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index]);
|
||||
}
|
||||
|
||||
const DynamicStat<float> &CreatureStats::getDynamic(int index) const
|
||||
{
|
||||
if (index < 0 || index > 2) {
|
||||
|
@ -164,11 +156,29 @@ namespace MWMechanics
|
|||
return mMagicEffects;
|
||||
}
|
||||
|
||||
void CreatureStats::setAttribute(int index, int base)
|
||||
{
|
||||
MWMechanics::Stat<int> current = getAttribute(index);
|
||||
current.setBase(base);
|
||||
setAttribute(index, current);
|
||||
}
|
||||
|
||||
void CreatureStats::setAttribute(int index, const Stat<int> &value)
|
||||
{
|
||||
if (index < 0 || index > 7) {
|
||||
throw std::runtime_error("attribute index is out of range");
|
||||
}
|
||||
|
||||
const Stat<int>& currentValue = !mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index];
|
||||
|
||||
if (value.getModified() != currentValue.getModified())
|
||||
{
|
||||
if (index != ESM::Attribute::Luck
|
||||
&& index != ESM::Attribute::Personality
|
||||
&& index != ESM::Attribute::Speed)
|
||||
mRecalcDynamicStats = true;
|
||||
}
|
||||
|
||||
if(!mIsWerewolf)
|
||||
mAttributes[index] = value;
|
||||
else
|
||||
|
@ -218,6 +228,10 @@ namespace MWMechanics
|
|||
|
||||
void CreatureStats::setMagicEffects(const MagicEffects &effects)
|
||||
{
|
||||
if (effects.get(MWMechanics::EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).mMagnitude
|
||||
!= mMagicEffects.get(MWMechanics::EffectKey(ESM::MagicEffect::FortifyMaximumMagicka)).mMagnitude)
|
||||
mRecalcDynamicStats = true;
|
||||
|
||||
mMagicEffects = effects;
|
||||
}
|
||||
|
||||
|
@ -369,4 +383,14 @@ namespace MWMechanics
|
|||
mFallHeight = 0;
|
||||
return height;
|
||||
}
|
||||
|
||||
bool CreatureStats::needToRecalcDynamicStats()
|
||||
{
|
||||
if (mRecalcDynamicStats)
|
||||
{
|
||||
mRecalcDynamicStats = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,9 @@ namespace MWMechanics
|
|||
|
||||
std::string mLastHitObject; // The last object to hit this actor
|
||||
|
||||
// Do we need to recalculate stats derived from attributes or other factors?
|
||||
bool mRecalcDynamicStats;
|
||||
|
||||
std::map<std::string, MWWorld::TimeStamp> mUsedPowers;
|
||||
|
||||
protected:
|
||||
|
@ -51,6 +54,8 @@ namespace MWMechanics
|
|||
public:
|
||||
CreatureStats();
|
||||
|
||||
bool needToRecalcDynamicStats();
|
||||
|
||||
void addToFallHeight(float height);
|
||||
|
||||
/// Reset the fall height
|
||||
|
@ -83,8 +88,6 @@ namespace MWMechanics
|
|||
int getAiSetting (int index) const;
|
||||
///< 0: hello, 1 fight, 2 flee, 3 alarm
|
||||
|
||||
Stat<int> & getAttribute(int index);
|
||||
|
||||
Spells & getSpells();
|
||||
|
||||
ActiveSpells & getActiveSpells();
|
||||
|
@ -92,6 +95,8 @@ namespace MWMechanics
|
|||
MagicEffects & getMagicEffects();
|
||||
|
||||
void setAttribute(int index, const Stat<int> &value);
|
||||
// Shortcut to set only the base
|
||||
void setAttribute(int index, int base);
|
||||
|
||||
void setHealth(const DynamicStat<float> &value);
|
||||
|
||||
|
|
|
@ -31,15 +31,14 @@ namespace MWMechanics
|
|||
for (int i=0; i<27; ++i)
|
||||
npcStats.getSkill (i).setBase (player->mNpdt52.mSkills[i]);
|
||||
|
||||
creatureStats.getAttribute(0).setBase (player->mNpdt52.mStrength);
|
||||
creatureStats.getAttribute(1).setBase (player->mNpdt52.mIntelligence);
|
||||
creatureStats.getAttribute(2).setBase (player->mNpdt52.mWillpower);
|
||||
creatureStats.getAttribute(3).setBase (player->mNpdt52.mAgility);
|
||||
creatureStats.getAttribute(4).setBase (player->mNpdt52.mSpeed);
|
||||
creatureStats.getAttribute(5).setBase (player->mNpdt52.mEndurance);
|
||||
creatureStats.getAttribute(6).setBase (player->mNpdt52.mPersonality);
|
||||
creatureStats.getAttribute(7).setBase (player->mNpdt52.mLuck);
|
||||
|
||||
creatureStats.setAttribute(ESM::Attribute::Strength, player->mNpdt52.mStrength);
|
||||
creatureStats.setAttribute(ESM::Attribute::Intelligence, player->mNpdt52.mIntelligence);
|
||||
creatureStats.setAttribute(ESM::Attribute::Willpower, player->mNpdt52.mWillpower);
|
||||
creatureStats.setAttribute(ESM::Attribute::Agility, player->mNpdt52.mAgility);
|
||||
creatureStats.setAttribute(ESM::Attribute::Speed, player->mNpdt52.mSpeed);
|
||||
creatureStats.setAttribute(ESM::Attribute::Endurance, player->mNpdt52.mEndurance);
|
||||
creatureStats.setAttribute(ESM::Attribute::Personality, player->mNpdt52.mPersonality);
|
||||
creatureStats.setAttribute(ESM::Attribute::Luck, player->mNpdt52.mLuck);
|
||||
const MWWorld::ESMStore &esmStore =
|
||||
MWBase::Environment::get().getWorld()->getStore();
|
||||
|
||||
|
@ -55,7 +54,7 @@ namespace MWMechanics
|
|||
{
|
||||
const ESM::Race::MaleFemale& attribute = race->mData.mAttributeValues[i];
|
||||
|
||||
creatureStats.getAttribute(i).setBase (male ? attribute.mMale : attribute.mFemale);
|
||||
creatureStats.setAttribute(i, male ? attribute.mMale : attribute.mFemale);
|
||||
}
|
||||
|
||||
for (int i=0; i<27; ++i)
|
||||
|
@ -106,7 +105,7 @@ namespace MWMechanics
|
|||
int attribute = class_->mData.mAttribute[i];
|
||||
if (attribute>=0 && attribute<8)
|
||||
{
|
||||
creatureStats.getAttribute(attribute).setBase (
|
||||
creatureStats.setAttribute(attribute,
|
||||
creatureStats.getAttribute(attribute).getBase() + 10);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,10 +124,9 @@ namespace MWScript
|
|||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
MWWorld::Class::get(ptr)
|
||||
.getCreatureStats(ptr)
|
||||
.getAttribute(mIndex)
|
||||
.setModified (value, 0);
|
||||
MWMechanics::Stat<int> attribute = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex);
|
||||
attribute.setModified (value, 0);
|
||||
ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -147,16 +146,16 @@ namespace MWScript
|
|||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
value +=
|
||||
MWWorld::Class::get(ptr)
|
||||
.getCreatureStats(ptr)
|
||||
.getAttribute(mIndex)
|
||||
.getModified();
|
||||
|
||||
MWWorld::Class::get(ptr)
|
||||
MWMechanics::Stat<int> attribute = MWWorld::Class::get(ptr)
|
||||
.getCreatureStats(ptr)
|
||||
.getAttribute(mIndex)
|
||||
.getAttribute(mIndex);
|
||||
|
||||
value +=
|
||||
attribute.getModified();
|
||||
|
||||
attribute
|
||||
.setModified (value, 0, 100);
|
||||
ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue