1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
#include "cellid.hpp"
#include "esmreader.hpp"
#include "esmwriter.hpp"
#include <components/misc/algorithm.hpp>
#include <components/misc/concepts.hpp>
namespace ESM
{
template <Misc::SameAsWithoutCvref<CellId::CellIndex> T>
void decompose(T&& v, const auto& f)
{
f(v.mX, v.mY);
}
void CellId::load(ESMReader& esm)
{
mWorldspace = esm.getHNString("SPAC");
mIndex.mX = 0;
mIndex.mY = 0;
mPaged = esm.getOptionalComposite("CIDX", mIndex);
}
void CellId::save(ESMWriter& esm) const
{
esm.writeHNString("SPAC", mWorldspace);
if (mPaged)
esm.writeNamedComposite("CIDX", mIndex);
}
struct VisitCellRefId
{
CellId operator()(const ESM::EmptyRefId)
{
CellId out;
out.mPaged = true;
out.mIndex = {};
return out;
}
CellId operator()(const ESM::StringRefId& id)
{
CellId out;
out.mPaged = false;
out.mWorldspace = id.getValue();
out.mIndex = { 0, 0 };
return out;
}
CellId operator()(const ESM::ESM3ExteriorCellRefId& id)
{
CellId out;
out.mPaged = true;
out.mIndex = { id.getX(), id.getY() };
return out;
}
template <typename T>
CellId operator()(const T& id)
{
throw std::runtime_error("cannot extract CellId from this Id type");
}
};
CellId CellId::extractFromRefId(const ESM::RefId& id)
{
// This is bad and that code should not be merged.
return visit(VisitCellRefId(), id);
}
bool operator==(const CellId& left, const CellId& right)
{
return left.mWorldspace == right.mWorldspace && left.mPaged == right.mPaged
&& (!left.mPaged || (left.mIndex.mX == right.mIndex.mX && left.mIndex.mY == right.mIndex.mY));
}
bool operator!=(const CellId& left, const CellId& right)
{
return !(left == right);
}
bool operator<(const CellId& left, const CellId& right)
{
if (left.mPaged < right.mPaged)
return true;
if (left.mPaged > right.mPaged)
return false;
if (left.mPaged)
{
if (left.mIndex.mX < right.mIndex.mX)
return true;
if (left.mIndex.mX > right.mIndex.mX)
return false;
if (left.mIndex.mY < right.mIndex.mY)
return true;
if (left.mIndex.mY > right.mIndex.mY)
return false;
}
return left.mWorldspace < right.mWorldspace;
}
}
|