Migrate more members

This commit is contained in:
David Markowitz
2026-06-12 13:44:16 -07:00
parent 77077d84f9
commit b1e51a5f5b
20 changed files with 135 additions and 124 deletions

View File

@@ -1,5 +1,5 @@
#ifndef __LDFFORMAT__H__ #ifndef LDFFORMAT_H
#define __LDFFORMAT__H__ #define LDFFORMAT_H
// Custom Classes // Custom Classes
#include "dCommonVars.h" #include "dCommonVars.h"
@@ -229,7 +229,41 @@ template<> inline std::string LDFData<std::string>::GetValueString() const { ret
struct LwoNameValue { struct LwoNameValue {
using ValueType = std::map<std::u16string, std::unique_ptr<LDFBaseData>>; using ValueType = std::map<std::u16string, std::unique_ptr<LDFBaseData>>;
ValueType Copy() const {
ValueType copy;
for (const auto& [key, value] : values) copy.insert_or_assign(key, std::unique_ptr<LDFBaseData>(value->Copy()));
return copy;
}
void From(const std::vector<LDFBaseData*>& other) {
for (const auto* data : other) values.insert_or_assign(data->GetKey(), std::unique_ptr<LDFBaseData>(data->Copy()));
}
LwoNameValue& operator=(const LwoNameValue& other) {
this->values = other.Copy();
return *this;
}
template<typename T>
void Insert(const std::u16string& key, const T& value) {
values.insert_or_assign(key, std::unique_ptr(std::make_unique<LDFData<T>>(key, value)));
}
void Insert(const std::u16string& key, const char* value) {
Insert<std::string>(key, value);
}
void Insert(const std::u16string& key, const char16_t* value) {
Insert<std::u16string>(key, value);
}
LwoNameValue() = default;
LwoNameValue(const LwoNameValue& other) {
this->values = other.Copy();
}
ValueType values; ValueType values;
}; };
#endif //!__LDFFORMAT__H__ #endif //!LDFFORMAT_H

View File

@@ -123,8 +123,8 @@ Entity::Entity(const LWOOBJID& objectID, const EntityInfo& info, User* parentUse
m_PhantomCollisionCallbacks = {}; m_PhantomCollisionCallbacks = {};
m_IsParentChildDirty = true; m_IsParentChildDirty = true;
for (const auto* setting : info.settings) m_Settings.values.insert_or_assign(setting->GetKey(), std::unique_ptr<LDFBaseData>(setting->Copy())); m_Settings.From(info.settings);
for (const auto* setting : info.networkSettings) m_NetworkSettings.values.insert_or_assign(setting->GetKey(), std::unique_ptr<LDFBaseData>(setting->Copy())); m_NetworkSettings.From(info.settings);
m_DefaultPosition = info.pos; m_DefaultPosition = info.pos;
m_DefaultRotation = info.rot; m_DefaultRotation = info.rot;
m_Scale = info.scale; m_Scale = info.scale;

View File

@@ -330,11 +330,6 @@ public:
template<typename ComponentType, typename... VaArgs> template<typename ComponentType, typename... VaArgs>
ComponentType* AddComponent(VaArgs... args); ComponentType* AddComponent(VaArgs... args);
/**
* Get the LDF data.
*/
LDFBaseData* GetVarData(const std::u16string& name) const;
/** /**
* Get the LDF value and convert it to a string. * Get the LDF value and convert it to a string.
*/ */
@@ -377,6 +372,11 @@ public:
static Observable<Entity*, const PositionUpdate&> OnPlayerPositionUpdate; static Observable<Entity*, const PositionUpdate&> OnPlayerPositionUpdate;
private: private:
/**
* Get the LDF data.
*/
LDFBaseData* GetVarData(const std::u16string& name) const;
template<typename T> template<typename T>
LwoNameValue::ValueType::iterator InsertLnvData(LwoNameValue& lnv, const std::u16string& key, T value); LwoNameValue::ValueType::iterator InsertLnvData(LwoNameValue& lnv, const std::u16string& key, T value);
void WriteLDFData(const LwoNameValue& ldf, RakNet::BitStream& outBitStream) const; void WriteLDFData(const LwoNameValue& ldf, RakNet::BitStream& outBitStream) const;

View File

@@ -39,10 +39,10 @@ Leaderboard::~Leaderboard() {
} }
void Leaderboard::Clear() { void Leaderboard::Clear() {
for (auto& entry : entries) for (auto ldfData : entry) delete ldfData; entries.clear();
} }
inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) { inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, const LDFBaseData* const data) {
leaderboard << "\nResult[0].Row[" << index << "]." << data->GetString(); leaderboard << "\nResult[0].Row[" << index << "]." << data->GetString();
} }
@@ -59,8 +59,8 @@ void Leaderboard::Serialize(RakNet::BitStream& bitStream) const {
int32_t rowNumber = 0; int32_t rowNumber = 0;
for (auto& entry : entries) { for (auto& entry : entries) {
for (auto* data : entry) { for (const auto& data : entry.values | std::views::values) {
WriteLeaderboardRow(leaderboard, rowNumber, data); if (data) WriteLeaderboardRow(leaderboard, rowNumber, data.get());
} }
rowNumber++; rowNumber++;
} }
@@ -85,57 +85,56 @@ void QueryToLdf(Leaderboard& leaderboard, const std::vector<ILeaderboard::Entry>
for (const auto& leaderboardEntry : leaderboardEntries) { for (const auto& leaderboardEntry : leaderboardEntries) {
constexpr int32_t MAX_NUM_DATA_PER_ROW = 9; constexpr int32_t MAX_NUM_DATA_PER_ROW = 9;
auto& entry = leaderboard.PushBackEntry(); auto& entry = leaderboard.PushBackEntry();
entry.reserve(MAX_NUM_DATA_PER_ROW); entry.Insert<uint64_t>(u"CharacterID", leaderboardEntry.charId);
entry.push_back(new LDFData<uint64_t>(u"CharacterID", leaderboardEntry.charId)); entry.Insert<uint64_t>(u"LastPlayed", leaderboardEntry.lastPlayedTimestamp);
entry.push_back(new LDFData<uint64_t>(u"LastPlayed", leaderboardEntry.lastPlayedTimestamp)); entry.Insert<int32_t>(u"NumPlayed", leaderboardEntry.numTimesPlayed);
entry.push_back(new LDFData<int32_t>(u"NumPlayed", leaderboardEntry.numTimesPlayed)); entry.Insert<std::u16string>(u"name", GeneralUtils::ASCIIToUTF16(leaderboardEntry.name));
entry.push_back(new LDFData<std::u16string>(u"name", GeneralUtils::ASCIIToUTF16(leaderboardEntry.name))); entry.Insert<uint64_t>(u"RowNumber", leaderboardEntry.ranking);
entry.push_back(new LDFData<uint64_t>(u"RowNumber", leaderboardEntry.ranking));
switch (leaderboard.GetLeaderboardType()) { switch (leaderboard.GetLeaderboardType()) {
case ShootingGallery: case ShootingGallery:
entry.push_back(new LDFData<int32_t>(u"Score", leaderboardEntry.primaryScore)); entry.Insert<int32_t>(u"Score", leaderboardEntry.primaryScore);
// Score:1 // Score:1
entry.push_back(new LDFData<int32_t>(u"Streak", leaderboardEntry.secondaryScore)); entry.Insert<int32_t>(u"Streak", leaderboardEntry.secondaryScore);
// Streak:1 // Streak:1
entry.push_back(new LDFData<float>(u"HitPercentage", leaderboardEntry.tertiaryScore)); entry.Insert<float>(u"HitPercentage", leaderboardEntry.tertiaryScore);
// HitPercentage:3 between 0 and 1 // HitPercentage:3 between 0 and 1
break; break;
case Racing: case Racing:
entry.push_back(new LDFData<float>(u"BestTime", leaderboardEntry.primaryScore)); entry.Insert<float>(u"BestTime", leaderboardEntry.primaryScore);
// BestLapTime:3 // BestLapTime:3
entry.push_back(new LDFData<float>(u"BestLapTime", leaderboardEntry.secondaryScore)); entry.Insert<float>(u"BestLapTime", leaderboardEntry.secondaryScore);
// BestTime:3 // BestTime:3
entry.push_back(new LDFData<int32_t>(u"License", 1)); entry.Insert<int32_t>(u"License", 1);
// License:1 - 1 if player has completed mission 637 and 0 otherwise // License:1 - 1 if player has completed mission 637 and 0 otherwise
entry.push_back(new LDFData<int32_t>(u"NumWins", leaderboardEntry.numWins)); entry.Insert<int32_t>(u"NumWins", leaderboardEntry.numWins);
// NumWins:1 // NumWins:1
break; break;
case UnusedLeaderboard4: case UnusedLeaderboard4:
entry.push_back(new LDFData<int32_t>(u"Points", leaderboardEntry.primaryScore)); entry.Insert<int32_t>(u"Points", leaderboardEntry.primaryScore);
// Points:1 // Points:1
break; break;
case MonumentRace: case MonumentRace:
entry.push_back(new LDFData<int32_t>(u"Time", leaderboardEntry.primaryScore)); entry.Insert<int32_t>(u"Time", leaderboardEntry.primaryScore);
// Time:1(?) // Time:1(?)
break; break;
case FootRace: case FootRace:
entry.push_back(new LDFData<int32_t>(u"Time", leaderboardEntry.primaryScore)); entry.Insert<int32_t>(u"Time", leaderboardEntry.primaryScore);
// Time:1 // Time:1
break; break;
case Survival: case Survival:
entry.push_back(new LDFData<int32_t>(u"Points", leaderboardEntry.primaryScore)); entry.Insert<int32_t>(u"Points", leaderboardEntry.primaryScore);
// Points:1 // Points:1
entry.push_back(new LDFData<int32_t>(u"Time", leaderboardEntry.secondaryScore)); entry.Insert<int32_t>(u"Time", leaderboardEntry.secondaryScore);
// Time:1 // Time:1
break; break;
case SurvivalNS: case SurvivalNS:
entry.push_back(new LDFData<int32_t>(u"Wave", leaderboardEntry.primaryScore)); entry.Insert<int32_t>(u"Wave", leaderboardEntry.primaryScore);
// Wave:1 // Wave:1
entry.push_back(new LDFData<int32_t>(u"Time", leaderboardEntry.secondaryScore)); entry.Insert<int32_t>(u"Time", leaderboardEntry.secondaryScore);
// Time:1 // Time:1
break; break;
case Donations: case Donations:
entry.push_back(new LDFData<int32_t>(u"Score", leaderboardEntry.primaryScore)); entry.Insert<int32_t>(u"Score", leaderboardEntry.primaryScore);
// Score:1 // Score:1
break; break;
case None: case None:

View File

@@ -70,8 +70,7 @@ public:
private: private:
using LeaderboardEntry = std::vector<LDFBaseData*>; using LeaderboardEntries = std::vector<LwoNameValue>;
using LeaderboardEntries = std::vector<LeaderboardEntry>;
LeaderboardEntries entries; LeaderboardEntries entries;
LWOOBJID relatedPlayer; LWOOBJID relatedPlayer;
@@ -81,7 +80,7 @@ private:
bool weekly; bool weekly;
uint32_t numResults; uint32_t numResults;
public: public:
LeaderboardEntry& PushBackEntry() { LwoNameValue& PushBackEntry() {
return entries.emplace_back(); return entries.emplace_back();
} }

View File

@@ -24,6 +24,7 @@
#include "WorldPackets.h" #include "WorldPackets.h"
#include "MessageType/Game.h" #include "MessageType/Game.h"
#include <ctime> #include <ctime>
#include <ranges>
CharacterComponent::CharacterComponent(Entity* parent, const int32_t componentID, Character* character, const SystemAddress& systemAddress) : Component(parent, componentID) { CharacterComponent::CharacterComponent(Entity* parent, const int32_t componentID, Character* character, const SystemAddress& systemAddress) : Component(parent, componentID) {
m_Character = character; m_Character = character;
@@ -491,7 +492,7 @@ Item* CharacterComponent::RocketEquip(Entity* player) {
if (!rocket) return rocket; if (!rocket) return rocket;
// build and define the rocket config // build and define the rocket config
for (LDFBaseData* data : rocket->GetConfig()) { for (const auto& data : rocket->GetConfig().values | std::views::values) {
if (data->GetKey() == u"assemblyPartLOTs") { if (data->GetKey() == u"assemblyPartLOTs") {
std::string newRocketStr = data->GetValueAsString() + ";"; std::string newRocketStr = data->GetValueAsString() + ";";
GeneralUtils::ReplaceInString(newRocketStr, "+", ";"); GeneralUtils::ReplaceInString(newRocketStr, "+", ";");

View File

@@ -881,9 +881,9 @@ void DestroyableComponent::FixStats() {
int32_t currentImagination = destroyableComponent->GetImagination(); int32_t currentImagination = destroyableComponent->GetImagination();
// Unequip all items // Unequip all items
auto equipped = inventoryComponent->GetEquippedItems(); const auto equipped = inventoryComponent->GetEquippedItems();
for (auto& equippedItem : equipped) { for (const auto& equippedItem : equipped) {
// Get the item with the item ID // Get the item with the item ID
auto* item = inventoryComponent->FindItemById(equippedItem.second.id); auto* item = inventoryComponent->FindItemById(equippedItem.second.id);
@@ -924,7 +924,7 @@ void DestroyableComponent::FixStats() {
buffComponent->ReApplyBuffs(); buffComponent->ReApplyBuffs();
// Requip all items // Requip all items
for (auto& equippedItem : equipped) { for (const auto& equippedItem : equipped) {
// Get the item with the item ID // Get the item with the item ID
auto* item = inventoryComponent->FindItemById(equippedItem.second.id); auto* item = inventoryComponent->FindItemById(equippedItem.second.id);

View File

@@ -173,7 +173,7 @@ void InventoryComponent::AddItem(
const uint32_t count, const uint32_t count,
eLootSourceType lootSourceType, eLootSourceType lootSourceType,
eInventoryType inventoryType, eInventoryType inventoryType,
const std::vector<LDFBaseData*>& config, const LwoNameValue& config,
const LWOOBJID parent, const LWOOBJID parent,
const bool showFlyingLoot, const bool showFlyingLoot,
bool isModMoveAndEquip, bool isModMoveAndEquip,
@@ -204,7 +204,7 @@ void InventoryComponent::AddItem(
auto* inventory = GetInventory(inventoryType); auto* inventory = GetInventory(inventoryType);
if (!config.empty() || bound) { if (!config.values.empty() || bound) {
const auto slot = preferredSlot != -1 && inventory->IsSlotEmpty(preferredSlot) ? preferredSlot : inventory->FindEmptySlot(); const auto slot = preferredSlot != -1 && inventory->IsSlotEmpty(preferredSlot) ? preferredSlot : inventory->FindEmptySlot();
if (slot == -1) { if (slot == -1) {
@@ -356,7 +356,7 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in
const auto subkey = item->GetSubKey(); const auto subkey = item->GetSubKey();
if (subkey == LWOOBJID_EMPTY && item->GetConfig().empty() && (!item->GetBound() || (item->GetBound() && item->GetInfo().isBOP))) { if (subkey == LWOOBJID_EMPTY && item->GetConfig().values.empty() && (!item->GetBound() || (item->GetBound() && item->GetInfo().isBOP))) {
auto left = std::min<uint32_t>(count, origin->GetLotCount(lot)); auto left = std::min<uint32_t>(count, origin->GetLotCount(lot));
while (left > 0) { while (left > 0) {
@@ -379,11 +379,7 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in
isModMoveAndEquip = false; isModMoveAndEquip = false;
} }
} else { } else {
std::vector<LDFBaseData*> config; const auto config = item->GetConfig();
for (auto* const data : item->GetConfig()) {
config.push_back(data->Copy());
}
const auto delta = std::min<uint32_t>(item->GetCount(), count); const auto delta = std::min<uint32_t>(item->GetCount(), count);
@@ -744,18 +740,17 @@ void InventoryComponent::Serialize(RakNet::BitStream& outBitStream, const bool b
outBitStream.Write0(); outBitStream.Write0();
bool flag = !item.config.empty(); bool flag = !item.config.values.empty();
outBitStream.Write(flag); outBitStream.Write(flag);
if (flag) { if (flag) {
RakNet::BitStream ldfStream; RakNet::BitStream ldfStream;
ldfStream.Write<int32_t>(item.config.size()); // Key count ldfStream.Write<int32_t>(item.config.values.size()); // Key count
for (LDFBaseData* data : item.config) { for (const auto& data : item.config.values | std::views::values) {
if (data->GetKey() == u"assemblyPartLOTs") { if (data->GetKey() == u"assemblyPartLOTs") {
std::string newRocketStr = data->GetValueAsString() + ";"; std::string newRocketStr = data->GetValueAsString() + ";";
GeneralUtils::ReplaceInString(newRocketStr, "+", ";"); GeneralUtils::ReplaceInString(newRocketStr, "+", ";");
LDFData<std::u16string>* ldf_data = new LDFData<std::u16string>(u"assemblyPartLOTs", GeneralUtils::ASCIIToUTF16(newRocketStr)); LDFData<std::u16string> ldf_data(u"assemblyPartLOTs", GeneralUtils::ASCIIToUTF16(newRocketStr));
ldf_data->WriteToPacket(ldfStream); ldf_data.WriteToPacket(ldfStream);
delete ldf_data;
} else { } else {
data->WriteToPacket(ldfStream); data->WriteToPacket(ldfStream);
} }
@@ -782,7 +777,7 @@ void InventoryComponent::Update(float deltaTime) {
} }
} }
void InventoryComponent::UpdateSlot(const std::string& location, EquippedItem item, bool keepCurrent) { void InventoryComponent::UpdateSlot(const std::string& location, const EquippedItem& item, bool keepCurrent) {
const auto index = m_Equipped.find(location); const auto index = m_Equipped.find(location);
if (index != m_Equipped.end()) { if (index != m_Equipped.end()) {
@@ -1080,7 +1075,7 @@ void InventoryComponent::PushEquippedItems() {
} }
void InventoryComponent::PopEquippedItems() { void InventoryComponent::PopEquippedItems() {
auto current = m_Equipped; const auto current = m_Equipped;
for (const auto& pair : current) { for (const auto& pair : current) {
auto* const item = FindItemById(pair.second.id); auto* const item = FindItemById(pair.second.id);
@@ -1876,7 +1871,7 @@ bool InventoryComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInfo
slot.PushDebug<AMFBoolValue>("Bind on equip") = item->GetInfo().isBOE; slot.PushDebug<AMFBoolValue>("Bind on equip") = item->GetInfo().isBOE;
slot.PushDebug<AMFBoolValue>("Is currently bound") = item->GetBound(); slot.PushDebug<AMFBoolValue>("Is currently bound") = item->GetBound();
auto& extra = slot.PushDebug("Extra Info"); auto& extra = slot.PushDebug("Extra Info");
for (const auto* const setting : item->GetConfig()) { for (const auto& setting : item->GetConfig().values | std::views::values) {
if (setting) extra.PushDebug<AMFStringValue>(GeneralUtils::UTF16ToWTF8(setting->GetKey())) = setting->GetValueAsString(); if (setting) extra.PushDebug<AMFStringValue>(GeneralUtils::UTF16ToWTF8(setting->GetKey())) = setting->GetValueAsString();
} }
} }
@@ -1892,7 +1887,7 @@ bool InventoryComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInfo
equipSlot.PushDebug<AMFIntValue>("Slot") = info.slot; equipSlot.PushDebug<AMFIntValue>("Slot") = info.slot;
equipSlot.PushDebug<AMFIntValue>("Count") = info.count; equipSlot.PushDebug<AMFIntValue>("Count") = info.count;
auto& extra = equipSlot.PushDebug("Extra Info"); auto& extra = equipSlot.PushDebug("Extra Info");
for (const auto* const setting : info.config) { for (const auto& setting : info.config.values | std::views::values) {
if (setting) extra.PushDebug<AMFStringValue>(GeneralUtils::UTF16ToWTF8(setting->GetKey())) = setting->GetValueAsString(); if (setting) extra.PushDebug<AMFStringValue>(GeneralUtils::UTF16ToWTF8(setting->GetKey())) = setting->GetValueAsString();
} }
} }

View File

@@ -134,7 +134,7 @@ public:
uint32_t count, uint32_t count,
eLootSourceType lootSourceType = eLootSourceType::NONE, eLootSourceType lootSourceType = eLootSourceType::NONE,
eInventoryType inventoryType = INVALID, eInventoryType inventoryType = INVALID,
const std::vector<LDFBaseData*>& config = {}, const LwoNameValue& config = {},
LWOOBJID parent = LWOOBJID_EMPTY, LWOOBJID parent = LWOOBJID_EMPTY,
bool showFlyingLoot = true, bool showFlyingLoot = true,
bool isModMoveAndEquip = false, bool isModMoveAndEquip = false,
@@ -213,7 +213,7 @@ public:
* @param item the item to place * @param item the item to place
* @param keepCurrent stores the item in an additional temp slot if there's already an item equipped * @param keepCurrent stores the item in an additional temp slot if there's already an item equipped
*/ */
void UpdateSlot(const std::string& location, EquippedItem item, bool keepCurrent = false); void UpdateSlot(const std::string& location, const EquippedItem& item, bool keepCurrent = false);
/** /**
* Removes a slot from the inventory * Removes a slot from the inventory

View File

@@ -221,8 +221,8 @@ void ModelComponent::RemoveBehavior(MoveToInventoryMessage& msg, const bool keep
auto* const inventoryComponent = playerEntity->GetComponent<InventoryComponent>(); auto* const inventoryComponent = playerEntity->GetComponent<InventoryComponent>();
if (inventoryComponent && !behavior.GetIsLoot()) { if (inventoryComponent && !behavior.GetIsLoot()) {
// config is owned by the item // config is owned by the item
std::vector<LDFBaseData*> config; LwoNameValue config;
config.push_back(new LDFData<std::string>(u"userModelName", behavior.GetName())); config.Insert(u"userModelName", behavior.GetName());
inventoryComponent->AddItem(7965, 1, eLootSourceType::PROPERTY, eInventoryType::BEHAVIORS, config, LWOOBJID_EMPTY, true, false, msg.GetBehaviorId()); inventoryComponent->AddItem(7965, 1, eLootSourceType::PROPERTY, eInventoryType::BEHAVIORS, config, LWOOBJID_EMPTY, true, false, msg.GetBehaviorId());
} }
} }

View File

@@ -347,7 +347,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N
info.spawnerID = spawnerID; info.spawnerID = spawnerID;
info.spawnerNodeID = 0; info.spawnerNodeID = 0;
for (auto* setting : item->GetConfig()) { for (const auto& setting : item->GetConfig().values | std::views::values) {
info.settings.push_back(setting->Copy()); info.settings.push_back(setting->Copy());
} }
@@ -476,28 +476,19 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
if (model->GetLOT() == 14) { if (model->GetLOT() == 14) {
//add it to the inv //add it to the inv
std::vector<LDFBaseData*> settings; LwoNameValue actualConfig;
//fill our settings with BBB gurbage //fill our settings with BBB gurbage
LDFBaseData* ldfBlueprintID = new LDFData<LWOOBJID>(u"blueprintid", model->GetVar<LWOOBJID>(u"blueprintid")); actualConfig.Insert(u"blueprintid", model->GetVar<LWOOBJID>(u"blueprintid"));
LDFBaseData* userModelDesc = new LDFData<std::u16string>(u"userModelDesc", u"A cool model you made!"); actualConfig.Insert(u"userModelDesc", u"A cool model you made!");
LDFBaseData* userModelHasBhvr = new LDFData<bool>(u"userModelHasBhvr", false); actualConfig.Insert(u"userModelHasBhvr", false);
LDFBaseData* userModelID = new LDFData<LWOOBJID>(u"userModelID", model->GetVar<LWOOBJID>(u"userModelID")); actualConfig.Insert(u"userModelID", model->GetVar<LWOOBJID>(u"userModelID"));
LDFBaseData* userModelMod = new LDFData<bool>(u"userModelMod", false); actualConfig.Insert(u"userModelMod", false);
LDFBaseData* userModelName = new LDFData<std::u16string>(u"userModelName", u"My Cool Model"); actualConfig.Insert(u"userModelName", u"My Cool Model");
LDFBaseData* propertyObjectID = new LDFData<bool>(u"userModelOpt", true); actualConfig.Insert(u"userModelOpt", true);
LDFBaseData* modelType = new LDFData<int>(u"userModelPhysicsType", 2); actualConfig.Insert(u"userModelPhysicsType", 2);
settings.push_back(ldfBlueprintID); inventoryComponent->AddItem(6662, 1, eLootSourceType::DELETION, eInventoryType::MODELS_IN_BBB, actualConfig, LWOOBJID_EMPTY, false, false, spawnerId);
settings.push_back(userModelDesc);
settings.push_back(userModelHasBhvr);
settings.push_back(userModelID);
settings.push_back(userModelMod);
settings.push_back(userModelName);
settings.push_back(propertyObjectID);
settings.push_back(modelType);
inventoryComponent->AddItem(6662, 1, eLootSourceType::DELETION, eInventoryType::MODELS_IN_BBB, settings, LWOOBJID_EMPTY, false, false, spawnerId);
auto* item = inventoryComponent->FindItemBySubKey(spawnerId); auto* item = inventoryComponent->FindItemBySubKey(spawnerId);
if (item == nullptr) { if (item == nullptr) {

View File

@@ -26,6 +26,7 @@
#include "dZoneManager.h" #include "dZoneManager.h"
#include "CDActivitiesTable.h" #include "CDActivitiesTable.h"
#include "eStateChangeType.h" #include "eStateChangeType.h"
#include <ranges>
#include <ctime> #include <ctime>
#ifndef M_PI #ifndef M_PI
@@ -178,11 +179,10 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
moduleAssemblyComponent->SetSubKey(item->GetSubKey()); moduleAssemblyComponent->SetSubKey(item->GetSubKey());
moduleAssemblyComponent->SetUseOptionalParts(false); moduleAssemblyComponent->SetUseOptionalParts(false);
for (auto* config : item->GetConfig()) { const auto& lnv = item->GetConfig().values;
if (config->GetKey() == u"assemblyPartLOTs") { const auto itr = lnv.find(u"assemblyPartLOTs");
moduleAssemblyComponent->SetAssemblyPartsLOTs( if (itr != lnv.end()) {
GeneralUtils::ASCIIToUTF16(config->GetValueAsString())); moduleAssemblyComponent->SetAssemblyPartsLOTs(GeneralUtils::ASCIIToUTF16(itr->second->GetValueAsString()));
}
} }
} }
@@ -874,7 +874,7 @@ void RacingControlComponent::Update(float deltaTime) {
void RacingControlComponent::MsgConfigureRacingControl(const GameMessages::ConfigureRacingControl& msg) { void RacingControlComponent::MsgConfigureRacingControl(const GameMessages::ConfigureRacingControl& msg) {
for (const auto& dataUnique : msg.racingSettings) { for (const auto& dataUnique : msg.racingSettings) {
if (!dataUnique) continue; if (!dataUnique) continue;
const auto* const data = dataUnique.get(); const auto* const data = dataUnique.get();
if (data->GetKey() == u"Race_PathName" && data->GetValueType() == LDF_TYPE_UTF_16) { if (data->GetKey() == u"Race_PathName" && data->GetValueType() == LDF_TYPE_UTF_16) {
m_PathName = static_cast<const LDFData<std::u16string>*>(data)->GetValue(); m_PathName = static_cast<const LDFData<std::u16string>*>(data)->GetValue();
} else if (data->GetKey() == u"activityID" && data->GetValueType() == LDF_TYPE_S32) { } else if (data->GetKey() == u"activityID" && data->GetValueType() == LDF_TYPE_S32) {

View File

@@ -46,6 +46,7 @@
#include <sstream> #include <sstream>
#include <future> #include <future>
#include <chrono> #include <chrono>
#include <ranges>
#include "RakString.h" #include "RakString.h"
//CDB includes: //CDB includes:
@@ -469,7 +470,7 @@ void GameMessages::SendAddItemToInventoryClientSync(Entity* entity, const System
auto config = item->GetConfig(); auto config = item->GetConfig();
for (auto* data : config) { for (const auto& data : config.values | std::views::values) {
extraInfo += GeneralUtils::ASCIIToUTF16(data->GetString()) + u","; extraInfo += GeneralUtils::ASCIIToUTF16(data->GetString()) + u",";
} }
@@ -5502,10 +5503,8 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream& inStream, Entity*
//inv->UnequipItem(inv->GetItemStackByLOT(6086, eInventoryType::ITEMS)); // take off the thinking cap //inv->UnequipItem(inv->GetItemStackByLOT(6086, eInventoryType::ITEMS)); // take off the thinking cap
//Game::entityManager->SerializeEntity(entity); //Game::entityManager->SerializeEntity(entity);
const auto moduleAssembly = new LDFData<std::u16string>(u"assemblyPartLOTs", modules); LwoNameValue config;
config.Insert(u"assemblyPartLOTs", modules);
std::vector<LDFBaseData*> config;
config.push_back(moduleAssembly);
LWOOBJID newID = ObjectIDManager::GetPersistentID(); LWOOBJID newID = ObjectIDManager::GetPersistentID();

View File

@@ -31,5 +31,5 @@ struct EquippedItem
/** /**
* The configuration of the item with any extra data * The configuration of the item with any extra data
*/ */
std::vector<LDFBaseData*> config = {}; LwoNameValue config = {};
}; };

View File

@@ -28,6 +28,7 @@
#include "CDObjectSkillsTable.h" #include "CDObjectSkillsTable.h"
#include "CDComponentsRegistryTable.h" #include "CDComponentsRegistryTable.h"
#include "CDPackageComponentTable.h" #include "CDPackageComponentTable.h"
#include <ranges>
namespace { namespace {
const std::map<std::string, std::string> ExtraSettingAbbreviations = { const std::map<std::string, std::string> ExtraSettingAbbreviations = {
@@ -46,7 +47,7 @@ namespace {
}; };
} }
Item::Item(const LWOOBJID id, const LOT lot, Inventory* inventory, const uint32_t slot, const uint32_t count, const bool bound, const std::vector<LDFBaseData*>& config, const LWOOBJID parent, LWOOBJID subKey, eLootSourceType lootSourceType) { Item::Item(const LWOOBJID id, const LOT lot, Inventory* inventory, const uint32_t slot, const uint32_t count, const bool bound, const LwoNameValue& config, const LWOOBJID parent, LWOOBJID subKey, eLootSourceType lootSourceType) {
if (!Inventory::IsValidItem(lot)) { if (!Inventory::IsValidItem(lot)) {
return; return;
} }
@@ -71,7 +72,7 @@ Item::Item(
Inventory* inventory, Inventory* inventory,
const uint32_t slot, const uint32_t slot,
const uint32_t count, const uint32_t count,
const std::vector<LDFBaseData*>& config, const LwoNameValue& config,
const LWOOBJID parent, const LWOOBJID parent,
bool showFlyingLoot, bool showFlyingLoot,
bool isModMoveAndEquip, bool isModMoveAndEquip,
@@ -131,11 +132,11 @@ uint32_t Item::GetSlot() const {
return slot; return slot;
} }
std::vector<LDFBaseData*> Item::GetConfig() const { const LwoNameValue& Item::GetConfig() const {
return config; return config;
} }
std::vector<LDFBaseData*>& Item::GetConfig() { LwoNameValue& Item::GetConfig() {
return config; return config;
} }
@@ -379,7 +380,7 @@ void Item::UseNonEquip(Item* item) {
} }
void Item::Disassemble(const eInventoryType inventoryType) { void Item::Disassemble(const eInventoryType inventoryType) {
for (auto* data : config) { for (const auto& data : config.values | std::views::values) {
if (data->GetKey() == u"assemblyPartLOTs") { if (data->GetKey() == u"assemblyPartLOTs") {
auto modStr = data->GetValueAsString(); auto modStr = data->GetValueAsString();
@@ -530,18 +531,12 @@ void Item::RemoveFromInventory() {
Item::~Item() { Item::~Item() {
delete preconditions; delete preconditions;
for (auto* value : config) {
delete value;
}
config.clear();
} }
void Item::SaveConfigXml(tinyxml2::XMLElement& i) const { void Item::SaveConfigXml(tinyxml2::XMLElement& i) const {
tinyxml2::XMLElement* x = nullptr; tinyxml2::XMLElement* x = nullptr;
for (const auto* config : this->config) { for (const auto& config : config.values | std::views::values) {
const auto& key = GeneralUtils::UTF16ToWTF8(config->GetKey()); const auto& key = GeneralUtils::UTF16ToWTF8(config->GetKey());
const auto saveKey = ExtraSettingAbbreviations.find(key); const auto saveKey = ExtraSettingAbbreviations.find(key);
if (saveKey == ExtraSettingAbbreviations.end()) { if (saveKey == ExtraSettingAbbreviations.end()) {
@@ -561,12 +556,12 @@ void Item::LoadConfigXml(const tinyxml2::XMLElement& i) {
const auto* x = i.FirstChildElement("x"); const auto* x = i.FirstChildElement("x");
if (!x) return; if (!x) return;
for (const auto& pair : ExtraSettingAbbreviations) { for (const auto& [fullName, abbreviation] : ExtraSettingAbbreviations) {
const auto* data = x->Attribute(pair.second.c_str()); const auto* data = x->Attribute(abbreviation.c_str());
if (!data) continue; if (!data) continue;
const auto value = pair.first + "=" + data; auto* const newPtr = LDFBaseData::DataFromString(fullName + "=" + data);
config.push_back(LDFBaseData::DataFromString(value)); config.values.insert_or_assign(newPtr->GetKey(), std::unique_ptr<LDFBaseData>(newPtr));
} }
} }

View File

@@ -40,7 +40,7 @@ public:
uint32_t slot, uint32_t slot,
uint32_t count, uint32_t count,
bool bound, bool bound,
const std::vector<LDFBaseData*>& config, const LwoNameValue& config,
LWOOBJID parent, LWOOBJID parent,
LWOOBJID subKey, LWOOBJID subKey,
eLootSourceType lootSourceType = eLootSourceType::NONE eLootSourceType lootSourceType = eLootSourceType::NONE
@@ -64,7 +64,7 @@ public:
Inventory* inventory, Inventory* inventory,
uint32_t slot = 0, uint32_t slot = 0,
uint32_t count = 1, uint32_t count = 1,
const std::vector<LDFBaseData*>& config = {}, const LwoNameValue& config = {},
LWOOBJID parent = LWOOBJID_EMPTY, LWOOBJID parent = LWOOBJID_EMPTY,
bool showFlyingLoot = true, bool showFlyingLoot = true,
bool isModMoveAndEquip = false, bool isModMoveAndEquip = false,
@@ -118,13 +118,13 @@ public:
* Returns current config info for this item, e.g. for rockets * Returns current config info for this item, e.g. for rockets
* @return current config info for this item * @return current config info for this item
*/ */
std::vector<LDFBaseData*>& GetConfig(); LwoNameValue& GetConfig();
/** /**
* Returns current config info for this item, e.g. for rockets * Returns current config info for this item, e.g. for rockets
* @return current config info for this item * @return current config info for this item
*/ */
std::vector<LDFBaseData*> GetConfig() const; const LwoNameValue& GetConfig() const;
/** /**
* Returns the database info for this item * Returns the database info for this item
@@ -269,7 +269,7 @@ private:
/** /**
* Config data for this item, e.g. for rocket parts and car parts * Config data for this item, e.g. for rocket parts and car parts
*/ */
std::vector<LDFBaseData*> config; LwoNameValue config;
/** /**
* The inventory this item belongs to * The inventory this item belongs to

View File

@@ -218,7 +218,6 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string&
uint32_t activityId; uint32_t activityId;
uint32_t lot; uint32_t lot;
uint32_t collectionId; uint32_t collectionId;
std::vector<LDFBaseData*> settings;
switch (type) { switch (type) {
case eMissionTaskType::UNKNOWN: case eMissionTaskType::UNKNOWN:

View File

@@ -1268,10 +1268,10 @@ namespace DEVGMCommands {
auto* inventoryComponent = entity->GetComponent<InventoryComponent>(); auto* inventoryComponent = entity->GetComponent<InventoryComponent>();
if (!inventoryComponent) return; if (!inventoryComponent) return;
std::vector<LDFBaseData*> data{}; LwoNameValue config;
data.push_back(new LDFData<int32_t>(u"reforgedLOT", reforgedItem.value())); config.Insert<LOT>(u"reforgedLOT", reforgedItem.value());
inventoryComponent->AddItem(baseItem.value(), 1, eLootSourceType::MODERATION, eInventoryType::INVALID, data); inventoryComponent->AddItem(baseItem.value(), 1, eLootSourceType::MODERATION, eInventoryType::INVALID, config);
} }
void Crash(Entity* entity, const SystemAddress& sysAddr, const std::string args) { void Crash(Entity* entity, const SystemAddress& sysAddr, const std::string args) {

View File

@@ -70,7 +70,7 @@ void Level::MakeSpawner(SceneObject obj) {
if (data->GetValueType() == eLDFType::LDF_TYPE_FLOAT) // Floats are in seconds if (data->GetValueType() == eLDFType::LDF_TYPE_FLOAT) // Floats are in seconds
{ {
spawnInfo.respawnTime = GeneralUtils::TryParse(data->GetValueAsString(), 0.0f); spawnInfo.respawnTime = GeneralUtils::TryParse(data->GetValueAsString(), 0.0f);
} else if (data->GetValueType() == eLDFType::LDF_TYPE_U32) // Ints are in ms? } else if (data->GetValueType() == eLDFType::LDF_TYPE_U32) // Ints are in ms
{ {
spawnInfo.respawnTime = GeneralUtils::TryParse(data->GetValueAsString(), 0) / 1000; spawnInfo.respawnTime = GeneralUtils::TryParse(data->GetValueAsString(), 0) / 1000;
} }

View File

@@ -13,7 +13,6 @@ struct SceneObject {
NiPoint3 position; NiPoint3 position;
NiQuaternion rotation = QuatUtils::IDENTITY; NiQuaternion rotation = QuatUtils::IDENTITY;
float scale = 1.0f; float scale = 1.0f;
//std::string settings;
uint32_t value3; uint32_t value3;
std::vector<LDFBaseData*> settings; std::vector<LDFBaseData*> settings;
}; };