1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-25 15:35:23 +00:00

these were supposed to be included

This commit is contained in:
unknown 2020-07-28 18:24:09 +02:00
parent 6ad20ec9c7
commit e27858cfab
2 changed files with 235 additions and 0 deletions

View 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;
}
}
}
}

View 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