From c19ee04c8abdb9d761262c78e893e71f2f6cfc23 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Sun, 8 Jun 2025 19:41:43 -0700 Subject: [PATCH] fix: property behavior crashes (#1813) --- dCommon/DluAssert.h | 2 +- dGame/dPropertyBehaviors/Strip.cpp | 13 ++++++++++--- dGame/dPropertyBehaviors/Strip.h | 3 +++ dWorldServer/WorldServer.cpp | 4 ++-- dZoneManager/dZoneManager.h | 1 + 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/dCommon/DluAssert.h b/dCommon/DluAssert.h index f099443a..802c6d16 100644 --- a/dCommon/DluAssert.h +++ b/dCommon/DluAssert.h @@ -4,7 +4,7 @@ #include #ifdef _DEBUG -# define DluAssert(expression) do { assert(expression) } while(0) +# define DluAssert(expression) do { assert(expression); } while(0) #else # define DluAssert(expression) #endif diff --git a/dGame/dPropertyBehaviors/Strip.cpp b/dGame/dPropertyBehaviors/Strip.cpp index 5e90d2ba..8f5a6aaa 100644 --- a/dGame/dPropertyBehaviors/Strip.cpp +++ b/dGame/dPropertyBehaviors/Strip.cpp @@ -84,9 +84,11 @@ void Strip::HandleMsg(MigrateActionsMessage& msg) { template<> void Strip::HandleMsg(GameMessages::RequestUse& msg) { - if (m_PausedTime > 0.0f) return; + if (m_PausedTime > 0.0f || !HasMinimumActions()) return; - if (m_Actions[m_NextActionIndex].GetType() == "OnInteract") { + auto& nextAction = GetNextAction(); + + if (nextAction.GetType() == "OnInteract") { IncrementAction(); m_WaitingForAction = false; } @@ -170,7 +172,6 @@ void Strip::ProcNormalAction(float deltaTime, ModelComponent& modelComponent) { LOG("Tried to play action (%s) which is not supported.", nextActionType.data()); g_WarnedActions.insert(nextActionType.data()); } - return; } IncrementAction(); @@ -190,11 +191,17 @@ void Strip::RemoveStates(ModelComponent& modelComponent) const { } void Strip::Update(float deltaTime, ModelComponent& modelComponent) { + // No point in running a strip with only one action. + // Strips are also designed to have 2 actions or more to run. + if (!HasMinimumActions()) return; + + // Don't run this strip if we're paused. m_PausedTime -= deltaTime; if (m_PausedTime > 0.0f) return; m_PausedTime = 0.0f; + // Return here if we're waiting for external interactions to continue. if (m_WaitingForAction) return; auto& entity = *modelComponent.GetParent(); diff --git a/dGame/dPropertyBehaviors/Strip.h b/dGame/dPropertyBehaviors/Strip.h index 3f929a7d..6e4aa66d 100644 --- a/dGame/dPropertyBehaviors/Strip.h +++ b/dGame/dPropertyBehaviors/Strip.h @@ -33,6 +33,9 @@ public: void SpawnDrop(LOT dropLOT, Entity& entity); void ProcNormalAction(float deltaTime, ModelComponent& modelComponent); void RemoveStates(ModelComponent& modelComponent) const; + + // 2 actions are required for strips to work + bool HasMinimumActions() const { return m_Actions.size() >= 2; } private: // Indicates this Strip is waiting for an action to be taken upon it to progress to its actions bool m_WaitingForAction{ false }; diff --git a/dWorldServer/WorldServer.cpp b/dWorldServer/WorldServer.cpp index c83b82d7..9e9581b7 100644 --- a/dWorldServer/WorldServer.cpp +++ b/dWorldServer/WorldServer.cpp @@ -713,12 +713,12 @@ void HandleMasterPacket(Packet* packet) { //Create our user and send them in: UserManager::Instance()->CreateUser(it->second.sysAddr, username.GetAsString(), userHash); - auto zone = Game::zoneManager->GetZone(); - if (zone) { + if (Game::zoneManager->HasZone()) { float x = 0.0f; float y = 0.0f; float z = 0.0f; + auto zone = Game::zoneManager->GetZone(); if (zone->GetZoneID().GetMapID() == 1100) { auto pos = zone->GetSpawnPos(); x = pos.x; diff --git a/dZoneManager/dZoneManager.h b/dZoneManager/dZoneManager.h index f9abee8c..fc07a4b8 100644 --- a/dZoneManager/dZoneManager.h +++ b/dZoneManager/dZoneManager.h @@ -29,6 +29,7 @@ public: /* Gets a pointer to the currently loaded zone. */ Zone* GetZoneMut() const; const Zone* GetZone() const { return GetZoneMut(); }; + bool HasZone() const { return m_pZone != nullptr; }; void LoadZone(const LWOZONEID& zoneID); //Discard the current zone (if any) and loads a new zone. /* Adds a spawner to the zone with the specified ID. */