[General] Implement activator & static records for RecordDynamic packets

pull/541/head
David Cernat 5 years ago
parent e9336e53fc
commit 247d2fad30

@ -24,6 +24,8 @@ MiscellaneousRecord tempMiscellaneous;
WeaponRecord tempWeapon;
ContainerRecord tempContainer;
DoorRecord tempDoor;
ActivatorRecord tempActivator;
StaticRecord tempStatic;
BaseOverrides tempOverrides;
@ -343,6 +345,10 @@ void RecordsDynamicFunctions::SetRecordId(const char* id) noexcept
tempContainer.data.mId = id;
else if (writeRecordsType == mwmp::RECORD_TYPE::DOOR)
tempDoor.data.mId = id;
else if (writeRecordsType == mwmp::RECORD_TYPE::ACTIVATOR)
tempActivator.data.mId = id;
else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC)
tempStatic.data.mId = id;
else
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set id for record type %i which lacks that property", writeRecordsType);
}
@ -375,6 +381,10 @@ void RecordsDynamicFunctions::SetRecordBaseId(const char* baseId) noexcept
tempContainer.baseId = baseId;
else if (writeRecordsType == mwmp::RECORD_TYPE::DOOR)
tempDoor.baseId = baseId;
else if (writeRecordsType == mwmp::RECORD_TYPE::ACTIVATOR)
tempActivator.baseId = baseId;
else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC)
tempStatic.baseId = baseId;
else
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set baseId for record type %i which lacks that property", writeRecordsType);
}
@ -442,6 +452,8 @@ void RecordsDynamicFunctions::SetRecordName(const char* name) noexcept
tempContainer.data.mName = name;
else if (writeRecordsType == mwmp::RECORD_TYPE::DOOR)
tempDoor.data.mName = name;
else if (writeRecordsType == mwmp::RECORD_TYPE::ACTIVATOR)
tempActivator.data.mName = name;
else
{
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set name for record type %i which lacks that property", writeRecordsType);
@ -475,6 +487,10 @@ void RecordsDynamicFunctions::SetRecordModel(const char* model) noexcept
tempContainer.data.mModel = model;
else if (writeRecordsType == mwmp::RECORD_TYPE::DOOR)
tempDoor.data.mModel = model;
else if (writeRecordsType == mwmp::RECORD_TYPE::ACTIVATOR)
tempActivator.data.mModel = model;
else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC)
tempStatic.data.mModel = model;
else
{
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set model for record type %i which lacks that property", writeRecordsType);
@ -533,6 +549,8 @@ void RecordsDynamicFunctions::SetRecordScript(const char* script) noexcept
tempContainer.data.mScript = script;
else if (writeRecordsType == mwmp::RECORD_TYPE::DOOR)
tempDoor.data.mScript = script;
else if (writeRecordsType == mwmp::RECORD_TYPE::ACTIVATOR)
tempActivator.data.mScript = script;
else
{
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set script for record type %i which lacks that property", writeRecordsType);
@ -1258,6 +1276,18 @@ void RecordsDynamicFunctions::AddRecord() noexcept
WorldstateFunctions::writeWorldstate.doorRecords.push_back(tempDoor);
tempDoor = {};
}
else if (writeRecordsType == mwmp::RECORD_TYPE::ACTIVATOR)
{
tempActivator.baseOverrides = tempOverrides;
WorldstateFunctions::writeWorldstate.activatorRecords.push_back(tempActivator);
tempActivator = {};
}
else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC)
{
tempStatic.baseOverrides = tempOverrides;
WorldstateFunctions::writeWorldstate.staticRecords.push_back(tempStatic);
tempStatic = {};
}
tempOverrides = {};
}

