mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-01 00:32:52 +00:00
Store attributes and skills values as floats (bug #4021)
This commit is contained in:
parent
2eb9d4ad4e
commit
5468fcb29f
@ -5,6 +5,7 @@
|
||||
Bug #2311: Targeted scripts are not properly supported on non-unique RefIDs
|
||||
Bug #3676: NiParticleColorModifier isn't applied properly
|
||||
Bug #3714: Savegame fails to load due to conflict between SpellState and MagicEffects
|
||||
Bug #4021: Attributes and skills are not stored as floats
|
||||
Bug #4623: Corprus implementation is incorrect
|
||||
Bug #4774: Guards are ignorant of an invisible player that tries to attack them
|
||||
Bug #5108: Savegame bloating due to inefficient fog textures format
|
||||
|
@ -276,7 +276,7 @@ namespace MWClass
|
||||
const MWWorld::LiveCellRef<ESM::Armor> *ref = ptr.get<ESM::Armor>();
|
||||
|
||||
int armorSkillType = getEquipmentSkill(ptr);
|
||||
int armorSkill = actor.getClass().getSkill(actor, armorSkillType);
|
||||
float armorSkill = actor.getClass().getSkill(actor, armorSkillType);
|
||||
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
int iBaseArmorSkill = world->getStore().get<ESM::GameSetting>().find("iBaseArmorSkill")->mValue.getInteger();
|
||||
|
@ -605,7 +605,7 @@ namespace MWClass
|
||||
float Creature::getCapacity (const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
const MWMechanics::CreatureStats& stats = getCreatureStats (ptr);
|
||||
return static_cast<float>(stats.getAttribute(ESM::Attribute::Strength).getModified() * 5);
|
||||
return stats.getAttribute(ESM::Attribute::Strength).getModified() * 5;
|
||||
}
|
||||
|
||||
int Creature::getServices(const MWWorld::ConstPtr &actor) const
|
||||
@ -745,7 +745,7 @@ namespace MWClass
|
||||
throw std::runtime_error(std::string("Unexpected soundgen type: ")+name);
|
||||
}
|
||||
|
||||
int Creature::getSkill(const MWWorld::Ptr &ptr, int skill) const
|
||||
float Creature::getSkill(const MWWorld::Ptr &ptr, int skill) const
|
||||
{
|
||||
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||
ptr.get<ESM::Creature>();
|
||||
|
@ -108,7 +108,7 @@ namespace MWClass
|
||||
virtual bool canSwim (const MWWorld::ConstPtr &ptr) const;
|
||||
virtual bool canWalk (const MWWorld::ConstPtr &ptr) const;
|
||||
|
||||
virtual int getSkill(const MWWorld::Ptr &ptr, int skill) const;
|
||||
virtual float getSkill(const MWWorld::Ptr &ptr, int skill) const;
|
||||
|
||||
/// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini)
|
||||
virtual int getBloodTexture (const MWWorld::ConstPtr& ptr) const;
|
||||
|
@ -125,7 +125,7 @@ namespace MWClass
|
||||
}
|
||||
|
||||
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
||||
int alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy);
|
||||
float alchemySkill = player.getClass().getSkill(player, ESM::Skill::Alchemy);
|
||||
|
||||
static const float fWortChanceValue =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWortChanceValue")->mValue.getFloat();
|
||||
|
@ -127,8 +127,8 @@ namespace
|
||||
}
|
||||
|
||||
// initial health
|
||||
int strength = creatureStats.getAttribute(ESM::Attribute::Strength).getBase();
|
||||
int endurance = creatureStats.getAttribute(ESM::Attribute::Endurance).getBase();
|
||||
float strength = creatureStats.getAttribute(ESM::Attribute::Strength).getBase();
|
||||
float endurance = creatureStats.getAttribute(ESM::Attribute::Endurance).getBase();
|
||||
|
||||
int multiplier = 3;
|
||||
|
||||
@ -1011,7 +1011,7 @@ namespace MWClass
|
||||
gmst.fJumpEncumbranceMultiplier->mValue.getFloat() *
|
||||
(1.0f - Npc::getNormalizedEncumbrance(ptr));
|
||||
|
||||
float a = static_cast<float>(getSkill(ptr, ESM::Skill::Acrobatics));
|
||||
float a = getSkill(ptr, ESM::Skill::Acrobatics);
|
||||
float b = 0.0f;
|
||||
if(a > 50.0f)
|
||||
{
|
||||
@ -1136,7 +1136,7 @@ namespace MWClass
|
||||
|
||||
float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat();
|
||||
float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat();
|
||||
int unarmoredSkill = getSkill(ptr, ESM::Skill::Unarmored);
|
||||
float unarmoredSkill = getSkill(ptr, ESM::Skill::Unarmored);
|
||||
|
||||
float ratings[MWWorld::InventoryStore::Slots];
|
||||
for(int i = 0;i < MWWorld::InventoryStore::Slots;i++)
|
||||
@ -1283,7 +1283,7 @@ namespace MWClass
|
||||
return MWWorld::Ptr(cell.insert(ref), &cell);
|
||||
}
|
||||
|
||||
int Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const
|
||||
float Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const
|
||||
{
|
||||
return getNpcStats(ptr).getSkill(skill).getModified();
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ namespace MWClass
|
||||
|
||||
virtual std::string getModel(const MWWorld::ConstPtr &ptr) const;
|
||||
|
||||
virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const;
|
||||
virtual float getSkill(const MWWorld::Ptr& ptr, int skill) const;
|
||||
|
||||
/// Get a blood texture suitable for \a ptr (see Blood Texture 0-2 in Morrowind.ini)
|
||||
virtual int getBloodTexture (const MWWorld::ConstPtr& ptr) const;
|
||||
|
@ -95,9 +95,9 @@ namespace MWGui
|
||||
|
||||
MWMechanics::SkillValue& value = player.getClass().getNpcStats(player).getSkill(skill);
|
||||
if (skill == ESM::Skill::Security || skill == ESM::Skill::Sneak)
|
||||
value.setBase(std::min(100, value.getBase()+1));
|
||||
value.setBase(std::min(100.f, value.getBase()+1));
|
||||
else
|
||||
value.setBase(std::max(0, value.getBase()-1));
|
||||
value.setBase(std::max(0.f, value.getBase()-1));
|
||||
}
|
||||
|
||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
@ -157,7 +157,7 @@ namespace MWGui
|
||||
mAttributeValues[i]->setEnabled(true);
|
||||
availableAttributes++;
|
||||
|
||||
int mult = pcStats.getLevelupAttributeMultiplier (i);
|
||||
float mult = pcStats.getLevelupAttributeMultiplier (i);
|
||||
mult = std::min(mult, 100-pcStats.getAttribute(i).getBase());
|
||||
text->setCaption(mult <= 1 ? "" : "x" + MyGUI::utility::toString(mult));
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace MWGui
|
||||
{
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
mSourceModel = sourceModel;
|
||||
int chance = player.getClass().getSkill(player, ESM::Skill::Sneak);
|
||||
float chance = player.getClass().getSkill(player, ESM::Skill::Sneak);
|
||||
|
||||
mSourceModel->update();
|
||||
|
||||
|
@ -159,7 +159,7 @@ namespace MWGui
|
||||
for (int i=0; ids[i]; ++i)
|
||||
if (ids[i]==id)
|
||||
{
|
||||
setText (id, std::to_string(value.getModified()));
|
||||
setText (id, std::to_string(static_cast<int>(value.getModified())));
|
||||
|
||||
MyGUI::TextBox* box;
|
||||
getWidget(box, id);
|
||||
|
@ -74,11 +74,11 @@ namespace MWGui
|
||||
mPlayerGold->setCaptionWithReplacing("#{sGold}: " + MyGUI::utility::toString(playerGold));
|
||||
|
||||
// NPC can train you in his best 3 skills
|
||||
std::vector< std::pair<int, int> > skills;
|
||||
std::vector< std::pair<int, float> > skills;
|
||||
|
||||
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||
{
|
||||
int value = actor.getClass().getSkill(actor, i);
|
||||
float value = actor.getClass().getSkill(actor, i);
|
||||
|
||||
skills.push_back(std::make_pair(i, value));
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ void getRestorationPerHourOfSleep (const MWWorld::Ptr& ptr, float& health, float
|
||||
MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats (ptr);
|
||||
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||
float endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||
health = 0.1f * endurance;
|
||||
|
||||
float fRestMagicMult = settings.find("fRestMagicMult")->mValue.getFloat ();
|
||||
@ -765,7 +765,7 @@ namespace MWMechanics
|
||||
{
|
||||
CreatureStats& creatureStats = ptr.getClass().getCreatureStats (ptr);
|
||||
|
||||
int intelligence = creatureStats.getAttribute(ESM::Attribute::Intelligence).getModified();
|
||||
float intelligence = creatureStats.getAttribute(ESM::Attribute::Intelligence).getModified();
|
||||
|
||||
float base = 1.f;
|
||||
if (ptr == getPlayer())
|
||||
@ -844,7 +844,7 @@ namespace MWMechanics
|
||||
float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat ();
|
||||
float fEndFatigueMult = settings.find("fEndFatigueMult")->mValue.getFloat ();
|
||||
|
||||
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||
float endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||
|
||||
float normalizedEncumbrance = ptr.getClass().getNormalizedEncumbrance(ptr);
|
||||
if (normalizedEncumbrance > 1)
|
||||
@ -871,7 +871,7 @@ namespace MWMechanics
|
||||
return;
|
||||
|
||||
// Restore fatigue
|
||||
int endurance = stats.getAttribute(ESM::Attribute::Endurance).getModified();
|
||||
float endurance = stats.getAttribute(ESM::Attribute::Endurance).getModified();
|
||||
const MWWorld::Store<ESM::GameSetting>& settings = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
static const float fFatigueReturnBase = settings.find("fFatigueReturnBase")->mValue.getFloat ();
|
||||
static const float fFatigueReturnMult = settings.find("fFatigueReturnMult")->mValue.getFloat ();
|
||||
|
@ -468,7 +468,7 @@ MWMechanics::Alchemy::TEffectsIterator MWMechanics::Alchemy::endEffects() const
|
||||
|
||||
bool MWMechanics::Alchemy::knownEffect(unsigned int potionEffectIndex, const MWWorld::Ptr &npc)
|
||||
{
|
||||
int alchemySkill = npc.getClass().getSkill (npc, ESM::Skill::Alchemy);
|
||||
float alchemySkill = npc.getClass().getSkill (npc, ESM::Skill::Alchemy);
|
||||
static const float fWortChanceValue =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fWortChanceValue")->mValue.getFloat();
|
||||
return (potionEffectIndex <= 1 && alchemySkill >= fWortChanceValue)
|
||||
|
@ -2128,7 +2128,7 @@ void CharacterController::update(float duration, bool animationOnly)
|
||||
cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), osg::Vec3f(), true);
|
||||
}
|
||||
|
||||
const int acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics);
|
||||
const float acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics);
|
||||
if (healthLost > (acrobaticsSkill * fatigueTerm))
|
||||
{
|
||||
if (!godmode)
|
||||
|
@ -101,7 +101,7 @@ namespace MWMechanics
|
||||
blockerTerm *= gmst.find("fBlockStillBonus")->mValue.getFloat();
|
||||
blockerTerm *= blockerStats.getFatigueTerm();
|
||||
|
||||
int attackerSkill = 0;
|
||||
float attackerSkill = 0;
|
||||
if (weapon.isEmpty())
|
||||
attackerSkill = attacker.getClass().getSkill(attacker, ESM::Skill::HandToHand);
|
||||
else
|
||||
|
@ -126,7 +126,7 @@ namespace MWMechanics
|
||||
return mMagicEffects;
|
||||
}
|
||||
|
||||
void CreatureStats::setAttribute(int index, int base)
|
||||
void CreatureStats::setAttribute(int index, float base)
|
||||
{
|
||||
AttributeValue current = getAttribute(index);
|
||||
current.setBase(base);
|
||||
@ -152,10 +152,10 @@ namespace MWMechanics
|
||||
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();
|
||||
float strength = getAttribute(ESM::Attribute::Strength).getModified();
|
||||
float willpower = getAttribute(ESM::Attribute::Willpower).getModified();
|
||||
float agility = getAttribute(ESM::Attribute::Agility).getModified();
|
||||
float endurance = getAttribute(ESM::Attribute::Endurance).getModified();
|
||||
DynamicStat<float> fatigue = getFatigue();
|
||||
float diff = (strength+willpower+agility+endurance) - fatigue.getBase();
|
||||
float currentToBaseRatio = fatigue.getBase() > 0 ? (fatigue.getCurrent() / fatigue.getBase()) : 0;
|
||||
|
@ -138,7 +138,7 @@ namespace MWMechanics
|
||||
|
||||
void setAttribute(int index, const AttributeValue &value);
|
||||
// Shortcut to set only the base
|
||||
void setAttribute(int index, int base);
|
||||
void setAttribute(int index, float base);
|
||||
|
||||
void setHealth(const DynamicStat<float> &value);
|
||||
|
||||
|
@ -688,10 +688,10 @@ namespace MWMechanics
|
||||
// I suppose the temporary disposition change (second param to getDerivedDisposition()) _has_ to be considered here,
|
||||
// otherwise one would get different prices when exiting and re-entering the dialogue window...
|
||||
int clampedDisposition = getDerivedDisposition(ptr);
|
||||
float a = static_cast<float>(std::min(playerPtr.getClass().getSkill(playerPtr, ESM::Skill::Mercantile), 100));
|
||||
float a = std::min(playerPtr.getClass().getSkill(playerPtr, ESM::Skill::Mercantile), 100.f);
|
||||
float b = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
|
||||
float c = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
|
||||
float d = static_cast<float>(std::min(ptr.getClass().getSkill(ptr, ESM::Skill::Mercantile), 100));
|
||||
float d = std::min(ptr.getClass().getSkill(ptr, ESM::Skill::Mercantile), 100.f);
|
||||
float e = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
|
||||
float f = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
|
||||
float pcTerm = (clampedDisposition - 50 + a + b + c) * playerStats.getFatigueTerm();
|
||||
@ -1621,8 +1621,8 @@ namespace MWMechanics
|
||||
static float fSneakSkillMult = store.find("fSneakSkillMult")->mValue.getFloat();
|
||||
static float fSneakBootMult = store.find("fSneakBootMult")->mValue.getFloat();
|
||||
float sneak = static_cast<float>(ptr.getClass().getSkill(ptr, ESM::Skill::Sneak));
|
||||
int agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||
int luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||
float luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float bootWeight = 0;
|
||||
if (ptr.getClass().isNpc() && MWBase::Environment::get().getWorld()->isOnGround(ptr))
|
||||
{
|
||||
@ -1645,10 +1645,10 @@ namespace MWMechanics
|
||||
float x = sneakTerm * distTerm * stats.getFatigueTerm() + chameleon + invisibility;
|
||||
|
||||
CreatureStats& observerStats = observer.getClass().getCreatureStats(observer);
|
||||
int obsAgility = observerStats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||
int obsLuck = observerStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float obsAgility = observerStats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||
float obsLuck = observerStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float obsBlind = observerStats.getMagicEffects().get(ESM::MagicEffect::Blind).getMagnitude();
|
||||
int obsSneak = observer.getClass().getSkill(observer, ESM::Skill::Sneak);
|
||||
float obsSneak = observer.getClass().getSkill(observer, ESM::Skill::Sneak);
|
||||
|
||||
float obsTerm = obsSneak + 0.2f * obsAgility + 0.1f * obsLuck - obsBlind;
|
||||
|
||||
|
@ -226,9 +226,9 @@ void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_,
|
||||
|
||||
void MWMechanics::NpcStats::increaseSkill(int skillIndex, const ESM::Class &class_, bool preserveProgress, bool readBook)
|
||||
{
|
||||
int base = getSkill (skillIndex).getBase();
|
||||
float base = getSkill (skillIndex).getBase();
|
||||
|
||||
if (base >= 100)
|
||||
if (base >= 100.f)
|
||||
return;
|
||||
|
||||
base += 1;
|
||||
@ -299,7 +299,7 @@ void MWMechanics::NpcStats::levelUp()
|
||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||
mSkillIncreases[i] = 0;
|
||||
|
||||
const int endurance = getAttribute(ESM::Attribute::Endurance).getBase();
|
||||
const float endurance = getAttribute(ESM::Attribute::Endurance).getBase();
|
||||
|
||||
// "When you gain a level, in addition to increasing three primary attributes, your Health
|
||||
// will automatically increase by 10% of your Endurance attribute. If you increased Endurance this level,
|
||||
@ -316,8 +316,8 @@ void MWMechanics::NpcStats::levelUp()
|
||||
|
||||
void MWMechanics::NpcStats::updateHealth()
|
||||
{
|
||||
const int endurance = getAttribute(ESM::Attribute::Endurance).getBase();
|
||||
const int strength = getAttribute(ESM::Attribute::Strength).getBase();
|
||||
const float endurance = getAttribute(ESM::Attribute::Endurance).getBase();
|
||||
const float strength = getAttribute(ESM::Attribute::Strength).getBase();
|
||||
|
||||
setHealth(floor(0.5f * (strength + endurance)));
|
||||
}
|
||||
|
@ -22,8 +22,8 @@ namespace MWMechanics
|
||||
float Pickpocket::getChanceModifier(const MWWorld::Ptr &ptr, float add)
|
||||
{
|
||||
NpcStats& stats = ptr.getClass().getNpcStats(ptr);
|
||||
float agility = static_cast<float>(stats.getAttribute(ESM::Attribute::Agility).getModified());
|
||||
float luck = static_cast<float>(stats.getAttribute(ESM::Attribute::Luck).getModified());
|
||||
float agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||
float luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float sneak = static_cast<float>(ptr.getClass().getSkill(ptr, ESM::Skill::Sneak));
|
||||
return (add + 0.2f * agility + 0.1f * luck + sneak) * stats.getFatigueTerm();
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ void Repair::repair(const MWWorld::Ptr &itemToRepair)
|
||||
MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player);
|
||||
|
||||
float fatigueTerm = stats.getFatigueTerm();
|
||||
int pcStrength = stats.getAttribute(ESM::Attribute::Strength).getModified();
|
||||
int pcLuck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
int armorerSkill = player.getClass().getSkill(player, ESM::Skill::Armorer);
|
||||
float pcStrength = stats.getAttribute(ESM::Attribute::Strength).getModified();
|
||||
float pcLuck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float armorerSkill = player.getClass().getSkill(player, ESM::Skill::Armorer);
|
||||
|
||||
float fRepairAmountMult = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||
.find("fRepairAmountMult")->mValue.getFloat();
|
||||
|
@ -19,8 +19,8 @@ namespace MWMechanics
|
||||
: mActor(actor)
|
||||
{
|
||||
CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor);
|
||||
mAgility = static_cast<float>(creatureStats.getAttribute(ESM::Attribute::Agility).getModified());
|
||||
mLuck = static_cast<float>(creatureStats.getAttribute(ESM::Attribute::Luck).getModified());
|
||||
mAgility = creatureStats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||
mLuck = creatureStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
mSecuritySkill = static_cast<float>(actor.getClass().getSkill(actor, ESM::Skill::Security));
|
||||
mFatigueTerm = creatureStats.getFatigueTerm();
|
||||
}
|
||||
|
@ -40,8 +40,8 @@ namespace MWMechanics
|
||||
|
||||
float resistance = getEffectResistanceAttribute(effectId, magicEffects);
|
||||
|
||||
int willpower = stats.getAttribute(ESM::Attribute::Willpower).getModified();
|
||||
float luck = static_cast<float>(stats.getAttribute(ESM::Attribute::Luck).getModified());
|
||||
float willpower = stats.getAttribute(ESM::Attribute::Willpower).getModified();
|
||||
float luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float x = (willpower + 0.1f * luck) * stats.getFatigueTerm();
|
||||
|
||||
// This makes spells that are easy to cast harder to resist and vice versa
|
||||
|
@ -94,8 +94,8 @@ namespace MWMechanics
|
||||
|
||||
CreatureStats& stats = actor.getClass().getCreatureStats(actor);
|
||||
|
||||
int actorWillpower = stats.getAttribute(ESM::Attribute::Willpower).getModified();
|
||||
int actorLuck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
float actorWillpower = stats.getAttribute(ESM::Attribute::Willpower).getModified();
|
||||
float actorLuck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||
|
||||
float castChance = (lowestSkill - spell->mData.mCost + 0.2f * actorWillpower + 0.1f * actorLuck);
|
||||
|
||||
|
@ -227,29 +227,29 @@ namespace MWMechanics
|
||||
}
|
||||
|
||||
AttributeValue::AttributeValue() :
|
||||
mBase(0), mModifier(0), mDamage(0)
|
||||
mBase(0.f), mModifier(0.f), mDamage(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
int AttributeValue::getModified() const
|
||||
float AttributeValue::getModified() const
|
||||
{
|
||||
return std::max(0, mBase - (int) mDamage + mModifier);
|
||||
return std::max(0.f, mBase - mDamage + mModifier);
|
||||
}
|
||||
int AttributeValue::getBase() const
|
||||
float AttributeValue::getBase() const
|
||||
{
|
||||
return mBase;
|
||||
}
|
||||
int AttributeValue::getModifier() const
|
||||
float AttributeValue::getModifier() const
|
||||
{
|
||||
return mModifier;
|
||||
}
|
||||
|
||||
void AttributeValue::setBase(int base)
|
||||
void AttributeValue::setBase(float base)
|
||||
{
|
||||
mBase = base;
|
||||
}
|
||||
|
||||
void AttributeValue::setModifier(int mod)
|
||||
void AttributeValue::setModifier(float mod)
|
||||
{
|
||||
mModifier = mod;
|
||||
}
|
||||
@ -275,14 +275,14 @@ namespace MWMechanics
|
||||
return mDamage;
|
||||
}
|
||||
|
||||
void AttributeValue::writeState (ESM::StatState<int>& state) const
|
||||
void AttributeValue::writeState (ESM::StatState<float>& state) const
|
||||
{
|
||||
state.mBase = mBase;
|
||||
state.mMod = mModifier;
|
||||
state.mDamage = mDamage;
|
||||
}
|
||||
|
||||
void AttributeValue::readState (const ESM::StatState<int>& state)
|
||||
void AttributeValue::readState (const ESM::StatState<float>& state)
|
||||
{
|
||||
mBase = state.mBase;
|
||||
mModifier = state.mMod;
|
||||
@ -303,13 +303,13 @@ namespace MWMechanics
|
||||
mProgress = progress;
|
||||
}
|
||||
|
||||
void SkillValue::writeState (ESM::StatState<int>& state) const
|
||||
void SkillValue::writeState (ESM::StatState<float>& state) const
|
||||
{
|
||||
AttributeValue::writeState (state);
|
||||
state.mProgress = mProgress;
|
||||
}
|
||||
|
||||
void SkillValue::readState (const ESM::StatState<int>& state)
|
||||
void SkillValue::readState (const ESM::StatState<float>& state)
|
||||
{
|
||||
AttributeValue::readState (state);
|
||||
mProgress = state.mProgress;
|
||||
|
@ -122,20 +122,20 @@ namespace MWMechanics
|
||||
|
||||
class AttributeValue
|
||||
{
|
||||
int mBase;
|
||||
int mModifier;
|
||||
float mBase;
|
||||
float mModifier;
|
||||
float mDamage; // needs to be float to allow continuous damage
|
||||
|
||||
public:
|
||||
AttributeValue();
|
||||
|
||||
int getModified() const;
|
||||
int getBase() const;
|
||||
int getModifier() const;
|
||||
float getModified() const;
|
||||
float getBase() const;
|
||||
float getModifier() const;
|
||||
|
||||
void setBase(int base);
|
||||
void setBase(float base);
|
||||
|
||||
void setModifier(int mod);
|
||||
void setModifier(float mod);
|
||||
|
||||
// Maximum attribute damage is limited to the modified value.
|
||||
// Note: I think MW applies damage directly to mModified, since you can also
|
||||
@ -145,8 +145,8 @@ namespace MWMechanics
|
||||
|
||||
float getDamage() const;
|
||||
|
||||
void writeState (ESM::StatState<int>& state) const;
|
||||
void readState (const ESM::StatState<int>& state);
|
||||
void writeState (ESM::StatState<float>& state) const;
|
||||
void readState (const ESM::StatState<float>& state);
|
||||
};
|
||||
|
||||
class SkillValue : public AttributeValue
|
||||
@ -157,8 +157,8 @@ namespace MWMechanics
|
||||
float getProgress() const;
|
||||
void setProgress(float progress);
|
||||
|
||||
void writeState (ESM::StatState<int>& state) const;
|
||||
void readState (const ESM::StatState<int>& state);
|
||||
void writeState (ESM::StatState<float>& state) const;
|
||||
void readState (const ESM::StatState<float>& state);
|
||||
};
|
||||
|
||||
inline bool operator== (const AttributeValue& left, const AttributeValue& right)
|
||||
|
@ -95,7 +95,7 @@ namespace MWScript
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value =
|
||||
Interpreter::Type_Float value =
|
||||
ptr.getClass()
|
||||
.getCreatureStats (ptr)
|
||||
.getAttribute(mIndex)
|
||||
@ -118,7 +118,7 @@ namespace MWScript
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
Interpreter::Type_Float value = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
MWMechanics::AttributeValue attribute = ptr.getClass().getCreatureStats(ptr).getAttribute(mIndex);
|
||||
@ -140,7 +140,7 @@ namespace MWScript
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
Interpreter::Type_Float value = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
MWMechanics::AttributeValue attribute = ptr.getClass()
|
||||
@ -155,9 +155,9 @@ namespace MWScript
|
||||
return;
|
||||
|
||||
if (value < 0)
|
||||
attribute.setBase(std::max(0, attribute.getBase() + value));
|
||||
attribute.setBase(std::max(0.f, attribute.getBase() + value));
|
||||
else
|
||||
attribute.setBase(std::min(100, attribute.getBase() + value));
|
||||
attribute.setBase(std::min(100.f, attribute.getBase() + value));
|
||||
|
||||
ptr.getClass().getCreatureStats(ptr).setAttribute(mIndex, attribute);
|
||||
}
|
||||
@ -345,7 +345,7 @@ namespace MWScript
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = ptr.getClass().getSkill(ptr, mIndex);
|
||||
Interpreter::Type_Float value = ptr.getClass().getSkill(ptr, mIndex);
|
||||
|
||||
runtime.push (value);
|
||||
}
|
||||
@ -364,7 +364,7 @@ namespace MWScript
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
Interpreter::Type_Float value = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
MWMechanics::NpcStats& stats = ptr.getClass().getNpcStats (ptr);
|
||||
@ -386,7 +386,7 @@ namespace MWScript
|
||||
{
|
||||
MWWorld::Ptr ptr = R()(runtime);
|
||||
|
||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
||||
Interpreter::Type_Float value = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
MWMechanics::SkillValue &skill = ptr.getClass()
|
||||
@ -396,14 +396,14 @@ namespace MWScript
|
||||
if (value == 0)
|
||||
return;
|
||||
|
||||
if (((skill.getBase() <= 0) && (value < 0))
|
||||
|| ((skill.getBase() >= 100) && (value > 0)))
|
||||
if (((skill.getBase() <= 0.f) && (value < 0.f))
|
||||
|| ((skill.getBase() >= 100.f) && (value > 0.f)))
|
||||
return;
|
||||
|
||||
if (value < 0)
|
||||
skill.setBase(std::max(0, skill.getBase() + value));
|
||||
skill.setBase(std::max(0.f, skill.getBase() + value));
|
||||
else
|
||||
skill.setBase(std::min(100, skill.getBase() + value));
|
||||
skill.setBase(std::min(100.f, skill.getBase() + value));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -421,7 +421,7 @@ namespace MWWorld
|
||||
return canSwim(ptr) || canWalk(ptr) || canFly(ptr);
|
||||
}
|
||||
|
||||
int Class::getSkill(const MWWorld::Ptr& ptr, int skill) const
|
||||
float Class::getSkill(const MWWorld::Ptr& ptr, int skill) const
|
||||
{
|
||||
throw std::runtime_error("class does not support skills");
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ namespace MWWorld
|
||||
bool isPureLandCreature(const MWWorld::Ptr& ptr) const;
|
||||
bool isMobile(const MWWorld::Ptr& ptr) const;
|
||||
|
||||
virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const;
|
||||
virtual float getSkill(const MWWorld::Ptr& ptr, int skill) const;
|
||||
|
||||
virtual void readAdditionalState (const MWWorld::Ptr& ptr, const ESM::ObjectState& state)
|
||||
const;
|
||||
|
@ -284,12 +284,12 @@ void MWWorld::InventoryStore::autoEquipWeapon (const MWWorld::Ptr& actor, TSlots
|
||||
// rate weapon
|
||||
for (int i = 0; i < static_cast<int>(weaponSkillsLength); ++i)
|
||||
{
|
||||
int max = 0;
|
||||
float max = 0;
|
||||
int maxWeaponSkill = -1;
|
||||
|
||||
for (int j = 0; j < static_cast<int>(weaponSkillsLength); ++j)
|
||||
{
|
||||
int skillValue = actor.getClass().getSkill(actor, static_cast<int>(weaponSkills[j]));
|
||||
float skillValue = actor.getClass().getSkill(actor, static_cast<int>(weaponSkills[j]));
|
||||
if (skillValue > max && !weaponSkillVisited[j])
|
||||
{
|
||||
max = skillValue;
|
||||
@ -399,7 +399,7 @@ void MWWorld::InventoryStore::autoEquipArmor (const MWWorld::Ptr& actor, TSlots&
|
||||
static float fUnarmoredBase1 = store.find("fUnarmoredBase1")->mValue.getFloat();
|
||||
static float fUnarmoredBase2 = store.find("fUnarmoredBase2")->mValue.getFloat();
|
||||
|
||||
int unarmoredSkill = actor.getClass().getSkill(actor, ESM::Skill::Unarmored);
|
||||
float unarmoredSkill = actor.getClass().getSkill(actor, ESM::Skill::Unarmored);
|
||||
float unarmoredRating = (fUnarmoredBase1 * unarmoredSkill) * (fUnarmoredBase2 * unarmoredSkill);
|
||||
|
||||
for (ContainerStoreIterator iter (begin(ContainerStore::Type_Clothing | ContainerStore::Type_Armor)); iter!=end(); ++iter)
|
||||
|
@ -423,13 +423,13 @@ namespace Compiler
|
||||
|
||||
for (int i=0; i<numberOfAttributes; ++i)
|
||||
{
|
||||
extensions.registerFunction (get + attributes[i], 'l', "",
|
||||
extensions.registerFunction (get + attributes[i], 'f', "",
|
||||
opcodeGetAttribute+i, opcodeGetAttributeExplicit+i);
|
||||
|
||||
extensions.registerInstruction (set + attributes[i], "l",
|
||||
extensions.registerInstruction (set + attributes[i], "f",
|
||||
opcodeSetAttribute+i, opcodeSetAttributeExplicit+i);
|
||||
|
||||
extensions.registerInstruction (mod + attributes[i], "l",
|
||||
extensions.registerInstruction (mod + attributes[i], "f",
|
||||
opcodeModAttribute+i, opcodeModAttributeExplicit+i);
|
||||
}
|
||||
|
||||
@ -453,13 +453,13 @@ namespace Compiler
|
||||
|
||||
for (int i=0; i<numberOfSkills; ++i)
|
||||
{
|
||||
extensions.registerFunction (get + skills[i], 'l', "",
|
||||
extensions.registerFunction (get + skills[i], 'f', "",
|
||||
opcodeGetSkill+i, opcodeGetSkillExplicit+i);
|
||||
|
||||
extensions.registerInstruction (set + skills[i], "l",
|
||||
extensions.registerInstruction (set + skills[i], "f",
|
||||
opcodeSetSkill+i, opcodeSetSkillExplicit+i);
|
||||
|
||||
extensions.registerInstruction (mod + skills[i], "l",
|
||||
extensions.registerInstruction (mod + skills[i], "f",
|
||||
opcodeModSkill+i, opcodeModSkillExplicit+i);
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,9 @@
|
||||
|
||||
void ESM::CreatureStats::load (ESMReader &esm)
|
||||
{
|
||||
bool intFallback = esm.getFormat() < 11;
|
||||
for (int i=0; i<8; ++i)
|
||||
mAttributes[i].load (esm);
|
||||
mAttributes[i].load (esm, intFallback);
|
||||
|
||||
for (int i=0; i<3; ++i)
|
||||
mDynamic[i].load (esm);
|
||||
|
@ -29,7 +29,7 @@ namespace ESM
|
||||
TimeStamp mNextWorsening;
|
||||
};
|
||||
|
||||
StatState<int> mAttributes[Attribute::Length];
|
||||
StatState<float> mAttributes[Attribute::Length];
|
||||
StatState<float> mDynamic[3];
|
||||
|
||||
MagicEffects mMagicEffects;
|
||||
|
@ -31,8 +31,9 @@ void ESM::NpcStats::load (ESMReader &esm)
|
||||
mDisposition = 0;
|
||||
esm.getHNOT (mDisposition, "DISP");
|
||||
|
||||
bool intFallback = esm.getFormat() < 11;
|
||||
for (int i=0; i<27; ++i)
|
||||
mSkills[i].load (esm);
|
||||
mSkills[i].load (esm, intFallback);
|
||||
|
||||
mWerewolfDeprecatedData = false;
|
||||
if (esm.getFormat() < 8 && esm.peekNextSub("STBA"))
|
||||
@ -40,17 +41,17 @@ void ESM::NpcStats::load (ESMReader &esm)
|
||||
// we have deprecated werewolf skills, stored interleaved
|
||||
// Load into one big vector, then remove every 2nd value
|
||||
mWerewolfDeprecatedData = true;
|
||||
std::vector<ESM::StatState<int> > skills(mSkills, mSkills + sizeof(mSkills)/sizeof(mSkills[0]));
|
||||
std::vector<ESM::StatState<float> > skills(mSkills, mSkills + sizeof(mSkills)/sizeof(mSkills[0]));
|
||||
|
||||
for (int i=0; i<27; ++i)
|
||||
{
|
||||
ESM::StatState<int> skill;
|
||||
skill.load(esm);
|
||||
ESM::StatState<float> skill;
|
||||
skill.load(esm, intFallback);
|
||||
skills.push_back(skill);
|
||||
}
|
||||
|
||||
int i=0;
|
||||
for (std::vector<ESM::StatState<int> >::iterator it = skills.begin(); it != skills.end(); ++i)
|
||||
for (std::vector<ESM::StatState<float> >::iterator it = skills.begin(); it != skills.end(); ++i)
|
||||
{
|
||||
if (i%2 == 1)
|
||||
it = skills.erase(it);
|
||||
@ -68,7 +69,7 @@ void ESM::NpcStats::load (ESMReader &esm)
|
||||
{
|
||||
ESM::StatState<int> dummy;
|
||||
for (int i=0; i<8; ++i)
|
||||
dummy.load(esm);
|
||||
dummy.load(esm, intFallback);
|
||||
mWerewolfDeprecatedData = true;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ namespace ESM
|
||||
|
||||
std::map<std::string, Faction> mFactions; // lower case IDs
|
||||
int mDisposition;
|
||||
StatState<int> mSkills[27];
|
||||
StatState<float> mSkills[27];
|
||||
int mBounty;
|
||||
int mReputation;
|
||||
int mWerewolfKills;
|
||||
|
@ -43,12 +43,13 @@ void ESM::Player::load (ESMReader &esm)
|
||||
checkPrevItems = false;
|
||||
}
|
||||
|
||||
bool intFallback = esm.getFormat() < 11;
|
||||
if (esm.hasMoreSubs())
|
||||
{
|
||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||
mSaveAttributes[i].load(esm);
|
||||
mSaveAttributes[i].load(esm, intFallback);
|
||||
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||
mSaveSkills[i].load(esm);
|
||||
mSaveSkills[i].load(esm, intFallback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,8 @@ namespace ESM
|
||||
int mCurrentCrimeId;
|
||||
int mPaidCrimeId;
|
||||
|
||||
StatState<int> mSaveAttributes[ESM::Attribute::Length];
|
||||
StatState<int> mSaveSkills[ESM::Skill::Length];
|
||||
StatState<float> mSaveAttributes[ESM::Attribute::Length];
|
||||
StatState<float> mSaveSkills[ESM::Skill::Length];
|
||||
|
||||
typedef std::map<std::string, std::string> PreviousItems; // previous equipped items, needed for bound spells
|
||||
PreviousItems mPreviousItems;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "defs.hpp"
|
||||
|
||||
unsigned int ESM::SavedGame::sRecordId = ESM::REC_SAVE;
|
||||
int ESM::SavedGame::sCurrentFormat = 10;
|
||||
int ESM::SavedGame::sCurrentFormat = 11;
|
||||
|
||||
void ESM::SavedGame::load (ESMReader &esm)
|
||||
{
|
||||
|
@ -9,19 +9,44 @@ namespace ESM
|
||||
StatState<T>::StatState() : mBase(0), mMod(0), mCurrent(0), mDamage(0), mProgress(0) {}
|
||||
|
||||
template<typename T>
|
||||
void StatState<T>::load(ESMReader &esm)
|
||||
void StatState<T>::load(ESMReader &esm, bool intFallback)
|
||||
{
|
||||
// We changed stats values from integers to floats; ensure backwards compatibility
|
||||
if (intFallback)
|
||||
{
|
||||
int base = 0;
|
||||
esm.getHNT(base, "STBA");
|
||||
mBase = static_cast<float>(base);
|
||||
|
||||
int mod = 0;
|
||||
esm.getHNOT(mod, "STMO");
|
||||
mMod = static_cast<float>(mod);
|
||||
|
||||
int current = 0;
|
||||
esm.getHNOT(current, "STCU");
|
||||
mCurrent = static_cast<float>(current);
|
||||
|
||||
// mDamage was changed to a float; ensure backwards compatibility
|
||||
int oldDamage = 0;
|
||||
esm.getHNOT(oldDamage, "STDA");
|
||||
mDamage = static_cast<float>(oldDamage);
|
||||
}
|
||||
else
|
||||
{
|
||||
mBase = 0;
|
||||
esm.getHNT(mBase, "STBA");
|
||||
|
||||
mMod = 0;
|
||||
esm.getHNOT(mMod, "STMO");
|
||||
|
||||
mCurrent = 0;
|
||||
esm.getHNOT(mCurrent, "STCU");
|
||||
|
||||
// mDamage was changed to a float; ensure backwards compatibility
|
||||
T oldDamage = 0;
|
||||
esm.getHNOT(oldDamage, "STDA");
|
||||
mDamage = static_cast<float>(oldDamage);
|
||||
mDamage = 0;
|
||||
esm.getHNOT(mDamage, "STDF");
|
||||
|
||||
mProgress = 0;
|
||||
}
|
||||
|
||||
esm.getHNOT(mDamage, "STDF");
|
||||
|
||||
|
@ -20,7 +20,7 @@ namespace ESM
|
||||
|
||||
StatState();
|
||||
|
||||
void load (ESMReader &esm);
|
||||
void load (ESMReader &esm, bool intFallback = false);
|
||||
void save (ESMWriter &esm) const;
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user