mirror of
https://github.com/TES3MP/TES3MP.git
synced 2025-09-26 22:45:15 -04:00
[General] Allow followers to follow non-authority players through cells
This commit is contained in:
parent
ab5fd0aef8
commit
528bd26a3b
@ -17,14 +17,31 @@ namespace mwmp
|
|||||||
{
|
{
|
||||||
Cell *serverCell = CellController::get()->getCell(&actorList.cell);
|
Cell *serverCell = CellController::get()->getCell(&actorList.cell);
|
||||||
|
|
||||||
if (serverCell != nullptr && *serverCell->getAuthority() == actorList.guid)
|
if (serverCell != nullptr)
|
||||||
{
|
{
|
||||||
serverCell->removeActors(&actorList);
|
bool isFollowerCellChange = false;
|
||||||
|
|
||||||
Script::Call<Script::CallbackIdentity("OnActorCellChange")>(player.getId(), actorList.cell.getDescription().c_str());
|
// TODO: Move this check on the Lua side
|
||||||
|
for (unsigned int i = 0; i < actorList.count; i++)
|
||||||
|
{
|
||||||
|
if (actorList.baseActors.at(i).isFollowerCellChange)
|
||||||
|
{
|
||||||
|
isFollowerCellChange = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Send this to everyone
|
// Only accept regular cell changes from a cell's authority, but accept follower
|
||||||
packet.Send(true);
|
// cell changes from other players
|
||||||
|
if (*serverCell->getAuthority() == actorList.guid || isFollowerCellChange)
|
||||||
|
{
|
||||||
|
serverCell->removeActors(&actorList);
|
||||||
|
|
||||||
|
Script::Call<Script::CallbackIdentity("OnActorCellChange")>(player.getId(), actorList.cell.getDescription().c_str());
|
||||||
|
|
||||||
|
// Send this to everyone
|
||||||
|
packet.Send(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -72,6 +72,7 @@ void LocalActor::updateCell()
|
|||||||
|
|
||||||
cell = *ptr.getCell()->getCell();
|
cell = *ptr.getCell()->getCell();
|
||||||
position = ptr.getRefData().getPosition();
|
position = ptr.getRefData().getPosition();
|
||||||
|
isFollowerCellChange = false;
|
||||||
|
|
||||||
mwmp::Main::get().getNetworking()->getActorList()->addCellChangeActor(*this);
|
mwmp::Main::get().getNetworking()->getActorList()->addCellChangeActor(*this);
|
||||||
}
|
}
|
||||||
|
@ -351,7 +351,7 @@ namespace MWScript
|
|||||||
baseActor.aiTarget = MechanicsHelper::getTarget(targetPtr);
|
baseActor.aiTarget = MechanicsHelper::getTarget(targetPtr);
|
||||||
|
|
||||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Sending ID_ACTOR_AI about %s %i-%i to server",
|
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Sending ID_ACTOR_AI about %s %i-%i to server",
|
||||||
ptr.getCellRef().getRefId(), baseActor.refNum, baseActor.mpNum);
|
ptr.getCellRef().getRefId().c_str(), baseActor.refNum, baseActor.mpNum);
|
||||||
|
|
||||||
if (baseActor.aiTarget.isPlayer)
|
if (baseActor.aiTarget.isPlayer)
|
||||||
{
|
{
|
||||||
@ -361,7 +361,7 @@ namespace MWScript
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "- Following actor %s %i-%i",
|
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "- Following actor %s %i-%i",
|
||||||
targetPtr.getCellRef().getRefId(), baseActor.aiTarget.refNum, baseActor.aiTarget.mpNum);
|
targetPtr.getCellRef().getRefId().c_str(), baseActor.aiTarget.refNum, baseActor.aiTarget.mpNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
mwmp::ActorList *actorList = mwmp::Main::get().getNetworking()->getActorList();
|
mwmp::ActorList *actorList = mwmp::Main::get().getNetworking()->getActorList();
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <components/openmw-mp/Log.hpp>
|
#include <components/openmw-mp/Log.hpp>
|
||||||
#include "../mwbase/windowmanager.hpp"
|
#include "../mwbase/windowmanager.hpp"
|
||||||
#include "../mwmp/Main.hpp"
|
#include "../mwmp/Main.hpp"
|
||||||
|
#include "../mwmp/Networking.hpp"
|
||||||
|
#include "../mwmp/ActorList.hpp"
|
||||||
#include "../mwmp/CellController.hpp"
|
#include "../mwmp/CellController.hpp"
|
||||||
/*
|
/*
|
||||||
End of tes3mp addition
|
End of tes3mp addition
|
||||||
@ -41,17 +43,6 @@ namespace MWWorld
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
/*
|
|
||||||
Start of tes3mp addition
|
|
||||||
|
|
||||||
Update LocalActors before we unload their cells, so packets with their cell changes
|
|
||||||
can be sent
|
|
||||||
*/
|
|
||||||
mwmp::Main::get().getCellController()->updateLocal(true);
|
|
||||||
/*
|
|
||||||
End of tes3mp addition
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
teleport(actor);
|
teleport(actor);
|
||||||
@ -72,34 +63,78 @@ namespace MWWorld
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Start of tes3mp change (major)
|
Start of tes3mp addition
|
||||||
|
|
||||||
Only allow LocalActors to teleport across cells
|
Track the original cell of this actor so we can use it when sending a packet
|
||||||
*/
|
*/
|
||||||
if (!mwmp::Main::get().getCellController()->isLocalActor(actor))
|
ESM::Cell originalCell = *actor.getCell()->getCell();
|
||||||
{
|
|
||||||
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)
|
End of tes3mp addition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp change (minor)
|
||||||
|
|
||||||
|
If this is a DedicatedActor, get their new cell and override their stored cell with it
|
||||||
|
so their cell change is approved in World::moveObject()
|
||||||
|
*/
|
||||||
|
MWWorld::CellStore *newCellStore;
|
||||||
|
mwmp::CellController *cellController = mwmp::Main::get().getCellController();
|
||||||
|
|
||||||
if (mCellName.empty())
|
if (mCellName.empty())
|
||||||
{
|
{
|
||||||
int cellX;
|
int cellX;
|
||||||
int cellY;
|
int cellY;
|
||||||
world->positionToIndex(mPosition.pos[0],mPosition.pos[1],cellX,cellY);
|
world->positionToIndex(mPosition.pos[0],mPosition.pos[1],cellX,cellY);
|
||||||
|
|
||||||
|
newCellStore = world->getExterior(cellX, cellY);
|
||||||
|
if (cellController->isDedicatedActor(actor))
|
||||||
|
cellController->getDedicatedActor(actor)->cell = *newCellStore->getCell();
|
||||||
|
|
||||||
world->moveObject(actor,world->getExterior(cellX,cellY),
|
world->moveObject(actor,world->getExterior(cellX,cellY),
|
||||||
mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
|
mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
newCellStore = world->getInterior(mCellName);
|
||||||
|
if (cellController->isDedicatedActor(actor))
|
||||||
|
cellController->getDedicatedActor(actor)->cell = *newCellStore->getCell();
|
||||||
|
|
||||||
world->moveObject(actor,world->getInterior(mCellName),mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
|
world->moveObject(actor,world->getInterior(mCellName),mPosition.pos[0],mPosition.pos[1],mPosition.pos[2]);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Start of tes3mp change (minor)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Send ActorCellChange packets when an actor follows us across cells, regardless of
|
||||||
|
whether we're the cell authority or not; the server can decide if it wants to comply
|
||||||
|
with them
|
||||||
|
*/
|
||||||
|
mwmp::BaseActor baseActor;
|
||||||
|
baseActor.refNum = actor.getCellRef().getRefNum().mIndex;
|
||||||
|
baseActor.mpNum = actor.getCellRef().getMpNum();
|
||||||
|
baseActor.cell = *newCellStore->getCell();
|
||||||
|
baseActor.position = actor.getRefData().getPosition();
|
||||||
|
baseActor.isFollowerCellChange = true;
|
||||||
|
|
||||||
|
mwmp::ActorList *actorList = mwmp::Main::get().getNetworking()->getActorList();
|
||||||
|
actorList->reset();
|
||||||
|
actorList->cell = originalCell;
|
||||||
|
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Sending ID_ACTOR_CELL_CHANGE about %s %i-%i to server",
|
||||||
|
actor.getCellRef().getRefId().c_str(), baseActor.refNum, baseActor.mpNum);
|
||||||
|
|
||||||
|
LOG_APPEND(Log::LOG_INFO, "- Moved from %s to %s", actorList->cell.getDescription().c_str(),
|
||||||
|
baseActor.cell.getDescription().c_str());
|
||||||
|
|
||||||
|
actorList->addCellChangeActor(baseActor);
|
||||||
|
actorList->sendCellChangeActors();
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@ namespace mwmp
|
|||||||
|
|
||||||
Target killer;
|
Target killer;
|
||||||
|
|
||||||
|
bool isFollowerCellChange;
|
||||||
|
|
||||||
bool hasAiTarget;
|
bool hasAiTarget;
|
||||||
Target aiTarget;
|
Target aiTarget;
|
||||||
unsigned int aiAction;
|
unsigned int aiAction;
|
||||||
|
@ -16,4 +16,6 @@ void PacketActorCellChange::Actor(BaseActor &actor, bool send)
|
|||||||
|
|
||||||
RW(actor.position, send, true);
|
RW(actor.position, send, true);
|
||||||
RW(actor.direction, send, true);
|
RW(actor.direction, send, true);
|
||||||
|
|
||||||
|
RW(actor.isFollowerCellChange, send);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user