1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-04-01 20:36:42 +00:00

[General] Implement script records for RecordDynamic packets

This commit is contained in:
David Cernat 2019-11-09 21:34:09 +02:00
parent 383d6ecea6
commit afb9bd7eb5
7 changed files with 120 additions and 2 deletions

View file

@ -33,6 +33,7 @@ ProbeRecord tempProbe;
RepairRecord tempRepair;
LightRecord tempLight;
CellRecord tempCell;
ScriptRecord tempScript;
BaseOverrides tempOverrides;
@ -80,6 +81,7 @@ void RecordsDynamicFunctions::ClearRecords() noexcept
WorldstateFunctions::writeWorldstate.repairRecords.clear();
WorldstateFunctions::writeWorldstate.lightRecords.clear();
WorldstateFunctions::writeWorldstate.cellRecords.clear();
WorldstateFunctions::writeWorldstate.scriptRecords.clear();
}
unsigned short RecordsDynamicFunctions::GetRecordType() noexcept
@ -380,6 +382,8 @@ void RecordsDynamicFunctions::SetRecordId(const char* id) noexcept
tempRepair.data.mId = id;
else if (writeRecordsType == mwmp::RECORD_TYPE::LIGHT)
tempLight.data.mId = id;
else if (writeRecordsType == mwmp::RECORD_TYPE::SCRIPT)
tempScript.data.mId = id;
else
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set id for record type %i which lacks that property", writeRecordsType);
}
@ -430,6 +434,8 @@ void RecordsDynamicFunctions::SetRecordBaseId(const char* baseId) noexcept
tempLight.baseId = baseId;
else if (writeRecordsType == mwmp::RECORD_TYPE::CELL)
tempCell.baseId = baseId;
else if (writeRecordsType == mwmp::RECORD_TYPE::SCRIPT)
tempScript.baseId = baseId;
else
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set baseId for record type %i which lacks that property", writeRecordsType);
}
@ -1373,6 +1379,21 @@ void RecordsDynamicFunctions::SetRecordCloseSound(const char* sound) noexcept
tempOverrides.hasCloseSound = true;
}
void RecordsDynamicFunctions::SetRecordScriptText(const char* scriptText) noexcept
{
unsigned short writeRecordsType = WorldstateFunctions::writeWorldstate.recordsType;
if (writeRecordsType == mwmp::RECORD_TYPE::SCRIPT)
tempScript.data.mScriptText = scriptText;
else
{
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Tried to set close sound for record type %i which lacks that property", writeRecordsType);
return;
}
tempOverrides.hasScriptText = true;
}
void RecordsDynamicFunctions::SetRecordIdByIndex(unsigned int index, const char* id) noexcept
{
unsigned short writeRecordsType = WorldstateFunctions::writeWorldstate.recordsType;
@ -1606,6 +1627,12 @@ void RecordsDynamicFunctions::AddRecord() noexcept
WorldstateFunctions::writeWorldstate.cellRecords.push_back(tempCell);
tempCell = {};
}
else if (writeRecordsType == mwmp::RECORD_TYPE::SCRIPT)
{
tempScript.baseOverrides = tempOverrides;
WorldstateFunctions::writeWorldstate.scriptRecords.push_back(tempScript);
tempScript = {};
}
effectCount = 0;
tempOverrides = {};

View file

