1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-30 03:06:43 +00:00

[General] Implement cell records for RecordDynamic packets, part 1

New interior cells can be now be created that are either blank or based on existing interior cells.
This commit is contained in:
David Cernat 2019-09-28 13:12:48 +03:00
parent 18a7ac5940
commit 031acffcbe
6 changed files with 121 additions and 1 deletions

View file

@ -32,6 +32,7 @@ LockpickRecord tempLockpick;
ProbeRecord tempProbe;
RepairRecord tempRepair;
LightRecord tempLight;
CellRecord tempCell;
BaseOverrides tempOverrides;
@ -78,6 +79,7 @@ void RecordsDynamicFunctions::ClearRecords() noexcept
WorldstateFunctions::writeWorldstate.probeRecords.clear();
WorldstateFunctions::writeWorldstate.repairRecords.clear();
WorldstateFunctions::writeWorldstate.lightRecords.clear();
WorldstateFunctions::writeWorldstate.cellRecords.clear();
}
unsigned short RecordsDynamicFunctions::GetRecordType() noexcept
@ -426,6 +428,8 @@ void RecordsDynamicFunctions::SetRecordBaseId(const char* baseId) noexcept
tempRepair.baseId = baseId;
else if (writeRecordsType == mwmp::RECORD_TYPE::LIGHT)
tempLight.baseId = baseId;
else if (writeRecordsType == mwmp::RECORD_TYPE::CELL)
tempCell.baseId = baseId;
else
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set baseId for record type %i which lacks that property", writeRecordsType);
}
@ -509,6 +513,8 @@ void RecordsDynamicFunctions::SetRecordName(const char* name) noexcept
tempRepair.data.mName = name;
else if (writeRecordsType == mwmp::RECORD_TYPE::LIGHT)
tempLight.data.mName = name;
else if (writeRecordsType == mwmp::RECORD_TYPE::CELL)
tempCell.data.mName = name;
else
{
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set name for record type %i which lacks that property", writeRecordsType);
@ -1594,6 +1600,12 @@ void RecordsDynamicFunctions::AddRecord() noexcept
WorldstateFunctions::writeWorldstate.lightRecords.push_back(tempLight);
tempLight = {};
}
else if (writeRecordsType == mwmp::RECORD_TYPE::CELL)
{
tempCell.baseOverrides = tempOverrides;
WorldstateFunctions::writeWorldstate.cellRecords.push_back(tempCell);
tempCell = {};
}
effectCount = 0;
tempOverrides = {};

View file

@ -2,6 +2,7 @@
#include "../mwbase/environment.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/worldimp.hpp"
#include "RecordHelper.hpp"
@ -160,6 +161,13 @@ bool RecordHelper::doesLightRecordExist(const std::string& id)
return world->getStore().get<ESM::Light>().search(id);
}
bool RecordHelper::doesCellRecordExist(const std::string& id)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
return world->getStore().get<ESM::Cell>().search(id);
}
std::string RecordHelper::createCreatureRecord(const ESM::Creature& record)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1485,6 +1493,61 @@ void RecordHelper::overrideLightRecord(const mwmp::LightRecord& record)
world->updatePtrsWithRefId(recordData.mId);
}
void RecordHelper::overrideCellRecord(const mwmp::CellRecord& record)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
ESM::Cell recordData = record.data;
if (recordData.mName.empty())
{
LOG_APPEND(TimedLog::LOG_INFO, "-- Ignoring record override with no id provided");
return;
}
MWWorld::Ptr playerPtr = world->getPlayerPtr();
bool isCurrentCell = Misc::StringUtils::ciEqual(recordData.mName, playerPtr.getCell()->getCell()->mName);
if (record.baseId.empty())
{
recordData.mData.mFlags |= ESM::Cell::Flags::Interior;
world->unloadCell(recordData);
world->clearCellStore(recordData);
world->getModifiableStore().overrideRecord(recordData);
}
else if (doesCellRecordExist(record.baseId))
{
const ESM::Cell *baseData = world->getStore().get<ESM::Cell>().search(record.baseId);
ESM::Cell finalData = *baseData;
finalData.mName = recordData.mName;
world->unloadCell(finalData);
world->clearCellStore(finalData);
world->getModifiableStore().overrideRecord(finalData);
}
else
{
LOG_APPEND(TimedLog::LOG_INFO, "-- Ignoring record override with invalid baseId %s", record.baseId.c_str());
return;
}
if (isCurrentCell)
{
// As a temporary solution, move the player to exterior 0, 0, but
// fix this once it's possible to override exteriors cells as well
ESM::Position tempPos;
tempPos.pos[0] = 0;
tempPos.pos[1] = 0;
tempPos.pos[2] = 0;
ESM::Position playerPos = playerPtr.getRefData().getPosition();
world->changeToExteriorCell(tempPos, true, true);
world->changeToInteriorCell(recordData.mName, playerPos, true, true);
}
}
void RecordHelper::overrideCreatureRecord(const ESM::Creature& record)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1624,3 +1687,10 @@ void RecordHelper::overrideLightRecord(const ESM::Light& record)
world->getModifiableStore().overrideRecord(record);
}
void RecordHelper::overrideCellRecord(const ESM::Cell& record)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
world->getModifiableStore().overrideRecord(record);
}

