forked from teamnwah/openmw-tes3coop
[Client] Streamline creation of references for DedicatedPlayers
Additionally, delete DedicatedPlayers who disconnect. Previously, all disconnected DedicatedPlayers were still kept in memory, but never used again. There was code that suggested they were meant to be reused upon reconnecting, but that reuse had never actually been implemented, and would probably not be that useful anyway.
This commit is contained in:
parent
14f90e773d
commit
141eb8b7c2
5 changed files with 39 additions and 139 deletions
|
@ -46,6 +46,10 @@ DedicatedPlayer::DedicatedPlayer(RakNet::RakNetGUID guid) : BasePlayer(guid)
|
||||||
creatureStats.mDead = false;
|
creatureStats.mDead = false;
|
||||||
movementFlags = 0;
|
movementFlags = 0;
|
||||||
attack.instant = false;
|
attack.instant = false;
|
||||||
|
|
||||||
|
cell.blank();
|
||||||
|
position.pos[0] = position.pos[1] = Main::get().getCellController()->getCellSize() / 2;
|
||||||
|
position.pos[2] = 0;
|
||||||
}
|
}
|
||||||
DedicatedPlayer::~DedicatedPlayer()
|
DedicatedPlayer::~DedicatedPlayer()
|
||||||
{
|
{
|
||||||
|
@ -94,7 +98,7 @@ void DedicatedPlayer::update(float dt)
|
||||||
|
|
||||||
void DedicatedPlayer::move(float dt)
|
void DedicatedPlayer::move(float dt)
|
||||||
{
|
{
|
||||||
if (state != 2) return;
|
if (!reference) return;
|
||||||
|
|
||||||
ESM::Position refPos = ptr.getRefData().getPosition();
|
ESM::Position refPos = ptr.getRefData().getPosition();
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
@ -151,31 +155,26 @@ void DedicatedPlayer::setBaseInfo()
|
||||||
tempNpc = getNpcRecord();
|
tempNpc = getNpcRecord();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool reset = false;
|
|
||||||
if (reference)
|
if (reference)
|
||||||
{
|
{
|
||||||
deleteReference();
|
deleteReference();
|
||||||
reset = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == 0)
|
createReference(tempNpc, tempCreature);
|
||||||
{
|
|
||||||
createReference(tempNpc, tempCreature, reset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
updateReference(tempNpc, tempCreature);
|
|
||||||
}
|
|
||||||
|
|
||||||
state = 2;
|
// Give this new character a temporary high fatigue of at least 1 so it doesn't
|
||||||
|
// spawn on the ground
|
||||||
// Give this new character a fatigue of at least 1 so it doesn't spawn
|
creatureStats.mDynamic[2].mBase = 1000;
|
||||||
// on the ground
|
|
||||||
creatureStats.mDynamic[2].mBase = 1;
|
|
||||||
|
|
||||||
world->enable(ptr);
|
world->enable(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DedicatedPlayer::setShapeshift()
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld()->scaleObject(ptr, scale);
|
||||||
|
MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, isWerewolf);
|
||||||
|
}
|
||||||
|
|
||||||
void DedicatedPlayer::setAnimFlags()
|
void DedicatedPlayer::setAnimFlags()
|
||||||
{
|
{
|
||||||
using namespace MWMechanics;
|
using namespace MWMechanics;
|
||||||
|
@ -250,9 +249,8 @@ void DedicatedPlayer::setEquipment()
|
||||||
|
|
||||||
void DedicatedPlayer::setCell()
|
void DedicatedPlayer::setCell()
|
||||||
{
|
{
|
||||||
// Prevent cell update when player hasn't been instantiated yet
|
// Prevent cell update when reference doesn't exist
|
||||||
if (state == 0)
|
if (!reference) return;
|
||||||
return;
|
|
||||||
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
|
@ -287,12 +285,6 @@ void DedicatedPlayer::setCell()
|
||||||
Main::get().getCellController()->getCell(cell)->updateLocal(true);
|
Main::get().getCellController()->getCell(cell)->updateLocal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DedicatedPlayer::setShapeshift()
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWorld()->scaleObject(ptr, scale);
|
|
||||||
MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, isWerewolf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DedicatedPlayer::updateMarker()
|
void DedicatedPlayer::updateMarker()
|
||||||
{
|
{
|
||||||
if (!markerEnabled)
|
if (!markerEnabled)
|
||||||
|
@ -388,122 +380,43 @@ ESM::NPC DedicatedPlayer::getNpcRecord()
|
||||||
return newNpc;
|
return newNpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DedicatedPlayer::createReference(ESM::NPC& npc, ESM::Creature& creature, bool reset)
|
void DedicatedPlayer::createReference(ESM::NPC& npc, ESM::Creature& creature)
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
// Temporarily spawn or move player to the center of exterior 0, 0
|
string recId;
|
||||||
ESM::Position spawnPos;
|
|
||||||
spawnPos.pos[0] = spawnPos.pos[1] = Main::get().getCellController()->getCellSize() / 2;
|
|
||||||
spawnPos.pos[2] = 0;
|
|
||||||
MWWorld::CellStore *cellStore = world->getExterior(0, 0);
|
|
||||||
|
|
||||||
string recid;
|
|
||||||
if (creatureRefId.empty())
|
if (creatureRefId.empty())
|
||||||
{
|
{
|
||||||
LOG_APPEND(Log::LOG_INFO, "- Creating new NPC record");
|
LOG_APPEND(Log::LOG_INFO, "- Creating new NPC record");
|
||||||
npc.mId = "Dedicated Player";
|
npc.mId = "Dedicated Player";
|
||||||
recid = world->createRecord(npc)->mId;
|
recId = world->createRecord(npc)->mId;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_APPEND(Log::LOG_INFO, "- Creating new Creature record");
|
LOG_APPEND(Log::LOG_INFO, "- Creating new Creature record");
|
||||||
creature.mId = "Dedicated Player";
|
creature.mId = "Dedicated Player";
|
||||||
recid = world->createRecord(creature)->mId;
|
recId = world->createRecord(creature)->mId;
|
||||||
}
|
}
|
||||||
|
|
||||||
reference = new MWWorld::ManualRef(world->getStore(), recid, 1);
|
reference = new MWWorld::ManualRef(world->getStore(), recId, 1);
|
||||||
|
|
||||||
LOG_APPEND(Log::LOG_INFO, "- Creating new reference pointer for %s", this->npc.mName.c_str());
|
LOG_APPEND(Log::LOG_INFO, "- Creating new reference pointer for %s", this->npc.mName.c_str());
|
||||||
|
|
||||||
MWWorld::Ptr tmp;
|
ptr = world->placeObject(reference->getPtr(), Main::get().getCellController()->getCellStore(cell), position);
|
||||||
|
|
||||||
if (reset)
|
|
||||||
{
|
|
||||||
if (cell.isExterior())
|
|
||||||
cellStore = world->getExterior(cell.mData.mX, cell.mData.mY);
|
|
||||||
else
|
|
||||||
cellStore = world->getInterior(cell.mName);
|
|
||||||
|
|
||||||
spawnPos = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = world->placeObject(reference->getPtr(), cellStore, spawnPos);
|
|
||||||
|
|
||||||
ptr.mCell = tmp.mCell;
|
|
||||||
ptr.mRef = tmp.mRef;
|
|
||||||
|
|
||||||
if (!reset)
|
|
||||||
{
|
|
||||||
cell = *ptr.getCell()->getCell();
|
|
||||||
position = ptr.getRefData().getPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
ESM::CustomMarker mEditingMarker = Main::get().getGUIController()->createMarker(guid);
|
ESM::CustomMarker mEditingMarker = Main::get().getGUIController()->createMarker(guid);
|
||||||
marker = mEditingMarker;
|
marker = mEditingMarker;
|
||||||
setMarkerState(true);
|
setMarkerState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DedicatedPlayer::updateReference(ESM::NPC& npc, ESM::Creature& creature)
|
|
||||||
{
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
|
||||||
|
|
||||||
// Temporarily spawn or move player to the center of exterior 0, 0
|
|
||||||
ESM::Position spawnPos;
|
|
||||||
spawnPos.pos[0] = spawnPos.pos[1] = Main::get().getCellController()->getCellSize() / 2;
|
|
||||||
spawnPos.pos[2] = 0;
|
|
||||||
MWWorld::CellStore *cellStore = world->getExterior(0, 0);
|
|
||||||
|
|
||||||
LOG_APPEND(Log::LOG_INFO, "- Updating reference pointer for %s", npc.mName.c_str());
|
|
||||||
|
|
||||||
MWWorld::ESMStore *store = const_cast<MWWorld::ESMStore *>(&world->getStore());
|
|
||||||
MWWorld::Store<ESM::Creature> *creature_store = const_cast<MWWorld::Store<ESM::Creature> *> (&store->get<ESM::Creature>());
|
|
||||||
MWWorld::Store<ESM::NPC> *npc_store = const_cast<MWWorld::Store<ESM::NPC> *> (&store->get<ESM::NPC>());
|
|
||||||
|
|
||||||
if (!creatureRefId.empty())
|
|
||||||
{
|
|
||||||
if (!npc.mId.empty() || npc.mId != "Dedicated Player")
|
|
||||||
{
|
|
||||||
LOG_APPEND(Log::LOG_INFO, "- Deleting NPC record");
|
|
||||||
npc_store->erase(npc.mId);
|
|
||||||
npc.mId.clear();
|
|
||||||
}
|
|
||||||
creature.mId = ptr.get<ESM::Creature>()->mBase->mId;
|
|
||||||
creature_store->insert(creature);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!creature.mId.empty() || creature.mId != "Dedicated Player")
|
|
||||||
{
|
|
||||||
LOG_APPEND(Log::LOG_INFO, "- Deleting Creature record");
|
|
||||||
creature_store->erase(creature.mId);
|
|
||||||
creature.mId.clear();
|
|
||||||
}
|
|
||||||
npc.mId = ptr.get<ESM::NPC>()->mBase->mId;
|
|
||||||
npc_store->insert(npc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable Ptr to avoid graphical glitches caused by race changes
|
|
||||||
world->disable(ptr);
|
|
||||||
|
|
||||||
setPtr(world->moveObject(ptr, cellStore, spawnPos.pos[0], spawnPos.pos[1], spawnPos.pos[2]));
|
|
||||||
setCell();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DedicatedPlayer::deleteReference()
|
void DedicatedPlayer::deleteReference()
|
||||||
{
|
{
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
|
||||||
bool isNPC = reference->getPtr().getTypeName() == typeid(ESM::NPC).name();
|
LOG_APPEND(Log::LOG_INFO, "- Deleting reference");
|
||||||
if ((!creatureRefId.empty() && isNPC) ||
|
|
||||||
(creatureRefId.empty() && !isNPC))
|
|
||||||
{
|
|
||||||
LOG_APPEND(Log::LOG_INFO, "- Deleting old reference");
|
|
||||||
state = 0;
|
|
||||||
world->deleteObject(ptr);
|
world->deleteObject(ptr);
|
||||||
delete reference;
|
delete reference;
|
||||||
reference = nullptr;
|
reference = nullptr;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MWWorld::Ptr DedicatedPlayer::getPtr()
|
MWWorld::Ptr DedicatedPlayer::getPtr()
|
||||||
|
|
|
@ -38,10 +38,10 @@ namespace mwmp
|
||||||
|
|
||||||
void move(float dt);
|
void move(float dt);
|
||||||
void setBaseInfo();
|
void setBaseInfo();
|
||||||
|
void setShapeshift();
|
||||||
void setAnimFlags();
|
void setAnimFlags();
|
||||||
void setEquipment();
|
void setEquipment();
|
||||||
void setCell();
|
void setCell();
|
||||||
void setShapeshift();
|
|
||||||
|
|
||||||
void updateMarker();
|
void updateMarker();
|
||||||
void removeMarker();
|
void removeMarker();
|
||||||
|
@ -53,8 +53,7 @@ namespace mwmp
|
||||||
ESM::NPC getNpcRecord();
|
ESM::NPC getNpcRecord();
|
||||||
ESM::Creature getCreatureRecord();
|
ESM::Creature getCreatureRecord();
|
||||||
|
|
||||||
void createReference(ESM::NPC& npc, ESM::Creature& creature, bool reset);
|
void createReference(ESM::NPC& npc, ESM::Creature& creature);
|
||||||
void updateReference(ESM::NPC& npc, ESM::Creature& creature);
|
|
||||||
void deleteReference();
|
void deleteReference();
|
||||||
|
|
||||||
MWWorld::Ptr getPtr();
|
MWWorld::Ptr getPtr();
|
||||||
|
@ -67,7 +66,6 @@ namespace mwmp
|
||||||
DedicatedPlayer(RakNet::RakNetGUID guid);
|
DedicatedPlayer(RakNet::RakNetGUID guid);
|
||||||
virtual ~DedicatedPlayer();
|
virtual ~DedicatedPlayer();
|
||||||
|
|
||||||
int state;
|
|
||||||
MWWorld::ManualRef* reference;
|
MWWorld::ManualRef* reference;
|
||||||
|
|
||||||
MWWorld::Ptr ptr;
|
MWWorld::Ptr ptr;
|
||||||
|
|
|
@ -39,30 +39,19 @@ DedicatedPlayer *PlayerList::newPlayer(RakNet::RakNetGUID guid)
|
||||||
LOG_APPEND(Log::LOG_INFO, "- Creating new DedicatedPlayer with guid %s", guid.ToString());
|
LOG_APPEND(Log::LOG_INFO, "- Creating new DedicatedPlayer with guid %s", guid.ToString());
|
||||||
|
|
||||||
players[guid] = new DedicatedPlayer(guid);
|
players[guid] = new DedicatedPlayer(guid);
|
||||||
players[guid]->state = 0;
|
|
||||||
|
LOG_APPEND(Log::LOG_INFO, "- There are now %i DedicatedPlayers", players.size());
|
||||||
|
|
||||||
return players[guid];
|
return players[guid];
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerList::disconnectPlayer(RakNet::RakNetGUID guid)
|
void PlayerList::deletePlayer(RakNet::RakNetGUID guid)
|
||||||
{
|
{
|
||||||
if (players[guid]->state > 1)
|
if (players[guid]->reference)
|
||||||
{
|
players[guid]->deleteReference();
|
||||||
players[guid]->state = 1;
|
|
||||||
|
|
||||||
// Remove player's marker
|
delete players[guid];
|
||||||
players[guid]->setMarkerState(false);
|
players.erase(guid);
|
||||||
|
|
||||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
|
||||||
world->disable(players[guid]->getPtr());
|
|
||||||
|
|
||||||
// Move player to exterior 0,0
|
|
||||||
ESM::Position newPos;
|
|
||||||
newPos.pos[0] = newPos.pos[1] = Main::get().getCellController()->getCellSize() / 2;
|
|
||||||
newPos.pos[2] = 0;
|
|
||||||
MWWorld::CellStore *cellStore = world->getExterior(0, 0);
|
|
||||||
|
|
||||||
world->moveObject(players[guid]->getPtr(), cellStore, newPos.pos[0], newPos.pos[1], newPos.pos[2]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerList::cleanUp()
|
void PlayerList::cleanUp()
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace mwmp
|
||||||
|
|
||||||
static DedicatedPlayer *newPlayer(RakNet::RakNetGUID guid);
|
static DedicatedPlayer *newPlayer(RakNet::RakNetGUID guid);
|
||||||
|
|
||||||
static void disconnectPlayer(RakNet::RakNetGUID guid);
|
static void deletePlayer(RakNet::RakNetGUID guid);
|
||||||
static void cleanUp();
|
static void cleanUp();
|
||||||
|
|
||||||
static DedicatedPlayer *getPlayer(RakNet::RakNetGUID guid);
|
static DedicatedPlayer *getPlayer(RakNet::RakNetGUID guid);
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace mwmp
|
||||||
if (isLocal())
|
if (isLocal())
|
||||||
MWBase::Environment::get().getStateManager()->requestQuit();
|
MWBase::Environment::get().getStateManager()->requestQuit();
|
||||||
else if (player != 0)
|
else if (player != 0)
|
||||||
PlayerList::disconnectPlayer(guid);
|
PlayerList::deletePlayer(guid);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue