|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include <apps/openmw-mp/Script/EventController.hpp>
|
|
|
|
#include "Networking.hpp"
|
|
|
|
|
|
|
|
#include "CellController.hpp"
|
|
|
|
#include "Cell.hpp"
|
|
|
|
#include "Player.hpp"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
CellController::~CellController()
|
|
|
|
{
|
|
|
|
for (auto cell : cells)
|
|
|
|
delete cell;
|
|
|
|
}
|
|
|
|
|
|
|
|
CellController &CellController::get()
|
|
|
|
{
|
|
|
|
static CellController cellCtrl;
|
|
|
|
return cellCtrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cell *CellController::getCell(const ESM::Cell &esmCell)
|
|
|
|
{
|
|
|
|
if (esmCell.isExterior())
|
|
|
|
return getCellByXY(esmCell.mData.mX, esmCell.mData.mY);
|
|
|
|
else
|
|
|
|
return getCellByName(esmCell.mName);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Cell *CellController::getCellByXY(int x, int y)
|
|
|
|
{
|
|
|
|
auto it = find_if(cells.begin(), cells.end(), [x, y](const Cell *c)
|
|
|
|
{
|
|
|
|
return c->cell.mData.mX == x && c->cell.mData.mY == y;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it == cells.end())
|
|
|
|
{
|
|
|
|
LOG_APPEND(Log::LOG_INFO, "- Attempt to get Cell at %i, %i failed!", x, y);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return *it;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cell *CellController::getCellByName(const std::string &cellName)
|
|
|
|
{
|
|
|
|
auto it = find_if(cells.begin(), cells.end(), [cellName](const Cell *c)
|
|
|
|
{
|
|
|
|
return c->cell.mName == cellName;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (it == cells.end())
|
|
|
|
{
|
|
|
|
LOG_APPEND(Log::LOG_INFO, "- Attempt to get Cell at %s failed!", cellName.c_str());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return *it;
|
|
|
|
}
|
|
|
|
|
|
|
|
Cell *CellController::addCell(const ESM::Cell &cellData)
|
|
|
|
{
|
|
|
|
LOG_APPEND(Log::LOG_INFO, "- Loaded cells: %d", cells.size());
|
|
|
|
auto it = find_if(cells.begin(), cells.end(), [cellData](const Cell *c) {
|
|
|
|
// Currently we cannot compare because plugin lists can be loaded in different order
|
|
|
|
//return c->cell.sRecordId == cellData.sRecordId;
|
|
|
|
if (c->cell.isExterior() && cellData.isExterior())
|
|
|
|
{
|
|
|
|
if (c->cell.mData.mX == cellData.mData.mX && c->cell.mData.mY == cellData.mData.mY)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if (c->cell.mName == cellData.mName)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
Cell *cell;
|
|
|
|
if (it == cells.end())
|
|
|
|
{
|
|
|
|
LOG_APPEND(Log::LOG_INFO, "- Adding %s to CellController", cellData.getDescription().c_str());
|
|
|
|
|
|
|
|
cell = new Cell(cellData);
|
|
|
|
cells.push_back(cell);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LOG_APPEND(Log::LOG_INFO, "- Found %s in CellController", cellData.getDescription().c_str());
|
|
|
|
cell = *it;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cell;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CellController::removeCell(Cell *cell)
|
|
|
|
{
|
|
|
|
if (cell == nullptr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (auto it = cells.begin(); it != cells.end();)
|
|
|
|
{
|
|
|
|
if (*it != nullptr && *it == cell)
|
|
|
|
{
|
|
|
|
mwmp::Networking::get().getState().getEventCtrl().Call<CoreEvent::ON_CELL_DELETION>(cell->getDescription());
|
|
|
|
|
|
|
|
LOG_APPEND(Log::LOG_INFO, "- Removing %s from CellController", cell->getDescription().c_str());
|
|
|
|
|
|
|
|
delete *it;
|
|
|
|
it = cells.erase(it);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CellController::removePlayer(Cell *cell, Player *player)
|
|
|
|
{
|
|
|
|
cell->removePlayer(player);
|
|
|
|
|
|
|
|
if (cell->players.empty())
|
|
|
|
{
|
|
|
|
LOG_APPEND(Log::LOG_INFO, "- Cell %s has no players left", cell->getDescription().c_str());
|
|
|
|
removeCell(cell);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CellController::deletePlayer(Player *player)
|
|
|
|
{
|
|
|
|
LOG_APPEND(Log::LOG_INFO, "- Iterating through Cells from Player %s", player->npc.mName.c_str());
|
|
|
|
|
|
|
|
for (auto it = player->getCells()->begin(); !player->getCells()->empty(); ++it)
|
|
|
|
removePlayer(*it, player);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CellController::update(Player *player)
|
|
|
|
{
|
|
|
|
for (auto cell : player->cellStateChanges.cellStates)
|
|
|
|
{
|
|
|
|
if (cell.type == mwmp::CellState::Type::Load)
|
|
|
|
{
|
|
|
|
Cell *c = addCell(cell.cell);
|
|
|
|
c->addPlayer(player);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Cell *c;
|
|
|
|
if (!cell.cell.isExterior())
|
|
|
|
c = getCellByName(cell.cell.mName);
|
|
|
|
else
|
|
|
|
c = getCellByXY(cell.cell.getGridX(), cell.cell.getGridY());
|
|
|
|
|
|
|
|
if (c != nullptr)
|
|
|
|
removePlayer(c, player);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|