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.
739 lines
25 KiB
C++
739 lines
25 KiB
C++
#include <components/openmw-mp/TimedLog.hpp>
|
|
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
#include "../mwgui/windowmanagerimp.hpp"
|
|
|
|
#include "../mwmechanics/mechanicsmanagerimp.hpp"
|
|
|
|
#include "../mwworld/player.hpp"
|
|
#include "../mwworld/worldimp.hpp"
|
|
|
|
#include "Worldstate.hpp"
|
|
#include "Main.hpp"
|
|
#include "Networking.hpp"
|
|
#include "PlayerList.hpp"
|
|
#include "DedicatedPlayer.hpp"
|
|
#include "RecordHelper.hpp"
|
|
#include "CellController.hpp"
|
|
|
|
using namespace mwmp;
|
|
|
|
Worldstate::Worldstate()
|
|
{
|
|
hasPlayerCollision = true;
|
|
hasActorCollision = true;
|
|
hasPlacedObjectCollision = false;
|
|
useActorCollisionForPlacedObjects = false;
|
|
}
|
|
|
|
Worldstate::~Worldstate()
|
|
{
|
|
|
|
}
|
|
|
|
Networking *Worldstate::getNetworking()
|
|
{
|
|
return mwmp::Main::get().getNetworking();
|
|
}
|
|
|
|
void Worldstate::addRecords()
|
|
{
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received ID_RECORD_DYNAMIC with %i records of type %i",
|
|
recordsCount, recordsType);
|
|
|
|
if (recordsType == mwmp::RECORD_TYPE::SPELL)
|
|
{
|
|
for (auto &&record : spellRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- spell record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::POTION)
|
|
{
|
|
for (auto &&record : potionRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- potion record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::ENCHANTMENT)
|
|
{
|
|
for (auto &&record : enchantmentRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- enchantment record %s, %i\n-- baseId is %s", record.data.mId.c_str(), record.data.mData.mType,
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::CREATURE)
|
|
{
|
|
for (auto &&record : creatureRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- creature record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::NPC)
|
|
{
|
|
for (auto &&record : npcRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- NPC record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::ARMOR)
|
|
{
|
|
for (auto &&record : armorRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- armor record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::BOOK)
|
|
{
|
|
for (auto &&record : bookRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- book record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::CLOTHING)
|
|
{
|
|
for (auto &&record : clothingRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- clothing record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::MISCELLANEOUS)
|
|
{
|
|
for (auto &&record : miscellaneousRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- miscellaneous record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::WEAPON)
|
|
{
|
|
for (auto &&record : weaponRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- weapon record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::CONTAINER)
|
|
{
|
|
for (auto &&record : containerRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- container record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::DOOR)
|
|
{
|
|
for (auto &&record : doorRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- door record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::ACTIVATOR)
|
|
{
|
|
for (auto &&record : activatorRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- activator record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::STATIC)
|
|
{
|
|
for (auto &&record : staticRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- static record %s\n-- baseId is %s", record.data.mId.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::INGREDIENT)
|
|
{
|
|
for (auto &&record : ingredientRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- ingredient record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::APPARATUS)
|
|
{
|
|
for (auto &&record : apparatusRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- apparatus record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::LOCKPICK)
|
|
{
|
|
for (auto &&record : lockpickRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- lockpick record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::PROBE)
|
|
{
|
|
for (auto &&record : probeRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- probe record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::REPAIR)
|
|
{
|
|
for (auto &&record : repairRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- repair record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::LIGHT)
|
|
{
|
|
for (auto &&record : lightRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- light record %s, %s\n-- baseId is %s", record.data.mId.c_str(), record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::CELL)
|
|
{
|
|
for (auto &&record : cellRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- cell record %s\n-- baseId is %s", record.data.mName.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::SCRIPT)
|
|
{
|
|
for (auto &&record : scriptRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- script record %s\n-- baseId is %s", record.data.mId.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::BODYPART)
|
|
{
|
|
for (auto &&record : bodyPartRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- bodypart record %s\n-- baseId is %s", record.data.mId.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::SOUND)
|
|
{
|
|
for (auto&& record : soundRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- sound record %s\n-- baseId is %s", record.data.mId.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
else if (recordsType == mwmp::RECORD_TYPE::GAMESETTING)
|
|
{
|
|
for (auto&& record : gameSettingRecords)
|
|
{
|
|
bool hasBaseId = !record.baseId.empty();
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- gameSetting record %s\n-- baseId is %s", record.data.mId.c_str(),
|
|
hasBaseId ? record.baseId.c_str() : "empty");
|
|
|
|
RecordHelper::overrideRecord(record);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Worldstate::containsExploredMapTile(int cellX, int cellY)
|
|
{
|
|
for (const auto &mapTile : exploredMapTiles)
|
|
{
|
|
if (mapTile.x == cellX && mapTile.y == cellY)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void Worldstate::markExploredMapTile(int cellX, int cellY)
|
|
{
|
|
mwmp::MapTile exploredTile;
|
|
exploredTile.x = cellX;
|
|
exploredTile.y = cellY;
|
|
exploredMapTiles.push_back(exploredTile);
|
|
}
|
|
|
|
void Worldstate::setClientGlobals()
|
|
{
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received ID_CLIENT_SCRIPT_GLOBAL with the following global values:");
|
|
std::string debugMessage = "";
|
|
|
|
for (const auto &clientGlobal : clientGlobals)
|
|
{
|
|
if (TimedLog::GetLevel() <= TimedLog::LOG_INFO)
|
|
{
|
|
if (!debugMessage.empty())
|
|
debugMessage += ", ";
|
|
|
|
std::string variableTypeAsString;
|
|
std::string valueAsString;
|
|
|
|
if (clientGlobal.variableType == mwmp::VARIABLE_TYPE::SHORT || clientGlobal.variableType == mwmp::VARIABLE_TYPE::LONG)
|
|
{
|
|
variableTypeAsString = clientGlobal.variableType == mwmp::VARIABLE_TYPE::SHORT ? "short" : "long";
|
|
valueAsString = std::to_string(clientGlobal.intValue);
|
|
}
|
|
else if (clientGlobal.variableType == mwmp::VARIABLE_TYPE::FLOAT)
|
|
{
|
|
variableTypeAsString = "float";
|
|
valueAsString = std::to_string(clientGlobal.floatValue);
|
|
}
|
|
|
|
debugMessage += clientGlobal.id + ": " + variableTypeAsString + " " + valueAsString;
|
|
}
|
|
|
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
|
|
|
// If this global doesn't exist, create it
|
|
if (!world->hasGlobal(clientGlobal.id))
|
|
{
|
|
ESM::VarType varType;
|
|
|
|
if (clientGlobal.variableType == mwmp::VARIABLE_TYPE::SHORT)
|
|
varType = ESM::VarType::VT_Short;
|
|
else if (clientGlobal.variableType == mwmp::VARIABLE_TYPE::LONG)
|
|
varType = ESM::VarType::VT_Long;
|
|
if (clientGlobal.variableType == mwmp::VARIABLE_TYPE::FLOAT)
|
|
varType = ESM::VarType::VT_Float;
|
|
|
|
world->createGlobal(clientGlobal.id, varType);
|
|
}
|
|
|
|
if (clientGlobal.variableType == mwmp::VARIABLE_TYPE::SHORT || clientGlobal.variableType == mwmp::VARIABLE_TYPE::LONG)
|
|
world->setGlobalInt(clientGlobal.id, clientGlobal.intValue);
|
|
else if (clientGlobal.variableType == mwmp::VARIABLE_TYPE::FLOAT)
|
|
world->setGlobalFloat(clientGlobal.id, clientGlobal.floatValue);
|
|
}
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- %s", debugMessage.c_str());
|
|
}
|
|
|
|
void Worldstate::setKills()
|
|
{
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Received ID_WORLD_KILL_COUNT with the following kill counts:");
|
|
std::string debugMessage = "";
|
|
|
|
for (const auto &killChange : killChanges)
|
|
{
|
|
if (TimedLog::GetLevel() <= TimedLog::LOG_INFO)
|
|
{
|
|
if (!debugMessage.empty())
|
|
debugMessage += ", ";
|
|
|
|
debugMessage += killChange.refId + ": " + std::to_string(killChange.number);
|
|
}
|
|
|
|
MWBase::Environment::get().getMechanicsManager()->setDeaths(killChange.refId, killChange.number);
|
|
}
|
|
|
|
LOG_APPEND(TimedLog::LOG_INFO, "- %s", debugMessage.c_str());
|
|
}
|
|
|
|
void Worldstate::setMapExplored()
|
|
{
|
|
for (const auto &mapTile : mapTiles)
|
|
{
|
|
const MWWorld::CellStore *cellStore = MWBase::Environment::get().getWorld()->getExterior(mapTile.x, mapTile.y);
|
|
|
|
if (!cellStore->getCell()->mName.empty())
|
|
MWBase::Environment::get().getWindowManager()->addVisitedLocation(cellStore->getCell()->mName, mapTile.x, mapTile.y);
|
|
|
|
MWBase::Environment::get().getWindowManager()->setGlobalMapImage(mapTile.x, mapTile.y, mapTile.imageData);
|
|
|
|
// Keep this tile marked as explored so we don't send any more packets for it
|
|
markExploredMapTile(mapTile.x, mapTile.y);
|
|
}
|
|
}
|
|
|
|
void Worldstate::setWeather()
|
|
{
|
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
|
|
|
// There's a chance we've been sent the weather for a region right after a teleportation
|
|
// that hasn't been registered in the WeatherManager yet, meaning the WeatherManager
|
|
// doesn't have the correct new region set for us, so make sure we update it
|
|
world->updateWeather(0);
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Setting weather for region: %s, currentWeather: %i, "
|
|
"nextWeather: %i, queuedWeather: %i, transitionFactor: %f, forceWeather is %s",
|
|
weather.region.c_str(), weather.currentWeather, weather.nextWeather,
|
|
weather.queuedWeather, weather.transitionFactor, forceWeather ? "true" : "false");
|
|
|
|
world->setRegionWeather(weather.region.c_str(), weather.currentWeather, weather.nextWeather,
|
|
weather.queuedWeather, weather.transitionFactor, forceWeather);
|
|
}
|
|
|
|
void Worldstate::resetCells(std::vector<ESM::Cell>* cells)
|
|
{
|
|
MWBase::World* world = MWBase::Environment::get().getWorld();
|
|
|
|
bool haveUnloadedActiveCells = false;
|
|
ESM::Cell playerCell = *world->getPlayerPtr().getCell()->getCell();
|
|
ESM::Position playerPos = world->getPlayerPtr().getRefData().getPosition();
|
|
std::vector<RakNet::RakNetGUID> playersInCell;
|
|
|
|
for (auto cell : *cells)
|
|
{
|
|
if (!haveUnloadedActiveCells)
|
|
{
|
|
if (world->isCellActive(cell))
|
|
{
|
|
playersInCell = mwmp::PlayerList::getPlayersInCell(cell);
|
|
|
|
// If there are any DedicatedPlayers in this cell, also move them to the temporary holding interior cell
|
|
if (!playersInCell.empty())
|
|
{
|
|
for (RakNet::RakNetGUID otherGuid : playersInCell)
|
|
{
|
|
DedicatedPlayer* dedicatedPlayer = mwmp::PlayerList::getPlayer(otherGuid);
|
|
dedicatedPlayer->cell = *world->getInterior(RecordHelper::getPlaceholderInteriorCellName())->getCell();
|
|
dedicatedPlayer->setCell();
|
|
}
|
|
}
|
|
|
|
// Change to temporary holding interior cell
|
|
world->changeToInteriorCell(RecordHelper::getPlaceholderInteriorCellName(), playerPos, true, true);
|
|
|
|
mwmp::Main::get().getCellController()->uninitializeCells();
|
|
world->unloadActiveCells();
|
|
|
|
haveUnloadedActiveCells = true;
|
|
}
|
|
}
|
|
|
|
world->clearCellStore(cell);
|
|
|
|
for (RakNet::RakNetGUID otherGuid : playersInCell)
|
|
{
|
|
DedicatedPlayer* dedicatedPlayer = mwmp::PlayerList::getPlayer(otherGuid);
|
|
dedicatedPlayer->cell = cell;
|
|
dedicatedPlayer->setCell();
|
|
}
|
|
}
|
|
|
|
// Move the player from their temporary holding cell to their previous cell
|
|
if (haveUnloadedActiveCells)
|
|
{
|
|
if (playerCell.isExterior())
|
|
world->changeToExteriorCell(playerPos, true, true);
|
|
else
|
|
world->changeToInteriorCell(playerCell.mName, playerPos, true, true);
|
|
}
|
|
}
|
|
|
|
void Worldstate::sendClientGlobal(std::string varName, int value, mwmp::VARIABLE_TYPE variableType)
|
|
{
|
|
clientGlobals.clear();
|
|
|
|
mwmp::ClientVariable clientVariable;
|
|
clientVariable.id = varName;
|
|
clientVariable.variableType = variableType;
|
|
clientVariable.intValue = value;
|
|
|
|
std::string variableTypeAsString;
|
|
|
|
if (variableType == mwmp::VARIABLE_TYPE::SHORT)
|
|
variableTypeAsString = "short";
|
|
else if (variableType == mwmp::VARIABLE_TYPE::LONG)
|
|
variableTypeAsString = "long";
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_CLIENT_SCRIPT_GLOBAL with name %s, type %s, value %i",
|
|
varName.c_str(), variableTypeAsString.c_str(), value);
|
|
|
|
clientGlobals.push_back(clientVariable);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_CLIENT_SCRIPT_GLOBAL)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_CLIENT_SCRIPT_GLOBAL)->Send();
|
|
}
|
|
|
|
void Worldstate::sendClientGlobal(std::string varName, float value)
|
|
{
|
|
clientGlobals.clear();
|
|
|
|
mwmp::ClientVariable clientVariable;
|
|
clientVariable.id = varName;
|
|
clientVariable.variableType = mwmp::VARIABLE_TYPE::FLOAT;
|
|
clientVariable.floatValue = value;
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_CLIENT_SCRIPT_GLOBAL with name %s, type float, value %f", varName.c_str(), value);
|
|
|
|
clientGlobals.push_back(clientVariable);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_CLIENT_SCRIPT_GLOBAL)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_CLIENT_SCRIPT_GLOBAL)->Send();
|
|
}
|
|
|
|
void Worldstate::sendMapExplored(int cellX, int cellY, const std::vector<char>& imageData)
|
|
{
|
|
mapTiles.clear();
|
|
|
|
mwmp::MapTile mapTile;
|
|
mapTile.x = cellX;
|
|
mapTile.y = cellY;
|
|
mapTile.imageData = imageData;
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_PLAYER_MAP with x: %i, y: %i", cellX, cellY);
|
|
|
|
mapTiles.push_back(mapTile);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_WORLD_MAP)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_WORLD_MAP)->Send();
|
|
}
|
|
|
|
void Worldstate::sendWeather(std::string region, int currentWeather, int nextWeather, int queuedWeather, float transitionFactor)
|
|
{
|
|
forceWeather = false;
|
|
weather.region = region;
|
|
weather.currentWeather = currentWeather;
|
|
weather.nextWeather = nextWeather;
|
|
weather.queuedWeather = queuedWeather;
|
|
weather.transitionFactor = transitionFactor;
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_PLAYER_WEATHER with region: %s, currentWeather: %i, "
|
|
"nextWeather: %i, queuedWeather, %i, transitionFactor: %f",
|
|
region.c_str(), currentWeather, nextWeather, queuedWeather, transitionFactor);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_WORLD_WEATHER)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_WORLD_WEATHER)->Send();
|
|
}
|
|
|
|
void Worldstate::sendEnchantmentRecord(const ESM::Enchantment* enchantment)
|
|
{
|
|
enchantmentRecords.clear();
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_RECORD_DYNAMIC with enchantment");
|
|
|
|
recordsType = mwmp::RECORD_TYPE::ENCHANTMENT;
|
|
|
|
mwmp::EnchantmentRecord record;
|
|
record.data = *enchantment;
|
|
enchantmentRecords.push_back(record);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->Send();
|
|
}
|
|
|
|
void Worldstate::sendPotionRecord(const ESM::Potion* potion, unsigned int quantity)
|
|
{
|
|
potionRecords.clear();
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_RECORD_DYNAMIC with potion %s", potion->mName.c_str());
|
|
|
|
recordsType = mwmp::RECORD_TYPE::POTION;
|
|
|
|
mwmp::PotionRecord record;
|
|
record.data = *potion;
|
|
record.quantity = quantity;
|
|
potionRecords.push_back(record);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->Send();
|
|
}
|
|
|
|
void Worldstate::sendSpellRecord(const ESM::Spell* spell)
|
|
{
|
|
spellRecords.clear();
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_RECORD_DYNAMIC with spell %s", spell->mName.c_str());
|
|
|
|
recordsType = mwmp::RECORD_TYPE::SPELL;
|
|
|
|
mwmp::SpellRecord record;
|
|
record.data = *spell;
|
|
spellRecords.push_back(record);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->Send();
|
|
}
|
|
|
|
void Worldstate::sendArmorRecord(const ESM::Armor* armor, std::string baseId)
|
|
{
|
|
armorRecords.clear();
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_RECORD_DYNAMIC with armor %s", armor->mName.c_str());
|
|
|
|
recordsType = mwmp::RECORD_TYPE::ARMOR;
|
|
|
|
mwmp::ArmorRecord record;
|
|
record.data = *armor;
|
|
record.baseId = baseId;
|
|
record.baseOverrides.hasName = true;
|
|
record.baseOverrides.hasEnchantmentId = true;
|
|
record.baseOverrides.hasEnchantmentCharge = true;
|
|
armorRecords.push_back(record);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->Send();
|
|
}
|
|
|
|
void Worldstate::sendBookRecord(const ESM::Book* book, std::string baseId)
|
|
{
|
|
bookRecords.clear();
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_RECORD_DYNAMIC with book %s", book->mName.c_str());
|
|
|
|
recordsType = mwmp::RECORD_TYPE::BOOK;
|
|
|
|
mwmp::BookRecord record;
|
|
record.data = *book;
|
|
record.baseId = baseId;
|
|
record.baseOverrides.hasName = true;
|
|
record.baseOverrides.hasEnchantmentId = true;
|
|
record.baseOverrides.hasEnchantmentCharge = true;
|
|
bookRecords.push_back(record);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->Send();
|
|
}
|
|
|
|
void Worldstate::sendClothingRecord(const ESM::Clothing* clothing, std::string baseId)
|
|
{
|
|
clothingRecords.clear();
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_RECORD_DYNAMIC with clothing %s", clothing->mName.c_str());
|
|
|
|
recordsType = mwmp::RECORD_TYPE::CLOTHING;
|
|
|
|
mwmp::ClothingRecord record;
|
|
record.data = *clothing;
|
|
record.baseId = baseId;
|
|
record.baseOverrides.hasName = true;
|
|
record.baseOverrides.hasEnchantmentId = true;
|
|
record.baseOverrides.hasEnchantmentCharge = true;
|
|
clothingRecords.push_back(record);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->Send();
|
|
}
|
|
|
|
void Worldstate::sendWeaponRecord(const ESM::Weapon* weapon, std::string baseId, unsigned int quantity)
|
|
{
|
|
weaponRecords.clear();
|
|
|
|
LOG_MESSAGE_SIMPLE(TimedLog::LOG_INFO, "Sending ID_RECORD_DYNAMIC with weapon %s", weapon->mName.c_str());
|
|
|
|
recordsType = mwmp::RECORD_TYPE::WEAPON;
|
|
|
|
mwmp::WeaponRecord record;
|
|
record.data = *weapon;
|
|
record.quantity = quantity;
|
|
record.baseId = baseId;
|
|
record.baseOverrides.hasName = true;
|
|
record.baseOverrides.hasEnchantmentId = true;
|
|
record.baseOverrides.hasEnchantmentCharge = true;
|
|
weaponRecords.push_back(record);
|
|
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->setWorldstate(this);
|
|
getNetworking()->getWorldstatePacket(ID_RECORD_DYNAMIC)->Send();
|
|
}
|