Make player references cross exterior cells only when called by server

Previously, clientside representations of players were able to move to a new exterior cell once during their movement tick and then again when sending a cell change packet to the server. Besides causing crashes in CellRef because of a messy cell-changing record, this also led to major desyncs.

Clientside representations of players can now only change their cells when a server-sent cell change packet specifically allows it.
pull/21/head
davidcernat 9 years ago
parent 360eec30a0
commit 3c8543bfaf

@ -242,6 +242,10 @@ void DedicatedPlayer::UpdatePtr(MWWorld::Ptr newPtr)
ptr.mCell = newPtr.mCell;
ptr.mRef = newPtr.mRef;
ptr.mContainerStore = newPtr.mContainerStore;
// Disallow this player's reference from moving across cells until
// the correct packet is sent by the player
ptr.getBase()->canChangeCell = false;
}
@ -400,5 +404,9 @@ void DedicatedPlayer::updateCell()
cellStore = world->getExterior(cell.mCellId.mIndex.mX, cell.mCellId.mIndex.mY);
else
cellStore = world->getInterior(cell.mName);
// Allow this player's reference to move across a cell now that
// a manual cell update has been called
ptr.getBase()->canChangeCell = true;
UpdatePtr(world->moveObject(ptr, cellStore, pos.pos[0], pos.pos[1], pos.pos[2]));
}

@ -14,6 +14,7 @@
MWWorld::LiveCellRefBase::LiveCellRefBase(const std::string& type, const ESM::CellRef &cref)
: mClass(&Class::get(type)), mRef(cref), mData(cref)
{
canChangeCell = true;
}
void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state)

@ -27,6 +27,11 @@ namespace MWWorld
* and individual type-dependent data.
*/
MWWorld::CellRef mRef;
/* Added by TES3MP to prevent dedicated players' references from automatically
* and unpredictably moving across exterior cell boundaries on clients
*/
bool canChangeCell;
/** runtime-data */
RefData mData;

@ -1141,7 +1141,7 @@ namespace MWWorld
bool haveToMove = isPlayer || (currCell && mWorldScene->isCellActive(*currCell));
MWWorld::Ptr newPtr = ptr;
if (currCell != newCell)
if (currCell != newCell && ptr.getBase()->canChangeCell)
{
removeContainerScripts(ptr);

Loading…
Cancel
Save