[Client] Add World::updatePtrsWithRefId() method

This makes it possible to "reload" the Ptrs in active cells when changes happen to the ESM record that they are based on. In practice, the old Ptrs are deleted, their RefNums and MpNums are blanked out, and new Ptrs are created that use the same RefNum and MpNum as before.

The above has required me to also add a method called setRefNum() to CellRef to allow setting a RefNum on the fly.

There may be a more elegant implementation available for updatePtrsWithRefIds(), but it requires additional research.
pull/471/head
David Cernat 7 years ago
parent 9497c7f6f2
commit 7136329a94

@ -204,6 +204,16 @@ namespace MWBase
End of tes3mp addition
*/
/*
Start of tes3mp addition
Make it possible to update all Ptrs in active cells that have a certain refId
*/
virtual void updatePtrsWithRefId(std::string refId) = 0;
/*
End of tes3mp addition
*/
virtual MWWorld::Ptr findContainer (const MWWorld::ConstPtr& ptr) = 0;
///< Return a pointer to a liveCellRef which contains \a ptr.
/// \note Search is limited to the active cells.

@ -23,7 +23,22 @@ namespace MWWorld
/*
Start of tes3mp addition
Get the mMpNum (unique multiplayer reference number) of a CellRef
Set the unique reference number index of a CellRef, needed to
make objects retain their uniqueIndex when they are updated
after their records are modified on the fly by the server
*/
void CellRef::setRefNum(unsigned int index)
{
mCellRef.mRefNum.mIndex = index;
}
/*
End of tes3mp addition
*/
/*
Start of tes3mp addition
Get the mMpNum (unique multiplayer number) of a CellRef
*/
unsigned int CellRef::getMpNum() const
{

@ -28,6 +28,18 @@ namespace MWWorld
// Set RefNum to its default state.
void unsetRefNum();
/*
Start of tes3mp addition
Set the unique reference number index of a CellRef, needed to
make objects retain their uniqueIndex when they are updated
after their records are modified on the fly by the server
*/
void CellRef::setRefNum(unsigned int index);
/*
End of tes3mp addition
*/
/*
Start of tes3mp addition

@ -766,6 +766,53 @@ namespace MWWorld
End of tes3mp addition
*/
/*
Start of tes3mp addition
Make it possible to update all Ptrs in active cells that have a certain refId
*/
void World::updatePtrsWithRefId(std::string refId)
{
for (Scene::CellStoreCollection::const_iterator iter(mWorldScene->getActiveCells().begin());
iter != mWorldScene->getActiveCells().end(); ++iter)
{
CellStore* cellStore = *iter;
for (auto &mergedRef : cellStore->getMergedRefs())
{
if (Misc::StringUtils::ciEqual(refId, mergedRef->mRef.getRefId()))
{
MWWorld::Ptr ptr(mergedRef, cellStore);
const ESM::Position* position = &ptr.getRefData().getPosition();
const unsigned int refNum = ptr.getCellRef().getRefNum().mIndex;
const unsigned int mpNum = ptr.getCellRef().getMpNum();
deleteObject(ptr);
ptr.getCellRef().unsetRefNum();
ptr.getCellRef().setMpNum(0);
MWWorld::ManualRef* reference = new MWWorld::ManualRef(getStore(), refId, 1);
MWWorld::Ptr newPtr = placeObject(reference->getPtr(), cellStore, *position);
newPtr.getCellRef().setRefNum(refNum);
newPtr.getCellRef().setMpNum(mpNum);
// Update Ptrs for LocalActors and DedicatedActors
if (newPtr.getClass().isActor())
{
if (mwmp::Main::get().getCellController()->isLocalActor(refNum, mpNum))
mwmp::Main::get().getCellController()->getLocalActor(refNum, mpNum)->setPtr(newPtr);
else if (mwmp::Main::get().getCellController()->isDedicatedActor(refNum, mpNum))
mwmp::Main::get().getCellController()->getDedicatedActor(refNum, mpNum)->setPtr(newPtr);
}
}
}
}
}
/*
End of tes3mp addition
*/
struct FindContainerVisitor
{
ConstPtr mContainedPtr;

@ -311,6 +311,16 @@ namespace MWWorld
End of tes3mp addition
*/
/*
Start of tes3mp addition
Make it possible to update all Ptrs in active cells that have a certain refId
*/
void updatePtrsWithRefId(std::string refId) override;
/*
End of tes3mp addition
*/
MWWorld::Ptr findContainer (const MWWorld::ConstPtr& ptr) override;
///< Return a pointer to a liveCellRef which contains \a ptr.
/// \note Search is limited to the active cells.

Loading…
Cancel
Save