mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-30 07:21:12 +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:
parent
7534fc968d
commit
d544551f61
@ -461,6 +461,26 @@ namespace MWClass
|
|||||||
throw std::runtime_error(std::string("Unexpected soundgen type: ")+name);
|
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::fMinWalkSpeedCreature;
|
||||||
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,8 @@ namespace MWClass
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isFlying (const MWWorld::Ptr &ptr) const;
|
virtual bool isFlying (const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
|
virtual int getSkill(const MWWorld::Ptr &ptr, int skill) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1211,6 +1211,11 @@ namespace MWClass
|
|||||||
return MWWorld::Ptr(&cell.mNpcs.insert(*ref), &cell);
|
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::fMinWalkSpeed;
|
||||||
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
||||||
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
||||||
|
@ -140,6 +140,8 @@ namespace MWClass
|
|||||||
|
|
||||||
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
|
|
||||||
|
virtual int getSkill(const MWWorld::Ptr& ptr, int skill) const;
|
||||||
|
|
||||||
virtual bool isActor() const {
|
virtual bool isActor() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ namespace MWGui
|
|||||||
PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& thief, ItemModel *sourceModel)
|
PickpocketItemModel::PickpocketItemModel(const MWWorld::Ptr& thief, ItemModel *sourceModel)
|
||||||
{
|
{
|
||||||
mSourceModel = 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();
|
mSourceModel->update();
|
||||||
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
|
for (size_t i = 0; i<mSourceModel->getItemCount(); ++i)
|
||||||
|
@ -296,10 +296,10 @@ namespace MWGui
|
|||||||
const MWMechanics::NpcStats &sellerStats = mPtr.getClass().getNpcStats(mPtr);
|
const MWMechanics::NpcStats &sellerStats = mPtr.getClass().getNpcStats(mPtr);
|
||||||
const MWMechanics::NpcStats &playerStats = player.getClass().getNpcStats(player);
|
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 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 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 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);
|
float f1 = std::min(0.2f * sellerStats.getAttribute(ESM::Attribute::Personality).getModified(), 10.f);
|
||||||
|
|
||||||
|
@ -1017,7 +1017,7 @@ void CharacterController::update(float duration)
|
|||||||
cls.getCreatureStats(mPtr).setHealth(health);
|
cls.getCreatureStats(mPtr).setHealth(health);
|
||||||
cls.onHit(mPtr, realHealthLost, true, MWWorld::Ptr(), MWWorld::Ptr(), true);
|
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))
|
if (healthLost > (acrobaticsSkill * fatigueTerm))
|
||||||
{
|
{
|
||||||
cls.getCreatureStats(mPtr).setKnockedDown(true);
|
cls.getCreatureStats(mPtr).setKnockedDown(true);
|
||||||
|
@ -902,12 +902,7 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
static float fSneakSkillMult = store.find("fSneakSkillMult")->getFloat();
|
static float fSneakSkillMult = store.find("fSneakSkillMult")->getFloat();
|
||||||
static float fSneakBootMult = store.find("fSneakBootMult")->getFloat();
|
static float fSneakBootMult = store.find("fSneakBootMult")->getFloat();
|
||||||
float sneak = 0;
|
float sneak = ptr.getClass().getSkill(ptr, ESM::Skill::Sneak);
|
||||||
// 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();
|
|
||||||
int agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
|
int agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||||
int luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
int luck = stats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||||
float bootWeight = 0;
|
float bootWeight = 0;
|
||||||
@ -935,9 +930,7 @@ namespace MWMechanics
|
|||||||
int obsAgility = observerStats.getAttribute(ESM::Attribute::Agility).getModified();
|
int obsAgility = observerStats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||||
int obsLuck = observerStats.getAttribute(ESM::Attribute::Luck).getModified();
|
int obsLuck = observerStats.getAttribute(ESM::Attribute::Luck).getModified();
|
||||||
float obsBlind = observerStats.getMagicEffects().get(ESM::MagicEffect::Blind).mMagnitude;
|
float obsBlind = observerStats.getMagicEffects().get(ESM::MagicEffect::Blind).mMagnitude;
|
||||||
int obsSneak = 0;
|
int obsSneak = observer.getClass().getSkill(observer, ESM::Skill::Sneak);
|
||||||
if (observer.getClass().isNpc())
|
|
||||||
obsSneak = observer.getClass().getNpcStats(observer).getSkill(ESM::Skill::Sneak).getModified();
|
|
||||||
|
|
||||||
float obsTerm = obsSneak + 0.2 * obsAgility + 0.1 * obsLuck - obsBlind;
|
float obsTerm = obsSneak + 0.2 * obsAgility + 0.1 * obsLuck - obsBlind;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ namespace MWMechanics
|
|||||||
NpcStats& stats = ptr.getClass().getNpcStats(ptr);
|
NpcStats& stats = ptr.getClass().getNpcStats(ptr);
|
||||||
float agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
|
float agility = stats.getAttribute(ESM::Attribute::Agility).getModified();
|
||||||
float luck = stats.getAttribute(ESM::Attribute::Luck).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();
|
return (add + 0.2 * agility + 0.1 * luck + sneak) * stats.getFatigueTerm();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,8 +30,7 @@ namespace MWMechanics
|
|||||||
|
|
||||||
float t = 2*x - y;
|
float t = 2*x - y;
|
||||||
|
|
||||||
NpcStats& pcStats = mThief.getClass().getNpcStats(mThief);
|
float pcSneak = mThief.getClass().getSkill(mThief, ESM::Skill::Sneak);
|
||||||
float pcSneak = pcStats.getSkill(ESM::Skill::Sneak).getModified();
|
|
||||||
int iPickMinChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
int iPickMinChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
.find("iPickMinChance")->getInt();
|
.find("iPickMinChance")->getInt();
|
||||||
int iPickMaxChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
int iPickMaxChance = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
namespace MWMechanics
|
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[0] = ESM::Skill::Alteration;
|
||||||
schoolSkillMap[1] = ESM::Skill::Conjuration;
|
schoolSkillMap[1] = ESM::Skill::Conjuration;
|
||||||
schoolSkillMap[3] = ESM::Skill::Illusion;
|
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)
|
inline float getSpellSuccessChance (const ESM::Spell* spell, const MWWorld::Ptr& actor, int* effectiveSchool = NULL)
|
||||||
{
|
{
|
||||||
NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor);
|
CreatureStats& stats = actor.getClass().getCreatureStats(actor);
|
||||||
CreatureStats& creatureStats = MWWorld::Class::get(actor).getCreatureStats(actor);
|
|
||||||
|
|
||||||
if (creatureStats.getMagicEffects().get(ESM::MagicEffect::Silence).mMagnitude)
|
if (stats.getMagicEffects().get(ESM::MagicEffect::Silence).mMagnitude)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
float y = FLT_MAX;
|
float y = FLT_MAX;
|
||||||
@ -63,7 +62,7 @@ namespace MWMechanics
|
|||||||
"fEffectCostMult")->getFloat();
|
"fEffectCostMult")->getFloat();
|
||||||
x *= fEffectCostMult;
|
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)
|
if (s - x < y)
|
||||||
{
|
{
|
||||||
y = s - x;
|
y = s - x;
|
||||||
|
@ -306,9 +306,7 @@ namespace MWScript
|
|||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
Interpreter::Type_Integer value =
|
Interpreter::Type_Integer value = ptr.getClass().getSkill(ptr, mIndex);
|
||||||
MWWorld::Class::get (ptr).getNpcStats (ptr).getSkill (mIndex).
|
|
||||||
getModified();
|
|
||||||
|
|
||||||
runtime.push (value);
|
runtime.push (value);
|
||||||
}
|
}
|
||||||
|
@ -358,4 +358,9 @@ namespace MWWorld
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Class::getSkill(const MWWorld::Ptr& ptr, int skill) const
|
||||||
|
{
|
||||||
|
throw std::runtime_error("class does not support skills");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -294,6 +294,8 @@ namespace MWWorld
|
|||||||
|
|
||||||
virtual bool isFlying(const MWWorld::Ptr& ptr) const;
|
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);
|
static const Class& get (const std::string& key);
|
||||||
///< If there is no class for this \a key, an exception is thrown.
|
///< If there is no class for this \a key, an exception is thrown.
|
||||||
|
|
||||||
|
@ -164,8 +164,6 @@ MWWorld::ContainerStoreIterator MWWorld::InventoryStore::getSlot (int slot)
|
|||||||
|
|
||||||
void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
|
void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
const MWMechanics::NpcStats& stats = MWWorld::Class::get(actor).getNpcStats(actor);
|
|
||||||
|
|
||||||
TSlots slots_;
|
TSlots slots_;
|
||||||
initSlots (slots_);
|
initSlots (slots_);
|
||||||
|
|
||||||
@ -190,10 +188,10 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
|
|||||||
!actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion")))
|
!actor.getRefData().getLocals().getIntVar(actor.getClass().getScript(actor), "companion")))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int testSkill = MWWorld::Class::get (test).getEquipmentSkill (test);
|
int testSkill = test.getClass().getEquipmentSkill (test);
|
||||||
|
|
||||||
std::pair<std::vector<int>, bool> itemsSlots =
|
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());
|
for (std::vector<int>::const_iterator iter2 (itemsSlots.first.begin());
|
||||||
iter2!=itemsSlots.first.end(); ++iter2)
|
iter2!=itemsSlots.first.end(); ++iter2)
|
||||||
@ -210,16 +208,16 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
|
|||||||
{
|
{
|
||||||
// check skill
|
// check skill
|
||||||
int oldSkill =
|
int oldSkill =
|
||||||
MWWorld::Class::get (old).getEquipmentSkill (old);
|
old.getClass().getEquipmentSkill (old);
|
||||||
|
|
||||||
if (testSkill!=-1 && oldSkill==-1)
|
if (testSkill!=-1 && oldSkill==-1)
|
||||||
use = true;
|
use = true;
|
||||||
else if (testSkill!=-1 && oldSkill!=-1 && testSkill!=oldSkill)
|
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.
|
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;
|
use = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,8 +225,8 @@ void MWWorld::InventoryStore::autoEquip (const MWWorld::Ptr& actor)
|
|||||||
if (!use)
|
if (!use)
|
||||||
{
|
{
|
||||||
// check value
|
// check value
|
||||||
if (MWWorld::Class::get (old).getValue (old)>=
|
if (old.getClass().getValue (old)>=
|
||||||
MWWorld::Class::get (test).getValue (test))
|
test.getClass().getValue (test))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,9 @@ struct Creature
|
|||||||
|
|
||||||
int mHealth, mMana, mFatigue; // Stats
|
int mHealth, mMana, mFatigue; // Stats
|
||||||
int mSoul; // The creatures soul value (used with soul gems.)
|
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 mAttack[6]; // AttackMin1, AttackMax1, ditto2, ditto3
|
||||||
int mGold;
|
int mGold;
|
||||||
}; // 96 byte
|
}; // 96 byte
|
||||||
|
Loading…
x
Reference in New Issue
Block a user