From 4e2860f5789235ed798ee509b455d82c3d9b6fc8 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Thu, 21 Apr 2022 18:08:23 +0300 Subject: [PATCH] [General] Make mwscript's PositionCell send ActorCellChange packets Make server accept ActorCellChange packets for unloaded cells. --- .../actor/ProcessorActorCellChange.hpp | 20 ++++++--- .../mwscript/transformationextensions.cpp | 43 +++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/apps/openmw-mp/processors/actor/ProcessorActorCellChange.hpp b/apps/openmw-mp/processors/actor/ProcessorActorCellChange.hpp index 3edf48a97..e77698dd0 100644 --- a/apps/openmw-mp/processors/actor/ProcessorActorCellChange.hpp +++ b/apps/openmw-mp/processors/actor/ProcessorActorCellChange.hpp @@ -15,6 +15,7 @@ namespace mwmp void Do(ActorPacket &packet, Player &player, BaseActorList &actorList) override { + bool isAccepted = false; Cell *serverCell = CellController::get()->getCell(&actorList.cell); if (serverCell != nullptr) @@ -31,17 +32,26 @@ namespace mwmp } } - // Only accept regular cell changes from a cell's authority, but accept follower + // If the cell is loaded, only accept regular cell changes from a cell's authority, but accept follower // cell changes from other players if (*serverCell->getAuthority() == actorList.guid || isFollowerCellChange) { serverCell->removeActors(&actorList); + isAccepted = true; + } + } + // If the cell isn't loaded, the packet must be from dialogue or a script, so accept it + else + { + isAccepted = true; + } - Script::Call(player.getId(), actorList.cell.getShortDescription().c_str()); + if (isAccepted) + { + Script::Call(player.getId(), actorList.cell.getShortDescription().c_str()); - // Send this to everyone - packet.Send(true); - } + // Send this to everyone + packet.Send(true); } } }; diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index a03b662aa..31b6a988e 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -12,6 +12,7 @@ #include "../mwmp/LocalPlayer.hpp" #include "../mwmp/PlayerList.hpp" #include "../mwmp/ObjectList.hpp" +#include "../mwmp/CellController.hpp" #include "../mwmp/ScriptController.hpp" /* End of tes3mp addition @@ -443,10 +444,52 @@ namespace MWScript } if(store) { + /* + Start of tes3mp addition + + Track the original cell of this object in case we need to use it when sending a packet + */ + ESM::Cell originalCell = *ptr.getCell()->getCell(); + /* + End of tes3mp addition + */ + MWWorld::Ptr base = ptr; ptr = MWBase::Environment::get().getWorld()->moveObject(ptr,store,x,y,z); dynamic_cast(runtime.getContext()).updatePtr(base,ptr); + /* + Start of tes3mp addition + + Send ActorCellChange packets when actors are moved here, regardless of whether we're + the cell authority or not; the server can decide if it wants to comply with them + */ + if (ptr.getClass().isActor() && !mwmp::Main::get().getCellController()->isSameCell(originalCell, *store->getCell())) + { + mwmp::BaseActor baseActor; + baseActor.refNum = ptr.getCellRef().getRefNum().mIndex; + baseActor.mpNum = ptr.getCellRef().getMpNum(); + baseActor.cell = *store->getCell(); + baseActor.position = ptr.getRefData().getPosition(); + baseActor.isFollowerCellChange = true; + + mwmp::ActorList* actorList = mwmp::Main::get().getNetworking()->getActorList(); + actorList->reset(); + actorList->cell = originalCell; + + LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_ACTOR_CELL_CHANGE about %s %i-%i to server", + ptr.getCellRef().getRefId().c_str(), baseActor.refNum, baseActor.mpNum); + + LOG_APPEND(TimedLog::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 + */ + float ax = ptr.getRefData().getPosition().rot[0]; float ay = ptr.getRefData().getPosition().rot[1]; // Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south = 10800, west = 16200)