From b6af92ef81a8c9f93557ad0492f927d027343d22 Mon Sep 17 00:00:00 2001 From: jadebenn Date: Sun, 18 Feb 2024 00:38:26 -0600 Subject: [PATCH 001/124] 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 | 31 +++++++++------ .../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, 361 insertions(+), 340 deletions(-) diff --git a/dCommon/Amf3.h b/dCommon/Amf3.h index dbafba1fe..c3077370a 100644 --- a/dCommon/Amf3.h +++ b/dCommon/Amf3.h @@ -127,12 +127,12 @@ class AMFArrayValue : public AMFBaseValue { /** * 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 @@ class AMFArrayValue : public AMFBaseValue { 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 @@ class AMFArrayValue : public AMFBaseValue { 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 3c42f4dbc..c38ef8807 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 2950ac822..e67a90d8b 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 3a5a6bf11..84722ea24 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 73f1391d5..f9d3cec83 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 df6658896..c2bb7ed7d 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 c2ba2eebd..0cdfbddde 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 91e91e728..7013e84e0 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 36d9a3dc0..44b1e9ab3 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 ac3a96122..a8737dd7d 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 cf96ab134..9c1033342 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 766276655..0832d687d 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 ac6e8db7a..064ba2e9b 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 2e2bf9a0d..dbd704212 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 a49a8aebb..f7688e1a7 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 f55fde8ec..cadf33bff 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 18327ecf6..d5a837143 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 7fa4d3a89..970a744d8 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 4d45429b7..8fa2cb5b4 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 2f1ac2439..e36711856 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 5195e6766..01709f705 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 dc1057666..9a3834694 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 d612ae2a1..0c3689fa7 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 db12c046c..054fbf3ed 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 c6164c6f7..ab13cd208 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 860df0af4..7e2122060 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 b70beecee..371faf1c0 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 6a32ab0c5..a65949e88 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 17365be22..d9c73f6aa 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 3f4119d2b..e71742963 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 45dad737a..9c35d1ba0 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 e41d50ebb..6cdcc5c3a 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); }; + SplitStripMessage(const AMFArrayValue* arguments); + + [[nodiscard]] int32_t GetSrcActionIndex() const noexcept { return m_SrcActionIndex; } + + [[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: - ActionContext sourceActionContext; - ActionContext destinationActionContext; - int32_t srcActionIndex; - StripUiPosition destinationPosition; + int32_t m_SrcActionIndex; + ActionContext m_SourceActionContext; + ActionContext m_DestinationActionContext; + StripUiPosition m_DestinationPosition; - std::vector transferredActions; + std::vector m_TransferredActions; }; #endif //!__SPLITSTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp index 8b2d1d365..0acbfb3fe 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; + + const auto* const yPositionValue = uiArray->Get("y"); + if (!yPositionValue) return; - yPosition = yPositionValue->GetValue(); - xPosition = xPositionValue->GetValue(); + 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 92578cdc2..6371b4652 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 924a9e62a..68b979170 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 aa34940b6..cfa9dd4d9 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 05dc7cf77..593673b62 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 0e9afe815..85ca5d544 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 5fee358de..c4d224824 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 ab7394083..4eab53674 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 @@ class ControlBehaviors: public Singleton { * @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 @@ class ControlBehaviors: public Singleton { * * @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 f6f6e4f1f..423751c42 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 dc53bbed6..c9cb4b987 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 @@ class PropertyBehavior { 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 59a9aa8bf..0c8a11d95 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 a6a6d23be..f04257635 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 7d27cacd4..0f459e469 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 f3e10964e..107fee112 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 002/124] 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 fc9fa0f07..9cd9df43c 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 003/124] 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 78cf4f485..3e3e2f9c7 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 15659912b..42d84aead 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 004/124] 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 c3077370a..294a5b6c3 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 @@ class AMFValue : public AMFBaseValue { }; // Explicit template class instantiations -template class AMFValue; +template class AMFValue; template class AMFValue; template class AMFValue; template class AMFValue; @@ -110,7 +111,7 @@ class AMFArrayValue : public AMFBaseValue { [[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 @@ class AMFArrayValue : public AMFBaseValue { /** * 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 @@ class AMFArrayValue : public AMFBaseValue { */ 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 @@ class AMFArrayValue : public AMFBaseValue { // 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 @@ class AMFArrayValue : public AMFBaseValue { [[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 @@ class AMFArrayValue : public AMFBaseValue { [[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 @@ class AMFArrayValue : public AMFBaseValue { * @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 @@ class AMFArrayValue : public AMFBaseValue { * @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 @@ class AMFArrayValue : public AMFBaseValue { */ 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 @@ class AMFArrayValue : public AMFBaseValue { * @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 @@ class AMFArrayValue : public AMFBaseValue { * 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 @@ class AMFArrayValue : public AMFBaseValue { } [[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 @@ class AMFArrayValue : public AMFBaseValue { */ 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 @@ class AMFArrayValue : public AMFBaseValue { */ 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 005/124] 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 cdf1d5bc9..4122a8009 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 18aa7a420..f509faa2a 100644 --- a/dGame/dComponents/BuffComponent.h +++ b/dGame/dComponents/BuffComponent.h @@ -141,7 +141,7 @@ class BuffComponent final : public Component { 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 006/124] 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 | 117 ++++-------------- dGame/dGameMessages/GameMessages.h | 3 +- dNet/AuthPackets.cpp | 2 +- 13 files changed, 224 insertions(+), 95 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 83acbf897..2b991dfbf 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 000000000..e61ee0ee2 --- /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 8862b1dba..97dcde9fc 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 6ba7b19e9..5067f2e2b 100644 --- a/dDatabase/CDClientDatabase/CDClientTables/CDMissionsTable.h +++ b/dDatabase/CDClientDatabase/CDClientTables/CDMissionsTable.h @@ -70,6 +70,9 @@ class CDMissionsTable : public CDTable> 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 269b4cc44..bb932991d 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 000000000..10a0ca29d --- /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 000000000..bffd39836 --- /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 ac509e11e..21fe92071 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 afa3d0132..9e9428f74 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 48b766d2f..9025148b3 100644 --- a/dGame/dComponents/VendorComponent.h +++ b/dGame/dComponents/VendorComponent.h @@ -47,6 +47,7 @@ class VendorComponent : public Component { 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 c38ef8807..a62bf3827 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; - - auto* propertyVendorComponent = static_cast(entity->GetComponent(eReplicaComponentType::PROPERTY_VENDOR)); - - if (propertyVendorComponent != nullptr) { - propertyVendorComponent->OnBuyFromVendor(player, bConfirmed, item, count); - + + // handle buying normal items + auto* vendorComponent = entity->GetComponent(); + if (vendorComponent) { + vendorComponent->Buy(player, 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); + // handle buying achievement items + auto* achievementVendorComponent = entity->GetComponent(); + if (achievementVendorComponent) { + achievementVendorComponent->Buy(player, item, count); 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); + // Handle buying properties + auto* propertyVendorComponent = entity->GetComponent(); + if (propertyVendorComponent) { + propertyVendorComponent->OnBuyFromVendor(player, bConfirmed, item, count); + return; } - - 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 a96bbf602..9604d261d 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 25ccc9029..54c28299f 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 007/124] 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 9524d908b..5f35b6290 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 008/124] 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 | 481 ++++++------------ 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, 375 insertions(+), 572 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 e085bfe71..b36bdb290 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 bb932991d..dd15f69d8 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 6546e458f..7d5e24c9c 100644 --- a/dGame/Entity.h +++ b/dGame/Entity.h @@ -295,6 +295,8 @@ class Entity { 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 fa1a3eac3..3e93f830f 100644 --- a/dGame/dUtilities/VanityUtilities.cpp +++ b/dGame/dUtilities/VanityUtilities.cpp @@ -22,18 +22,35 @@ #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() { + const uint32_t zoneID = Game::server->GetZoneID(); + + if (zoneID == 1200) { + { + EntityInfo info; + info.lot = 8139; + info.pos = { 259.5f, 246.4f, -705.2f }; + info.rot = { 0.0f, 0.0f, 1.0f, 0.0f }; + info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID(); + + info.settings = { new LDFData(u"hasCustomText", true), + new LDFData(u"customText", ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/TESTAMENT.md").string())) }; + + auto* entity = Game::entityManager->CreateEntity(info); + + Game::entityManager->ConstructEntity(entity); + } + } + if (Game::config->GetValue("disable_vanity") == "1") { return; } - const uint32_t zoneID = Game::server->GetZoneID(); - - for (const auto& npc : m_NPCs) { + for (const auto& npc : m_Objects) { if (npc.m_ID == LWOOBJID_EMPTY) continue; if (npc.m_LOT == 176){ Game::zoneManager->RemoveSpawner(npc.m_ID); @@ -44,169 +61,83 @@ void VanityUtilities::SpawnVanity() { } } - 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 = {}; + m_Objects.clear(); + m_LoadedFiles.clear(); - LOG("Spawning party with %i locations", party.m_Locations.size()); + ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity/root.xml").string()); - // 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; + // 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 = npc.m_Locations.at(Game::server->GetZoneID()); + 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 (location.m_Chance < rate) continue; - if (npc.ldf.empty()) { - npc.ldf = { + 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 (npc.m_LOT == 176){ - npc.m_ID = SpawnSpawner(npc.m_LOT, location.m_Position, location.m_Rotation, npc.ldf); + if (object.m_LOT == 176){ + object.m_ID = SpawnSpawner(object, location); } 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* 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 = npcEntity->GetComponent(); + auto* scriptComponent = objectEntity->GetComponent(); - if (scriptComponent && !npc.m_Script.empty()) { - scriptComponent->SetScript(npc.m_Script); + if (scriptComponent && !object.m_Script.empty()) { + scriptComponent->SetScript(object.m_Script); scriptComponent->SetSerialized(false); - - for (const auto& npc : npc.m_Flags) { - npcEntity->SetVar(GeneralUtils::ASCIIToUTF16(npc.first), npc.second); - } } - SetupNPCTalk(npcEntity); + SetupNPCTalk(objectEntity); } } } - - if (zoneID == 1200) { - { - EntityInfo info; - info.lot = 8139; - info.pos = { 259.5f, 246.4f, -705.2f }; - info.rot = { 0.0f, 0.0f, 1.0f, 0.0f }; - info.spawnerID = Game::entityManager->GetZoneControlEntity()->GetObjectID(); - - info.settings = { new LDFData(u"hasCustomText", true), - new LDFData(u"customText", ParseMarkdown((BinaryPathFinder::GetBinaryDir() / "vanity/TESTAMENT.md").string())) }; - - auto* entity = Game::entityManager->CreateEntity(info); - - Game::entityManager->ConstructEntity(entity); - } - } } -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); + ParseXML((BinaryPathFinder::GetBinaryDir() / "vanity" / filename).string()); } - - 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); - } - } + // Read the objects + auto* objects = doc.FirstChildElement("objects"); - for (auto* npc = npcs->FirstChildElement("npc"); npc != nullptr; npc = npc->NextSiblingElement("npc")) { - // Get the NPC name - auto* name = npc->Attribute("name"); + if (objects) { + for (auto* object = objects->FirstChildElement("object"); object != nullptr; object = object->NextSiblingElement("object")) { + // Get the NPC name + auto* name = object->Attribute("name"); - if (!name) name = ""; + if (!name) name = ""; - // Get the NPC lot - auto* lot = npc->Attribute("lot"); + // Get the NPC lot + auto* lot = object->Attribute("lot"); - if (lot == nullptr) { - LOG("Failed to parse NPC lot"); - continue; - } + if (lot == nullptr) { + LOG("Failed to parse object lot"); + continue; + } - // Get the equipment - auto* equipment = npc->FirstChildElement("equipment"); - std::vector inventory; + // Get the equipment + auto* equipment = object->FirstChildElement("equipment"); + std::vector inventory; - if (equipment) { - auto* text = equipment->GetText(); + if (equipment) { + auto* text = equipment->GetText(); - if (text != nullptr) { - std::string equipmentString(text); + if (text != nullptr) { + std::string equipmentString(text); - std::vector splitEquipment = GeneralUtils::SplitString(equipmentString, ','); + std::vector splitEquipment = GeneralUtils::SplitString(equipmentString, ','); - for (auto& item : splitEquipment) { - inventory.push_back(std::stoi(item)); + for (auto& item : splitEquipment) { + inventory.push_back(std::stoi(item)); + } } } - } - // Get the phrases - auto* phrases = npc->FirstChildElement("phrases"); + // Get the phrases + auto* phrases = object->FirstChildElement("phrases"); - std::vector phraseList = {}; + 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; + 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); } - phraseList.push_back(text); } - } - // Get the script - auto* scriptElement = npc->FirstChildElement("script"); + // Get the script + auto* scriptElement = object->FirstChildElement("script"); - std::string scriptName = ""; - - if (scriptElement != nullptr) { - auto* scriptNameAttribute = scriptElement->Attribute("name"); - if (scriptNameAttribute) scriptName = scriptNameAttribute; - } + std::string scriptName = ""; - 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 (scriptElement != nullptr) { + auto* scriptNameAttribute = scriptElement->Attribute("name"); + if (scriptNameAttribute) scriptName = scriptNameAttribute; } - } - 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"); + auto* configElement = object->FirstChildElement("config"); + std::vector keys = {}; - if (value == nullptr) { - LOG("Failed to parse NPC flag value"); - continue; - } + 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; - npcData.m_Flags[name] = std::stoi(value); + 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)); - // 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"); - continue; - } + 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 cff73bce2..49bd23ab0 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 @@ class VanityUtilities 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 64d4cbbdf..fb257d3e6 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 ba2c66044..8aff19952 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 aeb8e051d..a13ba901c 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 071bd7a3e..7cb853e62 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 000000000..96ed1a2b7 --- /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 2311ab462..d20e31a68 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* -