[General] Implement ingredient records for RecordDynamic packets

pull/541/head
David Cernat 5 years ago
parent 300cef0073
commit 4100d93dea

@ -26,9 +26,11 @@ ContainerRecord tempContainer;
DoorRecord tempDoor; DoorRecord tempDoor;
ActivatorRecord tempActivator; ActivatorRecord tempActivator;
StaticRecord tempStatic; StaticRecord tempStatic;
IngredientRecord tempIngredient;
BaseOverrides tempOverrides; BaseOverrides tempOverrides;
unsigned int effectCount = 0;
ESM::ENAMstruct tempEffect; ESM::ENAMstruct tempEffect;
ESM::PartReference tempBodyPart; ESM::PartReference tempBodyPart;
mwmp::Item tempInventoryItem; mwmp::Item tempInventoryItem;
@ -65,6 +67,7 @@ void RecordsDynamicFunctions::ClearRecords() noexcept
WorldstateFunctions::writeWorldstate.doorRecords.clear(); WorldstateFunctions::writeWorldstate.doorRecords.clear();
WorldstateFunctions::writeWorldstate.activatorRecords.clear(); WorldstateFunctions::writeWorldstate.activatorRecords.clear();
WorldstateFunctions::writeWorldstate.staticRecords.clear(); WorldstateFunctions::writeWorldstate.staticRecords.clear();
WorldstateFunctions::writeWorldstate.ingredientRecords.clear();
} }
unsigned short RecordsDynamicFunctions::GetRecordType() noexcept unsigned short RecordsDynamicFunctions::GetRecordType() noexcept
@ -353,6 +356,8 @@ void RecordsDynamicFunctions::SetRecordId(const char* id) noexcept
tempActivator.data.mId = id; tempActivator.data.mId = id;
else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC) else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC)
tempStatic.data.mId = id; tempStatic.data.mId = id;
else if (writeRecordsType == mwmp::RECORD_TYPE::INGREDIENT)
tempIngredient.data.mId = id;
else else
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set id for record type %i which lacks that property", writeRecordsType); LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set id for record type %i which lacks that property", writeRecordsType);
} }
@ -389,6 +394,8 @@ void RecordsDynamicFunctions::SetRecordBaseId(const char* baseId) noexcept
tempActivator.baseId = baseId; tempActivator.baseId = baseId;
else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC) else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC)
tempStatic.baseId = baseId; tempStatic.baseId = baseId;
else if (writeRecordsType == mwmp::RECORD_TYPE::INGREDIENT)
tempIngredient.baseId = baseId;
else else
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set baseId for record type %i which lacks that property", writeRecordsType); LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set baseId for record type %i which lacks that property", writeRecordsType);
} }
@ -458,6 +465,8 @@ void RecordsDynamicFunctions::SetRecordName(const char* name) noexcept
tempDoor.data.mName = name; tempDoor.data.mName = name;
else if (writeRecordsType == mwmp::RECORD_TYPE::ACTIVATOR) else if (writeRecordsType == mwmp::RECORD_TYPE::ACTIVATOR)
tempActivator.data.mName = name; tempActivator.data.mName = name;
else if (writeRecordsType == mwmp::RECORD_TYPE::INGREDIENT)
tempIngredient.data.mName = name;
else else
{ {
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set name for record type %i which lacks that property", writeRecordsType); LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set name for record type %i which lacks that property", writeRecordsType);
@ -495,6 +504,8 @@ void RecordsDynamicFunctions::SetRecordModel(const char* model) noexcept
tempActivator.data.mModel = model; tempActivator.data.mModel = model;
else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC) else if (writeRecordsType == mwmp::RECORD_TYPE::STATIC)
tempStatic.data.mModel = model; tempStatic.data.mModel = model;
else if (writeRecordsType == mwmp::RECORD_TYPE::INGREDIENT)
tempIngredient.data.mModel = model;
else else
{ {
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set model for record type %i which lacks that property", writeRecordsType); LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set model for record type %i which lacks that property", writeRecordsType);
@ -520,6 +531,8 @@ void RecordsDynamicFunctions::SetRecordIcon(const char* icon) noexcept
tempMiscellaneous.data.mIcon = icon; tempMiscellaneous.data.mIcon = icon;
else if (writeRecordsType == mwmp::RECORD_TYPE::WEAPON) else if (writeRecordsType == mwmp::RECORD_TYPE::WEAPON)
tempWeapon.data.mIcon = icon; tempWeapon.data.mIcon = icon;
else if (writeRecordsType == mwmp::RECORD_TYPE::INGREDIENT)
tempIngredient.data.mIcon = icon;
else else
{ {
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set icon for record type %i which lacks that property", writeRecordsType); LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set icon for record type %i which lacks that property", writeRecordsType);
@ -555,6 +568,8 @@ void RecordsDynamicFunctions::SetRecordScript(const char* script) noexcept
tempDoor.data.mScript = script; tempDoor.data.mScript = script;
else if (writeRecordsType == mwmp::RECORD_TYPE::ACTIVATOR) else if (writeRecordsType == mwmp::RECORD_TYPE::ACTIVATOR)
tempActivator.data.mScript = script; tempActivator.data.mScript = script;
else if (writeRecordsType == mwmp::RECORD_TYPE::INGREDIENT)
tempIngredient.data.mScript = script;
else else
{ {
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set script for record type %i which lacks that property", writeRecordsType); LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set script for record type %i which lacks that property", writeRecordsType);
@ -707,6 +722,8 @@ void RecordsDynamicFunctions::SetRecordValue(int value) noexcept
tempMiscellaneous.data.mData.mValue = value; tempMiscellaneous.data.mData.mValue = value;
else if (writeRecordsType == mwmp::RECORD_TYPE::WEAPON) else if (writeRecordsType == mwmp::RECORD_TYPE::WEAPON)
tempWeapon.data.mData.mValue = value; tempWeapon.data.mData.mValue = value;
else if (writeRecordsType == mwmp::RECORD_TYPE::INGREDIENT)
tempIngredient.data.mData.mValue = value;
else else
{ {
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set value for record type %i which lacks that property", writeRecordsType); LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set value for record type %i which lacks that property", writeRecordsType);
@ -734,6 +751,8 @@ void RecordsDynamicFunctions::SetRecordWeight(double weight) noexcept
tempWeapon.data.mData.mWeight = weight; tempWeapon.data.mData.mWeight = weight;
else if (writeRecordsType == mwmp::RECORD_TYPE::CONTAINER) else if (writeRecordsType == mwmp::RECORD_TYPE::CONTAINER)
tempContainer.data.mWeight = weight; tempContainer.data.mWeight = weight;
else if (writeRecordsType == mwmp::RECORD_TYPE::INGREDIENT)
tempIngredient.data.mData.mWeight = weight;
else else
{ {
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set weight for record type %i which lacks that property", writeRecordsType); LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Tried to set weight for record type %i which lacks that property", writeRecordsType);
@ -1294,7 +1313,14 @@ void RecordsDynamicFunctions::AddRecord() noexcept
WorldstateFunctions::writeWorldstate.staticRecords.push_back(tempStatic); WorldstateFunctions::writeWorldstate.staticRecords.push_back(tempStatic);
tempStatic = {}; tempStatic = {};
} }
else if (writeRecordsType == mwmp::RECORD_TYPE::INGREDIENT)
{
tempIngredient.baseOverrides = tempOverrides;
WorldstateFunctions::writeWorldstate.ingredientRecords.push_back(tempIngredient);
tempIngredient = {};
}
effectCount = 0;
tempOverrides = {}; tempOverrides = {};
} }
@ -1308,8 +1334,25 @@ void RecordsDynamicFunctions::AddRecordEffect() noexcept
tempPotion.data.mEffects.mList.push_back(tempEffect); tempPotion.data.mEffects.mList.push_back(tempEffect);
else if (writeRecordsType == mwmp::RECORD_TYPE::ENCHANTMENT) else if (writeRecordsType == mwmp::RECORD_TYPE::ENCHANTMENT)
tempEnchantment.data.mEffects.mList.push_back(tempEffect); tempEnchantment.data.mEffects.mList.push_back(tempEffect);
else if (writeRecordsType == mwmp::RECORD_TYPE::INGREDIENT)
{
const static unsigned int effectCap = sizeof(tempIngredient.data.mData.mEffectID) / sizeof(tempIngredient.data.mData.mEffectID[0]);
if (effectCount < effectCap)
{
tempIngredient.data.mData.mEffectID[effectCount] = tempEffect.mEffectID;
tempIngredient.data.mData.mAttributes[effectCount] = tempEffect.mAttribute;
tempIngredient.data.mData.mSkills[effectCount] = tempEffect.mSkill;
}
else
{
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Could not add record effect to temporary ingredient record because the cap of %i effects has been reached",
effectCap);
}
}
tempOverrides.hasEffects = true; tempOverrides.hasEffects = true;
effectCount++;
tempEffect = {}; tempEffect = {};
} }

@ -118,6 +118,13 @@ bool RecordHelper::doesStaticRecordExist(const std::string& id)
return world->getStore().get<ESM::Static>().search(id); return world->getStore().get<ESM::Static>().search(id);
} }
bool RecordHelper::doesIngredientRecordExist(const std::string& id)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
return world->getStore().get<ESM::Ingredient>().search(id);
}
std::string RecordHelper::createCreatureRecord(const ESM::Creature& record) std::string RecordHelper::createCreatureRecord(const ESM::Creature& record)
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1056,6 +1063,71 @@ void RecordHelper::overrideStaticRecord(const mwmp::StaticRecord& record)
world->updatePtrsWithRefId(recordData.mId); world->updatePtrsWithRefId(recordData.mId);
} }
void RecordHelper::overrideIngredientRecord(const mwmp::IngredientRecord& record)
{
const ESM::Ingredient &recordData = record.data;
if (recordData.mId.empty())
{
LOG_APPEND(Log::LOG_INFO, "-- Ignoring record override with no id provided");
return;
}
bool isExistingId = doesIngredientRecordExist(recordData.mId);
MWBase::World *world = MWBase::Environment::get().getWorld();
if (record.baseId.empty())
{
world->getModifiableStore().overrideRecord(recordData);
}
else if (doesIngredientRecordExist(record.baseId))
{
const ESM::Ingredient *baseData = world->getStore().get<ESM::Ingredient>().search(record.baseId);
ESM::Ingredient 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.hasIcon)
finalData.mIcon = recordData.mIcon;
if (record.baseOverrides.hasWeight)
finalData.mData.mWeight = recordData.mData.mWeight;
if (record.baseOverrides.hasValue)
finalData.mData.mValue = recordData.mData.mValue;
if (record.baseOverrides.hasScript)
finalData.mScript = recordData.mScript;
if (record.baseOverrides.hasEffects)
{
const static unsigned int effectCap = sizeof(recordData.mData.mEffectID) / sizeof(recordData.mData.mEffectID[0]);
for (int effectIndex = 0; effectIndex < effectCap; effectIndex++)
{
finalData.mData.mEffectID[effectIndex] = recordData.mData.mEffectID[effectIndex];
finalData.mData.mAttributes[effectIndex] = recordData.mData.mAttributes[effectIndex];
finalData.mData.mSkills[effectIndex] = recordData.mData.mSkills[effectIndex];
}
}
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) void RecordHelper::overrideCreatureRecord(const ESM::Creature& record)
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
@ -1153,3 +1225,10 @@ void RecordHelper::overrideStaticRecord(const ESM::Static& record)
world->getModifiableStore().overrideRecord(record); world->getModifiableStore().overrideRecord(record);
} }
void RecordHelper::overrideIngredientRecord(const ESM::Ingredient& record)
{
MWBase::World *world = MWBase::Environment::get().getWorld();
world->getModifiableStore().overrideRecord(record);
}

