1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-21 07:53:53 +00:00

Added getSkill to Class interface, since creatures also have skills (which are provided by generalized Combat, Magic and Stealth attributes which substitute for the specific skills, in the same way as specialization)

Information provided by Hrnchamd.
This commit is contained in:
scrawl 2014-01-15 15:50:45 +01:00
parent 7534fc968d
commit d544551f61
15 changed files with 60 additions and 35 deletions

View file

@ -461,6 +461,26 @@ namespace MWClass
throw std::runtime_error(std::string("Unexpected soundgen type: ")+name);
}
int Creature::getSkill(const MWWorld::Ptr &ptr, int skill) const
{
MWWorld::LiveCellRef<ESM::Creature> *ref =
ptr.get<ESM::Creature>();
const ESM::Skill* skillRecord = MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find(skill);
switch (skillRecord->mData.mSpecialization)
{
case ESM::Class::Combat:
return ref->mBase->mData.mCombat;
case ESM::Class::Magic:
return ref->mBase->mData.mMagic;
case ESM::Class::Stealth:
return ref->mBase->mData.mStealth;
default:
throw std::runtime_error("invalid specialisation");
}
}
const ESM::GameSetting* Creature::fMinWalkSpeedCreature;
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
}

View file

@ -101,6 +101,8 @@ namespace MWClass
}
virtual bool isFlying (const MWWorld::Ptr &ptr) const;
virtual int getSkill(const MWWorld::Ptr &ptr, int skill) const;
};
}

View file

@ -1211,6 +1211,11 @@ namespace MWClass
return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell);
}
int Npc::getSkill(const MWWorld::Ptr& ptr, int skill) const
{
return ptr.getClass().getNpcStats(ptr).getSkill(skill).getModified();
}
const ESM::GameSetting *Npc::fMinWalkSpeed;
const ESM::GameSetting *Npc::fMaxWalkSpeed;
const ESM::GameSetting *Npc::fEncumberedMoveEffect;

View file

@ -140,6 +140,8 @@ namespace MWClass
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const;
virtual bool isActor() const {
return true;
}

View file

@ -9,7 +9,7 @@ namespace MWGui
PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& thief, ItemModel *sourceModel)
{
mSourceModel = sourceModel;
int chance = MWWorld::Class::get(thief).getNpcStats(thief).getSkill(ESM::Skill::Sneak).getModified();
int chance = thief.getClass().getSkill(thief, ESM::Skill::Sneak);
mSourceModel->update();
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)

View file

@ -296,10 +296,10 @@ namespace MWGui
const MWMechanics::NpcStats &sellerStats = mPtr.getClass().getNpcStats(mPtr);
const MWMechanics::NpcStats &playerStats = player.getClass().getNpcStats(player);
float a1 = std::min(playerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100);
float a1 = std::min(player.getClass().getSkill(player, ESM::Skill::Mercantile), 100);
float b1 = std::min(0.1f * playerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
float c1 = std::min(0.2f * playerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
float d1 = std::min(sellerStats.getSkill(ESM::Skill::Mercantile).getModified(), 100);
float d1 = std::min(mPtr.getClass().getSkill(mPtr, ESM::Skill::Mercantile), 100);
float e1 = std::min(0.1f * sellerStats.getAttribute(ESM::Attribute::Luck).getModified(), 10.f);
float f1 = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);

View file

@ -1017,7 +1017,7 @@ void CharacterController::update(float duration)
cls.getCreatureStats(mPtr).setHealth(health);
cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), true);
const float acrobaticsSkill = cls.getNpcStats(mPtr).getSkill(ESM::Skill::Acrobatics).getModified();
const float acrobaticsSkill = cls.getSkill(mPtr, ESM::Skill::Acrobatics);
if (healthLost > (acrobaticsSkill * fatigueTerm))
{
cls.getCreatureStats(mPtr).setKnockedDown(true);

View file

@ -902,12 +902,7 @@ namespace MWMechanics
{
static float fSneakSkillMult = store.find("fSneakSkillMult")->getFloat();
static float fSneakBootMult = store.find("fSneakBootMult")->getFloat();
float sneak = 0;
// TODO: According to Hrnchamd Research:Movement, "Creatures have generalized combat, magic and stealth
// stats which substitute for the specific skills (in the same way as specializations)."
// This probably applies to a large part of the code base.
if (ptr.getClass().isNpc())
sneak = ptr.getClass().getNpcStats(ptr).getSkill(ESM::Skill::Sneak).getModified();
float sneak = ptr.getClass().getSkill(ptr, ESM::Skill::Sneak);
int agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
int luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
float bootWeight = 0;
@ -935,9 +930,7 @@ namespace MWMechanics
int obsAgility = observerStats.getAttribute(ESM::Attribute::Agility).getModified();
int obsLuck = observerStats.getAttribute(ESM::Attribute::Luck).getModified();
float obsBlind = observerStats.getMagicEffects().get(ESM::MagicEffect::Blind).mMagnitude;
int obsSneak = 0;
if (observer.getClass().isNpc())
obsSneak = observer.getClass().getNpcStats(observer).getSkill(ESM::Skill::Sneak).getModified();
int obsSneak = observer.getClass().getSkill(observer, ESM::Skill::Sneak);
float obsTerm = obsSneak + 0.2 * obsAgility + 0.1 * obsLuck - obsBlind;

View file

@ -19,7 +19,7 @@ namespace MWMechanics
NpcStats& stats = ptr.getClass().getNpcStats(ptr);
float agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
float luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
float sneak = stats.getSkill(ESM::Skill::Sneak).getModified();
float sneak = ptr.getClass().getSkill(ptr, ESM::Skill::Sneak);
return (add + 0.2 * agility + 0.1 * luck + sneak) * stats.getFatigueTerm();
}
@ -30,8 +30,7 @@ namespace MWMechanics
float t = 2*x - y;
NpcStats& pcStats = mThief.getClass().getNpcStats(mThief);
float pcSneak = pcStats.getSkill(ESM::Skill::Sneak).getModified();
float pcSneak = mThief.getClass().getSkill(mThief, ESM::Skill::Sneak);
int iPickMinChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
.find("iPickMinChance")->getInt();
int iPickMaxChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()

View file

@ -16,9 +16,9 @@
namespace MWMechanics
{
inline int spellSchoolToSkill(int school)
inline ESM::Skill::SkillEnum spellSchoolToSkill(int school)
{
std::map<int, int> schoolSkillMap; // maps spell school to skill id
std::map<int, ESM::Skill::SkillEnum> schoolSkillMap; // maps spell school to skill id
schoolSkillMap[0] = ESM::Skill::Alteration;
schoolSkillMap[1] = ESM::Skill::Conjuration;
schoolSkillMap[3] = ESM::Skill::Illusion;
@ -38,10 +38,9 @@ namespace MWMechanics
*/
inline float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool = NULL)
{
NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor);
CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor);
CreatureStats& stats = actor.getClass().getCreatureStats(actor);
if (creatureStats.getMagicEffects().get(ESM::MagicEffect::Silence).mMagnitude)
if (stats.getMagicEffects().get(ESM::MagicEffect::Silence).mMagnitude)
return 0;
float y = FLT_MAX;
@ -63,7 +62,7 @@ namespace MWMechanics
"fEffectCostMult")->getFloat();
x *= fEffectCostMult;
float s = 2 * stats.getSkill(spellSchoolToSkill(magicEffect->mData.mSchool)).getModified();
float s = 2 * actor.getClass().getSkill(actor, spellSchoolToSkill(magicEffect->mData.mSchool));
if (s - x < y)
{
y = s - x;

View file

@ -306,9 +306,7 @@ namespace MWScript
{
MWWorld::Ptr ptr = R()(runtime);
Interpreter::Type_Integer value =
MWWorld::Class::get (ptr).getNpcStats (ptr).getSkill (mIndex).
getModified();
Interpreter::Type_Integer value = ptr.getClass().getSkill(ptr, mIndex);
runtime.push (value);
}

View file

@ -358,4 +358,9 @@ namespace MWWorld
return false;
}
int Class::getSkill(const MWWorld::Ptr& ptr, int skill) const
{
throw std::runtime_error("class does not support skills");
}
}

