From c1427b2558feae58c3a622d36919c9bb078d5ce2 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Fri, 3 Feb 2017 20:27:40 +0200 Subject: [PATCH] [General] Simultaneously send loads & unloads in ID_PLAYER_CELL_STATE --- apps/openmw-mp/Networking.cpp | 2 +- apps/openmw-mp/Script/Functions/Cells.cpp | 10 ++++- apps/openmw-mp/Script/Functions/Cells.hpp | 2 + apps/openmw-mp/Script/ScriptFunctions.hpp | 2 +- apps/openmw/mwmp/LocalPlayer.cpp | 39 +++++++++---------- apps/openmw/mwmp/LocalPlayer.hpp | 7 +++- apps/openmw/mwworld/scene.cpp | 24 +++++++++--- components/openmw-mp/Base/BasePlayer.hpp | 23 ++++++----- .../Packets/Player/PacketPlayerCellState.cpp | 23 ++++++----- 9 files changed, 80 insertions(+), 52 deletions(-) diff --git a/apps/openmw-mp/Networking.cpp b/apps/openmw-mp/Networking.cpp index c9cf8d4ef..e364d0e11 100644 --- a/apps/openmw-mp/Networking.cpp +++ b/apps/openmw-mp/Networking.cpp @@ -180,7 +180,7 @@ void Networking::processPlayerPacket(RakNet::Packet *packet) myPacket->Read(player); - Script::Call(player->getId(), player->cellStateChanges.action); + Script::Call(player->getId()); break; } diff --git a/apps/openmw-mp/Script/Functions/Cells.cpp b/apps/openmw-mp/Script/Functions/Cells.cpp index 515054b56..507ffc7f4 100644 --- a/apps/openmw-mp/Script/Functions/Cells.cpp +++ b/apps/openmw-mp/Script/Functions/Cells.cpp @@ -16,6 +16,14 @@ unsigned int CellFunctions::GetCellStateChangesSize(unsigned short pid) noexcept return player->cellStateChanges.count; } +unsigned int CellFunctions::GetCellStateType(unsigned short pid, unsigned int i) noexcept +{ + Player *player; + GET_PLAYER(pid, player, 0); + + return player->cellStateChanges.cellStates.at(i).type; +} + const char *CellFunctions::GetCellStateDescription(unsigned short pid, unsigned int i) noexcept { Player *player; @@ -24,7 +32,7 @@ const char *CellFunctions::GetCellStateDescription(unsigned short pid, unsigned if (i >= player->cellStateChanges.count) return "invalid"; - string cellDescription = player->cellStateChanges.cells.at(i).getDescription(); + string cellDescription = player->cellStateChanges.cellStates.at(i).cell.getDescription(); static vector cstrDescription; cstrDescription.reserve(cellDescription.size() + 1); diff --git a/apps/openmw-mp/Script/Functions/Cells.hpp b/apps/openmw-mp/Script/Functions/Cells.hpp index a802a0b92..3110cb1d3 100644 --- a/apps/openmw-mp/Script/Functions/Cells.hpp +++ b/apps/openmw-mp/Script/Functions/Cells.hpp @@ -6,6 +6,7 @@ #define CELLAPI \ {"GetCellStateChangesSize", CellFunctions::GetCellStateChangesSize},\ \ + {"GetCellStateType", CellFunctions::GetCellStateType},\ {"GetCellStateDescription", CellFunctions::GetCellStateDescription},\ \ {"GetCell", CellFunctions::GetCell},\ @@ -23,6 +24,7 @@ class CellFunctions public: static unsigned int GetCellStateChangesSize(unsigned short pid) noexcept; + static unsigned int GetCellStateType(unsigned short pid, unsigned int i) noexcept; static const char *GetCellStateDescription(unsigned short pid, unsigned int i) noexcept; static const char *GetCell(unsigned short pid) noexcept; diff --git a/apps/openmw-mp/Script/ScriptFunctions.hpp b/apps/openmw-mp/Script/ScriptFunctions.hpp index 63dde0d90..0412ad10e 100644 --- a/apps/openmw-mp/Script/ScriptFunctions.hpp +++ b/apps/openmw-mp/Script/ScriptFunctions.hpp @@ -109,7 +109,7 @@ public: {"OnPlayerDeath", Function()}, {"OnPlayerResurrect", Function()}, {"OnPlayerCellChange", Function()}, - {"OnPlayerCellState", Function()}, + {"OnPlayerCellState", Function()}, {"OnPlayerAttributesChange", Function()}, {"OnPlayerSkillsChange", Function()}, {"OnPlayerLevelChange", Function()}, diff --git a/apps/openmw/mwmp/LocalPlayer.cpp b/apps/openmw/mwmp/LocalPlayer.cpp index 71094cdb8..838d8bf44 100644 --- a/apps/openmw/mwmp/LocalPlayer.cpp +++ b/apps/openmw/mwmp/LocalPlayer.cpp @@ -1000,6 +1000,11 @@ void LocalPlayer::sendSpellbook() Main::get().getNetworking()->getPlayerPacket(ID_GAME_SPELLBOOK)->Send(this); } +void LocalPlayer::sendCellStates() +{ + Main::get().getNetworking()->getPlayerPacket(ID_PLAYER_CELL_STATE)->Send(this); +} + void LocalPlayer::sendSpellAddition(std::string id) { if (id.find("$dynamic") != string::npos) // skip custom spells @@ -1072,26 +1077,6 @@ void LocalPlayer::sendJournalIndex(const std::string& quest, int index) Main::get().getNetworking()->getPlayerPacket(ID_GAME_JOURNAL)->Send(this); } -void LocalPlayer::sendCellLoad(ESM::Cell cellLoaded) -{ - cellStateChanges.cells.clear(); - - cellStateChanges.cells.push_back(cellLoaded); - - cellStateChanges.action = CellStateChanges::LOAD; - Main::get().getNetworking()->getPlayerPacket(ID_PLAYER_CELL_STATE)->Send(this); -} - -void LocalPlayer::sendCellUnload(ESM::Cell cellUnloaded) -{ - cellStateChanges.cells.clear(); - - cellStateChanges.cells.push_back(cellUnloaded); - - cellStateChanges.action = CellStateChanges::UNLOAD; - Main::get().getNetworking()->getPlayerPacket(ID_PLAYER_CELL_STATE)->Send(this); -} - void LocalPlayer::sendAttack(Attack::TYPE type) { MWMechanics::DrawState_ state = getPlayerPtr().getClass().getNpcStats(getPlayerPtr()).getDrawState(); @@ -1103,6 +1088,20 @@ void LocalPlayer::sendAttack(Attack::TYPE type) getNetworking()->sendData(&bs); } +void LocalPlayer::clearCellStates() +{ + cellStateChanges.cellStates.clear(); +} + +void LocalPlayer::storeCellState(ESM::Cell cell, int stateType) +{ + CellState cellState; + cellState.cell = cell; + cellState.type = stateType; + + cellStateChanges.cellStates.push_back(cellState); +} + void LocalPlayer::prepareAttack(Attack::TYPE type, bool state) { if (attack.pressed == state && type != Attack::MAGIC) diff --git a/apps/openmw/mwmp/LocalPlayer.hpp b/apps/openmw/mwmp/LocalPlayer.hpp index 85afc587d..7f4e82e43 100644 --- a/apps/openmw/mwmp/LocalPlayer.hpp +++ b/apps/openmw/mwmp/LocalPlayer.hpp @@ -58,16 +58,19 @@ namespace mwmp void sendClass(); void sendInventory(); void sendSpellbook(); + void sendCellStates(); void sendSpellAddition(std::string id); void sendSpellAddition(const ESM::Spell &spell); void sendSpellRemoval(std::string id); 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 clearCellStates(); + + void storeCellState(ESM::Cell cell, int stateType); + void prepareAttack(Attack::TYPE type, bool state); private: diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index abd11aaa7..2932aac2c 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -246,9 +246,8 @@ namespace MWWorld // Added by tes3mp // - // LocalPlayer has unloaded a cell, so send a packet with it, but only if CharGen is over - if (mwmp::Main::get().getLocalPlayer()->hasFinishedCharGen()) - mwmp::Main::get().getLocalPlayer()->sendCellUnload(*(*iter)->getCell()); + // LocalPlayer has unloaded a cell, so store it + mwmp::Main::get().getLocalPlayer()->storeCellState(*(*iter)->getCell(), 1); } void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener, bool respawn) @@ -316,9 +315,8 @@ namespace MWWorld // Added by tes3mp // - // LocalPlayer has loaded a cell, so send a packet with it, but only if CharGen is over - if (mwmp::Main::get().getLocalPlayer()->hasFinishedCharGen()) - mwmp::Main::get().getLocalPlayer()->sendCellLoad(*cell->getCell()); + // LocalPlayer has loaded a cell, so store it + mwmp::Main::get().getLocalPlayer()->storeCellState(*cell->getCell(), 0); } mPreloader->notifyLoaded(cell); @@ -356,6 +354,9 @@ namespace MWWorld void Scene::changeCellGrid (int X, int Y, bool changeEvent) { + // Added by tes3mp + mwmp::Main::get().getLocalPlayer()->clearCellStates(); + Loading::Listener* loadingListener = MWBase::Environment::get().getWindowManager()->getLoadingScreen(); Loading::ScopedLoad load(loadingListener); @@ -433,6 +434,10 @@ namespace MWWorld } } + // Added by tes3mp + if (mwmp::Main::get().getLocalPlayer()->hasFinishedCharGen()) + mwmp::Main::get().getLocalPlayer()->sendCellStates(); + CellStore* current = MWBase::Environment::get().getWorld()->getExterior(X,Y); MWBase::Environment::get().getWindowManager()->changeCell(current); @@ -512,6 +517,9 @@ namespace MWWorld void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent) { + // Added by tes3mp + mwmp::Main::get().getLocalPlayer()->clearCellStates(); + CellStore *cell = MWBase::Environment::get().getWorld()->getInterior(cellName); bool loadcell = (mCurrentCell == NULL); if(!loadcell) @@ -559,6 +567,10 @@ namespace MWWorld // Load cell. loadCell (cell, loadingListener, changeEvent); + // Added by tes3mp + if (mwmp::Main::get().getLocalPlayer()->hasFinishedCharGen()) + mwmp::Main::get().getLocalPlayer()->sendCellStates(); + changePlayerCell(cell, position, adjustPlayerPos); // adjust fog diff --git a/components/openmw-mp/Base/BasePlayer.hpp b/components/openmw-mp/Base/BasePlayer.hpp index c00079e75..dea0a9954 100644 --- a/components/openmw-mp/Base/BasePlayer.hpp +++ b/components/openmw-mp/Base/BasePlayer.hpp @@ -62,6 +62,19 @@ namespace mwmp int type; // 0 - An entire entry, 1 - An index }; + struct CellState + { + ESM::Cell cell; + + enum CELl_STATE_ACTION + { + LOAD = 0, + UNLOAD = 1 + }; + + int type; // 0 - Cell load, 1 - Cell unload + }; + struct JournalChanges { std::vector journalItems; @@ -96,16 +109,8 @@ namespace mwmp struct CellStateChanges { - std::vector cells; + std::vector cellStates; unsigned int count; - - enum ACTION_TYPE - { - LOAD = 0, - UNLOAD = 1 - }; - - int action; // 0 - Load a cell, 1 - Unload a cell }; class BasePlayer diff --git a/components/openmw-mp/Packets/Player/PacketPlayerCellState.cpp b/components/openmw-mp/Packets/Player/PacketPlayerCellState.cpp index c910fa1b9..1c6a6038a 100644 --- a/components/openmw-mp/Packets/Player/PacketPlayerCellState.cpp +++ b/components/openmw-mp/Packets/Player/PacketPlayerCellState.cpp @@ -13,32 +13,31 @@ void mwmp::PacketPlayerCellState::Packet(RakNet::BitStream *bs, mwmp::BasePlayer { PlayerPacket::Packet(bs, player, send); - RW(player->cellStateChanges.action, send); - if (!send) - player->cellStateChanges.cells.clear(); + player->cellStateChanges.cellStates.clear(); else - player->cellStateChanges.count = (unsigned int)(player->cellStateChanges.cells.size()); + player->cellStateChanges.count = (unsigned int)(player->cellStateChanges.cellStates.size()); RW(player->cellStateChanges.count, send); for (unsigned int i = 0; i < player->cellStateChanges.count; i++) { - ESM::Cell cell; + CellState cellState; if (send) { - cell = player->cellStateChanges.cells[i]; + cellState = player->cellStateChanges.cellStates[i]; } - - RW(cell.mData.mFlags, send); - RW(cell.mData.mX, send); - RW(cell.mData.mY, send); - RW(cell.mName, send); + + RW(cellState.type, send); + RW(cellState.cell.mData.mFlags, send); + RW(cellState.cell.mData.mX, send); + RW(cellState.cell.mData.mY, send); + RW(cellState.cell.mName, send); if (!send) { - player->cellStateChanges.cells.push_back(cell); + player->cellStateChanges.cellStates.push_back(cellState); } } }