diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index 25bc7188c..de9f2b261 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -1060,6 +1060,26 @@ void LocalPlayer::sendJournalIndex(const std::string& quest, int index) Main::get().getNetworking()->getPlayerPacket(ID_GAME_JOURNAL)->Send(this); } +void LocalPlayer::sendCellLoad(ESM::Cell cellLoaded) +{ + cellLoadChanges.cells.clear(); + + cellLoadChanges.cells.push_back(cellLoaded); + + cellLoadChanges.action = CellLoadChanges::LOAD; + Main::get().getNetworking()->getPlayerPacket(ID_PLAYER_CELL_LOAD)->Send(this); +} + +void LocalPlayer::sendCellUnload(ESM::Cell cellUnloaded) +{ + cellLoadChanges.cells.clear(); + + cellLoadChanges.cells.push_back(cellUnloaded); + + cellLoadChanges.action = CellLoadChanges::UNLOAD; + Main::get().getNetworking()->getPlayerPacket(ID_PLAYER_CELL_LOAD)->Send(this); +} + void LocalPlayer::sendAttack(Attack::TYPE type) { MWMechanics::DrawState_ state = getPlayerPtr().getClass().getNpcStats(getPlayerPtr()).getDrawState(); diff --git a/apps/openmw/mwmp/LocalPlayer.hpp b/apps/openmw/mwmp/LocalPlayer.hpp index 2627d05ee..c6f8492d0 100644 --- a/apps/openmw/mwmp/LocalPlayer.hpp +++ b/apps/openmw/mwmp/LocalPlayer.hpp @@ -63,6 +63,8 @@ namespace mwmp void sendSpellRemoval(const ESM::Spell &spell); void sendJournalEntry(const std::string& id, int index, const MWWorld::Ptr& actor); void sendJournalIndex(const std::string& id, int index); + void sendCellLoad(ESM::Cell cellLoaded); + void sendCellUnload(ESM::Cell cellUnloaded); void sendAttack(Attack::TYPE type); void prepareAttack(Attack::TYPE type, bool state); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 7061e4418..540b392f6 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -3,6 +3,9 @@ #include #include +#include "../mwmp/Main.hpp" +#include "../mwmp/LocalPlayer.hpp" + #include #include #include @@ -240,6 +243,11 @@ namespace MWWorld MWBase::Environment::get().getSoundManager()->stopSound (*iter); mActiveCells.erase(*iter); + + // Added by tes3mp + // + // LocalPlayer has unloaded a cell, so send a packet with it + mwmp::Main::get().getLocalPlayer()->sendCellUnload(*(*iter)->getCell()); } void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn) @@ -304,6 +312,11 @@ namespace MWWorld if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx)) mRendering.configureAmbient(cell->getCell()); + + // Added by tes3mp + // + // LocalPlayer has loaded a cell, so send a packet with it + mwmp::Main::get().getLocalPlayer()->sendCellLoad(*cell->getCell()); } mPreloader->notifyLoaded(cell); diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index c715f7b16..d5212af02 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -94,6 +94,20 @@ namespace mwmp int action; //0 - Clear and set in entirety, 1 - Add spell, 2 - Remove spell }; + struct CellLoadChanges + { + std::vector cells; + unsigned int count; + + enum ACTION_TYPE + { + LOAD = 0, + UNLOAD = 1 + }; + + int action; // 0 - Load a cell, 1 - Unload a cell + }; + class BasePlayer { public: @@ -143,6 +157,7 @@ namespace mwmp InventoryChanges inventoryChanges; SpellbookChanges spellbookChanges; JournalChanges journalChanges; + CellLoadChanges cellLoadChanges; bool consoleAllowed; bool ignorePosPacket; ESM::ActiveSpells activeSpells; diff --git a/components/openmw-mp/Packets/Player/PacketPlayerCellLoad.cpp b/components/openmw-mp/Packets/Player/PacketPlayerCellLoad.cpp index 3dc8af1cb..d38181d1d 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerCellLoad.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerCellLoad.cpp @@ -12,4 +12,33 @@ mwmp::PacketPlayerCellLoad::PacketPlayerCellLoad(RakNet::RakPeerInterface *peer) void mwmp::PacketPlayerCellLoad::Packet(RakNet::BitStream *bs, mwmp::BasePlayer *player, bool send) { PlayerPacket::Packet(bs, player, send); + + RW(player->cellLoadChanges.action, send); + + if (!send) + player->cellLoadChanges.cells.clear(); + else + player->cellLoadChanges.count = (unsigned int)(player->cellLoadChanges.cells.size()); + + RW(player->cellLoadChanges.count, send); + + for (unsigned int i = 0; i < player->cellLoadChanges.count; i++) + { + ESM::Cell cellLoaded; + + if (send) + { + cellLoaded = player->cellLoadChanges.cells[i]; + } + + RW(cellLoaded.mData.mFlags, send); + RW(cellLoaded.mData.mX, send); + RW(cellLoaded.mData.mY, send); + RW(cellLoaded.mName, send); + + if (!send) + { + player->cellLoadChanges.cells.push_back(cellLoaded); + } + } }