From 141eb8b7c249f87b8369a71a5f8ee41edb1c5532 Mon Sep 17 00:00:00 2001 From: David Cernat Date: Sun, 8 Apr 2018 15:02:43 +0300 Subject: [PATCH] [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. --- apps/openmw/mwmp/DedicatedPlayer.cpp | 141 ++++-------------- apps/openmw/mwmp/DedicatedPlayer.hpp | 6 +- apps/openmw/mwmp/PlayerList.cpp | 27 +--- apps/openmw/mwmp/PlayerList.hpp | 2 +- .../player/ProcessorUserDisconnected.hpp | 2 +- 5 files changed, 39 insertions(+), 139 deletions(-) diff --git a/apps/openmw/mwmp/DedicatedPlayer.cpp b/apps/openmw/mwmp/DedicatedPlayer.cpp index a30d60939..c218f3846 100644 --- a/apps/openmw/mwmp/DedicatedPlayer.cpp +++ b/apps/openmw/mwmp/DedicatedPlayer.cpp @@ -46,6 +46,10 @@ DedicatedPlayer::DedicatedPlayer(RakNet::RakNetGUID guid) : BasePlayer(guid) creatureStats.mDead = false; movementFlags = 0; attack.instant = false; + + cell.blank(); + position.pos[0] = position.pos[1] = Main::get().getCellController()->getCellSize() / 2; + position.pos[2] = 0; } DedicatedPlayer::~DedicatedPlayer() { @@ -94,7 +98,7 @@ void DedicatedPlayer::update(float dt) void DedicatedPlayer::move(float dt) { - if (state != 2) return; + if (!reference) return; ESM::Position refPos = ptr.getRefData().getPosition(); MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -151,31 +155,26 @@ void DedicatedPlayer::setBaseInfo() tempNpc = getNpcRecord(); } - bool reset = false; if (reference) { deleteReference(); - reset = true; - } - - if (state == 0) - { - createReference(tempNpc, tempCreature, reset); - } - else - { - updateReference(tempNpc, tempCreature); } - state = 2; + createReference(tempNpc, tempCreature); - // Give this new character a fatigue of at least 1 so it doesn't spawn - // on the ground - creatureStats.mDynamic[2].mBase = 1; + // Give this new character a temporary high fatigue of at least 1 so it doesn't + // spawn on the ground + creatureStats.mDynamic[2].mBase = 1000; world->enable(ptr); } +void DedicatedPlayer::setShapeshift() +{ + MWBase::Environment::get().getWorld()->scaleObject(ptr, scale); + MWBase::Environment::get().getMechanicsManager()->setWerewolf(ptr, isWerewolf); +} + void DedicatedPlayer::setAnimFlags() { using namespace MWMechanics; @@ -250,9 +249,8 @@ void DedicatedPlayer::setEquipment() void DedicatedPlayer::setCell() { - // Prevent cell update when player hasn't been instantiated yet - if (state == 0) - return; + // Prevent cell update when reference doesn't exist + if (!reference) return; MWBase::World *world = MWBase::Environment::get().getWorld(); @@ -287,12 +285,6 @@ void DedicatedPlayer::setCell() 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() { if (!markerEnabled) @@ -388,122 +380,43 @@ ESM::NPC DedicatedPlayer::getNpcRecord() 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(); - // 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); - - string recid; + string recId; if (creatureRefId.empty()) { LOG_APPEND(Log::LOG_INFO, "- Creating new NPC record"); npc.mId = "Dedicated Player"; - recid = world->createRecord(npc)->mId; + recId = world->createRecord(npc)->mId; } else { LOG_APPEND(Log::LOG_INFO, "- Creating new Creature record"); 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()); - MWWorld::Ptr tmp; - - 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(); - } + ptr = world->placeObject(reference->getPtr(), Main::get().getCellController()->getCellStore(cell), position); ESM::CustomMarker mEditingMarker = Main::get().getGUIController()->createMarker(guid); marker = mEditingMarker; 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(&world->getStore()); - MWWorld::Store *creature_store = const_cast *> (&store->get()); - MWWorld::Store *npc_store = const_cast *> (&store->get()); - - 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()->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()->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() { MWBase::World *world = MWBase::Environment::get().getWorld(); - bool isNPC = reference->getPtr().getTypeName() == typeid(ESM::NPC).name(); - if ((!creatureRefId.empty() && isNPC) || - (creatureRefId.empty() && !isNPC)) - { - LOG_APPEND(Log::LOG_INFO, "- Deleting old reference"); - state = 0; - world->deleteObject(ptr); - delete reference; - reference = nullptr; - } + LOG_APPEND(Log::LOG_INFO, "- Deleting reference"); + world->deleteObject(ptr); + delete reference; + reference = nullptr; } MWWorld::Ptr DedicatedPlayer::getPtr() diff --git a/apps/openmw/mwmp/DedicatedPlayer.hpp b/apps/openmw/mwmp/DedicatedPlayer.hpp index b141fa463..d01ac91cb 100644 --- a/apps/openmw/mwmp/DedicatedPlayer.hpp +++ b/apps/openmw/mwmp/DedicatedPlayer.hpp @@ -38,10 +38,10 @@ namespace mwmp void move(float dt); void setBaseInfo(); + void setShapeshift(); void setAnimFlags(); void setEquipment(); void setCell(); - void setShapeshift(); void updateMarker(); void removeMarker(); @@ -53,8 +53,7 @@ namespace mwmp ESM::NPC getNpcRecord(); ESM::Creature getCreatureRecord(); - void createReference(ESM::NPC& npc, ESM::Creature& creature, bool reset); - void updateReference(ESM::NPC& npc, ESM::Creature& creature); + void createReference(ESM::NPC& npc, ESM::Creature& creature); void deleteReference(); MWWorld::Ptr getPtr(); @@ -67,7 +66,6 @@ namespace mwmp DedicatedPlayer(RakNet::RakNetGUID guid); virtual ~DedicatedPlayer(); - int state; MWWorld::ManualRef* reference; MWWorld::Ptr ptr; diff --git a/apps/openmw/mwmp/PlayerList.cpp b/apps/openmw/mwmp/PlayerList.cpp index c7d064d9b..24e392511 100644 --- a/apps/openmw/mwmp/PlayerList.cpp +++ b/apps/openmw/mwmp/PlayerList.cpp @@ -39,30 +39,19 @@ DedicatedPlayer *PlayerList::newPlayer(RakNet::RakNetGUID guid) LOG_APPEND(Log::LOG_INFO, "- Creating new DedicatedPlayer with guid %s", guid.ToString()); players[guid] = new DedicatedPlayer(guid); - players[guid]->state = 0; + + LOG_APPEND(Log::LOG_INFO, "- There are now %i DedicatedPlayers", players.size()); + return players[guid]; } -void PlayerList::disconnectPlayer(RakNet::RakNetGUID guid) +void PlayerList::deletePlayer(RakNet::RakNetGUID guid) { - if (players[guid]->state > 1) - { - players[guid]->state = 1; - - // Remove player's marker - players[guid]->setMarkerState(false); + if (players[guid]->reference) + players[guid]->deleteReference(); - 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]); - } + delete players[guid]; + players.erase(guid); } void PlayerList::cleanUp() diff --git a/apps/openmw/mwmp/PlayerList.hpp b/apps/openmw/mwmp/PlayerList.hpp index 91f03d869..c8a9eb959 100644 --- a/apps/openmw/mwmp/PlayerList.hpp +++ b/apps/openmw/mwmp/PlayerList.hpp @@ -29,7 +29,7 @@ namespace mwmp static DedicatedPlayer *newPlayer(RakNet::RakNetGUID guid); - static void disconnectPlayer(RakNet::RakNetGUID guid); + static void deletePlayer(RakNet::RakNetGUID guid); static void cleanUp(); static DedicatedPlayer *getPlayer(RakNet::RakNetGUID guid); diff --git a/apps/openmw/mwmp/processors/player/ProcessorUserDisconnected.hpp b/apps/openmw/mwmp/processors/player/ProcessorUserDisconnected.hpp index e1c7fec6d..68eabfda4 100644 --- a/apps/openmw/mwmp/processors/player/ProcessorUserDisconnected.hpp +++ b/apps/openmw/mwmp/processors/player/ProcessorUserDisconnected.hpp @@ -26,7 +26,7 @@ namespace mwmp if (isLocal()) MWBase::Environment::get().getStateManager()->requestQuit(); else if (player != 0) - PlayerList::disconnectPlayer(guid); + PlayerList::deletePlayer(guid); } }; }