Address review feedback.

This commit is contained in:
cc9cii 2015-06-25 13:32:22 +10:00
parent e5e4a04f8b
commit 7af43a1155
17 changed files with 236 additions and 285 deletions

View File

@ -11,9 +11,9 @@
#include <components/esm/loadglob.hpp> #include <components/esm/loadglob.hpp>
#include <components/esm/cellref.hpp> #include <components/esm/cellref.hpp>
#include <components/gameplay/autocalc.hpp> #include <components/autocalc/autocalc.hpp>
#include <components/gameplay/autocalcspell.hpp> #include <components/autocalc/autocalcspell.hpp>
#include <components/gameplay/store.hpp> #include <components/autocalc/store.hpp>
#include "idtable.hpp" #include "idtable.hpp"
#include "idtree.hpp" #include "idtree.hpp"
@ -27,15 +27,21 @@
namespace namespace
{ {
class SpellStore : public GamePlay::CommonStore <ESM::Spell> class CSStore : public AutoCalc::StoreCommon
{ {
const CSMWorld::IdCollection<ESM::GameSetting>& mGmstTable;
const CSMWorld::IdCollection<ESM::Skill>& mSkillTable;
const CSMWorld::IdCollection<ESM::MagicEffect>& mMagicEffectTable;
const CSMWorld::NestedIdCollection<ESM::Spell>& mSpells; const CSMWorld::NestedIdCollection<ESM::Spell>& mSpells;
std::vector<ESM::Spell *> mLocal; std::vector<ESM::Spell *> mLocal;
public: public:
SpellStore(const CSMWorld::NestedIdCollection<ESM::Spell>& spells) CSStore(const CSMWorld::IdCollection<ESM::GameSetting>& gmst,
: mSpells(spells) const CSMWorld::IdCollection<ESM::Skill>& skills,
const CSMWorld::IdCollection<ESM::MagicEffect>& magicEffects,
const CSMWorld::NestedIdCollection<ESM::Spell>& spells)
: mGmstTable(gmst), mSkillTable(skills), mMagicEffectTable(magicEffects), mSpells(spells)
{ {
// prepare data in a format used by OpenMW store // prepare data in a format used by OpenMW store
for (int index = 0; index < mSpells.getSize(); ++index) for (int index = 0; index < mSpells.getSize(); ++index)
@ -44,53 +50,6 @@ namespace
mLocal.push_back(spell); mLocal.push_back(spell);
} }
} }
~SpellStore() {}
typedef GamePlay::SharedIterator<ESM::Spell> iterator;
virtual iterator begin() const
{
return mLocal.begin();
}
virtual iterator end() const
{
return mLocal.end();
}
virtual const ESM::Spell *find(const std::string &id) const
{
return &mSpells.getRecord(id).get();
}
virtual size_t getSize() const
{
return mSpells.getSize();
}
private:
// not used in OpenCS
virtual void load(ESM::ESMReader &esm, const std::string &id)
{
}
};
class CSStore : public GamePlay::StoreWrap
{
const CSMWorld::IdCollection<ESM::GameSetting>& mGmstTable;
const CSMWorld::IdCollection<ESM::Skill>& mSkillTable;
const CSMWorld::IdCollection<ESM::MagicEffect>& mMagicEffectTable;
const SpellStore mSpellStore;
public:
CSStore(const CSMWorld::IdCollection<ESM::GameSetting>& gmst,
const CSMWorld::IdCollection<ESM::Skill>& skills,
const CSMWorld::IdCollection<ESM::MagicEffect>& magicEffects,
const CSMWorld::NestedIdCollection<ESM::Spell>& spells)
: mGmstTable(gmst), mSkillTable(skills), mMagicEffectTable(magicEffects), mSpellStore(spells)
{ }
~CSStore() {} ~CSStore() {}
virtual int findGmstInt(const std::string& name) const virtual int findGmstInt(const std::string& name) const
@ -115,18 +74,18 @@ namespace
return &mMagicEffectTable.getRecord(ESM::MagicEffect::indexToId((short)id)).get(); return &mMagicEffectTable.getRecord(ESM::MagicEffect::indexToId((short)id)).get();
} }
virtual const GamePlay::CommonStore<ESM::Spell>& getSpells() const virtual const std::vector<ESM::Spell*>& getSpells() const
{ {
return mSpellStore; return mLocal;
} }
}; };
unsigned short autoCalculateMana(GamePlay::StatsBase& stats) unsigned short autoCalculateMana(AutoCalc::StatsBase& stats)
{ {
return stats.getBaseAttribute(ESM::Attribute::Intelligence) * 2; return stats.getBaseAttribute(ESM::Attribute::Intelligence) * 2;
} }
unsigned short autoCalculateFatigue(GamePlay::StatsBase& stats) unsigned short autoCalculateFatigue(AutoCalc::StatsBase& stats)
{ {
return stats.getBaseAttribute(ESM::Attribute::Strength) return stats.getBaseAttribute(ESM::Attribute::Strength)
+ stats.getBaseAttribute(ESM::Attribute::Willpower) + stats.getBaseAttribute(ESM::Attribute::Willpower)
@ -1579,15 +1538,15 @@ CSMWorld::NpcStats* CSMWorld::Data::npcAutoCalculate(const ESM::NPC& npc) const
if (autoCalc) if (autoCalc)
{ {
GamePlay::autoCalcAttributesImpl (&npc, race, class_, level, *stats, &store); AutoCalc::autoCalcAttributesImpl (&npc, race, class_, level, *stats, &store);
stats->setHealth(autoCalculateHealth(level, class_, *stats)); stats->setHealth(autoCalculateHealth(level, class_, *stats));
stats->setMana(autoCalculateMana(*stats)); stats->setMana(autoCalculateMana(*stats));
stats->setFatigue(autoCalculateFatigue(*stats)); stats->setFatigue(autoCalculateFatigue(*stats));
GamePlay::autoCalcSkillsImpl(&npc, race, class_, level, *stats, &store); AutoCalc::autoCalcSkillsImpl(&npc, race, class_, level, *stats, &store);
GamePlay::autoCalculateSpells(race, *stats, &store); AutoCalc::autoCalculateSpells(race, *stats, &store);
} }
else else
{ {
@ -1645,7 +1604,7 @@ CSMWorld::NpcStats* CSMWorld::Data::npcAutoCalculate(const ESM::NPC& npc) const
int school; int school;
float skillTerm; float skillTerm;
GamePlay::calcWeakestSchool(spell, skills, school, skillTerm, &store); AutoCalc::calcWeakestSchool(spell, skills, school, skillTerm, &store);
float chance = calcAutoCastChance(spell, skills, attributes, school, &store); float chance = calcAutoCastChance(spell, skills, attributes, school, &store);
stats->addCostAndChance((*it).mName, cost, (int)ceil(chance)); // percent stats->addCostAndChance((*it).mName, cost, (int)ceil(chance)); // percent

View File

@ -7,7 +7,7 @@
#include <components/esm/attr.hpp> #include <components/esm/attr.hpp>
#include <components/esm/loadskil.hpp> #include <components/esm/loadskil.hpp>
#include <components/gameplay/autocalc.hpp> #include <components/autocalc/autocalc.hpp>
namespace CSMWorld namespace CSMWorld
{ {
@ -20,7 +20,7 @@ namespace CSMWorld
int mChance; int mChance;
}; };
class NpcStats : public GamePlay::StatsBase class NpcStats : public AutoCalc::StatsBase
{ {
int mAttr[ESM::Attribute::Length]; int mAttr[ESM::Attribute::Length];

View File

@ -11,9 +11,9 @@
#include <components/esm/loadnpc.hpp> #include <components/esm/loadnpc.hpp>
#include <components/esm/npcstate.hpp> #include <components/esm/npcstate.hpp>
#include <components/gameplay/autocalc.hpp> #include <components/autocalc/autocalc.hpp>
#include <components/gameplay/autocalcspell.hpp> #include <components/autocalc/autocalcspell.hpp>
#include <components/gameplay/store.hpp> #include <components/autocalc/store.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -62,28 +62,26 @@ namespace
return new NpcCustomData (*this); return new NpcCustomData (*this);
} }
class Stats : public GamePlay::StatsBase class Stats : public AutoCalc::StatsBase
{ {
MWMechanics::CreatureStats& mCreatureStats;
MWMechanics::NpcStats& mNpcStats; MWMechanics::NpcStats& mNpcStats;
public: public:
Stats(MWMechanics::CreatureStats& creatureStats, MWMechanics::NpcStats& npcStats) Stats(MWMechanics::NpcStats& npcStats) : mNpcStats(npcStats) {}
: mCreatureStats(creatureStats), mNpcStats(npcStats) {}
virtual unsigned char getBaseAttribute(int index) const { return mCreatureStats.getAttribute(index).getBase(); } virtual unsigned char getBaseAttribute(int index) const { return mNpcStats.getAttribute(index).getBase(); }
virtual void setAttribute(int index, unsigned char value) { mCreatureStats.setAttribute(index, value); } virtual void setAttribute(int index, unsigned char value) { mNpcStats.setAttribute(index, value); }
virtual void addSpells(std::string id) { mCreatureStats.getSpells().add(id); } virtual void addSpells(std::string id) { mNpcStats.getSpells().add(id); }
virtual unsigned char getBaseSkill(int index) const { return mNpcStats.getSkill(index).getBase(); } virtual unsigned char getBaseSkill(int index) const { return mNpcStats.getSkill(index).getBase(); }
virtual void setBaseSkill(int index, unsigned char value) { mNpcStats.getSkill(index).setBase(value); } virtual void setBaseSkill(int index, unsigned char value) { mNpcStats.getSkill(index).setBase(value); }
}; };
void autoCalculateAttributes (const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats) void autoCalculateAttributes (const ESM::NPC* npc, MWMechanics::NpcStats& npcStats)
{ {
const ESM::Race *race = const ESM::Race *race =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc->mRace); MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc->mRace);
@ -91,16 +89,15 @@ namespace
const ESM::Class *class_ = const ESM::Class *class_ =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(npc->mClass); MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().find(npc->mClass);
int level = creatureStats.getLevel(); int level = npcStats.getLevel();
MWMechanics::NpcStats dummy; // npc stats are needed for skills, which is not calculated here Stats stats(npcStats);
Stats stats(creatureStats, dummy);
MWWorld::MWStore store; MWWorld::MWStore store;
GamePlay::autoCalcAttributesImpl (npc, race, class_, level, stats, &store); AutoCalc::autoCalcAttributesImpl (npc, race, class_, level, stats, &store);
creatureStats.setHealth(GamePlay::autoCalculateHealth(level, class_, stats)); npcStats.setHealth(AutoCalc::autoCalculateHealth(level, class_, stats));
} }
void autoCalculateSkills(const ESM::NPC* npc, MWMechanics::NpcStats& npcStats, const MWWorld::Ptr& ptr) void autoCalculateSkills(const ESM::NPC* npc, MWMechanics::NpcStats& npcStats, const MWWorld::Ptr& ptr)
@ -112,13 +109,13 @@ namespace
const ESM::Race *race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc->mRace); const ESM::Race *race = MWBase::Environment::get().getWorld()->getStore().get<ESM::Race>().find(npc->mRace);
Stats stats(npcStats, npcStats); Stats stats(npcStats);
MWWorld::MWStore store; MWWorld::MWStore store;
GamePlay::autoCalcSkillsImpl(npc, race, class_, level, stats, &store); AutoCalc::autoCalcSkillsImpl(npc, race, class_, level, stats, &store);
GamePlay::autoCalculateSpells(race, stats, &store); AutoCalc::autoCalculateSpells(race, stats, &store);
} }
} }

