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:
parent
18a7ac5940
commit
031acffcbe
6 changed files with 121 additions and 1 deletions
|
@ -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 = {};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue