mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-22 09:09:41 +00:00
Merge branch 'ingredients'
This commit is contained in:
commit
835c530e06
14 changed files with 487 additions and 262 deletions
|
@ -51,7 +51,7 @@ add_openmw_dir (mwworld
|
||||||
refdata worldimp physicssystem scene globals class action nullaction actionteleport
|
refdata worldimp physicssystem scene globals class action nullaction actionteleport
|
||||||
containerstore actiontalk actiontake manualref player cellfunctors
|
containerstore actiontalk actiontake manualref player cellfunctors
|
||||||
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
||||||
actionequip timestamp actionalchemy cellstore actionapply
|
actionequip timestamp actionalchemy cellstore actionapply actioneat
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwclass
|
add_openmw_dir (mwclass
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "../mwworld/actiontake.hpp"
|
#include "../mwworld/actiontake.hpp"
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
#include "../mwworld/physicssystem.hpp"
|
#include "../mwworld/physicssystem.hpp"
|
||||||
|
#include "../mwworld/actioneat.hpp"
|
||||||
|
|
||||||
#include "../mwgui/tooltips.hpp"
|
#include "../mwgui/tooltips.hpp"
|
||||||
|
|
||||||
|
@ -19,6 +20,14 @@
|
||||||
|
|
||||||
namespace MWClass
|
namespace MWClass
|
||||||
{
|
{
|
||||||
|
std::string Ingredient::getId (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
MWWorld::LiveCellRef<ESM::Ingredient> *ref =
|
||||||
|
ptr.get<ESM::Ingredient>();
|
||||||
|
|
||||||
|
return ref->base->mId;
|
||||||
|
}
|
||||||
|
|
||||||
void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
@ -84,6 +93,16 @@ namespace MWClass
|
||||||
return ref->base->data.value;
|
return ref->base->data.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boost::shared_ptr<MWWorld::Action> Ingredient::use (const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
boost::shared_ptr<MWWorld::Action> action (new MWWorld::ActionEat (ptr));
|
||||||
|
|
||||||
|
action->setSound ("Swallow");
|
||||||
|
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
void Ingredient::registerSelf()
|
void Ingredient::registerSelf()
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Class> instance (new Ingredient);
|
boost::shared_ptr<Class> instance (new Ingredient);
|
||||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
virtual std::string getId (const MWWorld::Ptr& ptr) const;
|
||||||
|
///< Return ID of \a ptr
|
||||||
|
|
||||||
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
virtual void insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const;
|
||||||
///< Add reference into a cell for rendering
|
///< Add reference into a cell for rendering
|
||||||
|
|
||||||
|
@ -37,6 +40,10 @@ namespace MWClass
|
||||||
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||||
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
///< Return trade value of the object. Throws an exception, if the object can't be traded.
|
||||||
|
|
||||||
|
virtual boost::shared_ptr<MWWorld::Action> use (const MWWorld::Ptr& ptr)
|
||||||
|
const;
|
||||||
|
///< Generate action for using via inventory menu
|
||||||
|
|
||||||
static void registerSelf();
|
static void registerSelf();
|
||||||
|
|
||||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
|
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
|
@ -365,7 +365,7 @@ namespace MWClass
|
||||||
|
|
||||||
/// \todo consider instant effects
|
/// \todo consider instant effects
|
||||||
|
|
||||||
return stats.getActiveSpells().addSpell (id);
|
return stats.getActiveSpells().addSpell (id, actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Npc::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const
|
void Npc::skillUsageSucceeded (const MWWorld::Ptr& ptr, int skill, int usageType) const
|
||||||
|
|
|
@ -5,12 +5,20 @@
|
||||||
|
|
||||||
#include <components/esm/loadalch.hpp>
|
#include <components/esm/loadalch.hpp>
|
||||||
#include <components/esm/loadspel.hpp>
|
#include <components/esm/loadspel.hpp>
|
||||||
|
#include <components/esm/loadingr.hpp>
|
||||||
|
#include <components/esm/loadmgef.hpp>
|
||||||
|
#include <components/esm/loadskil.hpp>
|
||||||
|
|
||||||
#include <components/esm_store/store.hpp>
|
#include <components/esm_store/store.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
#include "creaturestats.hpp"
|
||||||
|
#include "npcstats.hpp"
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
void ActiveSpells::update() const
|
void ActiveSpells::update() const
|
||||||
|
@ -41,47 +49,102 @@ namespace MWMechanics
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rebuild)
|
if (rebuild)
|
||||||
|
rebuildEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActiveSpells::rebuildEffects() const
|
||||||
{
|
{
|
||||||
|
MWWorld::TimeStamp now = MWBase::Environment::get().getWorld()->getTimeStamp();
|
||||||
|
|
||||||
mEffects = MagicEffects();
|
mEffects = MagicEffects();
|
||||||
|
|
||||||
for (TIterator iter (begin()); iter!=end(); ++iter)
|
for (TIterator iter (begin()); iter!=end(); ++iter)
|
||||||
{
|
{
|
||||||
const ESM::EffectList& effects = getEffectList (iter->first);
|
std::pair<ESM::EffectList, bool> effects = getEffectList (iter->first);
|
||||||
|
|
||||||
const MWWorld::TimeStamp& start = iter->second.first;
|
const MWWorld::TimeStamp& start = iter->second.first;
|
||||||
float magnitude = iter->second.second;
|
float magnitude = iter->second.second;
|
||||||
|
|
||||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin());
|
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin());
|
||||||
iter!=effects.list.end(); ++iter)
|
iter!=effects.first.list.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (iter->duration)
|
if (iter->duration)
|
||||||
{
|
{
|
||||||
|
int duration = iter->duration;
|
||||||
|
|
||||||
|
if (effects.second)
|
||||||
|
duration *= magnitude;
|
||||||
|
|
||||||
MWWorld::TimeStamp end = start;
|
MWWorld::TimeStamp end = start;
|
||||||
end += static_cast<double> (iter->duration)*
|
end += static_cast<double> (duration)*
|
||||||
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
|
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
|
||||||
|
|
||||||
if (end>now)
|
if (end>now)
|
||||||
{
|
{
|
||||||
EffectParam param;
|
EffectParam param;
|
||||||
|
|
||||||
|
if (effects.second)
|
||||||
|
{
|
||||||
|
const ESM::MagicEffect *magicEffect =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().magicEffects.find (
|
||||||
|
iter->effectID);
|
||||||
|
|
||||||
|
if (iter->duration==0)
|
||||||
|
{
|
||||||
|
param.mMagnitude =
|
||||||
|
static_cast<int> (magnitude / (0.1 * magicEffect->data.baseCost));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
param.mMagnitude =
|
||||||
|
static_cast<int> (0.05*magnitude / (0.1 * magicEffect->data.baseCost));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
param.mMagnitude = static_cast<int> (
|
param.mMagnitude = static_cast<int> (
|
||||||
(iter->magnMax-iter->magnMin+1)*magnitude + iter->magnMin);
|
(iter->magnMax-iter->magnMin)*magnitude + iter->magnMin);
|
||||||
|
|
||||||
mEffects.add (*iter, param);
|
mEffects.add (*iter, param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const ESM::EffectList& ActiveSpells::getEffectList (const std::string& id) const
|
std::pair<ESM::EffectList, bool> ActiveSpells::getEffectList (const std::string& id) const
|
||||||
{
|
{
|
||||||
if (const ESM::Spell *spell =
|
if (const ESM::Spell *spell =
|
||||||
MWBase::Environment::get().getWorld()->getStore().spells.search (id))
|
MWBase::Environment::get().getWorld()->getStore().spells.search (id))
|
||||||
return spell->effects;
|
return std::make_pair (spell->effects, false);
|
||||||
|
|
||||||
if (const ESM::Potion *potion =
|
if (const ESM::Potion *potion =
|
||||||
MWBase::Environment::get().getWorld()->getStore().potions.search (id))
|
MWBase::Environment::get().getWorld()->getStore().potions.search (id))
|
||||||
return potion->effects;
|
return std::make_pair (potion->effects, false);
|
||||||
|
|
||||||
|
if (const ESM::Ingredient *ingredient =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().ingreds.search (id))
|
||||||
|
{
|
||||||
|
const ESM::MagicEffect *magicEffect =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().magicEffects.find (
|
||||||
|
ingredient->data.effectID[0]);
|
||||||
|
|
||||||
|
ESM::ENAMstruct effect;
|
||||||
|
effect.effectID = ingredient->data.effectID[0];
|
||||||
|
effect.skill = ingredient->data.skills[0];
|
||||||
|
effect.attribute = ingredient->data.attributes[0];
|
||||||
|
effect.range = 0;
|
||||||
|
effect.area = 0;
|
||||||
|
effect.duration = magicEffect->data.flags & ESM::MagicEffect::NoDuration ? 0 : 1;
|
||||||
|
effect.magnMin = 1;
|
||||||
|
effect.magnMax = 1;
|
||||||
|
|
||||||
|
std::pair<ESM::EffectList, bool> result;
|
||||||
|
|
||||||
|
result.first.list.push_back (effect);
|
||||||
|
result.second = true;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
throw std::runtime_error ("ID " + id + " can not produce lasting effects");
|
throw std::runtime_error ("ID " + id + " can not produce lasting effects");
|
||||||
}
|
}
|
||||||
|
@ -90,14 +153,14 @@ namespace MWMechanics
|
||||||
: mSpellsChanged (false), mLastUpdate (MWBase::Environment::get().getWorld()->getTimeStamp())
|
: mSpellsChanged (false), mLastUpdate (MWBase::Environment::get().getWorld()->getTimeStamp())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool ActiveSpells::addSpell (const std::string& id)
|
bool ActiveSpells::addSpell (const std::string& id, const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
const ESM::EffectList& effects = getEffectList (id);
|
std::pair<ESM::EffectList, bool> effects = getEffectList (id);
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin());
|
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin());
|
||||||
iter!=effects.list.end(); ++iter)
|
iter!=effects.first.list.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (iter->duration)
|
if (iter->duration)
|
||||||
{
|
{
|
||||||
|
@ -113,6 +176,22 @@ namespace MWMechanics
|
||||||
|
|
||||||
float random = static_cast<float> (std::rand()) / RAND_MAX;
|
float random = static_cast<float> (std::rand()) / RAND_MAX;
|
||||||
|
|
||||||
|
if (effects.second)
|
||||||
|
{
|
||||||
|
// ingredient -> special treatment required.
|
||||||
|
const CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor);
|
||||||
|
const NpcStats& npcStats = MWWorld::Class::get (actor).getNpcStats (actor);
|
||||||
|
|
||||||
|
float x =
|
||||||
|
(npcStats.getSkill (ESM::Skill::Alchemy).getModified() +
|
||||||
|
0.2 * creatureStats.getAttribute (1).getModified()
|
||||||
|
+ 0.1 * creatureStats.getAttribute (7).getModified())
|
||||||
|
* creatureStats.getFatigueTerm();
|
||||||
|
random *= 100;
|
||||||
|
random = random / std::min (x, 100.0f);
|
||||||
|
random *= 0.25 * x;
|
||||||
|
}
|
||||||
|
|
||||||
if (iter==mSpells.end())
|
if (iter==mSpells.end())
|
||||||
mSpells.insert (std::make_pair (id,
|
mSpells.insert (std::make_pair (id,
|
||||||
std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random)));
|
std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random)));
|
||||||
|
@ -155,17 +234,20 @@ namespace MWMechanics
|
||||||
|
|
||||||
double ActiveSpells::timeToExpire (const TIterator& iterator) const
|
double ActiveSpells::timeToExpire (const TIterator& iterator) const
|
||||||
{
|
{
|
||||||
const ESM::EffectList& effects = getEffectList (iterator->first);
|
std::pair<ESM::EffectList, bool> effects = getEffectList (iterator->first);
|
||||||
|
|
||||||
int duration = 0;
|
int duration = 0;
|
||||||
|
|
||||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin());
|
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin());
|
||||||
iter!=effects.list.end(); ++iter)
|
iter!=effects.first.list.end(); ++iter)
|
||||||
{
|
{
|
||||||
if (iter->duration>duration)
|
if (iter->duration>duration)
|
||||||
duration = iter->duration;
|
duration = iter->duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (effects.second)
|
||||||
|
duration *= iterator->second.second;
|
||||||
|
|
||||||
double scaledDuration = duration *
|
double scaledDuration = duration *
|
||||||
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
|
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,11 @@ namespace ESM
|
||||||
struct EffectList;
|
struct EffectList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
class Ptr;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
/// \brief Lasting spell effects
|
/// \brief Lasting spell effects
|
||||||
|
@ -37,13 +42,15 @@ namespace MWMechanics
|
||||||
|
|
||||||
void update() const;
|
void update() const;
|
||||||
|
|
||||||
const ESM::EffectList& getEffectList (const std::string& id) const;
|
void rebuildEffects() const;
|
||||||
|
|
||||||
|
std::pair<ESM::EffectList, bool> getEffectList (const std::string& id) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ActiveSpells();
|
ActiveSpells();
|
||||||
|
|
||||||
bool addSpell (const std::string& id);
|
bool addSpell (const std::string& id, const MWWorld::Ptr& actor);
|
||||||
///< Overwrites an existing spell with the same ID. If the spell does not have any
|
///< Overwrites an existing spell with the same ID. If the spell does not have any
|
||||||
/// non-instant effects, it is ignored.
|
/// non-instant effects, it is ignored.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,51 +1,14 @@
|
||||||
#include "creaturestats.hpp"
|
#include "creaturestats.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <components/esm_store/store.hpp>
|
||||||
|
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
CreatureStats::CreatureStats()
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Can't use all benefits of members initialization because of
|
|
||||||
// lack of copy constructors
|
|
||||||
CreatureStats::CreatureStats(const CreatureStats &orig)
|
|
||||||
: mLevel(orig.mLevel), mHello(orig.mHello), mFight(orig.mFight),
|
|
||||||
mFlee(orig.mFlee), mAlarm(orig.mAlarm)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
mAttributes[i] = orig.mAttributes[i];
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
mDynamic[i] = orig.mDynamic[i];
|
|
||||||
}
|
|
||||||
mSpells = orig.mSpells;
|
|
||||||
mActiveSpells = orig.mActiveSpells;
|
|
||||||
mMagicEffects = orig.mMagicEffects;
|
|
||||||
}
|
|
||||||
|
|
||||||
CreatureStats::~CreatureStats()
|
|
||||||
{}
|
|
||||||
|
|
||||||
const CreatureStats &
|
|
||||||
CreatureStats::operator=(const CreatureStats &orig)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
mAttributes[i] = orig.mAttributes[i];
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
|
||||||
mDynamic[i] = orig.mDynamic[i];
|
|
||||||
}
|
|
||||||
mLevel = orig.mLevel;
|
|
||||||
mSpells = orig.mSpells;
|
|
||||||
mActiveSpells = orig.mActiveSpells;
|
|
||||||
mMagicEffects = orig.mMagicEffects;
|
|
||||||
mHello = orig.mHello;
|
|
||||||
mFight = orig.mFight;
|
|
||||||
mFlee = orig.mFlee;
|
|
||||||
mAlarm = orig.mAlarm;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
const AiSequence& CreatureStats::getAiSequence() const
|
const AiSequence& CreatureStats::getAiSequence() const
|
||||||
{
|
{
|
||||||
return mAiSequence;
|
return mAiSequence;
|
||||||
|
@ -55,4 +18,189 @@ namespace MWMechanics
|
||||||
{
|
{
|
||||||
return mAiSequence;
|
return mAiSequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float CreatureStats::getFatigueTerm() const
|
||||||
|
{
|
||||||
|
int max = getFatigue().getModified();
|
||||||
|
int current = getFatigue().getCurrent();
|
||||||
|
|
||||||
|
float normalised = max==0 ? 1 : std::max (0.0f, static_cast<float> (current)/max);
|
||||||
|
|
||||||
|
const ESMS::ESMStore& store = MWBase::Environment::get().getWorld()->getStore();
|
||||||
|
|
||||||
|
return store.gameSettings.find ("fFatigueBase")->getFloat()
|
||||||
|
- store.gameSettings.find ("fFatigueMult")->getFloat() * (1-normalised);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Stat<int> &CreatureStats::getAttribute(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index > 7) {
|
||||||
|
throw std::runtime_error("attribute index is out of range");
|
||||||
|
}
|
||||||
|
return mAttributes[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const DynamicStat<int> &CreatureStats::getHealth() const
|
||||||
|
{
|
||||||
|
return mDynamic[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
const DynamicStat<int> &CreatureStats::getMagicka() const
|
||||||
|
{
|
||||||
|
return mDynamic[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
const DynamicStat<int> &CreatureStats::getFatigue() const
|
||||||
|
{
|
||||||
|
return mDynamic[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Spells &CreatureStats::getSpells() const
|
||||||
|
{
|
||||||
|
return mSpells;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ActiveSpells &CreatureStats::getActiveSpells() const
|
||||||
|
{
|
||||||
|
return mActiveSpells;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MagicEffects &CreatureStats::getMagicEffects() const
|
||||||
|
{
|
||||||
|
return mMagicEffects;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CreatureStats::getLevel() const
|
||||||
|
{
|
||||||
|
return mLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CreatureStats::getHello() const
|
||||||
|
{
|
||||||
|
return mHello;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CreatureStats::getFight() const
|
||||||
|
{
|
||||||
|
return mFight;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CreatureStats::getFlee() const
|
||||||
|
{
|
||||||
|
return mFlee;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CreatureStats::getAlarm() const
|
||||||
|
{
|
||||||
|
return mAlarm;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stat<int> &CreatureStats::getAttribute(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index > 7) {
|
||||||
|
throw std::runtime_error("attribute index is out of range");
|
||||||
|
}
|
||||||
|
return mAttributes[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicStat<int> &CreatureStats::getHealth()
|
||||||
|
{
|
||||||
|
return mDynamic[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicStat<int> &CreatureStats::getMagicka()
|
||||||
|
{
|
||||||
|
return mDynamic[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicStat<int> &CreatureStats::getFatigue()
|
||||||
|
{
|
||||||
|
return mDynamic[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicStat<int> &CreatureStats::getDynamic(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index > 2) {
|
||||||
|
throw std::runtime_error("dynamic stat index is out of range");
|
||||||
|
}
|
||||||
|
return mDynamic[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
Spells &CreatureStats::getSpells()
|
||||||
|
{
|
||||||
|
return mSpells;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setSpells(const Spells &spells)
|
||||||
|
{
|
||||||
|
mSpells = spells;
|
||||||
|
}
|
||||||
|
|
||||||
|
ActiveSpells &CreatureStats::getActiveSpells()
|
||||||
|
{
|
||||||
|
return mActiveSpells;
|
||||||
|
}
|
||||||
|
|
||||||
|
MagicEffects &CreatureStats::getMagicEffects()
|
||||||
|
{
|
||||||
|
return mMagicEffects;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setAttribute(int index, const Stat<int> &value)
|
||||||
|
{
|
||||||
|
if (index < 0 || index > 7) {
|
||||||
|
throw std::runtime_error("attribute index is out of range");
|
||||||
|
}
|
||||||
|
mAttributes[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setHealth(const DynamicStat<int> &value)
|
||||||
|
{
|
||||||
|
mDynamic[0] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setMagicka(const DynamicStat<int> &value)
|
||||||
|
{
|
||||||
|
mDynamic[1] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setFatigue(const DynamicStat<int> &value)
|
||||||
|
{
|
||||||
|
mDynamic[2] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setLevel(int level)
|
||||||
|
{
|
||||||
|
mLevel = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setActiveSpells(const ActiveSpells &active)
|
||||||
|
{
|
||||||
|
mActiveSpells = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setMagicEffects(const MagicEffects &effects)
|
||||||
|
{
|
||||||
|
mMagicEffects = effects;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setHello(int value)
|
||||||
|
{
|
||||||
|
mHello = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setFight(int value)
|
||||||
|
{
|
||||||
|
mFight = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setFlee(int value)
|
||||||
|
{
|
||||||
|
mFlee = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::setAlarm(int value)
|
||||||
|
{
|
||||||
|
mAlarm = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,11 +31,6 @@ namespace MWMechanics
|
||||||
AiSequence mAiSequence;
|
AiSequence mAiSequence;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CreatureStats();
|
|
||||||
CreatureStats(const CreatureStats &);
|
|
||||||
virtual ~CreatureStats();
|
|
||||||
|
|
||||||
const CreatureStats & operator=(const CreatureStats &);
|
|
||||||
|
|
||||||
const Stat<int> & getAttribute(int index) const;
|
const Stat<int> & getAttribute(int index) const;
|
||||||
|
|
||||||
|
@ -106,185 +101,10 @@ namespace MWMechanics
|
||||||
const AiSequence& getAiSequence() const;
|
const AiSequence& getAiSequence() const;
|
||||||
|
|
||||||
AiSequence& getAiSequence();
|
AiSequence& getAiSequence();
|
||||||
|
|
||||||
|
float getFatigueTerm() const;
|
||||||
|
///< Return effective fatigue
|
||||||
};
|
};
|
||||||
|
|
||||||
// Inline const getters
|
|
||||||
|
|
||||||
inline const Stat<int> &
|
|
||||||
CreatureStats::getAttribute(int index) const {
|
|
||||||
if (index < 0 || index > 7) {
|
|
||||||
throw std::runtime_error("attribute index is out of range");
|
|
||||||
}
|
|
||||||
return mAttributes[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const DynamicStat<int> &
|
|
||||||
CreatureStats::getHealth() const {
|
|
||||||
return mDynamic[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const DynamicStat<int> &
|
|
||||||
CreatureStats::getMagicka() const {
|
|
||||||
return mDynamic[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const DynamicStat<int> &
|
|
||||||
CreatureStats::getFatigue() const {
|
|
||||||
return mDynamic[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const Spells &
|
|
||||||
CreatureStats::getSpells() const {
|
|
||||||
return mSpells;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const ActiveSpells &
|
|
||||||
CreatureStats::getActiveSpells() const {
|
|
||||||
return mActiveSpells;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const MagicEffects &
|
|
||||||
CreatureStats::getMagicEffects() const {
|
|
||||||
return mMagicEffects;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int
|
|
||||||
CreatureStats::getLevel() const {
|
|
||||||
return mLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int
|
|
||||||
CreatureStats::getHello() const {
|
|
||||||
return mHello;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int
|
|
||||||
CreatureStats::getFight() const {
|
|
||||||
return mFight;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int
|
|
||||||
CreatureStats::getFlee() const {
|
|
||||||
return mFlee;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int
|
|
||||||
CreatureStats::getAlarm() const {
|
|
||||||
return mAlarm;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inline non-const getters
|
|
||||||
|
|
||||||
inline Stat<int> &
|
|
||||||
CreatureStats::getAttribute(int index) {
|
|
||||||
if (index < 0 || index > 7) {
|
|
||||||
throw std::runtime_error("attribute index is out of range");
|
|
||||||
}
|
|
||||||
return mAttributes[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline DynamicStat<int> &
|
|
||||||
CreatureStats::getHealth() {
|
|
||||||
return mDynamic[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline DynamicStat<int> &
|
|
||||||
CreatureStats::getMagicka() {
|
|
||||||
return mDynamic[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline DynamicStat<int> &
|
|
||||||
CreatureStats::getFatigue() {
|
|
||||||
return mDynamic[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline DynamicStat<int> &
|
|
||||||
CreatureStats::getDynamic(int index) {
|
|
||||||
if (index < 0 || index > 2) {
|
|
||||||
throw std::runtime_error("dynamic stat index is out of range");
|
|
||||||
}
|
|
||||||
return mDynamic[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Spells &
|
|
||||||
CreatureStats::getSpells() {
|
|
||||||
return mSpells;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setSpells(const Spells &spells) {
|
|
||||||
mSpells = spells;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ActiveSpells &
|
|
||||||
CreatureStats::getActiveSpells() {
|
|
||||||
return mActiveSpells;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline MagicEffects &
|
|
||||||
CreatureStats::getMagicEffects() {
|
|
||||||
return mMagicEffects;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inline setters
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setAttribute(int index, const Stat<int> &value) {
|
|
||||||
if (index < 0 || index > 7) {
|
|
||||||
throw std::runtime_error("attribute index is out of range");
|
|
||||||
}
|
|
||||||
mAttributes[index] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setHealth(const DynamicStat<int> &value) {
|
|
||||||
mDynamic[0] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setMagicka(const DynamicStat<int> &value) {
|
|
||||||
mDynamic[1] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setFatigue(const DynamicStat<int> &value) {
|
|
||||||
mDynamic[2] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setLevel(int level) {
|
|
||||||
mLevel = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setActiveSpells(const ActiveSpells &active) {
|
|
||||||
mActiveSpells = active;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setMagicEffects(const MagicEffects &effects) {
|
|
||||||
mMagicEffects = effects;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setHello(int value) {
|
|
||||||
mHello = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setFight(int value) {
|
|
||||||
mFight = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setFlee(int value) {
|
|
||||||
mFlee = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
CreatureStats::setAlarm(int value) {
|
|
||||||
mAlarm = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
49
apps/openmw/mwworld/actioneat.cpp
Normal file
49
apps/openmw/mwworld/actioneat.cpp
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
#include "actioneat.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <components/esm/loadskil.hpp>
|
||||||
|
|
||||||
|
#include <components/esm_store/store.hpp>
|
||||||
|
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
#include "../mwmechanics/npcstats.hpp"
|
||||||
|
|
||||||
|
#include "class.hpp"
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
void ActionEat::executeImp (const Ptr& actor)
|
||||||
|
{
|
||||||
|
// remove used item
|
||||||
|
getTarget().getRefData().setCount (getTarget().getRefData().getCount()-1);
|
||||||
|
|
||||||
|
// check for success
|
||||||
|
const MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor);
|
||||||
|
MWMechanics::NpcStats& npcStats = MWWorld::Class::get (actor).getNpcStats (actor);
|
||||||
|
|
||||||
|
float x =
|
||||||
|
(npcStats.getSkill (ESM::Skill::Alchemy).getModified() +
|
||||||
|
0.2 * creatureStats.getAttribute (1).getModified()
|
||||||
|
+ 0.1 * creatureStats.getAttribute (7).getModified())
|
||||||
|
* creatureStats.getFatigueTerm();
|
||||||
|
|
||||||
|
if (x>=100*static_cast<float> (std::rand()) / RAND_MAX)
|
||||||
|
{
|
||||||
|
// apply to actor
|
||||||
|
std::string id = Class::get (getTarget()).getId (getTarget());
|
||||||
|
|
||||||
|
Class::get (actor).apply (actor, id, actor);
|
||||||
|
// we ignore the result here. Skill increases no matter if the ingredient did something or not.
|
||||||
|
|
||||||
|
// increase skill
|
||||||
|
Class::get (actor).skillUsageSucceeded (actor, ESM::Skill::Alchemy, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionEat::ActionEat (const MWWorld::Ptr& object) : Action (false, object) {}
|
||||||
|
}
|
19
apps/openmw/mwworld/actioneat.hpp
Normal file
19
apps/openmw/mwworld/actioneat.hpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#ifndef GAME_MWWORLD_ACTIONEAT_H
|
||||||
|
#define GAME_MWWORLD_ACTIONEAT_H
|
||||||
|
|
||||||
|
#include "action.hpp"
|
||||||
|
#include "ptr.hpp"
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
class ActionEat : public Action
|
||||||
|
{
|
||||||
|
virtual void executeImp (const Ptr& actor);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ActionEat (const MWWorld::Ptr& object);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,8 +1,15 @@
|
||||||
#include "loadgmst.hpp"
|
#include "loadgmst.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "defs.hpp"
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/// \todo Review GMST "fixing". Probably remove completely or at least make it optional. Its definitely not
|
||||||
|
/// working properly in its current state and I doubt it can be fixed without breaking other stuff.
|
||||||
|
|
||||||
// Some handy macros
|
// Some handy macros
|
||||||
#define cI(s,x) { if(id == (s)) return (i == (x)); }
|
#define cI(s,x) { if(id == (s)) return (i == (x)); }
|
||||||
#define cF(s,x) { if(id == (s)) return (f == (x)); }
|
#define cF(s,x) { if(id == (s)) return (f == (x)); }
|
||||||
|
@ -169,4 +176,32 @@ void GameSetting::load(ESMReader &esm)
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GameSetting::getInt() const
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case VT_Float: return static_cast<int> (f);
|
||||||
|
case VT_Int: return i;
|
||||||
|
default: throw std::runtime_error ("GMST " + id + " is not of a numeric type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameSetting::getFloat() const
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case VT_Float: return f;
|
||||||
|
case VT_Int: return i;
|
||||||
|
default: throw std::runtime_error ("GMST " + id + " is not of a numeric type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GameSetting::getString() const
|
||||||
|
{
|
||||||
|
if (type==VT_String)
|
||||||
|
return str;
|
||||||
|
|
||||||
|
throw std::runtime_error ("GMST " + id + " is not a string");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,15 @@ struct GameSetting
|
||||||
bool isDirtyBloodmoon();
|
bool isDirtyBloodmoon();
|
||||||
|
|
||||||
void load(ESMReader &esm);
|
void load(ESMReader &esm);
|
||||||
|
|
||||||
|
int getInt() const;
|
||||||
|
///< Throws an exception if GMST is not of type int or float.
|
||||||
|
|
||||||
|
int getFloat() const;
|
||||||
|
///< Throws an exception if GMST is not of type int or float.
|
||||||
|
|
||||||
|
std::string getString() const;
|
||||||
|
///< Throwns an exception if GMST is not of type string.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,30 @@
|
||||||
#include "loadmgef.hpp"
|
#include "loadmgef.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
const int NumberOfHardcodedFlags = 143;
|
||||||
|
const int HardcodedFlags[NumberOfHardcodedFlags] = {
|
||||||
|
0x11c8, 0x11c0, 0x11c8, 0x11e0, 0x11e0, 0x11e0, 0x11e0, 0x11d0,
|
||||||
|
0x11c0, 0x11c0, 0x11e0, 0x11c0, 0x11184, 0x11184, 0x1f0, 0x1f0,
|
||||||
|
0x1f0, 0x11d2, 0x11f0, 0x11d0, 0x11d0, 0x11d1, 0x1d2, 0x1f0,
|
||||||
|
0x1d0, 0x1d0, 0x1d1, 0x1f0, 0x11d0, 0x11d0, 0x11d0, 0x11d0,
|
||||||
|
0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x11d0, 0x1d0, 0x1d0, 0x11c8,
|
||||||
|
0x31c0, 0x11c0, 0x11c0, 0x11c0, 0x1180, 0x11d8, 0x11d8, 0x11d0,
|
||||||
|
0x11d0, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180, 0x11180,
|
||||||
|
0x11180, 0x11c4, 0x111b8, 0x1040, 0x104c, 0x104c, 0x104c, 0x104c,
|
||||||
|
0x1040, 0x1040, 0x1040, 0x11c0, 0x11c0, 0x1cc, 0x1cc, 0x1cc,
|
||||||
|
0x1cc, 0x1cc, 0x1c2, 0x1c0, 0x1c0, 0x1c0, 0x1c1, 0x11c2,
|
||||||
|
0x11c0, 0x11c0, 0x11c0, 0x11c1, 0x11c0, 0x21192, 0x20190, 0x20190,
|
||||||
|
0x20190, 0x21191, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x11c0,
|
||||||
|
0x11c0, 0x11c0, 0x11c0, 0x11c0, 0x1c0, 0x11190, 0x9048, 0x9048,
|
||||||
|
0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x9048,
|
||||||
|
0x9048, 0x9048, 0x9048, 0x9048, 0x9048, 0x11c0, 0x1180, 0x1180,
|
||||||
|
0x5048, 0x5048, 0x5048, 0x5048, 0x5048, 0x5048, 0x1188, 0x5048,
|
||||||
|
0x5048, 0x5048, 0x5048, 0x5048, 0x1048, 0x104c, 0x1048, 0x40,
|
||||||
|
0x11c8, 0x1048, 0x1048, 0x1048, 0x1048, 0x1048, 0x1048
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace ESM
|
namespace ESM
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -8,6 +33,10 @@ void MagicEffect::load(ESMReader &esm)
|
||||||
esm.getHNT(index, "INDX");
|
esm.getHNT(index, "INDX");
|
||||||
|
|
||||||
esm.getHNT(data, "MEDT", 36);
|
esm.getHNT(data, "MEDT", 36);
|
||||||
|
|
||||||
|
if (index>=0 && index<NumberOfHardcodedFlags)
|
||||||
|
data.flags |= HardcodedFlags[index];
|
||||||
|
|
||||||
icon = esm.getHNOString("ITEX");
|
icon = esm.getHNOString("ITEX");
|
||||||
particle = esm.getHNOString("PTEX");
|
particle = esm.getHNOString("PTEX");
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ struct MagicEffect
|
||||||
{
|
{
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
|
NoDuration = 0x4,
|
||||||
SpellMaking = 0x0200,
|
SpellMaking = 0x0200,
|
||||||
Enchanting = 0x0400,
|
Enchanting = 0x0400,
|
||||||
Negative = 0x0800 // A harmful effect. Will determine whether
|
Negative = 0x0800 // A harmful effect. Will determine whether
|
||||||
|
|
Loading…
Reference in a new issue