[Client] Fix interior-to-exterior and v.v. cell transitions for actors

Make sure only players who are cell authorities can get actors to teleport across cells for them, and display a message box for players who are not cell authorities.
This commit is contained in:
David Cernat 2018-06-21 16:44:49 +03:00
parent fd05beef94
commit 7e90d1f2a4
2 changed files with 26 additions and 5 deletions

View file

@ -204,14 +204,14 @@ bool CellController::isLocalActor(MWWorld::Ptr ptr)
std::string actorIndex = generateMapIndex(ptr); std::string actorIndex = generateMapIndex(ptr);
return (localActorsToCells.count(actorIndex) > 0 && isInitializedCell(localActorsToCells.at(actorIndex))); return localActorsToCells.count(actorIndex) > 0;
} }
bool CellController::isLocalActor(int refNumIndex, int mpNum) bool CellController::isLocalActor(int refNumIndex, int mpNum)
{ {
std::string actorIndex = generateMapIndex(refNumIndex, mpNum); std::string actorIndex = generateMapIndex(refNumIndex, mpNum);
return (localActorsToCells.count(actorIndex) > 0 && isInitializedCell(localActorsToCells.at(actorIndex))); return localActorsToCells.count(actorIndex) > 0;
} }
LocalActor *CellController::getLocalActor(MWWorld::Ptr ptr) LocalActor *CellController::getLocalActor(MWWorld::Ptr ptr)
@ -247,14 +247,14 @@ bool CellController::isDedicatedActor(MWWorld::Ptr ptr)
std::string actorIndex = generateMapIndex(ptr); std::string actorIndex = generateMapIndex(ptr);
return (dedicatedActorsToCells.count(actorIndex) > 0 && isInitializedCell(dedicatedActorsToCells.at(actorIndex))); return dedicatedActorsToCells.count(actorIndex) > 0;
} }
bool CellController::isDedicatedActor(int refNumIndex, int mpNum) bool CellController::isDedicatedActor(int refNumIndex, int mpNum)
{ {
std::string actorIndex = generateMapIndex(refNumIndex, mpNum); std::string actorIndex = generateMapIndex(refNumIndex, mpNum);
return (dedicatedActorsToCells.count(actorIndex) > 0 && isInitializedCell(dedicatedActorsToCells.at(actorIndex))); return dedicatedActorsToCells.count(actorIndex) > 0;
} }
DedicatedActor *CellController::getDedicatedActor(MWWorld::Ptr ptr) DedicatedActor *CellController::getDedicatedActor(MWWorld::Ptr ptr)

View file

@ -5,6 +5,8 @@
Include additional headers for multiplayer purposes Include additional headers for multiplayer purposes
*/ */
#include <components/openmw-mp/Log.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwmp/Main.hpp" #include "../mwmp/Main.hpp"
#include "../mwmp/CellController.hpp" #include "../mwmp/CellController.hpp"
/* /*
@ -46,7 +48,7 @@ namespace MWWorld
Update LocalActors before we unload their cells, so packets with their cell changes Update LocalActors before we unload their cells, so packets with their cell changes
can be sent can be sent
*/ */
mwmp::Main::get().getCellController()->updateLocal(false); mwmp::Main::get().getCellController()->updateLocal(true);
/* /*
End of tes3mp addition End of tes3mp addition
*/ */
@ -69,6 +71,25 @@ namespace MWWorld
} }
else else
{ {
/*
Start of tes3mp change (major)
Only allow LocalActors to teleport across cells
*/
if (!mwmp::Main::get().getCellController()->isLocalActor(actor))
{
MWBase::Environment::get().getWindowManager()->messageBox("That NPC can't follow you because their AI is running on another player's client.");
return;
}
else
{
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Teleporting actor %s-%i-%i to new cell", actor.getCellRef().getRefId().c_str(),
actor.getCellRef().getRefNum().mIndex, actor.getCellRef().getMpNum());
}
/*
End of tes3mp change (major)
*/
if (mCellName.empty()) if (mCellName.empty())
{ {
int cellX; int cellX;