View File

@ -4,8 +4,6 @@
#include <MyGUI_ImageBox.h> #include <MyGUI_ImageBox.h>
#include <MyGUI_EditBox.h> #include <MyGUI_EditBox.h>
#include <components/gameplay/store.hpp>
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -142,7 +140,7 @@ namespace MWGui
if(world->getStore().get<ESM::Class>().isDynamic(cls->mId)) if(world->getStore().get<ESM::Class>().isDynamic(cls->mId))
{ {
// Choosing Stealth specialization and Speed/Agility as attributes, if possible. Otherwise fall back to first class found. // Choosing Stealth specialization and Speed/Agility as attributes, if possible. Otherwise fall back to first class found.
GamePlay::SharedIterator<ESM::Class> it = world->getStore().get<ESM::Class>().begin(); MWWorld::SharedIterator<ESM::Class> it = world->getStore().get<ESM::Class>().begin();
for(; it != world->getStore().get<ESM::Class>().end(); ++it) for(; it != world->getStore().get<ESM::Class>().end(); ++it)
{ {
if(it->mData.mIsPlayable && it->mData.mSpecialization == 2 && it->mData.mAttribute[0] == 4 && it->mData.mAttribute[1] == 3) if(it->mData.mIsPlayable && it->mData.mSpecialization == 2 && it->mData.mAttribute[0] == 4 && it->mData.mAttribute[1] == 3)

View File

@ -6,7 +6,7 @@
#include <components/esm/stolenitems.hpp> #include <components/esm/stolenitems.hpp>
#include <components/gameplay/autocalcspell.hpp> #include <components/autocalc/autocalcspell.hpp>
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "../mwworld/inventorystore.hpp" #include "../mwworld/inventorystore.hpp"
@ -256,10 +256,10 @@ namespace MWMechanics
static const float fAutoPCSpellChance = esmStore.get<ESM::GameSetting>().find("fAutoPCSpellChance")->getFloat(); static const float fAutoPCSpellChance = esmStore.get<ESM::GameSetting>().find("fAutoPCSpellChance")->getFloat();
MWWorld::MWStore store; MWWorld::MWStore store;
if (GamePlay::calcAutoCastChance(spell, skills, attributes, -1, &store) < fAutoPCSpellChance) if (AutoCalc::calcAutoCastChance(spell, skills, attributes, -1, &store) < fAutoPCSpellChance)
continue; continue;
if (!GamePlay::attrSkillCheck(spell, skills, attributes, &store)) if (!AutoCalc::attrSkillCheck(spell, skills, attributes, &store))
continue; continue;
selectedSpells.push_back(spell->mId); selectedSpells.push_back(spell->mId);

View File

@ -66,7 +66,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
esm.getRecHeader(); esm.getRecHeader();
// Look up the record type. // Look up the record type.
std::map<int, GamePlay::StoreBase *>::iterator it = mStores.find(n.val); std::map<int, StoreBase *>::iterator it = mStores.find(n.val);
if (it == mStores.end()) { if (it == mStores.end()) {
if (n.val == ESM::REC_INFO) { if (n.val == ESM::REC_INFO) {
@ -130,7 +130,7 @@ void ESMStore::load(ESM::ESMReader &esm, Loading::Listener* listener)
void ESMStore::setUp() void ESMStore::setUp()
{ {
std::map<int, GamePlay::StoreBase *>::iterator it = mStores.begin(); std::map<int, StoreBase *>::iterator it = mStores.begin();
for (; it != mStores.end(); ++it) { for (; it != mStores.end(); ++it) {
it->second->setUp(); it->second->setUp();
} }

View File

@ -67,7 +67,7 @@ namespace MWWorld
// Lookup of all IDs. Makes looking up references faster. Just // Lookup of all IDs. Makes looking up references faster. Just
// maps the id name to the record type. // maps the id name to the record type.
std::map<std::string, int> mIds; std::map<std::string, int> mIds;
std::map<int, GamePlay::StoreBase *> mStores; std::map<int, StoreBase *> mStores;
ESM::NPC mPlayerTemplate; ESM::NPC mPlayerTemplate;
@ -75,7 +75,7 @@ namespace MWWorld
public: public:
/// \todo replace with SharedIterator<StoreBase> /// \todo replace with SharedIterator<StoreBase>
typedef std::map<int, GamePlay::StoreBase *>::const_iterator iterator; typedef std::map<int, StoreBase *>::const_iterator iterator;
iterator begin() const { iterator begin() const {
return mStores.begin(); return mStores.begin();
@ -144,7 +144,7 @@ namespace MWWorld
void clearDynamic () void clearDynamic ()
{ {
for (std::map<int, GamePlay::StoreBase *>::iterator it = mStores.begin(); it != mStores.end(); ++it) for (std::map<int, StoreBase *>::iterator it = mStores.begin(); it != mStores.end(); ++it)
it->second->clearDynamic(); it->second->clearDynamic();
mNpcs.insert(mPlayerTemplate); mNpcs.insert(mPlayerTemplate);

View File

@ -29,8 +29,8 @@ namespace MWWorld
return MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(id); return MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(id);
} }
const GamePlay::CommonStore<ESM::Spell>& MWStore::getSpells() const const std::vector<ESM::Spell*>& MWStore::getSpells() const
{ {
return MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>(); return MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().getShared();
} }
} }

View File

@ -3,13 +3,13 @@
#include <string> #include <string>
#include <components/gameplay/store.hpp> #include <components/autocalc/store.hpp>
#include "store.hpp" #include "store.hpp"
namespace MWWorld namespace MWWorld
{ {
class MWStore : public GamePlay::StoreWrap class MWStore : public AutoCalc::StoreCommon
{ {
const MWWorld::Store<ESM::GameSetting>& mGmst; const MWWorld::Store<ESM::GameSetting>& mGmst;
const MWWorld::Store<ESM::Spell> &mSpells; const MWWorld::Store<ESM::Spell> &mSpells;
@ -27,7 +27,7 @@ namespace MWWorld
virtual const ESM::MagicEffect* findMagicEffect(int id) const; virtual const ESM::MagicEffect* findMagicEffect(int id) const;
virtual const GamePlay::CommonStore<ESM::Spell>& getSpells() const; virtual const std::vector<ESM::Spell*>& getSpells() const;
}; };
} }

View File

@ -10,7 +10,6 @@
#include <openengine/misc/rng.hpp> #include <openengine/misc/rng.hpp>
#include <components/esm/esmwriter.hpp> #include <components/esm/esmwriter.hpp>
#include <components/gameplay/store.hpp>
#include <components/loadinglistener/loadinglistener.hpp> #include <components/loadinglistener/loadinglistener.hpp>
@ -18,10 +17,89 @@
namespace MWWorld namespace MWWorld
{ {
struct StoreBase
{
virtual ~StoreBase() {}
virtual void setUp() {}
virtual void listIdentifier(std::vector<std::string> &list) const {}
virtual size_t getSize() const = 0;
virtual int getDynamicSize() const { return 0; }
virtual void load(ESM::ESMReader &esm, const std::string &id) = 0;
virtual bool eraseStatic(const std::string &id) {return false;}
virtual void clearDynamic() {}
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const {}
virtual void read (ESM::ESMReader& reader, const std::string& id) {}
///< Read into dynamic storage
};
template <class T>
class SharedIterator
{
typedef typename std::vector<T *>::const_iterator Iter;
Iter mIter;
public:
SharedIterator() {}
SharedIterator(const SharedIterator &orig)
: mIter(orig.mIter)
{}
SharedIterator(const Iter &iter)
: mIter(iter)
{}
SharedIterator &operator++() {
++mIter;
return *this;
}
SharedIterator operator++(int) {
SharedIterator iter = *this;
++mIter;
return iter;
}
SharedIterator &operator--() {
--mIter;
return *this;
}
SharedIterator operator--(int) {
SharedIterator iter = *this;
--mIter;
return iter;
}
bool operator==(const SharedIterator &x) const {
return mIter == x.mIter;
}
bool operator!=(const SharedIterator &x) const {
return !(*this == x);
}
const T &operator*() const {
return **mIter;
}
const T *operator->() const {
return &(**mIter);
}
};
class ESMStore; class ESMStore;
template <class T> template <class T>
class Store : public GamePlay::CommonStore<T> class Store : public StoreBase
{ {
std::map<std::string, T> mStatic; std::map<std::string, T> mStatic;
std::vector<T *> mShared; // Preserves the record order as it came from the content files (this std::vector<T *> mShared; // Preserves the record order as it came from the content files (this
@ -59,7 +137,7 @@ namespace MWWorld
: mStatic(orig.mData) : mStatic(orig.mData)
{} {}
typedef GamePlay::SharedIterator<T> iterator; typedef SharedIterator<T> iterator;
// setUp needs to be called again after // setUp needs to be called again after
virtual void clearDynamic() virtual void clearDynamic()
@ -156,6 +234,10 @@ namespace MWWorld
return mShared.size(); return mShared.size();
} }
const std::vector<T *>& getShared() const {
return mShared;
}
int getDynamicSize() const int getDynamicSize() const
{ {
return static_cast<int> (mDynamic.size()); // truncated from unsigned __int64 if _MSC_VER && _WIN64 return static_cast<int> (mDynamic.size()); // truncated from unsigned __int64 if _MSC_VER && _WIN64
@ -302,7 +384,7 @@ namespace MWWorld
} }
template <> template <>
class Store<ESM::LandTexture> : public GamePlay::StoreBase class Store<ESM::LandTexture> : public StoreBase
{ {
// For multiple ESM/ESP files we need one list per file. // For multiple ESM/ESP files we need one list per file.
typedef std::vector<ESM::LandTexture> LandTextureList; typedef std::vector<ESM::LandTexture> LandTextureList;
@ -379,7 +461,7 @@ namespace MWWorld
}; };
template <> template <>
class Store<ESM::Land> : public GamePlay::StoreBase class Store<ESM::Land> : public StoreBase
{ {
std::vector<ESM::Land *> mStatic; std::vector<ESM::Land *> mStatic;
@ -394,7 +476,7 @@ namespace MWWorld
}; };
public: public:
typedef GamePlay::SharedIterator<ESM::Land> iterator; typedef SharedIterator<ESM::Land> iterator;
virtual ~Store<ESM::Land>() virtual ~Store<ESM::Land>()
{ {
@ -468,7 +550,7 @@ namespace MWWorld
}; };
template <> template <>
class Store<ESM::Cell> : public GamePlay::StoreBase class Store<ESM::Cell> : public StoreBase
{ {
struct DynamicExtCmp struct DynamicExtCmp
{ {
@ -508,7 +590,7 @@ namespace MWWorld
void handleMovedCellRefs(ESM::ESMReader& esm, ESM::Cell* cell); void handleMovedCellRefs(ESM::ESMReader& esm, ESM::Cell* cell);
public: public:
typedef GamePlay::SharedIterator<ESM::Cell> iterator; typedef SharedIterator<ESM::Cell> iterator;
const ESM::Cell *search(const std::string &id) const { const ESM::Cell *search(const std::string &id) const {
ESM::Cell cell; ESM::Cell cell;
@ -756,7 +838,7 @@ namespace MWWorld
}; };
template <> template <>
class Store<ESM::Pathgrid> : public GamePlay::StoreBase class Store<ESM::Pathgrid> : public StoreBase
{ {
private: private:
typedef std::map<std::string, ESM::Pathgrid> Interior; typedef std::map<std::string, ESM::Pathgrid> Interior;

View File

@ -119,7 +119,7 @@ add_component_dir (fontloader
fontloader fontloader
) )
add_component_dir (gameplay add_component_dir (autocalc
autocalc autocalcspell autocalc autocalcspell
) )

View File

@ -37,10 +37,10 @@ namespace
} }
} }
namespace GamePlay namespace AutoCalc
{ {
void autoCalcAttributesImpl (const ESM::NPC* npc, void autoCalcAttributesImpl (const ESM::NPC* npc,
const ESM::Race *race, const ESM::Class *class_, int level, StatsBase& stats, StoreWrap *store) const ESM::Race *race, const ESM::Class *class_, int level, StatsBase& stats, StoreCommon *store)
{ {
// race bonus // race bonus
bool male = (npc->mFlags & ESM::NPC::Female) == 0; bool male = (npc->mFlags & ESM::NPC::Female) == 0;
@ -106,7 +106,7 @@ namespace GamePlay
* and by adding class, race, specialization bonus. * and by adding class, race, specialization bonus.
*/ */
void autoCalcSkillsImpl (const ESM::NPC* npc, void autoCalcSkillsImpl (const ESM::NPC* npc,
const ESM::Race *race, const ESM::Class *class_, int level, StatsBase& stats, StoreWrap *store) const ESM::Race *race, const ESM::Class *class_, int level, StatsBase& stats, StoreCommon *store)
{ {
for (int i = 0; i < 2; ++i) for (int i = 0; i < 2; ++i)
{ {
@ -188,7 +188,7 @@ namespace GamePlay
return static_cast<unsigned short>(floor(0.5f * (strength + endurance)) + multiplier * (level-1)); return static_cast<unsigned short>(floor(0.5f * (strength + endurance)) + multiplier * (level-1));
} }
void autoCalculateSpells(const ESM::Race *race, StatsBase& stats, StoreWrap *store) void autoCalculateSpells(const ESM::Race *race, StatsBase& stats, StoreCommon *store)
{ {
int skills[ESM::Skill::Length]; int skills[ESM::Skill::Length];
for (int i=0; i<ESM::Skill::Length; ++i) for (int i=0; i<ESM::Skill::Length; ++i)

View File

@ -1,5 +1,5 @@
#ifndef COMPONENTS_GAMEPLAY_AUTOCALC_H #ifndef COMPONENTS_AUTOCALC_AUTOCALC_H
#define COMPONENTS_GAMEPLAY_AUTOCALC_H #define COMPONENTS_AUTOCALC_AUTOCALC_H
#include <string> #include <string>
@ -12,7 +12,7 @@ namespace ESM
struct Class; struct Class;
} }
namespace GamePlay namespace AutoCalc
{ {
// wrapper class for sharing the autocalc code between OpenMW and OpenCS // wrapper class for sharing the autocalc code between OpenMW and OpenCS
class StatsBase class StatsBase
@ -35,13 +35,13 @@ namespace GamePlay
}; };
void autoCalcAttributesImpl (const ESM::NPC* npc, void autoCalcAttributesImpl (const ESM::NPC* npc,
const ESM::Race *race, const ESM::Class *class_, int level, StatsBase& stats, StoreWrap *store); const ESM::Race *race, const ESM::Class *class_, int level, StatsBase& stats, StoreCommon *store);
void autoCalcSkillsImpl (const ESM::NPC* npc, void autoCalcSkillsImpl (const ESM::NPC* npc,
const ESM::Race *race, const ESM::Class *class_, int level, StatsBase& stats, StoreWrap *store); const ESM::Race *race, const ESM::Class *class_, int level, StatsBase& stats, StoreCommon *store);
unsigned short autoCalculateHealth(int level, const ESM::Class *class_, StatsBase& stats); unsigned short autoCalculateHealth(int level, const ESM::Class *class_, StatsBase& stats);
void autoCalculateSpells(const ESM::Race *race, StatsBase& stats, StoreWrap *store); void autoCalculateSpells(const ESM::Race *race, StatsBase& stats, StoreCommon *store);
} }
#endif // COMPONENTS_GAMEPLAY_AUTOCALC_H #endif // COMPONENTS_AUTOCALC_AUTOCALC_H

View File

@ -14,7 +14,7 @@
#include "autocalc.hpp" #include "autocalc.hpp"
// Most of the code in this file was moved from apps/openmw/mwmechanics/autocalcspell.cpp // Most of the code in this file was moved from apps/openmw/mwmechanics/autocalcspell.cpp
namespace GamePlay namespace AutoCalc
{ {
struct SchoolCaps struct SchoolCaps
@ -27,7 +27,7 @@ namespace GamePlay
}; };
std::vector<std::string> autoCalcNpcSpells(const int *actorSkills, std::vector<std::string> autoCalcNpcSpells(const int *actorSkills,
const int *actorAttributes, const ESM::Race* race, StoreWrap *store) const int *actorAttributes, const ESM::Race* race, StoreCommon *store)
{ {
static const float fNPCbaseMagickaMult = store->findGmstFloat("fNPCbaseMagickaMult"); static const float fNPCbaseMagickaMult = store->findGmstFloat("fNPCbaseMagickaMult");
float baseMagicka = fNPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence]; float baseMagicka = fNPCbaseMagickaMult * actorAttributes[ESM::Attribute::Intelligence];
@ -61,13 +61,13 @@ namespace GamePlay
std::vector<std::string> selectedSpells; std::vector<std::string> selectedSpells;
const CommonStore<ESM::Spell> &spells = store->getSpells(); const std::vector<ESM::Spell*>& spells = store->getSpells();
// Note: the algorithm heavily depends on the traversal order of the spells. For vanilla-compatible results the // Note: the algorithm heavily depends on the traversal order of the spells. For vanilla-compatible results the
// Store must preserve the record ordering as it was in the content files. // Store must preserve the record ordering as it was in the content files.
for (CommonStore<ESM::Spell>::iterator iter = spells.begin(); iter != spells.end(); ++iter) for (std::vector<ESM::Spell*>::const_iterator iter = spells.begin(); iter != spells.end(); ++iter)
{ {
const ESM::Spell* spell = &*iter; ESM::Spell* spell = *iter;
if (spell->mData.mType != ESM::Spell::ST_Spell) if (spell->mData.mType != ESM::Spell::ST_Spell)
continue; continue;
@ -107,7 +107,17 @@ namespace GamePlay
cap.mMinCost = INT_MAX; cap.mMinCost = INT_MAX;
for (std::vector<std::string>::iterator weakIt = selectedSpells.begin(); weakIt != selectedSpells.end(); ++weakIt) for (std::vector<std::string>::iterator weakIt = selectedSpells.begin(); weakIt != selectedSpells.end(); ++weakIt)
{ {
const ESM::Spell* testSpell = spells.find(*weakIt); std::vector<ESM::Spell*>::const_iterator it = spells.begin();
for (; it != spells.end(); ++it)
{
if ((*it)->mId == *weakIt)
break;
}
if (it == spells.end())
continue;
const ESM::Spell* testSpell = *it;
//int testSchool; //int testSchool;
//float dummySkillTerm; //float dummySkillTerm;
@ -146,7 +156,7 @@ namespace GamePlay
} }
bool attrSkillCheck (const ESM::Spell* spell, bool attrSkillCheck (const ESM::Spell* spell,
const int* actorSkills, const int* actorAttributes, StoreWrap *store) const int* actorSkills, const int* actorAttributes, StoreCommon *store)
{ {
const std::vector<ESM::ENAMstruct>& effects = spell->mEffects.mList; const std::vector<ESM::ENAMstruct>& effects = spell->mEffects.mList;
for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt) for (std::vector<ESM::ENAMstruct>::const_iterator effectIt = effects.begin(); effectIt != effects.end(); ++effectIt)
@ -186,7 +196,7 @@ namespace GamePlay
} }
void calcWeakestSchool (const ESM::Spell* spell, void calcWeakestSchool (const ESM::Spell* spell,
const int* actorSkills, int& effectiveSchool, float& skillTerm, StoreWrap *store) const int* actorSkills, int& effectiveSchool, float& skillTerm, StoreCommon *store)
{ {
float minChance = FLT_MAX; float minChance = FLT_MAX;
@ -220,7 +230,7 @@ namespace GamePlay
} }
float calcAutoCastChance(const ESM::Spell *spell, float calcAutoCastChance(const ESM::Spell *spell,
const int *actorSkills, const int *actorAttributes, int effectiveSchool, StoreWrap *store) const int *actorSkills, const int *actorAttributes, int effectiveSchool, StoreCommon *store)
{ {
if (spell->mData.mType != ESM::Spell::ST_Spell) if (spell->mData.mType != ESM::Spell::ST_Spell)
return 100.f; return 100.f;

View File

@ -1,5 +1,5 @@
#ifndef COMPONENTS_GAMEPLAY_AUTOCALCSPELL_H #ifndef COMPONENTS_AUTOCALC_AUTOCALCSPELL_H
#define COMPONENTS_GAMEPLAY_AUTOCALCSPELL_H #define COMPONENTS_AUTOCALC_AUTOCALCSPELL_H
#include <vector> #include <vector>
@ -11,28 +11,29 @@ namespace ESM
struct Race; struct Race;
} }
namespace GamePlay namespace AutoCalc
{ {
class StoreWrap; class StoreCommon;
/// Contains algorithm for calculating an NPC's spells based on stats /// Contains algorithm for calculating an NPC's spells based on stats
std::vector<std::string> autoCalcNpcSpells(const int* actorSkills, std::vector<std::string> autoCalcNpcSpells(const int* actorSkills,
const int* actorAttributes, const ESM::Race* race, StoreWrap *store); const int* actorAttributes, const ESM::Race* race, StoreCommon *store);
// Helpers // Helpers
bool attrSkillCheck (const ESM::Spell* spell, const int* actorSkills, const int* actorAttributes, StoreWrap *store); bool attrSkillCheck (const ESM::Spell* spell,
const int* actorSkills, const int* actorAttributes, StoreCommon *store);
ESM::Skill::SkillEnum mapSchoolToSkill(int school); ESM::Skill::SkillEnum mapSchoolToSkill(int school);
void calcWeakestSchool(const ESM::Spell* spell, void calcWeakestSchool(const ESM::Spell* spell,
const int* actorSkills, int& effectiveSchool, float& skillTerm, StoreWrap *store); const int* actorSkills, int& effectiveSchool, float& skillTerm, StoreCommon *store);
float calcAutoCastChance(const ESM::Spell* spell, float calcAutoCastChance(const ESM::Spell* spell,
const int* actorSkills, const int* actorAttributes, int effectiveSchool, StoreWrap *store); const int* actorSkills, const int* actorAttributes, int effectiveSchool, StoreCommon *store);
} }
#endif #endif // COMPONENTS_AUTOCALC_AUTOCALCSPELL_H

View File

@ -0,0 +1,42 @@
#ifndef COMPONENTS_AUTOCALC_STORE_H
#define COMPONENTS_AUTOCALC_STORE_H
#include <vector>
#include <string>
namespace Loading
{
class Listener;
}
namespace ESM
{
class ESMWriter;
class ESMReader;
struct Spell;
struct Skill;
struct MagicEffect;
}
namespace AutoCalc
{
// interface class for sharing the autocalc component between OpenMW and OpenCS
class StoreCommon
{
public:
StoreCommon() {}
virtual ~StoreCommon() {}
virtual int findGmstInt(const std::string& gmst) const = 0;
virtual float findGmstFloat(const std::string& gmst) const = 0;
virtual const ESM::Skill *findSkill(int index) const = 0;
virtual const ESM::MagicEffect* findMagicEffect(int id) const = 0;
virtual const std::vector<ESM::Spell*>& getSpells() const = 0;
};
}
#endif // COMPONENTS_AUTOCALC_STORE_H

View File

@ -1,138 +0,0 @@
#ifndef COMPONENTS_GAMEPLAY_STORE_H
#define COMPONENTS_GAMEPLAY_STORE_H
#include <vector>
#include <string>
namespace Loading
{
class Listener;
}
namespace ESM
{
class ESMWriter;
class ESMReader;
struct Spell;
struct Skill;
struct MagicEffect;
}
namespace GamePlay
{
// moved from apps/openmw/mwworld/store.hpp
struct StoreBase
{
virtual ~StoreBase() {}
virtual void setUp() {}
virtual void listIdentifier(std::vector<std::string> &list) const {}
virtual size_t getSize() const = 0;
virtual int getDynamicSize() const { return 0; }
virtual void load(ESM::ESMReader &esm, const std::string &id) = 0;
virtual bool eraseStatic(const std::string &id) {return false;}
virtual void clearDynamic() {}
virtual void write (ESM::ESMWriter& writer, Loading::Listener& progress) const {}
virtual void read (ESM::ESMReader& reader, const std::string& id) {}
///< Read into dynamic storage
};
// moved from apps/openmw/mwworld/store.hpp
template <class T>
class SharedIterator
{
typedef typename std::vector<T *>::const_iterator Iter;
Iter mIter;
public:
SharedIterator() {}
SharedIterator(const SharedIterator &orig)
: mIter(orig.mIter)
{}
SharedIterator(const Iter &iter)
: mIter(iter)
{}
SharedIterator &operator++() {
++mIter;
return *this;
}
SharedIterator operator++(int) {
SharedIterator iter = *this;
++mIter;
return iter;
}
SharedIterator &operator--() {
--mIter;
return *this;
}
SharedIterator operator--(int) {
SharedIterator iter = *this;
--mIter;
return iter;
}
bool operator==(const SharedIterator &x) const {
return mIter == x.mIter;
}
bool operator!=(const SharedIterator &x) const {
return !(*this == x);
}
const T &operator*() const {
return **mIter;
}
const T *operator->() const {
return &(**mIter);
}
};
// interface class for sharing the autocalc component between OpenMW and OpenCS
template <class T>
class CommonStore : public StoreBase
{
public:
typedef SharedIterator<T> iterator;
virtual iterator begin() const = 0;
virtual iterator end() const = 0;
virtual const T *find(const std::string &id) const = 0;
};
// interface class for sharing the autocalc component between OpenMW and OpenCS
class StoreWrap
{
public:
StoreWrap() {}
virtual ~StoreWrap() {}
virtual int findGmstInt(const std::string& gmst) const = 0;
virtual float findGmstFloat(const std::string& gmst) const = 0;
virtual const ESM::Skill *findSkill(int index) const = 0;
virtual const ESM::MagicEffect* findMagicEffect(int id) const = 0;
virtual const CommonStore<ESM::Spell>& getSpells() const = 0;
};
}
#endif // COMPONENTS_GAMEPLAY_STORE_H