View file

@ -294,6 +294,8 @@ namespace MWWorld
virtual bool isFlying(const MWWorld::Ptr& ptr) const;
virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const;
static const Class& get (const std::string& key);
///< If there is no class for this \a key, an exception is thrown.

View file

@ -164,8 +164,6 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot)
void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
{
const MWMechanics::NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor);
TSlots slots_;
initSlots (slots_);
@ -190,10 +188,10 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
!actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion")))
continue;
int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test);
int testSkill = test.getClass().getEquipmentSkill (test);
std::pair<std::vector<int>, bool> itemsSlots =
MWWorld::Class::get (*iter).getEquipmentSlots (*iter);
iter->getClass().getEquipmentSlots (*iter);
for (std::vector<int>::const_iterator iter2 (itemsSlots.first.begin());
iter2!=itemsSlots.first.end(); ++iter2)
@ -210,16 +208,16 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
{
// check skill
int oldSkill =
MWWorld::Class::get (old).getEquipmentSkill (old);
old.getClass().getEquipmentSkill (old);
if (testSkill!=-1 && oldSkill==-1)
use = true;
else if (testSkill!=-1 && oldSkill!=-1 && testSkill!=oldSkill)
{
if (stats.getSkill (oldSkill).getModified()>stats.getSkill (testSkill).getModified())
if (actor.getClass().getSkill(actor, oldSkill) > actor.getClass().getSkill (actor, testSkill))
continue; // rejected, because old item better matched the NPC's skills.
if (stats.getSkill (oldSkill).getModified()<stats.getSkill (testSkill).getModified())
if (actor.getClass().getSkill(actor, oldSkill) < actor.getClass().getSkill (actor, testSkill))
use = true;
}
}
@ -227,8 +225,8 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
if (!use)
{
// check value
if (MWWorld::Class::get (old).getValue (old)>=
MWWorld::Class::get (test).getValue (test))
if (old.getClass().getValue (old)>=
test.getClass().getValue (test))
{
continue;
}

View file

@ -63,7 +63,9 @@ struct Creature
int mHealth, mMana, mFatigue; // Stats
int mSoul; // The creatures soul value (used with soul gems.)
int mCombat, mMagic, mStealth; // Don't know yet.
// Creatures have generalized combat, magic and stealth stats which substitute for
// the specific skills (in the same way as specializations).
int mCombat, mMagic, mStealth;
int mAttack[6]; // AttackMin1, AttackMax1, ditto2, ditto3
int mGold;
}; // 96 byte