@ -104,6 +104,20 @@ bool RecordHelper::doesDoorRecordExist(const std::string& id)
return world->getStore().get<ESM::Door>().search(id);
}
bool RecordHelper::doesActivatorRecordExist(const std::string& id)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
return world->getStore().get<ESM::Activator>().search(id);
}
bool RecordHelper::doesStaticRecordExist(const std::string& id)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
return world->getStore().get<ESM::Static>().search(id);
}
std::string RecordHelper::createCreatureRecord(const ESM::Creature& record)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
@ -960,6 +974,88 @@ void RecordHelper::overrideDoorRecord(const mwmp::DoorRecord& record)
world->updatePtrsWithRefId(recordData.mId);
}
void RecordHelper::overrideActivatorRecord(const mwmp::ActivatorRecord& record)
{
const ESM::Activator &recordData = record.data;
if (recordData.mId.empty())
{
LOG_APPEND(Log::LOG_INFO, "-- Ignoring record override with no id provided");
return;
}
bool isExistingId = doesActivatorRecordExist(recordData.mId);
MWBase::World *world = MWBase::Environment::get().getWorld();
if (record.baseId.empty())
{
world->getModifiableStore().overrideRecord(recordData);
}
else if (doesActivatorRecordExist(record.baseId))
{
const ESM::Activator *baseData = world->getStore().get<ESM::Activator>().search(record.baseId);
ESM::Activator finalData = *baseData;
finalData.mId = recordData.mId;
if (record.baseOverrides.hasName)
finalData.mName = recordData.mName;
if (record.baseOverrides.hasModel)
finalData.mModel = recordData.mModel;
if (record.baseOverrides.hasScript)
finalData.mScript = recordData.mScript;
world->getModifiableStore().overrideRecord(finalData);
}
else
{
LOG_APPEND(Log::LOG_INFO, "-- Ignoring record override with invalid baseId %s", record.baseId.c_str());
return;
}
if (isExistingId)
world->updatePtrsWithRefId(recordData.mId);
}
void RecordHelper::overrideStaticRecord(const mwmp::StaticRecord& record)
{
const ESM::Static &recordData = record.data;
if (recordData.mId.empty())
{
LOG_APPEND(Log::LOG_INFO, "-- Ignoring record override with no id provided");
return;
}
bool isExistingId = doesStaticRecordExist(recordData.mId);
MWBase::World *world = MWBase::Environment::get().getWorld();
if (record.baseId.empty())
{
world->getModifiableStore().overrideRecord(recordData);
}
else if (doesStaticRecordExist(record.baseId))
{
const ESM::Static *baseData = world->getStore().get<ESM::Static>().search(record.baseId);
ESM::Static finalData = *baseData;
finalData.mId = recordData.mId;
if (record.baseOverrides.hasModel)
finalData.mModel = recordData.mModel;
world->getModifiableStore().overrideRecord(finalData);
}
else
{
LOG_APPEND(Log::LOG_INFO, "-- Ignoring record override with invalid baseId %s", record.baseId.c_str());
return;
}
if (isExistingId)
world->updatePtrsWithRefId(recordData.mId);
}
void RecordHelper::overrideCreatureRecord(const ESM::Creature& record)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1043,3 +1139,17 @@ void RecordHelper::overrideDoorRecord(const ESM::Door& record)
world->getModifiableStore().overrideRecord(record);
}
void RecordHelper::overrideActivatorRecord(const ESM::Activator& record)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
world->getModifiableStore().overrideRecord(record);
}
void RecordHelper::overrideStaticRecord(const ESM::Static& record)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
world->getModifiableStore().overrideRecord(record);
}

@ -27,6 +27,9 @@ namespace RecordHelper
bool doesContainerRecordExist(const std::string& id);
bool doesDoorRecordExist(const std::string& id);
bool doesActivatorRecordExist(const std::string& id);
bool doesStaticRecordExist(const std::string& id);
std::string createCreatureRecord(const ESM::Creature& record);
std::string createNpcRecord(const ESM::NPC& record);
@ -46,6 +49,9 @@ namespace RecordHelper
void overrideContainerRecord(const mwmp::ContainerRecord& record);
void overrideDoorRecord(const mwmp::DoorRecord& record);
void overrideActivatorRecord(const mwmp::ActivatorRecord& record);
void overrideStaticRecord(const mwmp::StaticRecord& record);
void overrideCreatureRecord(const ESM::Creature& record);
void overrideNpcRecord(const ESM::NPC& record);
@ -61,6 +67,9 @@ namespace RecordHelper
void overrideContainerRecord(const ESM::Container& record);
void overrideDoorRecord(const ESM::Door& record);
void overrideActivatorRecord(const ESM::Activator& record);
void overrideStaticRecord(const ESM::Static& record);
}

@ -182,6 +182,30 @@ void Worldstate::addRecords()
RecordHelper::overrideDoorRecord(record);
}
}
else if (recordsType == mwmp::RECORD_TYPE::ACTIVATOR)
{
for (auto &&record : activatorRecords)
{
bool hasBaseId = !record.baseId.empty();
LOG_APPEND(Log::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::overrideActivatorRecord(record);
}
}
else if (recordsType == mwmp::RECORD_TYPE::STATIC)
{
for (auto &&record : staticRecords)
{
bool hasBaseId = !record.baseId.empty();
LOG_APPEND(Log::LOG_INFO, "- static record %s\n-- baseId is %s", record.data.mId.c_str(),
hasBaseId ? record.baseId.c_str() : "empty");
RecordHelper::overrideStaticRecord(record);
}
}
}
bool Worldstate::containsExploredMapTile(int cellX, int cellY)