@ -97,6 +97,8 @@
{"SetRecordOpenSound", RecordsDynamicFunctions::SetRecordOpenSound},\
{"SetRecordCloseSound", RecordsDynamicFunctions::SetRecordCloseSound},\
\
{"SetRecordScriptText", RecordsDynamicFunctions::SetRecordScriptText},\
\
{"SetRecordIdByIndex", RecordsDynamicFunctions::SetRecordIdByIndex},\
{"SetRecordEnchantmentIdByIndex", RecordsDynamicFunctions::SetRecordEnchantmentIdByIndex},\
\
@ -824,6 +826,15 @@ public:
*/
static void SetRecordCloseSound(const char* sound) noexcept;
/**
* \brief Set the script text of the temporary record stored on the server for the
* currently specified record type.
*
* \param sound The script text of the record.
* \return void
*/
static void SetRecordScriptText(const char* scriptText) noexcept;
/**
* \brief Set the id of the record at a certain index in the records stored on the server.
*

View file

@ -1185,6 +1185,40 @@ void RecordHelper::overrideRecord(const mwmp::RepairRecord& record)
world->updatePtrsWithRefId(recordData.mId);
}
void RecordHelper::overrideRecord(const mwmp::ScriptRecord& record)
{
const ESM::Script &recordData = record.data;
if (recordData.mId.empty())
{
LOG_APPEND(TimedLog::LOG_INFO, "-- Ignoring record override with no id provided");
return;
}
MWBase::World *world = MWBase::Environment::get().getWorld();
if (record.baseId.empty())
{
world->getModifiableStore().overrideRecord(recordData);
}
else if (doesRecordIdExist<ESM::Script>(record.baseId))
{
const ESM::Script *baseData = world->getStore().get<ESM::Script>().search(record.baseId);
ESM::Script finalData = *baseData;
finalData.mId = recordData.mId;
if (record.baseOverrides.hasScriptText)
finalData.mScriptText = recordData.mScriptText;
world->getModifiableStore().overrideRecord(finalData);
}
else
{
LOG_APPEND(TimedLog::LOG_INFO, "-- Ignoring record override with invalid baseId %s", record.baseId.c_str());
return;
}
}
void RecordHelper::overrideRecord(const mwmp::SpellRecord& record)
{
const ESM::Spell &recordData = record.data;

View file

@ -25,6 +25,7 @@ namespace RecordHelper
void overrideRecord(const mwmp::PotionRecord& record);
void overrideRecord(const mwmp::ProbeRecord& record);
void overrideRecord(const mwmp::RepairRecord& record);
void overrideRecord(const mwmp::ScriptRecord& record);
void overrideRecord(const mwmp::SpellRecord& record);
void overrideRecord(const mwmp::StaticRecord& record);
void overrideRecord(const mwmp::WeaponRecord& record);

View file

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

View file

@ -20,6 +20,7 @@
#include <components/esm/loadnpc.hpp>
#include <components/esm/loadprob.hpp>
#include <components/esm/loadrepa.hpp>
#include <components/esm/loadscpt.hpp>
#include <components/esm/loadspel.hpp>
#include <components/esm/loadstat.hpp>
#include <components/esm/loadweap.hpp>
@ -52,7 +53,8 @@ namespace mwmp
PROBE,
REPAIR,
LIGHT,
CELL
CELL,
SCRIPT
};
// When using an existing record as a base, this struct tracks which changes
@ -125,6 +127,8 @@ namespace mwmp
bool hasSound = false;
bool hasOpenSound = false;
bool hasCloseSound = false;
bool hasScriptText = false;
};
struct ActivatorRecord
@ -258,6 +262,13 @@ namespace mwmp
BaseOverrides baseOverrides;
};
struct ScriptRecord
{
ESM::Script data;
std::string baseId;
BaseOverrides baseOverrides;
};
struct SpellRecord
{
ESM::Spell data;
@ -360,6 +371,7 @@ namespace mwmp
std::vector<PotionRecord> potionRecords;
std::vector<ProbeRecord> probeRecords;
std::vector<RepairRecord> repairRecords;
std::vector<ScriptRecord> scriptRecords;
std::vector<SpellRecord> spellRecords;
std::vector<StaticRecord> staticRecords;
std::vector<WeaponRecord> weaponRecords;

View file

@ -62,6 +62,8 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
worldstate->recordsCount = Utils::getVectorSize(worldstate->lightRecords);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::CELL)
worldstate->recordsCount = Utils::getVectorSize(worldstate->cellRecords);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::SCRIPT)
worldstate->recordsCount = Utils::getVectorSize(worldstate->scriptRecords);
else
{
LOG_MESSAGE_SIMPLE(TimedLog::LOG_ERROR, "Processed invalid ID_RECORD_DYNAMIC packet about unimplemented recordsType %i",
@ -124,6 +126,8 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
Utils::resetVector(worldstate->lightRecords, worldstate->recordsCount);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::CELL)
Utils::resetVector(worldstate->cellRecords, worldstate->recordsCount);
else if (worldstate->recordsType == mwmp::RECORD_TYPE::SCRIPT)
Utils::resetVector(worldstate->scriptRecords, worldstate->recordsCount);
}
if (worldstate->recordsType == mwmp::RECORD_TYPE::SPELL)
@ -784,7 +788,24 @@ void PacketRecordDynamic::Packet(RakNet::BitStream *bs, bool send)
auto &recordData = record.data;
RW(record.baseId, send, true);
RW(record.data.mName, send, true);
RW(recordData.mName, send, true);
}
}
else if (worldstate->recordsType == mwmp::RECORD_TYPE::SCRIPT)
{
for (auto &&record : worldstate->scriptRecords)
{
auto &recordData = record.data;
RW(record.baseId, send, true);
RW(recordData.mId, send, true);
RW(recordData.mScriptText, send, true);
if (!record.baseId.empty())
{
auto &&overrides = record.baseOverrides;
RW(overrides.hasScriptText, send);
}
}
}
}