From 4e86d8781f4ca9df491f6e0e59d2e79397026cf3 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 23 Apr 2017 13:31:06 +0300 Subject: [PATCH] [Client] Clean up & simplify logic for DedicatedPlayer cell transitions --- apps/openmw/mwmp/DedicatedPlayer.cpp | 23 +++++--------- apps/openmw/mwmp/DedicatedPlayer.hpp | 4 +-- apps/openmw/mwworld/livecellref.cpp | 9 ------ apps/openmw/mwworld/livecellref.hpp | 10 ------- apps/openmw/mwworld/worldimp.cpp | 45 +++++++++++++++++++++------- 5 files changed, 45 insertions(+), 46 deletions(-) diff --git a/apps/openmw/mwmp/DedicatedPlayer.cpp b/apps/openmw/mwmp/DedicatedPlayer.cpp index b17ef3dd9..e5d57dad2 100644 --- a/apps/openmw/mwmp/DedicatedPlayer.cpp +++ b/apps/openmw/mwmp/DedicatedPlayer.cpp @@ -148,9 +148,6 @@ void PlayerList::createPlayer(RakNet::RakNetGUID guid) { LOG_APPEND(Log::LOG_INFO, "- Updating reference pointer for %s", dedicPlayer->npc.mName.c_str()); - dedicPlayer->ptr.getBase()->canChangeCell = true; - dedicPlayer->updatePtr(world->moveObject(dedicPlayer->ptr, cellStore, spawnPos.pos[0], spawnPos.pos[1], spawnPos.pos[2])); - npc.mId = players[guid]->ptr.get()->mBase->mId; MWWorld::ESMStore *store = const_cast(&world->getStore()); @@ -158,6 +155,10 @@ void PlayerList::createPlayer(RakNet::RakNetGUID guid) esm_store->insert(npc); + // Disable Ptr to avoid graphical glitches caused by race changes + world->disable(players[guid]->ptr); + + dedicPlayer->setPtr(world->moveObject(dedicPlayer->ptr, cellStore, spawnPos.pos[0], spawnPos.pos[1], spawnPos.pos[2])); dedicPlayer->updateCell(); ESM::CustomMarker mEditingMarker = Main::get().getGUIController()->CreateMarker(guid); @@ -202,7 +203,6 @@ void PlayerList::disconnectPlayer(RakNet::RakNetGUID guid) newPos.pos[2] = 0; MWWorld::CellStore *cellStore = world->getExterior(0, 0); - players[guid]->getPtr().getBase()->canChangeCell = true; world->moveObject(players[guid]->getPtr(), cellStore, newPos.pos[0], newPos.pos[1], newPos.pos[2]); } } @@ -350,7 +350,7 @@ void DedicatedPlayer::updateCell() MWWorld::CellStore *cellStore; - LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Server says %s (%s) moved to %s", ptr.getBase()->mRef.getRefId().c_str(), + LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Server says DedicatedPlayer %s moved to %s", this->npc.mName.c_str(), cell.getDescription().c_str()); try @@ -371,8 +371,7 @@ void DedicatedPlayer::updateCell() // 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, position.pos[0], position.pos[1], position.pos[2])); + setPtr(world->moveObject(ptr, cellStore, position.pos[0], position.pos[1], position.pos[2])); // If this player is now in a cell that is active for us, we should send them all // NPC data in that cell @@ -435,13 +434,7 @@ MWWorld::ManualRef *DedicatedPlayer::getRef() return reference; } -void DedicatedPlayer::updatePtr(MWWorld::Ptr newPtr) +void DedicatedPlayer::setPtr(const 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; + ptr = newPtr; } diff --git a/apps/openmw/mwmp/DedicatedPlayer.hpp b/apps/openmw/mwmp/DedicatedPlayer.hpp index 428f5d597..d13a9d5d4 100644 --- a/apps/openmw/mwmp/DedicatedPlayer.hpp +++ b/apps/openmw/mwmp/DedicatedPlayer.hpp @@ -66,13 +66,13 @@ namespace mwmp MWWorld::Ptr getLiveCellPtr(); MWWorld::ManualRef* getRef(); + void setPtr(const MWWorld::Ptr& newPtr); + private: DedicatedPlayer(RakNet::RakNetGUID guid); virtual ~DedicatedPlayer(); - void updatePtr(MWWorld::Ptr newPtr); - int state; MWWorld::ManualRef* reference; diff --git a/apps/openmw/mwworld/livecellref.cpp b/apps/openmw/mwworld/livecellref.cpp index b0c4f63f9..294734f46 100644 --- a/apps/openmw/mwworld/livecellref.cpp +++ b/apps/openmw/mwworld/livecellref.cpp @@ -14,15 +14,6 @@ MWWorld::LiveCellRefBase::LiveCellRefBase(const std::string& type, const ESM::CellRef &cref) : mClass(&Class::get(type)), mRef(cref), mData(cref) { - /* - Start of tes3mp addition - - Set default values for tes3mp-only booleans - */ - canChangeCell = true; - /* - End of tes3mp addition - */ } void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state) diff --git a/apps/openmw/mwworld/livecellref.hpp b/apps/openmw/mwworld/livecellref.hpp index 493f2e4ca..2631f513f 100644 --- a/apps/openmw/mwworld/livecellref.hpp +++ b/apps/openmw/mwworld/livecellref.hpp @@ -27,16 +27,6 @@ namespace MWWorld * and individual type-dependent data. */ MWWorld::CellRef mRef; - - /* - Start of tes3mp addition - - Useful boolean for stopping momentum-based cell changes not approved by server - */ - bool canChangeCell; - /* - End of tes3mp addition - */ /** runtime-data */ RefData mData; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 44c13bd2a..8ee77b370 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -5,9 +5,19 @@ #include #include +/* + Start of tes3mp addition + + Include additional headers for multiplayer purposes +*/ #include "../mwmp/Main.hpp" #include "../mwmp/Networking.hpp" +#include "../mwmp/DedicatedPlayer.hpp" #include "../mwmp/WorldEvent.hpp" +#include "../mwmp/CellController.hpp" +/* + End of tes3mp addition +*/ #include #include @@ -1169,18 +1179,21 @@ namespace MWWorld bool isPlayer = ptr == mPlayer->getPlayer(); bool haveToMove = isPlayer || (currCell && mWorldScene->isCellActive(*currCell)); MWWorld::Ptr newPtr = ptr; - - // tes3mp debug start - if (currCell != newCell) { - - LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Tick: %s was %s move from %s to %s", ptr.getBase()->mRef.getRefId().c_str(), - ptr.getBase()->canChangeCell ? "allowed" : "denied", currCell->getCell()->getDescription().c_str(), - newCell->getCell()->getDescription().c_str()); - } - // tes3mp debug end - if (currCell != newCell && ptr.getBase()->canChangeCell) + if (currCell != newCell) { + /* + Start of tes3mp addition + + Check if DedicatedPlayer's new Ptr cell is the same as their packet cell, and deny the Ptr's cell change if it is not + */ + if (mwmp::PlayerList::isDedicatedPlayer(ptr) && + !mwmp::Main::get().getCellController()->isSameCell(mwmp::PlayerList::getPlayer(ptr)->cell, *newCell->getCell())) + return ptr; + /* + End of tes3mp addition + */ + removeContainerScripts(ptr); if (isPlayer) @@ -1245,6 +1258,17 @@ namespace MWWorld addContainerScripts (newPtr, newCell); } } + + /* + Start of tes3mp addition + + Update the Ptrs of DedicatedPlayers + */ + if (mwmp::PlayerList::isDedicatedPlayer(ptr)) + mwmp::PlayerList::getPlayer(ptr)->setPtr(newPtr); + /* + End of tes3mp addition + */ } } if (haveToMove && newPtr.getRefData().getBaseNode()) @@ -1257,6 +1281,7 @@ namespace MWWorld { mWorldScene->playerMoved(vec); } + return newPtr; }