[Client] Split up creation of DedicatedPlayers into multiple methods

Additionally, print player guids using their string representations for consistency.

The creation and updating of DedicatedPlayer references remains very inelegant, but this commit is the first step towards fixing that.
pull/404/head
David Cernat 7 years ago
parent c8abd11f5d
commit 14f90e773d

@ -1,7 +1,3 @@
//
// Created by koncord on 02.01.16.
//
#include <boost/algorithm/clamp.hpp>
#include <components/openmw-mp/Log.hpp>
#include <apps/openmw/mwmechanics/steering.hpp>
@ -130,6 +126,56 @@ void DedicatedPlayer::move(float dt)
MWMechanics::zTurn(ptr, position.rot[2], osg::DegreesToRadians(1.0));
}
void DedicatedPlayer::setBaseInfo()
{
MWBase::World *world = MWBase::Environment::get().getWorld();
ESM::Creature tempCreature;
ESM::NPC tempNpc;
if (!creatureRefId.empty())
{
const ESM::Creature *tmpCreature = world->getStore().get<ESM::Creature>().search(creatureRefId);
if (tmpCreature == 0)
{
creatureRefId = "";
}
else
{
tempCreature = getCreatureRecord();
}
}
if (creatureRefId.empty())
{
tempNpc = getNpcRecord();
}
bool reset = false;
if (reference)
{
deleteReference();
reset = true;
}
if (state == 0)
{
createReference(tempNpc, tempCreature, reset);
}
else
{
updateReference(tempNpc, tempCreature);
}
state = 2;
// Give this new character a fatigue of at least 1 so it doesn't spawn
// on the ground
creatureStats.mDynamic[2].mBase = 1;
world->enable(ptr);
}
void DedicatedPlayer::setAnimFlags()
{
using namespace MWMechanics;
@ -302,14 +348,167 @@ void DedicatedPlayer::playSpeech()
winMgr->messageBox(MWBase::Environment::get().getDialogueManager()->getVoiceCaption(sound), MWGui::ShowInDialogueMode_Never);
}
MWWorld::Ptr DedicatedPlayer::getPtr()
ESM::Creature DedicatedPlayer::getCreatureRecord()
{
return ptr;
MWBase::World *world = MWBase::Environment::get().getWorld();
ESM::Creature creature;
const ESM::Creature *tmpCreature = world->getStore().get<ESM::Creature>().search(creatureRefId);
creature = *tmpCreature;
creature.mScript = "";
if (!displayCreatureName)
creature.mName = npc.mName;
LOG_APPEND(Log::LOG_INFO, "Player %s looks like %s", npc.mName.c_str(), creatureRefId.c_str());
return creature;
}
ESM::NPC DedicatedPlayer::getNpcRecord()
{
MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = world->getPlayerPtr();
ESM::NPC newNpc = *player.get<ESM::NPC>()->mBase;
// To avoid freezes caused by invalid races, only set race if we find it
// on our client
if (world->getStore().get<ESM::Race>().search(npc.mRace) != 0)
newNpc.mRace = npc.mRace;
newNpc.mHead = npc.mHead;
newNpc.mHair = npc.mHair;
newNpc.mClass = npc.mClass;
newNpc.mName = npc.mName;
newNpc.mFlags = npc.mFlags;
return newNpc;
}
void DedicatedPlayer::createReference(ESM::NPC& npc, ESM::Creature& creature, bool reset)
{
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;
if (creatureRefId.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;
}
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();
}
ESM::CustomMarker mEditingMarker = Main::get().getGUIController()->createMarker(guid);
marker = mEditingMarker;
setMarkerState(true);
}
MWWorld::Ptr DedicatedPlayer::getLiveCellPtr()
void DedicatedPlayer::updateReference(ESM::NPC& npc, ESM::Creature& creature)
{
return reference->getPtr();
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()
{
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;
}
}
MWWorld::Ptr DedicatedPlayer::getPtr()
{
return ptr;
}
MWWorld::ManualRef *DedicatedPlayer::getRef()

@ -6,9 +6,12 @@
#define OPENMW_DEDICATEDPLAYER_HPP
#include <components/esm/custommarkerstate.hpp>
#include <components/esm/loadcrea.hpp>
#include <components/esm/loadnpc.hpp>
#include <components/openmw-mp/Base/BasePlayer.hpp>
#include "../mwclass/npc.hpp"
#include "../mwmechanics/aisequence.hpp"
#include "../mwworld/manualref.hpp"
@ -34,6 +37,7 @@ namespace mwmp
void update(float dt);
void move(float dt);
void setBaseInfo();
void setAnimFlags();
void setEquipment();
void setCell();
@ -46,8 +50,14 @@ namespace mwmp
void playAnimation();
void playSpeech();
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 deleteReference();
MWWorld::Ptr getPtr();
MWWorld::Ptr getLiveCellPtr();
MWWorld::ManualRef* getRef();
void setPtr(const MWWorld::Ptr& newPtr);