View file

@ -36,6 +36,7 @@ namespace RecordHelper
bool doesProbeRecordExist(const std::string& id);
bool doesRepairRecordExist(const std::string& id);
bool doesLightRecordExist(const std::string& id);
bool doesCellRecordExist(const std::string& id);
std::string createCreatureRecord(const ESM::Creature& record);
std::string createNpcRecord(const ESM::NPC& record);
@ -65,6 +66,7 @@ namespace RecordHelper
void overrideProbeRecord(const mwmp::ProbeRecord& record);
void overrideRepairRecord(const mwmp::RepairRecord& record);
void overrideLightRecord(const mwmp::LightRecord& record);
void overrideCellRecord(const mwmp::CellRecord& record);
void overrideCreatureRecord(const ESM::Creature& record);
void overrideNpcRecord(const ESM::NPC& record);
@ -91,6 +93,7 @@ namespace RecordHelper
void overrideProbeRecord(const ESM::Probe& record);
void overrideRepairRecord(const ESM::Repair& record);
void overrideLightRecord(const ESM::Light& record);
void overrideCellRecord(const ESM::Cell& record);
}

View file

@ -278,6 +278,18 @@ void Worldstate::addRecords()
RecordHelper::overrideLightRecord(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::overrideCellRecord(record);
}
}
}
bool Worldstate::containsExploredMapTile(int cellX, int cellY)

View file

@ -51,7 +51,8 @@ namespace mwmp
LOCKPICK,
PROBE,
REPAIR,
LIGHT
LIGHT,
CELL
};
// When using an existing record as a base, this struct tracks which changes
@ -154,6 +155,13 @@ namespace mwmp
BaseOverrides baseOverrides;
};
struct CellRecord
{
ESM::Cell data;
std::string baseId;
BaseOverrides baseOverrides;
};
struct ClothingRecord
{
ESM::Clothing data;
@ -331,6 +339,7 @@ namespace mwmp
std::vector<ApparatusRecord> apparatusRecords;
std::vector<ArmorRecord> armorRecords;
std::vector<BookRecord> bookRecords;
std::vector<CellRecord> cellRecords;
std::vector<ClothingRecord> clothingRecords;
std::vector<ContainerRecord> containerRecords;
std::vector<CreatureRecord> creatureRecords;

View file

@ -60,6 +60,8 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
worldstate->recordsCount = Utils::getVectorSize(worldstate->repairRecords);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::LIGHT)
worldstate->recordsCount = Utils::getVectorSize(worldstate->lightRecords);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::CELL)
worldstate->recordsCount = Utils::getVectorSize(worldstate->cellRecords);
else
{
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Processed invalid ID_RECORD_DYNAMIC packet about unimplemented recordsType %i",
@ -120,6 +122,8 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
Utils::resetVector(worldstate->repairRecords, worldstate->recordsCount);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::LIGHT)
Utils::resetVector(worldstate->lightRecords, worldstate->recordsCount);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::CELL)
Utils::resetVector(worldstate->cellRecords, worldstate->recordsCount);
}
if (worldstate->recordsType == mwmp::RECORD_TYPE::SPELL)
@ -773,6 +777,16 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
}
}
}
else if (worldstate->recordsType == mwmp::RECORD_TYPE::CELL)
{
for (auto &&record : worldstate->cellRecords)
{
auto &recordData = record.data;
RW(record.baseId, send, true);
RW(record.data.mName, send, true);
}
}
}
void PacketRecordDynamic::ProcessEffects(ESM::EffectList &effectList, bool send)