1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 20:29:57 +00:00

implemented magic effects from abilities (effects are not applied yet)

This commit is contained in:
Marc Zinnschlag 2010-09-30 15:42:28 +02:00
parent eeca39220b
commit 98405a5716
6 changed files with 221 additions and 2 deletions

View file

@ -182,11 +182,14 @@ set(GAMECLASS_HEADER
source_group(apps\\openmw\\mwclass FILES ${GAMECLASS} ${GAMECLASS_HEADER})
set(GAMEMECHANICS
mwmechanics/mechanicsmanager.cpp)
mwmechanics/mechanicsmanager.cpp
mwmechanics/magiceffects.cpp
)
set(GAMEMECHANICS_HEADER
mwmechanics/mechanicsmanager.hpp
mwmechanics/stat.hpp
mwmechanics/creaturestats.hpp
mwmechanics/magiceffects.hpp
)
source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER})

View file

@ -5,6 +5,7 @@
#include <string>
#include "stat.hpp"
#include "magiceffects.hpp"
namespace MWMechanics
{
@ -14,6 +15,7 @@ namespace MWMechanics
DynamicStat<int> mDynamic[3]; // health, magicka, fatigue
int mLevel;
std::set<std::string> mAbilities;
MagicEffects mMagicEffects;
};
}

View file

@ -0,0 +1,104 @@
#include "magiceffects.hpp"
#include <stdexcept>
#include <components/esm/defs.hpp>
namespace MWMechanics
{
EffectKey::EffectKey() : mId (0), mArg (-1) {}
EffectKey::EffectKey (const ESM::ENAMstruct& effect)
{
mId = effect.effectID;
mArg = -1;
if (effect.skill!=-1)
mArg = effect.skill;
if (effect.attribute!=-1)
{
if (mArg!=-1)
throw std::runtime_error (
"magic effect can't have both a skill and an attribute argument");
mArg = effect.attribute;
}
}
bool operator< (const EffectKey& left, const EffectKey& right)
{
if (left.mId<right.mId)
return true;
if (left.mId>right.mId)
return false;
return left.mArg<right.mArg;
}
EffectParam::EffectParam() : mMagnitude (0) {}
EffectParam& EffectParam::operator+= (const EffectParam& param)
{
mMagnitude += param.mMagnitude;
return *this;
}
EffectParam& EffectParam::operator-= (const EffectParam& param)
{
mMagnitude -= param.mMagnitude;
return *this;
}
void MagicEffects::add (const EffectKey& key, const EffectParam& param)
{
Collection::iterator iter = mCollection.find (key);
if (iter==mCollection.end())
{
mCollection.insert (std::make_pair (key, param));
}
else
{
iter->second += param;
}
}
MagicEffects MagicEffects::diff (const MagicEffects& prev, const MagicEffects& now)
{
MagicEffects result;
// adding/changing
for (Collection::const_iterator iter (now.Begin()); iter!=now.End(); ++iter)
{
Collection::const_iterator other = prev.mCollection.find (iter->first);
if (other==prev.End())
{
// adding
result.add (iter->first, iter->second);
}
else
{
// changing
result.add (iter->first, iter->second - other->second);
}
}
// removing
for (Collection::const_iterator iter (prev.Begin()); iter!=prev.End(); ++iter)
{
Collection::const_iterator other = now.mCollection.find (iter->first);
if (other==prev.End())
{
result.add (iter->first, EffectParam() - iter->second);
}
}
return result;
}
}

View file

@ -0,0 +1,72 @@
#ifndef GAME_MWMECHANICS_MAGICEFFECTS_H
#define GAME_MWMECHANICS_MAGICEFFECTS_H
#include <map>
namespace ESM
{
struct ENAMstruct;
}
namespace MWMechanics
{
struct EffectKey
{
int mId;
int mArg; // skill or ability
EffectKey();
EffectKey (const ESM::ENAMstruct& effect);
};
bool operator< (const EffectKey& left, const EffectKey& right);
struct EffectParam
{
int mMagnitude;
EffectParam();
EffectParam& operator+= (const EffectParam& param);
EffectParam& operator-= (const EffectParam& param);
};
inline EffectParam operator+ (const EffectParam& left, const EffectParam& right)
{
EffectParam param (left);
return param += right;
}
inline EffectParam operator- (const EffectParam& left, const EffectParam& right)
{
EffectParam param (left);
return param -= right;
}
/// \brief Effects currently affecting a NPC or creature
class MagicEffects
{
public:
typedef std::map<EffectKey, EffectParam> Collection;
private:
Collection mCollection;
public:
Collection::const_iterator Begin() const { return mCollection.begin(); }
Collection::const_iterator End() const { return mCollection.end(); }
void add (const EffectKey& key, const EffectParam& param);
static MagicEffects diff (const MagicEffects& prev, const MagicEffects& now);
///< Return changes from \a prev to \a now.
};
}
#endif

View file

@ -23,6 +23,7 @@ namespace MWMechanics
// reset
creatureStats.mLevel = player->npdt52.level;
creatureStats.mAbilities.clear();
creatureStats.mMagicEffects = MagicEffects();
for (int i=0; i<27; ++i)
npcStats.mSkill[i].setBase (player->npdt52.skills[i]);
@ -136,6 +137,9 @@ namespace MWMechanics
}
}
// magic effects
adjustMagicEffects (ptr);
// calculate dynamic stats
int strength = creatureStats.mAttributes[0].getBase();
int intelligence = creatureStats.mAttributes[1].getBase();
@ -166,7 +170,6 @@ namespace MWMechanics
if (creatureStats.mAbilities.find (id)==creatureStats.mAbilities.end())
{
creatureStats.mAbilities.insert (id);
// TODO apply effects
}
break;
@ -181,6 +184,39 @@ namespace MWMechanics
}
}
void MechanicsManager::adjustMagicEffects (MWWorld::Ptr& creature)
{
MWMechanics::CreatureStats& creatureStats =
MWWorld::Class::get (creature).getCreatureStats (creature);
MagicEffects now;
for (std::set<std::string>::const_iterator iter (creatureStats.mAbilities.begin());
iter!=creatureStats.mAbilities.end(); ++iter)
{
const ESM::Spell *spell = mEnvironment.mWorld->getStore().spells.find (*iter);
for (std::vector<ESM::ENAMstruct>::const_iterator iter = spell->effects.list.begin();
iter!=spell->effects.list.end(); ++iter)
{
if (iter->range==0) // self
{
EffectParam param;
param.mMagnitude = iter->magnMax; // TODO calculate magnitude
now.add (EffectKey (*iter), param);
}
}
}
// TODO add effects from other spell types, active spells and equipment
MagicEffects diff = MagicEffects::diff (creatureStats.mMagicEffects, now);
creatureStats.mMagicEffects = now;
// TODO apply diff to other stats
}
MechanicsManager::MechanicsManager (MWWorld::Environment& environment)
: mEnvironment (environment), mUpdatePlayer (true), mClassSelected (false),
mRaceSelected (false)

View file

@ -32,6 +32,8 @@ namespace MWMechanics
void insertSpell (const std::string& id, MWWorld::Ptr& creature);
void adjustMagicEffects (MWWorld::Ptr& creature);
public:
MechanicsManager (MWWorld::Environment& environment);