forked from teamnwah/openmw-tes3coop
Don't use separate werewolf skills/attributes for non-player werewolves
Still need to deal with save files.
This commit is contained in:
parent
c644f15167
commit
44582fe3b3
8 changed files with 101 additions and 49 deletions
apps/openmw
mwmechanics
mwworld
components/esm
|
@ -20,7 +20,7 @@ namespace MWMechanics
|
|||
mKnockdown(false), mKnockdownOneFrame(false), mKnockdownOverOneFrame(false),
|
||||
mHitRecovery(false), mBlock(false), mMovementFlags(0), mAttackStrength(0.f),
|
||||
mFallHeight(0), mRecalcMagicka(false), mLastRestock(0,0), mGoldPool(0), mActorId(-1),
|
||||
mDeathAnimation(0), mIsWerewolf(false), mLevel (0)
|
||||
mDeathAnimation(0), mLevel (0)
|
||||
{
|
||||
for (int i=0; i<4; ++i)
|
||||
mAiSettings[i] = 0;
|
||||
|
@ -55,7 +55,7 @@ namespace MWMechanics
|
|||
if (index < 0 || index > 7) {
|
||||
throw std::runtime_error("attribute index is out of range");
|
||||
}
|
||||
return (!mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index]);
|
||||
return mAttributes[index];
|
||||
}
|
||||
|
||||
const DynamicStat<float> &CreatureStats::getHealth() const
|
||||
|
@ -139,14 +139,11 @@ namespace MWMechanics
|
|||
throw std::runtime_error("attribute index is out of range");
|
||||
}
|
||||
|
||||
const AttributeValue& currentValue = !mIsWerewolf ? mAttributes[index] : mWerewolfAttributes[index];
|
||||
const AttributeValue& currentValue = mAttributes[index];
|
||||
|
||||
if (value != currentValue)
|
||||
{
|
||||
if(!mIsWerewolf)
|
||||
mAttributes[index] = value;
|
||||
else
|
||||
mWerewolfAttributes[index] = value;
|
||||
mAttributes[index] = value;
|
||||
|
||||
if (index == ESM::Attribute::Intelligence)
|
||||
mRecalcMagicka = true;
|
||||
|
|
|
@ -77,10 +77,6 @@ namespace MWMechanics
|
|||
std::vector<int> mSummonGraveyard;
|
||||
|
||||
protected:
|
||||
// These two are only set by NpcStats, but they are declared in CreatureStats to prevent using virtual methods.
|
||||
bool mIsWerewolf;
|
||||
AttributeValue mWerewolfAttributes[8];
|
||||
|
||||
int mLevel;
|
||||
|
||||
public:
|
||||
|
|
|
@ -32,6 +32,7 @@ MWMechanics::NpcStats::NpcStats()
|
|||
, mWerewolfKills (0)
|
||||
, mLevelProgress(0)
|
||||
, mTimeToStartDrowning(20.0)
|
||||
, mIsWerewolf(false)
|
||||
{
|
||||
mSkillIncreases.resize (ESM::Attribute::Length, 0);
|
||||
}
|
||||
|
@ -51,7 +52,7 @@ const MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index) const
|
|||
if (index<0 || index>=ESM::Skill::Length)
|
||||
throw std::runtime_error ("skill index out of range");
|
||||
|
||||
return (!mIsWerewolf ? mSkill[index] : mWerewolfSkill[index]);
|
||||
return mSkill[index];
|
||||
}
|
||||
|
||||
MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index)
|
||||
|
@ -59,7 +60,15 @@ MWMechanics::SkillValue& MWMechanics::NpcStats::getSkill (int index)
|
|||
if (index<0 || index>=ESM::Skill::Length)
|
||||
throw std::runtime_error ("skill index out of range");
|
||||
|
||||
return (!mIsWerewolf ? mSkill[index] : mWerewolfSkill[index]);
|
||||
return mSkill[index];
|
||||
}
|
||||
|
||||
void MWMechanics::NpcStats::setSkill(int index, const MWMechanics::SkillValue &value)
|
||||
{
|
||||
if (index<0 || index>=ESM::Skill::Length)
|
||||
throw std::runtime_error ("skill index out of range");
|
||||
|
||||
mSkill[index] = value;
|
||||
}
|
||||
|
||||
const std::map<std::string, int>& MWMechanics::NpcStats::getFactionRanks() const
|
||||
|
@ -188,10 +197,6 @@ float MWMechanics::NpcStats::getSkillProgressRequirement (int skillIndex, const
|
|||
|
||||
void MWMechanics::NpcStats::useSkill (int skillIndex, const ESM::Class& class_, int usageType, float extraFactor)
|
||||
{
|
||||
// Don't increase skills as a werewolf
|
||||
if(mIsWerewolf)
|
||||
return;
|
||||
|
||||
const ESM::Skill *skill =
|
||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Skill>().find (skillIndex);
|
||||
float skillGain = 1;
|
||||
|
@ -403,34 +408,12 @@ bool MWMechanics::NpcStats::isWerewolf() const
|
|||
|
||||
void MWMechanics::NpcStats::setWerewolf (bool set)
|
||||
{
|
||||
if (mIsWerewolf == set)
|
||||
return;
|
||||
|
||||
if(set != false)
|
||||
{
|
||||
const MWWorld::Store<ESM::GameSetting> &gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
|
||||
mWerewolfKills = 0;
|
||||
|
||||
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].setBase(int(gmst.find(name)->getFloat()));
|
||||
}
|
||||
|
||||
for(size_t i = 0;i < ESM::Skill::Length;i++)
|
||||
{
|
||||
mWerewolfSkill[i] = getSkill(i);
|
||||
|
||||
// Acrobatics is set separately for some reason.
|
||||
if(i == ESM::Skill::Acrobatics)
|
||||
continue;
|
||||
|
||||
// "Mercantile"! >_<
|
||||
std::string name = "fWerewolf"+((i==ESM::Skill::Mercantile) ? std::string("Merchantile") :
|
||||
ESM::Skill::sSkillNames[i]);
|
||||
mWerewolfSkill[i].setBase(int(gmst.find(name)->getFloat()));
|
||||
}
|
||||
}
|
||||
mIsWerewolf = set;
|
||||
}
|
||||
|
@ -466,12 +449,14 @@ void MWMechanics::NpcStats::writeState (ESM::NpcStats& state) const
|
|||
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||
{
|
||||
mSkill[i].writeState (state.mSkills[i].mRegular);
|
||||
mWerewolfSkill[i].writeState (state.mSkills[i].mWerewolf);
|
||||
//mWerewolfSkill[i].writeState (state.mSkills[i].mWerewolf);
|
||||
}
|
||||
/*
|
||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||
{
|
||||
mWerewolfAttributes[i].writeState (state.mWerewolfAttributes[i]);
|
||||
}
|
||||
*/
|
||||
state.mIsWerewolf = mIsWerewolf;
|
||||
|
||||
state.mCrimeId = mCrimeId;
|
||||
|
@ -521,12 +506,14 @@ void MWMechanics::NpcStats::readState (const ESM::NpcStats& state)
|
|||
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||
{
|
||||
mSkill[i].readState (state.mSkills[i].mRegular);
|
||||
mWerewolfSkill[i].readState (state.mSkills[i].mWerewolf);
|
||||
//mWerewolfSkill[i].readState (state.mSkills[i].mWerewolf);
|
||||
}
|
||||
/*
|
||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||
{
|
||||
mWerewolfAttributes[i].readState (state.mWerewolfAttributes[i]);
|
||||
}
|
||||
*/
|
||||
|
||||
mIsWerewolf = state.mIsWerewolf;
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace MWMechanics
|
|||
{
|
||||
int mDisposition;
|
||||
SkillValue mSkill[ESM::Skill::Length]; // SkillValue.mProgress used by the player only
|
||||
SkillValue mWerewolfSkill[ESM::Skill::Length];
|
||||
|
||||
int mReputation;
|
||||
int mCrimeId;
|
||||
|
||||
|
@ -41,6 +41,8 @@ namespace MWMechanics
|
|||
/// Countdown to getting damage while underwater
|
||||
float mTimeToStartDrowning;
|
||||
|
||||
bool mIsWerewolf;
|
||||
|
||||
public:
|
||||
|
||||
NpcStats();
|
||||
|
@ -56,6 +58,7 @@ namespace MWMechanics
|
|||
|
||||
const SkillValue& getSkill (int index) const;
|
||||
SkillValue& getSkill (int index);
|
||||
void setSkill(int index, const SkillValue& value);
|
||||
|
||||
const std::map<std::string, int>& getFactionRanks() const;
|
||||
/// Increase the rank in this faction by 1, if such a rank exists.
|
||||
|
|
|
@ -49,6 +49,55 @@ namespace MWWorld
|
|||
mPlayer.mData.setPosition(playerPos);
|
||||
}
|
||||
|
||||
void Player::saveSkillsAttributes()
|
||||
{
|
||||
MWMechanics::NpcStats& stats = getPlayer().getClass().getNpcStats(getPlayer());
|
||||
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||
mSaveSkills[i] = stats.getSkill(i);
|
||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||
mSaveAttributes[i] = stats.getAttribute(i);
|
||||
}
|
||||
|
||||
void Player::restoreSkillsAttributes()
|
||||
{
|
||||
MWMechanics::NpcStats& stats = getPlayer().getClass().getNpcStats(getPlayer());
|
||||
for (int i=0; i<ESM::Skill::Length; ++i)
|
||||
stats.setSkill(i, mSaveSkills[i]);
|
||||
for (int i=0; i<ESM::Attribute::Length; ++i)
|
||||
stats.setAttribute(i, mSaveAttributes[i]);
|
||||
}
|
||||
|
||||
void Player::setWerewolfSkillsAttributes()
|
||||
{
|
||||
const MWWorld::Store<ESM::GameSetting>& gmst = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
|
||||
MWMechanics::NpcStats& stats = getPlayer().getClass().getNpcStats(getPlayer());
|
||||
for(size_t i = 0;i < ESM::Attribute::Length;++i)
|
||||
{
|
||||
// Oh, Bethesda. It's "Intelligence".
|
||||
std::string name = "fWerewolf"+((i==ESM::Attribute::Intelligence) ? std::string("Intellegence") :
|
||||
ESM::Attribute::sAttributeNames[i]);
|
||||
|
||||
MWMechanics::AttributeValue value = stats.getAttribute(i);
|
||||
value.setBase(int(gmst.find(name)->getFloat()));
|
||||
stats.setAttribute(i, value);
|
||||
}
|
||||
|
||||
for(size_t i = 0;i < ESM::Skill::Length;i++)
|
||||
{
|
||||
// Acrobatics is set separately for some reason.
|
||||
if(i == ESM::Skill::Acrobatics)
|
||||
continue;
|
||||
|
||||
// "Mercantile"! >_<
|
||||
std::string name = "fWerewolf"+((i==ESM::Skill::Mercantile) ? std::string("Merchantile") :
|
||||
ESM::Skill::sSkillNames[i]);
|
||||
|
||||
MWMechanics::SkillValue value = stats.getSkill(i);
|
||||
value.setBase(int(gmst.find(name)->getFloat()));
|
||||
stats.setSkill(i, value);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::set(const ESM::NPC *player)
|
||||
{
|
||||
mPlayer.mBase = player;
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
|
||||
#include "../mwmechanics/drawstate.hpp"
|
||||
|
||||
#include "../mwmechanics/stat.hpp"
|
||||
|
||||
#include <components/esm/loadskil.hpp>
|
||||
#include <components/esm/attr.hpp>
|
||||
|
||||
#include <OgreVector3.h>
|
||||
|
||||
namespace ESM
|
||||
|
@ -50,10 +55,18 @@ namespace MWWorld
|
|||
int mCurrentCrimeId; // the id assigned witnesses
|
||||
int mPaidCrimeId; // the last id paid off (0 bounty)
|
||||
|
||||
// Saved skills and attributes prior to becoming a werewolf
|
||||
MWMechanics::SkillValue mSaveSkills[ESM::Skill::Length];
|
||||
MWMechanics::AttributeValue mSaveAttributes[ESM::Attribute::Length];
|
||||
|
||||
public:
|
||||
|
||||
Player(const ESM::NPC *player, const MWBase::World& world);
|
||||
|
||||
void saveSkillsAttributes();
|
||||
void restoreSkillsAttributes();
|
||||
void setWerewolfSkillsAttributes();
|
||||
|
||||
// For mark/recall magic effects
|
||||
void markPosition (CellStore* markedCell, ESM::Position markedPosition);
|
||||
void getMarkedPosition (CellStore*& markedCell, ESM::Position& markedPosition) const;
|
||||
|
|
|
@ -2485,6 +2485,17 @@ namespace MWWorld
|
|||
if (npcStats.isWerewolf() == werewolf)
|
||||
return;
|
||||
|
||||
if (actor == getPlayerPtr())
|
||||
{
|
||||
if (werewolf)
|
||||
{
|
||||
mPlayer->saveSkillsAttributes();
|
||||
mPlayer->setWerewolfSkillsAttributes();
|
||||
}
|
||||
else
|
||||
mPlayer->restoreSkillsAttributes();
|
||||
}
|
||||
|
||||
npcStats.setWerewolf(werewolf);
|
||||
|
||||
// This is a bit dangerous. Equipped items other than WerewolfRobe may reference
|
||||
|
|
|
@ -117,10 +117,6 @@ void ESM::NpcStats::save (ESMWriter &esm) const
|
|||
mSkills[i].mWerewolf.save (esm);
|
||||
}
|
||||
|
||||
esm.writeHNT ("HWAT", true);
|
||||
for (int i=0; i<8; ++i)
|
||||
mWerewolfAttributes[i].save (esm);
|
||||
|
||||
if (mIsWerewolf)
|
||||
esm.writeHNT ("WOLF", mIsWerewolf);
|
||||
|
||||
|
|
Loading…
Reference in a new issue