1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-20 13:53:53 +00:00
openmw/apps/opencs/model/world/refiddata.hpp

248 lines
8.2 KiB
C++
Raw Normal View History

#ifndef CSM_WOLRD_REFIDDATA_H
#define CSM_WOLRD_REFIDDATA_H
#include <vector>
#include <map>
#include <components/esm/loadacti.hpp>
#include <components/esm/loadalch.hpp>
#include <components/esm/loadappa.hpp>
#include <components/esm/loadarmo.hpp>
#include <components/esm/loadbook.hpp>
#include <components/esm/loadclot.hpp>
#include <components/esm/loadcont.hpp>
#include <components/esm/loadcrea.hpp>
#include <components/esm/loaddoor.hpp>
#include <components/esm/loadingr.hpp>
#include <components/esm/loadlevlist.hpp>
#include <components/esm/loadligh.hpp>
#include <components/esm/loadlock.hpp>
#include <components/esm/loadprob.hpp>
#include <components/esm/loadrepa.hpp>
#include <components/esm/loadstat.hpp>
#include <components/esm/loadweap.hpp>
#include <components/esm/loadnpc.hpp>
#include <components/esm/loadmisc.hpp>
2013-09-24 11:53:19 +00:00
#include <components/esm/esmwriter.hpp>
#include "record.hpp"
#include "universalid.hpp"
namespace ESM
{
class ESMReader;
}
namespace CSMWorld
{
struct RefIdDataContainerBase
{
virtual ~RefIdDataContainerBase();
virtual int getSize() const = 0;
2013-12-30 12:23:16 +00:00
virtual const RecordBase& getRecord(int index) const = 0;
2013-12-30 12:23:16 +00:00
virtual RecordBase& getRecord(int index) = 0;
2013-12-30 12:23:16 +00:00
virtual void appendRecord(const std::string& id) = 0;
2013-12-30 12:23:16 +00:00
virtual void load(int index, ESM::ESMReader& reader, bool base) = 0;
2013-12-30 12:23:16 +00:00
virtual void erase(int index, int count) = 0;
2013-12-30 12:23:16 +00:00
virtual std::string getId(int index) const = 0;
2013-09-24 11:53:19 +00:00
2013-12-30 12:23:16 +00:00
virtual void save(int index, ESM::ESMWriter& writer) const = 0;
};
template<typename RecordT>
struct RefIdDataContainer : public RefIdDataContainerBase
{
std::vector<Record<RecordT> > mContainer;
virtual int getSize() const;
2013-12-30 12:23:16 +00:00
virtual const RecordBase& getRecord(int index) const;
2013-12-30 12:23:16 +00:00
virtual RecordBase& getRecord(int index);
2013-12-30 12:23:16 +00:00
virtual void appendRecord(const std::string& id);
2013-12-30 12:23:16 +00:00
virtual void load(int index, ESM::ESMReader& reader, bool base);
2013-12-30 12:23:16 +00:00
virtual void erase(int index, int count);
2013-12-30 12:23:16 +00:00
virtual std::string getId(int index) const;
2013-09-24 11:53:19 +00:00
2013-12-30 12:23:16 +00:00
virtual void save(int index, ESM::ESMWriter& writer) const;
};
template<typename RecordT>
int RefIdDataContainer<RecordT>::getSize() const
{
2013-12-30 12:23:16 +00:00
return static_cast<int>(mContainer.size());
}
template<typename RecordT>
2013-12-30 12:23:16 +00:00
const RecordBase& RefIdDataContainer<RecordT>::getRecord(int index) const
{
2013-12-30 12:23:16 +00:00
return mContainer.at(index);
}
template<typename RecordT>
2013-12-30 12:23:16 +00:00
RecordBase& RefIdDataContainer<RecordT>::getRecord(int index)
{
2013-12-30 12:23:16 +00:00
return mContainer.at(index);
}
template<typename RecordT>
2013-12-30 12:23:16 +00:00
void RefIdDataContainer<RecordT>::appendRecord(const std::string& id)
{
Record<RecordT> record;
record.mModified.mId = id;
record.mModified.blank();
record.mState = RecordBase::State_ModifiedOnly;
2013-12-30 12:23:16 +00:00
mContainer.push_back(record);
}
template<typename RecordT>
2013-12-30 12:23:16 +00:00
void RefIdDataContainer<RecordT>::load(int index, ESM::ESMReader& reader, bool base)
{
2013-12-30 12:23:16 +00:00
(base ? mContainer.at(index).mBase : mContainer.at(index).mModified).load(reader);
}
template<typename RecordT>
2013-12-30 12:23:16 +00:00
void RefIdDataContainer<RecordT>::erase(int index, int count)
{
2013-12-30 12:23:16 +00:00
if (index < 0 || index + count >= getSize())
throw std::runtime_error("invalid RefIdDataContainer index");
2013-12-30 12:23:16 +00:00
mContainer.erase(mContainer.begin() + index, mContainer.begin() + index + count);
}
template<typename RecordT>
2013-12-30 12:23:16 +00:00
std::string RefIdDataContainer<RecordT>::getId(int index) const
{
2013-12-30 12:23:16 +00:00
return mContainer.at(index).get().mId;
}
2013-09-24 11:53:19 +00:00
template<typename RecordT>
2013-12-30 12:23:16 +00:00
void RefIdDataContainer<RecordT>::save(int index, ESM::ESMWriter& writer) const
2013-09-24 11:53:19 +00:00
{
2013-12-30 12:23:16 +00:00
CSMWorld::RecordBase::State state = mContainer.at(index).mState;
2013-09-24 11:53:19 +00:00
2013-12-30 12:23:16 +00:00
if (state == CSMWorld::RecordBase::State_Modified ||
state == CSMWorld::RecordBase::State_ModifiedOnly)
2013-09-24 11:53:19 +00:00
{
std::string type;
2013-12-30 12:23:16 +00:00
for (int i = 0; i < 4; ++i)
2013-09-24 11:53:19 +00:00
/// \todo make endianess agnostic (change ESMWriter interface?)
2013-12-30 12:23:16 +00:00
type += reinterpret_cast<const char*>(&mContainer.at(index).mModified.sRecordId)[i];
2013-09-24 11:53:19 +00:00
2013-12-30 12:23:16 +00:00
writer.startRecord(type);
writer.writeHNCString("NAME", getId(index));
mContainer.at(index).mModified.save(writer);
writer.endRecord(type);
2013-09-24 11:53:19 +00:00
}
2013-12-30 12:23:16 +00:00
else if (state == CSMWorld::RecordBase::State_Deleted)
2013-09-24 11:53:19 +00:00
{
/// \todo write record with delete flag
}
}
class RefIdData
{
public:
typedef std::pair<int, UniversalId::Type> LocalIndex;
private:
RefIdDataContainer<ESM::Activator> mActivators;
RefIdDataContainer<ESM::Potion> mPotions;
RefIdDataContainer<ESM::Apparatus> mApparati;
RefIdDataContainer<ESM::Armor> mArmors;
RefIdDataContainer<ESM::Book> mBooks;
RefIdDataContainer<ESM::Clothing> mClothing;
RefIdDataContainer<ESM::Container> mContainers;
RefIdDataContainer<ESM::Creature> mCreatures;
RefIdDataContainer<ESM::Door> mDoors;
RefIdDataContainer<ESM::Ingredient> mIngredients;
RefIdDataContainer<ESM::CreatureLevList> mCreatureLevelledLists;
RefIdDataContainer<ESM::ItemLevList> mItemLevelledLists;
RefIdDataContainer<ESM::Light> mLights;
RefIdDataContainer<ESM::Lockpick> mLockpicks;
RefIdDataContainer<ESM::Miscellaneous> mMiscellaneous;
RefIdDataContainer<ESM::NPC> mNpcs;
RefIdDataContainer<ESM::Probe> mProbes;
RefIdDataContainer<ESM::Repair> mRepairs;
RefIdDataContainer<ESM::Static> mStatics;
RefIdDataContainer<ESM::Weapon> mWeapons;
std::map<std::string, LocalIndex> mIndex;
2013-12-30 12:23:16 +00:00
std::map<UniversalId::Type, RefIdDataContainerBase*> mRecordContainers;
2013-12-30 12:23:16 +00:00
void erase(const LocalIndex& index, int count);
///< Must not spill over into another type.
public:
RefIdData();
2013-12-30 12:23:16 +00:00
LocalIndex globalToLocalIndex(int index) const;
2013-12-30 12:23:16 +00:00
int localToGlobalIndex(const LocalIndex& index) const;
2013-12-30 12:23:16 +00:00
LocalIndex searchId(const std::string& id) const;
2013-12-30 12:23:16 +00:00
void erase(int index, int count);
2013-12-30 12:23:16 +00:00
const RecordBase& getRecord(const LocalIndex& index) const;
2013-12-30 12:23:16 +00:00
RecordBase& getRecord(const LocalIndex& index);
2013-12-30 12:23:16 +00:00
void appendRecord(UniversalId::Type type, const std::string& id);
2013-12-30 12:23:16 +00:00
int getAppendIndex(UniversalId::Type type) const;
2013-12-30 12:23:16 +00:00
void load(const LocalIndex& index, ESM::ESMReader& reader, bool base);
int getSize() const;
2013-12-30 12:23:16 +00:00
std::vector<std::string> getIds(bool listDeleted = true) const;
///< Return a sorted collection of all IDs
///
/// \param listDeleted include deleted record in the list
2013-09-24 11:53:19 +00:00
2013-12-30 12:23:16 +00:00
void save(int index, ESM::ESMWriter& writer) const;
//RECORD CONTAINERS ACCESS METHODS
const RefIdDataContainer<ESM::Book>& getBooks() const;
const RefIdDataContainer<ESM::Activator>& getActivators() const;
const RefIdDataContainer<ESM::Potion>& getPotions() const;
const RefIdDataContainer<ESM::Apparatus>& getApparati() const;
const RefIdDataContainer<ESM::Armor>& getArmors() const;
const RefIdDataContainer<ESM::Clothing>& getClothing() const;
const RefIdDataContainer<ESM::Container>& getContainers() const;
const RefIdDataContainer<ESM::Creature>& getCreatures() const;
const RefIdDataContainer<ESM::Door>& getDoors() const;
const RefIdDataContainer<ESM::Ingredient>& getIngredients() const;
const RefIdDataContainer<ESM::CreatureLevList>& getCreatureLevelledLists() const;
const RefIdDataContainer<ESM::ItemLevList>& getItemLevelledList() const;
const RefIdDataContainer<ESM::Light>& getLights() const;
const RefIdDataContainer<ESM::Lockpick>& getLocpicks() const;
const RefIdDataContainer<ESM::Miscellaneous>& getMiscellaneous() const;
const RefIdDataContainer<ESM::NPC>& getNPCs() const;
};
}
#endif
2013-12-27 21:13:55 +00:00
2013-12-30 12:23:16 +00:00