@ -30,6 +30,8 @@ namespace RecordHelper
bool doesActivatorRecordExist(const std::string& id); bool doesActivatorRecordExist(const std::string& id);
bool doesStaticRecordExist(const std::string& id); bool doesStaticRecordExist(const std::string& id);
bool doesIngredientRecordExist(const std::string& id);
std::string createCreatureRecord(const ESM::Creature& record); std::string createCreatureRecord(const ESM::Creature& record);
std::string createNpcRecord(const ESM::NPC& record); std::string createNpcRecord(const ESM::NPC& record);
@ -52,6 +54,8 @@ namespace RecordHelper
void overrideActivatorRecord(const mwmp::ActivatorRecord& record); void overrideActivatorRecord(const mwmp::ActivatorRecord& record);
void overrideStaticRecord(const mwmp::StaticRecord& record); void overrideStaticRecord(const mwmp::StaticRecord& record);
void overrideIngredientRecord(const mwmp::IngredientRecord& record);
void overrideCreatureRecord(const ESM::Creature& record); void overrideCreatureRecord(const ESM::Creature& record);
void overrideNpcRecord(const ESM::NPC& record); void overrideNpcRecord(const ESM::NPC& record);
@ -70,6 +74,8 @@ namespace RecordHelper
void overrideActivatorRecord(const ESM::Activator& record); void overrideActivatorRecord(const ESM::Activator& record);
void overrideStaticRecord(const ESM::Static& record); void overrideStaticRecord(const ESM::Static& record);
void overrideIngredientRecord(const ESM::Ingredient& record);
} }

@ -206,6 +206,18 @@ void Worldstate::addRecords()
RecordHelper::overrideStaticRecord(record); RecordHelper::overrideStaticRecord(record);
} }
} }
else if (recordsType == mwmp::RECORD_TYPE::INGREDIENT)
{
for (auto &&record : ingredientRecords)
{
bool hasBaseId = !record.baseId.empty();
LOG_APPEND(Log::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::overrideIngredientRecord(record);
}
}
} }
bool Worldstate::containsExploredMapTile(int cellX, int cellY) bool Worldstate::containsExploredMapTile(int cellX, int cellY)

