You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
6.2 KiB
C++
252 lines
6.2 KiB
C++
//
|
|
// Created by koncord on 18.02.17.
|
|
//
|
|
|
|
#include "Cell.hpp"
|
|
|
|
#include <components/openmw-mp/NetworkMessages.hpp>
|
|
|
|
#include <iostream>
|
|
#include "Player.hpp"
|
|
#include "Script/Plugin.hpp"
|
|
|
|
using namespace std;
|
|
|
|
Cell::Cell(ESM::Cell cell) : cell(cell)
|
|
{
|
|
cellActorList.count = 0;
|
|
}
|
|
|
|
Cell::Iterator Cell::begin() const
|
|
{
|
|
return players.begin();
|
|
}
|
|
|
|
Cell::Iterator Cell::end() const
|
|
{
|
|
return players.end();
|
|
}
|
|
|
|
void Cell::addPlayer(Player *player)
|
|
{
|
|
// Ensure the player hasn't already been added
|
|
auto it = find(begin(), end(), player);
|
|
|
|
if (it != end())
|
|
{
|
|
LOG_APPEND(Log::LOG_INFO, "- Attempt to add %s to Cell %s again was ignored", player->npc.mName.c_str(),
|
|
getDescription().c_str());
|
|
return;
|
|
}
|
|
|
|
auto it2 = find(player->cells.begin(), player->cells.end(), this);
|
|
if (it2 == player->cells.end())
|
|
{
|
|
LOG_APPEND(Log::LOG_INFO, "- Adding %s to Player %s", getDescription().c_str(), player->npc.mName.c_str());
|
|
|
|
player->cells.push_back(this);
|
|
}
|
|
|
|
LOG_APPEND(Log::LOG_INFO, "- Adding %s to Cell %s", player->npc.mName.c_str(), getDescription().c_str());
|
|
|
|
PlayerId id = player->getId();
|
|
if (id != InvalidPID)
|
|
{
|
|
Plugin::Call<CallbackIndex("OnCellLoad")>(id, getDescription().c_str());
|
|
players.push_back(player);
|
|
}
|
|
}
|
|
|
|
void Cell::removePlayer(Player *player, bool cleanPlayer)
|
|
{
|
|
for (auto it = begin(); it != end(); ++it)
|
|
{
|
|
if (*it == player)
|
|
{
|
|
if (cleanPlayer)
|
|
{
|
|
auto it2 = find(player->cells.begin(), player->cells.end(), this);
|
|
if (it2 != player->cells.end())
|
|
{
|
|
LOG_APPEND(Log::LOG_INFO, "- Removing %s from Player %s", getDescription().c_str(), player->npc.mName.c_str());
|
|
|
|
player->cells.erase(it2);
|
|
}
|
|
}
|
|
|
|
LOG_APPEND(Log::LOG_INFO, "- Removing %s from Cell %s", player->npc.mName.c_str(), getDescription().c_str());
|
|
|
|
Plugin::Call<CallbackIndex("OnCellUnload")>(player->getId(), getDescription().c_str());
|
|
|
|
players.erase(it);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Cell::readActorList(unsigned char packetID, const mwmp::BaseActorList *newActorList)
|
|
{
|
|
for (unsigned int i = 0; i < newActorList->count; i++)
|
|
{
|
|
mwmp::BaseActor newActor = newActorList->baseActors.at(i);
|
|
mwmp::BaseActor *cellActor;
|
|
|
|
if (containsActor(newActor.refNum, newActor.mpNum))
|
|
{
|
|
cellActor = getActor(newActor.refNum, newActor.mpNum);
|
|
|
|
switch (packetID)
|
|
{
|
|
case ID_ACTOR_POSITION:
|
|
|
|
cellActor->hasPositionData = true;
|
|
cellActor->position = newActor.position;
|
|
break;
|
|
|
|
case ID_ACTOR_STATS_DYNAMIC:
|
|
|
|
cellActor->hasStatsDynamicData = true;
|
|
cellActor->creatureStats.mDynamic[0] = newActor.creatureStats.mDynamic[0];
|
|
cellActor->creatureStats.mDynamic[1] = newActor.creatureStats.mDynamic[1];
|
|
cellActor->creatureStats.mDynamic[2] = newActor.creatureStats.mDynamic[2];
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
cellActorList.baseActors.push_back(newActor);
|
|
}
|
|
|
|
cellActorList.count = cellActorList.baseActors.size();
|
|
}
|
|
|
|
bool Cell::containsActor(int refNum, int mpNum)
|
|
{
|
|
for (unsigned int i = 0; i < cellActorList.baseActors.size(); i++)
|
|
{
|
|
mwmp::BaseActor actor = cellActorList.baseActors.at(i);
|
|
|
|
if (actor.refNum == refNum && actor.mpNum == mpNum)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
mwmp::BaseActor *Cell::getActor(int refNum, int mpNum)
|
|
{
|
|
for (unsigned int i = 0; i < cellActorList.baseActors.size(); i++)
|
|
{
|
|
mwmp::BaseActor *actor = &cellActorList.baseActors.at(i);
|
|
|
|
if (actor->refNum == refNum && actor->mpNum == mpNum)
|
|
return actor;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void Cell::removeActors(const mwmp::BaseActorList *newActorList)
|
|
{
|
|
for (std::vector<mwmp::BaseActor>::iterator it = cellActorList.baseActors.begin(); it != cellActorList.baseActors.end();)
|
|
{
|
|
int refNum = (*it).refNum;
|
|
int mpNum = (*it).mpNum;
|
|
|
|
bool foundActor = false;
|
|
|
|
for (unsigned int i = 0; i < newActorList->count; i++)
|
|
{
|
|
mwmp::BaseActor newActor = newActorList->baseActors.at(i);
|
|
|
|
if (newActor.refNum == refNum && newActor.mpNum == mpNum)
|
|
{
|
|
it = cellActorList.baseActors.erase(it);
|
|
foundActor = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!foundActor)
|
|
++it;
|
|
}
|
|
|
|
cellActorList.count = cellActorList.baseActors.size();
|
|
}
|
|
|
|
RakNet::RakNetGUID *Cell::getAuthority()
|
|
{
|
|
return &authorityGuid;
|
|
}
|
|
|
|
void Cell::setAuthority(const RakNet::RakNetGUID& guid)
|
|
{
|
|
authorityGuid = guid;
|
|
}
|
|
|
|
mwmp::BaseActorList *Cell::getActorList()
|
|
{
|
|
return &cellActorList;
|
|
}
|
|
|
|
Cell::TPlayers Cell::getPlayers() const
|
|
{
|
|
return players;
|
|
}
|
|
|
|
void Cell::sendToLoaded(mwmp::ActorPacket *actorPacket, mwmp::BaseActorList *baseActorList) const
|
|
{
|
|
if (players.empty())
|
|
return;
|
|
|
|
std::list <Player*> plList;
|
|
|
|
for (auto pl : players)
|
|
{
|
|
if (pl != nullptr && !pl->npc.mName.empty())
|
|
plList.push_back(pl);
|
|
}
|
|
|
|
plList.sort();
|
|
plList.unique();
|
|
|
|
for (auto pl : plList)
|
|
{
|
|
if (pl->guid == baseActorList->guid) continue;
|
|
|
|
actorPacket->setActorList(baseActorList);
|
|
|
|
// Send the packet to this eligible guid
|
|
actorPacket->Send(pl->guid);
|
|
}
|
|
}
|
|
|
|
void Cell::sendToLoaded(mwmp::ObjectPacket *objectPacket, mwmp::BaseObjectList *baseObjectList) const
|
|
{
|
|
if (players.empty())
|
|
return;
|
|
|
|
std::list <Player*> plList;
|
|
|
|
for (auto pl : players)
|
|
{
|
|
if (pl != nullptr && !pl->npc.mName.empty())
|
|
plList.push_back(pl);
|
|
}
|
|
|
|
plList.sort();
|
|
plList.unique();
|
|
|
|
for (auto pl : plList)
|
|
{
|
|
if (pl->guid == baseObjectList->guid) continue;
|
|
|
|
objectPacket->setObjectList(baseObjectList);
|
|
|
|
// Send the packet to this eligible guid
|
|
objectPacket->Send(pl->guid);
|
|
}
|
|
}
|
|
|
|
std::string Cell::getDescription() const
|
|
{
|
|
return cell.getDescription();
|
|
}
|