mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-24 22:43:47 +00:00
Create new Vec2i RefId for ESM3 exterior cells.
Applies the necessary changes to use !2708 for the new Id type
This commit is contained in:
parent
1e0c3bfdec
commit
4c15064a83
@ -175,7 +175,7 @@ namespace MWMechanics
|
||||
}
|
||||
}
|
||||
else if (Misc::StringUtils::ciEqual(mCellId,
|
||||
actor.getCell()->getCell()->getWorldSpace().getRefIdString())) // Cell to travel to
|
||||
actor.getCell()->getCell()->getWorldSpace().toString())) // Cell to travel to
|
||||
{
|
||||
mRemainingDuration = mDuration;
|
||||
return true;
|
||||
|
@ -677,8 +677,8 @@ namespace MWWorld
|
||||
"Testing exterior cells (" + std::to_string(i) + "/" + std::to_string(cells.getExtSize()) + ")...");
|
||||
|
||||
CellStore* cell = mWorld.getWorldModel().getExterior(it->mData.mX, it->mData.mY);
|
||||
mNavigator.setWorldspace(Misc::StringUtils::lowerCase(cell->getCell()->getWorldSpace().getRefIdString()),
|
||||
navigatorUpdateGuard.get());
|
||||
mNavigator.setWorldspace(
|
||||
Misc::StringUtils::lowerCase(cell->getCell()->getWorldSpace().toString()), navigatorUpdateGuard.get());
|
||||
const osg::Vec3f position
|
||||
= osg::Vec3f(it->mData.mX + 0.5f, it->mData.mY + 0.5f, 0) * Constants::CellSizeInUnits;
|
||||
mNavigator.updateBounds(position, navigatorUpdateGuard.get());
|
||||
@ -735,8 +735,8 @@ namespace MWWorld
|
||||
"Testing interior cells (" + std::to_string(i) + "/" + std::to_string(cells.getIntSize()) + ")...");
|
||||
|
||||
CellStore* cell = mWorld.getWorldModel().getInterior(it->mName);
|
||||
mNavigator.setWorldspace(Misc::StringUtils::lowerCase(cell->getCell()->getWorldSpace().getRefIdString()),
|
||||
navigatorUpdateGuard.get());
|
||||
mNavigator.setWorldspace(
|
||||
Misc::StringUtils::lowerCase(cell->getCell()->getWorldSpace().toString()), navigatorUpdateGuard.get());
|
||||
ESM::Position position;
|
||||
mWorld.findInteriorPosition(it->mName, position);
|
||||
mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get());
|
||||
@ -752,7 +752,7 @@ namespace MWWorld
|
||||
{
|
||||
assert(!(*iter)->getCell()->isExterior());
|
||||
|
||||
if (it->mName == (*iter)->getCell()->getWorldSpace().getRefIdString())
|
||||
if (it->mName == (*iter)->getCell()->getWorldSpace().toString())
|
||||
{
|
||||
unloadCell(*iter, navigatorUpdateGuard.get());
|
||||
break;
|
||||
@ -891,8 +891,8 @@ namespace MWWorld
|
||||
|
||||
loadingListener->setProgressRange(cell->count());
|
||||
|
||||
mNavigator.setWorldspace(Misc::StringUtils::lowerCase(cell->getCell()->getWorldSpace().getRefIdString()),
|
||||
navigatorUpdateGuard.get());
|
||||
mNavigator.setWorldspace(
|
||||
Misc::StringUtils::lowerCase(cell->getCell()->getWorldSpace().toString()), navigatorUpdateGuard.get());
|
||||
mNavigator.updateBounds(position.asVec3(), navigatorUpdateGuard.get());
|
||||
|
||||
// Load cell.
|
||||
|
@ -224,18 +224,35 @@ MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
|
||||
return result->second;
|
||||
}
|
||||
|
||||
struct VisitorCellIdIsESM3Ext
|
||||
{
|
||||
bool operator()(const ESM::Vec2iRefId& id)
|
||||
{
|
||||
coordOut = { id.getValue().first, id.getValue().second };
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool operator()(const T&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::pair<int32_t, int32_t> coordOut = {};
|
||||
};
|
||||
|
||||
MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::RefId& id)
|
||||
{
|
||||
auto result = mCells.find(id);
|
||||
if (result != mCells.end())
|
||||
return &result->second;
|
||||
|
||||
// TODO tetramir: in the future replace that with elsid's refId variant that can be a osg::Vec2i
|
||||
ESM::CellId cellId = ESM::CellId::extractFromRefId(id);
|
||||
if (cellId.mPaged) // That is an exterior cell Id
|
||||
VisitorCellIdIsESM3Ext isESM3ExteriorVisitor;
|
||||
|
||||
if (visit(isESM3ExteriorVisitor, id)) // That is an exterior cell Id
|
||||
{
|
||||
|
||||
return getExterior(cellId.mIndex.mX, cellId.mIndex.mY);
|
||||
return getExterior(isESM3ExteriorVisitor.coordOut.first, isESM3ExteriorVisitor.coordOut.second);
|
||||
}
|
||||
|
||||
const ESM4::Cell* cell4 = mStore.get<ESM4::Cell>().search(id);
|
||||
|
@ -91,6 +91,7 @@ add_component_dir(esm attr common defs esmcommon records util luascripts format
|
||||
generatedrefid
|
||||
indexrefid
|
||||
serializerefid
|
||||
vec2irefid
|
||||
)
|
||||
|
||||
add_component_dir(fx pass technique lexer widgets stateupdater)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "generatedrefid.hpp"
|
||||
#include "indexrefid.hpp"
|
||||
#include "stringrefid.hpp"
|
||||
#include "vec2irefid.hpp"
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
@ -38,6 +39,7 @@ namespace ESM
|
||||
FormId = 3,
|
||||
Generated = 4,
|
||||
Index = 5,
|
||||
Vec2i = 6,
|
||||
};
|
||||
|
||||
// RefId is used to represent an Id that identifies an ESM record. These Ids can then be used in
|
||||
@ -70,6 +72,8 @@ namespace ESM
|
||||
// identified by index (i.e. ESM3 SKIL).
|
||||
static RefId index(RecNameInts recordType, std::uint32_t value) { return RefId(IndexRefId(recordType, value)); }
|
||||
|
||||
static RefId vec2i(std::pair<int32_t, int32_t> value) { return RefId(Vec2iRefId(value)); }
|
||||
|
||||
constexpr RefId() = default;
|
||||
|
||||
constexpr RefId(EmptyRefId value) noexcept
|
||||
@ -97,6 +101,11 @@ namespace ESM
|
||||
{
|
||||
}
|
||||
|
||||
constexpr RefId(Vec2iRefId value) noexcept
|
||||
: mValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
// Returns a reference to the value of StringRefId if it's the underlying value or throws an exception.
|
||||
const std::string& getRefIdString() const;
|
||||
|
||||
|
26
components/esm/vec2irefid.cpp
Normal file
26
components/esm/vec2irefid.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include "vec2irefid.hpp"
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
std::string Vec2iRefId::toString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << "# " << mValue.first << ", " << mValue.second;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
std::string Vec2iRefId::toDebugString() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << *this;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, Vec2iRefId value)
|
||||
{
|
||||
return stream << "Vec2i{" << value.mValue.first << "," << value.mValue.second << '}';
|
||||
}
|
||||
}
|
52
components/esm/vec2irefid.hpp
Normal file
52
components/esm/vec2irefid.hpp
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef OPENMW_COMPONENTS_ESM_VEC2IREFID_HPP
|
||||
#define OPENMW_COMPONENTS_ESM_VEC2IREFID_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace ESM
|
||||
{
|
||||
class Vec2iRefId
|
||||
{
|
||||
public:
|
||||
constexpr Vec2iRefId() = default;
|
||||
|
||||
constexpr explicit Vec2iRefId(std::pair<int32_t, int32_t> value) noexcept
|
||||
: mValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
std::pair<int32_t, int32_t> getValue() const { return mValue; }
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
std::string toDebugString() const;
|
||||
|
||||
constexpr bool operator==(Vec2iRefId rhs) const noexcept { return mValue == rhs.mValue; }
|
||||
|
||||
constexpr bool operator<(Vec2iRefId rhs) const noexcept { return mValue < rhs.mValue; }
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& stream, Vec2iRefId value);
|
||||
|
||||
friend struct std::hash<Vec2iRefId>;
|
||||
|
||||
private:
|
||||
std::pair<int32_t, int32_t> mValue = std::pair<int32_t, int32_t>(0, 0);
|
||||
};
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct hash<ESM::Vec2iRefId>
|
||||
{
|
||||
std::size_t operator()(ESM::Vec2iRefId value) const noexcept
|
||||
{
|
||||
return (53 + std::hash<int32_t>{}(value.mValue.first)) * 53 + std::hash<int32_t>{}(value.mValue.second);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -32,28 +32,36 @@ namespace ESM
|
||||
esm.writeHNT("CIDX", mIndex, 8);
|
||||
}
|
||||
|
||||
struct VisitCellRefId
|
||||
{
|
||||
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::Vec2iRefId& id)
|
||||
{
|
||||
CellId out;
|
||||
out.mPaged = true;
|
||||
out.mIndex = { id.getValue().first, id.getValue().second };
|
||||
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.
|
||||
const std::string& idString = id.getRefIdString();
|
||||
CellId out;
|
||||
if (idString[0] == '#' && idString.find(',')) // That is an exterior cell Id
|
||||
{
|
||||
int x, y;
|
||||
std::stringstream stringStream = std::stringstream(idString);
|
||||
char sharp = '#';
|
||||
char comma = ',';
|
||||
stringStream >> sharp >> x >> comma >> y;
|
||||
out.mPaged = true;
|
||||
out.mIndex = { x, y };
|
||||
}
|
||||
else
|
||||
{
|
||||
out.mPaged = false;
|
||||
out.mWorldspace = Misc::StringUtils::lowerCase(idString);
|
||||
}
|
||||
|
||||
return out;
|
||||
return visit(VisitCellRefId(), id);
|
||||
}
|
||||
|
||||
bool operator==(const CellId& left, const CellId& right)
|
||||
|
@ -491,6 +491,13 @@ namespace ESM
|
||||
getExact(&index, sizeof(std::uint32_t));
|
||||
return RefId::index(recordType, index);
|
||||
}
|
||||
case RefIdType::Vec2i:
|
||||
{
|
||||
std::pair<int32_t, int32_t> vec2i;
|
||||
getExact(&vec2i.first, sizeof(std::int32_t));
|
||||
getExact(&vec2i.second, sizeof(std::int32_t));
|
||||
return RefId::vec2i(vec2i);
|
||||
}
|
||||
}
|
||||
|
||||
fail("Unsupported RefIdType: " + std::to_string(static_cast<unsigned>(refIdType)));
|
||||
|
@ -4,8 +4,8 @@
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <components/esm3/cellid.hpp>
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/esm3/cellid.hpp>
|
||||
#include <components/misc/notnullptr.hpp>
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
@ -61,6 +61,13 @@ namespace ESM
|
||||
mWriter.writeT(v.getRecordType());
|
||||
mWriter.writeT(v.getValue());
|
||||
}
|
||||
|
||||
void operator()(Vec2iRefId v) const
|
||||
{
|
||||
mWriter.writeT(RefIdType::Vec2i);
|
||||
mWriter.writeT(v.getValue().first);
|
||||
mWriter.writeT(v.getValue().second);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ namespace ESM
|
||||
|
||||
ESM::RefId Cell::generateIdForExteriorCell(int x, int y)
|
||||
{
|
||||
return ESM::RefId::stringRefId("#" + std::to_string(x) + "," + std::to_string(y));
|
||||
return ESM::RefId::vec2i({ x, y });
|
||||
}
|
||||
|
||||
ESM::RefId Cell::generateIdForCell(bool exterior, std::string_view cellName, int x, int y)
|
||||
|
Loading…
x
Reference in New Issue
Block a user