mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-19 15:11:33 +00:00
these were supposed to be included
This commit is contained in:
parent
6ad20ec9c7
commit
e27858cfab
2 changed files with 235 additions and 0 deletions
175
apps/openmw/mwmechanics/spelllist.cpp
Normal file
175
apps/openmw/mwmechanics/spelllist.cpp
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
#include "spelllist.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <components/esm/loadspel.hpp>
|
||||||
|
#include <components/misc/rng.hpp>
|
||||||
|
|
||||||
|
#include "spells.hpp"
|
||||||
|
|
||||||
|
#include "../mwbase/environment.hpp"
|
||||||
|
#include "../mwbase/world.hpp"
|
||||||
|
|
||||||
|
#include "../mwworld/esmstore.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
const std::vector<std::string> getSpellList(const std::string& id)
|
||||||
|
{
|
||||||
|
return MWBase::Environment::get().getWorld()->getStore().get<T>().find(id)->mSpells.mList;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
bool withBaseRecord(const std::string& id, const std::function<bool(std::vector<std::string>&)>& function)
|
||||||
|
{
|
||||||
|
T copy = *MWBase::Environment::get().getWorld()->getStore().get<T>().find(id);
|
||||||
|
bool changed = function(copy.mSpells.mList);
|
||||||
|
if(changed)
|
||||||
|
MWBase::Environment::get().getWorld()->createOverrideRecord(copy);
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
SpellList::SpellList(const std::string& id, int type) : mId(id), mType(type) {}
|
||||||
|
|
||||||
|
bool SpellList::withBaseRecord(const std::function<bool(std::vector<std::string>&)>& function)
|
||||||
|
{
|
||||||
|
switch(mType)
|
||||||
|
{
|
||||||
|
case ESM::REC_CREA:
|
||||||
|
return ::withBaseRecord<ESM::Creature>(mId, function);
|
||||||
|
case ESM::REC_NPC_:
|
||||||
|
return ::withBaseRecord<ESM::NPC>(mId, function);
|
||||||
|
default:
|
||||||
|
throw std::logic_error("failed to update base record for " + mId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<std::string> SpellList::getSpells() const
|
||||||
|
{
|
||||||
|
switch(mType)
|
||||||
|
{
|
||||||
|
case ESM::REC_CREA:
|
||||||
|
return getSpellList<ESM::Creature>(mId);
|
||||||
|
case ESM::REC_NPC_:
|
||||||
|
return getSpellList<ESM::NPC>(mId);
|
||||||
|
default:
|
||||||
|
throw std::logic_error("failed to get spell list for " + mId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ESM::Spell* SpellList::getSpell(const std::string& id)
|
||||||
|
{
|
||||||
|
return MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellList::add (const ESM::Spell* spell)
|
||||||
|
{
|
||||||
|
auto& id = spell->mId;
|
||||||
|
bool changed = withBaseRecord([&] (auto& spells)
|
||||||
|
{
|
||||||
|
for(auto it : spells)
|
||||||
|
{
|
||||||
|
if(Misc::StringUtils::ciEqual(id, it))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
spells.push_back(id);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if(changed)
|
||||||
|
{
|
||||||
|
for(auto listener : mListeners)
|
||||||
|
listener->addSpell(spell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellList::remove (const ESM::Spell* spell)
|
||||||
|
{
|
||||||
|
auto& id = spell->mId;
|
||||||
|
bool changed = withBaseRecord([&] (auto& spells)
|
||||||
|
{
|
||||||
|
for(auto it = spells.begin(); it != spells.end(); it++)
|
||||||
|
{
|
||||||
|
if(Misc::StringUtils::ciEqual(id, *it))
|
||||||
|
{
|
||||||
|
spells.erase(it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
if(changed)
|
||||||
|
{
|
||||||
|
for(auto listener : mListeners)
|
||||||
|
listener->removeSpell(spell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellList::removeAll (const std::vector<std::string>& ids)
|
||||||
|
{
|
||||||
|
bool changed = withBaseRecord([&] (auto& spells)
|
||||||
|
{
|
||||||
|
const auto it = std::remove_if(spells.begin(), spells.end(), [&] (const auto& spell)
|
||||||
|
{
|
||||||
|
const auto isSpell = [&] (const auto& id) { return Misc::StringUtils::ciEqual(spell, id); };
|
||||||
|
return ids.end() != std::find_if(ids.begin(), ids.end(), isSpell);
|
||||||
|
});
|
||||||
|
if (it == spells.end())
|
||||||
|
return false;
|
||||||
|
spells.erase(it, spells.end());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if(changed)
|
||||||
|
{
|
||||||
|
for(auto listener : mListeners)
|
||||||
|
{
|
||||||
|
for(auto& id : ids)
|
||||||
|
{
|
||||||
|
const auto spell = getSpell(id);
|
||||||
|
listener->removeSpell(spell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellList::clear()
|
||||||
|
{
|
||||||
|
bool changed = withBaseRecord([] (auto& spells)
|
||||||
|
{
|
||||||
|
if(spells.empty())
|
||||||
|
return false;
|
||||||
|
spells.clear();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if(changed)
|
||||||
|
{
|
||||||
|
for(auto listener : mListeners)
|
||||||
|
listener->removeAllSpells();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellList::addListener(Spells* spells)
|
||||||
|
{
|
||||||
|
for(const auto ptr : mListeners)
|
||||||
|
{
|
||||||
|
if(ptr == spells)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mListeners.push_back(spells);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpellList::removeListener(Spells* spells)
|
||||||
|
{
|
||||||
|
for(auto it = mListeners.begin(); it != mListeners.end(); it++)
|
||||||
|
{
|
||||||
|
if(*it == spells)
|
||||||
|
{
|
||||||
|
mListeners.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
60
apps/openmw/mwmechanics/spelllist.hpp
Normal file
60
apps/openmw/mwmechanics/spelllist.hpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef GAME_MWMECHANICS_SPELLLIST_H
|
||||||
|
#define GAME_MWMECHANICS_SPELLLIST_H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <components/esm/loadspel.hpp>
|
||||||
|
|
||||||
|
#include "magiceffects.hpp"
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
struct SpellState;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
struct SpellParams
|
||||||
|
{
|
||||||
|
std::map<int, float> mEffectRands; // <effect index, normalised random magnitude>
|
||||||
|
std::set<int> mPurgedEffects; // indices of purged effects
|
||||||
|
};
|
||||||
|
|
||||||
|
class Spells;
|
||||||
|
|
||||||
|
class SpellList
|
||||||
|
{
|
||||||
|
const std::string mId;
|
||||||
|
const int mType;
|
||||||
|
std::vector<Spells*> mListeners;
|
||||||
|
|
||||||
|
bool withBaseRecord(const std::function<bool(std::vector<std::string>&)>& function);
|
||||||
|
public:
|
||||||
|
SpellList(const std::string& id, int type);
|
||||||
|
|
||||||
|
/// Get spell from ID, throws exception if not found
|
||||||
|
static const ESM::Spell* getSpell(const std::string& id);
|
||||||
|
|
||||||
|
void add (const ESM::Spell* spell);
|
||||||
|
///< Adding a spell that is already listed in *this is a no-op.
|
||||||
|
|
||||||
|
void remove (const ESM::Spell* spell);
|
||||||
|
|
||||||
|
void removeAll(const std::vector<std::string>& spells);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
///< Remove all spells of all types.
|
||||||
|
|
||||||
|
void addListener(Spells* spells);
|
||||||
|
|
||||||
|
void removeListener(Spells* spells);
|
||||||
|
|
||||||
|
const std::vector<std::string> getSpells() const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue