forked from teamnwah/openmw-tes3coop
[Client] Make LocalActor initialization include newly spawned Actors
This commit is contained in:
parent
79691254a4
commit
8d41a0c53b
6 changed files with 92 additions and 26 deletions
|
@ -8,6 +8,7 @@
|
|||
#include "Cell.hpp"
|
||||
#include "Main.hpp"
|
||||
#include "Networking.hpp"
|
||||
#include "LocalPlayer.hpp"
|
||||
#include "CellController.hpp"
|
||||
#include "MechanicsHelper.hpp"
|
||||
|
||||
|
@ -16,6 +17,7 @@ using namespace mwmp;
|
|||
mwmp::Cell::Cell(MWWorld::CellStore* cellStore)
|
||||
{
|
||||
store = cellStore;
|
||||
shouldInitializeActors = false;
|
||||
|
||||
std::map<std::string, LocalActor *> localActors;
|
||||
std::map<std::string, DedicatedActor *> dedicatedActors;
|
||||
|
@ -44,10 +46,7 @@ void Cell::updateLocal(bool forceUpdate)
|
|||
|
||||
Main::get().getCellController()->removeLocalActorRecord(it->first);
|
||||
|
||||
// If the cell this actor has moved to is active, initialize them in it
|
||||
if (Main::get().getCellController()->isInitializedCell(*newStore->getCell()))
|
||||
Main::get().getCellController()->getCell(*newStore->getCell())->initializeLocalActor(actor->getPtr());
|
||||
|
||||
delete actor;
|
||||
localActors.erase(it++);
|
||||
}
|
||||
else
|
||||
|
@ -280,6 +279,10 @@ void Cell::initializeLocalActors()
|
|||
// If this Ptr is lacking a unique index, ignore it
|
||||
if (ptr.getCellRef().getRefNum().mIndex == 0 && ptr.getCellRef().getMpNum() == 0) continue;
|
||||
|
||||
std::string mapIndex = Main::get().getCellController()->generateMapIndex(ptr);
|
||||
|
||||
// Only initialize this actor if it isn't already initialized
|
||||
if (localActors.count(mapIndex) == 0)
|
||||
initializeLocalActor(ptr);
|
||||
}
|
||||
}
|
||||
|
@ -352,6 +355,16 @@ DedicatedActor *Cell::getDedicatedActor(std::string actorIndex)
|
|||
return dedicatedActors.at(actorIndex);
|
||||
}
|
||||
|
||||
bool Cell::hasLocalAuthority()
|
||||
{
|
||||
return authorityGuid == Main::get().getLocalPlayer()->guid;
|
||||
}
|
||||
|
||||
void Cell::setAuthority(const RakNet::RakNetGUID& guid)
|
||||
{
|
||||
authorityGuid = guid;
|
||||
}
|
||||
|
||||
MWWorld::CellStore *Cell::getCellStore()
|
||||
{
|
||||
return store;
|
||||
|
|
|
@ -37,11 +37,18 @@ namespace mwmp
|
|||
virtual LocalActor *getLocalActor(std::string actorIndex);
|
||||
virtual DedicatedActor *getDedicatedActor(std::string actorIndex);
|
||||
|
||||
bool hasLocalAuthority();
|
||||
void setAuthority(const RakNet::RakNetGUID& guid);
|
||||
|
||||
MWWorld::CellStore* getCellStore();
|
||||
std::string getDescription();
|
||||
|
||||
bool shouldInitializeActors;
|
||||
|
||||
private:
|
||||
MWWorld::CellStore* store;
|
||||
RakNet::RakNetGUID authorityGuid;
|
||||
|
||||
std::map<std::string, LocalActor *> localActors;
|
||||
std::map<std::string, DedicatedActor *> dedicatedActors;
|
||||
};
|
||||
|
|
|
@ -24,6 +24,7 @@ mwmp::CellController::CellController()
|
|||
}
|
||||
void CellController::updateLocal(bool forceUpdate)
|
||||
{
|
||||
// Loop through Cells, deleting inactive ones and updating LocalActors in active ones
|
||||
for (std::map<std::string, mwmp::Cell *>::iterator it = cellsInitialized.begin(); it != cellsInitialized.end();)
|
||||
{
|
||||
mwmp::Cell *mpCell = it->second;
|
||||
|
@ -37,11 +38,24 @@ void CellController::updateLocal(bool forceUpdate)
|
|||
}
|
||||
else
|
||||
{
|
||||
//LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Updating mwmp::Cell %s", mpCell->getDescription().c_str());
|
||||
mpCell->updateLocal(forceUpdate);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through Cells and initialize new LocalActors for eligible ones
|
||||
//
|
||||
// Note: This cannot be combined with the above loop because initializing LocalActors in a Cell before they are
|
||||
// deleted from their previous one can make their records stay deleted
|
||||
for (std::map<std::string, mwmp::Cell *>::iterator it = cellsInitialized.begin(); it != cellsInitialized.end(); ++it)
|
||||
{
|
||||
mwmp::Cell *mpCell = it->second;
|
||||
if (mpCell->shouldInitializeActors == true)
|
||||
{
|
||||
mpCell->shouldInitializeActors = false;
|
||||
mpCell->initializeLocalActors();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CellController::updateDedicated(float dt)
|
||||
|
@ -70,20 +84,6 @@ void CellController::initializeCell(const ESM::Cell& cell)
|
|||
}
|
||||
}
|
||||
|
||||
void CellController::initializeLocalActors(const ESM::Cell& cell)
|
||||
{
|
||||
std::string mapIndex = cell.getDescription();
|
||||
|
||||
initializeCell(cell);
|
||||
|
||||
// If this now exists, initialize local actors in it
|
||||
if (cellsInitialized.count(mapIndex) > 0)
|
||||
{
|
||||
cellsInitialized[mapIndex]->uninitializeDedicatedActors();
|
||||
cellsInitialized[mapIndex]->initializeLocalActors();
|
||||
}
|
||||
}
|
||||
|
||||
void CellController::readPositions(ActorList& actorList)
|
||||
{
|
||||
std::string mapIndex = actorList.cell.getDescription();
|
||||
|
@ -279,6 +279,16 @@ std::string CellController::generateMapIndex(BaseActor baseActor)
|
|||
return generateMapIndex(baseActor.refId, baseActor.refNumIndex, baseActor.mpNum);
|
||||
}
|
||||
|
||||
bool CellController::hasLocalAuthority(const ESM::Cell& cell)
|
||||
{
|
||||
if (isInitializedCell(cell) && isActiveWorldCell(cell))
|
||||
{
|
||||
return getCell(cell)->hasLocalAuthority();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CellController::isInitializedCell(const ESM::Cell& cell)
|
||||
{
|
||||
return (cellsInitialized.count(cell.getDescription()) > 0);
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace mwmp
|
|||
void updateDedicated(float dt);
|
||||
|
||||
void initializeCell(const ESM::Cell& cell);
|
||||
void initializeLocalActors(const ESM::Cell& cell);
|
||||
|
||||
void readPositions(mwmp::ActorList& actorList);
|
||||
void readAnimFlags(mwmp::ActorList& actorList);
|
||||
|
@ -49,6 +48,7 @@ namespace mwmp
|
|||
std::string generateMapIndex(MWWorld::Ptr ptr);
|
||||
std::string generateMapIndex(mwmp::BaseActor baseActor);
|
||||
|
||||
bool hasLocalAuthority(const ESM::Cell& cell);
|
||||
bool isInitializedCell(const ESM::Cell& cell);
|
||||
bool isActiveWorldCell(const ESM::Cell& cell);
|
||||
virtual Cell *getCell(const ESM::Cell& cell);
|
||||
|
|
|
@ -23,15 +23,21 @@ namespace mwmp
|
|||
virtual void Do(ActorPacket &packet, ActorList &actorList)
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Received %s about %s", strPacketID.c_str(), actorList.cell.getDescription().c_str());
|
||||
mwmp::CellController *cellController = Main::get().getCellController();
|
||||
|
||||
// Never initialize LocalActors in a cell that is no longer loaded, if the server's packet arrived too late
|
||||
if (mwmp::Main::get().getCellController()->isActiveWorldCell(actorList.cell))
|
||||
if (cellController->isActiveWorldCell(actorList.cell))
|
||||
{
|
||||
cellController->initializeCell(actorList.cell);
|
||||
mwmp::Cell *cell = cellController->getCell(actorList.cell);
|
||||
cell->setAuthority(guid);
|
||||
|
||||
if (isLocal())
|
||||
{
|
||||
LOG_APPEND(Log::LOG_INFO, "- The new authority is me");
|
||||
Main::get().getCellController()->initializeLocalActors(actorList.cell);
|
||||
Main::get().getCellController()->getCell(actorList.cell)->updateLocal(true);
|
||||
cell->uninitializeDedicatedActors();
|
||||
cell->initializeLocalActors();
|
||||
cell->updateLocal(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -40,7 +46,7 @@ namespace mwmp
|
|||
if (player != 0)
|
||||
LOG_APPEND(Log::LOG_INFO, "- The new authority is %s", player->npc.mName.c_str());
|
||||
|
||||
Main::get().getCellController()->getCell(actorList.cell)->uninitializeLocalActors();
|
||||
cell->uninitializeLocalActors();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -5,6 +5,19 @@
|
|||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
Include additional headers for multiplayer purposes
|
||||
*/
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
#include "../mwmp/Main.hpp"
|
||||
#include "../mwmp/Networking.hpp"
|
||||
#include "../mwmp/CellController.hpp"
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
|
||||
#include <components/esm/cellstate.hpp>
|
||||
#include <components/esm/cellid.hpp>
|
||||
#include <components/esm/esmreader.hpp>
|
||||
|
@ -353,6 +366,23 @@ namespace MWWorld
|
|||
MergeVisitor visitor(mMergedRefs, mMovedHere, mMovedToAnotherCell);
|
||||
forEachInternal(visitor);
|
||||
visitor.merge();
|
||||
|
||||
/*
|
||||
Start of tes3mp addition
|
||||
|
||||
If the mwmp::Cell corresponding to this CellStore is under the authority of the LocalPlayer,
|
||||
prepare a new initialization of LocalActors in it
|
||||
|
||||
Warning: Don't directly use initializeLocalActors() from here because that will break any current
|
||||
cell transition that started in World::moveObject()
|
||||
*/
|
||||
if (mwmp::Main::get().getCellController()->hasLocalAuthority(*getCell()))
|
||||
{
|
||||
mwmp::Main::get().getCellController()->getCell(*getCell())->shouldInitializeActors = true;
|
||||
}
|
||||
/*
|
||||
End of tes3mp addition
|
||||
*/
|
||||
}
|
||||
|
||||
CellStore::CellStore (const ESM::Cell *cell, const MWWorld::ESMStore& esmStore, std::vector<ESM::ESMReader>& readerList)
|
||||
|
|
Loading…
Reference in a new issue