diff --git a/apps/openmw/mwmp/DedicatedPlayer.cpp b/apps/openmw/mwmp/DedicatedPlayer.cpp index cc4604f58..e03e0bf7f 100644 --- a/apps/openmw/mwmp/DedicatedPlayer.cpp +++ b/apps/openmw/mwmp/DedicatedPlayer.cpp @@ -41,6 +41,7 @@ using namespace std; DedicatedPlayer::DedicatedPlayer(RakNet::RakNetGUID guid) : BasePlayer(guid) { + reference = 0; attack.pressed = 0; creatureStats.mDead = false; movementFlags = 0; diff --git a/apps/openmw/mwmp/PlayerList.cpp b/apps/openmw/mwmp/PlayerList.cpp index c89bdf2b3..30942cf71 100644 --- a/apps/openmw/mwmp/PlayerList.cpp +++ b/apps/openmw/mwmp/PlayerList.cpp @@ -1,4 +1,5 @@ #include +#include #include "../mwbase/environment.hpp" @@ -20,7 +21,7 @@ using namespace mwmp; using namespace std; -std::map PlayerList::players; +std::map PlayerList::players; void PlayerList::update(float dt) { @@ -46,7 +47,7 @@ void PlayerList::createPlayer(RakNet::RakNetGUID guid) if (!dedicPlayer->creatureModel.empty()) { const ESM::Creature *tmpCreature = world->getStore().get().search(dedicPlayer->creatureModel); - if(tmpCreature == 0) + if (tmpCreature == 0) { dedicPlayer->creatureModel = ""; createPlayer(guid); @@ -54,8 +55,10 @@ void PlayerList::createPlayer(RakNet::RakNetGUID guid) } creature = *tmpCreature; creature.mScript = ""; - if(!dedicPlayer->useCreatureName) + if (!dedicPlayer->useCreatureName) creature.mName = dedicPlayer->npc.mName; + LOG_APPEND(Log::LOG_INFO, "Player %s looks like %s", dedicPlayer->npc.mName.c_str(), + dedicPlayer->creatureModel.c_str()); } else { @@ -75,64 +78,110 @@ void PlayerList::createPlayer(RakNet::RakNetGUID guid) npc.mFlags = dedicPlayer->npc.mFlags; } + bool reset = false; + if (dedicPlayer->reference) + { + bool isNPC = dedicPlayer->reference->getPtr().getTypeName() == typeid(ESM::NPC).name(); + if ((!dedicPlayer->creatureModel.empty() && isNPC) || + (dedicPlayer->creatureModel.empty() && !isNPC)) + { + if (dedicPlayer->reference) + { + LOG_APPEND(Log::LOG_INFO, "- Deleting old reference"); + dedicPlayer->state = 0; + world->deleteObject(dedicPlayer->ptr); + delete dedicPlayer->reference; + dedicPlayer->reference = NULL; + reset = true; + } + } + } + + // Temporarily spawn or move player to the center of exterior 0,0 whenever setting base info + 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); + if (dedicPlayer->state == 0) { string recid; if (dedicPlayer->creatureModel.empty()) { + LOG_APPEND(Log::LOG_INFO, "- Creating new NPC record"); npc.mId = "Dedicated Player"; recid = world->createRecord(npc)->mId; } else { + LOG_APPEND(Log::LOG_INFO, "- Creating new Creature record"); creature.mId = "Dedicated Player"; recid = world->createRecord(creature)->mId; } dedicPlayer->reference = new MWWorld::ManualRef(world->getStore(), recid, 1); - } - // Temporarily spawn or move player to the center of exterior 0,0 whenever setting base info - 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); - - if (dedicPlayer->state == 0) - { LOG_APPEND(Log::LOG_INFO, "- Creating new reference pointer for %s", dedicPlayer->npc.mName.c_str()); - MWWorld::Ptr tmp = world->placeObject(dedicPlayer->reference->getPtr(), cellStore, spawnPos); + MWWorld::Ptr tmp; + + if (reset) + { + if (dedicPlayer->cell.isExterior()) + cellStore = world->getExterior(dedicPlayer->cell.mData.mX, dedicPlayer->cell.mData.mY); + else + cellStore = world->getInterior(dedicPlayer->cell.mName); + + spawnPos = dedicPlayer->position; + } + + tmp = world->placeObject(dedicPlayer->reference->getPtr(), cellStore, spawnPos); dedicPlayer->ptr.mCell = tmp.mCell; dedicPlayer->ptr.mRef = tmp.mRef; - dedicPlayer->cell = *dedicPlayer->ptr.getCell()->getCell(); - dedicPlayer->position = dedicPlayer->ptr.getRefData().getPosition(); + if (!reset) + { + dedicPlayer->cell = *dedicPlayer->ptr.getCell()->getCell(); + dedicPlayer->position = dedicPlayer->ptr.getRefData().getPosition(); + } } else { LOG_APPEND(Log::LOG_INFO, "- Updating reference pointer for %s", dedicPlayer->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 (!dedicPlayer->creatureModel.empty()) { - creature.mId = players[guid]->ptr.get()->mBase->mId; - MWWorld::Store *esm_store = const_cast *> (&store->get()); - esm_store->insert(creature); + 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 = players[guid]->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 = players[guid]->ptr.get()->mBase->mId; - MWWorld::Store *esm_store = const_cast *> (&store->get()); - esm_store->insert(npc); + npc_store->insert(npc); } // Disable Ptr to avoid graphical glitches caused by race changes world->disable(players[guid]->ptr); - + dedicPlayer->setPtr(world->moveObject(dedicPlayer->ptr, cellStore, spawnPos.pos[0], spawnPos.pos[1], spawnPos.pos[2])); dedicPlayer->updateCell();