mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-19 18:09:50 +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
|
||||
containerstore actiontalk actiontake manualref player cellfunctors
|
||||
cells localscripts customdata weather inventorystore ptr actionopen actionread
|
||||
actionequip timestamp actionalchemy cellstore actionapply
|
||||
actionequip timestamp actionalchemy cellstore actionapply actioneat
|
||||
)
|
||||
|
||||
add_openmw_dir (mwclass
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../mwworld/actiontake.hpp"
|
||||
#include "../mwworld/cellstore.hpp"
|
||||
#include "../mwworld/physicssystem.hpp"
|
||||
#include "../mwworld/actioneat.hpp"
|
||||
|
||||
#include "../mwgui/tooltips.hpp"
|
||||
|
||||
|
@ -19,6 +20,14 @@
|
|||
|
||||
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
|
||||
{
|
||||
const std::string model = getModel(ptr);
|
||||
|
@ -84,6 +93,16 @@ namespace MWClass
|
|||
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()
|
||||
{
|
||||
boost::shared_ptr<Class> instance (new Ingredient);
|
||||
|
|
|
@ -12,6 +12,9 @@ namespace MWClass
|
|||
|
||||
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;
|
||||
///< Add reference into a cell for rendering
|
||||
|
||||
|
@ -37,6 +40,10 @@ namespace MWClass
|
|||
virtual int getValue (const MWWorld::Ptr& ptr) const;
|
||||
///< 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();
|
||||
|
||||
virtual std::string getUpSoundId (const MWWorld::Ptr& ptr) const;
|
||||
|
|
|
@ -365,7 +365,7 @@ namespace MWClass
|
|||
|
||||
/// \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
|
||||
|
|
|
@ -5,12 +5,20 @@
|
|||
|
||||
#include <components/esm/loadalch.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 "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "creaturestats.hpp"
|
||||
#include "npcstats.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
void ActiveSpells::update() const
|
||||
|
@ -41,47 +49,102 @@ namespace MWMechanics
|
|||
}
|
||||
|
||||
if (rebuild)
|
||||
rebuildEffects();
|
||||
}
|
||||
|
||||
void ActiveSpells::rebuildEffects() const
|
||||
{
|
||||
MWWorld::TimeStamp now = MWBase::Environment::get().getWorld()->getTimeStamp();
|
||||
|
||||
mEffects = MagicEffects();
|
||||
|
||||
for (TIterator iter (begin()); iter!=end(); ++iter)
|
||||
{
|
||||
mEffects = MagicEffects();
|
||||
std::pair<ESM::EffectList, bool> effects = getEffectList (iter->first);
|
||||
|
||||
for (TIterator iter (begin()); iter!=end(); ++iter)
|
||||
const MWWorld::TimeStamp& start = iter->second.first;
|
||||
float magnitude = iter->second.second;
|
||||
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin());
|
||||
iter!=effects.first.list.end(); ++iter)
|
||||
{
|
||||
const ESM::EffectList& effects = getEffectList (iter->first);
|
||||
|
||||
const MWWorld::TimeStamp& start = iter->second.first;
|
||||
float magnitude = iter->second.second;
|
||||
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin());
|
||||
iter!=effects.list.end(); ++iter)
|
||||
if (iter->duration)
|
||||
{
|
||||
if (iter->duration)
|
||||
{
|
||||
MWWorld::TimeStamp end = start;
|
||||
end += static_cast<double> (iter->duration)*
|
||||
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
|
||||
int duration = iter->duration;
|
||||
|
||||
if (effects.second)
|
||||
duration *= magnitude;
|
||||
|
||||
MWWorld::TimeStamp end = start;
|
||||
end += static_cast<double> (duration)*
|
||||
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
|
||||
|
||||
if (end>now)
|
||||
if (end>now)
|
||||
{
|
||||
EffectParam param;
|
||||
|
||||
if (effects.second)
|
||||
{
|
||||
EffectParam param;
|
||||
param.mMagnitude = static_cast<int> (
|
||||
(iter->magnMax-iter->magnMin+1)*magnitude + iter->magnMin);
|
||||
mEffects.add (*iter, param);
|
||||
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> (
|
||||
(iter->magnMax-iter->magnMin)*magnitude + iter->magnMin);
|
||||
|
||||
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 =
|
||||
MWBase::Environment::get().getWorld()->getStore().spells.search (id))
|
||||
return spell->effects;
|
||||
return std::make_pair (spell->effects, false);
|
||||
|
||||
if (const ESM::Potion *potion =
|
||||
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");
|
||||
}
|
||||
|
@ -90,14 +153,14 @@ namespace MWMechanics
|
|||
: 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;
|
||||
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin());
|
||||
iter!=effects.list.end(); ++iter)
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin());
|
||||
iter!=effects.first.list.end(); ++iter)
|
||||
{
|
||||
if (iter->duration)
|
||||
{
|
||||
|
@ -113,6 +176,22 @@ namespace MWMechanics
|
|||
|
||||
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())
|
||||
mSpells.insert (std::make_pair (id,
|
||||
std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random)));
|
||||
|
@ -155,17 +234,20 @@ namespace MWMechanics
|
|||
|
||||
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;
|
||||
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.list.begin());
|
||||
iter!=effects.list.end(); ++iter)
|
||||
for (std::vector<ESM::ENAMstruct>::const_iterator iter (effects.first.list.begin());
|
||||
iter!=effects.first.list.end(); ++iter)
|
||||
{
|
||||
if (iter->duration>duration)
|
||||
duration = iter->duration;
|
||||
}
|
||||
|
||||
if (effects.second)
|
||||
duration *= iterator->second.second;
|
||||
|
||||
double scaledDuration = duration *
|
||||
MWBase::Environment::get().getWorld()->getTimeScaleFactor()/(60*60);
|
||||
|
||||
|
|
|
@ -15,6 +15,11 @@ namespace ESM
|
|||
struct EffectList;
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
class Ptr;
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
/// \brief Lasting spell effects
|
||||
|
@ -36,14 +41,16 @@ namespace MWMechanics
|
|||
mutable MWWorld::TimeStamp mLastUpdate;
|
||||
|
||||
void update() const;
|
||||
|
||||
void rebuildEffects() const;
|
||||
|
||||
const ESM::EffectList& getEffectList (const std::string& id) const;
|
||||
std::pair<ESM::EffectList, bool> getEffectList (const std::string& id) const;
|
||||
|
||||
public:
|
||||
|
||||
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
|
||||
/// non-instant effects, it is ignored.
|
||||
///
|
||||
|
|
|
@ -1,51 +1,14 @@
|
|||
#include "creaturestats.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <components/esm_store/store.hpp>
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
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
|
||||
{
|
||||
return mAiSequence;
|
||||
|
@ -55,4 +18,189 @@ namespace MWMechanics
|
|||
{
|
||||
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;
|
||||
|
||||
public:
|
||||
CreatureStats();
|
||||
CreatureStats(const CreatureStats &);
|
||||
virtual ~CreatureStats();
|
||||
|
||||
const CreatureStats & operator=(const CreatureStats &);
|
||||
|
||||
const Stat<int> & getAttribute(int index) const;
|
||||
|
||||
|
@ -106,185 +101,10 @@ namespace MWMechanics
|
|||
const AiSequence& getAiSequence() const;
|
||||
|
||||
AiSequence& getAiSequence();
|
||||
};
|
||||
|
||||
// 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;
|
||||
}
|
||||
float getFatigueTerm() const;
|
||||
///< Return effective fatigue
|
||||
};
|
||||
}
|
||||
|
||||
#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 <stdexcept>
|
||||
|
||||
#include "defs.hpp"
|
||||
|
||||
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
|
||||
#define cI(s,x) { if(id == (s)) return (i == (x)); }
|
||||
#define cF(s,x) { if(id == (s)) return (f == (x)); }
|
||||
|
@ -169,4 +176,32 @@ void GameSetting::load(ESMReader &esm)
|
|||
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();
|
||||
|
||||
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
|
||||
|
|
|
@ -1,5 +1,30 @@
|
|||
#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
|
||||
{
|
||||
|
||||
|
@ -8,6 +33,10 @@ void MagicEffect::load(ESMReader &esm)
|
|||
esm.getHNT(index, "INDX");
|
||||
|
||||
esm.getHNT(data, "MEDT", 36);
|
||||
|
||||
if (index>=0 && index<NumberOfHardcodedFlags)
|
||||
data.flags |= HardcodedFlags[index];
|
||||
|
||||
icon = esm.getHNOString("ITEX");
|
||||
particle = esm.getHNOString("PTEX");
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ struct MagicEffect
|
|||
{
|
||||
enum Flags
|
||||
{
|
||||
NoDuration = 0x4,
|
||||
SpellMaking = 0x0200,
|
||||
Enchanting = 0x0400,
|
||||
Negative = 0x0800 // A harmful effect. Will determine whether
|
||||
|
|
Loading…
Reference in a new issue