forked from teamnwah/openmw-tes3coop
Merge branch 'death'
This commit is contained in:
commit
2e63ca5e0a
11 changed files with 219 additions and 86 deletions
|
@ -39,6 +39,8 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void addActor (const MWWorld::Ptr& ptr) = 0;
|
virtual void addActor (const MWWorld::Ptr& ptr) = 0;
|
||||||
///< Register an actor for stats management
|
///< Register an actor for stats management
|
||||||
|
///
|
||||||
|
/// \note Dead actors are ignored.
|
||||||
|
|
||||||
virtual void removeActor (const MWWorld::Ptr& ptr) = 0;
|
virtual void removeActor (const MWWorld::Ptr& ptr) = 0;
|
||||||
///< Deregister an actor for stats management
|
///< Deregister an actor for stats management
|
||||||
|
@ -74,6 +76,9 @@ namespace MWBase
|
||||||
|
|
||||||
virtual void restoreDynamicStats() = 0;
|
virtual void restoreDynamicStats() = 0;
|
||||||
///< If the player is sleeping, this should be called every hour.
|
///< If the player is sleeping, this should be called every hour.
|
||||||
|
|
||||||
|
virtual int countDeaths (const std::string& id) const = 0;
|
||||||
|
///< Return the number of deaths for actors with the given ID.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,9 +55,9 @@ namespace MWClass
|
||||||
data->mCreatureStats.getAttribute(5).set (ref->base->mData.mEndurance);
|
data->mCreatureStats.getAttribute(5).set (ref->base->mData.mEndurance);
|
||||||
data->mCreatureStats.getAttribute(6).set (ref->base->mData.mPersonality);
|
data->mCreatureStats.getAttribute(6).set (ref->base->mData.mPersonality);
|
||||||
data->mCreatureStats.getAttribute(7).set (ref->base->mData.mLuck);
|
data->mCreatureStats.getAttribute(7).set (ref->base->mData.mLuck);
|
||||||
data->mCreatureStats.getHealth().set (ref->base->mData.mHealth);
|
data->mCreatureStats.setHealth (ref->base->mData.mHealth);
|
||||||
data->mCreatureStats.getMagicka().set (ref->base->mData.mMana);
|
data->mCreatureStats.setMagicka (ref->base->mData.mMana);
|
||||||
data->mCreatureStats.getFatigue().set (ref->base->mData.mFatigue);
|
data->mCreatureStats.setFatigue (ref->base->mData.mFatigue);
|
||||||
|
|
||||||
data->mCreatureStats.setLevel(ref->base->mData.mLevel);
|
data->mCreatureStats.setLevel(ref->base->mData.mLevel);
|
||||||
|
|
||||||
|
|
|
@ -89,15 +89,22 @@ namespace MWClass
|
||||||
data->mCreatureStats.getAttribute(5).set (ref->base->mNpdt52.mEndurance);
|
data->mCreatureStats.getAttribute(5).set (ref->base->mNpdt52.mEndurance);
|
||||||
data->mCreatureStats.getAttribute(6).set (ref->base->mNpdt52.mPersonality);
|
data->mCreatureStats.getAttribute(6).set (ref->base->mNpdt52.mPersonality);
|
||||||
data->mCreatureStats.getAttribute(7).set (ref->base->mNpdt52.mLuck);
|
data->mCreatureStats.getAttribute(7).set (ref->base->mNpdt52.mLuck);
|
||||||
data->mCreatureStats.getHealth().set (ref->base->mNpdt52.mHealth);
|
data->mCreatureStats.setHealth (ref->base->mNpdt52.mHealth);
|
||||||
data->mCreatureStats.getMagicka().set (ref->base->mNpdt52.mMana);
|
data->mCreatureStats.setMagicka (ref->base->mNpdt52.mMana);
|
||||||
data->mCreatureStats.getFatigue().set (ref->base->mNpdt52.mFatigue);
|
data->mCreatureStats.setFatigue (ref->base->mNpdt52.mFatigue);
|
||||||
|
|
||||||
data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel);
|
data->mCreatureStats.setLevel(ref->base->mNpdt52.mLevel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/// \todo do something with mNpdt12 maybe:p
|
/// \todo do something with mNpdt12 maybe:p
|
||||||
|
for (int i=0; i<8; ++i)
|
||||||
|
data->mCreatureStats.getAttribute (i).set (10);
|
||||||
|
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
data->mCreatureStats.setDynamic (i, 10);
|
||||||
|
|
||||||
|
data->mCreatureStats.setLevel (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->mCreatureStats.setHello(ref->base->mAiData.mHello);
|
data->mCreatureStats.setHello(ref->base->mAiData.mHello);
|
||||||
|
|
|
@ -24,8 +24,8 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
// magic effects
|
// magic effects
|
||||||
adjustMagicEffects (ptr);
|
adjustMagicEffects (ptr);
|
||||||
calculateCreatureStatModifiers (ptr);
|
|
||||||
calculateDynamicStats (ptr);
|
calculateDynamicStats (ptr);
|
||||||
|
calculateCreatureStatModifiers (ptr);
|
||||||
|
|
||||||
// AI
|
// AI
|
||||||
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
CreatureStats& creatureStats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||||
|
@ -73,13 +73,17 @@ namespace MWMechanics
|
||||||
double magickaFactor =
|
double magickaFactor =
|
||||||
creatureStats.getMagicEffects().get (EffectKey (84)).mMagnitude * 0.1 + 0.5;
|
creatureStats.getMagicEffects().get (EffectKey (84)).mMagnitude * 0.1 + 0.5;
|
||||||
|
|
||||||
creatureStats.getHealth().setBase(
|
DynamicStat<float> health = creatureStats.getHealth();
|
||||||
static_cast<int> (0.5 * (strength + endurance)) + creatureStats.getLevelHealthBonus ());
|
health.setBase (static_cast<int> (0.5 * (strength + endurance)) + creatureStats.getLevelHealthBonus ());
|
||||||
|
creatureStats.setHealth (health);
|
||||||
|
|
||||||
creatureStats.getMagicka().setBase(
|
DynamicStat<float> magicka = creatureStats.getMagicka();
|
||||||
static_cast<int> (intelligence + magickaFactor * intelligence));
|
magicka.setBase (static_cast<int> (intelligence + magickaFactor * intelligence));
|
||||||
|
creatureStats.setMagicka (magicka);
|
||||||
creatureStats.getFatigue().setBase(strength+willpower+agility+endurance);
|
|
||||||
|
DynamicStat<float> fatigue = creatureStats.getFatigue();
|
||||||
|
fatigue.setBase (strength+willpower+agility+endurance);
|
||||||
|
creatureStats.setFatigue (fatigue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration)
|
void Actors::calculateRestoration (const MWWorld::Ptr& ptr, float duration)
|
||||||
|
@ -92,8 +96,10 @@ namespace MWMechanics
|
||||||
bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(136)).mMagnitude > 0;
|
bool stunted = stats.getMagicEffects ().get(MWMechanics::EffectKey(136)).mMagnitude > 0;
|
||||||
|
|
||||||
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
int endurance = stats.getAttribute (ESM::Attribute::Endurance).getModified ();
|
||||||
stats.getHealth().setCurrent(stats.getHealth ().getCurrent ()
|
|
||||||
+ 0.1 * endurance);
|
DynamicStat<float> health = stats.getHealth();
|
||||||
|
health.setCurrent (health.getCurrent() + 0.1 * endurance);
|
||||||
|
stats.setHealth (health);
|
||||||
|
|
||||||
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
|
@ -109,13 +115,19 @@ namespace MWMechanics
|
||||||
|
|
||||||
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
|
float x = fFatigueReturnBase + fFatigueReturnMult * (1 - normalizedEncumbrance);
|
||||||
x *= fEndFatigueMult * endurance;
|
x *= fEndFatigueMult * endurance;
|
||||||
stats.getFatigue ().setCurrent (stats.getFatigue ().getCurrent () + 3600 * x);
|
|
||||||
|
DynamicStat<float> fatigue = stats.getFatigue();
|
||||||
|
fatigue.setCurrent (fatigue.getCurrent() + 3600 * x);
|
||||||
|
stats.setFatigue (fatigue);
|
||||||
|
|
||||||
if (!stunted)
|
if (!stunted)
|
||||||
{
|
{
|
||||||
float fRestMagicMult = store.gameSettings.find("fRestMagicMult")->getFloat ();
|
float fRestMagicMult = store.gameSettings.find("fRestMagicMult")->getFloat ();
|
||||||
stats.getMagicka().setCurrent (stats.getMagicka ().getCurrent ()
|
|
||||||
+ fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified ());
|
DynamicStat<float> magicka = stats.getMagicka();
|
||||||
|
magicka.setCurrent (magicka.getCurrent()
|
||||||
|
+ fRestMagicMult * stats.getAttribute(ESM::Attribute::Intelligence).getModified());
|
||||||
|
stats.setMagicka (magicka);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,21 +149,26 @@ namespace MWMechanics
|
||||||
|
|
||||||
// dynamic stats
|
// dynamic stats
|
||||||
MagicEffects effects = creatureStats.getMagicEffects();
|
MagicEffects effects = creatureStats.getMagicEffects();
|
||||||
creatureStats.getHealth().setModifier(
|
|
||||||
effects.get(EffectKey(80)).mMagnitude - effects.get(EffectKey(18)).mMagnitude);
|
for (int i=0; i<3; ++i)
|
||||||
|
{
|
||||||
creatureStats.getMagicka().setModifier(
|
DynamicStat<float> stat = creatureStats.getDynamic (i);
|
||||||
effects.get(EffectKey(81)).mMagnitude - effects.get(EffectKey(19)).mMagnitude);
|
|
||||||
|
stat.setModifier (
|
||||||
creatureStats.getFatigue().setModifier(
|
effects.get (EffectKey(80+i)).mMagnitude - effects.get (EffectKey(18+i)).mMagnitude);
|
||||||
effects.get(EffectKey(82)).mMagnitude - effects.get(EffectKey(20)).mMagnitude);
|
|
||||||
|
creatureStats.setDynamic (i, stat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Actors::Actors() : mDuration (0) {}
|
Actors::Actors() : mDuration (0) {}
|
||||||
|
|
||||||
void Actors::addActor (const MWWorld::Ptr& ptr)
|
void Actors::addActor (const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
mActors.insert (ptr);
|
if (!MWWorld::Class::get (ptr).getCreatureStats (ptr).isDead())
|
||||||
|
mActors.insert (ptr);
|
||||||
|
else
|
||||||
|
MWBase::Environment::get().getWorld()->playAnimationGroup (ptr, "death1", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::removeActor (const MWWorld::Ptr& ptr)
|
void Actors::removeActor (const MWWorld::Ptr& ptr)
|
||||||
|
@ -184,13 +201,47 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
float totalDuration = mDuration;
|
float totalDuration = mDuration;
|
||||||
mDuration = 0;
|
mDuration = 0;
|
||||||
|
|
||||||
|
std::set<MWWorld::Ptr>::iterator iter (mActors.begin());
|
||||||
|
|
||||||
for (std::set<MWWorld::Ptr>::iterator iter (mActors.begin()); iter!=mActors.end(); ++iter)
|
while (iter!=mActors.end())
|
||||||
{
|
{
|
||||||
updateActor (*iter, totalDuration);
|
if (!MWWorld::Class::get (*iter).getCreatureStats (*iter).isDead())
|
||||||
|
{
|
||||||
|
updateActor (*iter, totalDuration);
|
||||||
|
|
||||||
if (iter->getTypeName()==typeid (ESM::NPC).name())
|
if (iter->getTypeName()==typeid (ESM::NPC).name())
|
||||||
updateNpc (*iter, totalDuration, paused);
|
updateNpc (*iter, totalDuration, paused);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MWWorld::Class::get (*iter).getCreatureStats (*iter).isDead())
|
||||||
|
{
|
||||||
|
// workaround: always keep player alive for now
|
||||||
|
// \todo remove workaround, once player death can be handled
|
||||||
|
if (iter->getRefData().getHandle()=="player")
|
||||||
|
{
|
||||||
|
MWMechanics::DynamicStat<float> stat (
|
||||||
|
MWWorld::Class::get (*iter).getCreatureStats (*iter).getHealth());
|
||||||
|
|
||||||
|
if (stat.getModified()<1)
|
||||||
|
{
|
||||||
|
stat.setModified (1, 0);
|
||||||
|
MWWorld::Class::get (*iter).getCreatureStats (*iter).setHealth (stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
MWWorld::Class::get (*iter).getCreatureStats (*iter).resurrect();
|
||||||
|
++iter;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
++mDeathCount[MWWorld::Class::get (*iter).getId (*iter)];
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWorld()->playAnimationGroup (*iter, "death1", 0);
|
||||||
|
|
||||||
|
mActors.erase (iter++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,4 +262,14 @@ namespace MWMechanics
|
||||||
calculateRestoration (*iter, 3600);
|
calculateRestoration (*iter, 3600);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Actors::countDeaths (const std::string& id) const
|
||||||
|
{
|
||||||
|
std::map<std::string, int>::const_iterator iter = mDeathCount.find (id);
|
||||||
|
|
||||||
|
if (iter!=mDeathCount.end())
|
||||||
|
return iter->second;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace Ogre
|
namespace Ogre
|
||||||
{
|
{
|
||||||
|
@ -22,6 +23,7 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
std::set<MWWorld::Ptr> mActors;
|
std::set<MWWorld::Ptr> mActors;
|
||||||
float mDuration;
|
float mDuration;
|
||||||
|
std::map<std::string, int> mDeathCount;
|
||||||
|
|
||||||
void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused);
|
void updateNpc (const MWWorld::Ptr& ptr, float duration, bool paused);
|
||||||
|
|
||||||
|
@ -40,6 +42,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
void addActor (const MWWorld::Ptr& ptr);
|
void addActor (const MWWorld::Ptr& ptr);
|
||||||
///< Register an actor for stats management
|
///< Register an actor for stats management
|
||||||
|
///
|
||||||
|
/// \note Dead actors are ignored.
|
||||||
|
|
||||||
void removeActor (const MWWorld::Ptr& ptr);
|
void removeActor (const MWWorld::Ptr& ptr);
|
||||||
///< Deregister an actor for stats management
|
///< Deregister an actor for stats management
|
||||||
|
@ -59,6 +63,9 @@ namespace MWMechanics
|
||||||
|
|
||||||
void restoreDynamicStats();
|
void restoreDynamicStats();
|
||||||
///< If the player is sleeping, this should be called every hour.
|
///< If the player is sleeping, this should be called every hour.
|
||||||
|
|
||||||
|
int countDeaths (const std::string& id) const;
|
||||||
|
///< Return the number of deaths for actors with the given ID.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
CreatureStats::CreatureStats()
|
CreatureStats::CreatureStats()
|
||||||
: mLevelHealthBonus(0.f)
|
: mLevel (0), mHello (0), mFight (0), mFlee (0), mAlarm (0), mLevelHealthBonus(0.f), mDead (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,22 +118,7 @@ namespace MWMechanics
|
||||||
return mAttributes[index];
|
return mAttributes[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
DynamicStat<float> &CreatureStats::getHealth()
|
const DynamicStat<float> &CreatureStats::getDynamic(int index) const
|
||||||
{
|
|
||||||
return mDynamic[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicStat<float> &CreatureStats::getMagicka()
|
|
||||||
{
|
|
||||||
return mDynamic[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicStat<float> &CreatureStats::getFatigue()
|
|
||||||
{
|
|
||||||
return mDynamic[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicStat<float> &CreatureStats::getDynamic(int index)
|
|
||||||
{
|
{
|
||||||
if (index < 0 || index > 2) {
|
if (index < 0 || index > 2) {
|
||||||
throw std::runtime_error("dynamic stat index is out of range");
|
throw std::runtime_error("dynamic stat index is out of range");
|
||||||
|
@ -171,19 +156,30 @@ namespace MWMechanics
|
||||||
|
|
||||||
void CreatureStats::setHealth(const DynamicStat<float> &value)
|
void CreatureStats::setHealth(const DynamicStat<float> &value)
|
||||||
{
|
{
|
||||||
mDynamic[0] = value;
|
setDynamic (0, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureStats::setMagicka(const DynamicStat<float> &value)
|
void CreatureStats::setMagicka(const DynamicStat<float> &value)
|
||||||
{
|
{
|
||||||
mDynamic[1] = value;
|
setDynamic (1, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreatureStats::setFatigue(const DynamicStat<float> &value)
|
void CreatureStats::setFatigue(const DynamicStat<float> &value)
|
||||||
{
|
{
|
||||||
mDynamic[2] = value;
|
setDynamic (2, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setDynamic (int index, const DynamicStat<float> &value)
|
||||||
|
{
|
||||||
|
if (index < 0 || index > 2)
|
||||||
|
throw std::runtime_error("dynamic stat index is out of range");
|
||||||
|
|
||||||
|
mDynamic[index] = value;
|
||||||
|
|
||||||
|
if (index==0 && mDynamic[index].getCurrent()<1)
|
||||||
|
mDead = true;
|
||||||
|
}
|
||||||
|
|
||||||
void CreatureStats::setLevel(int level)
|
void CreatureStats::setLevel(int level)
|
||||||
{
|
{
|
||||||
mLevel = level;
|
mLevel = level;
|
||||||
|
@ -218,4 +214,21 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
mAlarm = value;
|
mAlarm = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CreatureStats::isDead() const
|
||||||
|
{
|
||||||
|
return mDead;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::resurrect()
|
||||||
|
{
|
||||||
|
if (mDead)
|
||||||
|
{
|
||||||
|
if (mDynamic[0].getCurrent()<1)
|
||||||
|
mDynamic[0].setCurrent (1);
|
||||||
|
|
||||||
|
if (mDynamic[0].getCurrent()>=1)
|
||||||
|
mDead = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ namespace MWMechanics
|
||||||
int mFlee;
|
int mFlee;
|
||||||
int mAlarm;
|
int mAlarm;
|
||||||
AiSequence mAiSequence;
|
AiSequence mAiSequence;
|
||||||
|
|
||||||
float mLevelHealthBonus;
|
float mLevelHealthBonus;
|
||||||
|
bool mDead;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CreatureStats();
|
CreatureStats();
|
||||||
|
@ -43,6 +43,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
const DynamicStat<float> & getFatigue() const;
|
const DynamicStat<float> & getFatigue() const;
|
||||||
|
|
||||||
|
const DynamicStat<float> & getDynamic (int index) const;
|
||||||
|
|
||||||
const Spells & getSpells() const;
|
const Spells & getSpells() const;
|
||||||
|
|
||||||
const ActiveSpells & getActiveSpells() const;
|
const ActiveSpells & getActiveSpells() const;
|
||||||
|
@ -59,24 +61,14 @@ namespace MWMechanics
|
||||||
|
|
||||||
int getAlarm() const;
|
int getAlarm() const;
|
||||||
|
|
||||||
|
|
||||||
Stat<int> & getAttribute(int index);
|
Stat<int> & getAttribute(int index);
|
||||||
|
|
||||||
DynamicStat<float> & getHealth();
|
|
||||||
|
|
||||||
DynamicStat<float> & getMagicka();
|
|
||||||
|
|
||||||
DynamicStat<float> & getFatigue();
|
|
||||||
|
|
||||||
DynamicStat<float> & getDynamic(int index);
|
|
||||||
|
|
||||||
Spells & getSpells();
|
Spells & getSpells();
|
||||||
|
|
||||||
ActiveSpells & getActiveSpells();
|
ActiveSpells & getActiveSpells();
|
||||||
|
|
||||||
MagicEffects & getMagicEffects();
|
MagicEffects & getMagicEffects();
|
||||||
|
|
||||||
|
|
||||||
void setAttribute(int index, const Stat<int> &value);
|
void setAttribute(int index, const Stat<int> &value);
|
||||||
|
|
||||||
void setHealth(const DynamicStat<float> &value);
|
void setHealth(const DynamicStat<float> &value);
|
||||||
|
@ -85,6 +77,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
void setFatigue(const DynamicStat<float> &value);
|
void setFatigue(const DynamicStat<float> &value);
|
||||||
|
|
||||||
|
void setDynamic (int index, const DynamicStat<float> &value);
|
||||||
|
|
||||||
void setSpells(const Spells &spells);
|
void setSpells(const Spells &spells);
|
||||||
|
|
||||||
void setActiveSpells(const ActiveSpells &active);
|
void setActiveSpells(const ActiveSpells &active);
|
||||||
|
@ -111,6 +105,10 @@ namespace MWMechanics
|
||||||
// small hack to allow the fact that Health permanently increases by 10% of endurance on each level up
|
// small hack to allow the fact that Health permanently increases by 10% of endurance on each level up
|
||||||
void increaseLevelHealthBonus(float value);
|
void increaseLevelHealthBonus(float value);
|
||||||
float getLevelHealthBonus() const;
|
float getLevelHealthBonus() const;
|
||||||
|
|
||||||
|
bool isDead() const;
|
||||||
|
|
||||||
|
void resurrect();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,12 +153,14 @@ namespace MWMechanics
|
||||||
// forced update and current value adjustments
|
// forced update and current value adjustments
|
||||||
mActors.updateActor (ptr, 0);
|
mActors.updateActor (ptr, 0);
|
||||||
|
|
||||||
creatureStats.getHealth().setCurrent(creatureStats.getHealth().getModified());
|
for (int i=0; i<2; ++i)
|
||||||
creatureStats.getMagicka().setCurrent(creatureStats.getMagicka().getModified());
|
{
|
||||||
creatureStats.getFatigue().setCurrent(creatureStats.getFatigue().getModified());
|
DynamicStat<float> stat = creatureStats.getDynamic (i);
|
||||||
|
stat.setCurrent (stat.getModified());
|
||||||
|
creatureStats.setDynamic (i, stat);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MechanicsManager::MechanicsManager()
|
MechanicsManager::MechanicsManager()
|
||||||
: mUpdatePlayer (true), mClassSelected (false),
|
: mUpdatePlayer (true), mClassSelected (false),
|
||||||
mRaceSelected (false)
|
mRaceSelected (false)
|
||||||
|
@ -324,4 +326,9 @@ namespace MWMechanics
|
||||||
buildPlayer();
|
buildPlayer();
|
||||||
mUpdatePlayer = true;
|
mUpdatePlayer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MechanicsManager::countDeaths (const std::string& id) const
|
||||||
|
{
|
||||||
|
return mActors.countDeaths (id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual void addActor (const MWWorld::Ptr& ptr);
|
virtual void addActor (const MWWorld::Ptr& ptr);
|
||||||
///< Register an actor for stats management
|
///< Register an actor for stats management
|
||||||
|
///
|
||||||
|
/// \note Dead actors are ignored.
|
||||||
|
|
||||||
virtual void removeActor (const MWWorld::Ptr& ptr);
|
virtual void removeActor (const MWWorld::Ptr& ptr);
|
||||||
///< Deregister an actor for stats management
|
///< Deregister an actor for stats management
|
||||||
|
@ -76,6 +78,10 @@ namespace MWMechanics
|
||||||
|
|
||||||
virtual void restoreDynamicStats();
|
virtual void restoreDynamicStats();
|
||||||
///< If the player is sleeping, this should be called every hour.
|
///< If the player is sleeping, this should be called every hour.
|
||||||
|
|
||||||
|
virtual int countDeaths (const std::string& id) const;
|
||||||
|
///< Return the number of deaths for actors with the given ID.
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -206,5 +206,6 @@ op 0x200019f: GetPcSleep
|
||||||
op 0x20001a0: ShowMap
|
op 0x20001a0: ShowMap
|
||||||
op 0x20001a1: FillMap
|
op 0x20001a1: FillMap
|
||||||
op 0x20001a2: WakeUpPc
|
op 0x20001a2: WakeUpPc
|
||||||
opcodes 0x20001a3-0x3ffffff unused
|
op 0x20001a3: GetDeadCount
|
||||||
|
opcodes 0x20001a4-0x3ffffff unused
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/dialoguemanager.hpp"
|
#include "../mwbase/dialoguemanager.hpp"
|
||||||
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
#include "../mwworld/player.hpp"
|
||||||
|
@ -155,7 +156,7 @@ namespace MWScript
|
||||||
virtual void execute (Interpreter::Runtime& runtime)
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
Interpreter::Type_Integer value;
|
Interpreter::Type_Float value;
|
||||||
|
|
||||||
if (mIndex==0 && MWWorld::Class::get (ptr).hasItemHealth (ptr))
|
if (mIndex==0 && MWWorld::Class::get (ptr).hasItemHealth (ptr))
|
||||||
{
|
{
|
||||||
|
@ -185,13 +186,15 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
Interpreter::Type_Integer value = runtime[0].mInteger;
|
Interpreter::Type_Float value = runtime[0].mFloat;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
MWWorld::Class::get(ptr)
|
MWMechanics::DynamicStat<float> stat (MWWorld::Class::get (ptr).getCreatureStats (ptr)
|
||||||
.getCreatureStats(ptr)
|
.getDynamic (mIndex));
|
||||||
.getDynamic(mIndex)
|
|
||||||
.setModified(value, 0);
|
stat.setModified (value, 0);
|
||||||
|
|
||||||
|
MWWorld::Class::get (ptr).getCreatureStats (ptr).setDynamic (mIndex, stat);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -208,17 +211,21 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
Interpreter::Type_Integer diff = runtime[0].mInteger;
|
Interpreter::Type_Float diff = runtime[0].mFloat;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||||
|
|
||||||
Interpreter::Type_Integer current = stats.getDynamic(mIndex).getCurrent();
|
Interpreter::Type_Float current = stats.getDynamic(mIndex).getCurrent();
|
||||||
|
|
||||||
stats.getDynamic(mIndex).setModified(
|
MWMechanics::DynamicStat<float> stat (MWWorld::Class::get (ptr).getCreatureStats (ptr)
|
||||||
diff + stats.getDynamic(mIndex).getModified(), 0);
|
.getDynamic (mIndex));
|
||||||
|
|
||||||
stats.getDynamic(mIndex).setCurrent(diff + current);
|
stat.setModified (diff + stat.getModified(), 0);
|
||||||
|
|
||||||
|
stat.setCurrent (diff + current);
|
||||||
|
|
||||||
|
MWWorld::Class::get (ptr).getCreatureStats (ptr).setDynamic (mIndex, stat);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -235,14 +242,19 @@ namespace MWScript
|
||||||
{
|
{
|
||||||
MWWorld::Ptr ptr = R()(runtime);
|
MWWorld::Ptr ptr = R()(runtime);
|
||||||
|
|
||||||
Interpreter::Type_Integer diff = runtime[0].mInteger;
|
Interpreter::Type_Float diff = runtime[0].mFloat;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
MWMechanics::CreatureStats& stats = MWWorld::Class::get (ptr).getCreatureStats (ptr);
|
||||||
|
|
||||||
Interpreter::Type_Integer current = stats.getDynamic(mIndex).getCurrent();
|
Interpreter::Type_Float current = stats.getDynamic(mIndex).getCurrent();
|
||||||
|
|
||||||
stats.getDynamic(mIndex).setCurrent (diff + current);
|
MWMechanics::DynamicStat<float> stat (MWWorld::Class::get (ptr).getCreatureStats (ptr)
|
||||||
|
.getDynamic (mIndex));
|
||||||
|
|
||||||
|
stat.setCurrent (diff + current);
|
||||||
|
|
||||||
|
MWWorld::Class::get (ptr).getCreatureStats (ptr).setDynamic (mIndex, stat);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -580,6 +592,17 @@ namespace MWScript
|
||||||
/// \todo modify disposition towards the player
|
/// \todo modify disposition towards the player
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OpGetDeadCount : public Interpreter::Opcode0
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual void execute (Interpreter::Runtime& runtime)
|
||||||
|
{
|
||||||
|
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
|
runtime[0].mInteger = MWBase::Environment::get().getMechanicsManager()->countDeaths (id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const int numberOfAttributes = 8;
|
const int numberOfAttributes = 8;
|
||||||
|
@ -632,6 +655,8 @@ namespace MWScript
|
||||||
const int opcodeGetLevelExplicit = 0x200018d;
|
const int opcodeGetLevelExplicit = 0x200018d;
|
||||||
const int opcodeSetLevel = 0x200018e;
|
const int opcodeSetLevel = 0x200018e;
|
||||||
const int opcodeSetLevelExplicit = 0x200018f;
|
const int opcodeSetLevelExplicit = 0x200018f;
|
||||||
|
|
||||||
|
const int opcodeGetDeadCount = 0x20001a3;
|
||||||
|
|
||||||
void registerExtensions (Compiler::Extensions& extensions)
|
void registerExtensions (Compiler::Extensions& extensions)
|
||||||
{
|
{
|
||||||
|
@ -676,16 +701,16 @@ namespace MWScript
|
||||||
|
|
||||||
for (int i=0; i<numberOfDynamics; ++i)
|
for (int i=0; i<numberOfDynamics; ++i)
|
||||||
{
|
{
|
||||||
extensions.registerFunction (get + dynamics[i], 'l', "",
|
extensions.registerFunction (get + dynamics[i], 'f', "",
|
||||||
opcodeGetDynamic+i, opcodeGetDynamicExplicit+i);
|
opcodeGetDynamic+i, opcodeGetDynamicExplicit+i);
|
||||||
|
|
||||||
extensions.registerInstruction (set + dynamics[i], "l",
|
extensions.registerInstruction (set + dynamics[i], "f",
|
||||||
opcodeSetDynamic+i, opcodeSetDynamicExplicit+i);
|
opcodeSetDynamic+i, opcodeSetDynamicExplicit+i);
|
||||||
|
|
||||||
extensions.registerInstruction (mod + dynamics[i], "l",
|
extensions.registerInstruction (mod + dynamics[i], "f",
|
||||||
opcodeModDynamic+i, opcodeModDynamicExplicit+i);
|
opcodeModDynamic+i, opcodeModDynamicExplicit+i);
|
||||||
|
|
||||||
extensions.registerInstruction (modCurrent + dynamics[i], "l",
|
extensions.registerInstruction (modCurrent + dynamics[i], "f",
|
||||||
opcodeModCurrentDynamic+i, opcodeModCurrentDynamicExplicit+i);
|
opcodeModCurrentDynamic+i, opcodeModCurrentDynamicExplicit+i);
|
||||||
|
|
||||||
extensions.registerFunction (get + dynamics[i] + getRatio, 'f', "",
|
extensions.registerFunction (get + dynamics[i] + getRatio, 'f', "",
|
||||||
|
@ -718,6 +743,8 @@ namespace MWScript
|
||||||
|
|
||||||
extensions.registerInstruction("setlevel", "l", opcodeSetLevel, opcodeSetLevelExplicit);
|
extensions.registerInstruction("setlevel", "l", opcodeSetLevel, opcodeSetLevelExplicit);
|
||||||
extensions.registerFunction("getlevel", 'l', "", opcodeGetLevel, opcodeGetLevelExplicit);
|
extensions.registerFunction("getlevel", 'l', "", opcodeGetLevel, opcodeGetLevelExplicit);
|
||||||
|
|
||||||
|
extensions.registerFunction("getdeadcount", 'l', "c", opcodeGetDeadCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||||
|
@ -795,6 +822,7 @@ namespace MWScript
|
||||||
interpreter.installSegment5 (opcodeSetLevel, new OpSetLevel<ImplicitRef>);
|
interpreter.installSegment5 (opcodeSetLevel, new OpSetLevel<ImplicitRef>);
|
||||||
interpreter.installSegment5 (opcodeSetLevelExplicit, new OpSetLevel<ExplicitRef>);
|
interpreter.installSegment5 (opcodeSetLevelExplicit, new OpSetLevel<ExplicitRef>);
|
||||||
|
|
||||||
|
interpreter.installSegment5 (opcodeGetDeadCount, new OpGetDeadCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue