[Client] Make LocalActor initialization include newly spawned Actors

0.6.1
David Cernat 8 years ago
parent 79691254a4
commit 8d41a0c53b

@ -8,6 +8,7 @@
#include "Cell.hpp" #include "Cell.hpp"
#include "Main.hpp" #include "Main.hpp"
#include "Networking.hpp" #include "Networking.hpp"
#include "LocalPlayer.hpp"
#include "CellController.hpp" #include "CellController.hpp"
#include "MechanicsHelper.hpp" #include "MechanicsHelper.hpp"
@ -16,6 +17,7 @@ using namespace mwmp;
mwmp::Cell::Cell(MWWorld::CellStore* cellStore) mwmp::Cell::Cell(MWWorld::CellStore* cellStore)
{ {
store = cellStore; store = cellStore;
shouldInitializeActors = false;
std::map<std::string, LocalActor *> localActors; std::map<std::string, LocalActor *> localActors;
std::map<std::string, DedicatedActor *> dedicatedActors; std::map<std::string, DedicatedActor *> dedicatedActors;
@ -44,10 +46,7 @@ void Cell::updateLocal(bool forceUpdate)
Main::get().getCellController()->removeLocalActorRecord(it->first); Main::get().getCellController()->removeLocalActorRecord(it->first);
// If the cell this actor has moved to is active, initialize them in it delete actor;
if (Main::get().getCellController()->isInitializedCell(*newStore->getCell()))
Main::get().getCellController()->getCell(*newStore->getCell())->initializeLocalActor(actor->getPtr());
localActors.erase(it++); localActors.erase(it++);
} }
else else
@ -242,7 +241,7 @@ void Cell::readCellChange(ActorList& actorList)
actor->setCell(newStore); actor->setCell(newStore);
Main::get().getCellController()->removeDedicatedActorRecord(mapIndex); Main::get().getCellController()->removeDedicatedActorRecord(mapIndex);
// If the cell this actor has moved to is active, initialize them in it // If the cell this actor has moved to is active, initialize them in it
if (Main::get().getCellController()->isInitializedCell(actor->cell)) if (Main::get().getCellController()->isInitializedCell(actor->cell))
Main::get().getCellController()->getCell(actor->cell)->initializeDedicatedActor(actor->getPtr()); Main::get().getCellController()->getCell(actor->cell)->initializeDedicatedActor(actor->getPtr());
@ -280,7 +279,11 @@ void Cell::initializeLocalActors()
// If this Ptr is lacking a unique index, ignore it // If this Ptr is lacking a unique index, ignore it
if (ptr.getCellRef().getRefNum().mIndex == 0 && ptr.getCellRef().getMpNum() == 0) continue; if (ptr.getCellRef().getRefNum().mIndex == 0 && ptr.getCellRef().getMpNum() == 0) continue;
initializeLocalActor(ptr); 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); 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() MWWorld::CellStore *Cell::getCellStore()
{ {
return store; return store;

@ -37,11 +37,18 @@ namespace mwmp
virtual LocalActor *getLocalActor(std::string actorIndex); virtual LocalActor *getLocalActor(std::string actorIndex);
virtual DedicatedActor *getDedicatedActor(std::string actorIndex); virtual DedicatedActor *getDedicatedActor(std::string actorIndex);
bool hasLocalAuthority();
void setAuthority(const RakNet::RakNetGUID& guid);
MWWorld::CellStore* getCellStore(); MWWorld::CellStore* getCellStore();
std::string getDescription(); std::string getDescription();
bool shouldInitializeActors;
private: private:
MWWorld::CellStore* store; MWWorld::CellStore* store;
RakNet::RakNetGUID authorityGuid;
std::map<std::string, LocalActor *> localActors; std::map<std::string, LocalActor *> localActors;
std::map<std::string, DedicatedActor *> dedicatedActors; std::map<std::string, DedicatedActor *> dedicatedActors;
}; };

