mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-01 08:39:44 +00:00
Dest Door and teleport use ESM::RefId
This changes a lot of files as a consequence. Still buggy, moving to exterior doesn't bring to the right place yet coc "seyda neen" doesn't work. SO I broke somehting when fetching a cell from a name
This commit is contained in:
parent
96e42d1666
commit
3f678c3b0a
26 changed files with 258 additions and 170 deletions
|
@ -114,7 +114,7 @@ namespace MWBase
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
float x, y; // world position
|
float x, y; // world position
|
||||||
ESM::CellId dest;
|
ESM::RefId dest;
|
||||||
};
|
};
|
||||||
|
|
||||||
World() {}
|
World() {}
|
||||||
|
@ -260,6 +260,9 @@ namespace MWBase
|
||||||
virtual void changeToCell(
|
virtual void changeToCell(
|
||||||
const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true)
|
const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true)
|
||||||
= 0;
|
= 0;
|
||||||
|
virtual void changeToCell(
|
||||||
|
const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true)
|
||||||
|
= 0;
|
||||||
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
||||||
|
|
||||||
virtual MWWorld::Ptr getFacedObject() = 0;
|
virtual MWWorld::Ptr getFacedObject() = 0;
|
||||||
|
@ -514,13 +517,16 @@ namespace MWBase
|
||||||
virtual bool screenshot360(osg::Image* image) = 0;
|
virtual bool screenshot360(osg::Image* image) = 0;
|
||||||
|
|
||||||
/// Find default position inside exterior cell specified by name
|
/// Find default position inside exterior cell specified by name
|
||||||
/// \return false if exterior with given name not exists, true otherwise
|
/// \return invalid RefId if exterior with given name not exists, the cell's RefId otherwise
|
||||||
virtual bool findExteriorPosition(std::string_view name, ESM::Position& pos) = 0;
|
virtual ESM::RefId findExteriorPosition(std::string_view name, ESM::Position& pos) = 0;
|
||||||
|
|
||||||
/// Find default position inside interior cell specified by name
|
/// Find default position inside interior cell specified by name
|
||||||
/// \return false if interior with given name not exists, true otherwise
|
/// \return invalid RefId if interior with given name not exists, the cell's RefId otherwise
|
||||||
virtual bool findInteriorPosition(std::string_view name, ESM::Position& pos) = 0;
|
virtual ESM::RefId findInteriorPosition(std::string_view name, ESM::Position& pos) = 0;
|
||||||
|
|
||||||
|
/// Find default position inside interior or exterior cell specified by name
|
||||||
|
/// \return invalid RefId if interior with given name not exists, the cell's RefId otherwise
|
||||||
|
virtual ESM::RefId findCellPosition(std::string_view cellName, ESM::Position& pos) = 0;
|
||||||
/// Enables or disables use of teleport spell effects (recall, intervention, etc).
|
/// Enables or disables use of teleport spell effects (recall, intervention, etc).
|
||||||
virtual void enableTeleporting(bool enable) = 0;
|
virtual void enableTeleporting(bool enable) = 0;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "../mwworld/esmstore.hpp"
|
#include "../mwworld/esmstore.hpp"
|
||||||
#include "../mwworld/failedaction.hpp"
|
#include "../mwworld/failedaction.hpp"
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
#include "../mwworld/worldmodel.hpp"
|
||||||
|
|
||||||
#include "../mwgui/tooltips.hpp"
|
#include "../mwgui/tooltips.hpp"
|
||||||
#include "../mwgui/ustring.hpp"
|
#include "../mwgui/ustring.hpp"
|
||||||
|
@ -298,16 +299,8 @@ namespace MWClass
|
||||||
|
|
||||||
std::string Door::getDestination(const MWWorld::LiveCellRef<ESM::Door>& door)
|
std::string Door::getDestination(const MWWorld::LiveCellRef<ESM::Door>& door)
|
||||||
{
|
{
|
||||||
std::string_view dest = door.mRef.getDestCell();
|
std::string_view dest
|
||||||
if (dest.empty())
|
= MWBase::Environment::get().getWorldModel()->getCell(door.mRef.getDestCell())->getCell()->getDisplayName();
|
||||||
{
|
|
||||||
// door leads to exterior, use cell name (if any), otherwise translated region name
|
|
||||||
auto world = MWBase::Environment::get().getWorld();
|
|
||||||
const osg::Vec2i index
|
|
||||||
= MWWorld::positionToCellIndex(door.mRef.getDoorDest().pos[0], door.mRef.getDoorDest().pos[1]);
|
|
||||||
const ESM::Cell* cell = world->getStore().get<ESM::Cell>().search(index.x(), index.y());
|
|
||||||
dest = world->getCellName(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "#{sCell=" + std::string{ dest } + "}";
|
return "#{sCell=" + std::string{ dest } + "}";
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ namespace MWGui
|
||||||
return mMarkers.end();
|
return mMarkers.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomMarkerCollection::RangeType CustomMarkerCollection::getMarkers(const ESM::CellId& cellId) const
|
CustomMarkerCollection::RangeType CustomMarkerCollection::getMarkers(const ESM::RefId& cellId) const
|
||||||
{
|
{
|
||||||
return mMarkers.equal_range(cellId);
|
return mMarkers.equal_range(cellId);
|
||||||
}
|
}
|
||||||
|
@ -356,8 +356,8 @@ namespace MWGui
|
||||||
cellId.mWorldspace = (mInterior ? mPrefix : ESM::CellId::sDefaultWorldspace);
|
cellId.mWorldspace = (mInterior ? mPrefix : ESM::CellId::sDefaultWorldspace);
|
||||||
cellId.mIndex.mX = mCurX + dX;
|
cellId.mIndex.mX = mCurX + dX;
|
||||||
cellId.mIndex.mY = mCurY + dY;
|
cellId.mIndex.mY = mCurY + dY;
|
||||||
|
ESM::RefId cellRefId = cellId.getCellRefId();
|
||||||
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(cellId);
|
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(cellRefId);
|
||||||
for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second;
|
for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second;
|
||||||
++it)
|
++it)
|
||||||
{
|
{
|
||||||
|
@ -885,16 +885,19 @@ namespace MWGui
|
||||||
|
|
||||||
mEditingMarker.mWorldX = worldPos.x();
|
mEditingMarker.mWorldX = worldPos.x();
|
||||||
mEditingMarker.mWorldY = worldPos.y();
|
mEditingMarker.mWorldY = worldPos.y();
|
||||||
|
ESM::CellId clickedId;
|
||||||
|
|
||||||
mEditingMarker.mCell.mPaged = !mInterior;
|
clickedId.mPaged = !mInterior;
|
||||||
if (mInterior)
|
if (mInterior)
|
||||||
mEditingMarker.mCell.mWorldspace = LocalMapBase::mPrefix;
|
clickedId.mWorldspace = LocalMapBase::mPrefix;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mEditingMarker.mCell.mWorldspace = ESM::CellId::sDefaultWorldspace;
|
clickedId.mWorldspace = ESM::CellId::sDefaultWorldspace;
|
||||||
mEditingMarker.mCell.mIndex.mX = x;
|
clickedId.mIndex.mX = x;
|
||||||
mEditingMarker.mCell.mIndex.mY = y;
|
clickedId.mIndex.mY = y;
|
||||||
}
|
}
|
||||||
|
mEditingMarker.mCell = clickedId.getCellRefId();
|
||||||
|
mEditingMarker.mCellId = clickedId;
|
||||||
|
|
||||||
mEditNoteDialog.setVisible(true);
|
mEditNoteDialog.setVisible(true);
|
||||||
mEditNoteDialog.showDeleteButton(false);
|
mEditNoteDialog.showDeleteButton(false);
|
||||||
|
@ -1125,7 +1128,8 @@ namespace MWGui
|
||||||
cellId.mIndex.mY = y;
|
cellId.mIndex.mY = y;
|
||||||
cellId.mWorldspace = ESM::CellId::sDefaultWorldspace;
|
cellId.mWorldspace = ESM::CellId::sDefaultWorldspace;
|
||||||
cellId.mPaged = true;
|
cellId.mPaged = true;
|
||||||
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(cellId);
|
ESM::RefId cellRefId = cellId.getCellRefId();
|
||||||
|
CustomMarkerCollection::RangeType markers = mCustomMarkers.getMarkers(cellRefId);
|
||||||
std::vector<std::string> destNotes;
|
std::vector<std::string> destNotes;
|
||||||
for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second; ++it)
|
for (CustomMarkerCollection::ContainerType::const_iterator it = markers.first; it != markers.second; ++it)
|
||||||
destNotes.push_back(it->second.mNote);
|
destNotes.push_back(it->second.mNote);
|
||||||
|
|
|
@ -56,14 +56,14 @@ namespace MWGui
|
||||||
|
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
typedef std::multimap<ESM::CellId, ESM::CustomMarker> ContainerType;
|
typedef std::multimap<ESM::RefId, ESM::CustomMarker> ContainerType;
|
||||||
|
|
||||||
typedef std::pair<ContainerType::const_iterator, ContainerType::const_iterator> RangeType;
|
typedef std::pair<ContainerType::const_iterator, ContainerType::const_iterator> RangeType;
|
||||||
|
|
||||||
ContainerType::const_iterator begin() const;
|
ContainerType::const_iterator begin() const;
|
||||||
ContainerType::const_iterator end() const;
|
ContainerType::const_iterator end() const;
|
||||||
|
|
||||||
RangeType getMarkers(const ESM::CellId& cellId) const;
|
RangeType getMarkers(const ESM::RefId& cellId) const;
|
||||||
|
|
||||||
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
|
typedef MyGUI::delegates::CMultiDelegate0 EventHandle_Void;
|
||||||
EventHandle_Void eventMarkersChanged;
|
EventHandle_Void eventMarkersChanged;
|
||||||
|
|
|
@ -195,9 +195,15 @@ namespace MWGui
|
||||||
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
|
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->fadeScreenOut(1);
|
MWBase::Environment::get().getWindowManager()->fadeScreenOut(1);
|
||||||
|
ESM::CellId cellId;
|
||||||
|
osg::Vec2i posCell = MWWorld::positionToCellIndex(pos.pos[0], pos.pos[1]);
|
||||||
|
cellId.mPaged = !interior;
|
||||||
|
cellId.mWorldspace = Misc::StringUtils::lowerCase(cellname);
|
||||||
|
cellId.mIndex.mX = posCell.x();
|
||||||
|
cellId.mIndex.mY = posCell.y();
|
||||||
|
|
||||||
// Teleports any followers, too.
|
// Teleports any followers, too.
|
||||||
MWWorld::ActionTeleport action(interior ? cellname : "", pos, true);
|
MWWorld::ActionTeleport action(cellId.getCellRefId(), pos, true);
|
||||||
action.execute(player);
|
action.execute(player);
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0);
|
MWBase::Environment::get().getWindowManager()->fadeScreenOut(0);
|
||||||
|
|
|
@ -36,8 +36,7 @@ namespace MWLua
|
||||||
const MWWorld::CellRef& cellRef = doorPtr(o).getCellRef();
|
const MWWorld::CellRef& cellRef = doorPtr(o).getCellRef();
|
||||||
if (!cellRef.getTeleport())
|
if (!cellRef.getTeleport())
|
||||||
return sol::nil;
|
return sol::nil;
|
||||||
MWWorld::CellStore* cell = MWBase::Environment::get().getWorldModel()->getCellByPosition(
|
MWWorld::CellStore* cell = MWBase::Environment::get().getWorldModel()->getCell(cellRef.getDestCell());
|
||||||
cellRef.getDoorDest().asVec3(), cellRef.getDestCell());
|
|
||||||
assert(cell);
|
assert(cell);
|
||||||
return o.getCell(lua, cell);
|
return o.getCell(lua, cell);
|
||||||
};
|
};
|
||||||
|
|
|
@ -487,9 +487,9 @@ namespace MWMechanics
|
||||||
world->getPlayer().getMarkedPosition(markedCell, markedPosition);
|
world->getPlayer().getMarkedPosition(markedCell, markedPosition);
|
||||||
if (markedCell)
|
if (markedCell)
|
||||||
{
|
{
|
||||||
std::string_view dest;
|
ESM::RefId dest;
|
||||||
if (!markedCell->isExterior())
|
if (!markedCell->isExterior())
|
||||||
dest = markedCell->getCell()->getNameId();
|
dest = markedCell->getCell()->getId();
|
||||||
MWWorld::ActionTeleport action(dest, markedPosition, false);
|
MWWorld::ActionTeleport action(dest, markedPosition, false);
|
||||||
action.execute(target);
|
action.execute(target);
|
||||||
if (!caster.isEmpty())
|
if (!caster.isEmpty())
|
||||||
|
|
|
@ -92,19 +92,9 @@ namespace MWScript
|
||||||
ESM::Position pos;
|
ESM::Position pos;
|
||||||
MWBase::World* world = MWBase::Environment::get().getWorld();
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
||||||
const MWWorld::Ptr playerPtr = world->getPlayerPtr();
|
const MWWorld::Ptr playerPtr = world->getPlayerPtr();
|
||||||
|
ESM::RefId cellId = world->findCellPosition(cell, pos);
|
||||||
if (world->findExteriorPosition(cell, pos))
|
MWWorld::ActionTeleport(cellId, pos, false).execute(playerPtr);
|
||||||
{
|
world->adjustPosition(playerPtr, false);
|
||||||
MWWorld::ActionTeleport({}, pos, false).execute(playerPtr);
|
|
||||||
world->adjustPosition(playerPtr, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Change to interior even if findInteriorPosition()
|
|
||||||
// yields false. In this case position will be zero-point.
|
|
||||||
world->findInteriorPosition(cell, pos);
|
|
||||||
MWWorld::ActionTeleport(cell, pos, false).execute(playerPtr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
ActionTeleport::ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers)
|
ActionTeleport::ActionTeleport(ESM::RefId cellId, const ESM::Position& position, bool teleportFollowers)
|
||||||
: Action(true)
|
: Action(true)
|
||||||
, mCellName(cellName)
|
, mCellId(cellId)
|
||||||
, mPosition(position)
|
, mPosition(position)
|
||||||
, mTeleportFollowers(teleportFollowers)
|
, mTeleportFollowers(teleportFollowers)
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,9 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
// Find any NPCs that are following the actor and teleport them with him
|
// Find any NPCs that are following the actor and teleport them with him
|
||||||
std::set<MWWorld::Ptr> followers;
|
std::set<MWWorld::Ptr> followers;
|
||||||
getFollowers(actor, followers, mCellName.empty(), true);
|
|
||||||
|
bool toExterior = MWBase::Environment::get().getWorldModel()->getCell(mCellId)->isExterior();
|
||||||
|
getFollowers(actor, followers, toExterior, true);
|
||||||
|
|
||||||
for (std::set<MWWorld::Ptr>::iterator it = followers.begin(); it != followers.end(); ++it)
|
for (std::set<MWWorld::Ptr>::iterator it = followers.begin(); it != followers.end(); ++it)
|
||||||
teleport(*it);
|
teleport(*it);
|
||||||
|
@ -52,10 +54,8 @@ namespace MWWorld
|
||||||
if (actor == world->getPlayerPtr())
|
if (actor == world->getPlayerPtr())
|
||||||
{
|
{
|
||||||
world->getPlayer().setTeleported(true);
|
world->getPlayer().setTeleported(true);
|
||||||
if (mCellName.empty())
|
if (!mCellId.empty())
|
||||||
world->changeToExteriorCell(mPosition, true);
|
world->changeToCell(mCellId, mPosition, true);
|
||||||
else
|
|
||||||
world->changeToInteriorCell(mCellName, mPosition, true);
|
|
||||||
teleported = world->getPlayerPtr();
|
teleported = world->getPlayerPtr();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -65,15 +65,9 @@ namespace MWWorld
|
||||||
actor.getClass().getCreatureStats(actor).getAiSequence().stopCombat();
|
actor.getClass().getCreatureStats(actor).getAiSequence().stopCombat();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (mCellName.empty())
|
|
||||||
{
|
|
||||||
const osg::Vec2i index = positionToCellIndex(mPosition.pos[0], mPosition.pos[1]);
|
|
||||||
teleported = world->moveObject(
|
|
||||||
actor, worldModel->getExterior(index.x(), index.y()), mPosition.asVec3(), true, true);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
teleported
|
teleported = world->moveObject(actor, worldModel->getCell(mCellId), mPosition.asVec3(), true, true);
|
||||||
= world->moveObject(actor, worldModel->getInterior(mCellName), mPosition.asVec3(), true, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!world->isWaterWalkingCastableOnTarget(teleported) && MWMechanics::hasWaterWalking(teleported))
|
if (!world->isWaterWalkingCastableOnTarget(teleported) && MWMechanics::hasWaterWalking(teleported))
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
class ActionTeleport : public Action
|
class ActionTeleport : public Action
|
||||||
{
|
{
|
||||||
std::string mCellName;
|
ESM::RefId mCellId;
|
||||||
ESM::Position mPosition;
|
ESM::Position mPosition;
|
||||||
bool mTeleportFollowers;
|
bool mTeleportFollowers;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace MWWorld
|
||||||
public:
|
public:
|
||||||
/// If cellName is empty, an exterior cell is assumed.
|
/// If cellName is empty, an exterior cell is assumed.
|
||||||
/// @param teleportFollowers Whether to teleport any following actors of the target actor as well.
|
/// @param teleportFollowers Whether to teleport any following actors of the target actor as well.
|
||||||
ActionTeleport(std::string_view cellName, const ESM::Position& position, bool teleportFollowers);
|
ActionTeleport(ESM::RefId cellId, const ESM::Position& position, bool teleportFollowers);
|
||||||
|
|
||||||
/// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the
|
/// @param includeHostiles If true, include hostile followers (which won't actually be teleported) in the
|
||||||
/// output,
|
/// output,
|
||||||
|
|
|
@ -3,8 +3,11 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <components/debug/debuglog.hpp>
|
#include <components/debug/debuglog.hpp>
|
||||||
|
#include <components/esm3/cellid.hpp>
|
||||||
#include <components/esm3/objectstate.hpp>
|
#include <components/esm3/objectstate.hpp>
|
||||||
|
|
||||||
|
#include <apps/openmw/mwworld/cellutils.hpp>
|
||||||
|
|
||||||
namespace MWWorld
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
CellRef::CellRef(const ESM::CellRef& ref)
|
CellRef::CellRef(const ESM::CellRef& ref)
|
||||||
|
@ -67,12 +70,54 @@ namespace MWWorld
|
||||||
|
|
||||||
static const std::string emptyString = "";
|
static const std::string emptyString = "";
|
||||||
|
|
||||||
const std::string& CellRef::getDestCell() const
|
ESM::Position CellRef::getDoorDest() const
|
||||||
{
|
{
|
||||||
return std::visit(ESM::VisitOverload{
|
|
||||||
[&](const ESM4::Reference& /*ref*/) -> const std::string& { return emptyString; },
|
auto esm3Visit = [&](const ESM::CellRef& ref) -> ESM::Position {
|
||||||
[&](const ESM::CellRef& ref) -> const std::string& { return ref.mDestCell; },
|
// So the destinaion pos is always in relationship to the destination cells origin, interior or exterior
|
||||||
},
|
// alike
|
||||||
|
ESM::Position pos = ref.mDoorDest;
|
||||||
|
if (ref.mDestCell.empty()) // Exterior cell case
|
||||||
|
{
|
||||||
|
const osg::Vec2i index = positionToCellIndex(ref.mDoorDest.pos[0], ref.mDoorDest.pos[1]);
|
||||||
|
pos.pos[0] -= index.x() * Constants::CellSizeInUnits;
|
||||||
|
pos.pos[1] -= index.y() * Constants::CellSizeInUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
return std::visit(
|
||||||
|
ESM::VisitOverload{
|
||||||
|
[&](const ESM4::Reference& ref) { return ref.mDoor.destPos; },
|
||||||
|
esm3Visit,
|
||||||
|
},
|
||||||
|
mCellRef.mVariant);
|
||||||
|
}
|
||||||
|
|
||||||
|
ESM::RefId CellRef::getDestCell() const
|
||||||
|
{
|
||||||
|
auto esm3Visit = [&](const ESM::CellRef& ref) -> ESM::RefId {
|
||||||
|
if (!ref.mDestCell.empty())
|
||||||
|
{
|
||||||
|
return ESM::RefId::stringRefId(ref.mDestCell);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const osg::Vec2i index = positionToCellIndex(ref.mDoorDest.pos[0], ref.mDoorDest.pos[1]);
|
||||||
|
ESM::CellId CellId;
|
||||||
|
CellId.mPaged = true;
|
||||||
|
CellId.mIndex.mX = index.x();
|
||||||
|
CellId.mIndex.mY = index.y();
|
||||||
|
return CellId.getCellRefId();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return std::visit(
|
||||||
|
ESM::VisitOverload{
|
||||||
|
[&](const ESM4::Reference& ref) -> ESM::RefId { return ESM::RefId::sEmpty; },
|
||||||
|
esm3Visit,
|
||||||
|
},
|
||||||
mCellRef.mVariant);
|
mCellRef.mVariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,18 +61,10 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
// Teleport location for the door, if this is a teleporting door.
|
// Teleport location for the door, if this is a teleporting door.
|
||||||
const ESM::Position& getDoorDest() const
|
ESM::Position getDoorDest() const;
|
||||||
{
|
|
||||||
struct Visitor
|
|
||||||
{
|
|
||||||
const ESM::Position& operator()(const ESM::CellRef& ref) { return ref.mDoorDest; }
|
|
||||||
const ESM::Position& operator()(const ESM4::Reference& ref) { return ref.mDoor.destPos; }
|
|
||||||
};
|
|
||||||
return std::visit(Visitor(), mCellRef.mVariant);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destination cell for doors (optional)
|
// Destination cell for doors (optional)
|
||||||
const std::string& getDestCell() const;
|
ESM::RefId getDestCell() const;
|
||||||
|
|
||||||
// Scale applied to mesh
|
// Scale applied to mesh
|
||||||
float getScale() const
|
float getScale() const
|
||||||
|
|
|
@ -1081,7 +1081,7 @@ namespace MWWorld
|
||||||
ESM::CellId movedTo;
|
ESM::CellId movedTo;
|
||||||
refnum.load(reader, true, "MVRF");
|
refnum.load(reader, true, "MVRF");
|
||||||
movedTo.load(reader);
|
movedTo.load(reader);
|
||||||
|
ESM::RefId movedToId = movedTo.getCellRefId();
|
||||||
if (refnum.hasContentFile())
|
if (refnum.hasContentFile())
|
||||||
{
|
{
|
||||||
auto iter = contentFileMap.find(refnum.mContentFile);
|
auto iter = contentFileMap.find(refnum.mContentFile);
|
||||||
|
@ -1098,7 +1098,7 @@ namespace MWWorld
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CellStore* otherCell = callback->getCellStore(movedTo);
|
CellStore* otherCell = callback->getCellStore(movedToId);
|
||||||
|
|
||||||
if (otherCell == nullptr)
|
if (otherCell == nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -291,7 +291,7 @@ namespace MWWorld
|
||||||
struct GetCellStoreCallback
|
struct GetCellStoreCallback
|
||||||
{
|
{
|
||||||
///@note must return nullptr if the cell is not found
|
///@note must return nullptr if the cell is not found
|
||||||
virtual CellStore* getCellStore(const ESM::CellId& cellId) = 0;
|
virtual CellStore* getCellStore(const ESM::RefId& cellId) = 0;
|
||||||
virtual ~GetCellStoreCallback() = default;
|
virtual ~GetCellStoreCallback() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -367,7 +367,7 @@ namespace MWWorld
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mCellStore = MWBase::Environment::get().getWorldModel()->getCell(player.mCellId);
|
mCellStore = MWBase::Environment::get().getWorldModel()->getCellFromCellId(player.mCellId);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
@ -404,7 +404,7 @@ namespace MWWorld
|
||||||
if (player.mHasMark)
|
if (player.mHasMark)
|
||||||
{
|
{
|
||||||
mMarkedPosition = player.mMarkedPosition;
|
mMarkedPosition = player.mMarkedPosition;
|
||||||
mMarkedCell = MWBase::Environment::get().getWorldModel()->getCell(player.mMarkedCell);
|
mMarkedCell = MWBase::Environment::get().getWorldModel()->getCellFromCellId(player.mMarkedCell);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1129,15 +1129,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!door.getCellRef().getDestCell().empty())
|
preloadCell(mWorld.getWorldModel().getCell(door.getCellRef().getDestCell()));
|
||||||
preloadCell(mWorld.getWorldModel().getInterior(door.getCellRef().getDestCell()));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
osg::Vec3f pos = door.getCellRef().getDoorDest().asVec3();
|
|
||||||
const osg::Vec2i cellIndex = positionToCellIndex(pos.x(), pos.y());
|
|
||||||
preloadCell(mWorld.getWorldModel().getExterior(cellIndex.x(), cellIndex.y()), true);
|
|
||||||
exteriorPositions.emplace_back(pos, gridCenterToBounds(getNewGridCenter(pos)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (std::exception&)
|
catch (std::exception&)
|
||||||
{
|
{
|
||||||
|
|
|
@ -471,7 +471,7 @@ namespace MWWorld
|
||||||
const ESM::Cell* Store<ESM::Cell>::search(const ESM::RefId& cellId) const
|
const ESM::Cell* Store<ESM::Cell>::search(const ESM::RefId& cellId) const
|
||||||
{
|
{
|
||||||
auto foundCellIt = mCells.find(cellId);
|
auto foundCellIt = mCells.find(cellId);
|
||||||
if (foundCellIt == mCells.end())
|
if (foundCellIt != mCells.end())
|
||||||
return &foundCellIt->second;
|
return &foundCellIt->second;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -353,7 +353,7 @@ namespace MWWorld
|
||||||
if (bypass && !mStartCell.empty())
|
if (bypass && !mStartCell.empty())
|
||||||
{
|
{
|
||||||
ESM::Position pos;
|
ESM::Position pos;
|
||||||
if (findExteriorPosition(mStartCell, pos))
|
if (findExteriorPosition(mStartCell, pos).empty())
|
||||||
{
|
{
|
||||||
changeToExteriorCell(pos, true);
|
changeToExteriorCell(pos, true);
|
||||||
adjustPosition(getPlayerPtr(), false);
|
adjustPosition(getPlayerPtr(), false);
|
||||||
|
@ -1000,6 +1000,31 @@ namespace MWWorld
|
||||||
mCurrentDate->setup(mGlobalVariables);
|
mCurrentDate->setup(mGlobalVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::changeToCell(
|
||||||
|
const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent)
|
||||||
|
{
|
||||||
|
const MWWorld::Cell* destinationCell = getWorldModel().getCell(cellId)->getCell();
|
||||||
|
bool exteriorCell = destinationCell->isExterior();
|
||||||
|
|
||||||
|
mPhysics->clearQueuedMovement();
|
||||||
|
mDiscardMovements = true;
|
||||||
|
|
||||||
|
if (changeEvent && mCurrentWorldSpace != destinationCell->getNameId())
|
||||||
|
{
|
||||||
|
// changed worldspace
|
||||||
|
mProjectileManager->clear();
|
||||||
|
mRendering->notifyWorldSpaceChanged();
|
||||||
|
mCurrentWorldSpace = destinationCell->getNameId();
|
||||||
|
}
|
||||||
|
removeContainerScripts(getPlayerPtr());
|
||||||
|
if (exteriorCell)
|
||||||
|
mWorldScene->changeToExteriorCell(position, adjustPlayerPos, changeEvent);
|
||||||
|
else
|
||||||
|
mWorldScene->changeToInteriorCell(destinationCell->getNameId(), position, adjustPlayerPos, changeEvent);
|
||||||
|
addContainerScripts(getPlayerPtr(), getPlayerPtr().getCell());
|
||||||
|
mRendering->getCamera()->instantTransition();
|
||||||
|
}
|
||||||
|
|
||||||
float World::getMaxActivationDistance() const
|
float World::getMaxActivationDistance() const
|
||||||
{
|
{
|
||||||
if (mActivationDistanceOverride >= 0)
|
if (mActivationDistanceOverride >= 0)
|
||||||
|
@ -1420,9 +1445,9 @@ namespace MWWorld
|
||||||
esmPos.pos[0] = traced.x();
|
esmPos.pos[0] = traced.x();
|
||||||
esmPos.pos[1] = traced.y();
|
esmPos.pos[1] = traced.y();
|
||||||
esmPos.pos[2] = traced.z();
|
esmPos.pos[2] = traced.z();
|
||||||
std::string_view cell;
|
ESM::RefId cell;
|
||||||
if (!actor.getCell()->isExterior())
|
if (!actor.getCell()->isExterior())
|
||||||
cell = actor.getCell()->getCell()->getNameId();
|
cell = actor.getCell()->getCell()->getId();
|
||||||
MWWorld::ActionTeleport(cell, esmPos, false).execute(actor);
|
MWWorld::ActionTeleport(cell, esmPos, false).execute(actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2060,24 +2085,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
World::DoorMarker newMarker;
|
World::DoorMarker newMarker;
|
||||||
newMarker.name = MWClass::Door::getDestination(ref);
|
newMarker.name = MWClass::Door::getDestination(ref);
|
||||||
|
newMarker.dest = ref.mRef.getDestCell();
|
||||||
ESM::CellId cellid;
|
|
||||||
if (!ref.mRef.getDestCell().empty())
|
|
||||||
{
|
|
||||||
cellid.mWorldspace = ref.mRef.getDestCell();
|
|
||||||
cellid.mPaged = false;
|
|
||||||
cellid.mIndex.mX = 0;
|
|
||||||
cellid.mIndex.mY = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cellid.mPaged = true;
|
|
||||||
const osg::Vec2i index
|
|
||||||
= positionToCellIndex(ref.mRef.getDoorDest().pos[0], ref.mRef.getDoorDest().pos[1]);
|
|
||||||
cellid.mIndex.mX = index.x();
|
|
||||||
cellid.mIndex.mY = index.y();
|
|
||||||
}
|
|
||||||
newMarker.dest = cellid;
|
|
||||||
|
|
||||||
ESM::Position pos = ref.mData.getPosition();
|
ESM::Position pos = ref.mData.getPosition();
|
||||||
|
|
||||||
|
@ -2764,7 +2772,7 @@ namespace MWWorld
|
||||||
physicActor->enableCollisionBody(enable);
|
physicActor->enableCollisionBody(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::findInteriorPosition(std::string_view name, ESM::Position& pos)
|
ESM::RefId World::findInteriorPosition(std::string_view name, ESM::Position& pos)
|
||||||
{
|
{
|
||||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||||
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;
|
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;
|
||||||
|
@ -2772,8 +2780,9 @@ namespace MWWorld
|
||||||
MWWorld::CellStore* cellStore = mWorldModel.getInterior(name);
|
MWWorld::CellStore* cellStore = mWorldModel.getInterior(name);
|
||||||
|
|
||||||
if (!cellStore)
|
if (!cellStore)
|
||||||
return false;
|
return ESM::RefId::sEmpty;
|
||||||
|
|
||||||
|
ESM::RefId cellId = cellStore->getCell()->getId();
|
||||||
std::vector<const MWWorld::CellRef*> sortedDoors;
|
std::vector<const MWWorld::CellRef*> sortedDoors;
|
||||||
for (const MWWorld::LiveCellRef<ESM::Door>& door : cellStore->getReadOnlyDoors().mList)
|
for (const MWWorld::LiveCellRef<ESM::Door>& door : cellStore->getReadOnlyDoors().mList)
|
||||||
{
|
{
|
||||||
|
@ -2794,32 +2803,21 @@ namespace MWWorld
|
||||||
for (const MWWorld::CellRef* door : sortedDoors)
|
for (const MWWorld::CellRef* door : sortedDoors)
|
||||||
{
|
{
|
||||||
MWWorld::CellStore* source = nullptr;
|
MWWorld::CellStore* source = nullptr;
|
||||||
|
source = mWorldModel.getCell(door->getDestCell());
|
||||||
|
|
||||||
// door to exterior
|
|
||||||
if (door->getDestCell().empty())
|
|
||||||
{
|
|
||||||
ESM::Position doorDest = door->getDoorDest();
|
|
||||||
const osg::Vec2i index = positionToCellIndex(doorDest.pos[0], doorDest.pos[1]);
|
|
||||||
source = mWorldModel.getExterior(index.x(), index.y());
|
|
||||||
}
|
|
||||||
// door to interior
|
|
||||||
else
|
|
||||||
{
|
|
||||||
source = mWorldModel.getInterior(door->getDestCell());
|
|
||||||
}
|
|
||||||
if (source)
|
if (source)
|
||||||
{
|
{
|
||||||
// Find door leading to our current teleport door
|
// Find door leading to our current teleport door
|
||||||
// and use its destination to position inside cell.
|
// and use its destination to position inside cell.
|
||||||
for (const MWWorld::LiveCellRef<ESM::Door>& destDoor : source->getReadOnlyDoors().mList)
|
for (const MWWorld::LiveCellRef<ESM::Door>& destDoor : source->getReadOnlyDoors().mList)
|
||||||
{
|
{
|
||||||
if (name == destDoor.mRef.getDestCell())
|
if (ESM::RefId::stringRefId(name) == destDoor.mRef.getDestCell())
|
||||||
{
|
{
|
||||||
/// \note Using _any_ door pointed to the interior,
|
/// \note Using _any_ door pointed to the interior,
|
||||||
/// not the one pointed to current door.
|
/// not the one pointed to current door.
|
||||||
pos = destDoor.mRef.getDoorDest();
|
pos = destDoor.mRef.getDoorDest();
|
||||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||||
return true;
|
return cellId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2831,7 +2829,7 @@ namespace MWWorld
|
||||||
// found the COC position?
|
// found the COC position?
|
||||||
pos = stat4.mRef.getPosition();
|
pos = stat4.mRef.getPosition();
|
||||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||||
return true;
|
return cellId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Fall back to the first static location.
|
// Fall back to the first static location.
|
||||||
|
@ -2840,7 +2838,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
pos = statics4.begin()->mRef.getPosition();
|
pos = statics4.begin()->mRef.getPosition();
|
||||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||||
return true;
|
return cellId;
|
||||||
}
|
}
|
||||||
// Fall back to the first static location.
|
// Fall back to the first static location.
|
||||||
const MWWorld::CellRefList<ESM::Static>::List& statics = cellStore->getReadOnlyStatics().mList;
|
const MWWorld::CellRefList<ESM::Static>::List& statics = cellStore->getReadOnlyStatics().mList;
|
||||||
|
@ -2848,13 +2846,24 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
pos = statics.begin()->mRef.getPosition();
|
pos = statics.begin()->mRef.getPosition();
|
||||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||||
return true;
|
return cellId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return ESM::RefId::sEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::findExteriorPosition(std::string_view nameId, ESM::Position& pos)
|
ESM::RefId World::findCellPosition(std::string_view cellName, ESM::Position& pos)
|
||||||
|
{
|
||||||
|
ESM::RefId foundCell = findInteriorPosition(cellName, pos);
|
||||||
|
if (foundCell.empty())
|
||||||
|
{
|
||||||
|
return findInteriorPosition(cellName, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundCell;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESM::RefId World::findExteriorPosition(std::string_view nameId, ESM::Position& pos)
|
||||||
{
|
{
|
||||||
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
|
||||||
|
|
||||||
|
@ -2863,7 +2872,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
ext = mWorldModel.getCell(nameId)->getCell();
|
ext = mWorldModel.getCell(nameId)->getCell();
|
||||||
if (!ext->isExterior())
|
if (!ext->isExterior())
|
||||||
return false;
|
return ESM::RefId::sEmpty;
|
||||||
}
|
}
|
||||||
catch (std::exception&)
|
catch (std::exception&)
|
||||||
{
|
{
|
||||||
|
@ -2895,10 +2904,10 @@ namespace MWWorld
|
||||||
// Note: Z pos will be adjusted by adjustPosition later
|
// Note: Z pos will be adjusted by adjustPosition later
|
||||||
pos.pos[2] = 0;
|
pos.pos[2] = 0;
|
||||||
|
|
||||||
return true;
|
return ext->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return ESM::RefId::sEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::enableTeleporting(bool enable)
|
void World::enableTeleporting(bool enable)
|
||||||
|
@ -3289,10 +3298,10 @@ namespace MWWorld
|
||||||
|
|
||||||
// Search for a 'nearest' exterior, counting each cell between the starting
|
// Search for a 'nearest' exterior, counting each cell between the starting
|
||||||
// cell and the exterior as a distance of 1. Will fail for isolated interiors.
|
// cell and the exterior as a distance of 1. Will fail for isolated interiors.
|
||||||
std::set<std::string_view> checkedCells;
|
std::set<ESM::RefId> checkedCells;
|
||||||
std::set<std::string_view> currentCells;
|
std::set<ESM::RefId> currentCells;
|
||||||
std::set<std::string_view> nextCells;
|
std::set<ESM::RefId> nextCells;
|
||||||
nextCells.insert(cell->getCell()->getNameId());
|
nextCells.insert(cell->getCell()->getId());
|
||||||
|
|
||||||
while (!nextCells.empty())
|
while (!nextCells.empty())
|
||||||
{
|
{
|
||||||
|
@ -3300,7 +3309,7 @@ namespace MWWorld
|
||||||
nextCells.clear();
|
nextCells.clear();
|
||||||
for (const auto& currentCell : currentCells)
|
for (const auto& currentCell : currentCells)
|
||||||
{
|
{
|
||||||
MWWorld::CellStore* next = mWorldModel.getInterior(currentCell);
|
MWWorld::CellStore* next = mWorldModel.getCell(currentCell);
|
||||||
if (!next)
|
if (!next)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -3318,7 +3327,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const std::string_view dest = ref.mRef.getDestCell();
|
ESM::RefId dest = ref.mRef.getDestCell();
|
||||||
if (!checkedCells.count(dest) && !currentCells.count(dest))
|
if (!checkedCells.count(dest) && !currentCells.count(dest))
|
||||||
nextCells.insert(dest);
|
nextCells.insert(dest);
|
||||||
}
|
}
|
||||||
|
@ -3342,19 +3351,19 @@ namespace MWWorld
|
||||||
// Search for a 'nearest' marker, counting each cell between the starting
|
// Search for a 'nearest' marker, counting each cell between the starting
|
||||||
// cell and the exterior as a distance of 1. If an exterior is found, jump
|
// cell and the exterior as a distance of 1. If an exterior is found, jump
|
||||||
// to the nearest exterior marker, without further interior searching.
|
// to the nearest exterior marker, without further interior searching.
|
||||||
std::set<std::string_view> checkedCells;
|
std::set<ESM::RefId> checkedCells;
|
||||||
std::set<std::string_view> currentCells;
|
std::set<ESM::RefId> currentCells;
|
||||||
std::set<std::string_view> nextCells;
|
std::set<ESM::RefId> nextCells;
|
||||||
MWWorld::ConstPtr closestMarker;
|
MWWorld::ConstPtr closestMarker;
|
||||||
|
|
||||||
nextCells.insert(ptr.getCell()->getCell()->getNameId());
|
nextCells.insert(ptr.getCell()->getCell()->getId());
|
||||||
while (!nextCells.empty())
|
while (!nextCells.empty())
|
||||||
{
|
{
|
||||||
currentCells = nextCells;
|
currentCells = nextCells;
|
||||||
nextCells.clear();
|
nextCells.clear();
|
||||||
for (const auto& cell : currentCells)
|
for (const auto& cell : currentCells)
|
||||||
{
|
{
|
||||||
MWWorld::CellStore* next = mWorldModel.getInterior(cell);
|
MWWorld::CellStore* next = mWorldModel.getCell(cell);
|
||||||
checkedCells.insert(cell);
|
checkedCells.insert(cell);
|
||||||
if (!next)
|
if (!next)
|
||||||
continue;
|
continue;
|
||||||
|
@ -3440,11 +3449,11 @@ namespace MWWorld
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view cellName = "";
|
ESM::RefId cellId;
|
||||||
if (!closestMarker.mCell->isExterior())
|
if (!closestMarker.mCell->isExterior())
|
||||||
cellName = closestMarker.mCell->getCell()->getNameId();
|
cellId = closestMarker.mCell->getCell()->getId();
|
||||||
|
|
||||||
MWWorld::ActionTeleport action(cellName, closestMarker.getRefData().getPosition(), false);
|
MWWorld::ActionTeleport action(cellId, closestMarker.getRefData().getPosition(), false);
|
||||||
action.execute(ptr);
|
action.execute(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3646,13 +3655,13 @@ namespace MWWorld
|
||||||
Log(Debug::Warning) << "Failed to confiscate items: no closest prison marker found.";
|
Log(Debug::Warning) << "Failed to confiscate items: no closest prison marker found.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string_view prisonName = prisonMarker.getCellRef().getDestCell();
|
ESM::RefId prisonName = prisonMarker.getCellRef().getDestCell();
|
||||||
if (prisonName.empty())
|
if (prisonName.empty())
|
||||||
{
|
{
|
||||||
Log(Debug::Warning) << "Failed to confiscate items: prison marker not linked to prison interior";
|
Log(Debug::Warning) << "Failed to confiscate items: prison marker not linked to prison interior";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MWWorld::CellStore* prison = mWorldModel.getInterior(prisonName);
|
MWWorld::CellStore* prison = mWorldModel.getCell(prisonName);
|
||||||
if (!prison)
|
if (!prison)
|
||||||
{
|
{
|
||||||
Log(Debug::Warning) << "Failed to confiscate items: failed to load cell " << prisonName;
|
Log(Debug::Warning) << "Failed to confiscate items: failed to load cell " << prisonName;
|
||||||
|
|
|
@ -351,6 +351,9 @@ namespace MWWorld
|
||||||
|
|
||||||
void changeToCell(const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos,
|
void changeToCell(const ESM::CellId& cellId, const ESM::Position& position, bool adjustPlayerPos,
|
||||||
bool changeEvent = true) override;
|
bool changeEvent = true) override;
|
||||||
|
|
||||||
|
void changeToCell(const ESM::RefId& cellId, const ESM::Position& position, bool adjustPlayerPos,
|
||||||
|
bool changeEvent = true) override;
|
||||||
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes
|
||||||
|
|
||||||
MWWorld::Ptr getFacedObject() override;
|
MWWorld::Ptr getFacedObject() override;
|
||||||
|
@ -601,12 +604,12 @@ namespace MWWorld
|
||||||
|
|
||||||
/// Find center of exterior cell above land surface
|
/// Find center of exterior cell above land surface
|
||||||
/// \return false if exterior with given name not exists, true otherwise
|
/// \return false if exterior with given name not exists, true otherwise
|
||||||
bool findExteriorPosition(std::string_view nameId, ESM::Position& pos) override;
|
ESM::RefId findExteriorPosition(std::string_view nameId, ESM::Position& pos) override;
|
||||||
|
|
||||||
/// Find position in interior cell near door entrance
|
/// Find position in interior cell near door entrance
|
||||||
/// \return false if interior with given name not exists, true otherwise
|
/// \return false if interior with given name not exists, true otherwise
|
||||||
bool findInteriorPosition(std::string_view name, ESM::Position& pos) override;
|
ESM::RefId findInteriorPosition(std::string_view name, ESM::Position& pos) override;
|
||||||
|
ESM::RefId findCellPosition(std::string_view cellName, ESM::Position& pos) override;
|
||||||
/// Enables or disables use of teleport spell effects (recall, intervention, etc).
|
/// Enables or disables use of teleport spell effects (recall, intervention, etc).
|
||||||
void enableTeleporting(bool enable) override;
|
void enableTeleporting(bool enable) override;
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,7 @@ MWWorld::CellStore* MWWorld::WorldModel::getInterior(std::string_view name)
|
||||||
return result->second;
|
return result->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::CellId& id)
|
MWWorld::CellStore* MWWorld::WorldModel::getCellFromCellId(const ESM::CellId& id)
|
||||||
{
|
{
|
||||||
if (id.mPaged)
|
if (id.mPaged)
|
||||||
return getExterior(id.mIndex.mX, id.mIndex.mY);
|
return getExterior(id.mIndex.mX, id.mIndex.mY);
|
||||||
|
@ -234,6 +234,52 @@ MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::CellId& id)
|
||||||
return getInterior(id.mWorldspace);
|
return getInterior(id.mWorldspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWWorld::CellStore* MWWorld::WorldModel::getCell(const ESM::RefId& id)
|
||||||
|
{
|
||||||
|
auto result = mCells.find(id);
|
||||||
|
if (result != mCells.end())
|
||||||
|
return &result->second;
|
||||||
|
|
||||||
|
// TODO: in the future replace that with elsid's refId variant that can be a osg::Vec2i
|
||||||
|
const std::string& idString = id.getRefIdString();
|
||||||
|
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;
|
||||||
|
return getExterior(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ESM4::Cell* cell4 = mStore.get<ESM4::Cell>().search(id);
|
||||||
|
CellStore* newCellStore = nullptr;
|
||||||
|
if (!cell4)
|
||||||
|
{
|
||||||
|
const ESM::Cell* cell = mStore.get<ESM::Cell>().search(id);
|
||||||
|
newCellStore = &mCells.emplace(cell->mId, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newCellStore = &mCells.emplace(cell4->mId, CellStore(MWWorld::Cell(*cell4), mStore, mReaders)).first->second;
|
||||||
|
}
|
||||||
|
if (newCellStore->getCell()->isExterior())
|
||||||
|
{
|
||||||
|
std::pair<int, int> coord
|
||||||
|
= std::make_pair(newCellStore->getCell()->getGridX(), newCellStore->getCell()->getGridY());
|
||||||
|
mExteriors.emplace(coord, newCellStore).first;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mInteriors.emplace(newCellStore->getCell()->getNameId(), newCellStore).first;
|
||||||
|
}
|
||||||
|
if (newCellStore->getState() != CellStore::State_Loaded)
|
||||||
|
{
|
||||||
|
newCellStore->load();
|
||||||
|
}
|
||||||
|
return newCellStore;
|
||||||
|
}
|
||||||
|
|
||||||
const ESM::Cell* MWWorld::WorldModel::getESMCellByName(std::string_view name)
|
const ESM::Cell* MWWorld::WorldModel::getESMCellByName(std::string_view name)
|
||||||
{
|
{
|
||||||
const ESM::Cell* cell = mStore.get<ESM::Cell>().search(name); // first try interiors
|
const ESM::Cell* cell = mStore.get<ESM::Cell>().search(name); // first try interiors
|
||||||
|
@ -428,7 +474,7 @@ public:
|
||||||
|
|
||||||
MWWorld::WorldModel& mWorldModel;
|
MWWorld::WorldModel& mWorldModel;
|
||||||
|
|
||||||
MWWorld::CellStore* getCellStore(const ESM::CellId& cellId) override
|
MWWorld::CellStore* getCellStore(const ESM::RefId& cellId) override
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -452,7 +498,7 @@ bool MWWorld::WorldModel::readRecord(ESM::ESMReader& reader, uint32_t type, cons
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cellStore = getCell(state.mId);
|
cellStore = getCell(state.mId.getCellRefId());
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
|
|
|
@ -70,7 +70,8 @@ namespace MWWorld
|
||||||
CellStore* getExterior(int x, int y);
|
CellStore* getExterior(int x, int y);
|
||||||
CellStore* getInterior(std::string_view name);
|
CellStore* getInterior(std::string_view name);
|
||||||
CellStore* getCell(std::string_view name); // interior or named exterior
|
CellStore* getCell(std::string_view name); // interior or named exterior
|
||||||
CellStore* getCell(const ESM::CellId& Id);
|
CellStore* getCell(const ESM::RefId& Id);
|
||||||
|
CellStore* getCellFromCellId(const ESM::CellId& Id);
|
||||||
|
|
||||||
// If cellNameInSameWorldSpace is an interior - returns this interior.
|
// If cellNameInSameWorldSpace is an interior - returns this interior.
|
||||||
// Otherwise returns exterior cell for given position in the same world space.
|
// Otherwise returns exterior cell for given position in the same world space.
|
||||||
|
|
|
@ -33,6 +33,18 @@ namespace ESM
|
||||||
esm.writeHNT("CIDX", mIndex, 8);
|
esm.writeHNT("CIDX", mIndex, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ESM::RefId CellId::getCellRefId() const
|
||||||
|
{
|
||||||
|
if (mPaged)
|
||||||
|
{
|
||||||
|
return ESM::RefId::stringRefId("#" + std::to_string(mIndex.mX) + "," + std::to_string(mIndex.mY));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ESM::RefId::stringRefId(mWorldspace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const CellId& left, const CellId& right)
|
bool operator==(const CellId& left, const CellId& right)
|
||||||
{
|
{
|
||||||
return left.mWorldspace == right.mWorldspace && left.mPaged == right.mPaged
|
return left.mWorldspace == right.mWorldspace && left.mPaged == right.mPaged
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace ESM
|
||||||
|
|
||||||
void load(ESMReader& esm);
|
void load(ESMReader& esm);
|
||||||
void save(ESMWriter& esm) const;
|
void save(ESMWriter& esm) const;
|
||||||
|
ESM::RefId getCellRefId() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator==(const CellId& left, const CellId& right);
|
bool operator==(const CellId& left, const CellId& right);
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace ESM
|
||||||
{
|
{
|
||||||
esm.writeHNT("POSX", mWorldX);
|
esm.writeHNT("POSX", mWorldX);
|
||||||
esm.writeHNT("POSY", mWorldY);
|
esm.writeHNT("POSY", mWorldY);
|
||||||
mCell.save(esm);
|
mCellId.save(esm);
|
||||||
if (!mNote.empty())
|
if (!mNote.empty())
|
||||||
esm.writeHNString("NOTE", mNote);
|
esm.writeHNString("NOTE", mNote);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@ namespace ESM
|
||||||
{
|
{
|
||||||
esm.getHNT(mWorldX, "POSX");
|
esm.getHNT(mWorldX, "POSX");
|
||||||
esm.getHNT(mWorldY, "POSY");
|
esm.getHNT(mWorldY, "POSY");
|
||||||
mCell.load(esm);
|
mCellId.load(esm);
|
||||||
|
mCell = mCellId.getCellRefId();
|
||||||
mNote = esm.getHNOString("NOTE");
|
mNote = esm.getHNOString("NOTE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,8 @@ namespace ESM
|
||||||
float mWorldX;
|
float mWorldX;
|
||||||
float mWorldY;
|
float mWorldY;
|
||||||
|
|
||||||
CellId mCell;
|
RefId mCell;
|
||||||
|
CellId mCellId; // The CellId representation for saving/loading
|
||||||
|
|
||||||
std::string mNote;
|
std::string mNote;
|
||||||
|
|
||||||
|
|
|
@ -59,14 +59,7 @@ namespace ESM
|
||||||
|
|
||||||
const ESM::RefId& Cell::updateId()
|
const ESM::RefId& Cell::updateId()
|
||||||
{
|
{
|
||||||
if (isExterior())
|
mId = mCellId.getCellRefId();
|
||||||
{
|
|
||||||
mId = ESM::RefId::stringRefId("#" + std::to_string(mData.mX) + "," + std::to_string(mData.mY));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mId = ESM::RefId::stringRefId(mName);
|
|
||||||
}
|
|
||||||
return mId;
|
return mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue