[General] Make mwscript's PositionCell send ActorCellChange packets

Make server accept ActorCellChange packets for unloaded cells.
0.8.0
David Cernat 3 years ago
parent aa92128cf2
commit 4e2860f578

@ -15,6 +15,7 @@ namespace mwmp
void Do(ActorPacket &packet, Player &player, BaseActorList &actorList) override void Do(ActorPacket &packet, Player &player, BaseActorList &actorList) override
{ {
bool isAccepted = false;
Cell *serverCell = CellController::get()->getCell(&actorList.cell); Cell *serverCell = CellController::get()->getCell(&actorList.cell);
if (serverCell != nullptr) if (serverCell != nullptr)
@ -31,19 +32,28 @@ 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 // cell changes from other players
if (*serverCell->getAuthority() == actorList.guid || isFollowerCellChange) if (*serverCell->getAuthority() == actorList.guid || isFollowerCellChange)
{ {
serverCell->removeActors(&actorList); 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;
}
if (isAccepted)
{
Script::Call<Script::CallbackIdentity("OnActorCellChange")>(player.getId(), actorList.cell.getShortDescription().c_str()); Script::Call<Script::CallbackIdentity("OnActorCellChange")>(player.getId(), actorList.cell.getShortDescription().c_str());
// Send this to everyone // Send this to everyone
packet.Send(true); packet.Send(true);
} }
} }
}
}; };
} }

@ -12,6 +12,7 @@
#include "../mwmp/LocalPlayer.hpp" #include "../mwmp/LocalPlayer.hpp"
#include "../mwmp/PlayerList.hpp" #include "../mwmp/PlayerList.hpp"
#include "../mwmp/ObjectList.hpp" #include "../mwmp/ObjectList.hpp"
#include "../mwmp/CellController.hpp"
#include "../mwmp/ScriptController.hpp" #include "../mwmp/ScriptController.hpp"
/* /*
End of tes3mp addition End of tes3mp addition
@ -443,10 +444,52 @@ namespace MWScript
} }
if(store) 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; MWWorld::Ptr base = ptr;
ptr = MWBase::Environment::get().getWorld()->moveObject(ptr,store,x,y,z); ptr = MWBase::Environment::get().getWorld()->moveObject(ptr,store,x,y,z);
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(base,ptr); dynamic_cast<MWScript::InterpreterContext&>(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 ax = ptr.getRefData().getPosition().rot[0];
float ay = ptr.getRefData().getPosition().rot[1]; 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) // Note that you must specify ZRot in minutes (1 degree = 60 minutes; north = 0, east = 5400, south = 10800, west = 16200)

Loading…
Cancel
Save