From 1a4d9f9130924d5b49437c26a9898771767965ff Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Tue, 26 Dec 2023 23:05:16 -0800 Subject: [PATCH 01/24] Add addstrip handling add SendBehaviorBlocksToClient serialization add id generation and auto updating add behaviorlisttoclient serialization --- dGame/dComponents/ModelComponent.h | 41 +++ .../ControlBehaviorMessages/Action.cpp | 18 +- .../BehaviorMessageBase.cpp | 8 +- .../BehaviorMessageBase.h | 8 +- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 254 +++++++----------- dGame/dPropertyBehaviors/ControlBehaviors.h | 15 +- 6 files changed, 164 insertions(+), 180 deletions(-) diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index dd9984e72..62d2e5b11 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -1,13 +1,51 @@ #pragma once + +#include + #include "dCommonVars.h" #include "RakNetTypes.h" #include "NiPoint3.h" #include "NiQuaternion.h" #include "Component.h" #include "eReplicaComponentType.h" +#include "Amf3.h" + +#include "BehaviorStates.h" +#include "AddStripMessage.h" +#include "Action.h" +class Action; class Entity; +struct Strip { + void AddStrip(AddStripMessage& msg) { + m_Actions = msg.GetActionsToAdd(); + for (auto& action : m_Actions) { + LOG("%s %s %f %s", action.GetType().c_str(), action.GetValueParameterName().c_str(), (float)action.GetValueParameterDouble(), action.GetValueParameterString().c_str()); + } + m_Position = msg.GetPosition(); + }; + std::vector m_Actions; + StripUiPosition m_Position; +}; + +struct State { + void AddStrip(AddStripMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + m_Strips.resize(msg.GetActionContext().GetStripId() + 1); + } + m_Strips[msg.GetActionContext().GetStripId()].AddStrip(msg); + }; + std::vector m_Strips; +}; + +struct PropertyBehavior { + void AddStrip(AddStripMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].AddStrip(msg); + }; + std::map m_States; +}; + /** * Component that represents entities that are a model, e.g. collectible models and BBB models. */ @@ -43,6 +81,7 @@ class ModelComponent : public Component { */ void SetRotation(const NiQuaternion& rot) { m_OriginalRotation = rot; } + std::map m_Behaviors; private: /** @@ -59,4 +98,6 @@ class ModelComponent : public Component { * The ID of the user that made the model */ LWOOBJID m_userModelID; + + // std::map m_Behaviors; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp index eabe76b74..175412e12 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp @@ -12,19 +12,19 @@ Action::Action(AMFArrayValue* arguments) { valueParameterName = ""; valueParameterString = ""; valueParameterDouble = 0.0; - for (auto& typeValueMap : arguments->GetAssociative()) { - if (typeValueMap.first == "Type") { - if (typeValueMap.second->GetValueType() != eAmf::String) continue; - type = static_cast(typeValueMap.second)->GetValue(); + for (auto& [paramName, paramValue] : arguments->GetAssociative()) { + if (paramName == "Type") { + if (paramValue->GetValueType() != eAmf::String) continue; + type = static_cast(paramValue)->GetValue(); } else { - valueParameterName = typeValueMap.first; + valueParameterName = paramName; // Message is the only known string parameter if (valueParameterName == "Message") { - if (typeValueMap.second->GetValueType() != eAmf::String) continue; - valueParameterString = static_cast(typeValueMap.second)->GetValue(); + if (paramValue->GetValueType() != eAmf::String) continue; + valueParameterString = static_cast(paramValue)->GetValue(); } else { - if (typeValueMap.second->GetValueType() != eAmf::Double) continue; - valueParameterDouble = static_cast(typeValueMap.second)->GetValue(); + if (paramValue->GetValueType() != eAmf::Double) continue; + valueParameterDouble = static_cast(paramValue)->GetValue(); } } } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp index 3286504a2..79cc7c260 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp @@ -5,22 +5,20 @@ #include "dCommonVars.h" BehaviorMessageBase::BehaviorMessageBase(AMFArrayValue* arguments) { - behaviorId = 0; behaviorId = GetBehaviorIdFromArgument(arguments); } int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(AMFArrayValue* arguments) { const auto* key = "BehaviorID"; auto* behaviorIDValue = arguments->Get(key); - int32_t behaviorID = -1; if (behaviorIDValue && behaviorIDValue->GetValueType() == eAmf::String) { - behaviorID = std::stoul(behaviorIDValue->GetValue()); - } else if (arguments->Get(key)->GetValueType() != eAmf::Undefined) { + GeneralUtils::TryParse(behaviorIDValue->GetValue(), behaviorId); + } else if (arguments->Get(key) && arguments->Get(key)->GetValueType() != eAmf::Undefined) { throw std::invalid_argument("Unable to find behavior ID"); } - return behaviorID; + return behaviorId; } uint32_t BehaviorMessageBase::GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName) { diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h index 39246c9d9..00bcc1fcd 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h @@ -18,12 +18,14 @@ enum class BehaviorState : uint32_t; */ class BehaviorMessageBase { public: - const uint32_t GetBehaviorId() { return behaviorId; }; -protected: + static inline int32_t DefaultBehaviorId = -1; + const int32_t GetBehaviorId() { return behaviorId; }; + bool IsDefaultBehaviorId() { return behaviorId == DefaultBehaviorId; }; BehaviorMessageBase(AMFArrayValue* arguments); +protected: int32_t GetBehaviorIdFromArgument(AMFArrayValue* arguments); uint32_t GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName = "actionIndex"); - int32_t behaviorId = -1; + int32_t behaviorId = DefaultBehaviorId; }; #endif //!__BEHAVIORMESSAGEBASE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index b143cbc81..8bb556275 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -30,37 +30,24 @@ #include "UpdateActionMessage.h" #include "UpdateStripUiMessage.h" -void ControlBehaviors::RequestUpdatedID(int32_t behaviorID, ModelComponent* modelComponent, Entity* modelOwner, const SystemAddress& sysAddr) { - // auto behavior = modelComponent->FindBehavior(behaviorID); - // if (behavior->GetBehaviorID() == -1 || behavior->GetShouldSetNewID()) { - // ObjectIDManager::Instance()->RequestPersistentID( - // [behaviorID, behavior, modelComponent, modelOwner, sysAddr](uint32_t persistentId) { - // behavior->SetShouldGetNewID(false); - // behavior->SetIsTemplated(false); - // behavior->SetBehaviorID(persistentId); - - // // This updates the behavior ID of the behavior should this be a new behavior - // AMFArrayValue args; - - // AMFStringValue* behaviorIDString = new AMFStringValue(); - // behaviorIDString->SetValue(std::to_string(persistentId)); - // args.InsertValue("behaviorID", behaviorIDString); - - // AMFStringValue* objectIDAsString = new AMFStringValue(); - // objectIDAsString->SetValue(std::to_string(modelComponent->GetParent()->GetObjectID())); - // args.InsertValue("objectID", objectIDAsString); - - // GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorID", &args); - // ControlBehaviors::SendBehaviorListToClient(modelComponent->GetParent(), sysAddr, modelOwner); - // }); - // } -} +void ControlBehaviors::RequestUpdatedID(ControlBehaviorContext& context) { + ObjectIDManager::Instance()->RequestPersistentID( + [context](uint32_t persistentId) { + // This updates the behavior ID of the behavior should this be a new behavior + AMFArrayValue args; -void ControlBehaviors::SendBehaviorListToClient(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner) { - auto* modelComponent = modelEntity->GetComponent(); + args.Insert("behaviorID", std::to_string(persistentId)); + args.Insert("objectID", std::to_string(context.modelComponent->GetParent()->GetObjectID())); - if (!modelComponent) return; + GameMessages::SendUIMessageServerToSingleClient(context.modelOwner, context.modelOwner->GetSystemAddress(), "UpdateBehaviorID", args); + context.modelComponent->m_Behaviors[persistentId] = context.modelComponent->m_Behaviors[BehaviorMessageBase::DefaultBehaviorId]; + context.modelComponent->m_Behaviors.erase(BehaviorMessageBase::DefaultBehaviorId); + + ControlBehaviors::Instance().SendBehaviorListToClient(context); + }); +} +void ControlBehaviors::SendBehaviorListToClient(const ControlBehaviorContext& context) { AMFArrayValue behaviorsToSerialize; /** @@ -73,10 +60,17 @@ void ControlBehaviors::SendBehaviorListToClient(Entity* modelEntity, const Syste * "name": The name of the behavior formatted as an AMFString */ - behaviorsToSerialize.Insert("behaviors"); - behaviorsToSerialize.Insert("objectID", std::to_string(modelComponent->GetParent()->GetObjectID())); + int32_t index = 0; + auto behaviors = behaviorsToSerialize.InsertArray("behaviors"); + for (const auto& [id, behaviorInfo] : context.modelComponent->m_Behaviors) { + auto* array = behaviors->InsertArray(index++); + array->Insert("id", std::to_string(id)); + array->Insert("name", "Test name"); + array->Insert("isLoot", false); + } + behaviorsToSerialize.Insert("objectID", std::to_string(context.modelComponent->GetParent()->GetObjectID())); - GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorList", behaviorsToSerialize); + GameMessages::SendUIMessageServerToSingleClient(context.modelOwner, context.modelOwner->GetSystemAddress(), "UpdateBehaviorList", behaviorsToSerialize); } void ControlBehaviors::ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent) { @@ -92,8 +86,14 @@ void ControlBehaviors::ToggleExecutionUpdates() { //TODO do something with this info } -void ControlBehaviors::AddStrip(AMFArrayValue* arguments) { - AddStripMessage addStripMessage(arguments); +void ControlBehaviors::AddStrip(ControlBehaviorContext& context) { + AddStripMessage addStripMessage(context.arguments); + + if (addStripMessage.IsDefaultBehaviorId()) { + RequestUpdatedID(context); + } + + context.modelComponent->m_Behaviors[addStripMessage.GetBehaviorId()].AddStrip(addStripMessage); } void ControlBehaviors::RemoveStrip(AMFArrayValue* arguments) { @@ -137,109 +137,42 @@ void ControlBehaviors::Rename(Entity* modelEntity, const SystemAddress& sysAddr, } // TODO This is also supposed to serialize the state of the behaviors in progress but those aren't implemented yet -void ControlBehaviors::SendBehaviorBlocksToClient(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { - // uint32_t behaviorID = ControlBehaviors::GetBehaviorIDFromArgument(arguments); - - // auto modelBehavior = modelComponent->FindBehavior(behaviorID); - - // if (!modelBehavior) return; - - // modelBehavior->VerifyStates(); - - // auto states = modelBehavior->GetBehaviorStates(); - - // // Begin serialization. - - // /** - // * for each state - // * strip id - // * ui info - // * x - // * y - // * actions - // * action1 - // * action2 - // * ... - // * behaviorID of strip - // * objectID of strip - // */ - // LWOOBJID targetObjectID = LWOOBJID_EMPTY; - // behaviorID = 0; - // AMFArrayValue behaviorInfo; - - // AMFArrayValue* stateSerialize = new AMFArrayValue(); - - // for (auto it = states.begin(); it != states.end(); it++) { - // LOG("Begin serialization of state %i!\n", it->first); - // AMFArrayValue* state = new AMFArrayValue(); - - // AMFDoubleValue* stateAsDouble = new AMFDoubleValue(); - // stateAsDouble->SetValue(it->first); - // state->InsertValue("id", stateAsDouble); - - // AMFArrayValue* strips = new AMFArrayValue(); - // auto stripsInState = it->second->GetStrips(); - // for (auto strip = stripsInState.begin(); strip != stripsInState.end(); strip++) { - // LOG("Begin serialization of strip %i!\n", strip->first); - // AMFArrayValue* thisStrip = new AMFArrayValue(); - - // AMFDoubleValue* stripID = new AMFDoubleValue(); - // stripID->SetValue(strip->first); - // thisStrip->InsertValue("id", stripID); - - // AMFArrayValue* uiArray = new AMFArrayValue(); - // AMFDoubleValue* yPosition = new AMFDoubleValue(); - // yPosition->SetValue(strip->second->GetYPosition()); - // uiArray->InsertValue("y", yPosition); - - // AMFDoubleValue* xPosition = new AMFDoubleValue(); - // xPosition->SetValue(strip->second->GetXPosition()); - // uiArray->InsertValue("x", xPosition); - - // thisStrip->InsertValue("ui", uiArray); - // targetObjectID = modelComponent->GetParent()->GetObjectID(); - // behaviorID = modelBehavior->GetBehaviorID(); - - // AMFArrayValue* stripSerialize = new AMFArrayValue(); - // for (auto behaviorAction : strip->second->GetActions()) { - // LOG("Begin serialization of action %s!\n", behaviorAction->actionName.c_str()); - // AMFArrayValue* thisAction = new AMFArrayValue(); - - // AMFStringValue* actionName = new AMFStringValue(); - // actionName->SetValue(behaviorAction->actionName); - // thisAction->InsertValue("Type", actionName); - - // if (behaviorAction->parameterValueString != "") - // { - // AMFStringValue* valueAsString = new AMFStringValue(); - // valueAsString->SetValue(behaviorAction->parameterValueString); - // thisAction->InsertValue(behaviorAction->parameterName, valueAsString); - // } - // else if (behaviorAction->parameterValueDouble != 0.0) - // { - // AMFDoubleValue* valueAsDouble = new AMFDoubleValue(); - // valueAsDouble->SetValue(behaviorAction->parameterValueDouble); - // thisAction->InsertValue(behaviorAction->parameterName, valueAsDouble); - // } - // stripSerialize->PushBackValue(thisAction); - // } - // thisStrip->InsertValue("actions", stripSerialize); - // strips->PushBackValue(thisStrip); - // } - // state->InsertValue("strips", strips); - // stateSerialize->PushBackValue(state); - // } - // behaviorInfo.InsertValue("states", stateSerialize); - - // AMFStringValue* objectidAsString = new AMFStringValue(); - // objectidAsString->SetValue(std::to_string(targetObjectID)); - // behaviorInfo.InsertValue("objectID", objectidAsString); - - // AMFStringValue* behaviorIDAsString = new AMFStringValue(); - // behaviorIDAsString->SetValue(std::to_string(behaviorID)); - // behaviorInfo.InsertValue("BehaviorID", behaviorIDAsString); - - // GameMessages::SendUIMessageServerToSingleClient(modelOwner, sysAddr, "UpdateBehaviorBlocks", &behaviorInfo); +void ControlBehaviors::SendBehaviorBlocksToClient(ControlBehaviorContext& context) { + BehaviorMessageBase behaviorMsg(context.arguments); + + AMFArrayValue behavior; + behavior.Insert("BehaviorID", std::to_string(behaviorMsg.GetBehaviorId())); + behavior.Insert("objectID", std::to_string(context.modelComponent->GetParent()->GetObjectID())); + auto* stateArray = behavior.InsertArray("states"); + for (const auto& [stateId, state] : context.modelComponent->m_Behaviors[behaviorMsg.GetBehaviorId()].m_States) { + auto* stateInfo = stateArray->InsertArray(static_cast(stateId)); + stateInfo->Insert("id", static_cast(stateId)); + + auto* stripArray = stateInfo->InsertArray("strips"); + for (int32_t stripId = 0; stripId < state.m_Strips.size(); stripId++) { + auto strip = state.m_Strips.at(stripId); + + auto* stripInfo = stripArray->InsertArray(stripId); + stripInfo->Insert("id", static_cast(stripId)); + auto* uiInfo = stripInfo->InsertArray("ui"); + uiInfo->Insert("x", strip.m_Position.GetX()); + uiInfo->Insert("y", strip.m_Position.GetY()); + + auto* actions = stripInfo->InsertArray("actions"); + for (int32_t i = 0; i < strip.m_Actions.size(); i++) { + auto action = strip.m_Actions.at(i); + auto* actionInfo = actions->InsertArray(i); + actionInfo->Insert("Type", action.GetType()); + if (action.GetValueParameterName() == "Message") { + actionInfo->Insert(action.GetValueParameterName(), action.GetValueParameterString()); + } else if (!action.GetValueParameterName().empty()) { + actionInfo->Insert(action.GetValueParameterName(), action.GetValueParameterDouble()); + } + } + } + } + + GameMessages::SendUIMessageServerToSingleClient(context.modelOwner, context.modelOwner->GetSystemAddress(), "UpdateBehaviorBlocks", behavior); } void ControlBehaviors::UpdateAction(AMFArrayValue* arguments) { @@ -276,7 +209,7 @@ void ControlBehaviors::MoveToInventory(ModelComponent* modelComponent, const Sys MoveToInventoryMessage moveToInventoryMessage(arguments); - SendBehaviorListToClient(modelComponent->GetParent(), sysAddr, modelOwner); + // SendBehaviorListToClient(modelComponent->GetParent(), sysAddr, modelOwner); } void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner) { @@ -285,42 +218,45 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& if (!modelComponent) return; - if (command == "sendBehaviorListToClient") - SendBehaviorListToClient(modelEntity, sysAddr, modelOwner); - else if (command == "modelTypeChanged") + ControlBehaviorContext context(arguments, modelComponent, modelOwner); + + if (command == "sendBehaviorListToClient") { + SendBehaviorListToClient(context); + } else if (command == "modelTypeChanged") { ModelTypeChanged(arguments, modelComponent); - else if (command == "toggleExecutionUpdates") + } else if (command == "toggleExecutionUpdates") { ToggleExecutionUpdates(); - else if (command == "addStrip") - AddStrip(arguments); - else if (command == "removeStrip") + } else if (command == "addStrip") { + AddStrip(context); + } else if (command == "removeStrip") { RemoveStrip(arguments); - else if (command == "mergeStrips") + } else if (command == "mergeStrips") { MergeStrips(arguments); - else if (command == "splitStrip") + } else if (command == "splitStrip") { SplitStrip(arguments); - else if (command == "updateStripUI") + } else if (command == "updateStripUI") { UpdateStripUI(arguments); - else if (command == "addAction") + } else if (command == "addAction") { AddAction(arguments); - else if (command == "migrateActions") + } else if (command == "migrateActions") { MigrateActions(arguments); - else if (command == "rearrangeStrip") + } else if (command == "rearrangeStrip") { RearrangeStrip(arguments); - else if (command == "add") + } else if (command == "add") { Add(arguments); - else if (command == "removeActions") + } else if (command == "removeActions") { RemoveActions(arguments); - else if (command == "rename") + } else if (command == "rename") { Rename(modelEntity, sysAddr, modelOwner, arguments); - else if (command == "sendBehaviorBlocksToClient") - SendBehaviorBlocksToClient(modelComponent, sysAddr, modelOwner, arguments); - else if (command == "moveToInventory") + } else if (command == "sendBehaviorBlocksToClient") { + SendBehaviorBlocksToClient(context); + } else if (command == "moveToInventory") { MoveToInventory(modelComponent, sysAddr, modelOwner, arguments); - else if (command == "updateAction") + } else if (command == "updateAction") { UpdateAction(arguments); - else - LOG("Unknown behavior command (%s)\n", command.c_str()); + } else { + LOG("Unknown behavior command (%s)", command.c_str()); + } } ControlBehaviors::ControlBehaviors() { diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index a562aafeb..fcadf96ee 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -17,6 +17,13 @@ class SystemAddress; // Type definition to clarify what is used where typedef std::string BlockName; //! A block name +struct ControlBehaviorContext { + ControlBehaviorContext(AMFArrayValue* args, ModelComponent* modelComponent, Entity* modelOwner) : arguments(args), modelComponent(modelComponent), modelOwner(modelOwner) {}; + AMFArrayValue* arguments; + Entity* modelOwner; + ModelComponent* modelComponent; +}; + class ControlBehaviors: public Singleton { public: ControlBehaviors(); @@ -41,11 +48,11 @@ class ControlBehaviors: public Singleton { */ BlockDefinition* GetBlockInfo(const BlockName& blockName); private: - void RequestUpdatedID(int32_t behaviorID, ModelComponent* modelComponent, Entity* modelOwner, const SystemAddress& sysAddr); - void SendBehaviorListToClient(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner); + void RequestUpdatedID(ControlBehaviorContext& context); + void SendBehaviorListToClient(const ControlBehaviorContext& context); void ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent); void ToggleExecutionUpdates(); - void AddStrip(AMFArrayValue* arguments); + void AddStrip(ControlBehaviorContext& context); void RemoveStrip(AMFArrayValue* arguments); void MergeStrips(AMFArrayValue* arguments); void SplitStrip(AMFArrayValue* arguments); @@ -56,7 +63,7 @@ class ControlBehaviors: public Singleton { void Add(AMFArrayValue* arguments); void RemoveActions(AMFArrayValue* arguments); void Rename(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments); - void SendBehaviorBlocksToClient(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments); + void SendBehaviorBlocksToClient(ControlBehaviorContext& context); void UpdateAction(AMFArrayValue* arguments); void MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments); std::map blockTypes{}; From cbcc868029e0a605b42484fe017192d71e45d900 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 27 Dec 2023 03:54:30 -0800 Subject: [PATCH 02/24] fix crash happened if you added state 0 and 6 and nothing in between --- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 8bb556275..f10a1b7e5 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -145,7 +145,7 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ControlBehaviorContext& contex behavior.Insert("objectID", std::to_string(context.modelComponent->GetParent()->GetObjectID())); auto* stateArray = behavior.InsertArray("states"); for (const auto& [stateId, state] : context.modelComponent->m_Behaviors[behaviorMsg.GetBehaviorId()].m_States) { - auto* stateInfo = stateArray->InsertArray(static_cast(stateId)); + auto* stateInfo = stateArray->PushArray(); stateInfo->Insert("id", static_cast(stateId)); auto* stripArray = stateInfo->InsertArray("strips"); From a1f3261aa852889ef4b45f0dacf42574e2e111a4 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 27 Dec 2023 04:26:52 -0800 Subject: [PATCH 03/24] Section off code Use proper encapsulation to hide code away and only let specific objects do certain jobs. --- dGame/dComponents/ModelComponent.cpp | 45 ++++++++++++++ dGame/dComponents/ModelComponent.h | 62 +++++++++++++------ dGame/dPropertyBehaviors/ControlBehaviors.cpp | 32 +++------- dGame/dPropertyBehaviors/ControlBehaviors.h | 5 ++ 4 files changed, 102 insertions(+), 42 deletions(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index ccdad2817..0284530d0 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -1,6 +1,31 @@ #include "ModelComponent.h" #include "Entity.h" +void Strip::AddStrip(AddStripMessage& msg) { + m_Actions = msg.GetActionsToAdd(); + for (auto& action : m_Actions) { + LOG("%s %s %f %s", action.GetType().c_str(), action.GetValueParameterName().c_str(), (float)action.GetValueParameterDouble(), action.GetValueParameterString().c_str()); + } + m_Position = msg.GetPosition(); +}; + +void State::AddStrip(AddStripMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + m_Strips.resize(msg.GetActionContext().GetStripId() + 1); + } + m_Strips[msg.GetActionContext().GetStripId()].AddStrip(msg); +}; + +void PropertyBehavior::AddStrip(AddStripMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].AddStrip(msg); +}; + +void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { + args.Insert("name", m_Name); + args.Insert("isLocked", isLocked); + args.Insert("isLoot", isLoot); +} + ModelComponent::ModelComponent(Entity* parent) : Component(parent) { m_OriginalPosition = m_Parent->GetDefaultPosition(); m_OriginalRotation = m_Parent->GetDefaultRotation(); @@ -29,3 +54,23 @@ void ModelComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialU outBitStream->Write1(); // Is this model paused if (bIsInitialUpdate) outBitStream->Write0(); // We are not writing model editing info } + +void ModelComponent::HandleControlBehaviorsMsg(AddStripMessage& msg) { + m_Behaviors[msg.GetBehaviorId()].AddStrip(msg); +} + +void ModelComponent::UpdatePendingBehaviorId(const int32_t newId) { + m_Behaviors[newId] = m_Behaviors[BehaviorMessageBase::DefaultBehaviorId]; + m_Behaviors.erase(BehaviorMessageBase::DefaultBehaviorId); +} + +void ModelComponent::SendBehaviorListToClient(AMFArrayValue& args) { + args.Insert("objectID", std::to_string(m_Parent->GetObjectID())); + + auto* behaviorArray = args.InsertArray("behaviors"); + for (auto& [behaviorId, behavior] : m_Behaviors) { + auto* behaviorArgs = behaviorArray->PushArray(); + behaviorArgs->Insert("id", std::to_string(behaviorId)); + behavior.SendBehaviorListToClient(*behaviorArgs); + } +} diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 62d2e5b11..f3145257c 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -16,34 +16,40 @@ class Action; class Entity; +class AddStripMessage; -struct Strip { - void AddStrip(AddStripMessage& msg) { - m_Actions = msg.GetActionsToAdd(); - for (auto& action : m_Actions) { - LOG("%s %s %f %s", action.GetType().c_str(), action.GetValueParameterName().c_str(), (float)action.GetValueParameterDouble(), action.GetValueParameterString().c_str()); - } - m_Position = msg.GetPosition(); - }; +class Strip { +public: + void AddStrip(AddStripMessage& msg); +// private: std::vector m_Actions; StripUiPosition m_Position; }; -struct State { - void AddStrip(AddStripMessage& msg) { - if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { - m_Strips.resize(msg.GetActionContext().GetStripId() + 1); - } - m_Strips[msg.GetActionContext().GetStripId()].AddStrip(msg); - }; +class State { +public: + void AddStrip(AddStripMessage& msg); +// private: std::vector m_Strips; }; -struct PropertyBehavior { - void AddStrip(AddStripMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].AddStrip(msg); - }; +class PropertyBehavior { +public: + void AddStrip(AddStripMessage& msg); + void SendBehaviorListToClient(AMFArrayValue& args); +// private: + + // The states this behavior has. std::map m_States; + + // The name of this behavior. + std::string m_Name = "Test name new"; + + // Whether this behavior is locked and cannot be edited. + bool isLocked = false; + + // Whether this behavior is custom or pre-fab. + bool isLoot = false; }; /** @@ -81,6 +87,24 @@ class ModelComponent : public Component { */ void SetRotation(const NiQuaternion& rot) { m_OriginalRotation = rot; } + void HandleControlBehaviorsMsg(AddStripMessage& msg); + + // Updates the pending behavior ID to the new ID. + void UpdatePendingBehaviorId(const int32_t newId); + + // Sends the behavior list to the client. + + /** + * The behaviors AMFArray will have up to 5 elements in the dense portion. + * Each element in the dense portion will be made up of another AMFArray + * with the following information mapped in the associative portion + * "id": Behavior ID cast to an AMFString + * "isLocked": AMFTrue or AMFFalse of whether or not the behavior is locked + * "isLoot": AMFTrue or AMFFalse of whether or not the behavior is a custom behavior (true if custom) + * "name": The name of the behavior formatted as an AMFString + */ + void SendBehaviorListToClient(AMFArrayValue& args); + std::map m_Behaviors; private: diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index f10a1b7e5..115817727 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -33,6 +33,10 @@ void ControlBehaviors::RequestUpdatedID(ControlBehaviorContext& context) { ObjectIDManager::Instance()->RequestPersistentID( [context](uint32_t persistentId) { + if (!context) { + LOG("Model to update behavior ID for is null. Cannot update ID."); + return; + } // This updates the behavior ID of the behavior should this be a new behavior AMFArrayValue args; @@ -40,35 +44,17 @@ void ControlBehaviors::RequestUpdatedID(ControlBehaviorContext& context) { args.Insert("objectID", std::to_string(context.modelComponent->GetParent()->GetObjectID())); GameMessages::SendUIMessageServerToSingleClient(context.modelOwner, context.modelOwner->GetSystemAddress(), "UpdateBehaviorID", args); - context.modelComponent->m_Behaviors[persistentId] = context.modelComponent->m_Behaviors[BehaviorMessageBase::DefaultBehaviorId]; - context.modelComponent->m_Behaviors.erase(BehaviorMessageBase::DefaultBehaviorId); + context.modelComponent->UpdatePendingBehaviorId(persistentId); ControlBehaviors::Instance().SendBehaviorListToClient(context); }); } void ControlBehaviors::SendBehaviorListToClient(const ControlBehaviorContext& context) { - AMFArrayValue behaviorsToSerialize; + if (!context) return; - /** - * The behaviors AMFArray will have up to 5 elements in the dense portion. - * Each element in the dense portion will be made up of another AMFArray - * with the following information mapped in the associative portion - * "id": Behavior ID cast to an AMFString - * "isLocked": AMFTrue or AMFFalse of whether or not the behavior is locked - * "isLoot": AMFTrue or AMFFalse of whether or not the behavior is a custom behavior (true if custom) - * "name": The name of the behavior formatted as an AMFString - */ - - int32_t index = 0; - auto behaviors = behaviorsToSerialize.InsertArray("behaviors"); - for (const auto& [id, behaviorInfo] : context.modelComponent->m_Behaviors) { - auto* array = behaviors->InsertArray(index++); - array->Insert("id", std::to_string(id)); - array->Insert("name", "Test name"); - array->Insert("isLoot", false); - } - behaviorsToSerialize.Insert("objectID", std::to_string(context.modelComponent->GetParent()->GetObjectID())); + AMFArrayValue behaviorsToSerialize; + context.modelComponent->SendBehaviorListToClient(behaviorsToSerialize); GameMessages::SendUIMessageServerToSingleClient(context.modelOwner, context.modelOwner->GetSystemAddress(), "UpdateBehaviorList", behaviorsToSerialize); } @@ -93,7 +79,7 @@ void ControlBehaviors::AddStrip(ControlBehaviorContext& context) { RequestUpdatedID(context); } - context.modelComponent->m_Behaviors[addStripMessage.GetBehaviorId()].AddStrip(addStripMessage); + context.modelComponent->HandleControlBehaviorsMsg(addStripMessage); } void ControlBehaviors::RemoveStrip(AMFArrayValue* arguments) { diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index fcadf96ee..80f1625e6 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -19,6 +19,11 @@ typedef std::string BlockName; //! A block name struct ControlBehaviorContext { ControlBehaviorContext(AMFArrayValue* args, ModelComponent* modelComponent, Entity* modelOwner) : arguments(args), modelComponent(modelComponent), modelOwner(modelOwner) {}; + + operator bool() const { + return arguments != nullptr && modelComponent != nullptr && modelOwner != nullptr; + } + AMFArrayValue* arguments; Entity* modelOwner; ModelComponent* modelComponent; From 37318362c322755881dbf6464921903b4c3b1e77 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 27 Dec 2023 05:10:25 -0800 Subject: [PATCH 04/24] Organize serialization Section off into operational chunks Write data at the level most appropriate --- dGame/dComponents/ModelComponent.cpp | 36 +++++++++++++++++++ dGame/dComponents/ModelComponent.h | 14 +++++--- .../ControlBehaviorMessages/Action.cpp | 14 ++++++++ .../ControlBehaviorMessages/Action.h | 2 ++ .../StripUiPosition.cpp | 6 ++++ .../ControlBehaviorMessages/StripUiPosition.h | 1 + dGame/dPropertyBehaviors/ControlBehaviors.cpp | 33 ++--------------- 7 files changed, 71 insertions(+), 35 deletions(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 0284530d0..98510b5f9 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -9,6 +9,15 @@ void Strip::AddStrip(AddStripMessage& msg) { m_Position = msg.GetPosition(); }; +void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) { + m_Position.SendBehaviorBlocksToClient(args); + + auto* actions = args.InsertArray("actions"); + for (auto& action : m_Actions) { + action.SendBehaviorBlocksToClient(*actions); + } +} + void State::AddStrip(AddStripMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { m_Strips.resize(msg.GetActionContext().GetStripId() + 1); @@ -16,6 +25,18 @@ void State::AddStrip(AddStripMessage& msg) { m_Strips[msg.GetActionContext().GetStripId()].AddStrip(msg); }; +void State::SendBehaviorBlocksToClient(AMFArrayValue& args) { + auto* strips = args.InsertArray("strips"); + for (int32_t stripId = 0; stripId < m_Strips.size(); stripId++) { + auto& strip = m_Strips.at(stripId); + + auto* stripArgs = strips->PushArray(); + stripArgs->Insert("id", static_cast(stripId)); + + strip.SendBehaviorBlocksToClient(*stripArgs); + } +}; + void PropertyBehavior::AddStrip(AddStripMessage& msg) { m_States[msg.GetActionContext().GetStateId()].AddStrip(msg); }; @@ -26,6 +47,15 @@ void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { args.Insert("isLoot", isLoot); } +void PropertyBehavior::SendBehaviorBlocksToClient(AMFArrayValue& args) { + auto* stateArray = args.InsertArray("states"); + for (auto&[stateId, state] : m_States) { + auto* stateArgs = stateArray->PushArray(); + stateArgs->Insert("id", static_cast(stateId)); + state.SendBehaviorBlocksToClient(*stateArgs); + } +} + ModelComponent::ModelComponent(Entity* parent) : Component(parent) { m_OriginalPosition = m_Parent->GetDefaultPosition(); m_OriginalRotation = m_Parent->GetDefaultRotation(); @@ -74,3 +104,9 @@ void ModelComponent::SendBehaviorListToClient(AMFArrayValue& args) { behavior.SendBehaviorListToClient(*behaviorArgs); } } + +void ModelComponent::SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) { + args.Insert("BehaviorID", std::to_string(behaviorToSend)); + args.Insert("objectID", std::to_string(m_Parent->GetObjectID())); + m_Behaviors[behaviorToSend].SendBehaviorBlocksToClient(args); +} diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index f3145257c..2452946de 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -21,7 +21,9 @@ class AddStripMessage; class Strip { public: void AddStrip(AddStripMessage& msg); -// private: + void SendBehaviorBlocksToClient(AMFArrayValue& args); + StripUiPosition GetPosition() { return m_Position; } +private: std::vector m_Actions; StripUiPosition m_Position; }; @@ -29,7 +31,8 @@ class Strip { class State { public: void AddStrip(AddStripMessage& msg); -// private: + void SendBehaviorBlocksToClient(AMFArrayValue& args); +private: std::vector m_Strips; }; @@ -37,7 +40,8 @@ class PropertyBehavior { public: void AddStrip(AddStripMessage& msg); void SendBehaviorListToClient(AMFArrayValue& args); -// private: + void SendBehaviorBlocksToClient(AMFArrayValue& args); +private: // The states this behavior has. std::map m_States; @@ -105,8 +109,10 @@ class ModelComponent : public Component { */ void SendBehaviorListToClient(AMFArrayValue& args); - std::map m_Behaviors; + void SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args); + private: + std::map m_Behaviors; /** * The original position of the model diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp index 175412e12..0be60dfef 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp @@ -29,3 +29,17 @@ Action::Action(AMFArrayValue* arguments) { } } } + +void Action::SendBehaviorBlocksToClient(AMFArrayValue& args) { + auto* actionArgs = args.PushArray(); + actionArgs->Insert("Type", type); + + auto valueParameterName = GetValueParameterName(); + if (valueParameterName.empty()) return; + + if (valueParameterName == "Message") { + actionArgs->Insert(valueParameterName, valueParameterString); + } else { + actionArgs->Insert(valueParameterName, valueParameterDouble); + } +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h index c97b4050b..ff65370a4 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h @@ -15,6 +15,8 @@ class Action { const std::string& GetValueParameterName() { return valueParameterName; }; const std::string& GetValueParameterString() { return valueParameterString; }; const double GetValueParameterDouble() { return valueParameterDouble; }; + + void SendBehaviorBlocksToClient(AMFArrayValue& args); private: std::string type; std::string valueParameterName; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp index de612b452..b0834fef3 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp @@ -20,3 +20,9 @@ StripUiPosition::StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName yPosition = yPositionValue->GetValue(); xPosition = xPositionValue->GetValue(); } + +void StripUiPosition::SendBehaviorBlocksToClient(AMFArrayValue& args) { + auto uiArgs = args.InsertArray("ui"); + uiArgs->Insert("x", xPosition); + uiArgs->Insert("y", yPosition); +} diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h index 809f88909..eb03fa396 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h @@ -11,6 +11,7 @@ class StripUiPosition { public: StripUiPosition(); StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName = "ui"); + void SendBehaviorBlocksToClient(AMFArrayValue& args); double GetX() { return xPosition; }; double GetY() { return yPosition; }; private: diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 115817727..d2a58caff 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -124,40 +124,11 @@ void ControlBehaviors::Rename(Entity* modelEntity, const SystemAddress& sysAddr, // 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); AMFArrayValue behavior; - behavior.Insert("BehaviorID", std::to_string(behaviorMsg.GetBehaviorId())); - behavior.Insert("objectID", std::to_string(context.modelComponent->GetParent()->GetObjectID())); - auto* stateArray = behavior.InsertArray("states"); - for (const auto& [stateId, state] : context.modelComponent->m_Behaviors[behaviorMsg.GetBehaviorId()].m_States) { - auto* stateInfo = stateArray->PushArray(); - stateInfo->Insert("id", static_cast(stateId)); - - auto* stripArray = stateInfo->InsertArray("strips"); - for (int32_t stripId = 0; stripId < state.m_Strips.size(); stripId++) { - auto strip = state.m_Strips.at(stripId); - - auto* stripInfo = stripArray->InsertArray(stripId); - stripInfo->Insert("id", static_cast(stripId)); - auto* uiInfo = stripInfo->InsertArray("ui"); - uiInfo->Insert("x", strip.m_Position.GetX()); - uiInfo->Insert("y", strip.m_Position.GetY()); - - auto* actions = stripInfo->InsertArray("actions"); - for (int32_t i = 0; i < strip.m_Actions.size(); i++) { - auto action = strip.m_Actions.at(i); - auto* actionInfo = actions->InsertArray(i); - actionInfo->Insert("Type", action.GetType()); - if (action.GetValueParameterName() == "Message") { - actionInfo->Insert(action.GetValueParameterName(), action.GetValueParameterString()); - } else if (!action.GetValueParameterName().empty()) { - actionInfo->Insert(action.GetValueParameterName(), action.GetValueParameterDouble()); - } - } - } - } - + context.modelComponent->SendBehaviorBlocksToClient(behaviorMsg.GetBehaviorId(), behavior); GameMessages::SendUIMessageServerToSingleClient(context.modelOwner, context.modelOwner->GetSystemAddress(), "UpdateBehaviorBlocks", behavior); } From b60582ab0f1bf998421a15594ec0b13b916d934e Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 27 Dec 2023 05:21:08 -0800 Subject: [PATCH 05/24] Remove and simplify BlockDefinitions Remove pointer usage for BlockDefinitions and move to optional. --- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 33 +++++++++---------- dGame/dPropertyBehaviors/ControlBehaviors.h | 7 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index d2a58caff..c6c58cede 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -134,7 +134,7 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ControlBehaviorContext& contex void ControlBehaviors::UpdateAction(AMFArrayValue* arguments) { UpdateActionMessage updateActionMessage(arguments); - auto* blockDefinition = GetBlockInfo(updateActionMessage.GetAction().GetType()); + auto blockDefinition = GetBlockInfo(updateActionMessage.GetAction().GetType()); if (!blockDefinition) { LOG("Received undefined block type %s. Ignoring.", updateActionMessage.GetAction().GetType().c_str()); @@ -219,7 +219,7 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& ControlBehaviors::ControlBehaviors() { auto blocksBuffer = Game::assetManager->GetFile("ui\\ingame\\blocksdef.xml"); if (!blocksBuffer) { - LOG("Failed to open blocksdef.xml"); + LOG("Failed to open blocksdef.xml, property behaviors will be disabled for this zone!"); return; } @@ -264,14 +264,14 @@ ControlBehaviors::ControlBehaviors() { while (block) { blockName = block->Name(); - BlockDefinition* blockDefinition = new BlockDefinition(); + auto& blockDefinition = blockTypes[blockName]; std::string name{}; std::string typeName{}; auto* argument = block->FirstChildElement("Argument"); if (argument) { auto* defaultDefinition = argument->FirstChildElement("DefaultValue"); - if (defaultDefinition) blockDefinition->SetDefaultValue(defaultDefinition->GetText()); + if (defaultDefinition) blockDefinition.SetDefaultValue(defaultDefinition->GetText()); auto* typeDefinition = argument->FirstChildElement("Type"); if (typeDefinition) typeName = typeDefinition->GetText(); @@ -281,23 +281,23 @@ ControlBehaviors::ControlBehaviors() { // Now we parse the blocksdef file for the relevant information if (typeName == "String") { - blockDefinition->SetMaximumValue(50); // The client has a hardcoded limit of 50 characters in a string field + blockDefinition.SetMaximumValue(50); // The client has a hardcoded limit of 50 characters in a string field } else if (typeName == "Float" || typeName == "Integer") { auto* maximumDefinition = argument->FirstChildElement("Maximum"); - if (maximumDefinition) blockDefinition->SetMaximumValue(std::stof(maximumDefinition->GetText())); + if (maximumDefinition) blockDefinition.SetMaximumValue(std::stof(maximumDefinition->GetText())); auto* minimumDefinition = argument->FirstChildElement("Minimum"); - if (minimumDefinition) blockDefinition->SetMinimumValue(std::stof(minimumDefinition->GetText())); + if (minimumDefinition) blockDefinition.SetMinimumValue(std::stof(minimumDefinition->GetText())); } else if (typeName == "Enumeration") { auto* values = argument->FirstChildElement("Values"); if (values) { auto* value = values->FirstChildElement("Value"); while (value) { - if (value->GetText() == blockDefinition->GetDefaultValue()) blockDefinition->GetDefaultValue() = std::to_string(blockDefinition->GetMaximumValue()); - blockDefinition->SetMaximumValue(blockDefinition->GetMaximumValue() + 1); + if (value->GetText() == blockDefinition.GetDefaultValue()) blockDefinition.GetDefaultValue() = std::to_string(blockDefinition.GetMaximumValue()); + blockDefinition.SetMaximumValue(blockDefinition.GetMaximumValue() + 1); value = value->NextSiblingElement("Value"); } - blockDefinition->SetMaximumValue(blockDefinition->GetMaximumValue() - 1); // Maximum value is 0 indexed + blockDefinition.SetMaximumValue(blockDefinition.GetMaximumValue() - 1); // Maximum value is 0 indexed } else { values = argument->FirstChildElement("EnumerationSource"); if (!values) { @@ -314,8 +314,8 @@ ControlBehaviors::ControlBehaviors() { std::string serviceName = serviceNameNode->GetText(); if (serviceName == "GetBehaviorSoundList") { auto res = CDClientDatabase::ExecuteQuery("SELECT MAX(id) as countSounds FROM UGBehaviorSounds;"); - blockDefinition->SetMaximumValue(res.getIntField("countSounds")); - blockDefinition->SetDefaultValue("0"); + blockDefinition.SetMaximumValue(res.getIntField("countSounds")); + blockDefinition.SetDefaultValue("0"); } else { LOG("Unsupported Enumeration ServiceType (%s)", serviceName.c_str()); continue; @@ -326,19 +326,18 @@ ControlBehaviors::ControlBehaviors() { continue; } } - blockTypes.insert(std::make_pair(blockName, blockDefinition)); block = block->NextSiblingElement(); } blockSections = blockSections->NextSiblingElement(); } isInitialized = true; LOG_DEBUG("Created all base block classes"); - for (auto b : blockTypes) { - LOG_DEBUG("block name is %s default %s min %f max %f", b.first.c_str(), b.second->GetDefaultValue().c_str(), b.second->GetMinimumValue(), b.second->GetMaximumValue()); + for (auto&[name, block] : blockTypes) { + LOG_DEBUG("block name is %s default %s min %f max %f", name.c_str(), block.GetDefaultValue().c_str(), block.GetMinimumValue(), block.GetMaximumValue()); } } -BlockDefinition* ControlBehaviors::GetBlockInfo(const BlockName& blockName) { +std::optional ControlBehaviors::GetBlockInfo(const BlockName& blockName) { auto blockDefinition = blockTypes.find(blockName); - return blockDefinition != blockTypes.end() ? blockDefinition->second : nullptr; + return blockDefinition != blockTypes.end() ? std::optional(blockDefinition->second) : std::nullopt; } diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index 80f1625e6..4dbc58dc7 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -4,12 +4,13 @@ #define __CONTROLBEHAVIORS__H__ #include +#include #include +#include "BlockDefinition.h" #include "Singleton.h" class AMFArrayValue; -class BlockDefinition; class Entity; class ModelComponent; class SystemAddress; @@ -51,7 +52,7 @@ class ControlBehaviors: public Singleton { * * @return A pair of the block parameter name to its typing */ - BlockDefinition* GetBlockInfo(const BlockName& blockName); + std::optional GetBlockInfo(const BlockName& blockName); private: void RequestUpdatedID(ControlBehaviorContext& context); void SendBehaviorListToClient(const ControlBehaviorContext& context); @@ -71,7 +72,7 @@ class ControlBehaviors: public Singleton { void SendBehaviorBlocksToClient(ControlBehaviorContext& context); void UpdateAction(AMFArrayValue* arguments); void MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments); - std::map blockTypes{}; + std::map blockTypes{}; // If false, property behaviors will not be able to be edited. bool isInitialized = false; From c416fcd7f33b99736075faffdc5ca85d976427f5 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 28 Dec 2023 00:36:40 -0800 Subject: [PATCH 06/24] ControlBehaviors: Add addaction handling --- dGame/Character.cpp | 2 +- .../ControllablePhysicsComponent.cpp | 2 +- dGame/dComponents/ModelComponent.cpp | 28 +++++++++++++++++++ dGame/dComponents/ModelComponent.h | 8 ++++-- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 9 ++++-- dGame/dPropertyBehaviors/ControlBehaviors.h | 2 +- 6 files changed, 43 insertions(+), 8 deletions(-) diff --git a/dGame/Character.cpp b/dGame/Character.cpp index ee04710a6..e6d1d03ad 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -251,7 +251,7 @@ void Character::SaveXMLToDatabase() { auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID(); // lzid garbage, binary concat of zoneID, zoneInstance and zoneClone - if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0 && !Game::zoneManager->GetDisableSaveLocation()) { + if (zoneInfo.GetMapID() != 0) { uint64_t lzidConcat = zoneInfo.GetCloneID(); lzidConcat = (lzidConcat << 16) | uint16_t(zoneInfo.GetInstanceID()); lzidConcat = (lzidConcat << 16) | uint16_t(zoneInfo.GetMapID()); diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index dd981f660..cd3498d70 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -187,7 +187,7 @@ void ControllablePhysicsComponent::UpdateXml(tinyxml2::XMLDocument* doc) { auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID(); - if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0 && !Game::zoneManager->GetDisableSaveLocation()) { + if (zoneInfo.GetMapID() != 0) { character->SetAttribute("lzx", m_Position.x); character->SetAttribute("lzy", m_Position.y); character->SetAttribute("lzz", m_Position.z); diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 98510b5f9..07704d07f 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -1,6 +1,12 @@ #include "ModelComponent.h" #include "Entity.h" +#include "Game.h" +#include "Logger.h" + +#include "AddStripMessage.h" +#include "AddActionMessage.h" + void Strip::AddStrip(AddStripMessage& msg) { m_Actions = msg.GetActionsToAdd(); for (auto& action : m_Actions) { @@ -9,6 +15,10 @@ void Strip::AddStrip(AddStripMessage& msg) { m_Position = msg.GetPosition(); }; +void Strip::AddAction(AddActionMessage& msg) { + m_Actions.insert(m_Actions.begin() + msg.GetActionIndex(), msg.GetAction()); +}; + void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) { m_Position.SendBehaviorBlocksToClient(args); @@ -25,6 +35,14 @@ void State::AddStrip(AddStripMessage& msg) { m_Strips[msg.GetActionContext().GetStripId()].AddStrip(msg); }; +void State::AddAction(AddActionMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips[msg.GetActionContext().GetStripId()].AddAction(msg); +}; + void State::SendBehaviorBlocksToClient(AMFArrayValue& args) { auto* strips = args.InsertArray("strips"); for (int32_t stripId = 0; stripId < m_Strips.size(); stripId++) { @@ -41,6 +59,10 @@ void PropertyBehavior::AddStrip(AddStripMessage& msg) { m_States[msg.GetActionContext().GetStateId()].AddStrip(msg); }; +void PropertyBehavior::AddAction(AddActionMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].AddAction(msg); +}; + void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { args.Insert("name", m_Name); args.Insert("isLocked", isLocked); @@ -56,6 +78,8 @@ void PropertyBehavior::SendBehaviorBlocksToClient(AMFArrayValue& args) { } } +//////////////////////// ModelComponent //////////////////////// + ModelComponent::ModelComponent(Entity* parent) : Component(parent) { m_OriginalPosition = m_Parent->GetDefaultPosition(); m_OriginalRotation = m_Parent->GetDefaultRotation(); @@ -89,6 +113,10 @@ void ModelComponent::HandleControlBehaviorsMsg(AddStripMessage& msg) { m_Behaviors[msg.GetBehaviorId()].AddStrip(msg); } +void ModelComponent::HandleControlBehaviorsMsg(AddActionMessage& msg) { + m_Behaviors[msg.GetBehaviorId()].AddAction(msg); +} + void ModelComponent::UpdatePendingBehaviorId(const int32_t newId) { m_Behaviors[newId] = m_Behaviors[BehaviorMessageBase::DefaultBehaviorId]; m_Behaviors.erase(BehaviorMessageBase::DefaultBehaviorId); diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 2452946de..5716ad7f2 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -11,16 +11,17 @@ #include "Amf3.h" #include "BehaviorStates.h" -#include "AddStripMessage.h" +#include "StripUiPosition.h" #include "Action.h" -class Action; class Entity; class AddStripMessage; +class AddActionMessage; class Strip { public: void AddStrip(AddStripMessage& msg); + void AddAction(AddActionMessage& msg); void SendBehaviorBlocksToClient(AMFArrayValue& args); StripUiPosition GetPosition() { return m_Position; } private: @@ -31,6 +32,7 @@ class Strip { class State { public: void AddStrip(AddStripMessage& msg); + void AddAction(AddActionMessage& msg); void SendBehaviorBlocksToClient(AMFArrayValue& args); private: std::vector m_Strips; @@ -39,6 +41,7 @@ class State { class PropertyBehavior { public: void AddStrip(AddStripMessage& msg); + void AddAction(AddActionMessage& msg); void SendBehaviorListToClient(AMFArrayValue& args); void SendBehaviorBlocksToClient(AMFArrayValue& args); private: @@ -92,6 +95,7 @@ class ModelComponent : public Component { void SetRotation(const NiQuaternion& rot) { m_OriginalRotation = rot; } void HandleControlBehaviorsMsg(AddStripMessage& msg); + void HandleControlBehaviorsMsg(AddActionMessage& msg); // Updates the pending behavior ID to the new ID. void UpdatePendingBehaviorId(const int32_t newId); diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index c6c58cede..6c2010435 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -98,8 +98,11 @@ void ControlBehaviors::UpdateStripUI(AMFArrayValue* arguments) { UpdateStripUiMessage updateStripUiMessage(arguments); } -void ControlBehaviors::AddAction(AMFArrayValue* arguments) { - AddActionMessage addActionMessage(arguments); +void ControlBehaviors::AddAction(ControlBehaviorContext& context) { + if (!context) return; + AddActionMessage addActionMessage(context.arguments); + + context.modelComponent->HandleControlBehaviorsMsg(addActionMessage); } void ControlBehaviors::MigrateActions(AMFArrayValue* arguments) { @@ -194,7 +197,7 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "updateStripUI") { UpdateStripUI(arguments); } else if (command == "addAction") { - AddAction(arguments); + AddAction(context); } else if (command == "migrateActions") { MigrateActions(arguments); } else if (command == "rearrangeStrip") { diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index 4dbc58dc7..690724f67 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -63,7 +63,7 @@ class ControlBehaviors: public Singleton { void MergeStrips(AMFArrayValue* arguments); void SplitStrip(AMFArrayValue* arguments); void UpdateStripUI(AMFArrayValue* arguments); - void AddAction(AMFArrayValue* arguments); + void AddAction(ControlBehaviorContext& context); void MigrateActions(AMFArrayValue* arguments); void RearrangeStrip(AMFArrayValue* arguments); void Add(AMFArrayValue* arguments); From b2c7a1b3211c24974d18bfd7c787028f890768d8 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 28 Dec 2023 01:17:12 -0800 Subject: [PATCH 07/24] re-organization remove const from return value change to int from uint use generic methods to reduce code clutter --- dGame/dComponents/ModelComponent.cpp | 50 +++++++++++-------- dGame/dComponents/ModelComponent.h | 25 +++++++--- .../AddActionMessage.h | 2 +- .../BehaviorMessageBase.cpp | 4 +- .../BehaviorMessageBase.h | 5 +- .../ControlBehaviorMsgs.h | 23 +++++++++ .../MergeStripsMessage.h | 4 +- .../MigrateActionsMessage.h | 8 +-- .../RearrangeStripMessage.h | 8 +-- .../RemoveActionsMessage.h | 4 +- .../SplitStripMessage.h | 4 +- .../UpdateActionMessage.h | 4 +- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 15 ++---- dGame/dPropertyBehaviors/ControlBehaviors.h | 1 - 14 files changed, 92 insertions(+), 65 deletions(-) create mode 100644 dGame/dPropertyBehaviors/ControlBehaviorMessages/ControlBehaviorMsgs.h diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 07704d07f..e12788eb7 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -4,20 +4,26 @@ #include "Game.h" #include "Logger.h" -#include "AddStripMessage.h" -#include "AddActionMessage.h" +#include "ControlBehaviorMsgs.h" -void Strip::AddStrip(AddStripMessage& msg) { +///////////////// Strip /////////////////// + +template<> +void Strip::HandleMsg(AddStripMessage& msg) { m_Actions = msg.GetActionsToAdd(); for (auto& action : m_Actions) { LOG("%s %s %f %s", action.GetType().c_str(), action.GetValueParameterName().c_str(), (float)action.GetValueParameterDouble(), action.GetValueParameterString().c_str()); } + m_Position = msg.GetPosition(); }; -void Strip::AddAction(AddActionMessage& msg) { +template<> +void Strip::HandleMsg(AddActionMessage& msg) { + if (msg.GetActionIndex() == -1) return; + m_Actions.insert(m_Actions.begin() + msg.GetActionIndex(), msg.GetAction()); -}; +} void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) { m_Position.SendBehaviorBlocksToClient(args); @@ -26,21 +32,25 @@ void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) { for (auto& action : m_Actions) { action.SendBehaviorBlocksToClient(*actions); } -} +}; -void State::AddStrip(AddStripMessage& msg) { +///////////////// State /////////////////// + +template<> +void State::HandleMsg(AddStripMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { m_Strips.resize(msg.GetActionContext().GetStripId() + 1); } - m_Strips[msg.GetActionContext().GetStripId()].AddStrip(msg); + m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); }; -void State::AddAction(AddActionMessage& msg) { +template<> +void State::HandleMsg(AddActionMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { return; } - m_Strips[msg.GetActionContext().GetStripId()].AddAction(msg); + m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); }; void State::SendBehaviorBlocksToClient(AMFArrayValue& args) { @@ -55,12 +65,16 @@ void State::SendBehaviorBlocksToClient(AMFArrayValue& args) { } }; -void PropertyBehavior::AddStrip(AddStripMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].AddStrip(msg); +///////////////// PropertyBehavior /////////////////// + +template<> +void PropertyBehavior::HandleMsg(AddStripMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); }; -void PropertyBehavior::AddAction(AddActionMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].AddAction(msg); +template<> +void PropertyBehavior::HandleMsg(AddActionMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); }; void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { @@ -109,14 +123,6 @@ void ModelComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialU if (bIsInitialUpdate) outBitStream->Write0(); // We are not writing model editing info } -void ModelComponent::HandleControlBehaviorsMsg(AddStripMessage& msg) { - m_Behaviors[msg.GetBehaviorId()].AddStrip(msg); -} - -void ModelComponent::HandleControlBehaviorsMsg(AddActionMessage& msg) { - m_Behaviors[msg.GetBehaviorId()].AddAction(msg); -} - void ModelComponent::UpdatePendingBehaviorId(const int32_t newId) { m_Behaviors[newId] = m_Behaviors[BehaviorMessageBase::DefaultBehaviorId]; m_Behaviors.erase(BehaviorMessageBase::DefaultBehaviorId); diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 5716ad7f2..7282ed6cd 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -10,6 +10,8 @@ #include "eReplicaComponentType.h" #include "Amf3.h" +#include "BehaviorMessageBase.h" + #include "BehaviorStates.h" #include "StripUiPosition.h" #include "Action.h" @@ -20,8 +22,9 @@ class AddActionMessage; class Strip { public: - void AddStrip(AddStripMessage& msg); - void AddAction(AddActionMessage& msg); + template + void HandleMsg(Msg& msg); + void SendBehaviorBlocksToClient(AMFArrayValue& args); StripUiPosition GetPosition() { return m_Position; } private: @@ -31,8 +34,9 @@ class Strip { class State { public: - void AddStrip(AddStripMessage& msg); - void AddAction(AddActionMessage& msg); + template + void HandleMsg(Msg& msg); + void SendBehaviorBlocksToClient(AMFArrayValue& args); private: std::vector m_Strips; @@ -40,8 +44,9 @@ class State { class PropertyBehavior { public: - void AddStrip(AddStripMessage& msg); - void AddAction(AddActionMessage& msg); + template + void HandleMsg(Msg& msg); + void SendBehaviorListToClient(AMFArrayValue& args); void SendBehaviorBlocksToClient(AMFArrayValue& args); private: @@ -94,8 +99,12 @@ class ModelComponent : public Component { */ void SetRotation(const NiQuaternion& rot) { m_OriginalRotation = rot; } - void HandleControlBehaviorsMsg(AddStripMessage& msg); - void HandleControlBehaviorsMsg(AddActionMessage& msg); + template + void HandleControlBehaviorsMsg(AMFArrayValue* args) { + static_assert(std::is_base_of_v, "Msg must be a BehaviorMessageBase"); + Msg msg(args); + m_Behaviors[msg.GetBehaviorId()].HandleMsg(msg); + }; // Updates the pending behavior ID to the new ID. void UpdatePendingBehaviorId(const int32_t newId); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h index 4faf6a53e..b5a6e6a67 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h @@ -18,7 +18,7 @@ class AddActionMessage : public BehaviorMessageBase { Action GetAction() { return action; }; ActionContext GetActionContext() { return actionContext; }; private: - uint32_t actionIndex; + int32_t actionIndex = -1; ActionContext actionContext; Action action; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp index 79cc7c260..cc817cd71 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.cpp @@ -21,11 +21,11 @@ int32_t BehaviorMessageBase::GetBehaviorIdFromArgument(AMFArrayValue* arguments) return behaviorId; } -uint32_t BehaviorMessageBase::GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName) { +int32_t BehaviorMessageBase::GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName) { auto* actionIndexAmf = arguments->Get(keyName); if (!actionIndexAmf) { throw std::invalid_argument("Unable to find actionIndex"); } - return static_cast(actionIndexAmf->GetValue()); + return static_cast(actionIndexAmf->GetValue()); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h index 00bcc1fcd..ff66861f9 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h @@ -7,9 +7,6 @@ #include "Amf3.h" #include "dCommonVars.h" -#include "Game.h" -#include "Logger.h" - enum class BehaviorState : uint32_t; /** @@ -24,7 +21,7 @@ class BehaviorMessageBase { BehaviorMessageBase(AMFArrayValue* arguments); protected: int32_t GetBehaviorIdFromArgument(AMFArrayValue* arguments); - uint32_t GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName = "actionIndex"); + int32_t GetActionIndexFromArgument(AMFArrayValue* arguments, const std::string& keyName = "actionIndex"); int32_t behaviorId = DefaultBehaviorId; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ControlBehaviorMsgs.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ControlBehaviorMsgs.h new file mode 100644 index 000000000..0e17060bc --- /dev/null +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ControlBehaviorMsgs.h @@ -0,0 +1,23 @@ +#ifndef __CONTROLBEHAVIORMSGS__H__ +#define __CONTROLBEHAVIORMSGS__H__ + +#include "Action.h" +#include "ActionContext.h" +#include "AddActionMessage.h" +#include "AddMessage.h" +#include "AddStripMessage.h" +#include "BehaviorMessageBase.h" +#include "ControlBehaviorMsgs.h" +#include "MergeStripsMessage.h" +#include "MigrateActionsMessage.h" +#include "MoveToInventoryMessage.h" +#include "RearrangeStripMessage.h" +#include "RemoveActionsMessage.h" +#include "RemoveStripMessage.h" +#include "RenameMessage.h" +#include "SplitStripMessage.h" +#include "StripUiPosition.h" +#include "UpdateActionMessage.h" +#include "UpdateStripUiMessage.h" + +#endif //!__CONTROLBEHAVIORMSGS__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h index 0aff7f3ab..61f047b1f 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h @@ -13,13 +13,13 @@ class AMFArrayValue; class MergeStripsMessage : public BehaviorMessageBase { public: MergeStripsMessage(AMFArrayValue* arguments); - const uint32_t GetDstActionIndex() { return dstActionIndex; }; + int32_t GetDstActionIndex() { return dstActionIndex; }; ActionContext GetSourceActionContext() { return sourceActionContext; }; ActionContext GetDestinationActionContext() { return destinationActionContext; }; private: ActionContext sourceActionContext; ActionContext destinationActionContext; - uint32_t dstActionIndex; + int32_t dstActionIndex; }; #endif //!__MERGESTRIPSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h index f60e8748a..d4b4e58ba 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h @@ -13,15 +13,15 @@ class AMFArrayValue; class MigrateActionsMessage : public BehaviorMessageBase { public: MigrateActionsMessage(AMFArrayValue* arguments); - const uint32_t GetSrcActionIndex() { return srcActionIndex; }; - const uint32_t GetDstActionIndex() { return dstActionIndex; }; + int32_t GetSrcActionIndex() { return srcActionIndex; }; + int32_t GetDstActionIndex() { return dstActionIndex; }; ActionContext GetSourceActionContext() { return sourceActionContext; }; ActionContext GetDestinationActionContext() { return destinationActionContext; }; private: ActionContext sourceActionContext; ActionContext destinationActionContext; - uint32_t srcActionIndex; - uint32_t dstActionIndex; + int32_t srcActionIndex; + int32_t dstActionIndex; }; #endif //!__MIGRATEACTIONSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h index 46819404a..3b1329677 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h @@ -11,13 +11,13 @@ class RearrangeStripMessage : public BehaviorMessageBase { public: RearrangeStripMessage(AMFArrayValue* arguments); - const uint32_t GetSrcActionIndex() { return srcActionIndex; }; - const uint32_t GetDstActionIndex() { return dstActionIndex; }; + int32_t GetSrcActionIndex() { return srcActionIndex; }; + int32_t GetDstActionIndex() { return dstActionIndex; }; ActionContext GetActionContext() { return actionContext; }; private: ActionContext actionContext; - uint32_t srcActionIndex; - uint32_t dstActionIndex; + int32_t srcActionIndex; + int32_t dstActionIndex; }; #endif //!__REARRANGESTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h index 457ddba80..ee90fe56f 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h @@ -13,11 +13,11 @@ class AMFArrayValue; class RemoveActionsMessage : public BehaviorMessageBase { public: RemoveActionsMessage(AMFArrayValue* arguments); - const uint32_t GetActionIndex() { return actionIndex; }; + int32_t GetActionIndex() { return actionIndex; }; ActionContext GetActionContext() { return actionContext; }; private: ActionContext actionContext; - uint32_t actionIndex; + int32_t actionIndex; }; #endif //!__REMOVEACTIONSMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h index 9210efb0b..94e93d501 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h @@ -16,12 +16,12 @@ class SplitStripMessage : public BehaviorMessageBase { SplitStripMessage(AMFArrayValue* arguments); ActionContext GetSourceActionContext() { return sourceActionContext; }; ActionContext GetDestinationActionContext() { return destinationActionContext; }; - const uint32_t GetSrcActionIndex() { return srcActionIndex; }; + int32_t GetSrcActionIndex() { return srcActionIndex; }; StripUiPosition GetPosition() { return destinationPosition; }; private: ActionContext sourceActionContext; ActionContext destinationActionContext; - uint32_t srcActionIndex; + int32_t srcActionIndex; StripUiPosition destinationPosition; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h index 0a03ce9e4..1aa14c2cf 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h @@ -14,11 +14,11 @@ class AMFArrayValue; class UpdateActionMessage : public BehaviorMessageBase { public: UpdateActionMessage(AMFArrayValue* arguments); - const uint32_t GetActionIndex() { return actionIndex; }; + int32_t GetActionIndex() { return actionIndex; }; ActionContext GetActionContext() { return actionContext; }; Action GetAction() { return action; }; private: - uint32_t actionIndex; + int32_t actionIndex; ActionContext actionContext; Action action; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 6c2010435..58b59daab 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -73,13 +73,13 @@ void ControlBehaviors::ToggleExecutionUpdates() { } void ControlBehaviors::AddStrip(ControlBehaviorContext& context) { - AddStripMessage addStripMessage(context.arguments); + BehaviorMessageBase msgBase(context.arguments); - if (addStripMessage.IsDefaultBehaviorId()) { + if (msgBase.IsDefaultBehaviorId()) { RequestUpdatedID(context); } - context.modelComponent->HandleControlBehaviorsMsg(addStripMessage); + context.modelComponent->HandleControlBehaviorsMsg(context.arguments); } void ControlBehaviors::RemoveStrip(AMFArrayValue* arguments) { @@ -98,13 +98,6 @@ void ControlBehaviors::UpdateStripUI(AMFArrayValue* arguments) { UpdateStripUiMessage updateStripUiMessage(arguments); } -void ControlBehaviors::AddAction(ControlBehaviorContext& context) { - if (!context) return; - AddActionMessage addActionMessage(context.arguments); - - context.modelComponent->HandleControlBehaviorsMsg(addActionMessage); -} - void ControlBehaviors::MigrateActions(AMFArrayValue* arguments) { MigrateActionsMessage migrateActionsMessage(arguments); } @@ -197,7 +190,7 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "updateStripUI") { UpdateStripUI(arguments); } else if (command == "addAction") { - AddAction(context); + context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "migrateActions") { MigrateActions(arguments); } else if (command == "rearrangeStrip") { diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index 690724f67..f77588434 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -63,7 +63,6 @@ class ControlBehaviors: public Singleton { void MergeStrips(AMFArrayValue* arguments); void SplitStrip(AMFArrayValue* arguments); void UpdateStripUI(AMFArrayValue* arguments); - void AddAction(ControlBehaviorContext& context); void MigrateActions(AMFArrayValue* arguments); void RearrangeStrip(AMFArrayValue* arguments); void Add(AMFArrayValue* arguments); From 80615374beb73c358c9394ecb0965350af19f2c0 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 28 Dec 2023 01:21:28 -0800 Subject: [PATCH 08/24] add strip ui position handling --- dGame/dComponents/ModelComponent.cpp | 21 ++++++++++++++++++- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index e12788eb7..67d09b739 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -23,7 +23,12 @@ void Strip::HandleMsg(AddActionMessage& msg) { if (msg.GetActionIndex() == -1) return; m_Actions.insert(m_Actions.begin() + msg.GetActionIndex(), msg.GetAction()); -} +}; + +template<> +void Strip::HandleMsg(UpdateStripUiMessage& msg) { + m_Position = msg.GetPosition(); +}; void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) { m_Position.SendBehaviorBlocksToClient(args); @@ -53,6 +58,15 @@ void State::HandleMsg(AddActionMessage& msg) { m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); }; +template<> +void State::HandleMsg(UpdateStripUiMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); +}; + void State::SendBehaviorBlocksToClient(AMFArrayValue& args) { auto* strips = args.InsertArray("strips"); for (int32_t stripId = 0; stripId < m_Strips.size(); stripId++) { @@ -77,6 +91,11 @@ void PropertyBehavior::HandleMsg(AddActionMessage& msg) { m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); }; +template<> +void PropertyBehavior::HandleMsg(UpdateStripUiMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); +}; + void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { args.Insert("name", m_Name); args.Insert("isLocked", isLocked); diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 58b59daab..7a204ea73 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -188,7 +188,7 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "splitStrip") { SplitStrip(arguments); } else if (command == "updateStripUI") { - UpdateStripUI(arguments); + context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "addAction") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "migrateActions") { From 98ee7afa6bda5091a91b631e1a10293f165d6298 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 28 Dec 2023 02:09:47 -0800 Subject: [PATCH 09/24] add split strip functionality --- dGame/dComponents/ModelComponent.cpp | 37 ++++++++++++++++++- .../SplitStripMessage.h | 5 +++ dGame/dPropertyBehaviors/ControlBehaviors.cpp | 6 +-- dGame/dPropertyBehaviors/ControlBehaviors.h | 1 - 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 67d09b739..838bb25af 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -30,6 +30,18 @@ void Strip::HandleMsg(UpdateStripUiMessage& msg) { m_Position = msg.GetPosition(); }; +template<> +void Strip::HandleMsg(SplitStripMessage& msg) { + if (msg.GetTransferredActions().empty() && !m_Actions.empty()) { + auto startToMove = m_Actions.begin() + msg.GetSrcActionIndex(); + msg.SetTransferredActions(startToMove, m_Actions.end()); + m_Actions.erase(startToMove, m_Actions.end()); + } else { + m_Actions = msg.GetTransferredActions(); + m_Position = msg.GetPosition(); + } +}; + void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) { m_Position.SendBehaviorBlocksToClient(args); @@ -67,6 +79,23 @@ void State::HandleMsg(UpdateStripUiMessage& msg) { m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); }; +template<> +void State::HandleMsg(SplitStripMessage& msg) { + if (msg.GetTransferredActions().empty()) { + if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { + return; + } + + m_Strips[msg.GetSourceActionContext().GetStripId()].HandleMsg(msg); + } else { + if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { + m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); + } + + m_Strips[msg.GetDestinationActionContext().GetStripId()].HandleMsg(msg); + } +}; + void State::SendBehaviorBlocksToClient(AMFArrayValue& args) { auto* strips = args.InsertArray("strips"); for (int32_t stripId = 0; stripId < m_Strips.size(); stripId++) { @@ -96,6 +125,12 @@ void PropertyBehavior::HandleMsg(UpdateStripUiMessage& msg) { m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); }; +template<> +void PropertyBehavior::HandleMsg(SplitStripMessage& msg) { + m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); + m_States[msg.GetDestinationActionContext().GetStateId()].HandleMsg(msg); +}; + void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { args.Insert("name", m_Name); args.Insert("isLocked", isLocked); @@ -104,7 +139,7 @@ void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { void PropertyBehavior::SendBehaviorBlocksToClient(AMFArrayValue& args) { auto* stateArray = args.InsertArray("states"); - for (auto&[stateId, state] : m_States) { + for (auto& [stateId, state] : m_States) { auto* stateArgs = stateArray->PushArray(); stateArgs->Insert("id", static_cast(stateId)); state.SendBehaviorBlocksToClient(*stateArgs); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h index 94e93d501..4328e099a 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h @@ -1,6 +1,7 @@ #ifndef __SPLITSTRIPMESSAGE__H__ #define __SPLITSTRIPMESSAGE__H__ +#include "Action.h" #include "ActionContext.h" #include "BehaviorMessageBase.h" #include "StripUiPosition.h" @@ -18,11 +19,15 @@ class SplitStripMessage : public BehaviorMessageBase { ActionContext GetDestinationActionContext() { return destinationActionContext; }; int32_t GetSrcActionIndex() { return srcActionIndex; }; StripUiPosition GetPosition() { return destinationPosition; }; + const std::vector& GetTransferredActions() { return transferredActions; }; + void SetTransferredActions(std::vector::const_iterator begin, std::vector::const_iterator end) { transferredActions.assign(begin, end); }; private: ActionContext sourceActionContext; ActionContext destinationActionContext; int32_t srcActionIndex; StripUiPosition destinationPosition; + + std::vector transferredActions; }; #endif //!__SPLITSTRIPMESSAGE__H__ diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 7a204ea73..afe4a9fe2 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -90,10 +90,6 @@ void ControlBehaviors::MergeStrips(AMFArrayValue* arguments) { MergeStripsMessage mergeStripsMessage(arguments); } -void ControlBehaviors::SplitStrip(AMFArrayValue* arguments) { - SplitStripMessage splitStripMessage(arguments); -} - void ControlBehaviors::UpdateStripUI(AMFArrayValue* arguments) { UpdateStripUiMessage updateStripUiMessage(arguments); } @@ -186,7 +182,7 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "mergeStrips") { MergeStrips(arguments); } else if (command == "splitStrip") { - SplitStrip(arguments); + context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "updateStripUI") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "addAction") { diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index f77588434..75d7bec63 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -61,7 +61,6 @@ class ControlBehaviors: public Singleton { void AddStrip(ControlBehaviorContext& context); void RemoveStrip(AMFArrayValue* arguments); void MergeStrips(AMFArrayValue* arguments); - void SplitStrip(AMFArrayValue* arguments); void UpdateStripUI(AMFArrayValue* arguments); void MigrateActions(AMFArrayValue* arguments); void RearrangeStrip(AMFArrayValue* arguments); From ef1be80f22c5df7ba1aeec62ed2c88831cdc9807 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 28 Dec 2023 05:44:26 -0800 Subject: [PATCH 10/24] fix issues fix an issue where if you were on an empty state, the server would allow you to remain on that state fix an issue where the ui would not open on the previously opened state fix an issue where deleting strips in order caused the wrong strips to be deleted --- dGame/dComponents/ModelComponent.cpp | 49 +++++++++++++++++++ dGame/dComponents/ModelComponent.h | 4 ++ dGame/dPropertyBehaviors/ControlBehaviors.cpp | 10 +--- dGame/dPropertyBehaviors/ControlBehaviors.h | 2 - 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 838bb25af..ea93ca67a 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -30,6 +30,11 @@ void Strip::HandleMsg(UpdateStripUiMessage& msg) { m_Position = msg.GetPosition(); }; +template<> +void Strip::HandleMsg(RemoveStripMessage& msg) { + m_Actions.clear(); +}; + template<> void Strip::HandleMsg(SplitStripMessage& msg) { if (msg.GetTransferredActions().empty() && !m_Actions.empty()) { @@ -79,6 +84,15 @@ void State::HandleMsg(UpdateStripUiMessage& msg) { m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); }; +template<> +void State::HandleMsg(RemoveStripMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); +}; + template<> void State::HandleMsg(SplitStripMessage& msg) { if (msg.GetTransferredActions().empty()) { @@ -96,10 +110,18 @@ void State::HandleMsg(SplitStripMessage& msg) { } }; +bool State::IsEmpty() { + for (auto& strip : m_Strips) { + if (!strip.IsEmpty()) return false; + } + return true; +} + void State::SendBehaviorBlocksToClient(AMFArrayValue& args) { auto* strips = args.InsertArray("strips"); for (int32_t stripId = 0; stripId < m_Strips.size(); stripId++) { auto& strip = m_Strips.at(stripId); + if (strip.IsEmpty()) continue; auto* stripArgs = strips->PushArray(); stripArgs->Insert("id", static_cast(stripId)); @@ -113,22 +135,32 @@ void State::SendBehaviorBlocksToClient(AMFArrayValue& args) { template<> void PropertyBehavior::HandleMsg(AddStripMessage& msg) { m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); }; template<> void PropertyBehavior::HandleMsg(AddActionMessage& msg) { m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); }; template<> void PropertyBehavior::HandleMsg(UpdateStripUiMessage& msg) { m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); }; template<> void PropertyBehavior::HandleMsg(SplitStripMessage& msg) { m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); m_States[msg.GetDestinationActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(RemoveStripMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); }; void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { @@ -139,11 +171,28 @@ void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { void PropertyBehavior::SendBehaviorBlocksToClient(AMFArrayValue& args) { auto* stateArray = args.InsertArray("states"); + + auto lastState = BehaviorState::HOME_STATE; for (auto& [stateId, state] : m_States) { + if (state.IsEmpty()) continue; + + LOG("Serializing state %d", stateId); auto* stateArgs = stateArray->PushArray(); stateArgs->Insert("id", static_cast(stateId)); state.SendBehaviorBlocksToClient(*stateArgs); + if (m_States[m_LastEditedState].IsEmpty()) { + m_LastEditedState = stateId; + } } + + if (stateArray->GetDense().empty()) { + LOG("No states found, sending default state"); + m_LastEditedState = BehaviorState::HOME_STATE; + } + + auto* executionState = args.InsertArray("executionState"); + executionState->Insert("stateID", static_cast(m_LastEditedState)); + executionState->InsertArray("strips"); } //////////////////////// ModelComponent //////////////////////// diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 7282ed6cd..9b812faf6 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -27,6 +27,7 @@ class Strip { void SendBehaviorBlocksToClient(AMFArrayValue& args); StripUiPosition GetPosition() { return m_Position; } + bool IsEmpty() { return m_Actions.empty(); } private: std::vector m_Actions; StripUiPosition m_Position; @@ -38,6 +39,7 @@ class State { void HandleMsg(Msg& msg); void SendBehaviorBlocksToClient(AMFArrayValue& args); + bool IsEmpty(); private: std::vector m_Strips; }; @@ -62,6 +64,8 @@ class PropertyBehavior { // Whether this behavior is custom or pre-fab. bool isLoot = false; + + BehaviorState m_LastEditedState = BehaviorState::HOME_STATE; }; /** diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index afe4a9fe2..69ba1b328 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -82,18 +82,10 @@ void ControlBehaviors::AddStrip(ControlBehaviorContext& context) { context.modelComponent->HandleControlBehaviorsMsg(context.arguments); } -void ControlBehaviors::RemoveStrip(AMFArrayValue* arguments) { - RemoveStripMessage removeStrip(arguments); -} - void ControlBehaviors::MergeStrips(AMFArrayValue* arguments) { MergeStripsMessage mergeStripsMessage(arguments); } -void ControlBehaviors::UpdateStripUI(AMFArrayValue* arguments) { - UpdateStripUiMessage updateStripUiMessage(arguments); -} - void ControlBehaviors::MigrateActions(AMFArrayValue* arguments) { MigrateActionsMessage migrateActionsMessage(arguments); } @@ -178,7 +170,7 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "addStrip") { AddStrip(context); } else if (command == "removeStrip") { - RemoveStrip(arguments); + context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "mergeStrips") { MergeStrips(arguments); } else if (command == "splitStrip") { diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index 75d7bec63..5c19d8176 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -59,9 +59,7 @@ class ControlBehaviors: public Singleton { void ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent); void ToggleExecutionUpdates(); void AddStrip(ControlBehaviorContext& context); - void RemoveStrip(AMFArrayValue* arguments); void MergeStrips(AMFArrayValue* arguments); - void UpdateStripUI(AMFArrayValue* arguments); void MigrateActions(AMFArrayValue* arguments); void RearrangeStrip(AMFArrayValue* arguments); void Add(AMFArrayValue* arguments); From dce88fc5c78ce52789bd9eabf62fd52c2e1b69ce Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Thu, 28 Dec 2023 06:03:00 -0800 Subject: [PATCH 11/24] update how you remove behaviors from models --- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 69ba1b328..257d16c0d 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -142,11 +142,13 @@ void ControlBehaviors::UpdateAction(AMFArrayValue* arguments) { void ControlBehaviors::MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { // This closes the UI menu should it be open while the player is removing behaviors + // Replace this with BehaviorRemoved with the single argument objectID AMFArrayValue args; - args.Insert("visible", false); + // untested, should work. + args.Insert("objectID", std::to_string(modelComponent->GetParent()->GetObjectID())); - GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "ToggleBehaviorEditor", args); + GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "BehaviorRemoved", args); MoveToInventoryMessage moveToInventoryMessage(arguments); From f5e9f67423f6959f29ed68e190ab718eb3334d26 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 30 Dec 2023 23:12:14 -0800 Subject: [PATCH 12/24] Add remove actions and rename --- dGame/dComponents/ModelComponent.cpp | 25 +++++++++++++++++++ dGame/dComponents/ModelComponent.h | 2 +- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 6 +++-- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index ea93ca67a..4486841ca 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -35,6 +35,12 @@ void Strip::HandleMsg(RemoveStripMessage& msg) { m_Actions.clear(); }; +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<> void Strip::HandleMsg(SplitStripMessage& msg) { if (msg.GetTransferredActions().empty() && !m_Actions.empty()) { @@ -84,6 +90,15 @@ void State::HandleMsg(UpdateStripUiMessage& msg) { m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); }; +template<> +void State::HandleMsg(RemoveActionsMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); +}; + template<> void State::HandleMsg(RemoveStripMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { @@ -163,6 +178,16 @@ void PropertyBehavior::HandleMsg(RemoveStripMessage& msg) { m_LastEditedState = msg.GetActionContext().GetStateId(); }; +template<> +void PropertyBehavior::HandleMsg(RenameMessage& msg) { + m_Name = msg.GetName(); +}; + +template<> +void PropertyBehavior::HandleMsg(RemoveActionsMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); +}; + void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { args.Insert("name", m_Name); args.Insert("isLocked", isLocked); diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 9b812faf6..192aefed8 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -57,7 +57,7 @@ class PropertyBehavior { std::map m_States; // The name of this behavior. - std::string m_Name = "Test name new"; + std::string m_Name = "New Behavior"; // Whether this behavior is locked and cannot be edited. bool isLocked = false; diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 257d16c0d..9e88c34b2 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -188,9 +188,11 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "add") { Add(arguments); } else if (command == "removeActions") { - RemoveActions(arguments); + context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "rename") { - Rename(modelEntity, sysAddr, modelOwner, arguments); + context.modelComponent->HandleControlBehaviorsMsg(arguments); + // Send the list back to the client so the name is updated. + SendBehaviorListToClient(context); } else if (command == "sendBehaviorBlocksToClient") { SendBehaviorBlocksToClient(context); } else if (command == "moveToInventory") { From 65fe9deb4315a65c9ee6bbe007f67b1c9936adf0 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 30 Dec 2023 23:29:18 -0800 Subject: [PATCH 13/24] migrate actions --- dGame/dComponents/ModelComponent.cpp | 36 +++++++++++++++++++ .../MigrateActionsMessage.h | 5 +++ dGame/dPropertyBehaviors/ControlBehaviors.cpp | 2 +- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 4486841ca..c863d1dcc 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -53,6 +53,17 @@ void Strip::HandleMsg(SplitStripMessage& msg) { } }; +template<> +void Strip::HandleMsg(MigrateActionsMessage& msg) { + if (msg.GetMigratedActions().empty() && !m_Actions.empty()) { + auto startToMove = m_Actions.begin() + msg.GetSrcActionIndex(); + msg.SetMigratedActions(startToMove, m_Actions.end()); + m_Actions.erase(startToMove, m_Actions.end()); + } else { + m_Actions.insert(m_Actions.begin() + msg.GetDstActionIndex(), msg.GetMigratedActions().begin(), msg.GetMigratedActions().end()); + } +}; + void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) { m_Position.SendBehaviorBlocksToClient(args); @@ -125,6 +136,23 @@ void State::HandleMsg(SplitStripMessage& msg) { } }; +template<> +void State::HandleMsg(MigrateActionsMessage& msg) { + if (msg.GetMigratedActions().empty()) { + if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { + return; + } + + m_Strips[msg.GetSourceActionContext().GetStripId()].HandleMsg(msg); + } else { + if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { + m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); + } + + m_Strips[msg.GetDestinationActionContext().GetStripId()].HandleMsg(msg); + } +}; + bool State::IsEmpty() { for (auto& strip : m_Strips) { if (!strip.IsEmpty()) return false; @@ -172,6 +200,13 @@ void PropertyBehavior::HandleMsg(SplitStripMessage& msg) { m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); }; +template<> +void PropertyBehavior::HandleMsg(MigrateActionsMessage& msg) { + m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); + m_States[msg.GetDestinationActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); +}; + template<> void PropertyBehavior::HandleMsg(RemoveStripMessage& msg) { m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); @@ -186,6 +221,7 @@ void PropertyBehavior::HandleMsg(RenameMessage& msg) { template<> void PropertyBehavior::HandleMsg(RemoveActionsMessage& msg) { m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); }; void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h index d4b4e58ba..074513f6d 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h @@ -1,9 +1,11 @@ #ifndef __MIGRATEACTIONSMESSAGE__H__ #define __MIGRATEACTIONSMESSAGE__H__ +#include "Action.h" #include "ActionContext.h" #include "BehaviorMessageBase.h" + class AMFArrayValue; /** @@ -17,7 +19,10 @@ class MigrateActionsMessage : public BehaviorMessageBase { int32_t GetDstActionIndex() { return dstActionIndex; }; ActionContext GetSourceActionContext() { return sourceActionContext; }; ActionContext GetDestinationActionContext() { return destinationActionContext; }; + const std::vector& GetMigratedActions() { return migratedActions; }; + void SetMigratedActions(const std::vector::iterator start, const std::vector::iterator end) { migratedActions.assign(start, end); }; private: + std::vector migratedActions; ActionContext sourceActionContext; ActionContext destinationActionContext; int32_t srcActionIndex; diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 9e88c34b2..8358ee1b1 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -182,7 +182,7 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "addAction") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "migrateActions") { - MigrateActions(arguments); + context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "rearrangeStrip") { RearrangeStrip(arguments); } else if (command == "add") { From 686bb13d0281c3f0965afd44cc99e0ffc84b4dbc Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sat, 30 Dec 2023 23:41:00 -0800 Subject: [PATCH 14/24] update action and rearrange strip --- dGame/dComponents/ModelComponent.cpp | 42 +++++++++++++++++++ dGame/dPropertyBehaviors/ControlBehaviors.cpp | 6 +-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index c863d1dcc..0fb4a2679 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -41,6 +41,18 @@ void Strip::HandleMsg(RemoveActionsMessage& msg) { m_Actions.erase(m_Actions.begin() + msg.GetActionIndex(), m_Actions.end()); }; +template<> +void Strip::HandleMsg(UpdateActionMessage& msg) { + if (msg.GetActionIndex() >= m_Actions.size()) return; + m_Actions[msg.GetActionIndex()] = msg.GetAction(); +}; + +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<> void Strip::HandleMsg(SplitStripMessage& msg) { if (msg.GetTransferredActions().empty() && !m_Actions.empty()) { @@ -110,6 +122,24 @@ void State::HandleMsg(RemoveActionsMessage& msg) { m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); }; +template<> +void State::HandleMsg(RearrangeStripMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); +}; + +template<> +void State::HandleMsg(UpdateActionMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); +}; + template<> void State::HandleMsg(RemoveStripMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { @@ -187,6 +217,18 @@ void PropertyBehavior::HandleMsg(AddActionMessage& msg) { m_LastEditedState = msg.GetActionContext().GetStateId(); }; +template<> +void PropertyBehavior::HandleMsg(RearrangeStripMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(UpdateActionMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + template<> void PropertyBehavior::HandleMsg(UpdateStripUiMessage& msg) { m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 8358ee1b1..bad42ee9f 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -184,7 +184,7 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "migrateActions") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "rearrangeStrip") { - RearrangeStrip(arguments); + context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "add") { Add(arguments); } else if (command == "removeActions") { @@ -196,9 +196,9 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "sendBehaviorBlocksToClient") { SendBehaviorBlocksToClient(context); } else if (command == "moveToInventory") { - MoveToInventory(modelComponent, sysAddr, modelOwner, arguments); + MoveToInventory(modelComponent, sysAddr, modelOwner, arguments); // TODO } else if (command == "updateAction") { - UpdateAction(arguments); + context.modelComponent->HandleControlBehaviorsMsg(arguments); } else { LOG("Unknown behavior command (%s)", command.c_str()); } From 2adbad2d80d708c8b008395f7eea9355859f9325 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 31 Dec 2023 00:00:22 -0800 Subject: [PATCH 15/24] merge strips --- dGame/dComponents/ModelComponent.cpp | 34 +++++++++++++++++++ .../MergeStripsMessage.h | 4 +++ dGame/dPropertyBehaviors/ControlBehaviors.cpp | 15 ++++---- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 0fb4a2679..84396500f 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -65,6 +65,16 @@ void Strip::HandleMsg(SplitStripMessage& msg) { } }; +template<> +void Strip::HandleMsg(MergeStripsMessage& msg) { + if (msg.GetMigratedActions().empty() && !m_Actions.empty()) { + msg.SetMigratedActions(m_Actions.begin(), m_Actions.end()); + m_Actions.erase(m_Actions.begin(), m_Actions.end()); + } else { + m_Actions.insert(m_Actions.begin() + msg.GetDstActionIndex(), msg.GetMigratedActions().begin(), msg.GetMigratedActions().end()); + } +}; + template<> void Strip::HandleMsg(MigrateActionsMessage& msg) { if (msg.GetMigratedActions().empty() && !m_Actions.empty()) { @@ -166,6 +176,23 @@ void State::HandleMsg(SplitStripMessage& msg) { } }; +template<> +void State::HandleMsg(MergeStripsMessage& msg) { + if (msg.GetMigratedActions().empty()) { + if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { + return; + } + + m_Strips[msg.GetSourceActionContext().GetStripId()].HandleMsg(msg); + } else { + if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { + m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); + } + + m_Strips[msg.GetDestinationActionContext().GetStripId()].HandleMsg(msg); + } +}; + template<> void State::HandleMsg(MigrateActionsMessage& msg) { if (msg.GetMigratedActions().empty()) { @@ -249,6 +276,13 @@ void PropertyBehavior::HandleMsg(MigrateActionsMessage& msg) { m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); }; +template<> +void PropertyBehavior::HandleMsg(MergeStripsMessage& msg) { + m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); + m_States[msg.GetDestinationActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); +}; + template<> void PropertyBehavior::HandleMsg(RemoveStripMessage& msg) { m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h index 61f047b1f..5553530a8 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h @@ -1,6 +1,7 @@ #ifndef __MERGESTRIPSMESSAGE__H__ #define __MERGESTRIPSMESSAGE__H__ +#include "Action.h" #include "ActionContext.h" #include "BehaviorMessageBase.h" @@ -16,7 +17,10 @@ class MergeStripsMessage : public BehaviorMessageBase { int32_t GetDstActionIndex() { return dstActionIndex; }; ActionContext GetSourceActionContext() { return sourceActionContext; }; ActionContext GetDestinationActionContext() { return destinationActionContext; }; + const std::vector& GetMigratedActions() { return migratedActions; }; + void SetMigratedActions(const std::vector::iterator start, const std::vector::iterator end) { migratedActions.assign(start, end); }; private: + std::vector migratedActions; ActionContext sourceActionContext; ActionContext destinationActionContext; int32_t dstActionIndex; diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index bad42ee9f..0b56c6d00 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -166,15 +166,17 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& if (command == "sendBehaviorListToClient") { SendBehaviorListToClient(context); } else if (command == "modelTypeChanged") { - ModelTypeChanged(arguments, modelComponent); + ModelTypeChanged(arguments, modelComponent); // TODO } else if (command == "toggleExecutionUpdates") { - ToggleExecutionUpdates(); + ToggleExecutionUpdates(); // TODO } else if (command == "addStrip") { - AddStrip(context); + if (BehaviorMessageBase(context.arguments).IsDefaultBehaviorId()) RequestUpdatedID(context); + + context.modelComponent->HandleControlBehaviorsMsg(context.arguments); } else if (command == "removeStrip") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "mergeStrips") { - MergeStrips(arguments); + context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "splitStrip") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "updateStripUI") { @@ -186,11 +188,12 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "rearrangeStrip") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "add") { - Add(arguments); + Add(arguments); // TODO } else if (command == "removeActions") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "rename") { context.modelComponent->HandleControlBehaviorsMsg(arguments); + // Send the list back to the client so the name is updated. SendBehaviorListToClient(context); } else if (command == "sendBehaviorBlocksToClient") { @@ -320,7 +323,7 @@ ControlBehaviors::ControlBehaviors() { } isInitialized = true; LOG_DEBUG("Created all base block classes"); - for (auto&[name, block] : blockTypes) { + for (auto& [name, block] : blockTypes) { LOG_DEBUG("block name is %s default %s min %f max %f", name.c_str(), block.GetDefaultValue().c_str(), block.GetMinimumValue(), block.GetMaximumValue()); } } From d32c48dc5430cd08b05941556376552d02e8fce7 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 31 Dec 2023 00:52:35 -0800 Subject: [PATCH 16/24] add and move to inventory --- dGame/dComponents/ModelComponent.cpp | 33 ++++++++++++++++--- dGame/dComponents/ModelComponent.h | 25 +++++++++++--- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 8 +++-- 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 84396500f..7fe5dd573 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -300,7 +300,19 @@ void PropertyBehavior::HandleMsg(RemoveActionsMessage& msg) { m_LastEditedState = msg.GetActionContext().GetStateId(); }; +template<> +void PropertyBehavior::HandleMsg(AddMessage& msg) { + // TODO Parse the corresponding behavior xml file. + if (msg.GetBehaviorId() != 7965) isLoot = true; + m_BehaviorId = msg.GetBehaviorId(); +}; + +void PropertyBehavior::SetBehaviorId(int32_t behaviorId) { + m_BehaviorId = behaviorId; +} + void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { + args.Insert("id", std::to_string(m_BehaviorId)); args.Insert("name", m_Name); args.Insert("isLocked", isLocked); args.Insert("isLoot", isLoot); @@ -364,17 +376,15 @@ void ModelComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsInitialU } void ModelComponent::UpdatePendingBehaviorId(const int32_t newId) { - m_Behaviors[newId] = m_Behaviors[BehaviorMessageBase::DefaultBehaviorId]; - m_Behaviors.erase(BehaviorMessageBase::DefaultBehaviorId); + for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == -1) behavior.SetBehaviorId(newId); } void ModelComponent::SendBehaviorListToClient(AMFArrayValue& args) { args.Insert("objectID", std::to_string(m_Parent->GetObjectID())); auto* behaviorArray = args.InsertArray("behaviors"); - for (auto& [behaviorId, behavior] : m_Behaviors) { + for (auto& behavior : m_Behaviors) { auto* behaviorArgs = behaviorArray->PushArray(); - behaviorArgs->Insert("id", std::to_string(behaviorId)); behavior.SendBehaviorListToClient(*behaviorArgs); } } @@ -382,5 +392,18 @@ void ModelComponent::SendBehaviorListToClient(AMFArrayValue& args) { void ModelComponent::SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) { args.Insert("BehaviorID", std::to_string(behaviorToSend)); args.Insert("objectID", std::to_string(m_Parent->GetObjectID())); - m_Behaviors[behaviorToSend].SendBehaviorBlocksToClient(args); + for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == behaviorToSend) behavior.SendBehaviorBlocksToClient(args); +} + +void ModelComponent::AddBehavior(AddMessage& msg) { + // Can only have 1 of the loot behaviors + for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == msg.GetBehaviorId()) return; + m_Behaviors.insert(m_Behaviors.begin() + msg.GetBehaviorIndex(), PropertyBehavior()); + m_Behaviors[msg.GetBehaviorIndex()].HandleMsg(msg); +} + +void ModelComponent::MoveToInventory(MoveToInventoryMessage& msg) { + if (msg.GetBehaviorIndex() >= m_Behaviors.size() || m_Behaviors.at(msg.GetBehaviorIndex()).GetBehaviorId() != msg.GetBehaviorId()) return; + m_Behaviors.erase(m_Behaviors.begin() + msg.GetBehaviorIndex()); + // TODO move to the inventory } diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 192aefed8..93b24d0fe 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -17,8 +17,8 @@ #include "Action.h" class Entity; -class AddStripMessage; -class AddActionMessage; +class MoveToInventoryMessage; +class AddMessage; class Strip { public: @@ -51,6 +51,9 @@ class PropertyBehavior { void SendBehaviorListToClient(AMFArrayValue& args); void SendBehaviorBlocksToClient(AMFArrayValue& args); + + int32_t GetBehaviorId() const { return m_BehaviorId; } + void SetBehaviorId(int32_t id); private: // The states this behavior has. @@ -66,6 +69,8 @@ class PropertyBehavior { bool isLoot = false; BehaviorState m_LastEditedState = BehaviorState::HOME_STATE; + + int32_t m_BehaviorId = -1; }; /** @@ -107,9 +112,21 @@ class ModelComponent : public Component { void HandleControlBehaviorsMsg(AMFArrayValue* args) { static_assert(std::is_base_of_v, "Msg must be a BehaviorMessageBase"); Msg msg(args); - m_Behaviors[msg.GetBehaviorId()].HandleMsg(msg); + for (auto& behavior : m_Behaviors) { + if (behavior.GetBehaviorId() == msg.GetBehaviorId()) { + behavior.HandleMsg(msg); + return; + } + } + + m_Behaviors.insert(m_Behaviors.begin(), PropertyBehavior()); + m_Behaviors.at(0).HandleMsg(msg); }; + void AddBehavior(AddMessage& msg); + + void MoveToInventory(MoveToInventoryMessage& msg); + // Updates the pending behavior ID to the new ID. void UpdatePendingBehaviorId(const int32_t newId); @@ -129,7 +146,7 @@ class ModelComponent : public Component { void SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args); private: - std::map m_Behaviors; + std::vector m_Behaviors; /** * The original position of the model diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 0b56c6d00..d28abbbe9 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -188,7 +188,9 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "rearrangeStrip") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "add") { - Add(arguments); // TODO + AddMessage msg(context.arguments); + context.modelComponent->AddBehavior(msg); + SendBehaviorListToClient(context); } else if (command == "removeActions") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else if (command == "rename") { @@ -199,7 +201,9 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "sendBehaviorBlocksToClient") { SendBehaviorBlocksToClient(context); } else if (command == "moveToInventory") { - MoveToInventory(modelComponent, sysAddr, modelOwner, arguments); // TODO + MoveToInventoryMessage msg(arguments); + context.modelComponent->MoveToInventory(msg); + SendBehaviorListToClient(context); } else if (command == "updateAction") { context.modelComponent->HandleControlBehaviorsMsg(arguments); } else { From e7f6e4433d272ba5e1d8ad5fe5c537b8b44f304e Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 31 Dec 2023 01:03:43 -0800 Subject: [PATCH 17/24] Remove dead code --- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 57 +++---------------- dGame/dPropertyBehaviors/ControlBehaviors.h | 9 --- 2 files changed, 7 insertions(+), 59 deletions(-) diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index d28abbbe9..8c1ab7d3c 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -59,53 +59,6 @@ void ControlBehaviors::SendBehaviorListToClient(const ControlBehaviorContext& co GameMessages::SendUIMessageServerToSingleClient(context.modelOwner, context.modelOwner->GetSystemAddress(), "UpdateBehaviorList", behaviorsToSerialize); } -void ControlBehaviors::ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent) { - auto* modelTypeAmf = arguments->Get("ModelType"); - if (!modelTypeAmf) return; - - uint32_t modelType = static_cast(modelTypeAmf->GetValue()); - - //TODO Update the model type here -} - -void ControlBehaviors::ToggleExecutionUpdates() { - //TODO do something with this info -} - -void ControlBehaviors::AddStrip(ControlBehaviorContext& context) { - BehaviorMessageBase msgBase(context.arguments); - - if (msgBase.IsDefaultBehaviorId()) { - RequestUpdatedID(context); - } - - context.modelComponent->HandleControlBehaviorsMsg(context.arguments); -} - -void ControlBehaviors::MergeStrips(AMFArrayValue* arguments) { - MergeStripsMessage mergeStripsMessage(arguments); -} - -void ControlBehaviors::MigrateActions(AMFArrayValue* arguments) { - MigrateActionsMessage migrateActionsMessage(arguments); -} - -void ControlBehaviors::RearrangeStrip(AMFArrayValue* arguments) { - RearrangeStripMessage rearrangeStripMessage(arguments); -} - -void ControlBehaviors::Add(AMFArrayValue* arguments) { - AddMessage addMessage(arguments); -} - -void ControlBehaviors::RemoveActions(AMFArrayValue* arguments) { - RemoveActionsMessage removeActionsMessage(arguments); -} - -void ControlBehaviors::Rename(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { - RenameMessage renameMessage(arguments); -} - // 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; @@ -166,9 +119,12 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& if (command == "sendBehaviorListToClient") { SendBehaviorListToClient(context); } else if (command == "modelTypeChanged") { - ModelTypeChanged(arguments, modelComponent); // TODO + auto* modelType = arguments->Get("ModelType"); + if (!modelType) return; + + modelEntity->SetVar(u"modelType", modelType->GetValue()); } else if (command == "toggleExecutionUpdates") { - ToggleExecutionUpdates(); // TODO + // TODO } else if (command == "addStrip") { if (BehaviorMessageBase(context.arguments).IsDefaultBehaviorId()) RequestUpdatedID(context); @@ -214,7 +170,8 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& ControlBehaviors::ControlBehaviors() { auto blocksBuffer = Game::assetManager->GetFile("ui\\ingame\\blocksdef.xml"); if (!blocksBuffer) { - LOG("Failed to open blocksdef.xml, property behaviors will be disabled for this zone!"); + LOG("Failed to open blocksdef.xml, property behaviors will be disabled for this zone! " + "(This is a necessary file for cheat detection and ensuring we do not send unexpected values to the client)"); return; } diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index 5c19d8176..baa78032c 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -56,15 +56,6 @@ class ControlBehaviors: public Singleton { private: void RequestUpdatedID(ControlBehaviorContext& context); void SendBehaviorListToClient(const ControlBehaviorContext& context); - void ModelTypeChanged(AMFArrayValue* arguments, ModelComponent* ModelComponent); - void ToggleExecutionUpdates(); - void AddStrip(ControlBehaviorContext& context); - void MergeStrips(AMFArrayValue* arguments); - void MigrateActions(AMFArrayValue* arguments); - void RearrangeStrip(AMFArrayValue* arguments); - void Add(AMFArrayValue* arguments); - void RemoveActions(AMFArrayValue* arguments); - void Rename(Entity* modelEntity, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments); void SendBehaviorBlocksToClient(ControlBehaviorContext& context); void UpdateAction(AMFArrayValue* arguments); void MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments); From ff620fa511fd13558bc2b7eec6ff0a54ab2d03e2 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Sun, 31 Dec 2023 22:20:30 -0800 Subject: [PATCH 18/24] simplify code --- dGame/dComponents/ModelComponent.cpp | 2 +- dGame/dComponents/ModelComponent.h | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 7fe5dd573..534e5da8b 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -303,8 +303,8 @@ void PropertyBehavior::HandleMsg(RemoveActionsMessage& msg) { template<> void PropertyBehavior::HandleMsg(AddMessage& msg) { // TODO Parse the corresponding behavior xml file. - if (msg.GetBehaviorId() != 7965) isLoot = true; m_BehaviorId = msg.GetBehaviorId(); + isLoot = m_BehaviorId != 7965; }; void PropertyBehavior::SetBehaviorId(int32_t behaviorId) { diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 93b24d0fe..a24cc85b3 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -119,8 +119,9 @@ class ModelComponent : public Component { } } - m_Behaviors.insert(m_Behaviors.begin(), PropertyBehavior()); - m_Behaviors.at(0).HandleMsg(msg); + auto newBehavior = m_Behaviors.insert(m_Behaviors.begin(), PropertyBehavior()); + newBehavior->SetBehaviorId(msg.GetBehaviorId()); + newBehavior->HandleMsg(msg); }; void AddBehavior(AddMessage& msg); From e3a08a17a57732ec22200ab800d9c5ea807172a9 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 3 Jan 2024 03:00:47 -0800 Subject: [PATCH 19/24] nits and move finish MoveToInventory constify serialize further include path fixes use const, comments fix amf message Update ModelComponent.cpp replace operator subscript with at --- dGame/Character.cpp | 2 +- .../ControllablePhysicsComponent.cpp | 2 +- dGame/dComponents/ModelComponent.cpp | 107 ++++++++++-------- dGame/dComponents/ModelComponent.h | 63 ++++++++--- .../ControlBehaviorMessages/Action.cpp | 3 +- .../ControlBehaviorMessages/Action.h | 14 ++- .../MergeStripsMessage.h | 2 +- .../MigrateActionsMessage.h | 2 +- .../StripUiPosition.cpp | 4 +- .../ControlBehaviorMessages/StripUiPosition.h | 2 +- dGame/dPropertyBehaviors/ControlBehaviors.cpp | 27 ++--- dGame/dPropertyBehaviors/ControlBehaviors.h | 1 - 12 files changed, 132 insertions(+), 97 deletions(-) diff --git a/dGame/Character.cpp b/dGame/Character.cpp index e6d1d03ad..ee04710a6 100644 --- a/dGame/Character.cpp +++ b/dGame/Character.cpp @@ -251,7 +251,7 @@ void Character::SaveXMLToDatabase() { auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID(); // lzid garbage, binary concat of zoneID, zoneInstance and zoneClone - if (zoneInfo.GetMapID() != 0) { + if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0 && !Game::zoneManager->GetDisableSaveLocation()) { uint64_t lzidConcat = zoneInfo.GetCloneID(); lzidConcat = (lzidConcat << 16) | uint16_t(zoneInfo.GetInstanceID()); lzidConcat = (lzidConcat << 16) | uint16_t(zoneInfo.GetMapID()); diff --git a/dGame/dComponents/ControllablePhysicsComponent.cpp b/dGame/dComponents/ControllablePhysicsComponent.cpp index cd3498d70..dd981f660 100644 --- a/dGame/dComponents/ControllablePhysicsComponent.cpp +++ b/dGame/dComponents/ControllablePhysicsComponent.cpp @@ -187,7 +187,7 @@ void ControllablePhysicsComponent::UpdateXml(tinyxml2::XMLDocument* doc) { auto zoneInfo = Game::zoneManager->GetZone()->GetZoneID(); - if (zoneInfo.GetMapID() != 0) { + if (zoneInfo.GetMapID() != 0 && zoneInfo.GetCloneID() == 0 && !Game::zoneManager->GetDisableSaveLocation()) { character->SetAttribute("lzx", m_Position.x); character->SetAttribute("lzy", m_Position.y); character->SetAttribute("lzz", m_Position.z); diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 534e5da8b..d7dd9a34c 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -4,6 +4,7 @@ #include "Game.h" #include "Logger.h" +#include "BehaviorStates.h" #include "ControlBehaviorMsgs.h" ///////////////// Strip /////////////////// @@ -11,10 +12,6 @@ template<> void Strip::HandleMsg(AddStripMessage& msg) { m_Actions = msg.GetActionsToAdd(); - for (auto& action : m_Actions) { - LOG("%s %s %f %s", action.GetType().c_str(), action.GetValueParameterName().c_str(), (float)action.GetValueParameterDouble(), action.GetValueParameterString().c_str()); - } - m_Position = msg.GetPosition(); }; @@ -44,7 +41,7 @@ void Strip::HandleMsg(RemoveActionsMessage& msg) { template<> void Strip::HandleMsg(UpdateActionMessage& msg) { if (msg.GetActionIndex() >= m_Actions.size()) return; - m_Actions[msg.GetActionIndex()] = msg.GetAction(); + m_Actions.at(msg.GetActionIndex()) = msg.GetAction(); }; template<> @@ -86,7 +83,7 @@ void Strip::HandleMsg(MigrateActionsMessage& msg) { } }; -void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) { +void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) const { m_Position.SendBehaviorBlocksToClient(args); auto* actions = args.InsertArray("actions"); @@ -102,7 +99,7 @@ void State::HandleMsg(AddStripMessage& msg) { if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { m_Strips.resize(msg.GetActionContext().GetStripId() + 1); } - m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; template<> @@ -111,7 +108,7 @@ void State::HandleMsg(AddActionMessage& msg) { return; } - m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; template<> @@ -120,7 +117,7 @@ void State::HandleMsg(UpdateStripUiMessage& msg) { return; } - m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; template<> @@ -129,7 +126,7 @@ void State::HandleMsg(RemoveActionsMessage& msg) { return; } - m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; template<> @@ -138,7 +135,7 @@ void State::HandleMsg(RearrangeStripMessage& msg) { return; } - m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; template<> @@ -147,7 +144,7 @@ void State::HandleMsg(UpdateActionMessage& msg) { return; } - m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; template<> @@ -156,7 +153,7 @@ void State::HandleMsg(RemoveStripMessage& msg) { return; } - m_Strips[msg.GetActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); }; template<> @@ -166,13 +163,13 @@ void State::HandleMsg(SplitStripMessage& msg) { return; } - m_Strips[msg.GetSourceActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetSourceActionContext().GetStripId()).HandleMsg(msg); } else { if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); } - m_Strips[msg.GetDestinationActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetDestinationActionContext().GetStripId()).HandleMsg(msg); } }; @@ -183,13 +180,13 @@ void State::HandleMsg(MergeStripsMessage& msg) { return; } - m_Strips[msg.GetSourceActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetSourceActionContext().GetStripId()).HandleMsg(msg); } else { if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); } - m_Strips[msg.GetDestinationActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetDestinationActionContext().GetStripId()).HandleMsg(msg); } }; @@ -200,24 +197,24 @@ void State::HandleMsg(MigrateActionsMessage& msg) { return; } - m_Strips[msg.GetSourceActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetSourceActionContext().GetStripId()).HandleMsg(msg); } else { if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); } - m_Strips[msg.GetDestinationActionContext().GetStripId()].HandleMsg(msg); + m_Strips.at(msg.GetDestinationActionContext().GetStripId()).HandleMsg(msg); } }; -bool State::IsEmpty() { +bool State::IsEmpty() const { for (auto& strip : m_Strips) { if (!strip.IsEmpty()) return false; } return true; } -void State::SendBehaviorBlocksToClient(AMFArrayValue& args) { +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); @@ -232,6 +229,10 @@ void State::SendBehaviorBlocksToClient(AMFArrayValue& args) { ///////////////// PropertyBehavior /////////////////// +PropertyBehavior::PropertyBehavior() { + m_LastEditedState = BehaviorState::HOME_STATE; +} + template<> void PropertyBehavior::HandleMsg(AddStripMessage& msg) { m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); @@ -262,6 +263,18 @@ void PropertyBehavior::HandleMsg(UpdateStripUiMessage& msg) { m_LastEditedState = msg.GetActionContext().GetStateId(); }; +template<> +void PropertyBehavior::HandleMsg(RemoveStripMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(RemoveActionsMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + template<> void PropertyBehavior::HandleMsg(SplitStripMessage& msg) { m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); @@ -283,23 +296,11 @@ void PropertyBehavior::HandleMsg(MergeStripsMessage& msg) { m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); }; -template<> -void PropertyBehavior::HandleMsg(RemoveStripMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetActionContext().GetStateId(); -}; - template<> void PropertyBehavior::HandleMsg(RenameMessage& msg) { m_Name = msg.GetName(); }; -template<> -void PropertyBehavior::HandleMsg(RemoveActionsMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetActionContext().GetStateId(); -}; - template<> void PropertyBehavior::HandleMsg(AddMessage& msg) { // TODO Parse the corresponding behavior xml file. @@ -311,32 +312,40 @@ void PropertyBehavior::SetBehaviorId(int32_t behaviorId) { m_BehaviorId = behaviorId; } -void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) { +void PropertyBehavior::SendBehaviorListToClient(AMFArrayValue& args) const { args.Insert("id", std::to_string(m_BehaviorId)); args.Insert("name", m_Name); args.Insert("isLocked", isLocked); args.Insert("isLoot", isLoot); } -void PropertyBehavior::SendBehaviorBlocksToClient(AMFArrayValue& args) { +void PropertyBehavior::VerifyLastEditedState() { + if (!m_States[m_LastEditedState].IsEmpty()) return; + + for (const auto& [stateId, state] : m_States) { + if (state.IsEmpty()) continue; + + LOG_DEBUG("Updating last edited state to %i because %i is empty.", stateId, m_LastEditedState); + m_LastEditedState = stateId; + return; + } + + LOG_DEBUG("No states found, sending default state"); + + m_LastEditedState = BehaviorState::HOME_STATE; +} + +void PropertyBehavior::SendBehaviorBlocksToClient(AMFArrayValue& args) const { auto* stateArray = args.InsertArray("states"); auto lastState = BehaviorState::HOME_STATE; for (auto& [stateId, state] : m_States) { if (state.IsEmpty()) continue; - LOG("Serializing state %d", stateId); + LOG_DEBUG("Serializing state %i", stateId); auto* stateArgs = stateArray->PushArray(); stateArgs->Insert("id", static_cast(stateId)); state.SendBehaviorBlocksToClient(*stateArgs); - if (m_States[m_LastEditedState].IsEmpty()) { - m_LastEditedState = stateId; - } - } - - if (stateArray->GetDense().empty()) { - LOG("No states found, sending default state"); - m_LastEditedState = BehaviorState::HOME_STATE; } auto* executionState = args.InsertArray("executionState"); @@ -379,7 +388,7 @@ void ModelComponent::UpdatePendingBehaviorId(const int32_t newId) { for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == -1) behavior.SetBehaviorId(newId); } -void ModelComponent::SendBehaviorListToClient(AMFArrayValue& args) { +void ModelComponent::SendBehaviorListToClient(AMFArrayValue& args) const { args.Insert("objectID", std::to_string(m_Parent->GetObjectID())); auto* behaviorArray = args.InsertArray("behaviors"); @@ -389,7 +398,11 @@ void ModelComponent::SendBehaviorListToClient(AMFArrayValue& args) { } } -void ModelComponent::SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) { +void ModelComponent::VerifyBehaviors() { + for (auto& behavior : m_Behaviors) behavior.VerifyLastEditedState(); +} + +void ModelComponent::SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) const { args.Insert("BehaviorID", std::to_string(behaviorToSend)); args.Insert("objectID", std::to_string(m_Parent->GetObjectID())); for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == behaviorToSend) behavior.SendBehaviorBlocksToClient(args); @@ -399,7 +412,7 @@ void ModelComponent::AddBehavior(AddMessage& msg) { // Can only have 1 of the loot behaviors for (auto& behavior : m_Behaviors) if (behavior.GetBehaviorId() == msg.GetBehaviorId()) return; m_Behaviors.insert(m_Behaviors.begin() + msg.GetBehaviorIndex(), PropertyBehavior()); - m_Behaviors[msg.GetBehaviorIndex()].HandleMsg(msg); + m_Behaviors.at(msg.GetBehaviorIndex()).HandleMsg(msg); } void ModelComponent::MoveToInventory(MoveToInventoryMessage& msg) { diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index a24cc85b3..3066b8e09 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -8,26 +8,25 @@ #include "NiQuaternion.h" #include "Component.h" #include "eReplicaComponentType.h" -#include "Amf3.h" -#include "BehaviorMessageBase.h" - -#include "BehaviorStates.h" #include "StripUiPosition.h" #include "Action.h" +class AddMessage; +class AMFArrayValue; +class BehaviorMessageBase; class Entity; class MoveToInventoryMessage; -class AddMessage; + +enum class BehaviorState : uint32_t; class Strip { public: template void HandleMsg(Msg& msg); - void SendBehaviorBlocksToClient(AMFArrayValue& args); - StripUiPosition GetPosition() { return m_Position; } - bool IsEmpty() { return m_Actions.empty(); } + void SendBehaviorBlocksToClient(AMFArrayValue& args) const; + bool IsEmpty() const { return m_Actions.empty(); } private: std::vector m_Actions; StripUiPosition m_Position; @@ -38,19 +37,25 @@ class State { template void HandleMsg(Msg& msg); - void SendBehaviorBlocksToClient(AMFArrayValue& args); - bool IsEmpty(); + void SendBehaviorBlocksToClient(AMFArrayValue& args) const; + bool IsEmpty() const; private: std::vector m_Strips; }; +/** + * Represents the Entity of a Property Behavior and holds data associated with the behavior + */ class PropertyBehavior { public: + PropertyBehavior(); template void HandleMsg(Msg& msg); - void SendBehaviorListToClient(AMFArrayValue& args); - void SendBehaviorBlocksToClient(AMFArrayValue& args); + // If the last edited state has no strips, this method will set the last edited state to the first state that has strips. + void VerifyLastEditedState(); + void SendBehaviorListToClient(AMFArrayValue& args) const; + void SendBehaviorBlocksToClient(AMFArrayValue& args) const; int32_t GetBehaviorId() const { return m_BehaviorId; } void SetBehaviorId(int32_t id); @@ -68,8 +73,12 @@ class PropertyBehavior { // Whether this behavior is custom or pre-fab. bool isLoot = false; - BehaviorState m_LastEditedState = BehaviorState::HOME_STATE; + // The last state that was edited. This is used so when the client re-opens the behavior editor, it will open to the last edited state. + // If the last edited state has no strips, it will open to the first state that has strips. + BehaviorState m_LastEditedState; + // The behavior id for this behavior. This is expected to be fully unique, however an id of -1 means this behavior was just created + // and needs to be assigned an id. int32_t m_BehaviorId = -1; }; @@ -108,6 +117,12 @@ class ModelComponent : public Component { */ void SetRotation(const NiQuaternion& rot) { m_OriginalRotation = rot; } + /** + * Main gateway for all behavior messages to be passed to their respective behaviors. + * + * @tparam Msg The message type to pass + * @param args the arguments of the message to be deserialized + */ template void HandleControlBehaviorsMsg(AMFArrayValue* args) { static_assert(std::is_base_of_v, "Msg must be a BehaviorMessageBase"); @@ -119,7 +134,16 @@ class ModelComponent : public Component { } } + // If we somehow added more than 5 behaviors, resize to 5. + if (m_Behaviors.size() > 5) m_Behaviors.resize(5); + + // Do not allow more than 5 to be added. The client UI will break if you do! + if (m_Behaviors.size() == 5) return; + auto newBehavior = m_Behaviors.insert(m_Behaviors.begin(), PropertyBehavior()); + // Generally if we are inserting a new behavior, it is because the client is creating a new behavior. + // However if we are testing behaviors the behavior will not exist on the initial pass, so we set the ID here to that of the msg. + // This will either set the ID to -1 (no change in the current default) or set the ID to the ID of the behavior we are testing. newBehavior->SetBehaviorId(msg.GetBehaviorId()); newBehavior->HandleMsg(msg); }; @@ -142,11 +166,18 @@ class ModelComponent : public Component { * "isLoot": AMFTrue or AMFFalse of whether or not the behavior is a custom behavior (true if custom) * "name": The name of the behavior formatted as an AMFString */ - void SendBehaviorListToClient(AMFArrayValue& args); + void SendBehaviorListToClient(AMFArrayValue& args) const; - void SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args); + void SendBehaviorBlocksToClient(int32_t behaviorToSend, AMFArrayValue& args) const; + + void VerifyBehaviors(); private: + /** + * The behaviors of the model + * Note: This is a vector because the order of the behaviors matters when serializing to the client. + * Note: No two PropertyBehaviors should have the same behavior ID. + */ std::vector m_Behaviors; /** @@ -163,6 +194,4 @@ class ModelComponent : public Component { * The ID of the user that made the model */ LWOOBJID m_userModelID; - - // std::map m_Behaviors; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp index 0be60dfef..73f1391d5 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.cpp @@ -1,4 +1,5 @@ #include "Action.h" +#include "Amf3.h" Action::Action() { type = ""; @@ -30,7 +31,7 @@ Action::Action(AMFArrayValue* arguments) { } } -void Action::SendBehaviorBlocksToClient(AMFArrayValue& args) { +void Action::SendBehaviorBlocksToClient(AMFArrayValue& args) const { auto* actionArgs = args.PushArray(); actionArgs->Insert("Type", type); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h index ff65370a4..df6658896 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/Action.h @@ -1,7 +1,9 @@ #ifndef __ACTION__H__ #define __ACTION__H__ -#include "BehaviorMessageBase.h" +#include + +class AMFArrayValue; /** * @brief Sent if a ControlBehavior message has an Action associated with it @@ -11,12 +13,12 @@ class Action { public: Action(); Action(AMFArrayValue* arguments); - const std::string& GetType() { return type; }; - const std::string& GetValueParameterName() { return valueParameterName; }; - const std::string& GetValueParameterString() { return valueParameterString; }; - const double GetValueParameterDouble() { return valueParameterDouble; }; + 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; }; - void SendBehaviorBlocksToClient(AMFArrayValue& args); + void SendBehaviorBlocksToClient(AMFArrayValue& args) const; private: std::string type; std::string valueParameterName; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h index 5553530a8..f6a8a4ef9 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h @@ -18,7 +18,7 @@ class MergeStripsMessage : public BehaviorMessageBase { ActionContext GetSourceActionContext() { return sourceActionContext; }; ActionContext GetDestinationActionContext() { return destinationActionContext; }; const std::vector& GetMigratedActions() { return migratedActions; }; - void SetMigratedActions(const std::vector::iterator start, const std::vector::iterator end) { migratedActions.assign(start, end); }; + void SetMigratedActions(std::vector::const_iterator start, std::vector::const_iterator end) { migratedActions.assign(start, end); }; private: std::vector migratedActions; ActionContext sourceActionContext; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h index 074513f6d..4b3346a4d 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h @@ -20,7 +20,7 @@ class MigrateActionsMessage : public BehaviorMessageBase { ActionContext GetSourceActionContext() { return sourceActionContext; }; ActionContext GetDestinationActionContext() { return destinationActionContext; }; const std::vector& GetMigratedActions() { return migratedActions; }; - void SetMigratedActions(const std::vector::iterator start, const std::vector::iterator end) { migratedActions.assign(start, end); }; + void SetMigratedActions(std::vector::const_iterator start, std::vector::const_iterator end) { migratedActions.assign(start, end); }; private: std::vector migratedActions; ActionContext sourceActionContext; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp index b0834fef3..8b2d1d365 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.cpp @@ -21,8 +21,8 @@ StripUiPosition::StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName xPosition = xPositionValue->GetValue(); } -void StripUiPosition::SendBehaviorBlocksToClient(AMFArrayValue& args) { - auto uiArgs = args.InsertArray("ui"); +void StripUiPosition::SendBehaviorBlocksToClient(AMFArrayValue& args) const { + auto* uiArgs = args.InsertArray("ui"); uiArgs->Insert("x", xPosition); uiArgs->Insert("y", yPosition); } diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h index eb03fa396..5af48e947 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h @@ -11,7 +11,7 @@ class StripUiPosition { public: StripUiPosition(); StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName = "ui"); - void SendBehaviorBlocksToClient(AMFArrayValue& args); + void SendBehaviorBlocksToClient(AMFArrayValue& args) const; double GetX() { return xPosition; }; double GetY() { return yPosition; }; private: diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.cpp b/dGame/dPropertyBehaviors/ControlBehaviors.cpp index 8c1ab7d3c..248ce4e7d 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.cpp +++ b/dGame/dPropertyBehaviors/ControlBehaviors.cpp @@ -64,6 +64,7 @@ void ControlBehaviors::SendBehaviorBlocksToClient(ControlBehaviorContext& contex if (!context) return; BehaviorMessageBase behaviorMsg(context.arguments); + context.modelComponent->VerifyBehaviors(); AMFArrayValue behavior; context.modelComponent->SendBehaviorBlocksToClient(behaviorMsg.GetBehaviorId(), behavior); GameMessages::SendUIMessageServerToSingleClient(context.modelOwner, context.modelOwner->GetSystemAddress(), "UpdateBehaviorBlocks", behavior); @@ -93,21 +94,6 @@ void ControlBehaviors::UpdateAction(AMFArrayValue* arguments) { } } -void ControlBehaviors::MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments) { - // This closes the UI menu should it be open while the player is removing behaviors - // Replace this with BehaviorRemoved with the single argument objectID - AMFArrayValue args; - - // untested, should work. - args.Insert("objectID", std::to_string(modelComponent->GetParent()->GetObjectID())); - - GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "BehaviorRemoved", args); - - MoveToInventoryMessage moveToInventoryMessage(arguments); - - // SendBehaviorListToClient(modelComponent->GetParent(), sysAddr, modelOwner); -} - void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& sysAddr, AMFArrayValue* arguments, std::string command, Entity* modelOwner) { if (!isInitialized || !modelEntity || !modelOwner || !arguments) return; auto* modelComponent = modelEntity->GetComponent(); @@ -159,6 +145,11 @@ void ControlBehaviors::ProcessCommand(Entity* modelEntity, const SystemAddress& } else if (command == "moveToInventory") { MoveToInventoryMessage msg(arguments); context.modelComponent->MoveToInventory(msg); + + AMFArrayValue args; + args.Insert("BehaviorID", std::to_string(msg.GetBehaviorId())); + GameMessages::SendUIMessageServerToSingleClient(modelOwner, modelOwner->GetParentUser()->GetSystemAddress(), "BehaviorRemoved", args); + SendBehaviorListToClient(context); } else if (command == "updateAction") { context.modelComponent->HandleControlBehaviorsMsg(arguments); @@ -171,15 +162,15 @@ ControlBehaviors::ControlBehaviors() { auto blocksBuffer = Game::assetManager->GetFile("ui\\ingame\\blocksdef.xml"); if (!blocksBuffer) { LOG("Failed to open blocksdef.xml, property behaviors will be disabled for this zone! " - "(This is a necessary file for cheat detection and ensuring we do not send unexpected values to the client)"); + "(This is a necessary file for cheat detection and ensuring we do not send unexpected values to the client)"); return; } tinyxml2::XMLDocument m_Doc; - std::string read{}; + std::string read; - std::string buffer{}; + std::string buffer; bool commentBlockStart = false; while (std::getline(blocksBuffer, read)) { // tinyxml2 should handle comment blocks but the client has one that fails the processing. diff --git a/dGame/dPropertyBehaviors/ControlBehaviors.h b/dGame/dPropertyBehaviors/ControlBehaviors.h index baa78032c..ab7394083 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviors.h +++ b/dGame/dPropertyBehaviors/ControlBehaviors.h @@ -58,7 +58,6 @@ class ControlBehaviors: public Singleton { void SendBehaviorListToClient(const ControlBehaviorContext& context); void SendBehaviorBlocksToClient(ControlBehaviorContext& context); void UpdateAction(AMFArrayValue* arguments); - void MoveToInventory(ModelComponent* modelComponent, const SystemAddress& sysAddr, Entity* modelOwner, AMFArrayValue* arguments); std::map blockTypes{}; // If false, property behaviors will not be able to be edited. From 0fe4a3c2ab61f9d65c0171fc9a97982e4425be97 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 3 Jan 2024 04:23:49 -0800 Subject: [PATCH 20/24] Update ModelComponent.cpp --- dGame/dComponents/ModelComponent.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index d7dd9a34c..f0f3f2b55 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -351,6 +351,8 @@ void PropertyBehavior::SendBehaviorBlocksToClient(AMFArrayValue& args) const { auto* executionState = args.InsertArray("executionState"); executionState->Insert("stateID", static_cast(m_LastEditedState)); executionState->InsertArray("strips"); + + // TODO Serialize the execution state of the behavior } //////////////////////// ModelComponent //////////////////////// From 5cc6f694a9595ceda51e5091e4923a72eb6ed5db Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 3 Jan 2024 04:27:25 -0800 Subject: [PATCH 21/24] Update MigrateActionsMessage.h --- .../ControlBehaviorMessages/MigrateActionsMessage.h | 1 - 1 file changed, 1 deletion(-) diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h index 4b3346a4d..675580960 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h @@ -5,7 +5,6 @@ #include "ActionContext.h" #include "BehaviorMessageBase.h" - class AMFArrayValue; /** From 88fa58dfccb3be47388f999fc710bf720c9c7f92 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 3 Jan 2024 04:29:37 -0800 Subject: [PATCH 22/24] const --- .../ControlBehaviorMessages/ActionContext.h | 4 ++-- .../ControlBehaviorMessages/AddActionMessage.h | 6 +++--- .../ControlBehaviorMessages/AddMessage.h | 2 +- .../ControlBehaviorMessages/AddStripMessage.h | 6 +++--- .../ControlBehaviorMessages/BehaviorMessageBase.h | 2 +- .../ControlBehaviorMessages/MergeStripsMessage.h | 8 ++++---- .../ControlBehaviorMessages/MigrateActionsMessage.h | 10 +++++----- .../ControlBehaviorMessages/MoveToInventoryMessage.h | 2 +- .../ControlBehaviorMessages/RearrangeStripMessage.h | 6 +++--- .../ControlBehaviorMessages/RemoveActionsMessage.h | 4 ++-- .../ControlBehaviorMessages/RemoveStripMessage.h | 2 +- .../ControlBehaviorMessages/RenameMessage.h | 2 +- .../ControlBehaviorMessages/SplitStripMessage.h | 10 +++++----- .../ControlBehaviorMessages/StripUiPosition.h | 4 ++-- .../ControlBehaviorMessages/UpdateActionMessage.h | 6 +++--- .../ControlBehaviorMessages/UpdateStripUiMessage.h | 4 ++-- 16 files changed, 39 insertions(+), 39 deletions(-) diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h index 5f46fd8c5..91e91e728 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/ActionContext.h @@ -14,8 +14,8 @@ class ActionContext { public: ActionContext(); ActionContext(AMFArrayValue* arguments, std::string customStateKey = "stateID", std::string customStripKey = "stripID"); - const StripId GetStripId() { return stripId; }; - const BehaviorState GetStateId() { return stateId; }; + const StripId GetStripId() const { return stripId; }; + const BehaviorState GetStateId() const { return stateId; }; private: BehaviorState GetBehaviorStateFromArgument(AMFArrayValue* arguments, const std::string& key); StripId GetStripIdFromArgument(AMFArrayValue* arguments, const std::string& key); diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h index b5a6e6a67..ac3a96122 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddActionMessage.h @@ -14,9 +14,9 @@ class AMFArrayValue; class AddActionMessage : public BehaviorMessageBase { public: AddActionMessage(AMFArrayValue* arguments); - const uint32_t GetActionIndex() { return actionIndex; }; - Action GetAction() { return action; }; - ActionContext GetActionContext() { return actionContext; }; + int32_t GetActionIndex() const { return actionIndex; }; + Action GetAction() const { return action; }; + ActionContext GetActionContext() const { return actionContext; }; private: int32_t actionIndex = -1; ActionContext actionContext; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h index a46d5f98a..766276655 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddMessage.h @@ -10,7 +10,7 @@ class AddMessage : public BehaviorMessageBase { public: AddMessage(AMFArrayValue* arguments); - const uint32_t GetBehaviorIndex() { return behaviorIndex; }; + const uint32_t GetBehaviorIndex() const { return behaviorIndex; }; private: uint32_t behaviorIndex; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h index db75aef77..0b9a09e3d 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/AddStripMessage.h @@ -19,9 +19,9 @@ class AMFArrayValue; class AddStripMessage : public BehaviorMessageBase { public: AddStripMessage(AMFArrayValue* arguments); - StripUiPosition GetPosition() { return position; }; - ActionContext GetActionContext() { return actionContext; }; - std::vector GetActionsToAdd() { return actionsToAdd; }; + StripUiPosition GetPosition() const { return position; }; + ActionContext GetActionContext() const { return actionContext; }; + std::vector GetActionsToAdd() const { return actionsToAdd; }; private: StripUiPosition position; ActionContext actionContext; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h index ff66861f9..8a841d7f8 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/BehaviorMessageBase.h @@ -16,7 +16,7 @@ enum class BehaviorState : uint32_t; class BehaviorMessageBase { public: static inline int32_t DefaultBehaviorId = -1; - const int32_t GetBehaviorId() { return behaviorId; }; + const int32_t GetBehaviorId() const { return behaviorId; }; bool IsDefaultBehaviorId() { return behaviorId == DefaultBehaviorId; }; BehaviorMessageBase(AMFArrayValue* arguments); protected: diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h index f6a8a4ef9..7fa4d3a89 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MergeStripsMessage.h @@ -14,10 +14,10 @@ class AMFArrayValue; class MergeStripsMessage : public BehaviorMessageBase { public: MergeStripsMessage(AMFArrayValue* arguments); - int32_t GetDstActionIndex() { return dstActionIndex; }; - ActionContext GetSourceActionContext() { return sourceActionContext; }; - ActionContext GetDestinationActionContext() { return destinationActionContext; }; - const std::vector& GetMigratedActions() { return migratedActions; }; + 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); }; private: std::vector migratedActions; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h index 675580960..2f1ac2439 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MigrateActionsMessage.h @@ -14,11 +14,11 @@ class AMFArrayValue; class MigrateActionsMessage : public BehaviorMessageBase { public: MigrateActionsMessage(AMFArrayValue* arguments); - int32_t GetSrcActionIndex() { return srcActionIndex; }; - int32_t GetDstActionIndex() { return dstActionIndex; }; - ActionContext GetSourceActionContext() { return sourceActionContext; }; - ActionContext GetDestinationActionContext() { return destinationActionContext; }; - const std::vector& GetMigratedActions() { return migratedActions; }; + 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); }; private: std::vector migratedActions; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h index c48f7d173..dc1057666 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/MoveToInventoryMessage.h @@ -13,7 +13,7 @@ class AMFArrayValue; class MoveToInventoryMessage : public BehaviorMessageBase { public: MoveToInventoryMessage(AMFArrayValue* arguments); - const uint32_t GetBehaviorIndex() { return behaviorIndex; }; + const uint32_t GetBehaviorIndex() const { return behaviorIndex; }; private: uint32_t behaviorIndex; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h index 3b1329677..db12c046c 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RearrangeStripMessage.h @@ -11,9 +11,9 @@ class RearrangeStripMessage : public BehaviorMessageBase { public: RearrangeStripMessage(AMFArrayValue* arguments); - int32_t GetSrcActionIndex() { return srcActionIndex; }; - int32_t GetDstActionIndex() { return dstActionIndex; }; - ActionContext GetActionContext() { return actionContext; }; + int32_t GetSrcActionIndex() const { return srcActionIndex; }; + int32_t GetDstActionIndex() const { return dstActionIndex; }; + ActionContext GetActionContext() const { return actionContext; }; private: ActionContext actionContext; int32_t srcActionIndex; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h index ee90fe56f..860df0af4 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveActionsMessage.h @@ -13,8 +13,8 @@ class AMFArrayValue; class RemoveActionsMessage : public BehaviorMessageBase { public: RemoveActionsMessage(AMFArrayValue* arguments); - int32_t GetActionIndex() { return actionIndex; }; - ActionContext GetActionContext() { return actionContext; }; + int32_t GetActionIndex() const { return actionIndex; }; + ActionContext GetActionContext() const { return actionContext; }; private: ActionContext actionContext; int32_t actionIndex; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h index 36e2e4015..6a32ab0c5 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RemoveStripMessage.h @@ -11,7 +11,7 @@ class RemoveStripMessage : public BehaviorMessageBase { public: RemoveStripMessage(AMFArrayValue* arguments); - ActionContext GetActionContext() { return actionContext; }; + ActionContext GetActionContext() const { return actionContext; }; private: ActionContext actionContext; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h index ba181f630..3f4119d2b 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/RenameMessage.h @@ -12,7 +12,7 @@ class AMFArrayValue; class RenameMessage : public BehaviorMessageBase { public: RenameMessage(AMFArrayValue* arguments); - const std::string& GetName() { return name; }; + const std::string& GetName() const { return name; }; private: std::string name; }; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h index 4328e099a..e41d50ebb 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/SplitStripMessage.h @@ -15,11 +15,11 @@ class AMFArrayValue; class SplitStripMessage : public BehaviorMessageBase { public: SplitStripMessage(AMFArrayValue* arguments); - ActionContext GetSourceActionContext() { return sourceActionContext; }; - ActionContext GetDestinationActionContext() { return destinationActionContext; }; - int32_t GetSrcActionIndex() { return srcActionIndex; }; - StripUiPosition GetPosition() { return destinationPosition; }; - const std::vector& GetTransferredActions() { return transferredActions; }; + ActionContext GetSourceActionContext() const { return sourceActionContext; }; + ActionContext GetDestinationActionContext() const { return destinationActionContext; }; + int32_t GetSrcActionIndex() const { return srcActionIndex; }; + StripUiPosition GetPosition() const { return destinationPosition; }; + const std::vector& GetTransferredActions() const { return transferredActions; }; void SetTransferredActions(std::vector::const_iterator begin, std::vector::const_iterator end) { transferredActions.assign(begin, end); }; private: ActionContext sourceActionContext; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h index 5af48e947..92578cdc2 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/StripUiPosition.h @@ -12,8 +12,8 @@ class StripUiPosition { StripUiPosition(); StripUiPosition(AMFArrayValue* arguments, std::string uiKeyName = "ui"); void SendBehaviorBlocksToClient(AMFArrayValue& args) const; - double GetX() { return xPosition; }; - double GetY() { return yPosition; }; + double GetX() const { return xPosition; }; + double GetY() const { return yPosition; }; private: double xPosition; double yPosition; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h index 1aa14c2cf..aa34940b6 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateActionMessage.h @@ -14,9 +14,9 @@ class AMFArrayValue; class UpdateActionMessage : public BehaviorMessageBase { public: UpdateActionMessage(AMFArrayValue* arguments); - int32_t GetActionIndex() { return actionIndex; }; - ActionContext GetActionContext() { return actionContext; }; - Action GetAction() { return action; }; + int32_t GetActionIndex() const { return actionIndex; }; + ActionContext GetActionContext() const { return actionContext; }; + Action GetAction() const { return action; }; private: int32_t actionIndex; ActionContext actionContext; diff --git a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h index 6d96f90c5..0e9afe815 100644 --- a/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h +++ b/dGame/dPropertyBehaviors/ControlBehaviorMessages/UpdateStripUiMessage.h @@ -14,8 +14,8 @@ class AMFArrayValue; class UpdateStripUiMessage : public BehaviorMessageBase { public: UpdateStripUiMessage(AMFArrayValue* arguments); - StripUiPosition GetPosition() { return position; }; - ActionContext GetActionContext() { return actionContext; }; + StripUiPosition GetPosition() const { return position; }; + ActionContext GetActionContext() const { return actionContext; }; private: StripUiPosition position; ActionContext actionContext; From 5304bc2744efa2e9970f46c900a2a1ad77163a3c Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 3 Jan 2024 04:50:21 -0800 Subject: [PATCH 23/24] Move to separate translation units --- dGame/dComponents/ModelComponent.cpp | 350 ------------------ dGame/dComponents/ModelComponent.h | 67 +--- dGame/dPropertyBehaviors/CMakeLists.txt | 3 + dGame/dPropertyBehaviors/PropertyBehavior.cpp | 130 +++++++ dGame/dPropertyBehaviors/PropertyBehavior.h | 49 +++ dGame/dPropertyBehaviors/State.cpp | 136 +++++++ dGame/dPropertyBehaviors/State.h | 19 + dGame/dPropertyBehaviors/Strip.cpp | 86 +++++ dGame/dPropertyBehaviors/Strip.h | 23 ++ 9 files changed, 448 insertions(+), 415 deletions(-) create mode 100644 dGame/dPropertyBehaviors/PropertyBehavior.cpp create mode 100644 dGame/dPropertyBehaviors/PropertyBehavior.h create mode 100644 dGame/dPropertyBehaviors/State.cpp create mode 100644 dGame/dPropertyBehaviors/State.h create mode 100644 dGame/dPropertyBehaviors/Strip.cpp create mode 100644 dGame/dPropertyBehaviors/Strip.h diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index f0f3f2b55..3f8858c04 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -7,356 +7,6 @@ #include "BehaviorStates.h" #include "ControlBehaviorMsgs.h" -///////////////// Strip /////////////////// - -template<> -void Strip::HandleMsg(AddStripMessage& msg) { - m_Actions = msg.GetActionsToAdd(); - m_Position = msg.GetPosition(); -}; - -template<> -void Strip::HandleMsg(AddActionMessage& msg) { - if (msg.GetActionIndex() == -1) return; - - m_Actions.insert(m_Actions.begin() + msg.GetActionIndex(), msg.GetAction()); -}; - -template<> -void Strip::HandleMsg(UpdateStripUiMessage& msg) { - m_Position = msg.GetPosition(); -}; - -template<> -void Strip::HandleMsg(RemoveStripMessage& msg) { - m_Actions.clear(); -}; - -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<> -void Strip::HandleMsg(UpdateActionMessage& msg) { - if (msg.GetActionIndex() >= m_Actions.size()) return; - m_Actions.at(msg.GetActionIndex()) = msg.GetAction(); -}; - -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<> -void Strip::HandleMsg(SplitStripMessage& msg) { - if (msg.GetTransferredActions().empty() && !m_Actions.empty()) { - auto startToMove = m_Actions.begin() + msg.GetSrcActionIndex(); - msg.SetTransferredActions(startToMove, m_Actions.end()); - m_Actions.erase(startToMove, m_Actions.end()); - } else { - m_Actions = msg.GetTransferredActions(); - m_Position = msg.GetPosition(); - } -}; - -template<> -void Strip::HandleMsg(MergeStripsMessage& msg) { - if (msg.GetMigratedActions().empty() && !m_Actions.empty()) { - msg.SetMigratedActions(m_Actions.begin(), m_Actions.end()); - m_Actions.erase(m_Actions.begin(), m_Actions.end()); - } else { - m_Actions.insert(m_Actions.begin() + msg.GetDstActionIndex(), msg.GetMigratedActions().begin(), msg.GetMigratedActions().end()); - } -}; - -template<> -void Strip::HandleMsg(MigrateActionsMessage& msg) { - if (msg.GetMigratedActions().empty() && !m_Actions.empty()) { - auto startToMove = m_Actions.begin() + msg.GetSrcActionIndex(); - msg.SetMigratedActions(startToMove, m_Actions.end()); - m_Actions.erase(startToMove, m_Actions.end()); - } else { - m_Actions.insert(m_Actions.begin() + msg.GetDstActionIndex(), msg.GetMigratedActions().begin(), msg.GetMigratedActions().end()); - } -}; - -void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) const { - m_Position.SendBehaviorBlocksToClient(args); - - auto* actions = args.InsertArray("actions"); - for (auto& action : m_Actions) { - action.SendBehaviorBlocksToClient(*actions); - } -}; - -///////////////// State /////////////////// - -template<> -void State::HandleMsg(AddStripMessage& msg) { - if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { - m_Strips.resize(msg.GetActionContext().GetStripId() + 1); - } - m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); -}; - -template<> -void State::HandleMsg(AddActionMessage& msg) { - if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { - return; - } - - m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); -}; - -template<> -void State::HandleMsg(UpdateStripUiMessage& msg) { - if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { - return; - } - - m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); -}; - -template<> -void State::HandleMsg(RemoveActionsMessage& msg) { - if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { - return; - } - - m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); -}; - -template<> -void State::HandleMsg(RearrangeStripMessage& msg) { - if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { - return; - } - - m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); -}; - -template<> -void State::HandleMsg(UpdateActionMessage& msg) { - if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { - return; - } - - m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); -}; - -template<> -void State::HandleMsg(RemoveStripMessage& msg) { - if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { - return; - } - - m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); -}; - -template<> -void State::HandleMsg(SplitStripMessage& msg) { - if (msg.GetTransferredActions().empty()) { - if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { - return; - } - - m_Strips.at(msg.GetSourceActionContext().GetStripId()).HandleMsg(msg); - } else { - if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { - m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); - } - - m_Strips.at(msg.GetDestinationActionContext().GetStripId()).HandleMsg(msg); - } -}; - -template<> -void State::HandleMsg(MergeStripsMessage& msg) { - if (msg.GetMigratedActions().empty()) { - if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { - return; - } - - m_Strips.at(msg.GetSourceActionContext().GetStripId()).HandleMsg(msg); - } else { - if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { - m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); - } - - m_Strips.at(msg.GetDestinationActionContext().GetStripId()).HandleMsg(msg); - } -}; - -template<> -void State::HandleMsg(MigrateActionsMessage& msg) { - if (msg.GetMigratedActions().empty()) { - if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { - return; - } - - m_Strips.at(msg.GetSourceActionContext().GetStripId()).HandleMsg(msg); - } else { - if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { - m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); - } - - m_Strips.at(msg.GetDestinationActionContext().GetStripId()).HandleMsg(msg); - } -}; - -bool State::IsEmpty() const { - for (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); - if (strip.IsEmpty()) continue; - - auto* stripArgs = strips->PushArray(); - stripArgs->Insert("id", static_cast(stripId)); - - strip.SendBehaviorBlocksToClient(*stripArgs); - } -}; - -///////////////// PropertyBehavior /////////////////// - -PropertyBehavior::PropertyBehavior() { - m_LastEditedState = BehaviorState::HOME_STATE; -} - -template<> -void PropertyBehavior::HandleMsg(AddStripMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetActionContext().GetStateId(); -}; - -template<> -void PropertyBehavior::HandleMsg(AddActionMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetActionContext().GetStateId(); -}; - -template<> -void PropertyBehavior::HandleMsg(RearrangeStripMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetActionContext().GetStateId(); -}; - -template<> -void PropertyBehavior::HandleMsg(UpdateActionMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetActionContext().GetStateId(); -}; - -template<> -void PropertyBehavior::HandleMsg(UpdateStripUiMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetActionContext().GetStateId(); -}; - -template<> -void PropertyBehavior::HandleMsg(RemoveStripMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetActionContext().GetStateId(); -}; - -template<> -void PropertyBehavior::HandleMsg(RemoveActionsMessage& msg) { - m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetActionContext().GetStateId(); -}; - -template<> -void PropertyBehavior::HandleMsg(SplitStripMessage& msg) { - m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); - m_States[msg.GetDestinationActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); -}; - -template<> -void PropertyBehavior::HandleMsg(MigrateActionsMessage& msg) { - m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); - m_States[msg.GetDestinationActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); -}; - -template<> -void PropertyBehavior::HandleMsg(MergeStripsMessage& msg) { - m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); - m_States[msg.GetDestinationActionContext().GetStateId()].HandleMsg(msg); - m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); -}; - -template<> -void PropertyBehavior::HandleMsg(RenameMessage& msg) { - m_Name = msg.GetName(); -}; - -template<> -void PropertyBehavior::HandleMsg(AddMessage& msg) { - // TODO Parse the corresponding behavior xml file. - m_BehaviorId = msg.GetBehaviorId(); - 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); - args.Insert("isLocked", isLocked); - args.Insert("isLoot", isLoot); -} - -void PropertyBehavior::VerifyLastEditedState() { - if (!m_States[m_LastEditedState].IsEmpty()) return; - - for (const auto& [stateId, state] : m_States) { - if (state.IsEmpty()) continue; - - LOG_DEBUG("Updating last edited state to %i because %i is empty.", stateId, m_LastEditedState); - m_LastEditedState = stateId; - return; - } - - LOG_DEBUG("No states found, sending default state"); - - m_LastEditedState = BehaviorState::HOME_STATE; -} - -void PropertyBehavior::SendBehaviorBlocksToClient(AMFArrayValue& args) const { - auto* stateArray = args.InsertArray("states"); - - auto lastState = BehaviorState::HOME_STATE; - for (auto& [stateId, state] : m_States) { - if (state.IsEmpty()) continue; - - LOG_DEBUG("Serializing state %i", stateId); - auto* stateArgs = stateArray->PushArray(); - stateArgs->Insert("id", static_cast(stateId)); - state.SendBehaviorBlocksToClient(*stateArgs); - } - - auto* executionState = args.InsertArray("executionState"); - executionState->Insert("stateID", static_cast(m_LastEditedState)); - executionState->InsertArray("strips"); - - // TODO Serialize the execution state of the behavior -} - -//////////////////////// ModelComponent //////////////////////// - ModelComponent::ModelComponent(Entity* parent) : Component(parent) { m_OriginalPosition = m_Parent->GetDefaultPosition(); m_OriginalRotation = m_Parent->GetDefaultRotation(); diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 3066b8e09..a36328beb 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -9,8 +9,9 @@ #include "Component.h" #include "eReplicaComponentType.h" -#include "StripUiPosition.h" #include "Action.h" +#include "PropertyBehavior.h" +#include "StripUiPosition.h" class AddMessage; class AMFArrayValue; @@ -18,70 +19,6 @@ class BehaviorMessageBase; class Entity; class MoveToInventoryMessage; -enum class BehaviorState : uint32_t; - -class Strip { -public: - template - void HandleMsg(Msg& msg); - - void SendBehaviorBlocksToClient(AMFArrayValue& args) const; - bool IsEmpty() const { return m_Actions.empty(); } -private: - std::vector m_Actions; - StripUiPosition m_Position; -}; - -class State { -public: - template - void HandleMsg(Msg& msg); - - void SendBehaviorBlocksToClient(AMFArrayValue& args) const; - bool IsEmpty() const; -private: - std::vector m_Strips; -}; - -/** - * Represents the Entity of a Property Behavior and holds data associated with the behavior - */ -class PropertyBehavior { -public: - PropertyBehavior(); - 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. - void VerifyLastEditedState(); - void SendBehaviorListToClient(AMFArrayValue& args) const; - void SendBehaviorBlocksToClient(AMFArrayValue& args) const; - - int32_t GetBehaviorId() const { return m_BehaviorId; } - void SetBehaviorId(int32_t id); -private: - - // The states this behavior has. - std::map m_States; - - // The name of this behavior. - std::string m_Name = "New Behavior"; - - // Whether this behavior is locked and cannot be edited. - bool isLocked = false; - - // Whether this behavior is custom or pre-fab. - bool isLoot = false; - - // The last state that was edited. This is used so when the client re-opens the behavior editor, it will open to the last edited state. - // If the last edited state has no strips, it will open to the first state that has strips. - BehaviorState m_LastEditedState; - - // The behavior id for this behavior. This is expected to be fully unique, however an id of -1 means this behavior was just created - // and needs to be assigned an id. - int32_t m_BehaviorId = -1; -}; - /** * Component that represents entities that are a model, e.g. collectible models and BBB models. */ diff --git a/dGame/dPropertyBehaviors/CMakeLists.txt b/dGame/dPropertyBehaviors/CMakeLists.txt index 5e33a5f5c..8bffa9065 100644 --- a/dGame/dPropertyBehaviors/CMakeLists.txt +++ b/dGame/dPropertyBehaviors/CMakeLists.txt @@ -1,4 +1,7 @@ set(DGAME_DPROPERTYBEHAVIORS_SOURCES + "PropertyBehavior.cpp" + "State.cpp" + "Strip.cpp" "BlockDefinition.cpp" "ControlBehaviors.cpp" ) diff --git a/dGame/dPropertyBehaviors/PropertyBehavior.cpp b/dGame/dPropertyBehaviors/PropertyBehavior.cpp new file mode 100644 index 000000000..ee191ba17 --- /dev/null +++ b/dGame/dPropertyBehaviors/PropertyBehavior.cpp @@ -0,0 +1,130 @@ +#include "PropertyBehavior.h" + +#include "BehaviorStates.h" +#include "ControlBehaviorMsgs.h" + +PropertyBehavior::PropertyBehavior() { + m_LastEditedState = BehaviorState::HOME_STATE; +} + +template<> +void PropertyBehavior::HandleMsg(AddStripMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(AddActionMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(RearrangeStripMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(UpdateActionMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(UpdateStripUiMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(RemoveStripMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(RemoveActionsMessage& msg) { + m_States[msg.GetActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(SplitStripMessage& msg) { + m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); + m_States[msg.GetDestinationActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(MigrateActionsMessage& msg) { + m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); + m_States[msg.GetDestinationActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(MergeStripsMessage& msg) { + m_States[msg.GetSourceActionContext().GetStateId()].HandleMsg(msg); + m_States[msg.GetDestinationActionContext().GetStateId()].HandleMsg(msg); + m_LastEditedState = msg.GetDestinationActionContext().GetStateId(); +}; + +template<> +void PropertyBehavior::HandleMsg(RenameMessage& msg) { + m_Name = msg.GetName(); +}; + +template<> +void PropertyBehavior::HandleMsg(AddMessage& msg) { + // TODO Parse the corresponding behavior xml file. + m_BehaviorId = msg.GetBehaviorId(); + 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); + args.Insert("isLocked", isLocked); + args.Insert("isLoot", isLoot); +} + +void PropertyBehavior::VerifyLastEditedState() { + if (!m_States[m_LastEditedState].IsEmpty()) return; + + for (const auto& [stateId, state] : m_States) { + if (state.IsEmpty()) continue; + + LOG_DEBUG("Updating last edited state to %i because %i is empty.", stateId, m_LastEditedState); + m_LastEditedState = stateId; + return; + } + + LOG_DEBUG("No states found, sending default state"); + + m_LastEditedState = BehaviorState::HOME_STATE; +} + +void PropertyBehavior::SendBehaviorBlocksToClient(AMFArrayValue& args) const { + auto* stateArray = args.InsertArray("states"); + + auto lastState = BehaviorState::HOME_STATE; + for (auto& [stateId, state] : m_States) { + if (state.IsEmpty()) continue; + + LOG_DEBUG("Serializing state %i", stateId); + auto* stateArgs = stateArray->PushArray(); + stateArgs->Insert("id", static_cast(stateId)); + state.SendBehaviorBlocksToClient(*stateArgs); + } + + auto* executionState = args.InsertArray("executionState"); + executionState->Insert("stateID", static_cast(m_LastEditedState)); + executionState->InsertArray("strips"); + + // TODO Serialize the execution state of the behavior +} diff --git a/dGame/dPropertyBehaviors/PropertyBehavior.h b/dGame/dPropertyBehaviors/PropertyBehavior.h new file mode 100644 index 000000000..dc53bbed6 --- /dev/null +++ b/dGame/dPropertyBehaviors/PropertyBehavior.h @@ -0,0 +1,49 @@ +#ifndef __PROPERTYBEHAVIOR__H__ +#define __PROPERTYBEHAVIOR__H__ + +#include "State.h" + +enum class BehaviorState : uint32_t; + +class AMFArrayValue; + +/** + * Represents the Entity of a Property Behavior and holds data associated with the behavior + */ +class PropertyBehavior { +public: + PropertyBehavior(); + 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. + void VerifyLastEditedState(); + void SendBehaviorListToClient(AMFArrayValue& args) const; + void SendBehaviorBlocksToClient(AMFArrayValue& args) const; + + int32_t GetBehaviorId() const { return m_BehaviorId; } + void SetBehaviorId(int32_t id); +private: + + // The states this behavior has. + std::map m_States; + + // The name of this behavior. + std::string m_Name = "New Behavior"; + + // Whether this behavior is locked and cannot be edited. + bool isLocked = false; + + // Whether this behavior is custom or pre-fab. + bool isLoot = false; + + // The last state that was edited. This is used so when the client re-opens the behavior editor, it will open to the last edited state. + // If the last edited state has no strips, it will open to the first state that has strips. + BehaviorState m_LastEditedState; + + // The behavior id for this behavior. This is expected to be fully unique, however an id of -1 means this behavior was just created + // and needs to be assigned an id. + int32_t m_BehaviorId = -1; +}; + +#endif //!__PROPERTYBEHAVIOR__H__ diff --git a/dGame/dPropertyBehaviors/State.cpp b/dGame/dPropertyBehaviors/State.cpp new file mode 100644 index 000000000..f696c169e --- /dev/null +++ b/dGame/dPropertyBehaviors/State.cpp @@ -0,0 +1,136 @@ +#include "State.h" + +#include "ControlBehaviorMsgs.h" + +template<> +void State::HandleMsg(AddStripMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + m_Strips.resize(msg.GetActionContext().GetStripId() + 1); + } + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); +}; + +template<> +void State::HandleMsg(AddActionMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); +}; + +template<> +void State::HandleMsg(UpdateStripUiMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); +}; + +template<> +void State::HandleMsg(RemoveActionsMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); +}; + +template<> +void State::HandleMsg(RearrangeStripMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); +}; + +template<> +void State::HandleMsg(UpdateActionMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); +}; + +template<> +void State::HandleMsg(RemoveStripMessage& msg) { + if (m_Strips.size() <= msg.GetActionContext().GetStripId()) { + return; + } + + m_Strips.at(msg.GetActionContext().GetStripId()).HandleMsg(msg); +}; + +template<> +void State::HandleMsg(SplitStripMessage& msg) { + if (msg.GetTransferredActions().empty()) { + if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { + return; + } + + m_Strips.at(msg.GetSourceActionContext().GetStripId()).HandleMsg(msg); + } else { + if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { + m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); + } + + m_Strips.at(msg.GetDestinationActionContext().GetStripId()).HandleMsg(msg); + } +}; + +template<> +void State::HandleMsg(MergeStripsMessage& msg) { + if (msg.GetMigratedActions().empty()) { + if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { + return; + } + + m_Strips.at(msg.GetSourceActionContext().GetStripId()).HandleMsg(msg); + } else { + if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { + m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); + } + + m_Strips.at(msg.GetDestinationActionContext().GetStripId()).HandleMsg(msg); + } +}; + +template<> +void State::HandleMsg(MigrateActionsMessage& msg) { + if (msg.GetMigratedActions().empty()) { + if (m_Strips.size() <= msg.GetSourceActionContext().GetStripId()) { + return; + } + + m_Strips.at(msg.GetSourceActionContext().GetStripId()).HandleMsg(msg); + } else { + if (m_Strips.size() <= msg.GetDestinationActionContext().GetStripId()) { + m_Strips.resize(msg.GetDestinationActionContext().GetStripId() + 1); + } + + m_Strips.at(msg.GetDestinationActionContext().GetStripId()).HandleMsg(msg); + } +}; + +bool State::IsEmpty() const { + for (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); + if (strip.IsEmpty()) continue; + + auto* stripArgs = strips->PushArray(); + stripArgs->Insert("id", static_cast(stripId)); + + strip.SendBehaviorBlocksToClient(*stripArgs); + } +}; diff --git a/dGame/dPropertyBehaviors/State.h b/dGame/dPropertyBehaviors/State.h new file mode 100644 index 000000000..a6a6d23be --- /dev/null +++ b/dGame/dPropertyBehaviors/State.h @@ -0,0 +1,19 @@ +#ifndef __STATE__H__ +#define __STATE__H__ + +#include "Strip.h" + +class AMFArrayValue; + +class State { +public: + template + void HandleMsg(Msg& msg); + + void SendBehaviorBlocksToClient(AMFArrayValue& args) const; + bool IsEmpty() const; +private: + std::vector m_Strips; +}; + +#endif //!__STATE__H__ diff --git a/dGame/dPropertyBehaviors/Strip.cpp b/dGame/dPropertyBehaviors/Strip.cpp new file mode 100644 index 000000000..bf7def097 --- /dev/null +++ b/dGame/dPropertyBehaviors/Strip.cpp @@ -0,0 +1,86 @@ +#include "Strip.h" + +#include "ControlBehaviorMsgs.h" + +template<> +void Strip::HandleMsg(AddStripMessage& msg) { + m_Actions = msg.GetActionsToAdd(); + m_Position = msg.GetPosition(); +}; + +template<> +void Strip::HandleMsg(AddActionMessage& msg) { + if (msg.GetActionIndex() == -1) return; + + m_Actions.insert(m_Actions.begin() + msg.GetActionIndex(), msg.GetAction()); +}; + +template<> +void Strip::HandleMsg(UpdateStripUiMessage& msg) { + m_Position = msg.GetPosition(); +}; + +template<> +void Strip::HandleMsg(RemoveStripMessage& msg) { + m_Actions.clear(); +}; + +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<> +void Strip::HandleMsg(UpdateActionMessage& msg) { + if (msg.GetActionIndex() >= m_Actions.size()) return; + m_Actions.at(msg.GetActionIndex()) = msg.GetAction(); +}; + +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<> +void Strip::HandleMsg(SplitStripMessage& msg) { + if (msg.GetTransferredActions().empty() && !m_Actions.empty()) { + auto startToMove = m_Actions.begin() + msg.GetSrcActionIndex(); + msg.SetTransferredActions(startToMove, m_Actions.end()); + m_Actions.erase(startToMove, m_Actions.end()); + } else { + m_Actions = msg.GetTransferredActions(); + m_Position = msg.GetPosition(); + } +}; + +template<> +void Strip::HandleMsg(MergeStripsMessage& msg) { + if (msg.GetMigratedActions().empty() && !m_Actions.empty()) { + msg.SetMigratedActions(m_Actions.begin(), m_Actions.end()); + m_Actions.erase(m_Actions.begin(), m_Actions.end()); + } else { + m_Actions.insert(m_Actions.begin() + msg.GetDstActionIndex(), msg.GetMigratedActions().begin(), msg.GetMigratedActions().end()); + } +}; + +template<> +void Strip::HandleMsg(MigrateActionsMessage& msg) { + if (msg.GetMigratedActions().empty() && !m_Actions.empty()) { + auto startToMove = m_Actions.begin() + msg.GetSrcActionIndex(); + msg.SetMigratedActions(startToMove, m_Actions.end()); + m_Actions.erase(startToMove, m_Actions.end()); + } else { + m_Actions.insert(m_Actions.begin() + msg.GetDstActionIndex(), msg.GetMigratedActions().begin(), msg.GetMigratedActions().end()); + } +}; + +void Strip::SendBehaviorBlocksToClient(AMFArrayValue& args) const { + m_Position.SendBehaviorBlocksToClient(args); + + auto* actions = args.InsertArray("actions"); + for (auto& action : m_Actions) { + action.SendBehaviorBlocksToClient(*actions); + } +}; diff --git a/dGame/dPropertyBehaviors/Strip.h b/dGame/dPropertyBehaviors/Strip.h new file mode 100644 index 000000000..f3e10964e --- /dev/null +++ b/dGame/dPropertyBehaviors/Strip.h @@ -0,0 +1,23 @@ +#ifndef __STRIP__H__ +#define __STRIP__H__ + +#include "Action.h" +#include "StripUiPosition.h" + +#include + +class AMFArrayValue; + +class Strip { +public: + template + void HandleMsg(Msg& msg); + + void SendBehaviorBlocksToClient(AMFArrayValue& args) const; + bool IsEmpty() const { return m_Actions.empty(); } +private: + std::vector m_Actions; + StripUiPosition m_Position; +}; + +#endif //!__STRIP__H__ From 2c23eeb34485894b1b0842fe584188af39586de9 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 3 Jan 2024 04:52:47 -0800 Subject: [PATCH 24/24] include amf3 its precompiled, but just in case --- dGame/dPropertyBehaviors/PropertyBehavior.cpp | 1 + dGame/dPropertyBehaviors/State.cpp | 1 + dGame/dPropertyBehaviors/Strip.cpp | 1 + 3 files changed, 3 insertions(+) diff --git a/dGame/dPropertyBehaviors/PropertyBehavior.cpp b/dGame/dPropertyBehaviors/PropertyBehavior.cpp index ee191ba17..f6f6e4f1f 100644 --- a/dGame/dPropertyBehaviors/PropertyBehavior.cpp +++ b/dGame/dPropertyBehaviors/PropertyBehavior.cpp @@ -1,5 +1,6 @@ #include "PropertyBehavior.h" +#include "Amf3.h" #include "BehaviorStates.h" #include "ControlBehaviorMsgs.h" diff --git a/dGame/dPropertyBehaviors/State.cpp b/dGame/dPropertyBehaviors/State.cpp index f696c169e..59a9aa8bf 100644 --- a/dGame/dPropertyBehaviors/State.cpp +++ b/dGame/dPropertyBehaviors/State.cpp @@ -1,5 +1,6 @@ #include "State.h" +#include "Amf3.h" #include "ControlBehaviorMsgs.h" template<> diff --git a/dGame/dPropertyBehaviors/Strip.cpp b/dGame/dPropertyBehaviors/Strip.cpp index bf7def097..7d27cacd4 100644 --- a/dGame/dPropertyBehaviors/Strip.cpp +++ b/dGame/dPropertyBehaviors/Strip.cpp @@ -1,5 +1,6 @@ #include "Strip.h" +#include "Amf3.h" #include "ControlBehaviorMsgs.h" template<>