mirror of
https://github.com/TES3MP/TES3MP.git
synced 2025-10-02 09:31:12 -04:00
[General] Implement CellReset packet, stage 2
This commit is contained in:
parent
6cb4d5ec35
commit
c89efd251c
@ -3,6 +3,7 @@
|
|||||||
#include <apps/openmw-mp/Networking.hpp>
|
#include <apps/openmw-mp/Networking.hpp>
|
||||||
#include <apps/openmw-mp/Player.hpp>
|
#include <apps/openmw-mp/Player.hpp>
|
||||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||||
|
#include <apps/openmw-mp/CellController.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include <apps/openmw-mp/Utils.hpp>
|
#include <apps/openmw-mp/Utils.hpp>
|
||||||
@ -299,8 +300,29 @@ void WorldstateFunctions::SendCellReset(unsigned short pid, bool sendToOtherPlay
|
|||||||
writeWorldstate.guid = player->guid;
|
writeWorldstate.guid = player->guid;
|
||||||
|
|
||||||
packet->setWorldstate(&writeWorldstate);
|
packet->setWorldstate(&writeWorldstate);
|
||||||
|
|
||||||
packet->Send(sendToOtherPlayers);
|
packet->Send(sendToOtherPlayers);
|
||||||
|
|
||||||
|
if (sendToOtherPlayers)
|
||||||
|
{
|
||||||
|
packet->Send(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CellController * cellController = CellController::get();
|
||||||
|
|
||||||
|
for (ESM::Cell cell : writeWorldstate.cellsToReset)
|
||||||
|
{
|
||||||
|
if (sendToOtherPlayers)
|
||||||
|
{
|
||||||
|
TPlayers * players = Players::getPlayers();
|
||||||
|
for (TPlayers::iterator iter = players->begin(); iter != players->end(); iter++)
|
||||||
|
{
|
||||||
|
cellController->getCell(&cell)->removePlayer((*iter).second, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cellController->getCell(&cell)->removePlayer(Players::getPlayer(pid), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
\
|
\
|
||||||
{"AddCellToReset", WorldstateFunctions::AddCellToReset},\
|
{"AddCellToReset", WorldstateFunctions::AddCellToReset},\
|
||||||
{"ClearCellsToReset", WorldstateFunctions::ClearCellsToReset},\
|
{"ClearCellsToReset", WorldstateFunctions::ClearCellsToReset},\
|
||||||
{"SendCellsToReset", WorldstateFunctions::SendCellReset},\
|
{"SendCellReset", WorldstateFunctions::SendCellReset},\
|
||||||
\
|
\
|
||||||
{"ReadLastWorldstate", WorldstateFunctions::ReadLastWorldstate},\
|
{"ReadLastWorldstate", WorldstateFunctions::ReadLastWorldstate},\
|
||||||
{"CopyLastWorldstateToStore", WorldstateFunctions::CopyLastWorldstateToStore}
|
{"CopyLastWorldstateToStore", WorldstateFunctions::CopyLastWorldstateToStore}
|
||||||
|
@ -579,7 +579,17 @@ namespace MWBase
|
|||||||
|
|
||||||
Make it possible to check whether a cell is active
|
Make it possible to check whether a cell is active
|
||||||
*/
|
*/
|
||||||
virtual bool isCellActive(MWWorld::CellStore* cell) = 0;
|
virtual bool isCellActive(ESM::Cell cell) = 0;
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Make it possible to reload active cells (e.g. for CellReset)
|
||||||
|
*/
|
||||||
|
virtual void reloadCells(std::vector<ESM::Cell> * cells) = 0;
|
||||||
/*
|
/*
|
||||||
End of tes3mp addition
|
End of tes3mp addition
|
||||||
*/
|
*/
|
||||||
|
@ -35,7 +35,7 @@ void CellController::updateLocal(bool forceUpdate)
|
|||||||
{
|
{
|
||||||
mwmp::Cell *mpCell = it->second;
|
mwmp::Cell *mpCell = it->second;
|
||||||
|
|
||||||
if (!MWBase::Environment::get().getWorld()->isCellActive(mpCell->getCellStore()))
|
if (!MWBase::Environment::get().getWorld()->isCellActive(*(mpCell->getCellStore()->getCell())))
|
||||||
{
|
{
|
||||||
mpCell->uninitializeLocalActors();
|
mpCell->uninitializeLocalActors();
|
||||||
mpCell->uninitializeDedicatedActors();
|
mpCell->uninitializeDedicatedActors();
|
||||||
@ -312,11 +312,7 @@ bool CellController::isInitializedCell(const ESM::Cell& cell)
|
|||||||
|
|
||||||
bool CellController::isActiveWorldCell(const ESM::Cell& cell)
|
bool CellController::isActiveWorldCell(const ESM::Cell& cell)
|
||||||
{
|
{
|
||||||
MWWorld::CellStore *cellStore = getCellStore(cell);
|
return MWBase::Environment::get().getWorld()->isCellActive(cell);
|
||||||
|
|
||||||
if (!cellStore) return false;
|
|
||||||
|
|
||||||
return MWBase::Environment::get().getWorld()->isCellActive(cellStore);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Cell *CellController::getCell(const ESM::Cell& cell)
|
Cell *CellController::getCell(const ESM::Cell& cell)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define OPENMW_PROCESSORCELLRESET_HPP
|
#define OPENMW_PROCESSORCELLRESET_HPP
|
||||||
|
|
||||||
#include "../WorldstateProcessor.hpp"
|
#include "../WorldstateProcessor.hpp"
|
||||||
|
#include <apps/openmw/mwworld/player.hpp>
|
||||||
|
|
||||||
namespace mwmp
|
namespace mwmp
|
||||||
{
|
{
|
||||||
@ -16,19 +17,20 @@ namespace mwmp
|
|||||||
virtual void Do(WorldstatePacket &packet, Worldstate &worldstate)
|
virtual void Do(WorldstatePacket &packet, Worldstate &worldstate)
|
||||||
{
|
{
|
||||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Received ID_CELL_RESET");
|
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Received ID_CELL_RESET");
|
||||||
|
|
||||||
CellController* cellController = Main::get().getCellController();
|
CellController* cellController = Main::get().getCellController();
|
||||||
|
MWBase::World * world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
|
world->reloadCells(&worldstate.cellsToReset);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for (ESM::Cell cell : worldstate.cellsToReset)
|
/*for (ESM::Cell cell : worldstate.cellsToReset)
|
||||||
{
|
{
|
||||||
MWWorld::CellStore * cellStore = cellController->getCellStore(cell);
|
Main::get().getLocalPlayer()->storeCellState(cell, CellState::LOAD);
|
||||||
if (cellStore != nullptr)
|
|
||||||
{
|
|
||||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Resetting cell %s!", cell.getDescription().c_str());
|
|
||||||
cellStore->clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Attempted to reset an uninitialized cell %s!", cell.getDescription().c_str());
|
|
||||||
}
|
}
|
||||||
|
Main::get().getLocalPlayer()->sendCellStates();
|
||||||
|
Main::get().getLocalPlayer()->clearCellStates();*/
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -605,6 +605,41 @@ namespace MWWorld
|
|||||||
End of tes3mp addition
|
End of tes3mp addition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Make it possible to get mMovedHere in the CellStore from elsewhere in the code
|
||||||
|
*/
|
||||||
|
std::vector<Ptr> CellStore::getMovedHere()
|
||||||
|
{
|
||||||
|
std::vector<Ptr> hereVector;
|
||||||
|
for (CellStore::MovedRefTracker::iterator iter = mMovedHere.begin(); iter != mMovedHere.end(); ++iter)
|
||||||
|
{
|
||||||
|
hereVector.push_back(Ptr(iter->first, iter->second));
|
||||||
|
}
|
||||||
|
return hereVector;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Make it possible to return all NPCs back to this cell from elsewhere in the code
|
||||||
|
*/
|
||||||
|
void CellStore::returnFromOtherCells()
|
||||||
|
{
|
||||||
|
for (CellStore::MovedRefTracker::iterator iter = mMovedToAnotherCell.begin(); iter != mMovedToAnotherCell.end(); ++iter)
|
||||||
|
{
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Returning actor from %d, %d!", iter->second->getCell()->getGridX(), iter->second->getCell()->getGridY());
|
||||||
|
iter->second->moveTo(iter->first, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
float CellStore::getWaterLevel() const
|
float CellStore::getWaterLevel() const
|
||||||
{
|
{
|
||||||
if (isExterior())
|
if (isExterior())
|
||||||
@ -1198,7 +1233,6 @@ namespace MWWorld
|
|||||||
mBooks.mList.clear();
|
mBooks.mList.clear();
|
||||||
mClothes.mList.clear();
|
mClothes.mList.clear();
|
||||||
mContainers.mList.clear();
|
mContainers.mList.clear();
|
||||||
mCreatures.mList.clear();
|
|
||||||
mDoors.mList.clear();
|
mDoors.mList.clear();
|
||||||
mIngreds.mList.clear();
|
mIngreds.mList.clear();
|
||||||
mCreatureLists.mList.clear();
|
mCreatureLists.mList.clear();
|
||||||
@ -1206,13 +1240,30 @@ namespace MWWorld
|
|||||||
mLights.mList.clear();
|
mLights.mList.clear();
|
||||||
mLockpicks.mList.clear();
|
mLockpicks.mList.clear();
|
||||||
mMiscItems.mList.clear();
|
mMiscItems.mList.clear();
|
||||||
mNpcs.mList.clear();
|
|
||||||
mProbes.mList.clear();
|
mProbes.mList.clear();
|
||||||
mRepairs.mList.clear();
|
mRepairs.mList.clear();
|
||||||
mStatics.mList.clear();
|
mStatics.mList.clear();
|
||||||
mWeapons.mList.clear();
|
mWeapons.mList.clear();
|
||||||
mBodyParts.mList.clear();
|
mBodyParts.mList.clear();
|
||||||
|
|
||||||
|
mwmp::CellController * cellController = mwmp::Main::get().getCellController();
|
||||||
|
|
||||||
|
for (std::list<LiveCellRef<ESM::Creature>>::iterator ref = mCreatures.mList.begin(); ref != mCreatures.mList.end(); ref++)
|
||||||
|
{
|
||||||
|
if (!cellController->isDedicatedActor(MWWorld::Ptr(&*ref, this)))
|
||||||
|
{
|
||||||
|
mCreatures.mList.erase(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::list<LiveCellRef<ESM::NPC>>::iterator ref = mNpcs.mList.begin(); ref != mNpcs.mList.end(); ref++)
|
||||||
|
{
|
||||||
|
if (!cellController->isDedicatedActor(MWWorld::Ptr(&*ref, this)))
|
||||||
|
{
|
||||||
|
mNpcs.mList.erase(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mMovedHere.clear();
|
mMovedHere.clear();
|
||||||
mMovedToAnotherCell.clear();
|
mMovedToAnotherCell.clear();
|
||||||
mMergedRefs.clear();
|
mMergedRefs.clear();
|
||||||
|
@ -289,6 +289,26 @@ namespace MWWorld
|
|||||||
End of tes3mp addition
|
End of tes3mp addition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Make it possible to get the mContainers in the CellStore from elsewhere in the code
|
||||||
|
*/
|
||||||
|
std::vector<Ptr> getMovedHere();
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Make it possible to get mMovedHere in the CellStore from elsewhere in the code
|
||||||
|
*/
|
||||||
|
void returnFromOtherCells();
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
float getWaterLevel() const;
|
float getWaterLevel() const;
|
||||||
|
|
||||||
void setWaterLevel (float level);
|
void setWaterLevel (float level);
|
||||||
|
@ -2691,9 +2691,106 @@ namespace MWWorld
|
|||||||
|
|
||||||
Make it possible to check whether a cell is active
|
Make it possible to check whether a cell is active
|
||||||
*/
|
*/
|
||||||
bool World::isCellActive(MWWorld::CellStore* cell)
|
bool World::isCellActive(ESM::Cell cell)
|
||||||
{
|
{
|
||||||
return mWorldScene->isCellActive(*cell);
|
MWWorld::Scene::CellStoreCollection activeCells = (*mWorldScene).getActiveCells();
|
||||||
|
mwmp::CellController* cellController = mwmp::Main::get().getCellController();
|
||||||
|
for (MWWorld::Scene::CellStoreCollection::iterator iter = activeCells.begin(); iter != activeCells.end(); iter++)
|
||||||
|
{
|
||||||
|
ESM::Cell iterCell = *(*iter)->getCell();
|
||||||
|
if (cellController->isSameCell(iterCell, cell)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Make it possible to reload active cells (e.g. for CellReset)
|
||||||
|
*/
|
||||||
|
void World::reloadCells(std::vector<ESM::Cell> * cells)
|
||||||
|
{
|
||||||
|
mwmp::CellController* cellController = mwmp::Main::get().getCellController();
|
||||||
|
MWWorld::Scene::CellStoreCollection activeCells = (*mWorldScene).getActiveCells();
|
||||||
|
|
||||||
|
MWWorld::Scene::CellStoreCollection activeToReset;
|
||||||
|
|
||||||
|
for (MWWorld::Scene::CellStoreCollection::iterator iter = activeCells.begin(); iter != activeCells.end(); iter++)
|
||||||
|
{
|
||||||
|
ESM::Cell iterCell = *(*iter)->getCell();
|
||||||
|
for (ESM::Cell cell : *cells)
|
||||||
|
{
|
||||||
|
if (cellController->isSameCell(iterCell, cell))
|
||||||
|
{
|
||||||
|
activeToReset.insert(*iter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!activeToReset.empty())
|
||||||
|
{
|
||||||
|
typedef std::pair<Ptr, CellStore*> returnPtr;
|
||||||
|
std::map<Ptr, CellStore*> moveBack;
|
||||||
|
for (MWWorld::Scene::CellStoreCollection::iterator iter = activeToReset.begin(); iter != activeToReset.end(); iter++)
|
||||||
|
{
|
||||||
|
ESM::Cell iterCell = *(*iter)->getCell();
|
||||||
|
MWWorld::CellStore * cellStore = cellController->getCellStore(iterCell);
|
||||||
|
|
||||||
|
cellStore->returnFromOtherCells();
|
||||||
|
std::vector<Ptr> movedRefs = cellStore->getMovedHere();
|
||||||
|
for (Ptr ref : movedRefs)
|
||||||
|
{
|
||||||
|
moveBack.insert(returnPtr(ref, cellStore));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MWWorld::Scene::CellStoreCollection::iterator iter = activeCells.begin(); iter != activeCells.end(); iter++)
|
||||||
|
{
|
||||||
|
ESM::Cell iterCell = *(*iter)->getCell();
|
||||||
|
MWWorld::CellStore * cellStore = cellController->getCellStore(iterCell);
|
||||||
|
|
||||||
|
mWorldScene->unloadCell(iter);
|
||||||
|
cellController->getCell(iterCell)->uninitializeLocalActors();
|
||||||
|
cellController->getCell(iterCell)->uninitializeDedicatedActors();
|
||||||
|
|
||||||
|
if (activeToReset.count(*iter) > 0)
|
||||||
|
{
|
||||||
|
cellStore->clear();
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Resetting cell %s!", iterCell.getDescription().c_str());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ESM::CellId pCellId = getPlayerPtr().getCell()->getCell()->getCellId();
|
||||||
|
|
||||||
|
changeToCell(pCellId, getPlayerPtr().getRefData().getPosition(), false, true);
|
||||||
|
|
||||||
|
for (returnPtr ret : moveBack)
|
||||||
|
{
|
||||||
|
ret.first.getCell()->moveTo(ret.first, ret.second);
|
||||||
|
cellController->getCell(*ret.second->getCell())->initializeDedicatedActor(ret.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (ESM::Cell cell : *cells)
|
||||||
|
{
|
||||||
|
MWWorld::CellStore * cellStore = cellController->getCellStore(cell);
|
||||||
|
cellStore->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
End of tes3mp addition
|
End of tes3mp addition
|
||||||
|
@ -677,7 +677,17 @@ namespace MWWorld
|
|||||||
|
|
||||||
Make it possible to check whether a cell is active
|
Make it possible to check whether a cell is active
|
||||||
*/
|
*/
|
||||||
bool isCellActive(MWWorld::CellStore* cell) override;
|
bool isCellActive(ESM::Cell cell) override;
|
||||||
|
/*
|
||||||
|
End of tes3mp addition
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Start of tes3mp addition
|
||||||
|
|
||||||
|
Make it possible to reload active cells (e.g. for CellReset)
|
||||||
|
*/
|
||||||
|
void reloadCells(std::vector<ESM::Cell> * cells) override;
|
||||||
/*
|
/*
|
||||||
End of tes3mp addition
|
End of tes3mp addition
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user