@ -285,7 +285,7 @@ ESM::CustomMarker mwmp::GUIController::createMarker(const RakNet::RakNetGUID &gu
ESM::CustomMarker mEditingMarker;
if (!player)
{
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Unknown player guid: %lu", guid.g);
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Unknown player guid: %s", guid.ToString());
return mEditingMarker;
}

@ -34,173 +34,9 @@ void PlayerList::update(float dt)
}
}
void PlayerList::createPlayer(RakNet::RakNetGUID guid)
{
LOG_APPEND(Log::LOG_INFO, "- Setting up character info");
MWBase::World *world = MWBase::Environment::get().getWorld();
DedicatedPlayer *dedicPlayer = players[guid];
ESM::Creature creature;
ESM::NPC npc;
if (!dedicPlayer->creatureRefId.empty())
{
const ESM::Creature *tmpCreature = world->getStore().get<ESM::Creature>().search(dedicPlayer->creatureRefId);
if (tmpCreature == 0)
{
dedicPlayer->creatureRefId = "";
createPlayer(guid);
return;
}
creature = *tmpCreature;
creature.mScript = "";
if (!dedicPlayer->displayCreatureName)
creature.mName = dedicPlayer->npc.mName;
LOG_APPEND(Log::LOG_INFO, "Player %s looks like %s", dedicPlayer->npc.mName.c_str(),
dedicPlayer->creatureRefId.c_str());
}
else
{
MWWorld::Ptr player = world->getPlayerPtr();
npc = *player.get<ESM::NPC>()->mBase;
// To avoid freezes caused by invalid races, only set race if we find it
// on our client
if (world->getStore().get<ESM::Race>().search(dedicPlayer->npc.mRace) != 0)
npc.mRace = dedicPlayer->npc.mRace;
npc.mHead = dedicPlayer->npc.mHead;
npc.mHair = dedicPlayer->npc.mHair;
npc.mClass = dedicPlayer->npc.mClass;
npc.mName = dedicPlayer->npc.mName;
npc.mFlags = dedicPlayer->npc.mFlags;
}
bool reset = false;
if (dedicPlayer->reference)
{
bool isNPC = dedicPlayer->reference->getPtr().getTypeName() == typeid(ESM::NPC).name();
if ((!dedicPlayer->creatureRefId.empty() && isNPC) ||
(dedicPlayer->creatureRefId.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 = nullptr;
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->creatureRefId.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);
LOG_APPEND(Log::LOG_INFO, "- Creating new reference pointer for %s", dedicPlayer->npc.mName.c_str());
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;
if (!reset)
{
dedicPlayer->cell = *dedicPlayer->ptr.getCell()->getCell();
dedicPlayer->position = dedicPlayer->ptr.getRefData().getPosition();
}
ESM::CustomMarker mEditingMarker = Main::get().getGUIController()->createMarker(guid);
dedicPlayer->marker = mEditingMarker;
dedicPlayer->setMarkerState(true);
}
else
{
LOG_APPEND(Log::LOG_INFO, "- Updating reference pointer for %s", dedicPlayer->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 (!dedicPlayer->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 = players[guid]->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 = players[guid]->ptr.get<ESM::NPC>()->mBase->mId;
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->setCell();
}
dedicPlayer->guid = guid;
dedicPlayer->state = 2;
// Give this new character a fatigue of at least 1 so it doesn't spawn
// on the ground
dedicPlayer->creatureStats.mDynamic[2].mBase = 1;
world->enable(players[guid]->ptr);
}
DedicatedPlayer *PlayerList::newPlayer(RakNet::RakNetGUID guid)
{
LOG_APPEND(Log::LOG_INFO, "- Creating new DedicatedPlayer with guid %lu", guid.g);
LOG_APPEND(Log::LOG_INFO, "- Creating new DedicatedPlayer with guid %s", guid.ToString());
players[guid] = new DedicatedPlayer(guid);
players[guid]->state = 0;

@ -27,7 +27,6 @@ namespace mwmp
static void update(float dt);
static void createPlayer(RakNet::RakNetGUID guid);
static DedicatedPlayer *newPlayer(RakNet::RakNetGUID guid);
static void disconnectPlayer(RakNet::RakNetGUID guid);

@ -49,7 +49,7 @@ namespace mwmp
packet.Read();
}
PlayerList::createPlayer(guid);
static_cast<DedicatedPlayer*>(player)->setBaseInfo();
}
}
};

Loading…
Cancel
Save