@ -12,6 +12,7 @@
#include <components/esm/loadcrea.hpp> #include <components/esm/loadcrea.hpp>
#include <components/esm/loaddoor.hpp> #include <components/esm/loaddoor.hpp>
#include <components/esm/loadench.hpp> #include <components/esm/loadench.hpp>
#include <components/esm/loadingr.hpp>
#include <components/esm/loadmisc.hpp> #include <components/esm/loadmisc.hpp>
#include <components/esm/loadnpc.hpp> #include <components/esm/loadnpc.hpp>
#include <components/esm/loadspel.hpp> #include <components/esm/loadspel.hpp>
@ -39,7 +40,8 @@ namespace mwmp
CONTAINER, CONTAINER,
DOOR, DOOR,
ACTIVATOR, ACTIVATOR,
STATIC STATIC,
INGREDIENT
}; };
// When using an existing record as a base, this struct tracks which changes // When using an existing record as a base, this struct tracks which changes
@ -163,6 +165,13 @@ namespace mwmp
BaseOverrides baseOverrides; BaseOverrides baseOverrides;
}; };
struct IngredientRecord
{
ESM::Ingredient data;
std::string baseId;
BaseOverrides baseOverrides;
};
struct MiscellaneousRecord struct MiscellaneousRecord
{ {
ESM::Miscellaneous data; ESM::Miscellaneous data;
@ -269,6 +278,7 @@ namespace mwmp
std::vector<CreatureRecord> creatureRecords; std::vector<CreatureRecord> creatureRecords;
std::vector<DoorRecord> doorRecords; std::vector<DoorRecord> doorRecords;
std::vector<EnchantmentRecord> enchantmentRecords; std::vector<EnchantmentRecord> enchantmentRecords;
std::vector<IngredientRecord> ingredientRecords;
std::vector<MiscellaneousRecord> miscellaneousRecords; std::vector<MiscellaneousRecord> miscellaneousRecords;
std::vector<NpcRecord> npcRecords; std::vector<NpcRecord> npcRecords;
std::vector<PotionRecord> potionRecords; std::vector<PotionRecord> potionRecords;

@ -48,6 +48,8 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
worldstate->recordsCount = Utils::getVectorSize(worldstate->activatorRecords); worldstate->recordsCount = Utils::getVectorSize(worldstate->activatorRecords);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::STATIC) else if (worldstate->recordsType == mwmp::RECORD_TYPE::STATIC)
worldstate->recordsCount = Utils::getVectorSize(worldstate->staticRecords); worldstate->recordsCount = Utils::getVectorSize(worldstate->staticRecords);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::INGREDIENT)
worldstate->recordsCount = Utils::getVectorSize(worldstate->ingredientRecords);
else else
{ {
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Processed invalid ID_RECORD_DYNAMIC packet about unimplemented recordsType %i", LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "Processed invalid ID_RECORD_DYNAMIC packet about unimplemented recordsType %i",
@ -96,6 +98,8 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
Utils::resetVector(worldstate->activatorRecords, worldstate->recordsCount); Utils::resetVector(worldstate->activatorRecords, worldstate->recordsCount);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::STATIC) else if (worldstate->recordsType == mwmp::RECORD_TYPE::STATIC)
Utils::resetVector(worldstate->staticRecords, worldstate->recordsCount); Utils::resetVector(worldstate->staticRecords, worldstate->recordsCount);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::INGREDIENT)
Utils::resetVector(worldstate->ingredientRecords, worldstate->recordsCount);
} }
if (worldstate->recordsType == mwmp::RECORD_TYPE::SPELL) if (worldstate->recordsType == mwmp::RECORD_TYPE::SPELL)
@ -544,6 +548,37 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
} }
} }
} }
else if (worldstate->recordsType == mwmp::RECORD_TYPE::INGREDIENT)
{
for (auto &&record : worldstate->ingredientRecords)
{
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.mIcon, send, true);
RW(recordData.mData.mWeight, send);
RW(recordData.mData.mValue, send);
RW(recordData.mData.mEffectID, send);
RW(recordData.mData.mAttributes, send);
RW(recordData.mData.mSkills, send);
RW(recordData.mScript, send, true);
if (!record.baseId.empty())
{
auto &&overrides = record.baseOverrides;
RW(overrides.hasName, send);
RW(overrides.hasModel, send);
RW(overrides.hasIcon, send);
RW(overrides.hasWeight, send);
RW(overrides.hasValue, send);
RW(overrides.hasEffects, send);
RW(overrides.hasScript, send);
}
}
}
} }
void PacketRecordDynamic::ProcessEffects(ESM::EffectList &effectList, bool send) void PacketRecordDynamic::ProcessEffects(ESM::EffectList &effectList, bool send)

Loading…
Cancel
Save