diff --git a/dGame/dComponents/ModelComponent.cpp b/dGame/dComponents/ModelComponent.cpp index 52682efb..0a5e6cd4 100644 --- a/dGame/dComponents/ModelComponent.cpp +++ b/dGame/dComponents/ModelComponent.cpp @@ -16,7 +16,7 @@ ModelComponent::ModelComponent(Entity* parent) : Component(parent) { m_OriginalPosition = m_Parent->GetDefaultPosition(); m_OriginalRotation = m_Parent->GetDefaultRotation(); m_IsPaused = false; - m_IsPickable = false; + m_NumListeningInteract = 0; m_userModelID = m_Parent->GetVarAs(u"userModelID"); RegisterMsg(MessageType::Game::REQUEST_USE, this, &ModelComponent::OnRequestUse); @@ -79,7 +79,7 @@ void ModelComponent::Serialize(RakNet::BitStream& outBitStream, bool bIsInitialU //actual model component: outBitStream.Write1(); // Yes we are writing model info - outBitStream.Write(m_IsPickable); // Is pickable + outBitStream.Write(m_NumListeningInteract > 0); // Is pickable outBitStream.Write(2); // Physics type outBitStream.Write(m_OriginalPosition); // Original position outBitStream.Write(m_OriginalRotation); // Original rotation @@ -158,3 +158,16 @@ std::array, 5> ModelComponent::GetBehaviorsForSa } return toReturn; } + +void ModelComponent::AddInteract() { + LOG("adding interact %i", m_NumListeningInteract); + m_Dirty = true; + m_NumListeningInteract++; +} + +void ModelComponent::RemoveInteract() { + DluAssert(m_NumListeningInteract > 0); + LOG("Removing interact %i", m_NumListeningInteract); + m_Dirty = true; + m_NumListeningInteract--; +} diff --git a/dGame/dComponents/ModelComponent.h b/dGame/dComponents/ModelComponent.h index 90f824e3..f4d0ffbb 100644 --- a/dGame/dComponents/ModelComponent.h +++ b/dGame/dComponents/ModelComponent.h @@ -119,7 +119,8 @@ public: const std::vector& GetBehaviors() const { return m_Behaviors; }; - void SetIsPickable(bool pickable) { m_Dirty = m_IsPickable == pickable; m_IsPickable = pickable; } + void AddInteract(); + void RemoveInteract(); void Pause() { m_Dirty = true; m_IsPaused = true; } @@ -127,7 +128,7 @@ public: private: bool m_Dirty{}; - bool m_IsPickable{}; + uint32_t m_NumListeningInteract{}; bool m_IsPaused{}; /** diff --git a/dGame/dPropertyBehaviors/Strip.cpp b/dGame/dPropertyBehaviors/Strip.cpp index 8a22184e..ea56dfa0 100644 --- a/dGame/dPropertyBehaviors/Strip.cpp +++ b/dGame/dPropertyBehaviors/Strip.cpp @@ -82,7 +82,10 @@ void Strip::HandleMsg(MigrateActionsMessage& msg) { template<> void Strip::HandleMsg(GameMessages::RequestUse& msg) { - if (m_Actions[m_NextActionIndex].GetType() == "OnInteract") IncrementAction(); + if (m_Actions[m_NextActionIndex].GetType() == "OnInteract") { + IncrementAction(); + m_WaitingForAction = false; + } } void Strip::IncrementAction() { @@ -135,6 +138,7 @@ void Strip::ProcNormalAction(float deltaTime, ModelComponent& modelComponent) { unsmash.duration = number; unsmash.builderID = LWOOBJID_EMPTY; unsmash.Send(UNASSIGNED_SYSTEM_ADDRESS); + m_PausedTime = number; } else if (nextAction.GetType() == "Wait") { m_PausedTime = number; } else { @@ -145,18 +149,35 @@ void Strip::ProcNormalAction(float deltaTime, ModelComponent& modelComponent) { IncrementAction(); } +// Decrement references to the previous state if we have progressed to the next one. +void Strip::RemoveStates(ModelComponent& modelComponent) const { + // Starting blocks can only be at index one, don't bother trying to remove them otherwise. + if (m_NextActionIndex != 1) return; + + if (GetPreviousAction().GetType() == "OnInteract") { + modelComponent.RemoveInteract(); + Game::entityManager->SerializeEntity(modelComponent.GetParent()); + } +} + void Strip::Update(float deltaTime, ModelComponent& modelComponent) { m_PausedTime -= deltaTime; if (m_PausedTime > 0.0f) return; m_PausedTime = 0.0f; + + if (m_WaitingForAction) return; + auto& entity = *modelComponent.GetParent(); auto& nextAction = GetNextAction(); + RemoveStates(modelComponent); + // Check for starting blocks and if not a starting block proc this blocks action if (nextAction.GetType() == "OnInteract") { - modelComponent.SetIsPickable(true); + modelComponent.AddInteract(); Game::entityManager->SerializeEntity(entity); + m_WaitingForAction = true; } else { // should be a normal block ProcNormalAction(deltaTime, modelComponent); } @@ -191,3 +212,9 @@ void Strip::Deserialize(const tinyxml2::XMLElement& strip) { action.Deserialize(*actionElement); } } + +const Action& Strip::GetPreviousAction() const { + DluAssert(m_NextActionIndex < m_Actions.size()); + size_t index = m_NextActionIndex == 0 ? m_Actions.size() - 1 : m_NextActionIndex - 1; + return m_Actions[index]; +} diff --git a/dGame/dPropertyBehaviors/Strip.h b/dGame/dPropertyBehaviors/Strip.h index 11b48682..d159fb59 100644 --- a/dGame/dPropertyBehaviors/Strip.h +++ b/dGame/dPropertyBehaviors/Strip.h @@ -28,13 +28,16 @@ public: const std::vector& GetActions() const { return m_Actions; } const Action& GetNextAction() const { DluAssert(m_NextActionIndex < m_Actions.size()); return m_Actions[m_NextActionIndex]; } + const Action& GetPreviousAction() const; void IncrementAction(); void Spawn(LOT object, Entity& entity); void Update(float deltaTime, ModelComponent& modelComponent); void SpawnDrop(LOT dropLOT, Entity& entity); void ProcNormalAction(float deltaTime, ModelComponent& modelComponent); + void RemoveStates(ModelComponent& modelComponent) const; private: + bool m_WaitingForAction{ false }; float m_PausedTime{ 0.0f }; size_t m_NextActionIndex{ 0 }; std::vector m_Actions;