mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-06-13 10:14:22 +00:00
Compare commits
3 Commits
canary
...
lwonameval
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1e51a5f5b | ||
|
|
77077d84f9 | ||
|
|
adf9200c9a |
@@ -1,11 +1,12 @@
|
||||
#ifndef __LDFFORMAT__H__
|
||||
#define __LDFFORMAT__H__
|
||||
#ifndef LDFFORMAT_H
|
||||
#define LDFFORMAT_H
|
||||
|
||||
// Custom Classes
|
||||
#include "dCommonVars.h"
|
||||
#include "GeneralUtils.h"
|
||||
|
||||
// C++
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <sstream>
|
||||
@@ -226,4 +227,43 @@ template<> inline std::string LDFData<LWOOBJID>::GetValueString() const { return
|
||||
|
||||
template<> inline std::string LDFData<std::string>::GetValueString() const { return this->value; }
|
||||
|
||||
#endif //!__LDFFORMAT__H__
|
||||
struct LwoNameValue {
|
||||
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;
|
||||
};
|
||||
|
||||
#endif //!LDFFORMAT_H
|
||||
|
||||
@@ -111,18 +111,6 @@ private:
|
||||
|
||||
constexpr LWOSCENEID LWOSCENEID_INVALID = -1;
|
||||
|
||||
struct LWONameValue {
|
||||
uint32_t length = 0; //!< The length of the name
|
||||
std::u16string name; //!< The name
|
||||
|
||||
LWONameValue() = default;
|
||||
|
||||
LWONameValue(const std::u16string& name) {
|
||||
this->name = name;
|
||||
this->length = static_cast<uint32_t>(name.length());
|
||||
}
|
||||
};
|
||||
|
||||
struct FriendData {
|
||||
public:
|
||||
bool isOnline = false;
|
||||
|
||||
@@ -123,8 +123,8 @@ Entity::Entity(const LWOOBJID& objectID, const EntityInfo& info, User* parentUse
|
||||
m_PhantomCollisionCallbacks = {};
|
||||
m_IsParentChildDirty = true;
|
||||
|
||||
m_Settings = info.settings;
|
||||
m_NetworkSettings = info.networkSettings;
|
||||
m_Settings.From(info.settings);
|
||||
m_NetworkSettings.From(info.settings);
|
||||
m_DefaultPosition = info.pos;
|
||||
m_DefaultRotation = info.rot;
|
||||
m_Scale = info.scale;
|
||||
@@ -949,13 +949,13 @@ void Entity::SetGMLevel(eGameMasterLevel value) {
|
||||
}
|
||||
}
|
||||
|
||||
void Entity::WriteLDFData(const std::vector<LDFBaseData*>& ldf, RakNet::BitStream& outBitStream) const {
|
||||
void Entity::WriteLDFData(const LwoNameValue& ldf, RakNet::BitStream& outBitStream) const {
|
||||
RakNet::BitStream settingStream;
|
||||
int32_t numberOfValidKeys = ldf.size();
|
||||
int32_t numberOfValidKeys = ldf.values.size();
|
||||
|
||||
// Writing keys value pairs the client does not expect to receive or interpret will result in undefined behavior,
|
||||
// so we need to filter out any keys that are not valid and fix the number of valid keys to be correct.
|
||||
for (LDFBaseData* data : ldf) {
|
||||
for (const auto& data : ldf.values | std::views::values) {
|
||||
if (data && data->GetValueType() != eLDFType::LDF_TYPE_UNKNOWN) {
|
||||
data->WriteToPacket(settingStream);
|
||||
} else {
|
||||
@@ -987,16 +987,15 @@ void Entity::WriteBaseReplicaData(RakNet::BitStream& outBitStream, eReplicaPacke
|
||||
const auto& syncLDF = GetVar<std::vector<std::u16string>>(u"syncLDF");
|
||||
|
||||
// Only sync for models.
|
||||
if (!m_Settings.empty() && (GetComponent<ModelComponent>() && !GetComponent<PetComponent>())) {
|
||||
if (!m_Settings.values.empty() && (GetComponent<ModelComponent>() && !GetComponent<PetComponent>())) {
|
||||
outBitStream.Write1(); // Has ldf data
|
||||
WriteLDFData(m_Settings, outBitStream);
|
||||
} else if (!syncLDF.empty()) {
|
||||
// Find all the ldf data we need to write
|
||||
std::vector<LDFBaseData*> ldfData;
|
||||
ldfData.reserve(m_Settings.size());
|
||||
LwoNameValue ldfData;
|
||||
|
||||
for (const auto& data : syncLDF) {
|
||||
ldfData.push_back(GetVarData(data));
|
||||
ldfData.values.insert_or_assign(data, std::unique_ptr<LDFBaseData>(GetVarData(data)->Copy()));
|
||||
}
|
||||
|
||||
outBitStream.Write1(); // Has ldf data
|
||||
@@ -2045,13 +2044,7 @@ void Entity::SetI64(const std::u16string& name, const int64_t value) {
|
||||
}
|
||||
|
||||
bool Entity::HasVar(const std::u16string& name) const {
|
||||
for (auto* data : m_Settings) {
|
||||
if (data->GetKey() == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return m_Settings.values.contains(name);
|
||||
}
|
||||
|
||||
uint16_t Entity::GetNetworkId() const {
|
||||
@@ -2084,19 +2077,8 @@ void Entity::SendNetworkVar(const std::string& data, const SystemAddress& sysAdd
|
||||
}
|
||||
|
||||
LDFBaseData* Entity::GetVarData(const std::u16string& name) const {
|
||||
for (auto* data : m_Settings) {
|
||||
if (data == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (data->GetKey() != name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
const auto itr = m_Settings.values.find(name);
|
||||
return itr != m_Settings.values.cend() ? itr->second.get() : nullptr;
|
||||
}
|
||||
|
||||
std::string Entity::GetVarAsString(const std::u16string& name) const {
|
||||
@@ -2276,7 +2258,7 @@ bool Entity::MsgRequestServerObjectInfo(GameMessages::RequestServerObjectInfo& r
|
||||
}
|
||||
|
||||
auto& configData = objectInfo.PushDebug("Config Data");
|
||||
for (const auto config : m_Settings) {
|
||||
for (const auto& config : m_Settings.values | std::views::values) {
|
||||
configData.PushDebug<AMFStringValue>(GeneralUtils::UTF16ToWTF8(config->GetKey())) = config->GetValueAsString();
|
||||
}
|
||||
|
||||
|
||||
133
dGame/Entity.h
133
dGame/Entity.h
@@ -97,9 +97,9 @@ public:
|
||||
|
||||
LWOOBJID GetSpawnerID() const { return m_SpawnerID; }
|
||||
|
||||
const std::vector<LDFBaseData*>& GetSettings() const { return m_Settings; }
|
||||
const LwoNameValue& GetSettings() const { return m_Settings; }
|
||||
|
||||
const std::vector<LDFBaseData*>& GetNetworkSettings() const { return m_NetworkSettings; }
|
||||
const LwoNameValue& GetNetworkSettings() const { return m_NetworkSettings; }
|
||||
|
||||
bool GetIsDead() const;
|
||||
|
||||
@@ -312,6 +312,12 @@ public:
|
||||
template<typename T>
|
||||
void SetNetworkVar(const std::u16string& name, std::vector<T> value, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
template<typename T>
|
||||
void SetNetworkVar(const std::string& name, T value, const SystemAddress& sysAddr = UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
template<typename T>
|
||||
LwoNameValue::ValueType::iterator InsertNetworkVar(const std::u16string& name, T value);
|
||||
|
||||
template<typename T>
|
||||
T GetNetworkVar(const std::u16string& name);
|
||||
|
||||
@@ -324,11 +330,6 @@ public:
|
||||
template<typename ComponentType, typename... VaArgs>
|
||||
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.
|
||||
*/
|
||||
@@ -360,7 +361,7 @@ public:
|
||||
// This is the actual function that will be registered, which casts the base GameMsg to the derived type
|
||||
const auto castWrapper = [boundFunction](GameMessages::GameMsg& msg) {
|
||||
return boundFunction(static_cast<DerivedGameMsg&>(msg));
|
||||
};
|
||||
};
|
||||
DerivedGameMsg msg;
|
||||
RegisterMsg(msg.msgId, castWrapper);
|
||||
}
|
||||
@@ -371,13 +372,20 @@ public:
|
||||
static Observable<Entity*, const PositionUpdate&> OnPlayerPositionUpdate;
|
||||
|
||||
private:
|
||||
void WriteLDFData(const std::vector<LDFBaseData*>& ldf, RakNet::BitStream& outBitStream) const;
|
||||
|
||||
/**
|
||||
* Get the LDF data.
|
||||
*/
|
||||
LDFBaseData* GetVarData(const std::u16string& name) const;
|
||||
template<typename T>
|
||||
LwoNameValue::ValueType::iterator InsertLnvData(LwoNameValue& lnv, const std::u16string& key, T value);
|
||||
void WriteLDFData(const LwoNameValue& ldf, RakNet::BitStream& outBitStream) const;
|
||||
LWOOBJID m_ObjectID;
|
||||
|
||||
LOT m_TemplateID;
|
||||
|
||||
std::vector<LDFBaseData*> m_Settings;
|
||||
std::vector<LDFBaseData*> m_NetworkSettings;
|
||||
LwoNameValue m_Settings;
|
||||
LwoNameValue m_NetworkSettings;
|
||||
|
||||
NiPoint3 m_DefaultPosition;
|
||||
NiQuaternion m_DefaultRotation = QuatUtils::IDENTITY;
|
||||
@@ -483,52 +491,44 @@ T Entity::GetVarAs(const std::u16string& name) const {
|
||||
|
||||
template<typename T>
|
||||
void Entity::SetVar(const std::u16string& name, T value) {
|
||||
auto* data = GetVarData(name);
|
||||
InsertLnvData<T>(m_Settings, name, value);
|
||||
}
|
||||
|
||||
if (data == nullptr) {
|
||||
auto* data = new LDFData<T>(name, value);
|
||||
|
||||
m_Settings.push_back(data);
|
||||
|
||||
return;
|
||||
template<typename T>
|
||||
LwoNameValue::ValueType::iterator Entity::InsertLnvData(LwoNameValue& lnv, const std::u16string& key, T value) {
|
||||
auto itr = lnv.values.find(key);
|
||||
if (itr != lnv.values.end()) {
|
||||
auto lnv = dynamic_cast<LDFData<T>*>(itr->second.get());
|
||||
if (!lnv) {
|
||||
// Is of different type
|
||||
itr->second = std::make_unique<LDFData<T>>(key, value);
|
||||
} else {
|
||||
// Is the same type and exists
|
||||
lnv->SetValue(value);
|
||||
}
|
||||
} else {
|
||||
// Doesn't exist
|
||||
itr = lnv.values.insert_or_assign(key, std::make_unique<LDFData<T>>(key, value)).first;
|
||||
}
|
||||
|
||||
auto* typed = dynamic_cast<LDFData<T>*>(data);
|
||||
return itr;
|
||||
}
|
||||
|
||||
if (typed == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
typed->SetValue(value);
|
||||
template<typename T>
|
||||
LwoNameValue::ValueType::iterator Entity::InsertNetworkVar(const std::u16string& name, T value) {
|
||||
return InsertLnvData<T>(m_NetworkSettings, name, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void Entity::SetNetworkVar(const std::u16string& name, T value, const SystemAddress& sysAddr) {
|
||||
LDFData<T>* newData = nullptr;
|
||||
const auto itr = InsertNetworkVar<T>(name, value);
|
||||
|
||||
for (auto* data : m_NetworkSettings) {
|
||||
if (data->GetKey() != name)
|
||||
continue;
|
||||
SendNetworkVar(itr->second->GetString(), sysAddr);
|
||||
}
|
||||
|
||||
newData = dynamic_cast<LDFData<T>*>(data);
|
||||
if (newData != nullptr) {
|
||||
newData->SetValue(value);
|
||||
} else { // If we're changing types
|
||||
m_NetworkSettings.erase(
|
||||
std::remove(m_NetworkSettings.begin(), m_NetworkSettings.end(), data), m_NetworkSettings.end()
|
||||
);
|
||||
delete data;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (newData == nullptr) {
|
||||
newData = new LDFData<T>(name, value);
|
||||
}
|
||||
|
||||
m_NetworkSettings.push_back(newData);
|
||||
SendNetworkVar(newData->GetString(true), sysAddr);
|
||||
template<typename T>
|
||||
void Entity::SetNetworkVar(const std::string& name, T value, const SystemAddress& sysAddr) {
|
||||
SetNetworkVar(GeneralUtils::UTF8ToUTF16(name), value, sysAddr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -539,26 +539,10 @@ void Entity::SetNetworkVar(const std::u16string& name, std::vector<T> values, co
|
||||
for (const auto& value : values) {
|
||||
LDFData<T>* newData = nullptr;
|
||||
const auto& indexedName = name + u"." + GeneralUtils::to_u16string(index);
|
||||
|
||||
for (auto* data : m_NetworkSettings) {
|
||||
if (data->GetKey() != indexedName)
|
||||
continue;
|
||||
|
||||
newData = dynamic_cast<LDFData<T>*>(data);
|
||||
newData->SetValue(value);
|
||||
break;
|
||||
}
|
||||
|
||||
if (newData == nullptr) {
|
||||
newData = new LDFData<T>(indexedName, value);
|
||||
}
|
||||
|
||||
m_NetworkSettings.push_back(newData);
|
||||
|
||||
if (index == values.size()) {
|
||||
updates << newData->GetString(true);
|
||||
} else {
|
||||
updates << newData->GetString(true) << "\n";
|
||||
const auto itr = InsertNetworkVar<T>(indexedName, value);
|
||||
updates << itr->second->GetString();
|
||||
if (index != values.size()) {
|
||||
updates << "\n";
|
||||
}
|
||||
|
||||
index++;
|
||||
@@ -569,18 +553,15 @@ void Entity::SetNetworkVar(const std::u16string& name, std::vector<T> values, co
|
||||
|
||||
template<typename T>
|
||||
T Entity::GetNetworkVar(const std::u16string& name) {
|
||||
for (auto* data : m_NetworkSettings) {
|
||||
if (data == nullptr || data->GetKey() != name)
|
||||
continue;
|
||||
T toReturn = LDFData<T>::Default;
|
||||
|
||||
auto* typed = dynamic_cast<LDFData<T>*>(data);
|
||||
if (typed == nullptr)
|
||||
continue;
|
||||
|
||||
return typed->GetValue();
|
||||
const auto itr = m_NetworkSettings.values.find(name);
|
||||
if (itr != m_NetworkSettings.values.cend()) {
|
||||
auto* cast = dynamic_cast<LDFData<T>*>(itr->second.get());
|
||||
if (cast) toReturn = cast->GetValue();
|
||||
}
|
||||
|
||||
return LDFData<T>::Default;
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,10 +39,10 @@ Leaderboard::~Leaderboard() {
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ void Leaderboard::Serialize(RakNet::BitStream& bitStream) const {
|
||||
|
||||
int32_t rowNumber = 0;
|
||||
for (auto& entry : entries) {
|
||||
for (auto* data : entry) {
|
||||
WriteLeaderboardRow(leaderboard, rowNumber, data);
|
||||
for (const auto& data : entry.values | std::views::values) {
|
||||
if (data) WriteLeaderboardRow(leaderboard, rowNumber, data.get());
|
||||
}
|
||||
rowNumber++;
|
||||
}
|
||||
@@ -85,57 +85,56 @@ void QueryToLdf(Leaderboard& leaderboard, const std::vector<ILeaderboard::Entry>
|
||||
for (const auto& leaderboardEntry : leaderboardEntries) {
|
||||
constexpr int32_t MAX_NUM_DATA_PER_ROW = 9;
|
||||
auto& entry = leaderboard.PushBackEntry();
|
||||
entry.reserve(MAX_NUM_DATA_PER_ROW);
|
||||
entry.push_back(new LDFData<uint64_t>(u"CharacterID", leaderboardEntry.charId));
|
||||
entry.push_back(new LDFData<uint64_t>(u"LastPlayed", leaderboardEntry.lastPlayedTimestamp));
|
||||
entry.push_back(new LDFData<int32_t>(u"NumPlayed", leaderboardEntry.numTimesPlayed));
|
||||
entry.push_back(new LDFData<std::u16string>(u"name", GeneralUtils::ASCIIToUTF16(leaderboardEntry.name)));
|
||||
entry.push_back(new LDFData<uint64_t>(u"RowNumber", leaderboardEntry.ranking));
|
||||
entry.Insert<uint64_t>(u"CharacterID", leaderboardEntry.charId);
|
||||
entry.Insert<uint64_t>(u"LastPlayed", leaderboardEntry.lastPlayedTimestamp);
|
||||
entry.Insert<int32_t>(u"NumPlayed", leaderboardEntry.numTimesPlayed);
|
||||
entry.Insert<std::u16string>(u"name", GeneralUtils::ASCIIToUTF16(leaderboardEntry.name));
|
||||
entry.Insert<uint64_t>(u"RowNumber", leaderboardEntry.ranking);
|
||||
switch (leaderboard.GetLeaderboardType()) {
|
||||
case ShootingGallery:
|
||||
entry.push_back(new LDFData<int32_t>(u"Score", leaderboardEntry.primaryScore));
|
||||
entry.Insert<int32_t>(u"Score", leaderboardEntry.primaryScore);
|
||||
// Score:1
|
||||
entry.push_back(new LDFData<int32_t>(u"Streak", leaderboardEntry.secondaryScore));
|
||||
entry.Insert<int32_t>(u"Streak", leaderboardEntry.secondaryScore);
|
||||
// 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
|
||||
break;
|
||||
case Racing:
|
||||
entry.push_back(new LDFData<float>(u"BestTime", leaderboardEntry.primaryScore));
|
||||
entry.Insert<float>(u"BestTime", leaderboardEntry.primaryScore);
|
||||
// BestLapTime:3
|
||||
entry.push_back(new LDFData<float>(u"BestLapTime", leaderboardEntry.secondaryScore));
|
||||
entry.Insert<float>(u"BestLapTime", leaderboardEntry.secondaryScore);
|
||||
// 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
|
||||
entry.push_back(new LDFData<int32_t>(u"NumWins", leaderboardEntry.numWins));
|
||||
entry.Insert<int32_t>(u"NumWins", leaderboardEntry.numWins);
|
||||
// NumWins:1
|
||||
break;
|
||||
case UnusedLeaderboard4:
|
||||
entry.push_back(new LDFData<int32_t>(u"Points", leaderboardEntry.primaryScore));
|
||||
entry.Insert<int32_t>(u"Points", leaderboardEntry.primaryScore);
|
||||
// Points:1
|
||||
break;
|
||||
case MonumentRace:
|
||||
entry.push_back(new LDFData<int32_t>(u"Time", leaderboardEntry.primaryScore));
|
||||
entry.Insert<int32_t>(u"Time", leaderboardEntry.primaryScore);
|
||||
// Time:1(?)
|
||||
break;
|
||||
case FootRace:
|
||||
entry.push_back(new LDFData<int32_t>(u"Time", leaderboardEntry.primaryScore));
|
||||
entry.Insert<int32_t>(u"Time", leaderboardEntry.primaryScore);
|
||||
// Time:1
|
||||
break;
|
||||
case Survival:
|
||||
entry.push_back(new LDFData<int32_t>(u"Points", leaderboardEntry.primaryScore));
|
||||
entry.Insert<int32_t>(u"Points", leaderboardEntry.primaryScore);
|
||||
// Points:1
|
||||
entry.push_back(new LDFData<int32_t>(u"Time", leaderboardEntry.secondaryScore));
|
||||
entry.Insert<int32_t>(u"Time", leaderboardEntry.secondaryScore);
|
||||
// Time:1
|
||||
break;
|
||||
case SurvivalNS:
|
||||
entry.push_back(new LDFData<int32_t>(u"Wave", leaderboardEntry.primaryScore));
|
||||
entry.Insert<int32_t>(u"Wave", leaderboardEntry.primaryScore);
|
||||
// Wave:1
|
||||
entry.push_back(new LDFData<int32_t>(u"Time", leaderboardEntry.secondaryScore));
|
||||
entry.Insert<int32_t>(u"Time", leaderboardEntry.secondaryScore);
|
||||
// Time:1
|
||||
break;
|
||||
case Donations:
|
||||
entry.push_back(new LDFData<int32_t>(u"Score", leaderboardEntry.primaryScore));
|
||||
entry.Insert<int32_t>(u"Score", leaderboardEntry.primaryScore);
|
||||
// Score:1
|
||||
break;
|
||||
case None:
|
||||
|
||||
@@ -70,8 +70,7 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
using LeaderboardEntry = std::vector<LDFBaseData*>;
|
||||
using LeaderboardEntries = std::vector<LeaderboardEntry>;
|
||||
using LeaderboardEntries = std::vector<LwoNameValue>;
|
||||
|
||||
LeaderboardEntries entries;
|
||||
LWOOBJID relatedPlayer;
|
||||
@@ -81,7 +80,7 @@ private:
|
||||
bool weekly;
|
||||
uint32_t numResults;
|
||||
public:
|
||||
LeaderboardEntry& PushBackEntry() {
|
||||
LwoNameValue& PushBackEntry() {
|
||||
return entries.emplace_back();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "WorldPackets.h"
|
||||
#include "MessageType/Game.h"
|
||||
#include <ctime>
|
||||
#include <ranges>
|
||||
|
||||
CharacterComponent::CharacterComponent(Entity* parent, const int32_t componentID, Character* character, const SystemAddress& systemAddress) : Component(parent, componentID) {
|
||||
m_Character = character;
|
||||
@@ -491,7 +492,7 @@ Item* CharacterComponent::RocketEquip(Entity* player) {
|
||||
if (!rocket) return rocket;
|
||||
|
||||
// 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") {
|
||||
std::string newRocketStr = data->GetValueAsString() + ";";
|
||||
GeneralUtils::ReplaceInString(newRocketStr, "+", ";");
|
||||
|
||||
@@ -881,9 +881,9 @@ void DestroyableComponent::FixStats() {
|
||||
int32_t currentImagination = destroyableComponent->GetImagination();
|
||||
|
||||
// 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
|
||||
auto* item = inventoryComponent->FindItemById(equippedItem.second.id);
|
||||
|
||||
@@ -924,7 +924,7 @@ void DestroyableComponent::FixStats() {
|
||||
buffComponent->ReApplyBuffs();
|
||||
|
||||
// Requip all items
|
||||
for (auto& equippedItem : equipped) {
|
||||
for (const auto& equippedItem : equipped) {
|
||||
// Get the item with the item ID
|
||||
auto* item = inventoryComponent->FindItemById(equippedItem.second.id);
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ void InventoryComponent::AddItem(
|
||||
const uint32_t count,
|
||||
eLootSourceType lootSourceType,
|
||||
eInventoryType inventoryType,
|
||||
const std::vector<LDFBaseData*>& config,
|
||||
const LwoNameValue& config,
|
||||
const LWOOBJID parent,
|
||||
const bool showFlyingLoot,
|
||||
bool isModMoveAndEquip,
|
||||
@@ -204,7 +204,7 @@ void InventoryComponent::AddItem(
|
||||
|
||||
auto* inventory = GetInventory(inventoryType);
|
||||
|
||||
if (!config.empty() || bound) {
|
||||
if (!config.values.empty() || bound) {
|
||||
const auto slot = preferredSlot != -1 && inventory->IsSlotEmpty(preferredSlot) ? preferredSlot : inventory->FindEmptySlot();
|
||||
|
||||
if (slot == -1) {
|
||||
@@ -356,7 +356,7 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in
|
||||
|
||||
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));
|
||||
|
||||
while (left > 0) {
|
||||
@@ -379,11 +379,7 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in
|
||||
isModMoveAndEquip = false;
|
||||
}
|
||||
} else {
|
||||
std::vector<LDFBaseData*> config;
|
||||
|
||||
for (auto* const data : item->GetConfig()) {
|
||||
config.push_back(data->Copy());
|
||||
}
|
||||
const auto config = item->GetConfig();
|
||||
|
||||
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();
|
||||
|
||||
bool flag = !item.config.empty();
|
||||
bool flag = !item.config.values.empty();
|
||||
outBitStream.Write(flag);
|
||||
if (flag) {
|
||||
RakNet::BitStream ldfStream;
|
||||
ldfStream.Write<int32_t>(item.config.size()); // Key count
|
||||
for (LDFBaseData* data : item.config) {
|
||||
ldfStream.Write<int32_t>(item.config.values.size()); // Key count
|
||||
for (const auto& data : item.config.values | std::views::values) {
|
||||
if (data->GetKey() == u"assemblyPartLOTs") {
|
||||
std::string newRocketStr = data->GetValueAsString() + ";";
|
||||
GeneralUtils::ReplaceInString(newRocketStr, "+", ";");
|
||||
LDFData<std::u16string>* ldf_data = new LDFData<std::u16string>(u"assemblyPartLOTs", GeneralUtils::ASCIIToUTF16(newRocketStr));
|
||||
ldf_data->WriteToPacket(ldfStream);
|
||||
delete ldf_data;
|
||||
LDFData<std::u16string> ldf_data(u"assemblyPartLOTs", GeneralUtils::ASCIIToUTF16(newRocketStr));
|
||||
ldf_data.WriteToPacket(ldfStream);
|
||||
} else {
|
||||
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);
|
||||
|
||||
if (index != m_Equipped.end()) {
|
||||
@@ -1080,7 +1075,7 @@ void InventoryComponent::PushEquippedItems() {
|
||||
}
|
||||
|
||||
void InventoryComponent::PopEquippedItems() {
|
||||
auto current = m_Equipped;
|
||||
const auto current = m_Equipped;
|
||||
|
||||
for (const auto& pair : current) {
|
||||
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>("Is currently bound") = item->GetBound();
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -1892,7 +1887,7 @@ bool InventoryComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInfo
|
||||
equipSlot.PushDebug<AMFIntValue>("Slot") = info.slot;
|
||||
equipSlot.PushDebug<AMFIntValue>("Count") = info.count;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
uint32_t count,
|
||||
eLootSourceType lootSourceType = eLootSourceType::NONE,
|
||||
eInventoryType inventoryType = INVALID,
|
||||
const std::vector<LDFBaseData*>& config = {},
|
||||
const LwoNameValue& config = {},
|
||||
LWOOBJID parent = LWOOBJID_EMPTY,
|
||||
bool showFlyingLoot = true,
|
||||
bool isModMoveAndEquip = false,
|
||||
@@ -213,7 +213,7 @@ public:
|
||||
* @param item the item to place
|
||||
* @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
|
||||
|
||||
@@ -221,8 +221,8 @@ void ModelComponent::RemoveBehavior(MoveToInventoryMessage& msg, const bool keep
|
||||
auto* const inventoryComponent = playerEntity->GetComponent<InventoryComponent>();
|
||||
if (inventoryComponent && !behavior.GetIsLoot()) {
|
||||
// config is owned by the item
|
||||
std::vector<LDFBaseData*> config;
|
||||
config.push_back(new LDFData<std::string>(u"userModelName", behavior.GetName()));
|
||||
LwoNameValue config;
|
||||
config.Insert(u"userModelName", behavior.GetName());
|
||||
inventoryComponent->AddItem(7965, 1, eLootSourceType::PROPERTY, eInventoryType::BEHAVIORS, config, LWOOBJID_EMPTY, true, false, msg.GetBehaviorId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +347,7 @@ void PropertyManagementComponent::UpdateModelPosition(const LWOOBJID id, const N
|
||||
info.spawnerID = spawnerID;
|
||||
info.spawnerNodeID = 0;
|
||||
|
||||
for (auto* setting : item->GetConfig()) {
|
||||
for (const auto& setting : item->GetConfig().values | std::views::values) {
|
||||
info.settings.push_back(setting->Copy());
|
||||
}
|
||||
|
||||
@@ -476,28 +476,19 @@ void PropertyManagementComponent::DeleteModel(const LWOOBJID id, const int delet
|
||||
|
||||
if (model->GetLOT() == 14) {
|
||||
//add it to the inv
|
||||
std::vector<LDFBaseData*> settings;
|
||||
|
||||
LwoNameValue actualConfig;
|
||||
|
||||
//fill our settings with BBB gurbage
|
||||
LDFBaseData* ldfBlueprintID = new LDFData<LWOOBJID>(u"blueprintid", model->GetVar<LWOOBJID>(u"blueprintid"));
|
||||
LDFBaseData* userModelDesc = new LDFData<std::u16string>(u"userModelDesc", u"A cool model you made!");
|
||||
LDFBaseData* userModelHasBhvr = new LDFData<bool>(u"userModelHasBhvr", false);
|
||||
LDFBaseData* userModelID = new LDFData<LWOOBJID>(u"userModelID", model->GetVar<LWOOBJID>(u"userModelID"));
|
||||
LDFBaseData* userModelMod = new LDFData<bool>(u"userModelMod", false);
|
||||
LDFBaseData* userModelName = new LDFData<std::u16string>(u"userModelName", u"My Cool Model");
|
||||
LDFBaseData* propertyObjectID = new LDFData<bool>(u"userModelOpt", true);
|
||||
LDFBaseData* modelType = new LDFData<int>(u"userModelPhysicsType", 2);
|
||||
actualConfig.Insert(u"blueprintid", model->GetVar<LWOOBJID>(u"blueprintid"));
|
||||
actualConfig.Insert(u"userModelDesc", u"A cool model you made!");
|
||||
actualConfig.Insert(u"userModelHasBhvr", false);
|
||||
actualConfig.Insert(u"userModelID", model->GetVar<LWOOBJID>(u"userModelID"));
|
||||
actualConfig.Insert(u"userModelMod", false);
|
||||
actualConfig.Insert(u"userModelName", u"My Cool Model");
|
||||
actualConfig.Insert(u"userModelOpt", true);
|
||||
actualConfig.Insert(u"userModelPhysicsType", 2);
|
||||
|
||||
settings.push_back(ldfBlueprintID);
|
||||
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);
|
||||
inventoryComponent->AddItem(6662, 1, eLootSourceType::DELETION, eInventoryType::MODELS_IN_BBB, actualConfig, LWOOBJID_EMPTY, false, false, spawnerId);
|
||||
auto* item = inventoryComponent->FindItemBySubKey(spawnerId);
|
||||
|
||||
if (item == nullptr) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "dZoneManager.h"
|
||||
#include "CDActivitiesTable.h"
|
||||
#include "eStateChangeType.h"
|
||||
#include <ranges>
|
||||
#include <ctime>
|
||||
|
||||
#ifndef M_PI
|
||||
@@ -178,11 +179,10 @@ void RacingControlComponent::LoadPlayerVehicle(Entity* player,
|
||||
moduleAssemblyComponent->SetSubKey(item->GetSubKey());
|
||||
moduleAssemblyComponent->SetUseOptionalParts(false);
|
||||
|
||||
for (auto* config : item->GetConfig()) {
|
||||
if (config->GetKey() == u"assemblyPartLOTs") {
|
||||
moduleAssemblyComponent->SetAssemblyPartsLOTs(
|
||||
GeneralUtils::ASCIIToUTF16(config->GetValueAsString()));
|
||||
}
|
||||
const auto& lnv = item->GetConfig().values;
|
||||
const auto itr = lnv.find(u"assemblyPartLOTs");
|
||||
if (itr != lnv.end()) {
|
||||
moduleAssemblyComponent->SetAssemblyPartsLOTs(GeneralUtils::ASCIIToUTF16(itr->second->GetValueAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -874,7 +874,7 @@ void RacingControlComponent::Update(float deltaTime) {
|
||||
void RacingControlComponent::MsgConfigureRacingControl(const GameMessages::ConfigureRacingControl& msg) {
|
||||
for (const auto& dataUnique : msg.racingSettings) {
|
||||
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) {
|
||||
m_PathName = static_cast<const LDFData<std::u16string>*>(data)->GetValue();
|
||||
} else if (data->GetKey() == u"activityID" && data->GetValueType() == LDF_TYPE_S32) {
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include "GameMessages.h"
|
||||
#include "Amf3.h"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
ScriptComponent::ScriptComponent(Entity* parent, const int32_t componentID, const std::string& scriptName, bool serialized, bool client) : Component(parent, componentID) {
|
||||
m_Serialized = serialized;
|
||||
m_Client = client;
|
||||
@@ -20,7 +22,7 @@ ScriptComponent::ScriptComponent(Entity* parent, const int32_t componentID, cons
|
||||
void ScriptComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialUpdate) {
|
||||
if (bIsInitialUpdate) {
|
||||
const auto& networkSettings = m_Parent->GetNetworkSettings();
|
||||
auto hasNetworkSettings = !networkSettings.empty();
|
||||
auto hasNetworkSettings = !networkSettings.values.empty();
|
||||
outBitStream.Write(hasNetworkSettings);
|
||||
|
||||
if (hasNetworkSettings) {
|
||||
@@ -28,9 +30,9 @@ void ScriptComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitial
|
||||
// First write the most inner LDF data
|
||||
RakNet::BitStream ldfData;
|
||||
ldfData.Write<uint8_t>(0);
|
||||
ldfData.Write<uint32_t>(networkSettings.size());
|
||||
ldfData.Write<uint32_t>(networkSettings.values.size());
|
||||
|
||||
for (auto* networkSetting : networkSettings) {
|
||||
for (const auto& networkSetting : networkSettings.values | std::views::values) {
|
||||
networkSetting->WriteToPacket(ldfData);
|
||||
}
|
||||
|
||||
@@ -56,7 +58,7 @@ bool ScriptComponent::OnGetObjectReportInfo(GameMessages::GetObjectReportInfo& r
|
||||
auto& scriptInfo = reportInfo.info->PushDebug("Script");
|
||||
scriptInfo.PushDebug<AMFStringValue>("Script Name") = m_ScriptName.empty() ? "None" : m_ScriptName;
|
||||
auto& networkSettings = scriptInfo.PushDebug("Network Settings");
|
||||
for (const auto* const setting : m_Parent->GetNetworkSettings()) {
|
||||
for (const auto& setting : m_Parent->GetNetworkSettings().values | std::views::values) {
|
||||
networkSettings.PushDebug<AMFStringValue>(GeneralUtils::UTF16ToWTF8(setting->GetKey())) = setting->GetValueAsString();
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include <sstream>
|
||||
#include <future>
|
||||
#include <chrono>
|
||||
#include <ranges>
|
||||
#include "RakString.h"
|
||||
|
||||
//CDB includes:
|
||||
@@ -465,20 +466,20 @@ void GameMessages::SendAddItemToInventoryClientSync(Entity* entity, const System
|
||||
|
||||
bitStream.Write(lootSourceType != eLootSourceType::NONE); // Loot source
|
||||
if (lootSourceType != eLootSourceType::NONE) bitStream.Write(lootSourceType);
|
||||
LWONameValue extraInfo;
|
||||
std::u16string extraInfo;
|
||||
|
||||
auto config = item->GetConfig();
|
||||
|
||||
for (auto* data : config) {
|
||||
extraInfo.name += GeneralUtils::ASCIIToUTF16(data->GetString()) + u",";
|
||||
for (const auto& data : config.values | std::views::values) {
|
||||
extraInfo += GeneralUtils::ASCIIToUTF16(data->GetString()) + u",";
|
||||
}
|
||||
|
||||
if (extraInfo.name.length() > 0) extraInfo.name.pop_back(); // remove the last comma
|
||||
if (extraInfo.length() > 0) extraInfo.pop_back(); // remove the last comma
|
||||
|
||||
bitStream.Write<uint32_t>(extraInfo.name.size());
|
||||
if (extraInfo.name.size() > 0) {
|
||||
for (uint32_t i = 0; i < extraInfo.name.size(); ++i) {
|
||||
bitStream.Write<uint16_t>(extraInfo.name[i]);
|
||||
bitStream.Write<uint32_t>(extraInfo.size());
|
||||
if (extraInfo.size() > 0) {
|
||||
for (uint32_t i = 0; i < extraInfo.size(); ++i) {
|
||||
bitStream.Write<uint16_t>(extraInfo[i]);
|
||||
}
|
||||
bitStream.Write<uint16_t>(0x00);
|
||||
}
|
||||
@@ -743,13 +744,9 @@ void GameMessages::SendBroadcastTextToChatbox(Entity* entity, const SystemAddres
|
||||
bitStream.Write(entity->GetObjectID());
|
||||
bitStream.Write(MessageType::Game::BROADCAST_TEXT_TO_CHATBOX);
|
||||
|
||||
LWONameValue attribs;
|
||||
attribs.name = attrs;
|
||||
attribs.length = attrs.size();
|
||||
|
||||
bitStream.Write<uint32_t>(attribs.length);
|
||||
for (uint32_t i = 0; i < attribs.length; ++i) {
|
||||
bitStream.Write<uint16_t>(attribs.name[i]);
|
||||
bitStream.Write<uint32_t>(attrs.size());
|
||||
for (uint32_t i = 0; i < attrs.size(); ++i) {
|
||||
bitStream.Write<uint16_t>(attrs[i]);
|
||||
}
|
||||
bitStream.Write<uint16_t>(0x00); // Null Terminator
|
||||
|
||||
@@ -5266,7 +5263,8 @@ void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream& inStream, En
|
||||
int eInvType = INVENTORY_MAX;
|
||||
bool eLootTypeSourceIsDefault = false;
|
||||
int eLootTypeSource = LOOTTYPE_NONE;
|
||||
LWONameValue extraInfo;
|
||||
int32_t extraInfoLength = 0;
|
||||
std::u16string extraInfo;
|
||||
bool forceDeletion = true;
|
||||
bool iLootTypeSourceIsDefault = false;
|
||||
LWOOBJID iLootTypeSource = LWOOBJID_EMPTY;
|
||||
@@ -5292,12 +5290,12 @@ void GameMessages::HandleRemoveItemFromInventory(RakNet::BitStream& inStream, En
|
||||
if (eInvTypeIsDefault) inStream.Read(eInvType);
|
||||
inStream.Read(eLootTypeSourceIsDefault);
|
||||
if (eLootTypeSourceIsDefault) inStream.Read(eLootTypeSource);
|
||||
inStream.Read(extraInfo.length);
|
||||
if (extraInfo.length > 0) {
|
||||
for (uint32_t i = 0; i < extraInfo.length; ++i) {
|
||||
inStream.Read(extraInfoLength);
|
||||
if (extraInfoLength > 0) {
|
||||
for (uint32_t i = 0; i < extraInfoLength; ++i) {
|
||||
uint16_t character;
|
||||
inStream.Read(character);
|
||||
extraInfo.name.push_back(character);
|
||||
extraInfo.push_back(character);
|
||||
}
|
||||
uint16_t nullTerm;
|
||||
inStream.Read(nullTerm);
|
||||
@@ -5505,10 +5503,8 @@ void GameMessages::HandleModularBuildFinish(RakNet::BitStream& inStream, Entity*
|
||||
//inv->UnequipItem(inv->GetItemStackByLOT(6086, eInventoryType::ITEMS)); // take off the thinking cap
|
||||
//Game::entityManager->SerializeEntity(entity);
|
||||
|
||||
const auto moduleAssembly = new LDFData<std::u16string>(u"assemblyPartLOTs", modules);
|
||||
|
||||
std::vector<LDFBaseData*> config;
|
||||
config.push_back(moduleAssembly);
|
||||
LwoNameValue config;
|
||||
config.Insert(u"assemblyPartLOTs", modules);
|
||||
|
||||
LWOOBJID newID = ObjectIDManager::GetPersistentID();
|
||||
|
||||
@@ -5754,7 +5750,6 @@ void GameMessages::HandleUseNonEquipmentItem(RakNet::BitStream& inStream, Entity
|
||||
|
||||
void GameMessages::HandleMatchRequest(RakNet::BitStream& inStream, Entity* entity) {
|
||||
LWOOBJID activator;
|
||||
//std::map<LWOOBJID, LWONameValue> additionalPlayers;
|
||||
uint32_t playerChoicesLen;
|
||||
std::string playerChoices;
|
||||
int type;
|
||||
|
||||
@@ -31,5 +31,5 @@ struct EquippedItem
|
||||
/**
|
||||
* The configuration of the item with any extra data
|
||||
*/
|
||||
std::vector<LDFBaseData*> config = {};
|
||||
LwoNameValue config = {};
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "CDObjectSkillsTable.h"
|
||||
#include "CDComponentsRegistryTable.h"
|
||||
#include "CDPackageComponentTable.h"
|
||||
#include <ranges>
|
||||
|
||||
namespace {
|
||||
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)) {
|
||||
return;
|
||||
}
|
||||
@@ -71,7 +72,7 @@ Item::Item(
|
||||
Inventory* inventory,
|
||||
const uint32_t slot,
|
||||
const uint32_t count,
|
||||
const std::vector<LDFBaseData*>& config,
|
||||
const LwoNameValue& config,
|
||||
const LWOOBJID parent,
|
||||
bool showFlyingLoot,
|
||||
bool isModMoveAndEquip,
|
||||
@@ -131,11 +132,11 @@ uint32_t Item::GetSlot() const {
|
||||
return slot;
|
||||
}
|
||||
|
||||
std::vector<LDFBaseData*> Item::GetConfig() const {
|
||||
const LwoNameValue& Item::GetConfig() const {
|
||||
return config;
|
||||
}
|
||||
|
||||
std::vector<LDFBaseData*>& Item::GetConfig() {
|
||||
LwoNameValue& Item::GetConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -379,7 +380,7 @@ void Item::UseNonEquip(Item* item) {
|
||||
}
|
||||
|
||||
void Item::Disassemble(const eInventoryType inventoryType) {
|
||||
for (auto* data : config) {
|
||||
for (const auto& data : config.values | std::views::values) {
|
||||
if (data->GetKey() == u"assemblyPartLOTs") {
|
||||
auto modStr = data->GetValueAsString();
|
||||
|
||||
@@ -530,18 +531,12 @@ void Item::RemoveFromInventory() {
|
||||
|
||||
Item::~Item() {
|
||||
delete preconditions;
|
||||
|
||||
for (auto* value : config) {
|
||||
delete value;
|
||||
}
|
||||
|
||||
config.clear();
|
||||
}
|
||||
|
||||
void Item::SaveConfigXml(tinyxml2::XMLElement& i) const {
|
||||
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 saveKey = ExtraSettingAbbreviations.find(key);
|
||||
if (saveKey == ExtraSettingAbbreviations.end()) {
|
||||
@@ -561,12 +556,12 @@ void Item::LoadConfigXml(const tinyxml2::XMLElement& i) {
|
||||
const auto* x = i.FirstChildElement("x");
|
||||
if (!x) return;
|
||||
|
||||
for (const auto& pair : ExtraSettingAbbreviations) {
|
||||
const auto* data = x->Attribute(pair.second.c_str());
|
||||
for (const auto& [fullName, abbreviation] : ExtraSettingAbbreviations) {
|
||||
const auto* data = x->Attribute(abbreviation.c_str());
|
||||
if (!data) continue;
|
||||
|
||||
const auto value = pair.first + "=" + data;
|
||||
config.push_back(LDFBaseData::DataFromString(value));
|
||||
auto* const newPtr = LDFBaseData::DataFromString(fullName + "=" + data);
|
||||
config.values.insert_or_assign(newPtr->GetKey(), std::unique_ptr<LDFBaseData>(newPtr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
uint32_t slot,
|
||||
uint32_t count,
|
||||
bool bound,
|
||||
const std::vector<LDFBaseData*>& config,
|
||||
const LwoNameValue& config,
|
||||
LWOOBJID parent,
|
||||
LWOOBJID subKey,
|
||||
eLootSourceType lootSourceType = eLootSourceType::NONE
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
Inventory* inventory,
|
||||
uint32_t slot = 0,
|
||||
uint32_t count = 1,
|
||||
const std::vector<LDFBaseData*>& config = {},
|
||||
const LwoNameValue& config = {},
|
||||
LWOOBJID parent = LWOOBJID_EMPTY,
|
||||
bool showFlyingLoot = true,
|
||||
bool isModMoveAndEquip = false,
|
||||
@@ -118,13 +118,13 @@ public:
|
||||
* Returns current config info for this item, e.g. for rockets
|
||||
* @return current config info for this item
|
||||
*/
|
||||
std::vector<LDFBaseData*>& GetConfig();
|
||||
LwoNameValue& GetConfig();
|
||||
|
||||
/**
|
||||
* Returns current config info for this item, e.g. for rockets
|
||||
* @return current config info for this item
|
||||
*/
|
||||
std::vector<LDFBaseData*> GetConfig() const;
|
||||
const LwoNameValue& GetConfig() const;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
std::vector<LDFBaseData*> config;
|
||||
LwoNameValue config;
|
||||
|
||||
/**
|
||||
* The inventory this item belongs to
|
||||
|
||||
@@ -218,7 +218,6 @@ void MissionTask::Progress(int32_t value, LWOOBJID associate, const std::string&
|
||||
uint32_t activityId;
|
||||
uint32_t lot;
|
||||
uint32_t collectionId;
|
||||
std::vector<LDFBaseData*> settings;
|
||||
|
||||
switch (type) {
|
||||
case eMissionTaskType::UNKNOWN:
|
||||
|
||||
@@ -1268,10 +1268,10 @@ namespace DEVGMCommands {
|
||||
auto* inventoryComponent = entity->GetComponent<InventoryComponent>();
|
||||
if (!inventoryComponent) return;
|
||||
|
||||
std::vector<LDFBaseData*> data{};
|
||||
data.push_back(new LDFData<int32_t>(u"reforgedLOT", reforgedItem.value()));
|
||||
LwoNameValue config;
|
||||
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) {
|
||||
|
||||
@@ -70,7 +70,7 @@ void Level::MakeSpawner(SceneObject obj) {
|
||||
if (data->GetValueType() == eLDFType::LDF_TYPE_FLOAT) // Floats are in seconds
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ struct SceneObject {
|
||||
NiPoint3 position;
|
||||
NiQuaternion rotation = QuatUtils::IDENTITY;
|
||||
float scale = 1.0f;
|
||||
//std::string settings;
|
||||
uint32_t value3;
|
||||
std::vector<LDFBaseData*> settings;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user