[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 "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
@ -242,7 +241,7 @@ void Cell::readCellChange(ActorList& actorList)
actor->setCell(newStore);
Main::get().getCellController()->removeDedicatedActorRecord(mapIndex);
// If the cell this actor has moved to is active, initialize them in it
if (Main::get().getCellController()->isInitializedCell(actor->cell))
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 (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);
}
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…
Cancel
Save