From b6af92ef81a8c9f93557ad0492f927d027343d22 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sun, 18 Feb 2024 00:38:26 -0600 Subject: [PATCH 01/54] refactor: Rewrite BehaviorMessage classes to use member initialization, preferred member naming conventions, and const-ref getters (#1456) * Split out BehaviorMessage class changes from PR #1452 * remove inclusion in ActionContext.h * add the arguments nullptr check back in * remove redundant std::string constructor calls * Update AddStripMessage.cpp - change push_back to emplace_back --- dCommon/Amf3.h | 8 ++-- dGame/dGameMessages/GameMessages.cpp | 2 +- dGame/dPropertyBehaviors/BlockDefinition.cpp | 8 ++-- dGame/dPropertyBehaviors/BlockDefinition.h | 21 +++++----- .../ControlBehaviorMessages/Action.cpp | 38 +++++++------------ .../ControlBehaviorMessages/Action.h | 21 +++++----- .../ControlBehaviorMessages/ActionContext.cpp | 21 ++++------ .../ControlBehaviorMessages/ActionContext.h | 17 +++++---- .../AddActionMessage.cpp | 13 ++++--- .../AddActionMessage.h | 18 +++++---- .../ControlBehaviorMessages/AddMessage.cpp | 10 ++--- .../ControlBehaviorMessages/AddMessage.h | 7 ++-- .../AddStripMessage.cpp | 23 +++++------ .../ControlBehaviorMessages/AddStripMessage.h | 18 +++++---- .../BehaviorMessageBase.cpp | 17 ++++----- .../BehaviorMessageBase.h | 15 ++++---- .../MergeStripsMessage.cpp | 12 +++--- .../MergeStripsMessage.h | 26 ++++++++----- .../MigrateActionsMessage.cpp | 14 +++---- .../MigrateActionsMessage.h | 31 +++++++++------ .../MoveToInventoryMessage.cpp | 8 ++-- .../MoveToInventoryMessage.h | 8 ++-- .../RearrangeStripMessage.cpp | 12 +++--- .../RearrangeStripMessage.h | 17 +++++---- .../RemoveActionsMessage.cpp | 9 +++-- .../RemoveActionsMessage.h | 13 ++++--- .../RemoveStripMessage.cpp | 7 ++-- .../RemoveStripMessage.h | 8 ++-- .../ControlBehaviorMessages/RenameMessage.cpp | 8 ++-- .../ControlBehaviorMessages/RenameMessage.h | 8 ++-- .../SplitStripMessage.cpp | 14 +++---- .../SplitStripMessage.h | 33 +++++++++------- .../StripUiPosition.cpp | 29 ++++++-------- .../ControlBehaviorMessages/StripUiPosition.h | 13 ++++--- .../UpdateActionMessage.cpp | 15 ++++---- .../UpdateActionMessage.h | 18 +++++---- .../UpdateStripUiMessage.cpp | 9 +++-- .../UpdateStripUiMessage.h | 13 ++++--- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 22 +++++------ dGame/dPropertyBehaviors/ControlBehaviors.h | 15 ++++---- dGame/dPropertyBehaviors/PropertyBehavior.cpp | 13 ++----- dGame/dPropertyBehaviors/PropertyBehavior.h | 8 ++-- dGame/dPropertyBehaviors/State.cpp | 30 +++++++-------- dGame/dPropertyBehaviors/State.h | 3 +- dGame/dPropertyBehaviors/Strip.cpp | 25 ++++++------ dGame/dPropertyBehaviors/Strip.h | 5 ++- 46 files changed, 362 insertions(+), 341 deletions(-) diff --git a/dCommon/Amf3.h b/dCommon/Amf3.h index dbafba1f..c3077370 100644 --- a/dCommon/Amf3.h +++ b/dCommon/Amf3.h @@ -127,12 +127,12 @@ public: /** * Returns the Associative portion of the object */ - [[nodiscard]] inline AMFAssociative& GetAssociative() noexcept { return this->associative; } + [[nodiscard]] inline const AMFAssociative& GetAssociative() const noexcept { return this->associative; } /** * Returns the dense portion of the object */ - [[nodiscard]] inline AMFDense& GetDense() noexcept { return this->dense; } + [[nodiscard]] inline const AMFDense& GetDense() const noexcept { return this->dense; } /** * Inserts an AMFValue into the associative portion with the given key. @@ -297,7 +297,7 @@ public: if (!this->dense.empty()) Remove(this->dense.size() - 1); } - [[nodiscard]] AMFArrayValue* GetArray(const std::string& key) { + [[nodiscard]] AMFArrayValue* GetArray(const std::string& key) const { AMFAssociative::const_iterator it = this->associative.find(key); if (it != this->associative.end()) { return dynamic_cast(it->second); @@ -305,7 +305,7 @@ public: return nullptr; } - [[nodiscard]] AMFArrayValue* GetArray(const size_t index) { + [[nodiscard]] AMFArrayValue* GetArray(const size_t index) const { return index >= this->dense.size() ? nullptr : dynamic_cast(this->dense.at(index)); } diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index 3c42f4db..c38ef880 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -2504,7 +2504,7 @@ void GameMessages::HandleControlBehaviors(RakNet::BitStream* inStream, Entity* e auto owner = PropertyManagementComponent::Instance()->GetOwner(); if (!owner) return; - ControlBehaviors::Instance().ProcessCommand(entity, sysAddr, static_cast(amfArguments.get()), command, owner); + ControlBehaviors::Instance().ProcessCommand(entity, static_cast(amfArguments.get()), command, owner); } void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { diff --git a/dGame/dPropertyBehaviors/BlockDefinition.cpp b/dGame/dPropertyBehaviors/BlockDefinition.cpp index 2950ac82..e67a90d8 100644 --- a/dGame/dPropertyBehaviors/BlockDefinition.cpp +++ b/dGame/dPropertyBehaviors/BlockDefinition.cpp @@ -2,8 +2,8 @@ BlockDefinition BlockDefinition::blockDefinitionDefault{}; -BlockDefinition::BlockDefinition(std::string defaultValue, float minimumValue, float maximumValue) { - this->defaultValue = defaultValue; - this->minimumValue = minimumValue; - this->maximumValue = maximumValue; +BlockDefinition::BlockDefinition(const std::string& defaultValue, const float minimumValue, const float maximumValue) + : m_DefaultValue{ defaultValue } + , m_MinimumValue{ minimumValue } + , m_MaximumValue{ maximumValue } { } diff --git a/dGame/dPropertyBehaviors/BlockDefinition.h b/dGame/dPropertyBehaviors/BlockDefinition.h index 3a5a6bf1..84722ea2 100644 --- a/dGame/dPropertyBehaviors/BlockDefinition.h +++ b/dGame/dPropertyBehaviors/BlockDefinition.h @@ -7,19 +7,20 @@ class AMFArrayValue; class BlockDefinition { public: - BlockDefinition(std::string defaultValue = "", float minimumValue = 0.0f, float maximumValue = 0.0f); + BlockDefinition(const std::string& defaultValue = "", const float minimumValue = 0.0f, const float maximumValue = 0.0f); static BlockDefinition blockDefinitionDefault; - std::string& GetDefaultValue() { return defaultValue; }; - float GetMinimumValue() { return minimumValue; }; - float GetMaximumValue() { return maximumValue; }; - void SetDefaultValue(std::string value) { defaultValue = value; }; - void SetMinimumValue(float value) { minimumValue = value; }; - void SetMaximumValue(float value) { maximumValue = value; }; + [[nodiscard]] const std::string& GetDefaultValue() const { return m_DefaultValue; } + [[nodiscard]] float GetMinimumValue() const noexcept { return m_MinimumValue; } + [[nodiscard]] float GetMaximumValue() const noexcept { return m_MaximumValue; } + void SetDefaultValue(const std::string& value) { m_DefaultValue = value; } + void SetMinimumValue(const float value) noexcept { m_MinimumValue = value; } + void SetMaximumValue(const float value) noexcept { m_MaximumValue = value; } + private: - std::string defaultValue; - float minimumValue; - float maximumValue; + std::string m_DefaultValue; + float m_MinimumValue; + float m_MaximumValue; }; #endif //!__BLOCKDEFINITION__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp index 73f1391d..f9d3cec8 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp @@ -1,46 +1,34 @@ #include "Action.h" #include "Amf3.h" -Action::Action() { - type = ""; - valueParameterName = ""; - valueParameterString = ""; - valueParameterDouble = 0.0; -} - -Action::Action(AMFArrayValue* arguments) { - type = ""; - valueParameterName = ""; - valueParameterString = ""; - valueParameterDouble = 0.0; - for (auto& [paramName, paramValue] : arguments->GetAssociative()) { +Action::Action(const AMFArrayValue* arguments) { + for (const auto& [paramName, paramValue] : arguments->GetAssociative()) { if (paramName == "Type") { if (paramValue->GetValueType() != eAmf::String) continue; - type = static_cast(paramValue)->GetValue(); + m_Type = static_cast(paramValue)->GetValue(); } else { - valueParameterName = paramName; + m_ValueParameterName = paramName; // Message is the only known string parameter - if (valueParameterName == "Message") { + if (m_ValueParameterName == "Message") { if (paramValue->GetValueType() != eAmf::String) continue; - valueParameterString = static_cast(paramValue)->GetValue(); + m_ValueParameterString = static_cast(paramValue)->GetValue(); } else { if (paramValue->GetValueType() != eAmf::Double) continue; - valueParameterDouble = static_cast(paramValue)->GetValue(); + m_ValueParameterDouble = static_cast(paramValue)->GetValue(); } } } } void Action::SendBehaviorBlocksToClient(AMFArrayValue& args) const { - auto* actionArgs = args.PushArray(); - actionArgs->Insert("Type", type); + auto* const actionArgs = args.PushArray(); + actionArgs->Insert("Type", m_Type); - auto valueParameterName = GetValueParameterName(); - if (valueParameterName.empty()) return; + if (m_ValueParameterName.empty()) return; - if (valueParameterName == "Message") { - actionArgs->Insert(valueParameterName, valueParameterString); + if (m_ValueParameterName == "Message") { + actionArgs->Insert(m_ValueParameterName, m_ValueParameterString); } else { - actionArgs->Insert(valueParameterName, valueParameterDouble); + actionArgs->Insert(m_ValueParameterName, m_ValueParameterDouble); } } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h index df665889..c2bb7ed7 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h @@ -11,19 +11,20 @@ class AMFArrayValue; */ class Action { public: - Action(); - Action(AMFArrayValue* arguments); - const std::string& GetType() const { return type; }; - const std::string& GetValueParameterName() const { return valueParameterName; }; - const std::string& GetValueParameterString() const { return valueParameterString; }; - const double GetValueParameterDouble() const { return valueParameterDouble; }; + Action() = default; + Action(const AMFArrayValue* arguments); + [[nodiscard]] const std::string& GetType() const { return m_Type; }; + [[nodiscard]] const std::string& GetValueParameterName() const { return m_ValueParameterName; }; + [[nodiscard]] const std::string& GetValueParameterString() const { return m_ValueParameterString; }; + [[nodiscard]] double GetValueParameterDouble() const noexcept { return m_ValueParameterDouble; }; void SendBehaviorBlocksToClient(AMFArrayValue& args) const; + private: - std::string type; - std::string valueParameterName; - std::string valueParameterString; - double valueParameterDouble; + double m_ValueParameterDouble{ 0.0 }; + std::string m_Type{ "" }; + std::string m_ValueParameterName{ "" }; + std::string m_ValueParameterString{ "" }; }; #endif //!__ACTION__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp index c2ba2eeb..0cdfbddd 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.cpp @@ -4,27 +4,20 @@ #include "Amf3.h" -ActionContext::ActionContext() { - stripId = 0; - stateId = BehaviorState::HOME_STATE; +ActionContext::ActionContext(const AMFArrayValue* arguments, const std::string& customStateKey, const std::string& customStripKey) + : m_StripId{ GetStripIdFromArgument(arguments, customStripKey) } + , m_StateId{ GetBehaviorStateFromArgument(arguments, customStateKey) } { } -ActionContext::ActionContext(AMFArrayValue* arguments, std::string customStateKey, std::string customStripKey) { - stripId = 0; - stateId = BehaviorState::HOME_STATE; - stripId = GetStripIdFromArgument(arguments, customStripKey); - stateId = GetBehaviorStateFromArgument(arguments, customStateKey); -} - -BehaviorState ActionContext::GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key) { - auto* stateIDValue = arguments->Get(key); +BehaviorState ActionContext::GetBehaviorStateFromArgument(const AMFArrayValue* arguments, const std::string& key) const { + const auto* const stateIDValue = arguments->Get(key); if (!stateIDValue) throw std::invalid_argument("Unable to find behavior state from argument \"" + key + "\""); return static_cast(stateIDValue->GetValue()); } -StripId ActionContext::GetStripIdFromArgument(AMFArrayValue* arguments, const std::string& key) { - auto* stripIdValue = arguments->Get(key); +StripId ActionContext::GetStripIdFromArgument(const AMFArrayValue* arguments, const std::string& key) const { + const auto* const stripIdValue = arguments->Get(key); if (!stripIdValue) throw std::invalid_argument("Unable to find strip ID from argument \"" + key + "\""); return static_cast(stripIdValue->GetValue()); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h index 91e91e72..7013e84e 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h @@ -12,15 +12,16 @@ class AMFArrayValue; */ class ActionContext { public: - ActionContext(); - ActionContext(AMFArrayValue* arguments, std::string customStateKey = "stateID", std::string customStripKey = "stripID"); - const StripId GetStripId() const { return stripId; }; - const BehaviorState GetStateId() const { return stateId; }; + ActionContext() noexcept = default; + ActionContext(const AMFArrayValue* arguments, const std::string& customStateKey = "stateID", const std::string& customStripKey = "stripID"); + [[nodiscard]] StripId GetStripId() const noexcept { return m_StripId; }; + [[nodiscard]] BehaviorState GetStateId() const noexcept { return m_StateId; }; + private: - BehaviorState GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key); - StripId GetStripIdFromArgument(AMFArrayValue* arguments, const std::string& key); - StripId stripId; - BehaviorState stateId; + [[nodiscard]] BehaviorState GetBehaviorStateFromArgument(const AMFArrayValue* arguments, const std::string& key) const; + [[nodiscard]] StripId GetStripIdFromArgument(const AMFArrayValue* arguments, const std::string& key) const; + StripId m_StripId{ 0 }; + BehaviorState m_StateId{ BehaviorState::HOME_STATE }; }; #endif //!__ACTIONCONTEXT__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp index 36d9a3dc..44b1e9ab 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.cpp @@ -1,13 +1,14 @@ #include "AddActionMessage.h" -AddActionMessage::AddActionMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - actionContext = ActionContext(arguments); - actionIndex = GetActionIndexFromArgument(arguments); +AddActionMessage::AddActionMessage(const AMFArrayValue* arguments) + : BehaviorMessageBase{ arguments } + , m_ActionIndex{ GetActionIndexFromArgument(arguments) } + , m_ActionContext{ arguments } { - auto* actionValue = arguments->GetArray("action"); + const auto* const actionValue = arguments->GetArray("action"); if (!actionValue) return; - action = Action(actionValue); + m_Action = Action{ actionValue }; - LOG_DEBUG("actionIndex %i stripId %i stateId %i type %s valueParameterName %s valueParameterString %s valueParameterDouble %f behaviorId %i", actionIndex, actionContext.GetStripId(), actionContext.GetStateId(), action.GetType().c_str(), action.GetValueParameterName().c_str(), action.GetValueParameterString().c_str(), action.GetValueParameterDouble(), behaviorId); + LOG_DEBUG("actionIndex %i stripId %i stateId %i type %s valueParameterName %s valueParameterString %s valueParameterDouble %f m_BehaviorId %i", m_ActionIndex, m_ActionContext.GetStripId(), m_ActionContext.GetStateId(), m_Action.GetType().c_str(), m_Action.GetValueParameterName().c_str(), m_Action.GetValueParameterString().c_str(), m_Action.GetValueParameterDouble(), m_BehaviorId); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h index ac3a9612..a8737dd7 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h @@ -13,14 +13,18 @@ class AMFArrayValue; */ class AddActionMessage : public BehaviorMessageBase { public: - AddActionMessage(AMFArrayValue* arguments); - int32_t GetActionIndex() const { return actionIndex; }; - Action GetAction() const { return action; }; - ActionContext GetActionContext() const { return actionContext; }; + AddActionMessage(const AMFArrayValue* arguments); + + [[nodiscard]] int32_t GetActionIndex() const noexcept { return m_ActionIndex; }; + + [[nodiscard]] const Action& GetAction() const noexcept { return m_Action; }; + + [[nodiscard]] const ActionContext& GetActionContext() const noexcept { return m_ActionContext; }; + private: - int32_t actionIndex = -1; - ActionContext actionContext; - Action action; + int32_t m_ActionIndex{ -1 }; + ActionContext m_ActionContext; + Action m_Action; }; #endif //!__ADDACTIONMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp index cf96ab13..9c103334 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.cpp @@ -1,11 +1,9 @@ #include "AddMessage.h" -AddMessage::AddMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - behaviorIndex = 0; - auto* behaviorIndexValue = arguments->Get("BehaviorIndex"); - +AddMessage::AddMessage(const AMFArrayValue* arguments) : BehaviorMessageBase{ arguments } { + const auto* const behaviorIndexValue = arguments->Get("BehaviorIndex"); if (!behaviorIndexValue) return; - behaviorIndex = static_cast(behaviorIndexValue->GetValue()); - LOG_DEBUG("behaviorId %i index %i", behaviorId, behaviorIndex); + m_BehaviorIndex = static_cast(behaviorIndexValue->GetValue()); + LOG_DEBUG("behaviorId %i index %i", m_BehaviorId, m_BehaviorIndex); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h index 76627665..0832d687 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h @@ -9,10 +9,11 @@ */ class AddMessage : public BehaviorMessageBase { public: - AddMessage(AMFArrayValue* arguments); - const uint32_t GetBehaviorIndex() const { return behaviorIndex; }; + AddMessage(const AMFArrayValue* arguments); + [[nodiscard]] uint32_t GetBehaviorIndex() const noexcept { return m_BehaviorIndex; }; + private: - uint32_t behaviorIndex; + uint32_t m_BehaviorIndex{ 0 }; }; #endif //!__ADDMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp index ac6e8db7..064ba2e9 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.cpp @@ -2,27 +2,24 @@ #include "Action.h" -AddStripMessage::AddStripMessage(AMFArrayValue* const arguments) : BehaviorMessageBase{ arguments } { - actionContext = ActionContext(arguments); - position = StripUiPosition(arguments); +AddStripMessage::AddStripMessage(const AMFArrayValue* arguments) + : BehaviorMessageBase{ arguments } + , m_Position{ arguments } + , m_ActionContext{ arguments } { - auto* strip = arguments->GetArray("strip"); + const auto* const strip = arguments->GetArray("strip"); if (!strip) return; - auto* actions = strip->GetArray("actions"); + const auto* const actions = strip->GetArray("actions"); if (!actions) return; for (uint32_t actionNumber = 0; actionNumber < actions->GetDense().size(); actionNumber++) { - auto* actionValue = actions->GetArray(actionNumber); + const auto* const actionValue = actions->GetArray(actionNumber); if (!actionValue) continue; - actionsToAdd.push_back(Action(actionValue)); + m_ActionsToAdd.emplace_back(actionValue); - LOG_DEBUG("xPosition %f yPosition %f stripId %i stateId %i behaviorId %i t %s valueParameterName %s valueParameterString %s valueParameterDouble %f", position.GetX(), position.GetY(), actionContext.GetStripId(), actionContext.GetStateId(), behaviorId, actionsToAdd.back().GetType().c_str(), actionsToAdd.back().GetValueParameterName().c_str(), actionsToAdd.back().GetValueParameterString().c_str(), actionsToAdd.back().GetValueParameterDouble()); + LOG_DEBUG("xPosition %f yPosition %f stripId %i stateId %i behaviorId %i t %s valueParameterName %s valueParameterString %s valueParameterDouble %f", m_Position.GetX(), m_Position.GetY(), m_ActionContext.GetStripId(), m_ActionContext.GetStateId(), m_BehaviorId, m_ActionsToAdd.back().GetType().c_str(), m_ActionsToAdd.back().GetValueParameterName().c_str(), m_ActionsToAdd.back().GetValueParameterString().c_str(), m_ActionsToAdd.back().GetValueParameterDouble()); } - LOG_DEBUG("number of actions %i", actionsToAdd.size()); -} - -std::vector AddStripMessage::GetActionsToAdd() const { - return actionsToAdd; + LOG_DEBUG("number of actions %i", m_ActionsToAdd.size()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h index 2e2bf9a0..dbd70421 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h @@ -18,14 +18,18 @@ class AMFArrayValue; */ class AddStripMessage : public BehaviorMessageBase { public: - AddStripMessage(AMFArrayValue* const arguments); - StripUiPosition GetPosition() const { return position; }; - ActionContext GetActionContext() const { return actionContext; }; - std::vector GetActionsToAdd() const; + AddStripMessage(const AMFArrayValue* arguments); + + [[nodiscard]] const StripUiPosition& GetPosition() const noexcept { return m_Position; } + + [[nodiscard]] const ActionContext& GetActionContext() const noexcept { return m_ActionContext; } + + [[nodiscard]] const std::vector& GetActionsToAdd() const noexcept { return m_ActionsToAdd; } + private: - StripUiPosition position; - ActionContext actionContext; - std::vector actionsToAdd; + StripUiPosition m_Position; + ActionContext m_ActionContext; + std::vector m_ActionsToAdd; }; #endif //!__ADDSTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp index a49a8aeb..f7688e1a 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp @@ -4,25 +4,22 @@ #include "BehaviorStates.h" #include "dCommonVars.h" -BehaviorMessageBase::BehaviorMessageBase(AMFArrayValue* arguments) { - this->behaviorId = GetBehaviorIdFromArgument(arguments); -} - -int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(AMFArrayValue* const arguments) { - const char* const key = "BehaviorID"; +int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(const AMFArrayValue* arguments) { + static constexpr const char* key = "BehaviorID"; const auto* const behaviorIDValue = arguments->Get(key); + int32_t behaviorId = DefaultBehaviorId; if (behaviorIDValue && behaviorIDValue->GetValueType() == eAmf::String) { - this->behaviorId = - GeneralUtils::TryParse(behaviorIDValue->GetValue()).value_or(this->behaviorId); + behaviorId = + GeneralUtils::TryParse(behaviorIDValue->GetValue()).value_or(behaviorId); } else if (arguments->Get(key) && arguments->Get(key)->GetValueType() != eAmf::Undefined) { throw std::invalid_argument("Unable to find behavior ID"); } - return this->behaviorId; + return behaviorId; } -int32_t BehaviorMessageBase::GetActionIndexFromArgument(AMFArrayValue* const arguments, const std::string& keyName) const { +int32_t BehaviorMessageBase::GetActionIndexFromArgument(const AMFArrayValue* arguments, const std::string& keyName) const { const auto* const actionIndexAmf = arguments->Get(keyName); if (!actionIndexAmf) throw std::invalid_argument("Unable to find actionIndex"); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h index f55fde8e..cadf33bf 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h @@ -15,14 +15,15 @@ enum class BehaviorState : uint32_t; */ class BehaviorMessageBase { public: - static constexpr int32_t DefaultBehaviorId = -1; - [[nodiscard]] int32_t GetBehaviorId() const { return behaviorId; }; - [[nodiscard]] bool IsDefaultBehaviorId() { return behaviorId == DefaultBehaviorId; }; - BehaviorMessageBase(AMFArrayValue* const arguments); + static constexpr int32_t DefaultBehaviorId{ -1 }; + BehaviorMessageBase(const AMFArrayValue* arguments) : m_BehaviorId{ GetBehaviorIdFromArgument(arguments) } {} + [[nodiscard]] int32_t GetBehaviorId() const noexcept { return m_BehaviorId; } + [[nodiscard]] bool IsDefaultBehaviorId() const noexcept { return m_BehaviorId == DefaultBehaviorId; } + protected: - [[nodiscard]] int32_t GetBehaviorIdFromArgument(AMFArrayValue* const arguments); - [[nodiscard]] int32_t GetActionIndexFromArgument(AMFArrayValue* const arguments, const std::string& keyName = "actionIndex") const; - int32_t behaviorId = DefaultBehaviorId; + [[nodiscard]] int32_t GetBehaviorIdFromArgument(const AMFArrayValue* arguments); + [[nodiscard]] int32_t GetActionIndexFromArgument(const AMFArrayValue* arguments, const std::string& keyName = "actionIndex") const; + int32_t m_BehaviorId{ DefaultBehaviorId }; }; #endif //!__BEHAVIORMESSAGEBASE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp index 18327ecf..d5a83714 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.cpp @@ -1,11 +1,11 @@ #include "MergeStripsMessage.h" -MergeStripsMessage::MergeStripsMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - sourceActionContext = ActionContext(arguments, "srcStateID", "srcStripID"); +MergeStripsMessage::MergeStripsMessage(const AMFArrayValue* arguments) + : BehaviorMessageBase{ arguments } + , m_DstActionIndex{ GetActionIndexFromArgument(arguments, "dstActionIndex") } + , m_SourceActionContext{ arguments, "srcStateID", "srcStripID" } + , m_DestinationActionContext{ arguments, "dstStateID", "dstStripID" } { - destinationActionContext = ActionContext(arguments, "dstStateID", "dstStripID"); - dstActionIndex = GetActionIndexFromArgument(arguments, "dstActionIndex"); - - LOG_DEBUG("srcstripId %i dststripId %i srcstateId %i dststateId %i dstactionIndex %i behaviorId %i", sourceActionContext.GetStripId(), destinationActionContext.GetStripId(), sourceActionContext.GetStateId(), destinationActionContext.GetStateId(), dstActionIndex, behaviorId); + LOG_DEBUG("srcstripId %i dststripId %i srcstateId %i dststateId %i dstactionIndex %i behaviorId %i", m_SourceActionContext.GetStripId(), m_DestinationActionContext.GetStripId(), m_SourceActionContext.GetStateId(), m_DestinationActionContext.GetStateId(), m_DstActionIndex, m_BehaviorId); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h index 7fa4d3a8..970a744d 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h @@ -13,17 +13,23 @@ class AMFArrayValue; */ class MergeStripsMessage : public BehaviorMessageBase { public: - MergeStripsMessage(AMFArrayValue* arguments); - int32_t GetDstActionIndex() const { return dstActionIndex; }; - ActionContext GetSourceActionContext() const { return sourceActionContext; }; - ActionContext GetDestinationActionContext() const { return destinationActionContext; }; - const std::vector& GetMigratedActions() const { return migratedActions; }; - void SetMigratedActions(std::vector::const_iterator start, std::vector::const_iterator end) { migratedActions.assign(start, end); }; + MergeStripsMessage(const AMFArrayValue* arguments); + + [[nodiscard]] int32_t GetDstActionIndex() const noexcept { return m_DstActionIndex; } + + [[nodiscard]] const ActionContext& GetSourceActionContext() const noexcept { return m_SourceActionContext; } + + [[nodiscard]] const ActionContext& GetDestinationActionContext() const noexcept { return m_DestinationActionContext; } + + [[nodiscard]] const std::vector& GetMigratedActions() const noexcept { return m_MigratedActions; } + + void SetMigratedActions(std::vector::const_iterator start, std::vector::const_iterator end) { m_MigratedActions.assign(start, end); }; + private: - std::vector migratedActions; - ActionContext sourceActionContext; - ActionContext destinationActionContext; - int32_t dstActionIndex; + int32_t m_DstActionIndex; + std::vector m_MigratedActions; + ActionContext m_SourceActionContext; + ActionContext m_DestinationActionContext; }; #endif //!__MERGESTRIPSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp index 4d45429b..8fa2cb5b 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.cpp @@ -1,11 +1,11 @@ #include "MigrateActionsMessage.h" -MigrateActionsMessage::MigrateActionsMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - sourceActionContext = ActionContext(arguments, "srcStateID", "srcStripID"); - srcActionIndex = GetActionIndexFromArgument(arguments, "srcActionIndex"); +MigrateActionsMessage::MigrateActionsMessage(const AMFArrayValue* arguments) + : BehaviorMessageBase{ arguments } + , m_SrcActionIndex{ GetActionIndexFromArgument(arguments, "srcActionIndex") } + , m_DstActionIndex{ GetActionIndexFromArgument(arguments, "dstActionIndex") } + , m_SourceActionContext{ arguments, "srcStateID", "srcStripID" } + , m_DestinationActionContext{ arguments, "dstStateID", "dstStripID" } { - destinationActionContext = ActionContext(arguments, "dstStateID", "dstStripID"); - dstActionIndex = GetActionIndexFromArgument(arguments, "dstActionIndex"); - - LOG_DEBUG("srcactionIndex %i dstactionIndex %i srcstripId %i dststripId %i srcstateId %i dststateId %i behaviorId %i", srcActionIndex, dstActionIndex, sourceActionContext.GetStripId(), destinationActionContext.GetStripId(), sourceActionContext.GetStateId(), destinationActionContext.GetStateId(), behaviorId); + LOG_DEBUG("srcactionIndex %i dstactionIndex %i srcstripId %i dststripId %i srcstateId %i dststateId %i behaviorId %i", m_SrcActionIndex, m_DstActionIndex, m_SourceActionContext.GetStripId(), m_DestinationActionContext.GetStripId(), m_SourceActionContext.GetStateId(), m_DestinationActionContext.GetStateId(), m_BehaviorId); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h index 2f1ac243..e3671185 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h @@ -13,19 +13,26 @@ class AMFArrayValue; */ class MigrateActionsMessage : public BehaviorMessageBase { public: - MigrateActionsMessage(AMFArrayValue* arguments); - int32_t GetSrcActionIndex() const { return srcActionIndex; }; - int32_t GetDstActionIndex() const { return dstActionIndex; }; - ActionContext GetSourceActionContext() const { return sourceActionContext; }; - ActionContext GetDestinationActionContext() const { return destinationActionContext; }; - const std::vector& GetMigratedActions() const { return migratedActions; }; - void SetMigratedActions(std::vector::const_iterator start, std::vector::const_iterator end) { migratedActions.assign(start, end); }; + MigrateActionsMessage(const AMFArrayValue* arguments); + + [[nodiscard]] int32_t GetSrcActionIndex() const noexcept { return m_SrcActionIndex; } + + [[nodiscard]] int32_t GetDstActionIndex() const noexcept { return m_DstActionIndex; } + + [[nodiscard]] const ActionContext& GetSourceActionContext() const noexcept { return m_SourceActionContext; } + + [[nodiscard]] const ActionContext& GetDestinationActionContext() const noexcept { return m_DestinationActionContext; } + + [[nodiscard]] const std::vector& GetMigratedActions() const noexcept { return m_MigratedActions; } + + void SetMigratedActions(std::vector::const_iterator start, std::vector::const_iterator end) { m_MigratedActions.assign(start, end); } + private: - std::vector migratedActions; - ActionContext sourceActionContext; - ActionContext destinationActionContext; - int32_t srcActionIndex; - int32_t dstActionIndex; + int32_t m_SrcActionIndex; + int32_t m_DstActionIndex; + std::vector m_MigratedActions; + ActionContext m_SourceActionContext; + ActionContext m_DestinationActionContext; }; #endif //!__MIGRATEACTIONSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp index 5195e676..01709f70 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.cpp @@ -1,9 +1,9 @@ #include "MoveToInventoryMessage.h" -MoveToInventoryMessage::MoveToInventoryMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - auto* behaviorIndexValue = arguments->Get("BehaviorIndex"); +MoveToInventoryMessage::MoveToInventoryMessage(const AMFArrayValue* arguments) : BehaviorMessageBase{ arguments } { + const auto* const behaviorIndexValue = arguments->Get("BehaviorIndex"); if (!behaviorIndexValue) return; - behaviorIndex = static_cast(behaviorIndexValue->GetValue()); - LOG_DEBUG("behaviorId %i behaviorIndex %i", behaviorId, behaviorIndex); + m_BehaviorIndex = static_cast(behaviorIndexValue->GetValue()); + LOG_DEBUG("behaviorId %i behaviorIndex %i", m_BehaviorId, m_BehaviorIndex); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h index dc105766..9a383469 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h @@ -7,15 +7,15 @@ class AMFArrayValue; /** * @brief Sent when a player moves a Behavior A at position B to their inventory. - * */ #pragma warning("This Control Behavior Message does not have a test yet. Non-developers can ignore this warning.") class MoveToInventoryMessage : public BehaviorMessageBase { public: - MoveToInventoryMessage(AMFArrayValue* arguments); - const uint32_t GetBehaviorIndex() const { return behaviorIndex; }; + MoveToInventoryMessage(const AMFArrayValue* arguments); + [[nodiscard]] uint32_t GetBehaviorIndex() const noexcept { return m_BehaviorIndex; }; + private: - uint32_t behaviorIndex; + uint32_t m_BehaviorIndex; }; #endif //!__MOVETOINVENTORYMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp index d612ae2a..0c3689fa 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.cpp @@ -1,10 +1,10 @@ #include "RearrangeStripMessage.h" -RearrangeStripMessage::RearrangeStripMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - actionContext = ActionContext(arguments); - srcActionIndex = GetActionIndexFromArgument(arguments, "srcActionIndex"); +RearrangeStripMessage::RearrangeStripMessage(const AMFArrayValue* arguments) + : BehaviorMessageBase{ arguments } + , m_SrcActionIndex{ GetActionIndexFromArgument(arguments, "srcActionIndex") } + , m_DstActionIndex{ GetActionIndexFromArgument(arguments, "dstActionIndex") } + , m_ActionContext{ arguments } { - dstActionIndex = GetActionIndexFromArgument(arguments, "dstActionIndex"); - - LOG_DEBUG("srcactionIndex %i dstactionIndex %i stripId %i behaviorId %i stateId %i", srcActionIndex, dstActionIndex, actionContext.GetStripId(), behaviorId, actionContext.GetStateId()); + LOG_DEBUG("srcactionIndex %i dstactionIndex %i stripId %i behaviorId %i stateId %i", m_SrcActionIndex, m_DstActionIndex, m_ActionContext.GetStripId(), m_BehaviorId, m_ActionContext.GetStateId()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h index db12c046..054fbf3e 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h @@ -10,14 +10,17 @@ */ class RearrangeStripMessage : public BehaviorMessageBase { public: - RearrangeStripMessage(AMFArrayValue* arguments); - int32_t GetSrcActionIndex() const { return srcActionIndex; }; - int32_t GetDstActionIndex() const { return dstActionIndex; }; - ActionContext GetActionContext() const { return actionContext; }; + RearrangeStripMessage(const AMFArrayValue* arguments); + + [[nodiscard]] int32_t GetSrcActionIndex() const noexcept { return m_SrcActionIndex; } + [[nodiscard]] int32_t GetDstActionIndex() const noexcept { return m_DstActionIndex; } + + [[nodiscard]] const ActionContext& GetActionContext() const noexcept { return m_ActionContext; } + private: - ActionContext actionContext; - int32_t srcActionIndex; - int32_t dstActionIndex; + int32_t m_SrcActionIndex; + int32_t m_DstActionIndex; + ActionContext m_ActionContext; }; #endif //!__REARRANGESTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp index c6164c6f..ab13cd20 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.cpp @@ -1,8 +1,9 @@ #include "RemoveActionsMessage.h" -RemoveActionsMessage::RemoveActionsMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - actionContext = ActionContext(arguments); - actionIndex = GetActionIndexFromArgument(arguments); +RemoveActionsMessage::RemoveActionsMessage(const AMFArrayValue* arguments) + : BehaviorMessageBase{ arguments } + , m_ActionIndex{ GetActionIndexFromArgument(arguments) } + , m_ActionContext{ arguments } { - LOG_DEBUG("behaviorId %i actionIndex %i stripId %i stateId %i", behaviorId, actionIndex, actionContext.GetStripId(), actionContext.GetStateId()); + LOG_DEBUG("behaviorId %i actionIndex %i stripId %i stateId %i", m_BehaviorId, m_ActionIndex, m_ActionContext.GetStripId(), m_ActionContext.GetStateId()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h index 860df0af..7e212206 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h @@ -12,12 +12,15 @@ class AMFArrayValue; */ class RemoveActionsMessage : public BehaviorMessageBase { public: - RemoveActionsMessage(AMFArrayValue* arguments); - int32_t GetActionIndex() const { return actionIndex; }; - ActionContext GetActionContext() const { return actionContext; }; + RemoveActionsMessage(const AMFArrayValue* arguments); + + [[nodiscard]] int32_t GetActionIndex() const noexcept { return m_ActionIndex; } + + [[nodiscard]] const ActionContext& GetActionContext() const noexcept { return m_ActionContext; } + private: - ActionContext actionContext; - int32_t actionIndex; + int32_t m_ActionIndex; + ActionContext m_ActionContext; }; #endif //!__REMOVEACTIONSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp index b70beece..371faf1c 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.cpp @@ -1,7 +1,8 @@ #include "RemoveStripMessage.h" -RemoveStripMessage::RemoveStripMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - actionContext = ActionContext(arguments); +RemoveStripMessage::RemoveStripMessage(const AMFArrayValue* arguments) + : BehaviorMessageBase{ arguments } + , m_ActionContext{ arguments } { - LOG_DEBUG("stripId %i stateId %i behaviorId %i", actionContext.GetStripId(), actionContext.GetStateId(), behaviorId); + LOG_DEBUG("stripId %i stateId %i behaviorId %i", m_ActionContext.GetStripId(), m_ActionContext.GetStateId(), m_BehaviorId); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h index 6a32ab0c..a65949e8 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h @@ -10,10 +10,12 @@ */ class RemoveStripMessage : public BehaviorMessageBase { public: - RemoveStripMessage(AMFArrayValue* arguments); - ActionContext GetActionContext() const { return actionContext; }; + RemoveStripMessage(const AMFArrayValue* arguments); + + const ActionContext& GetActionContext() const noexcept { return m_ActionContext; } + private: - ActionContext actionContext; + ActionContext m_ActionContext; }; #endif //!__REMOVESTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp index 17365be2..d9c73f6a 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.cpp @@ -1,9 +1,9 @@ #include "RenameMessage.h" -RenameMessage::RenameMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - auto* nameAmf = arguments->Get("Name"); +RenameMessage::RenameMessage(const AMFArrayValue* arguments) : BehaviorMessageBase{ arguments } { + const auto* const nameAmf = arguments->Get("Name"); if (!nameAmf) return; - name = nameAmf->GetValue(); - LOG_DEBUG("behaviorId %i n %s", behaviorId, name.c_str()); + m_Name = nameAmf->GetValue(); + LOG_DEBUG("behaviorId %i n %s", m_BehaviorId, m_Name.c_str()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h index 3f4119d2..e7174296 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h @@ -7,14 +7,14 @@ class AMFArrayValue; /** * @brief Sent when a player renames this behavior - * */ class RenameMessage : public BehaviorMessageBase { public: - RenameMessage(AMFArrayValue* arguments); - const std::string& GetName() const { return name; }; + RenameMessage(const AMFArrayValue* arguments); + [[nodiscard]] const std::string& GetName() const { return m_Name; }; + private: - std::string name; + std::string m_Name; }; #endif //!__RENAMEMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp index 45dad737..9c35d1ba 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.cpp @@ -1,11 +1,11 @@ #include "SplitStripMessage.h" -SplitStripMessage::SplitStripMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - sourceActionContext = ActionContext(arguments, "srcStateID", "srcStripID"); - srcActionIndex = GetActionIndexFromArgument(arguments, "srcActionIndex"); +SplitStripMessage::SplitStripMessage(const AMFArrayValue* arguments) + : BehaviorMessageBase{ arguments } + , m_SrcActionIndex{ GetActionIndexFromArgument(arguments, "srcActionIndex") } + , m_SourceActionContext{ arguments, "srcStateID", "srcStripID" } + , m_DestinationActionContext{ arguments, "dstStateID", "dstStripID" } + , m_DestinationPosition{ arguments, "dstStripUI" } { - destinationActionContext = ActionContext(arguments, "dstStateID", "dstStripID"); - destinationPosition = StripUiPosition(arguments, "dstStripUI"); - - LOG_DEBUG("behaviorId %i xPosition %f yPosition %f sourceStrip %i destinationStrip %i sourceState %i destinationState %i srcActindex %i", behaviorId, destinationPosition.GetX(), destinationPosition.GetY(), sourceActionContext.GetStripId(), destinationActionContext.GetStripId(), sourceActionContext.GetStateId(), destinationActionContext.GetStateId(), srcActionIndex); + LOG_DEBUG("behaviorId %i xPosition %f yPosition %f sourceStrip %i destinationStrip %i sourceState %i destinationState %i srcActindex %i", m_BehaviorId, m_DestinationPosition.GetX(), m_DestinationPosition.GetY(), m_SourceActionContext.GetStripId(), m_DestinationActionContext.GetStripId(), m_SourceActionContext.GetStateId(), m_DestinationActionContext.GetStateId(), m_SrcActionIndex); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h index e41d50eb..6cdcc5c3 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h @@ -14,20 +14,27 @@ class AMFArrayValue; */ class SplitStripMessage : public BehaviorMessageBase { public: - SplitStripMessage(AMFArrayValue* arguments); - ActionContext GetSourceActionContext() const { return sourceActionContext; }; - ActionContext GetDestinationActionContext() const { return destinationActionContext; }; - int32_t GetSrcActionIndex() const { return srcActionIndex; }; - StripUiPosition GetPosition() const { return destinationPosition; }; - const std::vector& GetTransferredActions() const { return transferredActions; }; - void SetTransferredActions(std::vector::const_iterator begin, std::vector::const_iterator end) { transferredActions.assign(begin, end); }; -private: - ActionContext sourceActionContext; - ActionContext destinationActionContext; - int32_t srcActionIndex; - StripUiPosition destinationPosition; + SplitStripMessage(const AMFArrayValue* arguments); + + [[nodiscard]] int32_t GetSrcActionIndex() const noexcept { return m_SrcActionIndex; } - std::vector transferredActions; + [[nodiscard]] const ActionContext& GetSourceActionContext() const noexcept { return m_SourceActionContext; } + + [[nodiscard]] const ActionContext& GetDestinationActionContext() const noexcept { return m_DestinationActionContext; } + + [[nodiscard]] const StripUiPosition& GetPosition() const noexcept { return m_DestinationPosition; } + + [[nodiscard]] const std::vector& GetTransferredActions() const noexcept { return m_TransferredActions; } + + void SetTransferredActions(std::vector::const_iterator begin, std::vector::const_iterator end) { m_TransferredActions.assign(begin, end); }; + +private: + int32_t m_SrcActionIndex; + ActionContext m_SourceActionContext; + ActionContext m_DestinationActionContext; + StripUiPosition m_DestinationPosition; + + std::vector m_TransferredActions; }; #endif //!__SPLITSTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp index 8b2d1d36..0acbfb3f 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp @@ -2,27 +2,22 @@ #include "Amf3.h" -StripUiPosition::StripUiPosition() { - xPosition = 0.0; - yPosition = 0.0; -} - -StripUiPosition::StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName) { - xPosition = 0.0; - yPosition = 0.0; - auto* uiArray = arguments->GetArray(uiKeyName); +StripUiPosition::StripUiPosition(const AMFArrayValue* arguments, const std::string& uiKeyName) { + const auto* const uiArray = arguments->GetArray(uiKeyName); if (!uiArray) return; - auto* xPositionValue = uiArray->Get("x"); - auto* yPositionValue = uiArray->Get("y"); - if (!xPositionValue || !yPositionValue) return; + const auto* const xPositionValue = uiArray->Get("x"); + if (!xPositionValue) return; - yPosition = yPositionValue->GetValue(); - xPosition = xPositionValue->GetValue(); + const auto* const yPositionValue = uiArray->Get("y"); + if (!yPositionValue) return; + + m_YPosition = yPositionValue->GetValue(); + m_XPosition = xPositionValue->GetValue(); } void StripUiPosition::SendBehaviorBlocksToClient(AMFArrayValue& args) const { - auto* uiArgs = args.InsertArray("ui"); - uiArgs->Insert("x", xPosition); - uiArgs->Insert("y", yPosition); + auto* const uiArgs = args.InsertArray("ui"); + uiArgs->Insert("x", m_XPosition); + uiArgs->Insert("y", m_YPosition); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h index 92578cdc..6371b465 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h @@ -9,14 +9,15 @@ class AMFArrayValue; */ class StripUiPosition { public: - StripUiPosition(); - StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName = "ui"); + StripUiPosition() noexcept = default; + StripUiPosition(const AMFArrayValue* arguments, const std::string& uiKeyName = "ui"); void SendBehaviorBlocksToClient(AMFArrayValue& args) const; - double GetX() const { return xPosition; }; - double GetY() const { return yPosition; }; + [[nodiscard]] double GetX() const noexcept { return m_XPosition; } + [[nodiscard]] double GetY() const noexcept { return m_YPosition; } + private: - double xPosition; - double yPosition; + double m_XPosition{ 0.0 }; + double m_YPosition{ 0.0 }; }; #endif //!__STRIPUIPOSITION__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp index 924a9e62..68b97917 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.cpp @@ -2,14 +2,15 @@ #include "Action.h" -UpdateActionMessage::UpdateActionMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - actionContext = ActionContext(arguments); +UpdateActionMessage::UpdateActionMessage(const AMFArrayValue* arguments) + : BehaviorMessageBase{ arguments } + , m_ActionIndex{ GetActionIndexFromArgument(arguments) } + , m_ActionContext{ arguments } { - auto* actionValue = arguments->GetArray("action"); + const auto* const actionValue = arguments->GetArray("action"); if (!actionValue) return; + + m_Action = Action{ actionValue }; - action = Action(actionValue); - actionIndex = GetActionIndexFromArgument(arguments); - - LOG_DEBUG("type %s valueParameterName %s valueParameterString %s valueParameterDouble %f behaviorId %i actionIndex %i stripId %i stateId %i", action.GetType().c_str(), action.GetValueParameterName().c_str(), action.GetValueParameterString().c_str(), action.GetValueParameterDouble(), behaviorId, actionIndex, actionContext.GetStripId(), actionContext.GetStateId()); + LOG_DEBUG("type %s valueParameterName %s valueParameterString %s valueParameterDouble %f behaviorId %i actionIndex %i stripId %i stateId %i", m_Action.GetType().c_str(), m_Action.GetValueParameterName().c_str(), m_Action.GetValueParameterString().c_str(), m_Action.GetValueParameterDouble(), m_BehaviorId, m_ActionIndex, m_ActionContext.GetStripId(), m_ActionContext.GetStateId()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h index aa34940b..cfa9dd4d 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h @@ -13,14 +13,18 @@ class AMFArrayValue; */ class UpdateActionMessage : public BehaviorMessageBase { public: - UpdateActionMessage(AMFArrayValue* arguments); - int32_t GetActionIndex() const { return actionIndex; }; - ActionContext GetActionContext() const { return actionContext; }; - Action GetAction() const { return action; }; + UpdateActionMessage(const AMFArrayValue* arguments); + + [[nodiscard]] int32_t GetActionIndex() const noexcept { return m_ActionIndex; } + + [[nodiscard]] const ActionContext& GetActionContext() const noexcept { return m_ActionContext; } + + [[nodiscard]] const Action& GetAction() const noexcept { return m_Action; } + private: - int32_t actionIndex; - ActionContext actionContext; - Action action; + int32_t m_ActionIndex; + ActionContext m_ActionContext; + Action m_Action; }; #endif //!__UPDATEACTIONMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp index 05dc7cf7..593673b6 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.cpp @@ -1,8 +1,9 @@ #include "UpdateStripUiMessage.h" -UpdateStripUiMessage::UpdateStripUiMessage(AMFArrayValue* arguments) : BehaviorMessageBase(arguments) { - position = StripUiPosition(arguments); - actionContext = ActionContext(arguments); +UpdateStripUiMessage::UpdateStripUiMessage(const AMFArrayValue* arguments) + : BehaviorMessageBase{ arguments } + , m_Position{ arguments } + , m_ActionContext{ arguments } { - LOG_DEBUG("xPosition %f yPosition %f stripId %i stateId %i behaviorId %i", position.GetX(), position.GetY(), actionContext.GetStripId(), actionContext.GetStateId(), behaviorId); + LOG_DEBUG("xPosition %f yPosition %f stripId %i stateId %i behaviorId %i", m_Position.GetX(), m_Position.GetY(), m_ActionContext.GetStripId(), m_ActionContext.GetStateId(), m_BehaviorId); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h index 0e9afe81..85ca5d54 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h @@ -13,12 +13,15 @@ class AMFArrayValue; */ class UpdateStripUiMessage : public BehaviorMessageBase { public: - UpdateStripUiMessage(AMFArrayValue* arguments); - StripUiPosition GetPosition() const { return position; }; - ActionContext GetActionContext() const { return actionContext; }; + UpdateStripUiMessage(const AMFArrayValue* arguments); + + [[nodiscard]] const StripUiPosition& GetPosition() const noexcept { return m_Position; }; + + [[nodiscard]] const ActionContext& GetActionContext() const noexcept { return m_ActionContext; }; + private: - StripUiPosition position; - ActionContext actionContext; + StripUiPosition m_Position; + ActionContext m_ActionContext; }; #endif //!__UPDATESTRIPUIMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 5fee358d..c4d22482 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -63,7 +63,7 @@ void ControlBehaviors::SendBehaviorListToClient(const ControlBehaviorContext& co // TODO This is also supposed to serialize the state of the behaviors in progress but those aren't implemented yet void ControlBehaviors::SendBehaviorBlocksToClient(ControlBehaviorContext& context) { if (!context) return; - BehaviorMessageBase behaviorMsg(context.arguments); + BehaviorMessageBase behaviorMsg{ context.arguments }; context.modelComponent->VerifyBehaviors(); AMFArrayValue behavior; @@ -71,8 +71,8 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ControlBehaviorContext& contex GameMessages::SendUIMessageServerToSingleClient(context.modelOwner, context.modelOwner->GetSystemAddress(), "UpdateBehaviorBlocks", behavior); } -void ControlBehaviors::UpdateAction(AMFArrayValue* arguments) { - UpdateActionMessage updateActionMessage(arguments); +void ControlBehaviors::UpdateAction(const AMFArrayValue* arguments) { + UpdateActionMessage updateActionMessage{ arguments }; auto blockDefinition = GetBlockInfo(updateActionMessage.GetAction().GetType()); if (!blockDefinition) { @@ -95,18 +95,18 @@ void ControlBehaviors::UpdateAction(AMFArrayValue* arguments) { } } -void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner) { +void ControlBehaviors::ProcessCommand(Entity* modelEntity, AMFArrayValue* arguments, std::string& command, Entity* modelOwner) { if (!isInitialized || !modelEntity || !modelOwner || !arguments) return; - auto* modelComponent = modelEntity->GetComponent(); + auto* const modelComponent = modelEntity->GetComponent(); if (!modelComponent) return; - ControlBehaviorContext context(arguments, modelComponent, modelOwner); + ControlBehaviorContext context{ arguments, modelComponent, modelOwner }; if (command == "sendBehaviorListToClient") { SendBehaviorListToClient(context); } else if (command == "modelTypeChanged") { - auto* modelType = arguments->Get("ModelType"); + auto* const modelType = arguments->Get("ModelType"); if (!modelType) return; modelEntity->SetVar(u"modelType", modelType->GetValue()); @@ -131,7 +131,7 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "rearrangeStrip") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "add") { - AddMessage msg(context.arguments); + AddMessage msg{ context.arguments }; context.modelComponent->AddBehavior(msg); SendBehaviorListToClient(context); } else if (command == "removeActions") { @@ -144,7 +144,7 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "sendBehaviorBlocksToClient") { SendBehaviorBlocksToClient(context); } else if (command == "moveToInventory") { - MoveToInventoryMessage msg(arguments); + MoveToInventoryMessage msg{ arguments }; context.modelComponent->MoveToInventory(msg); auto* characterComponent = modelOwner->GetComponent(); if (!characterComponent) return; @@ -239,7 +239,7 @@ ControlBehaviors::ControlBehaviors() { if (values) { auto* value = values->FirstChildElement("Value"); while (value) { - if (value->GetText() == blockDefinition.GetDefaultValue()) blockDefinition.GetDefaultValue() = std::to_string(blockDefinition.GetMaximumValue()); + if (value->GetText() == blockDefinition.GetDefaultValue()) blockDefinition.SetDefaultValue(std::to_string(blockDefinition.GetMaximumValue())); blockDefinition.SetMaximumValue(blockDefinition.GetMaximumValue() + 1); value = value->NextSiblingElement("Value"); } @@ -283,7 +283,7 @@ ControlBehaviors::ControlBehaviors() { } } -std::optional ControlBehaviors::GetBlockInfo(const BlockName& blockName) { +std::optional ControlBehaviors::GetBlockInfo(const std::string& blockName) { auto blockDefinition = blockTypes.find(blockName); return blockDefinition != blockTypes.end() ? std::optional(blockDefinition->second) : std::nullopt; } diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index ab739408..4eab5367 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -19,15 +19,17 @@ class SystemAddress; typedef std::string BlockName; //! A block name struct ControlBehaviorContext { - ControlBehaviorContext(AMFArrayValue* args, ModelComponent* modelComponent, Entity* modelOwner) : arguments(args), modelComponent(modelComponent), modelOwner(modelOwner) {}; + ControlBehaviorContext(AMFArrayValue* args, ModelComponent* modelComponent, Entity* modelOwner) noexcept + : arguments{ args }, modelComponent{ modelComponent }, modelOwner{ modelOwner } { + }; operator bool() const { return arguments != nullptr && modelComponent != nullptr && modelOwner != nullptr; } AMFArrayValue* arguments; - Entity* modelOwner; ModelComponent* modelComponent; + Entity* modelOwner; }; class ControlBehaviors: public Singleton { @@ -37,12 +39,11 @@ public: * @brief Main driver for processing Property Behavior commands * * @param modelEntity The model that sent this command - * @param sysAddr The SystemAddress to respond to * @param arguments The arguments formatted as an AMFArrayValue * @param command The command to perform * @param modelOwner The owner of the model which sent this command */ - void ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner); + void ProcessCommand(Entity* modelEntity, AMFArrayValue* arguments, std::string& command, Entity* modelOwner); /** * @brief Gets a blocks parameter values by the name @@ -52,13 +53,13 @@ public: * * @return A pair of the block parameter name to its typing */ - std::optional GetBlockInfo(const BlockName& blockName); + [[nodiscard]] std::optional GetBlockInfo(const std::string& blockName); private: void RequestUpdatedID(ControlBehaviorContext& context); void SendBehaviorListToClient(const ControlBehaviorContext& context); void SendBehaviorBlocksToClient(ControlBehaviorContext& context); - void UpdateAction(AMFArrayValue* arguments); - std::map blockTypes{}; + void UpdateAction(const AMFArrayValue* arguments); + std::map> blockTypes{}; // If false, property behaviors will not be able to be edited. bool isInitialized = false; diff --git a/dGame/dPropertyBehaviors/PropertyBehavior.cpp b/dGame/dPropertyBehaviors/PropertyBehavior.cpp index f6f6e4f1..423751c4 100644 --- a/dGame/dPropertyBehaviors/PropertyBehavior.cpp +++ b/dGame/dPropertyBehaviors/PropertyBehavior.cpp @@ -83,10 +83,6 @@ void PropertyBehavior::HandleMsg(AddMessage& msg) { isLoot = m_BehaviorId != 7965; }; -void PropertyBehavior::SetBehaviorId(int32_t behaviorId) { - m_BehaviorId = behaviorId; -} - void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) const { args.Insert("id", std::to_string(m_BehaviorId)); args.Insert("name", m_Name); @@ -111,19 +107,18 @@ void PropertyBehavior::VerifyLastEditedState() { } void PropertyBehavior::SendBehaviorBlocksToClient(AMFArrayValue& args) const { - auto* stateArray = args.InsertArray("states"); + auto* const stateArray = args.InsertArray("states"); - auto lastState = BehaviorState::HOME_STATE; - for (auto& [stateId, state] : m_States) { + for (const auto& [stateId, state] : m_States) { if (state.IsEmpty()) continue; LOG_DEBUG("Serializing state %i", stateId); - auto* stateArgs = stateArray->PushArray(); + auto* const stateArgs = stateArray->PushArray(); stateArgs->Insert("id", static_cast(stateId)); state.SendBehaviorBlocksToClient(*stateArgs); } - auto* executionState = args.InsertArray("executionState"); + auto* const executionState = args.InsertArray("executionState"); executionState->Insert("stateID", static_cast(m_LastEditedState)); executionState->InsertArray("strips"); diff --git a/dGame/dPropertyBehaviors/PropertyBehavior.h b/dGame/dPropertyBehaviors/PropertyBehavior.h index dc53bbed..c9cb4b98 100644 --- a/dGame/dPropertyBehaviors/PropertyBehavior.h +++ b/dGame/dPropertyBehaviors/PropertyBehavior.h @@ -13,7 +13,8 @@ class AMFArrayValue; class PropertyBehavior { public: PropertyBehavior(); - template + + template void HandleMsg(Msg& msg); // If the last edited state has no strips, this method will set the last edited state to the first state that has strips. @@ -21,8 +22,9 @@ public: void SendBehaviorListToClient(AMFArrayValue& args) const; void SendBehaviorBlocksToClient(AMFArrayValue& args) const; - int32_t GetBehaviorId() const { return m_BehaviorId; } - void SetBehaviorId(int32_t id); + [[nodiscard]] int32_t GetBehaviorId() const noexcept { return m_BehaviorId; } + void SetBehaviorId(int32_t id) noexcept { m_BehaviorId = id; } + private: // The states this behavior has. diff --git a/dGame/dPropertyBehaviors/State.cpp b/dGame/dPropertyBehaviors/State.cpp index 59a9aa8b..0c8a11d9 100644 --- a/dGame/dPropertyBehaviors/State.cpp +++ b/dGame/dPropertyBehaviors/State.cpp @@ -3,7 +3,7 @@ #include "Amf3.h" #include "ControlBehaviorMsgs.h" -template<> +template <> void State::HandleMsg(AddStripMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { m_Strips.resize(msg.GetActionContext().GetStripId() + 1); @@ -11,7 +11,7 @@ void State::HandleMsg(AddStripMessage& msg) { m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; -template<> +template <> void State::HandleMsg(AddActionMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { return; @@ -20,7 +20,7 @@ void State::HandleMsg(AddActionMessage& msg) { m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; -template<> +template <> void State::HandleMsg(UpdateStripUiMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { return; @@ -29,7 +29,7 @@ void State::HandleMsg(UpdateStripUiMessage& msg) { m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; -template<> +template <> void State::HandleMsg(RemoveActionsMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { return; @@ -38,7 +38,7 @@ void State::HandleMsg(RemoveActionsMessage& msg) { m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; -template<> +template <> void State::HandleMsg(RearrangeStripMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { return; @@ -47,7 +47,7 @@ void State::HandleMsg(RearrangeStripMessage& msg) { m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; -template<> +template <> void State::HandleMsg(UpdateActionMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { return; @@ -56,7 +56,7 @@ void State::HandleMsg(UpdateActionMessage& msg) { m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; -template<> +template <> void State::HandleMsg(RemoveStripMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { return; @@ -65,7 +65,7 @@ void State::HandleMsg(RemoveStripMessage& msg) { m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; -template<> +template <> void State::HandleMsg(SplitStripMessage& msg) { if (msg.GetTransferredActions().empty()) { if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { @@ -82,7 +82,7 @@ void State::HandleMsg(SplitStripMessage& msg) { } }; -template<> +template <> void State::HandleMsg(MergeStripsMessage& msg) { if (msg.GetMigratedActions().empty()) { if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { @@ -99,7 +99,7 @@ void State::HandleMsg(MergeStripsMessage& msg) { } }; -template<> +template <> void State::HandleMsg(MigrateActionsMessage& msg) { if (msg.GetMigratedActions().empty()) { if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { @@ -117,19 +117,19 @@ void State::HandleMsg(MigrateActionsMessage& msg) { }; bool State::IsEmpty() const { - for (auto& strip : m_Strips) { + for (const auto& strip : m_Strips) { if (!strip.IsEmpty()) return false; } return true; } void State::SendBehaviorBlocksToClient(AMFArrayValue& args) const { - auto* strips = args.InsertArray("strips"); - for (int32_t stripId = 0; stripId < m_Strips.size(); stripId++) { - auto& strip = m_Strips.at(stripId); + auto* const strips = args.InsertArray("strips"); + for (size_t stripId = 0; stripId < m_Strips.size(); ++stripId) { + const auto& strip = m_Strips.at(stripId); if (strip.IsEmpty()) continue; - auto* stripArgs = strips->PushArray(); + auto* const stripArgs = strips->PushArray(); stripArgs->Insert("id", static_cast(stripId)); strip.SendBehaviorBlocksToClient(*stripArgs); diff --git a/dGame/dPropertyBehaviors/State.h b/dGame/dPropertyBehaviors/State.h index a6a6d23b..f0425763 100644 --- a/dGame/dPropertyBehaviors/State.h +++ b/dGame/dPropertyBehaviors/State.h @@ -7,11 +7,12 @@ class AMFArrayValue; class State { public: - template + template void HandleMsg(Msg& msg); void SendBehaviorBlocksToClient(AMFArrayValue& args) const; bool IsEmpty() const; + private: std::vector m_Strips; }; diff --git a/dGame/dPropertyBehaviors/Strip.cpp b/dGame/dPropertyBehaviors/Strip.cpp index 7d27cacd..0f459e46 100644 --- a/dGame/dPropertyBehaviors/Strip.cpp +++ b/dGame/dPropertyBehaviors/Strip.cpp @@ -3,48 +3,47 @@ #include "Amf3.h" #include "ControlBehaviorMsgs.h" -template<> +template <> void Strip::HandleMsg(AddStripMessage& msg) { m_Actions = msg.GetActionsToAdd(); m_Position = msg.GetPosition(); }; -template<> +template <> void Strip::HandleMsg(AddActionMessage& msg) { if (msg.GetActionIndex() == -1) return; - m_Actions.insert(m_Actions.begin() + msg.GetActionIndex(), msg.GetAction()); }; -template<> +template <> void Strip::HandleMsg(UpdateStripUiMessage& msg) { m_Position = msg.GetPosition(); }; -template<> +template <> void Strip::HandleMsg(RemoveStripMessage& msg) { m_Actions.clear(); }; -template<> +template <> void Strip::HandleMsg(RemoveActionsMessage& msg) { if (msg.GetActionIndex() >= m_Actions.size()) return; m_Actions.erase(m_Actions.begin() + msg.GetActionIndex(), m_Actions.end()); }; -template<> +template <> void Strip::HandleMsg(UpdateActionMessage& msg) { if (msg.GetActionIndex() >= m_Actions.size()) return; m_Actions.at(msg.GetActionIndex()) = msg.GetAction(); }; -template<> +template <> void Strip::HandleMsg(RearrangeStripMessage& msg) { if (msg.GetDstActionIndex() >= m_Actions.size() || msg.GetSrcActionIndex() >= m_Actions.size() || msg.GetSrcActionIndex() <= msg.GetDstActionIndex()) return; std::rotate(m_Actions.begin() + msg.GetDstActionIndex(), m_Actions.begin() + msg.GetSrcActionIndex(), m_Actions.end()); }; -template<> +template <> void Strip::HandleMsg(SplitStripMessage& msg) { if (msg.GetTransferredActions().empty() && !m_Actions.empty()) { auto startToMove = m_Actions.begin() + msg.GetSrcActionIndex(); @@ -56,7 +55,7 @@ void Strip::HandleMsg(SplitStripMessage& msg) { } }; -template<> +template <> void Strip::HandleMsg(MergeStripsMessage& msg) { if (msg.GetMigratedActions().empty() && !m_Actions.empty()) { msg.SetMigratedActions(m_Actions.begin(), m_Actions.end()); @@ -66,7 +65,7 @@ void Strip::HandleMsg(MergeStripsMessage& msg) { } }; -template<> +template <> void Strip::HandleMsg(MigrateActionsMessage& msg) { if (msg.GetMigratedActions().empty() && !m_Actions.empty()) { auto startToMove = m_Actions.begin() + msg.GetSrcActionIndex(); @@ -80,8 +79,8 @@ void Strip::HandleMsg(MigrateActionsMessage& msg) { void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) const { m_Position.SendBehaviorBlocksToClient(args); - auto* actions = args.InsertArray("actions"); - for (auto& action : m_Actions) { + auto* const actions = args.InsertArray("actions"); + for (const auto& action : m_Actions) { action.SendBehaviorBlocksToClient(*actions); } }; diff --git a/dGame/dPropertyBehaviors/Strip.h b/dGame/dPropertyBehaviors/Strip.h index f3e10964..107fee11 100644 --- a/dGame/dPropertyBehaviors/Strip.h +++ b/dGame/dPropertyBehaviors/Strip.h @@ -10,11 +10,12 @@ class AMFArrayValue; class Strip { public: - template + template void HandleMsg(Msg& msg); void SendBehaviorBlocksToClient(AMFArrayValue& args) const; - bool IsEmpty() const { return m_Actions.empty(); } + bool IsEmpty() const noexcept { return m_Actions.empty(); } + private: std::vector m_Actions; StripUiPosition m_Position; From f38537aece7a63d541ae5d93c1fc43d2269734ad Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 20 Feb 2024 03:51:02 -0800 Subject: [PATCH 02/54] fix: incorrectly inverted statement (#1459) if we DONT find it, we want to kill/delete it. not the other way around where if we find it we try to delete it again. tested that you no longer crash when trying to login tested that bird monument issues are fixed --- dGame/EntityManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dGame/EntityManager.cpp b/dGame/EntityManager.cpp index fc9fa0f0..9cd9df43 100644 --- a/dGame/EntityManager.cpp +++ b/dGame/EntityManager.cpp @@ -575,13 +575,13 @@ void EntityManager::ScheduleForKill(Entity* entity) { const auto objectId = entity->GetObjectID(); - if (std::find(m_EntitiesToKill.begin(), m_EntitiesToKill.end(), objectId) != m_EntitiesToKill.end()) { + if (std::find(m_EntitiesToKill.begin(), m_EntitiesToKill.end(), objectId) == m_EntitiesToKill.end()) { m_EntitiesToKill.push_back(objectId); } } void EntityManager::ScheduleForDeletion(LWOOBJID entity) { - if (std::find(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity) != m_EntitiesToDelete.end()) { + if (std::find(m_EntitiesToDelete.begin(), m_EntitiesToDelete.end(), entity) == m_EntitiesToDelete.end()) { m_EntitiesToDelete.push_back(entity); } } From 5ae8fd8e0e7088dc125819fd47f9184074a2be80 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sat, 24 Feb 2024 04:30:02 -0600 Subject: [PATCH 03/54] chore: Remove anonymous namespace from GeneralUtils.h (#1460) * remove anonymous namespace from GeneralUtils.h * Put helper functions in nested details namespace to hide from hinting * rename implementation functions to use lower case, leading underscore and move definitions to source file --- dCommon/GeneralUtils.cpp | 50 +++++++++++++++++++++++++++++----------- dCommon/GeneralUtils.h | 26 +++++---------------- 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/dCommon/GeneralUtils.cpp b/dCommon/GeneralUtils.cpp index 78cf4f48..3e3e2f9c 100644 --- a/dCommon/GeneralUtils.cpp +++ b/dCommon/GeneralUtils.cpp @@ -294,28 +294,50 @@ std::u16string GeneralUtils::ReadWString(RakNet::BitStream* inStream) { std::vector GeneralUtils::GetSqlFileNamesFromFolder(const std::string& folder) { // Because we dont know how large the initial number before the first _ is we need to make it a map like so. - std::map filenames{}; + std::map filenames{}; for (auto& t : std::filesystem::directory_iterator(folder)) { - auto filename = t.path().filename().string(); - auto index = std::stoi(GeneralUtils::SplitString(filename, '_').at(0)); - filenames.insert(std::make_pair(index, filename)); + auto filename = t.path().filename().string(); + auto index = std::stoi(GeneralUtils::SplitString(filename, '_').at(0)); + filenames.insert(std::make_pair(index, filename)); } // Now sort the map by the oldest migration. std::vector sortedFiles{}; - auto fileIterator = filenames.begin(); - std::map::iterator oldest = filenames.begin(); - while (!filenames.empty()) { + auto fileIterator = filenames.begin(); + std::map::iterator oldest = filenames.begin(); + while (!filenames.empty()) { if (fileIterator == filenames.end()) { - sortedFiles.push_back(oldest->second); - filenames.erase(oldest); - fileIterator = filenames.begin(); - oldest = filenames.begin(); - continue; + sortedFiles.push_back(oldest->second); + filenames.erase(oldest); + fileIterator = filenames.begin(); + oldest = filenames.begin(); + continue; } - if (oldest->first > fileIterator->first) oldest = fileIterator; - fileIterator++; + if (oldest->first > fileIterator->first) oldest = fileIterator; + fileIterator++; } return sortedFiles; } + +#ifdef DARKFLAME_PLATFORM_MACOS + +// MacOS floating-point parse function specializations +namespace GeneralUtils::details { + template <> + [[nodiscard]] float _parse(const std::string_view str, size_t& parseNum) { + return std::stof(std::string{ str }, &parseNum); + } + + template <> + [[nodiscard]] double _parse(const std::string_view str, size_t& parseNum) { + return std::stod(std::string{ str }, &parseNum); + } + + template <> + [[nodiscard]] long double _parse(const std::string_view str, size_t& parseNum) { + return std::stold(std::string{ str }, &parseNum); + } +} + +#endif diff --git a/dCommon/GeneralUtils.h b/dCommon/GeneralUtils.h index 15659912..42d84aea 100644 --- a/dCommon/GeneralUtils.h +++ b/dCommon/GeneralUtils.h @@ -168,25 +168,10 @@ namespace GeneralUtils { #ifdef DARKFLAME_PLATFORM_MACOS - // Anonymous namespace containing MacOS floating-point parse function specializations - namespace { + // MacOS floating-point parse helper function specializations + namespace details { template - [[nodiscard]] T Parse(const std::string_view str, size_t* parseNum); - - template <> - [[nodiscard]] float Parse(const std::string_view str, size_t* parseNum) { - return std::stof(std::string{ str }, parseNum); - } - - template <> - [[nodiscard]] double Parse(const std::string_view str, size_t* parseNum) { - return std::stod(std::string{ str }, parseNum); - } - - template <> - [[nodiscard]] long double Parse(const std::string_view str, size_t* parseNum) { - return std::stold(std::string{ str }, parseNum); - } + [[nodiscard]] T _parse(const std::string_view str, size_t& parseNum); } /** @@ -196,9 +181,10 @@ namespace GeneralUtils { * @returns An std::optional containing the desired value if it is equivalent to the string */ template - [[nodiscard]] std::optional TryParse(const std::string_view str) noexcept try { + [[nodiscard]] std::optional TryParse(const std::string_view str) noexcept + try { size_t parseNum; - const T result = Parse(str, &parseNum); + const T result = details::_parse(str, parseNum); const bool isParsed = str.length() == parseNum; return isParsed ? result : std::optional{}; From 721ea78bb47d11551b82c14630c1c4a2e41da618 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sat, 24 Feb 2024 23:03:59 -0600 Subject: [PATCH 04/54] Update Amf3.h member naming scheme (#1463) --- dCommon/Amf3.h | 100 ++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 51 deletions(-) diff --git a/dCommon/Amf3.h b/dCommon/Amf3.h index c3077370..294a5b6c 100644 --- a/dCommon/Amf3.h +++ b/dCommon/Amf3.h @@ -41,12 +41,13 @@ template class AMFValue : public AMFBaseValue { public: AMFValue() = default; - AMFValue(const ValueType value) { m_Data = value; } + AMFValue(const ValueType value) : m_Data{ value } {} virtual ~AMFValue() override = default; [[nodiscard]] constexpr eAmf GetValueType() const noexcept override; [[nodiscard]] const ValueType& GetValue() const { return m_Data; } + void SetValue(const ValueType value) { m_Data = value; } protected: @@ -54,7 +55,7 @@ protected: }; // Explicit template class instantiations -template class AMFValue; +template class AMFValue; template class AMFValue; template class AMFValue; template class AMFValue; @@ -110,7 +111,7 @@ public: [[nodiscard]] constexpr eAmf GetValueType() const noexcept override { return eAmf::Array; } ~AMFArrayValue() override { - for (auto valueToDelete : GetDense()) { + for (const auto* valueToDelete : GetDense()) { if (valueToDelete) { delete valueToDelete; valueToDelete = nullptr; @@ -127,12 +128,12 @@ public: /** * Returns the Associative portion of the object */ - [[nodiscard]] inline const AMFAssociative& GetAssociative() const noexcept { return this->associative; } + [[nodiscard]] inline const AMFAssociative& GetAssociative() const noexcept { return m_Associative; } /** * Returns the dense portion of the object */ - [[nodiscard]] inline const AMFDense& GetDense() const noexcept { return this->dense; } + [[nodiscard]] inline const AMFDense& GetDense() const noexcept { return m_Dense; } /** * Inserts an AMFValue into the associative portion with the given key. @@ -150,12 +151,12 @@ public: */ template [[maybe_unused]] std::pair*, bool> Insert(const std::string& key, const ValueType value) { - auto element = associative.find(key); + const auto element = m_Associative.find(key); AMFValue* val = nullptr; bool found = true; - if (element == associative.end()) { + if (element == m_Associative.cend()) { val = new AMFValue(value); - associative.insert(std::make_pair(key, val)); + m_Associative.emplace(key, val); } else { val = dynamic_cast*>(element->second); found = false; @@ -165,12 +166,12 @@ public: // Associates an array with a string key [[maybe_unused]] std::pair Insert(const std::string& key) { - auto element = associative.find(key); + const auto element = m_Associative.find(key); AMFArrayValue* val = nullptr; bool found = true; - if (element == associative.end()) { + if (element == m_Associative.cend()) { val = new AMFArrayValue(); - associative.insert(std::make_pair(key, val)); + m_Associative.emplace(key, val); } else { val = dynamic_cast(element->second); found = false; @@ -182,13 +183,13 @@ public: [[maybe_unused]] std::pair Insert(const size_t index) { AMFArrayValue* val = nullptr; bool inserted = false; - if (index >= dense.size()) { - dense.resize(index + 1); + if (index >= m_Dense.size()) { + m_Dense.resize(index + 1); val = new AMFArrayValue(); - dense.at(index) = val; + m_Dense.at(index) = val; inserted = true; } - return std::make_pair(dynamic_cast(dense.at(index)), inserted); + return std::make_pair(dynamic_cast(m_Dense.at(index)), inserted); } /** @@ -205,13 +206,13 @@ public: [[maybe_unused]] std::pair*, bool> Insert(const size_t index, const ValueType value) { AMFValue* val = nullptr; bool inserted = false; - if (index >= this->dense.size()) { - this->dense.resize(index + 1); + if (index >= m_Dense.size()) { + m_Dense.resize(index + 1); val = new AMFValue(value); - this->dense.at(index) = val; + m_Dense.at(index) = val; inserted = true; } - return std::make_pair(dynamic_cast*>(this->dense.at(index)), inserted); + return std::make_pair(dynamic_cast*>(m_Dense.at(index)), inserted); } /** @@ -224,12 +225,12 @@ public: * @param value The value to insert */ void Insert(const std::string& key, AMFBaseValue* const value) { - auto element = associative.find(key); - if (element != associative.end() && element->second) { + const auto element = m_Associative.find(key); + if (element != m_Associative.cend() && element->second) { delete element->second; element->second = value; } else { - associative.insert(std::make_pair(key, value)); + m_Associative.emplace(key, value); } } @@ -243,13 +244,13 @@ public: * @param value The value to insert */ void Insert(const size_t index, AMFBaseValue* const value) { - if (index < dense.size()) { - AMFDense::iterator itr = dense.begin() + index; - if (*itr) delete dense.at(index); + if (index < m_Dense.size()) { + const AMFDense::const_iterator itr = m_Dense.cbegin() + index; + if (*itr) delete m_Dense.at(index); } else { - dense.resize(index + 1); + m_Dense.resize(index + 1); } - dense.at(index) = value; + m_Dense.at(index) = value; } /** @@ -264,7 +265,7 @@ public: */ template [[maybe_unused]] inline AMFValue* Push(const ValueType value) { - return Insert(this->dense.size(), value).first; + return Insert(m_Dense.size(), value).first; } /** @@ -275,10 +276,10 @@ public: * @param key The key to remove from the associative portion */ void Remove(const std::string& key, const bool deleteValue = true) { - AMFAssociative::iterator it = this->associative.find(key); - if (it != this->associative.end()) { + const AMFAssociative::const_iterator it = m_Associative.find(key); + if (it != m_Associative.cend()) { if (deleteValue) delete it->second; - this->associative.erase(it); + m_Associative.erase(it); } } @@ -286,27 +287,24 @@ public: * Pops the last element in the dense portion, deleting it in the process. */ void Remove(const size_t index) { - if (!this->dense.empty() && index < this->dense.size()) { - auto itr = this->dense.begin() + index; + if (!m_Dense.empty() && index < m_Dense.size()) { + const auto itr = m_Dense.cbegin() + index; if (*itr) delete (*itr); - this->dense.erase(itr); + m_Dense.erase(itr); } } void Pop() { - if (!this->dense.empty()) Remove(this->dense.size() - 1); + if (!m_Dense.empty()) Remove(m_Dense.size() - 1); } [[nodiscard]] AMFArrayValue* GetArray(const std::string& key) const { - AMFAssociative::const_iterator it = this->associative.find(key); - if (it != this->associative.end()) { - return dynamic_cast(it->second); - } - return nullptr; + const AMFAssociative::const_iterator it = m_Associative.find(key); + return it != m_Associative.cend() ? dynamic_cast(it->second) : nullptr; } [[nodiscard]] AMFArrayValue* GetArray(const size_t index) const { - return index >= this->dense.size() ? nullptr : dynamic_cast(this->dense.at(index)); + return index < m_Dense.size() ? dynamic_cast(m_Dense.at(index)) : nullptr; } [[maybe_unused]] inline AMFArrayValue* InsertArray(const std::string& key) { @@ -318,7 +316,7 @@ public: } [[maybe_unused]] inline AMFArrayValue* PushArray() { - return static_cast(Insert(this->dense.size()).first); + return static_cast(Insert(m_Dense.size()).first); } /** @@ -332,16 +330,16 @@ public: */ template [[nodiscard]] AMFValue* Get(const std::string& key) const { - AMFAssociative::const_iterator it = this->associative.find(key); - return it != this->associative.end() ? + const AMFAssociative::const_iterator it = m_Associative.find(key); + return it != m_Associative.cend() ? dynamic_cast*>(it->second) : nullptr; } // Get from the array but dont cast it [[nodiscard]] AMFBaseValue* Get(const std::string& key) const { - AMFAssociative::const_iterator it = this->associative.find(key); - return it != this->associative.end() ? it->second : nullptr; + const AMFAssociative::const_iterator it = m_Associative.find(key); + return it != m_Associative.cend() ? it->second : nullptr; } /** @@ -355,27 +353,27 @@ public: */ template [[nodiscard]] AMFValue* Get(const size_t index) const { - return index < this->dense.size() ? - dynamic_cast*>(this->dense.at(index)) : + return index < m_Dense.size() ? + dynamic_cast*>(m_Dense.at(index)) : nullptr; } // Get from the dense but dont cast it [[nodiscard]] AMFBaseValue* Get(const size_t index) const { - return index < this->dense.size() ? this->dense.at(index) : nullptr; + return index < m_Dense.size() ? m_Dense.at(index) : nullptr; } private: /** * The associative portion. These values are key'd with strings to an AMFValue. */ - AMFAssociative associative; + AMFAssociative m_Associative; /** * The dense portion. These AMFValue's are stored one after * another with the most recent addition being at the back. */ - AMFDense dense; + AMFDense m_Dense; }; #endif //!__AMF3__H__ From 1328850a8d225d969784fb6b59fe282e4e019915 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sat, 24 Feb 2024 23:01:28 -0800 Subject: [PATCH 05/54] buffRemoval (#1464) Update BuffComponent.cpp --- dGame/dComponents/BuffComponent.cpp | 7 +++---- dGame/dComponents/BuffComponent.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/dGame/dComponents/BuffComponent.cpp b/dGame/dComponents/BuffComponent.cpp index cdf1d5bc..4122a800 100644 --- a/dGame/dComponents/BuffComponent.cpp +++ b/dGame/dComponents/BuffComponent.cpp @@ -208,9 +208,8 @@ void BuffComponent::ApplyBuff(const int32_t id, const float duration, const LWOO void BuffComponent::RemoveBuff(int32_t id, bool fromUnEquip, bool removeImmunity, bool ignoreRefCount) { const auto& iter = m_Buffs.find(id); - if (iter == m_Buffs.end()) { - return; - } + // If the buff is already scheduled to be removed, don't do it again + if (iter == m_Buffs.end() || m_BuffsToRemove.contains(id)) return; if (!ignoreRefCount && !iter->second.cancelOnRemoveBuff) { iter->second.refCount--; @@ -222,7 +221,7 @@ void BuffComponent::RemoveBuff(int32_t id, bool fromUnEquip, bool removeImmunity GameMessages::SendRemoveBuff(m_Parent, fromUnEquip, removeImmunity, id); - m_BuffsToRemove.push_back(id); + m_BuffsToRemove.insert(id); RemoveBuffEffect(id); } diff --git a/dGame/dComponents/BuffComponent.h b/dGame/dComponents/BuffComponent.h index 18aa7a42..f509faa2 100644 --- a/dGame/dComponents/BuffComponent.h +++ b/dGame/dComponents/BuffComponent.h @@ -141,7 +141,7 @@ private: std::map m_Buffs; // Buffs to remove at the end of the update frame. - std::vector m_BuffsToRemove; + std::set m_BuffsToRemove; /** * Parameters (=effects) for each buff From e729c7f84659029a0777f409f2f146697797ab81 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sun, 25 Feb 2024 01:47:05 -0600 Subject: [PATCH 06/54] feat: achievement vendor and vendor feedback (#1461) * Groundwork * movie buying logic out of gm handler make transaction result more useful * Full implementation Cleanup and fix some calls in gamemessages * Load the component in the entity Patch Auth * new line at eof * cache lookups * remove sort * fix includes --- dCommon/dEnums/eReplicaComponentType.h | 2 +- dCommon/dEnums/eVendorTransactionResult.h | 15 +++ .../CDClientTables/CDMissionsTable.cpp | 10 +- .../CDClientTables/CDMissionsTable.h | 3 + dGame/Entity.cpp | 8 ++ .../AchievementVendorComponent.cpp | 72 +++++++++++ .../dComponents/AchievementVendorComponent.h | 23 ++++ dGame/dComponents/CMakeLists.txt | 1 + dGame/dComponents/VendorComponent.cpp | 62 +++++++++ dGame/dComponents/VendorComponent.h | 1 + dGame/dGameMessages/GameMessages.cpp | 121 ++++-------------- dGame/dGameMessages/GameMessages.h | 3 +- dNet/AuthPackets.cpp | 2 +- 13 files changed, 226 insertions(+), 97 deletions(-) create mode 100644 dCommon/dEnums/eVendorTransactionResult.h create mode 100644 dGame/dComponents/AchievementVendorComponent.cpp create mode 100644 dGame/dComponents/AchievementVendorComponent.h diff --git a/dCommon/dEnums/eReplicaComponentType.h b/dCommon/dEnums/eReplicaComponentType.h index 83acbf89..2b991dfb 100644 --- a/dCommon/dEnums/eReplicaComponentType.h +++ b/dCommon/dEnums/eReplicaComponentType.h @@ -106,7 +106,7 @@ enum class eReplicaComponentType : uint32_t { INTERACTION_MANAGER, DONATION_VENDOR, COMBAT_MEDIATOR, - COMMENDATION_VENDOR, + ACHIEVEMENT_VENDOR, GATE_RUSH_CONTROL, RAIL_ACTIVATOR, ROLLER, diff --git a/dCommon/dEnums/eVendorTransactionResult.h b/dCommon/dEnums/eVendorTransactionResult.h new file mode 100644 index 00000000..e61ee0ee --- /dev/null +++ b/dCommon/dEnums/eVendorTransactionResult.h @@ -0,0 +1,15 @@ +#ifndef __EVENDORTRANSACTIONRESULT__ +#define __EVENDORTRANSACTIONRESULT__ + +#include + +enum class eVendorTransactionResult : uint32_t { + SELL_SUCCESS = 0, + SELL_FAIL, + PURCHASE_SUCCESS, + PURCHASE_FAIL, + DONATION_FAIL, + DONATION_FULL +}; + +#endif // !__EVENDORTRANSACTIONRESULT__ diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDMissionsTable.cpp b/dDatabase/CDClientDatabase/CDClientTables/CDMissionsTable.cpp index 8862b1db..97dcde9f 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CDMissionsTable.cpp +++ b/dDatabase/CDClientDatabase/CDClientTables/CDMissionsTable.cpp @@ -79,7 +79,6 @@ void CDMissionsTable::LoadValuesFromDatabase() { entries.push_back(entry); tableData.nextRow(); } - tableData.finalize(); Default.id = -1; @@ -118,3 +117,12 @@ const CDMissions& CDMissionsTable::GetByMissionID(uint32_t missionID, bool& foun return Default; } +const std::set CDMissionsTable::GetMissionsForReward(LOT lot) { + std::set toReturn {}; + for (const auto& entry : GetEntries()) { + if (lot == entry.reward_item1 || lot == entry.reward_item2 || lot == entry.reward_item3 || lot == entry.reward_item4) { + toReturn.insert(entry.id); + } + } + return toReturn; +} diff --git a/dDatabase/CDClientDatabase/CDClientTables/CDMissionsTable.h b/dDatabase/CDClientDatabase/CDClientTables/CDMissionsTable.h index 6ba7b19e..5067f2e2 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CDMissionsTable.h +++ b/dDatabase/CDClientDatabase/CDClientTables/CDMissionsTable.h @@ -70,6 +70,9 @@ public: const CDMissions& GetByMissionID(uint32_t missionID, bool& found) const; + const std::set GetMissionsForReward(LOT lot); + + static CDMissions Default; }; diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index 269b4cc4..bb932991 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -82,6 +82,7 @@ #include "CollectibleComponent.h" #include "ItemComponent.h" #include "GhostComponent.h" +#include "AchievementVendorComponent.h" // Table includes #include "CDComponentsRegistryTable.h" @@ -615,6 +616,8 @@ void Entity::Initialize() { AddComponent(); } else if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::DONATION_VENDOR, -1) != -1)) { AddComponent(); + } else if ((compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::ACHIEVEMENT_VENDOR, -1) != -1)) { + AddComponent(); } if (compRegistryTable->GetByIDAndType(m_TemplateID, eReplicaComponentType::PROPERTY_VENDOR, -1) != -1) { @@ -1191,6 +1194,11 @@ void Entity::WriteComponents(RakNet::BitStream* outBitStream, eReplicaPacketType donationVendorComponent->Serialize(outBitStream, bIsInitialUpdate); } + AchievementVendorComponent* achievementVendorComponent; + if (TryGetComponent(eReplicaComponentType::ACHIEVEMENT_VENDOR, achievementVendorComponent)) { + achievementVendorComponent->Serialize(outBitStream, bIsInitialUpdate); + } + BouncerComponent* bouncerComponent; if (TryGetComponent(eReplicaComponentType::BOUNCER, bouncerComponent)) { bouncerComponent->Serialize(outBitStream, bIsInitialUpdate); diff --git a/dGame/dComponents/AchievementVendorComponent.cpp b/dGame/dComponents/AchievementVendorComponent.cpp new file mode 100644 index 00000000..10a0ca29 --- /dev/null +++ b/dGame/dComponents/AchievementVendorComponent.cpp @@ -0,0 +1,72 @@ +#include "AchievementVendorComponent.h" +#include "MissionComponent.h" +#include "InventoryComponent.h" +#include "eMissionState.h" +#include "CDComponentsRegistryTable.h" +#include "CDItemComponentTable.h" +#include "eVendorTransactionResult.h" +#include "CheatDetection.h" +#include "UserManager.h" +#include "CDMissionsTable.h" + +bool AchievementVendorComponent::SellsItem(Entity* buyer, const LOT lot) { + auto* missionComponent = buyer->GetComponent(); + if (!missionComponent) return false; + + if (m_PlayerPurchasableItems[buyer->GetObjectID()].contains(lot)){ + return true; + } + + CDMissionsTable* missionsTable = CDClientManager::GetTable(); + const auto missions = missionsTable->GetMissionsForReward(lot); + for (const auto mission : missions) { + if (missionComponent->GetMissionState(mission) == eMissionState::COMPLETE) { + m_PlayerPurchasableItems[buyer->GetObjectID()].insert(lot); + return true; + } + } + return false; +} + +void AchievementVendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) { + // get the item Comp from the item LOT + CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable(); + CDItemComponentTable* itemComponentTable = CDClientManager::GetTable(); + int itemCompID = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::ITEM); + CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); + uint32_t costLOT = itemComp.commendationLOT; + + if (costLOT == -1 || !SellsItem(buyer, lot)) { + auto* user = UserManager::Instance()->GetUser(buyer->GetSystemAddress()); + CheatDetection::ReportCheat(user, buyer->GetSystemAddress(), "Attempted to buy item %i from achievement vendor %i that is not purchasable", lot, m_Parent->GetLOT()); + GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL); + return; + } + + auto* inventoryComponent = buyer->GetComponent(); + if (!inventoryComponent) { + GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL); + return; + } + + if (costLOT == 13763) { // Faction Token Proxy + auto* missionComponent = buyer->GetComponent(); + if (!missionComponent) return; + + if (missionComponent->GetMissionState(545) == eMissionState::COMPLETE) costLOT = 8318; // "Assembly Token" + if (missionComponent->GetMissionState(556) == eMissionState::COMPLETE) costLOT = 8321; // "Venture League Token" + if (missionComponent->GetMissionState(567) == eMissionState::COMPLETE) costLOT = 8319; // "Sentinels Token" + if (missionComponent->GetMissionState(578) == eMissionState::COMPLETE) costLOT = 8320; // "Paradox Token" + } + + const uint32_t altCurrencyCost = itemComp.commendationCost * count; + if (inventoryComponent->GetLotCount(costLOT) < altCurrencyCost) { + GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL); + return; + } + + inventoryComponent->RemoveItem(costLOT, altCurrencyCost); + inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR); + GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS); + +} \ No newline at end of file diff --git a/dGame/dComponents/AchievementVendorComponent.h b/dGame/dComponents/AchievementVendorComponent.h new file mode 100644 index 00000000..bffd3983 --- /dev/null +++ b/dGame/dComponents/AchievementVendorComponent.h @@ -0,0 +1,23 @@ +#ifndef __ACHIEVEMENTVENDORCOMPONENT__H__ +#define __ACHIEVEMENTVENDORCOMPONENT__H__ + +#include "VendorComponent.h" +#include "eReplicaComponentType.h" +#include +#include + +class Entity; + +class AchievementVendorComponent final : public VendorComponent { +public: + static constexpr eReplicaComponentType ComponentType = eReplicaComponentType::ACHIEVEMENT_VENDOR; + AchievementVendorComponent(Entity* parent) : VendorComponent(parent) {}; + bool SellsItem(Entity* buyer, const LOT lot); + void Buy(Entity* buyer, LOT lot, uint32_t count); + +private: + std::map> m_PlayerPurchasableItems; +}; + + +#endif //!__ACHIEVEMENTVENDORCOMPONENT__H__ diff --git a/dGame/dComponents/CMakeLists.txt b/dGame/dComponents/CMakeLists.txt index ac509e11..21fe9207 100644 --- a/dGame/dComponents/CMakeLists.txt +++ b/dGame/dComponents/CMakeLists.txt @@ -1,4 +1,5 @@ set(DGAME_DCOMPONENTS_SOURCES + "AchievementVendorComponent.cpp" "ActivityComponent.cpp" "BaseCombatAIComponent.cpp" "BouncerComponent.cpp" diff --git a/dGame/dComponents/VendorComponent.cpp b/dGame/dComponents/VendorComponent.cpp index afa3d013..9e9428f7 100644 --- a/dGame/dComponents/VendorComponent.cpp +++ b/dGame/dComponents/VendorComponent.cpp @@ -8,6 +8,11 @@ #include "CDLootMatrixTable.h" #include "CDLootTableTable.h" #include "CDItemComponentTable.h" +#include "InventoryComponent.h" +#include "Character.h" +#include "eVendorTransactionResult.h" +#include "UserManager.h" +#include "CheatDetection.h" VendorComponent::VendorComponent(Entity* parent) : Component(parent) { m_HasStandardCostItems = false; @@ -151,3 +156,60 @@ void VendorComponent::HandleMrReeCameras(){ m_Inventory.push_back(SoldItem(camera, 0)); } } + + +void VendorComponent::Buy(Entity* buyer, LOT lot, uint32_t count) { + + if (!SellsItem(lot)) { + auto* user = UserManager::Instance()->GetUser(buyer->GetSystemAddress()); + CheatDetection::ReportCheat(user, buyer->GetSystemAddress(), "Attempted to buy item %i from achievement vendor %i that is not purchasable", lot, m_Parent->GetLOT()); + GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL); + return; + } + + auto* inventoryComponent = buyer->GetComponent(); + if (!inventoryComponent) { + GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL); + return; + } + CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable(); + CDItemComponentTable* itemComponentTable = CDClientManager::GetTable(); + int itemCompID = compRegistryTable->GetByIDAndType(lot, eReplicaComponentType::ITEM); + CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); + + // Extra currency that needs to be deducted in case of crafting + auto craftingCurrencies = CDItemComponentTable::ParseCraftingCurrencies(itemComp); + for (const auto& [crafintCurrencyLOT, crafintCurrencyCount]: craftingCurrencies) { + if (inventoryComponent->GetLotCount(crafintCurrencyLOT) < (crafintCurrencyCount * count)) { + GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL); + return; + } + } + for (const auto& [crafintCurrencyLOT, crafintCurrencyCount]: craftingCurrencies) { + inventoryComponent->RemoveItem(crafintCurrencyLOT, crafintCurrencyCount * count); + } + + + float buyScalar = GetBuyScalar(); + const auto coinCost = static_cast(std::floor((itemComp.baseValue * buyScalar) * count)); + + Character* character = buyer->GetCharacter(); + if (!character || character->GetCoins() < coinCost) { + GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL); + return; + } + + if (Inventory::IsValidItem(itemComp.currencyLOT)) { + const uint32_t altCurrencyCost = std::floor(itemComp.altCurrencyCost * buyScalar) * count; + if (inventoryComponent->GetLotCount(itemComp.currencyLOT) < altCurrencyCost) { + GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_FAIL); + return; + } + inventoryComponent->RemoveItem(itemComp.currencyLOT, altCurrencyCost); + } + + character->SetCoins(character->GetCoins() - (coinCost), eLootSourceType::VENDOR); + inventoryComponent->AddItem(lot, count, eLootSourceType::VENDOR); + GameMessages::SendVendorTransactionResult(buyer, buyer->GetSystemAddress(), eVendorTransactionResult::PURCHASE_SUCCESS); + +} \ No newline at end of file diff --git a/dGame/dComponents/VendorComponent.h b/dGame/dComponents/VendorComponent.h index 48b766d2..9025148b 100644 --- a/dGame/dComponents/VendorComponent.h +++ b/dGame/dComponents/VendorComponent.h @@ -47,6 +47,7 @@ public: m_DirtyVendor = true; } + void Buy(Entity* buyer, LOT lot, uint32_t count); private: void SetupMaxCustomVendor(); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index c38ef880..a62bf382 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -78,6 +78,7 @@ #include "LevelProgressionComponent.h" #include "DonationVendorComponent.h" #include "GhostComponent.h" +#include "AchievementVendorComponent.h" // Message includes: #include "dZoneManager.h" @@ -97,6 +98,7 @@ #include "ePetAbilityType.h" #include "ActivityManager.h" #include "PlayerManager.h" +#include "eVendorTransactionResult.h" #include "CDComponentsRegistryTable.h" #include "CDObjectsTable.h" @@ -1323,15 +1325,14 @@ void GameMessages::SendVendorStatusUpdate(Entity* entity, const SystemAddress& s SEND_PACKET; } -void GameMessages::SendVendorTransactionResult(Entity* entity, const SystemAddress& sysAddr) { +void GameMessages::SendVendorTransactionResult(Entity* entity, const SystemAddress& sysAddr, eVendorTransactionResult result) { CBITSTREAM; CMSGHEADER; - int iResult = 0x02; // success, seems to be the only relevant one bitStream.Write(entity->GetObjectID()); bitStream.Write(eGameMessageType::VENDOR_TRANSACTION_RESULT); - bitStream.Write(iResult); + bitStream.Write(result); SEND_PACKET; } @@ -4664,94 +4665,27 @@ void GameMessages::HandleBuyFromVendor(RakNet::BitStream* inStream, Entity* enti if (!user) return; Entity* player = Game::entityManager->GetEntity(user->GetLoggedInChar()); if (!player) return; + + // handle buying normal items + auto* vendorComponent = entity->GetComponent(); + if (vendorComponent) { + vendorComponent->Buy(player, item, count); + return; + } - auto* propertyVendorComponent = static_cast(entity->GetComponent(eReplicaComponentType::PROPERTY_VENDOR)); + // handle buying achievement items + auto* achievementVendorComponent = entity->GetComponent(); + if (achievementVendorComponent) { + achievementVendorComponent->Buy(player, item, count); + return; + } - if (propertyVendorComponent != nullptr) { + // Handle buying properties + auto* propertyVendorComponent = entity->GetComponent(); + if (propertyVendorComponent) { propertyVendorComponent->OnBuyFromVendor(player, bConfirmed, item, count); - return; } - - const auto isCommendationVendor = entity->GetLOT() == 13806; - - auto* vend = entity->GetComponent(); - if (!vend && !isCommendationVendor) return; - - auto* inv = player->GetComponent(); - if (!inv) return; - - if (!isCommendationVendor && !vend->SellsItem(item)) { - LOG("User %llu %s tried to buy an item %i from a vendor when they do not sell said item", player->GetObjectID(), user->GetUsername().c_str(), item); - return; - } - - CDComponentsRegistryTable* compRegistryTable = CDClientManager::GetTable(); - CDItemComponentTable* itemComponentTable = CDClientManager::GetTable(); - - int itemCompID = compRegistryTable->GetByIDAndType(item, eReplicaComponentType::ITEM); - CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); - - Character* character = player->GetCharacter(); - if (!character) return; - - // Extra currency that needs to be deducted in case of crafting - auto craftingCurrencies = CDItemComponentTable::ParseCraftingCurrencies(itemComp); - for (const auto& craftingCurrency : craftingCurrencies) { - inv->RemoveItem(craftingCurrency.first, craftingCurrency.second * count); - } - - if (isCommendationVendor) { - if (itemComp.commendationLOT != 13763) { - return; - } - - auto* missionComponent = player->GetComponent(); - - if (missionComponent == nullptr) { - return; - } - - LOT tokenId = -1; - - if (missionComponent->GetMissionState(545) == eMissionState::COMPLETE) tokenId = 8318; // "Assembly Token" - if (missionComponent->GetMissionState(556) == eMissionState::COMPLETE) tokenId = 8321; // "Venture League Token" - if (missionComponent->GetMissionState(567) == eMissionState::COMPLETE) tokenId = 8319; // "Sentinels Token" - if (missionComponent->GetMissionState(578) == eMissionState::COMPLETE) tokenId = 8320; // "Paradox Token" - - const uint32_t altCurrencyCost = itemComp.commendationCost * count; - - if (inv->GetLotCount(tokenId) < altCurrencyCost) { - return; - } - - inv->RemoveItem(tokenId, altCurrencyCost); - - inv->AddItem(item, count, eLootSourceType::VENDOR); - } else { - float buyScalar = vend->GetBuyScalar(); - - const auto coinCost = static_cast(std::floor((itemComp.baseValue * buyScalar) * count)); - - if (character->GetCoins() < coinCost) { - return; - } - - if (Inventory::IsValidItem(itemComp.currencyLOT)) { - const uint32_t altCurrencyCost = std::floor(itemComp.altCurrencyCost * buyScalar) * count; - - if (inv->GetLotCount(itemComp.currencyLOT) < altCurrencyCost) { - return; - } - - inv->RemoveItem(itemComp.currencyLOT, altCurrencyCost); - } - - character->SetCoins(character->GetCoins() - (coinCost), eLootSourceType::VENDOR); - inv->AddItem(item, count, eLootSourceType::VENDOR); - } - - GameMessages::SendVendorTransactionResult(entity, sysAddr); } void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -4785,7 +4719,10 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit CDItemComponent itemComp = itemComponentTable->GetItemComponentByID(itemCompID); // Items with a base value of 0 or max int are special items that should not be sold if they're not sub items - if (itemComp.baseValue == 0 || itemComp.baseValue == UINT_MAX) return; + if (itemComp.baseValue == 0 || itemComp.baseValue == UINT_MAX) { + GameMessages::SendVendorTransactionResult(entity, sysAddr, eVendorTransactionResult::SELL_FAIL); + return; + } float sellScalar = vend->GetSellScalar(); if (Inventory::IsValidItem(itemComp.currencyLOT)) { @@ -4793,11 +4730,9 @@ void GameMessages::HandleSellToVendor(RakNet::BitStream* inStream, Entity* entit inv->AddItem(itemComp.currencyLOT, std::floor(altCurrency), eLootSourceType::VENDOR); // Return alt currencies like faction tokens. } - //inv->RemoveItem(count, -1, iObjID); inv->MoveItemToInventory(item, eInventoryType::VENDOR_BUYBACK, count, true, false, true); character->SetCoins(std::floor(character->GetCoins() + (static_cast(itemComp.baseValue * sellScalar) * count)), eLootSourceType::VENDOR); - //Game::entityManager->SerializeEntity(player); // so inventory updates - GameMessages::SendVendorTransactionResult(entity, sysAddr); + GameMessages::SendVendorTransactionResult(entity, sysAddr, eVendorTransactionResult::SELL_SUCCESS); } void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { @@ -4839,16 +4774,16 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* const auto cost = static_cast(std::floor(((itemComp.baseValue * sellScalar) * count))); if (character->GetCoins() < cost) { + GameMessages::SendVendorTransactionResult(entity, sysAddr, eVendorTransactionResult::PURCHASE_FAIL); return; } if (Inventory::IsValidItem(itemComp.currencyLOT)) { const uint32_t altCurrencyCost = std::floor(itemComp.altCurrencyCost * sellScalar) * count; - if (inv->GetLotCount(itemComp.currencyLOT) < altCurrencyCost) { + GameMessages::SendVendorTransactionResult(entity, sysAddr, eVendorTransactionResult::PURCHASE_FAIL); return; } - inv->RemoveItem(itemComp.currencyLOT, altCurrencyCost); } @@ -4856,7 +4791,7 @@ void GameMessages::HandleBuybackFromVendor(RakNet::BitStream* inStream, Entity* inv->MoveItemToInventory(item, Inventory::FindInventoryTypeForLot(item->GetLot()), count, true, false); character->SetCoins(character->GetCoins() - cost, eLootSourceType::VENDOR); //Game::entityManager->SerializeEntity(player); // so inventory updates - GameMessages::SendVendorTransactionResult(entity, sysAddr); + GameMessages::SendVendorTransactionResult(entity, sysAddr, eVendorTransactionResult::PURCHASE_SUCCESS); } void GameMessages::HandleParseChatMessage(RakNet::BitStream* inStream, Entity* entity, const SystemAddress& sysAddr) { diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index a96bbf60..9604d261 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -38,6 +38,7 @@ enum class eUseItemResponse : uint32_t; enum class eQuickBuildFailReason : uint32_t; enum class eQuickBuildState : uint32_t; enum class BehaviorSlot : int32_t; +enum class eVendorTransactionResult : uint32_t; namespace GameMessages { class PropertyDataMessage; @@ -135,7 +136,7 @@ namespace GameMessages { void SendVendorOpenWindow(Entity* entity, const SystemAddress& sysAddr); void SendVendorStatusUpdate(Entity* entity, const SystemAddress& sysAddr, bool bUpdateOnly = false); - void SendVendorTransactionResult(Entity* entity, const SystemAddress& sysAddr); + void SendVendorTransactionResult(Entity* entity, const SystemAddress& sysAddr, eVendorTransactionResult result); void SendRemoveItemFromInventory(Entity* entity, const SystemAddress& sysAddr, LWOOBJID iObjID, LOT templateID, int inventoryType, uint32_t stackCount, uint32_t stackRemaining); void SendConsumeClientItem(Entity* entity, bool bSuccess, LWOOBJID item); diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index 25ccc902..54c28299 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -82,7 +82,7 @@ void AuthPackets::SendHandshake(dServer* server, const SystemAddress& sysAddr, c if (serverType == ServerType::Auth) bitStream.Write(ServiceId::Auth); else if (serverType == ServerType::World) bitStream.Write(ServiceId::World); else bitStream.Write(ServiceId::General); - bitStream.Write(774909490); + bitStream.Write(215523405360); server->Send(&bitStream, sysAddr, false); } From cf706d4974199c053addb708525195081d3b711f Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 25 Feb 2024 05:56:01 -0800 Subject: [PATCH 07/54] Remove ag special case patch (#1462) Tested that revision was never the poison value in any lvl file when starting zone 1100. --- dZoneManager/Level.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/dZoneManager/Level.cpp b/dZoneManager/Level.cpp index 9524d908..5f35b629 100644 --- a/dZoneManager/Level.cpp +++ b/dZoneManager/Level.cpp @@ -200,9 +200,6 @@ void Level::ReadFileInfoChunk(std::istream& file, Header& header) { BinaryIO::BinaryRead(file, header.fileInfo.enviromentChunkStart); BinaryIO::BinaryRead(file, header.fileInfo.objectChunkStart); BinaryIO::BinaryRead(file, header.fileInfo.particleChunkStart); - - //PATCH FOR AG: (messed up file?) - if (header.fileInfo.revision == 0xCDCDCDCD && m_ParentZone->GetZoneID().GetMapID() == 1100) header.fileInfo.revision = 26; } void Level::ReadSceneObjectDataChunk(std::istream& file, Header& header) { From 192c8cf974b46b03b5604457274797733a73d330 Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Sun, 25 Feb 2024 16:59:10 -0600 Subject: [PATCH 08/54] feat: refactor vanity (#1477) * feat: refactor vanity cleanup code to be generalized for objects remove unused party feature add fallback to data to text Allow for better organizing data in multiple files remove special case flag values in favor of config data general cleanup and fixes * newline at eof's --- CMakeLists.txt | 2 +- dGame/Entity.cpp | 6 + dGame/Entity.h | 2 + dGame/dUtilities/VanityUtilities.cpp | 559 +++++++----------- dGame/dUtilities/VanityUtilities.h | 43 +- dScripts/02_server/DLU/CMakeLists.txt | 2 +- ...NPC.cpp => DLUVanityTeleportingObject.cpp} | 26 +- ...nityNPC.h => DLUVanityTeleportingObject.h} | 7 +- dScripts/CppScripts.cpp | 6 +- vanity/atm.xml | 23 + vanity/{NPC.xml => dev-tribute.xml} | 345 +++++------ vanity/root.xml | 4 + 12 files changed, 414 insertions(+), 611 deletions(-) rename dScripts/02_server/DLU/{DLUVanityNPC.cpp => DLUVanityTeleportingObject.cpp} (51%) rename dScripts/02_server/DLU/{DLUVanityNPC.h => DLUVanityTeleportingObject.h} (54%) create mode 100644 vanity/atm.xml rename vanity/{NPC.xml => dev-tribute.xml} (65%) create mode 100644 vanity/root.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index e085bfe7..b36bdb29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,7 +179,7 @@ file(ARCHIVE_EXTRACT INPUT ${PROJECT_BINARY_DIR}/navmeshes.zip DESTINATION ${PRO file(REMOVE ${PROJECT_BINARY_DIR}/navmeshes.zip) # Copy vanity files on first build -set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "NPC.xml") +set(VANITY_FILES "CREDITS.md" "INFO.md" "TESTAMENT.md" "root.xml" "dev-tribute.xml" "atm.xml") foreach(file ${VANITY_FILES}) configure_file("${CMAKE_SOURCE_DIR}/vanity/${file}" "${CMAKE_BINARY_DIR}/vanity/${file}" COPYONLY) diff --git a/dGame/Entity.cpp b/dGame/Entity.cpp index bb932991..dd15f69d 100644 --- a/dGame/Entity.cpp +++ b/dGame/Entity.cpp @@ -2197,3 +2197,9 @@ void Entity::SetRespawnRot(const NiQuaternion& rotation) { auto* characterComponent = GetComponent(); if (characterComponent) characterComponent->SetRespawnRot(rotation); } + +void Entity::SetScale(const float scale) { + if (scale == m_Scale) return; + m_Scale = scale; + Game::entityManager->SerializeEntity(this); +} \ No newline at end of file diff --git a/dGame/Entity.h b/dGame/Entity.h index 6546e458..7d5e24c9 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -295,6 +295,8 @@ public: void ProcessPositionUpdate(PositionUpdate& update); + void SetScale(const float scale); + protected: LWOOBJID m_ObjectID; diff --git a/dGame/dUtilities/VanityUtilities.cpp b/dGame/dUtilities/VanityUtilities.cpp index fa1a3eac..3e93f830 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -22,143 +22,13 @@ #include -std::vector VanityUtilities::m_NPCs = {}; -std::vector VanityUtilities::m_Parties = {}; -std::vector VanityUtilities::m_PartyPhrases = {}; +std::vector VanityUtilities::m_Objects = {}; +std::set VanityUtilities::m_LoadedFiles = {}; + void VanityUtilities::SpawnVanity() { - if (Game::config->GetValue("disable_vanity") == "1") { - return; - } - const uint32_t zoneID = Game::server->GetZoneID(); - for (const auto& npc : m_NPCs) { - if (npc.m_ID == LWOOBJID_EMPTY) continue; - if (npc.m_LOT == 176){ - Game::zoneManager->RemoveSpawner(npc.m_ID); - } else{ - auto* entity = Game::entityManager->GetEntity(npc.m_ID); - if (!entity) continue; - entity->Smash(LWOOBJID_EMPTY, eKillType::VIOLENT); - } - } - - m_NPCs.clear(); - m_Parties.clear(); - m_PartyPhrases.clear(); - - ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity/NPC.xml").string()); - - // Loop through all parties - for (const auto& party : m_Parties) { - const auto chance = party.m_Chance; - const auto zone = party.m_Zone; - - if (zone != Game::server->GetZoneID()) { - continue; - } - - float rate = GeneralUtils::GenerateRandomNumber(0, 1); - if (chance < rate) { - continue; - } - - // Copy m_NPCs into a new vector - std::vector npcList = m_NPCs; - std::vector taken = {}; - - LOG("Spawning party with %i locations", party.m_Locations.size()); - - // Loop through all locations - for (const auto& location : party.m_Locations) { - rate = GeneralUtils::GenerateRandomNumber(0, 1); - if (0.75f < rate) { - continue; - } - - // Get a random NPC - auto npcIndex = GeneralUtils::GenerateRandomNumber(0, npcList.size() - 1); - - while (std::find(taken.begin(), taken.end(), npcIndex) != taken.end()) { - npcIndex = GeneralUtils::GenerateRandomNumber(0, npcList.size() - 1); - } - - auto& npc = npcList[npcIndex]; - // Skip spawners - if (npc.m_LOT == 176) continue; - - taken.push_back(npcIndex); - - LOG("ldf size is %i", npc.ldf.size()); - if (npc.ldf.empty()) { - npc.ldf = { - new LDFData>(u"syncLDF", { u"custom_script_client" }), - new LDFData(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") - }; - } - - // Spawn the NPC - if (npc.m_LOT == 176){ - npc.m_ID = SpawnSpawner(npc.m_LOT, location.m_Position, location.m_Rotation, npc.ldf); - } else { - auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf); - if (!npc.m_Phrases.empty()) { - npcEntity->SetVar>(u"chats", m_PartyPhrases); - SetupNPCTalk(npcEntity); - } - } - } - return; - } - - // Loop through all NPCs - for (auto& npc : m_NPCs) { - if (npc.m_Locations.find(Game::server->GetZoneID()) == npc.m_Locations.end()) - continue; - - const std::vector& locations = npc.m_Locations.at(Game::server->GetZoneID()); - - // Pick a random location - const auto& location = locations[GeneralUtils::GenerateRandomNumber( - static_cast(0), static_cast(locations.size() - 1))]; - - float rate = GeneralUtils::GenerateRandomNumber(0, 1); - if (location.m_Chance < rate) { - continue; - } - - if (npc.ldf.empty()) { - npc.ldf = { - new LDFData>(u"syncLDF", { u"custom_script_client" }), - new LDFData(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") - }; - } - if (npc.m_LOT == 176){ - npc.m_ID = SpawnSpawner(npc.m_LOT, location.m_Position, location.m_Rotation, npc.ldf); - } else { - // Spawn the NPC - auto* npcEntity = SpawnNPC(npc.m_LOT, npc.m_Name, location.m_Position, location.m_Rotation, npc.m_Equipment, npc.ldf); - if (!npcEntity) continue; - npc.m_ID = npcEntity->GetObjectID(); - if (!npc.m_Phrases.empty()){ - npcEntity->SetVar>(u"chats", npc.m_Phrases); - - auto* scriptComponent = npcEntity->GetComponent(); - - if (scriptComponent && !npc.m_Script.empty()) { - scriptComponent->SetScript(npc.m_Script); - scriptComponent->SetSerialized(false); - - for (const auto& npc : npc.m_Flags) { - npcEntity->SetVar(GeneralUtils::ASCIIToUTF16(npc.first), npc.second); - } - } - SetupNPCTalk(npcEntity); - } - } - } - if (zoneID == 1200) { { EntityInfo info; @@ -175,38 +45,99 @@ void VanityUtilities::SpawnVanity() { Game::entityManager->ConstructEntity(entity); } } + + if (Game::config->GetValue("disable_vanity") == "1") { + return; + } + + for (const auto& npc : m_Objects) { + if (npc.m_ID == LWOOBJID_EMPTY) continue; + if (npc.m_LOT == 176){ + Game::zoneManager->RemoveSpawner(npc.m_ID); + } else{ + auto* entity = Game::entityManager->GetEntity(npc.m_ID); + if (!entity) continue; + entity->Smash(LWOOBJID_EMPTY, eKillType::VIOLENT); + } + } + + m_Objects.clear(); + m_LoadedFiles.clear(); + + ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity/root.xml").string()); + + // Loop through all objects + for (auto& object : m_Objects) { + if (object.m_Locations.find(Game::server->GetZoneID()) == object.m_Locations.end()) continue; + + const std::vector& locations = object.m_Locations.at(Game::server->GetZoneID()); + + // Pick a random location + const auto& location = locations[GeneralUtils::GenerateRandomNumber( + static_cast(0), static_cast(locations.size() - 1))]; + + float rate = GeneralUtils::GenerateRandomNumber(0, 1); + if (location.m_Chance < rate) continue; + + if (object.m_Config.empty()) { + object.m_Config = { + new LDFData>(u"syncLDF", { u"custom_script_client" }), + new LDFData(u"custom_script_client", u"scripts\\ai\\SPEC\\MISSION_MINIGAME_CLIENT.lua") + }; + } + if (object.m_LOT == 176){ + object.m_ID = SpawnSpawner(object, location); + } else { + // Spawn the NPC + auto* objectEntity = SpawnObject(object, location); + if (!objectEntity) continue; + object.m_ID = objectEntity->GetObjectID(); + if (!object.m_Phrases.empty()){ + objectEntity->SetVar>(u"chats", object.m_Phrases); + + auto* scriptComponent = objectEntity->GetComponent(); + + if (scriptComponent && !object.m_Script.empty()) { + scriptComponent->SetScript(object.m_Script); + scriptComponent->SetSerialized(false); + } + SetupNPCTalk(objectEntity); + } + } + } } -LWOOBJID VanityUtilities::SpawnSpawner(LOT lot, const NiPoint3& position, const NiQuaternion& rotation, const std::vector& ldf){ +LWOOBJID VanityUtilities::SpawnSpawner(const VanityObject& object, const VanityObjectLocation& location) { SceneObject obj; - obj.lot = lot; + obj.lot = object.m_LOT; // guratantee we have no collisions do { obj.id = ObjectIDManager::GenerateObjectID(); } while(Game::zoneManager->GetSpawner(obj.id)); - obj.position = position; - obj.rotation = rotation; - obj.settings = ldf; + obj.position = location.m_Position; + obj.rotation = location.m_Rotation; + obj.settings = object.m_Config; Level::MakeSpawner(obj); return obj.id; } -Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoint3& position, const NiQuaternion& rotation, const std::vector& inventory, const std::vector& ldf) { +Entity* VanityUtilities::SpawnObject(const VanityObject& object, const VanityObjectLocation& location) { EntityInfo info; - info.lot = lot; - info.pos = position; - info.rot = rotation; + info.lot = object.m_LOT; + info.pos = location.m_Position; + info.rot = location.m_Rotation; + info.scale = location.m_Scale; info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID(); - info.settings = ldf; + info.settings = object.m_Config; auto* entity = Game::entityManager->CreateEntity(info); - entity->SetVar(u"npcName", name); + entity->SetVar(u"npcName", object.m_Name); if (entity->GetVar(u"noGhosting")) entity->SetIsGhostingCandidate(false); auto* inventoryComponent = entity->GetComponent(); - if (inventoryComponent && !inventory.empty()) { - inventoryComponent->SetNPCItems(inventory); + if (inventoryComponent && !object.m_Equipment.empty()) { + inventoryComponent->SetNPCItems(object.m_Equipment); } auto* destroyableComponent = entity->GetComponent(); @@ -223,6 +154,11 @@ Entity* VanityUtilities::SpawnNPC(LOT lot, const std::string& name, const NiPoin } void VanityUtilities::ParseXML(const std::string& file) { + if (m_LoadedFiles.contains(file)){ + LOG("Trying to load vanity file %s twice!!!", file.c_str()); + return; + } + m_LoadedFiles.insert(file); // Read the entire file std::ifstream xmlFile(file); std::string xml((std::istreambuf_iterator(xmlFile)), std::istreambuf_iterator()); @@ -231,210 +167,112 @@ void VanityUtilities::ParseXML(const std::string& file) { tinyxml2::XMLDocument doc; doc.Parse(xml.c_str(), xml.size()); - // Read the NPCs - auto* npcs = doc.FirstChildElement("npcs"); - - if (npcs == nullptr) { - LOG("Failed to parse NPCs"); - return; - } - - for (auto* party = npcs->FirstChildElement("party"); party != nullptr; party = party->NextSiblingElement("party")) { - // Get 'zone' as uint32_t and 'chance' as float - uint32_t zone = 0; - float chance = 0.0f; - - if (party->Attribute("zone") != nullptr) { - zone = std::stoul(party->Attribute("zone")); - } - - if (party->Attribute("chance") != nullptr) { - chance = std::stof(party->Attribute("chance")); - } - - VanityParty partyInfo; - partyInfo.m_Zone = zone; - partyInfo.m_Chance = chance; - - auto* locations = party->FirstChildElement("locations"); - - if (locations == nullptr) { - LOG("Failed to parse party locations"); - continue; - } - - for (auto* location = locations->FirstChildElement("location"); location != nullptr; - location = location->NextSiblingElement("location")) { - // Get the location data - auto* x = location->Attribute("x"); - auto* y = location->Attribute("y"); - auto* z = location->Attribute("z"); - auto* rw = location->Attribute("rw"); - auto* rx = location->Attribute("rx"); - auto* ry = location->Attribute("ry"); - auto* rz = location->Attribute("rz"); - - if (x == nullptr || y == nullptr || z == nullptr || rw == nullptr || rx == nullptr || ry == nullptr - || rz == nullptr) { - LOG("Failed to parse party location data"); + // Read the objects + auto* files = doc.FirstChildElement("files"); + if (files) { + for (auto* file = files->FirstChildElement("file"); file != nullptr; file = file->NextSiblingElement("file")) { + std::string enabled = file->Attribute("enabled"); + std::string filename = file->Attribute("name"); + if (enabled != "1") { continue; } - - VanityNPCLocation locationData; - locationData.m_Position = { std::stof(x), std::stof(y), std::stof(z) }; - locationData.m_Rotation = { std::stof(rw), std::stof(rx), std::stof(ry), std::stof(rz) }; - locationData.m_Chance = 1.0f; - - partyInfo.m_Locations.push_back(locationData); - } - - m_Parties.push_back(partyInfo); - } - - auto* partyPhrases = npcs->FirstChildElement("partyphrases"); - - if (partyPhrases == nullptr) { - LOG("No party phrases found"); - } else { - for (auto* phrase = partyPhrases->FirstChildElement("phrase"); phrase != nullptr; - phrase = phrase->NextSiblingElement("phrase")) { - // Get the phrase - auto* text = phrase->GetText(); - - if (text == nullptr) { - LOG("Failed to parse party phrase"); - continue; - } - - m_PartyPhrases.push_back(text); + ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity" / filename).string()); } } - for (auto* npc = npcs->FirstChildElement("npc"); npc != nullptr; npc = npc->NextSiblingElement("npc")) { - // Get the NPC name - auto* name = npc->Attribute("name"); + // Read the objects + auto* objects = doc.FirstChildElement("objects"); - if (!name) name = ""; + if (objects) { + for (auto* object = objects->FirstChildElement("object"); object != nullptr; object = object->NextSiblingElement("object")) { + // Get the NPC name + auto* name = object->Attribute("name"); - // Get the NPC lot - auto* lot = npc->Attribute("lot"); + if (!name) name = ""; - if (lot == nullptr) { - LOG("Failed to parse NPC lot"); - continue; - } + // Get the NPC lot + auto* lot = object->Attribute("lot"); - // Get the equipment - auto* equipment = npc->FirstChildElement("equipment"); - std::vector inventory; - - if (equipment) { - auto* text = equipment->GetText(); - - if (text != nullptr) { - std::string equipmentString(text); - - std::vector splitEquipment = GeneralUtils::SplitString(equipmentString, ','); - - for (auto& item : splitEquipment) { - inventory.push_back(std::stoi(item)); - } - } - } - - - // Get the phrases - auto* phrases = npc->FirstChildElement("phrases"); - - std::vector phraseList = {}; - - if (phrases) { - for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr; - phrase = phrase->NextSiblingElement("phrase")) { - // Get the phrase - auto* text = phrase->GetText(); - if (text == nullptr) { - LOG("Failed to parse NPC phrase"); - continue; - } - phraseList.push_back(text); - } - } - - // Get the script - auto* scriptElement = npc->FirstChildElement("script"); - - std::string scriptName = ""; - - if (scriptElement != nullptr) { - auto* scriptNameAttribute = scriptElement->Attribute("name"); - if (scriptNameAttribute) scriptName = scriptNameAttribute; - } - - auto* ldfElement = npc->FirstChildElement("ldf"); - std::vector keys = {}; - - std::vector ldf = {}; - if(ldfElement) { - for (auto* entry = ldfElement->FirstChildElement("entry"); entry != nullptr; - entry = entry->NextSiblingElement("entry")) { - // Get the ldf data - auto* data = entry->Attribute("data"); - if (!data) continue; - - LDFBaseData* ldfData = LDFBaseData::DataFromString(data); - keys.push_back(ldfData->GetKey()); - ldf.push_back(ldfData); - } - } - if (!keys.empty()) ldf.push_back(new LDFData>(u"syncLDF", keys)); - - VanityNPC npcData; - npcData.m_Name = name; - npcData.m_LOT = std::stoi(lot); - npcData.m_Equipment = inventory; - npcData.m_Phrases = phraseList; - npcData.m_Script = scriptName; - npcData.ldf = ldf; - - // Get flags - auto* flags = npc->FirstChildElement("flags"); - - if (flags != nullptr) { - for (auto* flag = flags->FirstChildElement("flag"); flag != nullptr; - flag = flag->NextSiblingElement("flag")) { - // Get the flag name - auto* name = flag->Attribute("name"); - - if (name == nullptr) { - LOG("Failed to parse NPC flag name"); - continue; - } - - // Get the flag value - auto* value = flag->Attribute("value"); - - if (value == nullptr) { - LOG("Failed to parse NPC flag value"); - continue; - } - - npcData.m_Flags[name] = std::stoi(value); - } - } - - // Get the zones - for (auto* zone = npc->FirstChildElement("zone"); zone != nullptr; zone = zone->NextSiblingElement("zone")) { - // Get the zone ID - auto* zoneID = zone->Attribute("id"); - - if (zoneID == nullptr) { - LOG("Failed to parse NPC zone ID"); + if (lot == nullptr) { + LOG("Failed to parse object lot"); continue; } + // Get the equipment + auto* equipment = object->FirstChildElement("equipment"); + std::vector inventory; + + if (equipment) { + auto* text = equipment->GetText(); + + if (text != nullptr) { + std::string equipmentString(text); + + std::vector splitEquipment = GeneralUtils::SplitString(equipmentString, ','); + + for (auto& item : splitEquipment) { + inventory.push_back(std::stoi(item)); + } + } + } + + + // Get the phrases + auto* phrases = object->FirstChildElement("phrases"); + + std::vector phraseList = {}; + + if (phrases) { + for (auto* phrase = phrases->FirstChildElement("phrase"); phrase != nullptr; + phrase = phrase->NextSiblingElement("phrase")) { + // Get the phrase + auto* text = phrase->GetText(); + if (text == nullptr) { + LOG("Failed to parse NPC phrase"); + continue; + } + phraseList.push_back(text); + } + } + + // Get the script + auto* scriptElement = object->FirstChildElement("script"); + + std::string scriptName = ""; + + if (scriptElement != nullptr) { + auto* scriptNameAttribute = scriptElement->Attribute("name"); + if (scriptNameAttribute) scriptName = scriptNameAttribute; + } + + auto* configElement = object->FirstChildElement("config"); + std::vector keys = {}; + + std::vector config = {}; + if(configElement) { + for (auto* key = configElement->FirstChildElement("key"); key != nullptr; + key = key->NextSiblingElement("key")) { + // Get the config data + auto* data = key->Attribute("data"); + if (!data) continue; + + LDFBaseData* configData = LDFBaseData::DataFromString(data); + keys.push_back(configData->GetKey()); + config.push_back(configData); + } + } + if (!keys.empty()) config.push_back(new LDFData>(u"syncLDF", keys)); + + VanityObject objectData; + objectData.m_Name = name; + objectData.m_LOT = std::stoi(lot); + objectData.m_Equipment = inventory; + objectData.m_Phrases = phraseList; + objectData.m_Script = scriptName; + objectData.m_Config = config; + // Get the locations - auto* locations = zone->FirstChildElement("locations"); + auto* locations = object->FirstChildElement("locations"); if (locations == nullptr) { LOG("Failed to parse NPC locations"); @@ -443,7 +281,9 @@ void VanityUtilities::ParseXML(const std::string& file) { for (auto* location = locations->FirstChildElement("location"); location != nullptr; location = location->NextSiblingElement("location")) { + // Get the location data + auto* zoneID = location->Attribute("zone"); auto* x = location->Attribute("x"); auto* y = location->Attribute("y"); auto* z = location->Attribute("z"); @@ -452,41 +292,52 @@ void VanityUtilities::ParseXML(const std::string& file) { auto* ry = location->Attribute("ry"); auto* rz = location->Attribute("rz"); - if (x == nullptr || y == nullptr || z == nullptr || rw == nullptr || rx == nullptr || ry == nullptr + if (zoneID == nullptr || x == nullptr || y == nullptr || z == nullptr || rw == nullptr || rx == nullptr || ry == nullptr || rz == nullptr) { LOG("Failed to parse NPC location data"); continue; } - VanityNPCLocation locationData; + VanityObjectLocation locationData; locationData.m_Position = { std::stof(x), std::stof(y), std::stof(z) }; locationData.m_Rotation = { std::stof(rw), std::stof(rx), std::stof(ry), std::stof(rz) }; locationData.m_Chance = 1.0f; - if (location->Attribute("chance") != nullptr) { + if (location->Attribute("chance")) { locationData.m_Chance = std::stof(location->Attribute("chance")); } - const auto& it = npcData.m_Locations.find(std::stoi(zoneID)); + if (location->Attribute("scale")) { + locationData.m_Scale = std::stof(location->Attribute("scale")); + } - if (it != npcData.m_Locations.end()) { + + const auto& it = objectData.m_Locations.find(std::stoi(zoneID)); + + if (it != objectData.m_Locations.end()) { it->second.push_back(locationData); } else { - std::vector locations; + std::vector locations; locations.push_back(locationData); - npcData.m_Locations.insert(std::make_pair(std::stoi(zoneID), locations)); + objectData.m_Locations.insert(std::make_pair(std::stoi(zoneID), locations)); + } + + if (!(std::find(keys.begin(), keys.end(), u"teleport") != keys.end())) { + m_Objects.push_back(objectData); + objectData.m_Locations.clear(); } } + if (std::find(keys.begin(), keys.end(), u"teleport") != keys.end()) { + m_Objects.push_back(objectData); + } } - - m_NPCs.push_back(npcData); } } -VanityNPC* VanityUtilities::GetNPC(const std::string& name) { - for (size_t i = 0; i < m_NPCs.size(); i++) { - if (m_NPCs[i].m_Name == name) { - return &m_NPCs[i]; +VanityObject* VanityUtilities::GetObject(const std::string& name) { + for (size_t i = 0; i < m_Objects.size(); i++) { + if (m_Objects[i].m_Name == name) { + return &m_Objects[i]; } } @@ -498,10 +349,13 @@ std::string VanityUtilities::ParseMarkdown(const std::string& file) { // Read the file into a string std::ifstream t(file); - + std::stringstream output; // If the file does not exist, return an empty string. if (!t.good()) { - return ""; + output << "File "; + output << file.substr(file.rfind("/") + 1); + output << " not found!\nContact your DarkflameServer admin\nor find the server source at https://github.com/DarkflameUniverse/DarkflameServer"; + return output.str(); } std::stringstream buffer; @@ -511,7 +365,6 @@ std::string VanityUtilities::ParseMarkdown(const std::string& file) { // Loop through all lines in the file. // Replace all instances of the markdown syntax with the corresponding HTML. // Only care about headers - std::stringstream output; std::string line; std::stringstream ss; ss << fileContents; diff --git a/dGame/dUtilities/VanityUtilities.h b/dGame/dUtilities/VanityUtilities.h index cff73bce..49bd23ab 100644 --- a/dGame/dUtilities/VanityUtilities.h +++ b/dGame/dUtilities/VanityUtilities.h @@ -3,15 +3,17 @@ #include "dCommonVars.h" #include "Entity.h" #include +#include -struct VanityNPCLocation +struct VanityObjectLocation { float m_Chance = 1.0f; NiPoint3 m_Position; NiQuaternion m_Rotation; + float m_Scale = 1.0f; }; -struct VanityNPC +struct VanityObject { LWOOBJID m_ID = LWOOBJID_EMPTY; std::string m_Name; @@ -19,37 +21,24 @@ struct VanityNPC std::vector m_Equipment; std::vector m_Phrases; std::string m_Script; - std::map m_Flags; - std::map> m_Locations; - std::vector ldf; + std::map> m_Locations; + std::vector m_Config; }; -struct VanityParty -{ - uint32_t m_Zone; - float m_Chance = 1.0f; - std::vector m_Locations; -}; class VanityUtilities { public: static void SpawnVanity(); - static Entity* SpawnNPC( - LOT lot, - const std::string& name, - const NiPoint3& position, - const NiQuaternion& rotation, - const std::vector& inventory, - const std::vector& ldf + static Entity* SpawnObject( + const VanityObject& object, + const VanityObjectLocation& location ); static LWOOBJID SpawnSpawner( - LOT lot, - const NiPoint3& position, - const NiQuaternion& rotation, - const std::vector& ldf + const VanityObject& object, + const VanityObjectLocation& location ); static std::string ParseMarkdown( @@ -60,16 +49,14 @@ public: const std::string& file ); - static VanityNPC* GetNPC(const std::string& name); + static VanityObject* GetObject(const std::string& name); private: static void SetupNPCTalk(Entity* npc); static void NPCTalk(Entity* npc); - static std::vector m_NPCs; - - static std::vector m_Parties; - - static std::vector m_PartyPhrases; + static std::vector m_Objects; + + static std::set m_LoadedFiles; }; diff --git a/dScripts/02_server/DLU/CMakeLists.txt b/dScripts/02_server/DLU/CMakeLists.txt index 64d4cbbd..fb257d3e 100644 --- a/dScripts/02_server/DLU/CMakeLists.txt +++ b/dScripts/02_server/DLU/CMakeLists.txt @@ -1,3 +1,3 @@ set(DSCRIPTS_SOURCES_02_SERVER_DLU - "DLUVanityNPC.cpp" + "DLUVanityTeleportingObject.cpp" PARENT_SCOPE) diff --git a/dScripts/02_server/DLU/DLUVanityNPC.cpp b/dScripts/02_server/DLU/DLUVanityTeleportingObject.cpp similarity index 51% rename from dScripts/02_server/DLU/DLUVanityNPC.cpp rename to dScripts/02_server/DLU/DLUVanityTeleportingObject.cpp index ba2c6604..8aff1995 100644 --- a/dScripts/02_server/DLU/DLUVanityNPC.cpp +++ b/dScripts/02_server/DLU/DLUVanityTeleportingObject.cpp @@ -1,22 +1,22 @@ -#include "DLUVanityNPC.h" +#include "DLUVanityTeleportingObject.h" #include "GameMessages.h" #include "dServer.h" #include "VanityUtilities.h" #include "RenderComponent.h" -void DLUVanityNPC::OnStartup(Entity* self) { - m_NPC = VanityUtilities::GetNPC("averysumner - Destroyer of Worlds"); +void DLUVanityTeleportingObject::OnStartup(Entity* self) { + if (!self->HasVar(u"npcName") || !self->HasVar(u"teleport")) return; + m_Object = VanityUtilities::GetObject(self->GetVarAsString(u"npcName")); - if (m_NPC == nullptr) { - return; - } + if (!m_Object) return; + if (self->HasVar(u"teleportInterval")) m_TeleportInterval = self->GetVar(u"teleportInterval"); if (self->GetVar(u"teleport")) { - self->AddTimer("setupTeleport", 15.0f); + self->AddTimer("setupTeleport", m_TeleportInterval); } } -void DLUVanityNPC::OnTimerDone(Entity* self, std::string timerName) { +void DLUVanityTeleportingObject::OnTimerDone(Entity* self, std::string timerName) { if (timerName == "setupTeleport") { RenderComponent::PlayAnimation(self, u"interact"); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportBeam", "teleportBeam"); @@ -28,20 +28,22 @@ void DLUVanityNPC::OnTimerDone(Entity* self, std::string timerName) { GameMessages::SendStopFXEffect(self, true, "teleportBeam"); GameMessages::SendStopFXEffect(self, true, "teleportRings"); } else if (timerName == "teleport") { - std::vector& locations = m_NPC->m_Locations[Game::server->GetZoneID()]; + std::vector& locations = m_Object->m_Locations[Game::server->GetZoneID()]; selectLocation: - VanityNPCLocation& newLocation = locations[GeneralUtils::GenerateRandomNumber(0, locations.size() - 1)]; + VanityObjectLocation& newLocation = locations[GeneralUtils::GenerateRandomNumber(0, locations.size() - 1)]; + // try to get not the same position, but if we get the same one twice, it's fine if (self->GetPosition() == newLocation.m_Position) { - goto selectLocation; // cry about it + VanityObjectLocation& newLocation = locations[GeneralUtils::GenerateRandomNumber(0, locations.size() - 1)]; } self->SetPosition(newLocation.m_Position); self->SetRotation(newLocation.m_Rotation); + self->SetScale(newLocation.m_Scale); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportBeam", "teleportBeam"); GameMessages::SendPlayFXEffect(self->GetObjectID(), 6478, u"teleportRings", "teleportRings"); self->AddTimer("stopFX", 2.0f); - self->AddTimer("setupTeleport", 15.0f); + self->AddTimer("setupTeleport", m_TeleportInterval); } } diff --git a/dScripts/02_server/DLU/DLUVanityNPC.h b/dScripts/02_server/DLU/DLUVanityTeleportingObject.h similarity index 54% rename from dScripts/02_server/DLU/DLUVanityNPC.h rename to dScripts/02_server/DLU/DLUVanityTeleportingObject.h index aeb8e051..a13ba901 100644 --- a/dScripts/02_server/DLU/DLUVanityNPC.h +++ b/dScripts/02_server/DLU/DLUVanityTeleportingObject.h @@ -1,13 +1,14 @@ #pragma once #include "CppScripts.h" -class VanityNPC; -class DLUVanityNPC : public CppScripts::Script +class VanityObject; +class DLUVanityTeleportingObject : public CppScripts::Script { public: void OnStartup(Entity* self) override; void OnTimerDone(Entity* self, std::string timerName) override; private: - VanityNPC* m_NPC; + VanityObject* m_Object; + float m_TeleportInterval = 15.0f; }; diff --git a/dScripts/CppScripts.cpp b/dScripts/CppScripts.cpp index 071bd7a3..7cb853e6 100644 --- a/dScripts/CppScripts.cpp +++ b/dScripts/CppScripts.cpp @@ -216,7 +216,7 @@ #include "NtNaomiBreadcrumbServer.h" // DLU Scripts -#include "DLUVanityNPC.h" +#include "DLUVanityTeleportingObject.h" // AM Scripts #include "AmConsoleTeleportServer.h" @@ -834,8 +834,8 @@ CppScripts::Script* CppScripts::GetScript(Entity* parent, const std::string& scr script = new NjNyaMissionitems(); //DLU: - else if (scriptName == "scripts\\02_server\\DLU\\DLUVanityNPC.lua") - script = new DLUVanityNPC(); + else if (scriptName == "scripts\\02_server\\DLU\\DLUVanityTeleportingObject.lua") + script = new DLUVanityTeleportingObject(); // Survival minigame else if (scriptName == "scripts\\02_server\\Enemy\\Survival\\L_AG_SURVIVAL_STROMBIE.lua") diff --git a/vanity/atm.xml b/vanity/atm.xml new file mode 100644 index 00000000..96ed1a2b --- /dev/null +++ b/vanity/atm.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vanity/NPC.xml b/vanity/dev-tribute.xml similarity index 65% rename from vanity/NPC.xml rename to vanity/dev-tribute.xml index 2311ab46..d20e31a6 100644 --- a/vanity/NPC.xml +++ b/vanity/dev-tribute.xml @@ -1,5 +1,5 @@ - - + + 6802, 2519, 2623, 14806 Sorry for the mess. @@ -11,39 +11,33 @@ Everything is awesome! I hope my behaviors are behaving themselves. - - - - - - - + + + + + 12947, 12949, 12962, 12963 I hope quickbulds are still working! Be careful crossing the gap! Have The Maelstrom stopped going invisible? - - - - - - - + + + + + 9950, 9944, 14102, 14092 Hello Explorer! It's great to see you made it! Have you heard about Darkflame? I've traveled across this entire system, but nothing beats the view here. - - - - - - - + + + + + cmerw[acowipaejio;fawjioefasdl;kfjm; @@ -51,20 +45,18 @@ zxnpoasdfiopwemsadf'kawpfo[ekasdf;'s *teleports behind you* -