From ae183cb3e4808834c5a5704ee7f24103aa14f06a Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 9 Aug 2013 05:14:58 -0700 Subject: [PATCH] Handle werewolf stats --- apps/openmw/mwmechanics/creaturestats.cpp | 12 +++++--- apps/openmw/mwmechanics/creaturestats.hpp | 4 +++ apps/openmw/mwmechanics/npcstats.cpp | 35 +++++++++++++++++++---- apps/openmw/mwmechanics/npcstats.hpp | 4 +-- components/esm/attr.cpp | 11 +++++++ components/esm/attr.hpp | 1 + components/esm/loadskil.cpp | 29 +++++++++++++++++++ components/esm/loadskil.hpp | 1 + 8 files changed, 86 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index d7b254fee..52ed43be3 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -13,7 +13,8 @@ namespace MWMechanics : mLevel (0), mLevelHealthBonus(0.f), mDead (false), mDied (false), mFriendlyHits (0), mTalkedTo (false), mAlarmed (false), mAttacked (false), mHostile (false), - mAttackingOrSpell(false), mAttackType(AT_Chop) + mAttackingOrSpell(false), mAttackType(AT_Chop), + mIsWerewolf(false) { for (int i=0; i<4; ++i) mAiSettings[i] = 0; @@ -77,7 +78,7 @@ namespace MWMechanics if (index < 0 || index > 7) { throw std::runtime_error("attribute index is out of range"); } - return mAttributes[index]; + return (!mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index]); } const DynamicStat &CreatureStats::getHealth() const @@ -131,7 +132,7 @@ namespace MWMechanics if (index < 0 || index > 7) { throw std::runtime_error("attribute index is out of range"); } - return mAttributes[index]; + return (!mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index]); } const DynamicStat &CreatureStats::getDynamic(int index) const @@ -167,7 +168,10 @@ namespace MWMechanics if (index < 0 || index > 7) { throw std::runtime_error("attribute index is out of range"); } - mAttributes[index] = value; + if(!mIsWerewolf) + mAttributes[index] = value; + else + mWerewolfAttributes[index] = value; } void CreatureStats::setHealth(const DynamicStat &value) diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index c7f3ab94a..1a7cb5d69 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -40,6 +40,10 @@ namespace MWMechanics std::string mLastHitObject; // The last object to hit this actor + protected: + bool mIsWerewolf; + Stat mWerewolfAttributes[8]; + public: CreatureStats(); diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 9f5be87fb..69542b86c 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -30,7 +30,6 @@ MWMechanics::NpcStats::NpcStats() , mDisposition(0) , mVampire (0) , mReputation(0) -, mWerewolf (false) , mWerewolfKills (0) , mProfit(0) , mAttackStrength(0.0f) @@ -90,7 +89,7 @@ const MWMechanics::Stat& MWMechanics::NpcStats::getSkill (int index) cons if (index<0 || index>=27) throw std::runtime_error ("skill index out of range"); - return mSkill[index]; + return (!mIsWerewolf ? mSkill[index] : mWerewolfSkill[index]); } MWMechanics::Stat& MWMechanics::NpcStats::getSkill (int index) @@ -98,7 +97,7 @@ MWMechanics::Stat& MWMechanics::NpcStats::getSkill (int index) if (index<0 || index>=27) throw std::runtime_error ("skill index out of range"); - return mSkill[index]; + return (!mIsWerewolf ? mSkill[index] : mWerewolfSkill[index]); } const std::map& MWMechanics::NpcStats::getFactionRanks() const @@ -194,6 +193,10 @@ float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& cla void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType) { + // Don't increase skills as a werewolf + if(mIsWerewolf) + return; + float base = getSkill (skillIndex).getBase(); int level = static_cast (base); @@ -369,12 +372,34 @@ bool MWMechanics::NpcStats::hasSkillsForRank (const std::string& factionId, int bool MWMechanics::NpcStats::isWerewolf() const { - return mWerewolf; + return mIsWerewolf; } void MWMechanics::NpcStats::setWerewolf (bool set) { - mWerewolf = set; + if(set != false) + { + const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); + + for(size_t i = 0;i < ESM::Attribute::Length;i++) + { + mWerewolfAttributes[i] = getAttribute(i); + // Oh, Bethesda. It's "Intelligence". + std::string name = "fWerewolf"+((i==ESM::Attribute::Intelligence) ? std::string("Intellegence") : + ESM::Attribute::sAttributeNames[i]); + mWerewolfAttributes[i].setModified(int(gmst.find(name)->getFloat()), 0); + } + + for(size_t i = 0;i < ESM::Skill::Length;i++) + { + mWerewolfSkill[i] = getSkill(i); + // "Mercantile"! >_< + std::string name = "fWerewolf"+((i==ESM::Skill::Mercantile) ? std::string("Merchantile") : + ESM::Skill::sSkillNames[i]); + mWerewolfSkill[i].setModified(int(gmst.find(name)->getFloat()), 0); + } + } + mIsWerewolf = set; } int MWMechanics::NpcStats::getWerewolfKills() const diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 97dced432..d3fe61829 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -46,12 +46,12 @@ namespace MWMechanics int mDisposition; unsigned int mMovementFlags; Stat mSkill[27]; + Stat mWerewolfSkill[27]; int mBounty; std::set mExpelled; std::map mFactionReputation; bool mVampire; int mReputation; - bool mWerewolf; int mWerewolfKills; int mProfit; float mAttackStrength; @@ -143,7 +143,7 @@ namespace MWMechanics bool isWerewolf() const; - void setWerewolf (bool set); + void setWerewolf(bool set); int getWerewolfKills() const; diff --git a/components/esm/attr.cpp b/components/esm/attr.cpp index e20050bb3..75cf8b006 100644 --- a/components/esm/attr.cpp +++ b/components/esm/attr.cpp @@ -13,6 +13,17 @@ const Attribute::AttributeID Attribute::sAttributeIds[Attribute::Length] = { Attribute::Luck }; +const std::string Attribute::sAttributeNames[Attribute::Length] = { + "Strength", + "Intelligence", + "Willpower", + "Agility", + "Speed", + "Endurance", + "Personality", + "Luck" +}; + const std::string Attribute::sGmstAttributeIds[Attribute::Length] = { "sAttributeStrength", "sAttributeIntelligence", diff --git a/components/esm/attr.hpp b/components/esm/attr.hpp index 2ed9b4f41..993de6ccb 100644 --- a/components/esm/attr.hpp +++ b/components/esm/attr.hpp @@ -28,6 +28,7 @@ struct Attribute std::string mName, mDescription; static const AttributeID sAttributeIds[Length]; + static const std::string sAttributeNames[Length]; static const std::string sGmstAttributeIds[Length]; static const std::string sGmstAttributeDescIds[Length]; static const std::string sAttributeIcons[Length]; diff --git a/components/esm/loadskil.cpp b/components/esm/loadskil.cpp index b57645f3b..676a835c3 100644 --- a/components/esm/loadskil.cpp +++ b/components/esm/loadskil.cpp @@ -9,6 +9,35 @@ namespace ESM { + const std::string Skill::sSkillNames[Length] = { + "Block", + "Armorer", + "Mediumarmor", + "Heavyarmor", + "Bluntweapon", + "Longblade", + "Axe", + "Spear", + "Athletics", + "Enchant", + "Destruction", + "Alteration", + "Illusion", + "Conjuration", + "Mysticism", + "Restoration", + "Alchemy", + "Unarmored", + "Security", + "Sneak", + "Acrobatics", + "Lightarmor", + "Shortblade", + "Marksman", + "Mercantile", + "Speechcraft", + "Handtohand", + }; const std::string Skill::sSkillNameIds[Length] = { "sSkillBlock", "sSkillArmorer", diff --git a/components/esm/loadskil.hpp b/components/esm/loadskil.hpp index 43f4fc45e..384f87454 100644 --- a/components/esm/loadskil.hpp +++ b/components/esm/loadskil.hpp @@ -69,6 +69,7 @@ struct Skill HandToHand = 26, Length }; + static const std::string sSkillNames[Length]; static const std::string sSkillNameIds[Length]; static const std::string sIconNames[Length]; static const boost::array sSkillIds;