@ -24,6 +24,7 @@ mwmp::CellController::CellController()
} }
void CellController::updateLocal(bool forceUpdate) 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();) for (std::map<std::string, mwmp::Cell *>::iterator it = cellsInitialized.begin(); it != cellsInitialized.end();)
{ {
mwmp::Cell *mpCell = it->second; mwmp::Cell *mpCell = it->second;
@ -37,11 +38,24 @@ void CellController::updateLocal(bool forceUpdate)
} }
else else
{ {
//LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Updating mwmp::Cell %s", mpCell->getDescription().c_str());
mpCell->updateLocal(forceUpdate); mpCell->updateLocal(forceUpdate);
++it; ++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) 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) void CellController::readPositions(ActorList& actorList)
{ {
std::string mapIndex = actorList.cell.getDescription(); std::string mapIndex = actorList.cell.getDescription();
@ -279,6 +279,16 @@ std::string CellController::generateMapIndex(BaseActor baseActor)
return generateMapIndex(baseActor.refId, baseActor.refNumIndex, baseActor.mpNum); 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) bool CellController::isInitializedCell(const ESM::Cell& cell)
{ {
return (cellsInitialized.count(cell.getDescription()) > 0); return (cellsInitialized.count(cell.getDescription()) > 0);

@ -19,7 +19,6 @@ namespace mwmp
void updateDedicated(float dt); void updateDedicated(float dt);
void initializeCell(const ESM::Cell& cell); void initializeCell(const ESM::Cell& cell);
void initializeLocalActors(const ESM::Cell& cell);
void readPositions(mwmp::ActorList& actorList); void readPositions(mwmp::ActorList& actorList);
void readAnimFlags(mwmp::ActorList& actorList); void readAnimFlags(mwmp::ActorList& actorList);
@ -49,6 +48,7 @@ namespace mwmp
std::string generateMapIndex(MWWorld::Ptr ptr); std::string generateMapIndex(MWWorld::Ptr ptr);
std::string generateMapIndex(mwmp::BaseActor baseActor); std::string generateMapIndex(mwmp::BaseActor baseActor);
bool hasLocalAuthority(const ESM::Cell& cell);
bool isInitializedCell(const ESM::Cell& cell); bool isInitializedCell(const ESM::Cell& cell);
bool isActiveWorldCell(const ESM::Cell& cell); bool isActiveWorldCell(const ESM::Cell& cell);
virtual Cell *getCell(const ESM::Cell& cell); virtual Cell *getCell(const ESM::Cell& cell);

@ -23,15 +23,21 @@ namespace mwmp
virtual void Do(ActorPacket &packet, ActorList &actorList) 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()); 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 // 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()) if (isLocal())
{ {
LOG_APPEND(Log::LOG_INFO, "- The new authority is me"); LOG_APPEND(Log::LOG_INFO, "- The new authority is me");
Main::get().getCellController()->initializeLocalActors(actorList.cell); cell->uninitializeDedicatedActors();
Main::get().getCellController()->getCell(actorList.cell)->updateLocal(true); cell->initializeLocalActors();
cell->updateLocal(true);
} }
else else
{ {
@ -40,7 +46,7 @@ namespace mwmp
if (player != 0) if (player != 0)
LOG_APPEND(Log::LOG_INFO, "- The new authority is %s", player->npc.mName.c_str()); 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 else

@ -5,6 +5,19 @@
#include <iostream> #include <iostream>
#include <algorithm> #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/cellstate.hpp>
#include <components/esm/cellid.hpp> #include <components/esm/cellid.hpp>
#include <components/esm/esmreader.hpp> #include <components/esm/esmreader.hpp>
@ -353,6 +366,23 @@ namespace MWWorld
MergeVisitor visitor(mMergedRefs, mMovedHere, mMovedToAnotherCell); MergeVisitor visitor(mMergedRefs, mMovedHere, mMovedToAnotherCell);
forEachInternal(visitor); forEachInternal(visitor);
visitor.merge(); 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) CellStore::CellStore (const ESM::Cell *cell, const MWWorld::ESMStore& esmStore, std::vector<ESM::ESMReader>& readerList)

Loading…
Cancel
Save