@ -3,6 +3,7 @@
#include <vector>
#include <components/esm/loadacti.hpp>
#include <components/esm/loadalch.hpp>
#include <components/esm/loadarmo.hpp>
#include <components/esm/loadbook.hpp>
@ -14,6 +15,7 @@
#include <components/esm/loadmisc.hpp>
#include <components/esm/loadnpc.hpp>
#include <components/esm/loadspel.hpp>
#include <components/esm/loadstat.hpp>
#include <components/esm/loadweap.hpp>
#include <components/openmw-mp/Base/BaseStructs.hpp>
@ -35,7 +37,9 @@ namespace mwmp
SPELL,
WEAPON,
CONTAINER,
DOOR
DOOR,
ACTIVATOR,
STATIC
};
// When using an existing record as a base, this struct tracks which changes
@ -100,6 +104,13 @@ namespace mwmp
bool hasCloseSound = false;
};
struct ActivatorRecord
{
ESM::Activator data;
std::string baseId;
BaseOverrides baseOverrides;
};
struct ArmorRecord
{
ESM::Armor data;
@ -182,6 +193,13 @@ namespace mwmp
BaseOverrides baseOverrides;
};
struct StaticRecord
{
ESM::Static data;
std::string baseId;
BaseOverrides baseOverrides;
};
struct WeaponRecord
{
ESM::Weapon data;
@ -243,6 +261,7 @@ namespace mwmp
unsigned short recordsType;
unsigned int recordsCount;
std::vector<ActivatorRecord> activatorRecords;
std::vector<ArmorRecord> armorRecords;
std::vector<BookRecord> bookRecords;
std::vector<ClothingRecord> clothingRecords;
@ -254,6 +273,7 @@ namespace mwmp
std::vector<NpcRecord> npcRecords;
std::vector<PotionRecord> potionRecords;
std::vector<SpellRecord> spellRecords;
std::vector<StaticRecord> staticRecords;
std::vector<WeaponRecord> weaponRecords;
bool isValid;

@ -44,6 +44,10 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
worldstate->recordsCount = Utils::getVectorSize(worldstate->containerRecords);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::DOOR)
worldstate->recordsCount = Utils::getVectorSize(worldstate->doorRecords);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::ACTIVATOR)
worldstate->recordsCount = Utils::getVectorSize(worldstate->activatorRecords);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::STATIC)
worldstate->recordsCount = Utils::getVectorSize(worldstate->staticRecords);
else
{
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Processed invalid ID_RECORD_DYNAMIC packet about unimplemented recordsType %i",
@ -88,6 +92,10 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
Utils::resetVector(worldstate->containerRecords, worldstate->recordsCount);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::DOOR)
Utils::resetVector(worldstate->doorRecords, worldstate->recordsCount);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::ACTIVATOR)
Utils::resetVector(worldstate->activatorRecords, worldstate->recordsCount);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::STATIC)
Utils::resetVector(worldstate->staticRecords, worldstate->recordsCount);
}
if (worldstate->recordsType == mwmp::RECORD_TYPE::SPELL)
@ -498,6 +506,44 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
}
}
}
else if (worldstate->recordsType == mwmp::RECORD_TYPE::ACTIVATOR)
{
for (auto &&record : worldstate->activatorRecords)
{
auto &recordData = record.data;
RW(record.baseId, send, true);
RW(recordData.mId, send, true);
RW(recordData.mName, send, true);
RW(recordData.mModel, send, true);
RW(recordData.mScript, send, true);
if (!record.baseId.empty())
{
auto &&overrides = record.baseOverrides;
RW(overrides.hasName, send);
RW(overrides.hasModel, send);
RW(overrides.hasScript, send);
}
}
}
else if (worldstate->recordsType == mwmp::RECORD_TYPE::STATIC)
{
for (auto &&record : worldstate->staticRecords)
{
auto &recordData = record.data;
RW(record.baseId, send, true);
RW(recordData.mId, send, true);
RW(recordData.mModel, send, true);
if (!record.baseId.empty())
{
auto &&overrides = record.baseOverrides;
RW(overrides.hasModel, send);
}
}
}
}
void PacketRecordDynamic::ProcessEffects(ESM::EffectList &effectList, bool send)

Loading…
Cancel
Save