diff --git a/ChaosMod/ChaosMod.vcxproj b/ChaosMod/ChaosMod.vcxproj
index 6d21948f5..22f89ab7e 100644
--- a/ChaosMod/ChaosMod.vcxproj
+++ b/ChaosMod/ChaosMod.vcxproj
@@ -407,6 +407,7 @@
+
@@ -496,6 +497,7 @@
+
diff --git a/ChaosMod/Components/EffectDispatchTimer.cpp b/ChaosMod/Components/EffectDispatchTimer.cpp
new file mode 100644
index 000000000..37db56d68
--- /dev/null
+++ b/ChaosMod/Components/EffectDispatchTimer.cpp
@@ -0,0 +1,223 @@
+#include
+
+#include "Components/EffectDispatchTimer.h"
+#include "Components/EffectDispatcher.h"
+#include "Components/MetaModifiers.h"
+
+#include "Util/OptionsManager.h"
+
+EffectDispatchTimer::EffectDispatchTimer(const std::array &timerColor) : Component()
+{
+ m_TimerColor = timerColor;
+
+ m_EffectSpawnTime = g_OptionsManager.GetConfigValue({ "NewEffectSpawnTime" }, OPTION_DEFAULT_EFFECT_SPAWN_TIME);
+
+ m_DistanceChaosState.EnableDistanceBasedEffectDispatch = g_OptionsManager.GetConfigValue(
+ { "EnableDistanceBasedEffectDispatch" }, OPTION_DEFAULT_DISTANCE_BASED_DISPATCH_ENABLED);
+ m_DistanceChaosState.DistanceToActivateEffect =
+ g_OptionsManager.GetConfigValue({ "DistanceToActivateEffect" }, OPTION_DEFAULT_EFFECT_SPAWN_DISTANCE);
+ m_DistanceChaosState.DistanceType = static_cast(
+ g_OptionsManager.GetConfigValue({ "DistanceType" }, OPTION_DEFAULT_DISTANCE_TYPE));
+}
+
+void EffectDispatchTimer::UpdateTimer(int deltaTime)
+{
+ if (!m_EnableTimer || (ComponentExists() && GetComponent()->DisableChaos))
+ {
+ return;
+ }
+
+ m_TimerPercentage += deltaTime
+ * (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f)
+ / m_EffectSpawnTime / 1000;
+
+ if (m_TimerPercentage >= 1.f && m_DispatchEffectsOnTimer && ComponentExists())
+ {
+ GetComponent()->DispatchRandomEffect();
+
+ if (ComponentExists())
+ {
+ for (std::uint8_t i = 0; i < GetComponent()->AdditionalEffectsToDispatch; i++)
+ {
+ GetComponent()->DispatchRandomEffect();
+ }
+ }
+
+ m_TimerPercentage = 0.f;
+ }
+}
+
+void EffectDispatchTimer::UpdateTravelledDistance()
+{
+ auto player = PLAYER_PED_ID();
+ auto position = GET_ENTITY_COORDS(player, false);
+
+ if (ComponentExists() && GetComponent()->DisableChaos)
+ {
+ m_DistanceChaosState.SavedPosition = position;
+ return;
+ }
+
+ if (IS_ENTITY_DEAD(player, false))
+ {
+ m_DistanceChaosState.DeadFlag = true;
+ return;
+ }
+
+ if (m_DistanceChaosState.DeadFlag)
+ {
+ m_DistanceChaosState.DeadFlag = false;
+ m_DistanceChaosState.SavedPosition = GET_ENTITY_COORDS(player, false);
+ return;
+ }
+
+ auto distance =
+ GET_DISTANCE_BETWEEN_COORDS(position.x, position.y, position.z, m_DistanceChaosState.SavedPosition.x,
+ m_DistanceChaosState.SavedPosition.y, m_DistanceChaosState.SavedPosition.z, true);
+
+ if (m_DistanceChaosState.DistanceType == DistanceChaosState::TravelledDistanceType::Displacement)
+ {
+ if (distance * (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f)
+ >= m_DistanceChaosState.DistanceToActivateEffect)
+ {
+ if (m_DispatchEffectsOnTimer && ComponentExists())
+ {
+ GetComponent()->DispatchRandomEffect();
+
+ if (ComponentExists())
+ {
+ for (std::uint8_t i = 0; i < GetComponent()->AdditionalEffectsToDispatch; i++)
+ {
+ GetComponent()->DispatchRandomEffect();
+ }
+ }
+ }
+
+ m_DistanceChaosState.SavedPosition = position;
+ }
+
+ m_TimerPercentage =
+ (distance * (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f))
+ / m_DistanceChaosState.DistanceToActivateEffect;
+ }
+ else if (m_DistanceChaosState.DistanceType == DistanceChaosState::TravelledDistanceType::Distance)
+ {
+ m_DistanceChaosState.SavedPosition = position;
+ m_TimerPercentage +=
+ (distance * (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f))
+ / m_DistanceChaosState.DistanceToActivateEffect;
+
+ if (m_TimerPercentage >= 1.f && m_DispatchEffectsOnTimer && ComponentExists())
+ {
+ GetComponent()->DispatchRandomEffect();
+
+ if (ComponentExists())
+ {
+ for (std::uint8_t i = 0; i < GetComponent()->AdditionalEffectsToDispatch; i++)
+ {
+ GetComponent()->DispatchRandomEffect();
+ }
+ }
+
+ m_TimerPercentage = 0;
+ }
+ }
+}
+
+bool EffectDispatchTimer::IsTimerEnabled() const
+{
+ return m_EnableTimer;
+}
+
+void EffectDispatchTimer::SetTimerEnabled(bool state)
+{
+ m_EnableTimer = state;
+}
+
+std::uint64_t EffectDispatchTimer::GetTimer() const
+{
+ return m_Timer;
+}
+
+void EffectDispatchTimer::ResetTimer()
+{
+ m_TimerPercentage = 0.f;
+ m_Timer = GetTickCount64();
+}
+
+int EffectDispatchTimer::GetRemainingTimerTime() const
+{
+ return std::ceil(m_EffectSpawnTime
+ / (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f)
+ * (1 - m_TimerPercentage));
+}
+
+bool EffectDispatchTimer::ShouldDispatchEffectNow() const
+{
+ return GetRemainingTimerTime() <= 0;
+}
+
+void EffectDispatchTimer::SetShouldDispatchEffects(bool state)
+{
+ m_DispatchEffectsOnTimer = state;
+}
+
+void EffectDispatchTimer::SetFakeTimerPercentage(float percentage)
+{
+ m_FakeTimerPercentage = std::clamp(percentage, 0.f, 1.f);
+}
+
+void EffectDispatchTimer::ResetFakeTimerPercentage()
+{
+ m_FakeTimerPercentage = 0.f;
+}
+
+void EffectDispatchTimer::OnRun()
+{
+ if (!m_EnableTimer
+ || (ComponentExists()
+ && (GetComponent()->HideChaosUI || GetComponent()->DisableChaos)))
+ {
+ return;
+ }
+
+ float percentage = m_FakeTimerPercentage != 0.f ? m_FakeTimerPercentage : m_TimerPercentage;
+
+ // New Effect Bar
+ DRAW_RECT(.5f, .01f, 1.f, .021f, 0, 0, 0, 127, false);
+
+ if (ComponentExists() && GetComponent()->FlipChaosUI)
+ {
+ DRAW_RECT(1.f - percentage * .5f, .01f, percentage, .018f, m_TimerColor[0], m_TimerColor[1], m_TimerColor[2],
+ 255, false);
+ }
+ else
+ {
+ DRAW_RECT(percentage * .5f, .01f, percentage, .018f, m_TimerColor[0], m_TimerColor[1], m_TimerColor[2], 255,
+ false);
+ }
+
+ auto currentUpdateTime = GetTickCount64();
+ int deltaTime = currentUpdateTime
+ - (ComponentExists() ? GetComponent()->GetTimer() : 0);
+
+ // the game was paused
+ if (deltaTime > 1000)
+ {
+ deltaTime = 0;
+ }
+
+ if (!m_PauseTimer)
+ {
+ if (m_DistanceChaosState.EnableDistanceBasedEffectDispatch)
+ {
+ UpdateTravelledDistance();
+ }
+ else
+ {
+ UpdateTimer(deltaTime);
+ }
+ }
+
+ m_Timer = currentUpdateTime;
+}
\ No newline at end of file
diff --git a/ChaosMod/Components/EffectDispatchTimer.h b/ChaosMod/Components/EffectDispatchTimer.h
new file mode 100644
index 000000000..081e75233
--- /dev/null
+++ b/ChaosMod/Components/EffectDispatchTimer.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include "Components/Component.h"
+
+class EffectDispatchTimer : public Component
+{
+ private:
+ bool m_EnableTimer = true;
+ bool m_PauseTimer = false;
+ bool m_DispatchEffectsOnTimer = true;
+ std::uint16_t m_EffectSpawnTime = 0;
+ std::array m_TimerColor;
+ float m_TimerPercentage = 0.f;
+ float m_FakeTimerPercentage = 0.f;
+ std::uint64_t m_Timer = 0;
+
+ struct DistanceChaosState
+ {
+ bool DeadFlag = true;
+ bool EnableDistanceBasedEffectDispatch = false;
+ float DistanceToActivateEffect = 500.f;
+ enum class TravelledDistanceType
+ {
+ Distance,
+ Displacement
+ } DistanceType = TravelledDistanceType::Distance;
+ Vector3 SavedPosition = { 0.f, 0.f, 0.f };
+ } m_DistanceChaosState;
+
+ protected:
+ EffectDispatchTimer(const std::array &timerColor);
+
+ private:
+ void UpdateTimer(int deltaTime);
+ void UpdateTravelledDistance();
+
+ public:
+ bool IsTimerEnabled() const;
+ void SetTimerEnabled(bool state);
+
+ std::uint64_t GetTimer() const;
+ void ResetTimer();
+
+ int GetRemainingTimerTime() const;
+ bool ShouldDispatchEffectNow() const;
+
+ void SetShouldDispatchEffects(bool state);
+
+ void SetFakeTimerPercentage(float percentage);
+ void ResetFakeTimerPercentage();
+
+ virtual void OnRun() override;
+
+ template
+ requires std::is_base_of_v
+ friend struct ComponentHolder;
+};
\ No newline at end of file
diff --git a/ChaosMod/Components/EffectDispatcher.cpp b/ChaosMod/Components/EffectDispatcher.cpp
index 0c05970c1..3884938a0 100644
--- a/ChaosMod/Components/EffectDispatcher.cpp
+++ b/ChaosMod/Components/EffectDispatcher.cpp
@@ -3,6 +3,7 @@
#include "EffectDispatcher.h"
#include "Mp3Manager.h"
+#include "Components/EffectDispatchTimer.h"
#include "Components/MetaModifiers.h"
#include "Effects/EffectCategory.h"
@@ -190,7 +191,8 @@ static void _OnRunEffects(LPVOID data)
while (true)
{
auto currentUpdateTime = GetTickCount64();
- int deltaTime = currentUpdateTime - effectDispatcher->Timer;
+ int deltaTime = currentUpdateTime
+ - (ComponentExists() ? GetComponent()->GetTimer() : 0);
// the game was paused
if (deltaTime > 1000)
@@ -206,7 +208,7 @@ static void _OnRunEffects(LPVOID data)
effectDispatcher->UpdateEffects(deltaTime);
- if (!effectDispatcher->PauseTimer)
+ if (!ComponentExists() || GetComponent()->IsTimerEnabled())
{
effectDispatcher->UpdateMetaEffects(deltaTime);
}
@@ -215,11 +217,9 @@ static void _OnRunEffects(LPVOID data)
}
}
-EffectDispatcher::EffectDispatcher(const std::array &timerColor, const std::array &textColor,
- const std::array &effectTimerColor)
+EffectDispatcher::EffectDispatcher(const std::array &textColor, const std::array &effectTimerColor)
: Component()
{
- m_TimerColor = timerColor;
m_TextColor = textColor;
m_EffectTimerColor = effectTimerColor;
@@ -227,7 +227,6 @@ EffectDispatcher::EffectDispatcher(const std::array &timerColor, const
m_DisableDrawEffectTexts =
g_OptionsManager.GetConfigValue({ "DisableEffectTextDraw" }, OPTION_DEFAULT_NO_TEXT_DRAW);
- m_EffectSpawnTime = g_OptionsManager.GetConfigValue({ "NewEffectSpawnTime" }, OPTION_DEFAULT_EFFECT_SPAWN_TIME);
SharedState.EffectTimedDur = g_OptionsManager.GetConfigValue({ "EffectTimedDur" }, OPTION_DEFAULT_EFFECT_TIMED_DUR);
SharedState.EffectTimedShortDur =
g_OptionsManager.GetConfigValue({ "EffectTimedShortDur" }, OPTION_DEFAULT_EFFECT_SHORT_TIMED_DUR);
@@ -239,13 +238,6 @@ EffectDispatcher::EffectDispatcher(const std::array &timerColor, const
SharedState.MetaEffectShortDur =
g_OptionsManager.GetConfigValue({ "MetaShortEffectDur" }, OPTION_DEFAULT_EFFECT_META_SHORT_TIMED_DUR);
- m_DistanceChaosState.EnableDistanceBasedEffectDispatch = g_OptionsManager.GetConfigValue(
- { "EnableDistanceBasedEffectDispatch" }, OPTION_DEFAULT_DISTANCE_BASED_DISPATCH_ENABLED);
- m_DistanceChaosState.DistanceToActivateEffect =
- g_OptionsManager.GetConfigValue({ "DistanceToActivateEffect" }, OPTION_DEFAULT_EFFECT_SPAWN_DISTANCE);
- m_DistanceChaosState.DistanceType = static_cast(
- g_OptionsManager.GetConfigValue({ "DistanceType" }, OPTION_DEFAULT_DISTANCE_TYPE));
-
m_MaxRunningEffects =
g_OptionsManager.GetConfigValue({ "MaxParallelRunningEffects" }, OPTION_DEFAULT_MAX_RUNNING_PARALLEL_EFFECTS);
@@ -280,142 +272,12 @@ void EffectDispatcher::OnModPauseCleanup()
void EffectDispatcher::OnRun()
{
- auto currentUpdateTime = GetTickCount64();
- int deltaTime = currentUpdateTime - Timer;
-
- // the game was paused
- if (deltaTime > 1000)
- {
- deltaTime = 0;
- }
-
- if (!PauseTimer)
- {
- if (m_DistanceChaosState.EnableDistanceBasedEffectDispatch)
- {
- UpdateTravelledDistance();
- }
- else
- {
- UpdateTimer(deltaTime);
- }
- }
-
- DrawTimerBar();
-
if (g_EffectDispatcherThread)
{
SwitchToFiber(g_EffectDispatcherThread);
}
DrawEffectTexts();
-
- Timer = currentUpdateTime;
-}
-
-void EffectDispatcher::UpdateTravelledDistance()
-{
- auto player = PLAYER_PED_ID();
- auto position = GET_ENTITY_COORDS(player, false);
-
- if (ComponentExists() && GetComponent()->DisableChaos)
- {
- m_DistanceChaosState.SavedPosition = position;
- return;
- }
-
- if (IS_ENTITY_DEAD(player, false))
- {
- m_DeadFlag = true;
- return;
- }
-
- if (m_DeadFlag)
- {
- m_DeadFlag = false;
- m_DistanceChaosState.SavedPosition = GET_ENTITY_COORDS(player, false);
- return;
- }
-
- auto distance =
- GET_DISTANCE_BETWEEN_COORDS(position.x, position.y, position.z, m_DistanceChaosState.SavedPosition.x,
- m_DistanceChaosState.SavedPosition.y, m_DistanceChaosState.SavedPosition.z, true);
-
- if (m_DistanceChaosState.DistanceType == DistanceChaosState::TravelledDistanceType::Displacement)
- {
- if (distance * (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f)
- >= m_DistanceChaosState.DistanceToActivateEffect)
- {
- if (DispatchEffectsOnTimer)
- {
- DispatchRandomEffect();
-
- if (ComponentExists())
- {
- for (int i = 0; i < GetComponent()->AdditionalEffectsToDispatch; i++)
- {
- DispatchRandomEffect();
- }
- }
- }
-
- m_DistanceChaosState.SavedPosition = position;
- }
-
- m_TimerPercentage =
- (distance * (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f))
- / m_DistanceChaosState.DistanceToActivateEffect;
- }
- else if (m_DistanceChaosState.DistanceType == DistanceChaosState::TravelledDistanceType::Distance)
- {
- m_DistanceChaosState.SavedPosition = position;
- m_TimerPercentage +=
- (distance * (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f))
- / m_DistanceChaosState.DistanceToActivateEffect;
-
- if (m_TimerPercentage >= 1.f && DispatchEffectsOnTimer)
- {
- DispatchRandomEffect();
-
- if (ComponentExists())
- {
- for (int i = 0; i < GetComponent()->AdditionalEffectsToDispatch; i++)
- {
- DispatchRandomEffect();
- }
- }
-
- m_TimerPercentage = 0;
- }
- }
-}
-
-void EffectDispatcher::UpdateTimer(int deltaTime)
-{
- if (!m_EnableNormalEffectDispatch
- || (ComponentExists() && GetComponent()->DisableChaos))
- {
- return;
- }
-
- m_TimerPercentage += deltaTime
- * (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f)
- / m_EffectSpawnTime / 1000;
-
- if (m_TimerPercentage >= 1.f && DispatchEffectsOnTimer)
- {
- DispatchRandomEffect();
-
- if (ComponentExists())
- {
- for (int i = 0; i < GetComponent()->AdditionalEffectsToDispatch; i++)
- {
- DispatchRandomEffect();
- }
- }
-
- m_TimerPercentage = 0.f;
- }
}
void EffectDispatcher::UpdateEffects(int deltaTime)
@@ -587,33 +449,6 @@ void EffectDispatcher::UpdateMetaEffects(int deltaTime)
}
}
-void EffectDispatcher::DrawTimerBar()
-{
- if (!m_EnableNormalEffectDispatch || m_DisableDrawTimerBar
- || (ComponentExists()
- && (GetComponent()->HideChaosUI || GetComponent()->DisableChaos)))
- {
- return;
- }
-
- float percentage =
- FakeTimerBarPercentage > 0.f && FakeTimerBarPercentage <= 1.f ? FakeTimerBarPercentage : m_TimerPercentage;
-
- // New Effect Bar
- DRAW_RECT(.5f, .01f, 1.f, .021f, 0, 0, 0, 127, false);
-
- if (ComponentExists() && GetComponent()->FlipChaosUI)
- {
- DRAW_RECT(1.f - percentage * .5f, .01f, percentage, .018f, m_TimerColor[0], m_TimerColor[1], m_TimerColor[2],
- 255, false);
- }
- else
- {
- DRAW_RECT(percentage * .5f, .01f, percentage, .018f, m_TimerColor[0], m_TimerColor[1], m_TimerColor[2], 255,
- false);
- }
-}
-
void EffectDispatcher::DrawEffectTexts()
{
if (m_DisableDrawEffectTexts)
@@ -690,18 +525,6 @@ void EffectDispatcher::DrawEffectTexts()
}
}
-bool EffectDispatcher::ShouldDispatchEffectNow() const
-{
- return GetRemainingTimerTime() <= 0;
-}
-
-int EffectDispatcher::GetRemainingTimerTime() const
-{
- return std::ceil(m_EffectSpawnTime
- / (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f)
- * (1 - m_TimerPercentage));
-}
-
void EffectDispatcher::DispatchEffect(const EffectIdentifier &effectIdentifier, DispatchEffectFlags dispatchEffectFlags,
const std::string &suffix)
{
@@ -830,18 +653,11 @@ std::vector EffectDispatcher::GetRecentEffects(int distance,
void EffectDispatcher::Reset(ClearEffectsFlags clearEffectFlags)
{
ClearEffects(clearEffectFlags);
- ResetTimer();
SharedState.MetaEffectsEnabled = true;
SharedState.MetaEffectTimerPercentage = 0.f;
}
-void EffectDispatcher::ResetTimer()
-{
- m_TimerPercentage = 0.f;
- Timer = GetTickCount64();
-}
-
float EffectDispatcher::GetEffectTopSpace()
{
return EnableEffectTextExtraTopSpace ? EFFECT_TEXT_TOP_SPACING_EXTRA : EFFECT_TEXT_TOP_SPACING;
diff --git a/ChaosMod/Components/EffectDispatcher.h b/ChaosMod/Components/EffectDispatcher.h
index 08d80ed8b..23237ed2d 100644
--- a/ChaosMod/Components/EffectDispatcher.h
+++ b/ChaosMod/Components/EffectDispatcher.h
@@ -81,19 +81,6 @@ class EffectDispatcher : public Component
bool MetaEffectsEnabled = true;
} SharedState;
- private:
- struct DistanceChaosState
- {
- Vector3 SavedPosition = { 0.f, 0.f, 0.f };
- enum class TravelledDistanceType
- {
- Distance,
- Displacement
- } DistanceType = TravelledDistanceType::Distance;
- float DistanceToActivateEffect = 500.f;
- bool EnableDistanceBasedEffectDispatch = false;
- } m_DistanceChaosState;
-
public:
ChaosCancellableEvent OnPreDispatchEffect;
ChaosEvent OnPostDispatchEffect;
@@ -104,16 +91,9 @@ class EffectDispatcher : public Component
private:
std::vector m_PermanentEffects;
- std::uint16_t m_EffectSpawnTime = 0;
-
- public:
- std::uint64_t Timer = 0;
-
private:
int m_MaxRunningEffects = 0;
- float m_TimerPercentage = 0.f;
-
enum class ClearEffectsState
{
None,
@@ -121,31 +101,20 @@ class EffectDispatcher : public Component
AllRestartPermanent
} m_ClearEffectsState = ClearEffectsState::None;
- public:
- float FakeTimerBarPercentage = 0.f;
-
private:
- std::array m_TimerColor;
std::array m_TextColor;
std::array m_EffectTimerColor;
bool m_DisableDrawTimerBar = false;
bool m_DisableDrawEffectTexts = false;
- bool m_DeadFlag = true;
-
bool m_EnableNormalEffectDispatch = false;
public:
- bool PauseTimer = false;
-
- bool DispatchEffectsOnTimer = true;
-
bool EnableEffectTextExtraTopSpace = false;
protected:
- EffectDispatcher(const std::array &timerColor, const std::array &textColor,
- const std::array &effectTimerColor);
+ EffectDispatcher(const std::array &textColor, const std::array &effectTimerColor);
virtual ~EffectDispatcher() override;
private:
@@ -157,13 +126,8 @@ class EffectDispatcher : public Component
virtual void OnModPauseCleanup() override;
virtual void OnRun() override;
- void DrawTimerBar();
void DrawEffectTexts();
- bool ShouldDispatchEffectNow() const;
-
- int GetRemainingTimerTime() const;
-
void DispatchEffect(const EffectIdentifier &effectIdentifier,
DispatchEffectFlags dispatchEffectFlags = DispatchEffectFlag_None,
const std::string &suffix = {});
@@ -173,7 +137,6 @@ class EffectDispatcher : public Component
void UpdateTimer(int deltaTime);
void UpdateEffects(int deltaTime);
void UpdateMetaEffects(int deltaTime);
- void UpdateTravelledDistance();
void ClearEffect(const EffectIdentifier &effectId);
enum ClearEffectsFlags
@@ -189,7 +152,6 @@ class EffectDispatcher : public Component
std::vector GetRecentEffects(int distance, std::string_view ignoreEffect = {}) const;
void Reset(ClearEffectsFlags clearEffectFlags = ClearEffectsFlag_None);
- void ResetTimer();
void OverrideEffectName(std::string_view effectId, const std::string &overrideName);
void OverrideEffectNameId(std::string_view effectId, std::string_view fakeEffectId);
diff --git a/ChaosMod/Components/Failsafe.h b/ChaosMod/Components/Failsafe.h
index 5b046a9e4..faa5fc437 100644
--- a/ChaosMod/Components/Failsafe.h
+++ b/ChaosMod/Components/Failsafe.h
@@ -7,14 +7,13 @@
class Failsafe : public Component
{
private:
- bool m_Enabled = false;
+ CHAOS_EVENT_LISTENER(Hooks::OnScriptThreadRun) m_SearchFailGlobalListener;
- char m_FailCounts = 0;
- int m_FailTimestamp = 0;
- int m_LastState = -1;
int *m_StateGlobal = nullptr;
-
- CHAOS_EVENT_LISTENER(Hooks::OnScriptThreadRun) m_SearchFailGlobalListener;
+ int m_LastState = -1;
+ int m_FailTimestamp = 0;
+ char m_FailCounts = 0;
+ bool m_Enabled = false;
protected:
Failsafe();
diff --git a/ChaosMod/Components/Voting.cpp b/ChaosMod/Components/Voting.cpp
index e449758c1..54fcdcfb2 100644
--- a/ChaosMod/Components/Voting.cpp
+++ b/ChaosMod/Components/Voting.cpp
@@ -2,6 +2,8 @@
#include "Voting.h"
+#include "Components/EffectDispatchTimer.h"
+#include "Components/EffectDispatcher.h"
#include "Components/MetaModifiers.h"
#include "Components/SplashTexts.h"
@@ -39,7 +41,7 @@ void Voting::OnModPauseCleanup()
void Voting::OnRun()
{
- if (!m_EnableVoting || !ComponentExists())
+ if (!m_EnableVoting || !ComponentExists() || !ComponentExists())
{
return;
}
@@ -140,7 +142,7 @@ void Voting::OnRun()
return;
}
- if (GetComponent()->GetRemainingTimerTime() <= 1 && !m_HasReceivedResult)
+ if (GetComponent()->GetRemainingTimerTime() <= 1 && !m_HasReceivedResult)
{
// Get vote result 1 second before effect is supposed to dispatch
@@ -151,7 +153,7 @@ void Voting::OnRun()
SendToPipe("getvoteresult");
}
}
- else if (GetComponent()->ShouldDispatchEffectNow())
+ else if (GetComponent()->ShouldDispatchEffectNow())
{
// End of voting round; dispatch resulted effect
@@ -164,7 +166,7 @@ void Voting::OnRun()
{
GetComponent()->DispatchEffect(*m_ChosenEffectIdentifier);
}
- GetComponent()->ResetTimer();
+ GetComponent()->ResetTimer();
if (ComponentExists())
{
@@ -178,7 +180,7 @@ void Voting::OnRun()
}
else if (!m_IsVotingRunning && m_ReceivedHello
&& (m_SecsBeforeVoting == 0
- || GetComponent()->GetRemainingTimerTime() <= m_SecsBeforeVoting)
+ || GetComponent()->GetRemainingTimerTime() <= m_SecsBeforeVoting)
&& m_IsVotingRoundDone)
{
// New voting round
@@ -407,9 +409,9 @@ void Voting::HandleMsg(std::string_view message)
LOG("Received hello from voting pipe");
- if (ComponentExists())
+ if (ComponentExists())
{
- GetComponent()->DispatchEffectsOnTimer = false;
+ GetComponent()->SetShouldDispatchEffects(false);
}
SendToPipe("hello_back");
@@ -481,9 +483,10 @@ void Voting::ErrorOutWithMsg(std::string_view message)
CloseHandle(m_PipeHandle);
m_PipeHandle = INVALID_HANDLE_VALUE;
- if (ComponentExists())
+ if (ComponentExists())
{
- GetComponent()->DispatchEffectsOnTimer = true;
+ GetComponent()->SetShouldDispatchEffects(true);
}
+
m_EnableVoting = false;
}
\ No newline at end of file
diff --git a/ChaosMod/Components/Voting.h b/ChaosMod/Components/Voting.h
index c75081d98..c3a2de37d 100644
--- a/ChaosMod/Components/Voting.h
+++ b/ChaosMod/Components/Voting.h
@@ -1,7 +1,6 @@
#pragma once
#include "Components/Component.h"
-#include "Components/EffectDispatcher.h"
#include
#include
diff --git a/ChaosMod/Effects/db/Misc/MiscFakeCrash.cpp b/ChaosMod/Effects/db/Misc/MiscFakeCrash.cpp
index 5015e170b..7fcacd488 100644
--- a/ChaosMod/Effects/db/Misc/MiscFakeCrash.cpp
+++ b/ChaosMod/Effects/db/Misc/MiscFakeCrash.cpp
@@ -1,6 +1,6 @@
#include
-#include "Components/EffectDispatcher.h"
+#include "Components/EffectDispatchTimer.h"
static void SleepAllThreads(DWORD ms)
{
@@ -52,9 +52,9 @@ static void OnStart()
if (fakeTimer)
{
- if (ComponentExists())
+ if (ComponentExists())
{
- GetComponent()->FakeTimerBarPercentage = g_Random.GetRandomFloat(0.f, 1.f);
+ GetComponent()->SetFakeTimerPercentage(g_Random.GetRandomFloat(0.f, 1.f));
}
WAIT(0);
@@ -74,9 +74,9 @@ static void OnStart()
SleepAllThreads(g_Random.GetRandomInt(3000, 10000));
- if (fakeTimer && ComponentExists())
+ if (fakeTimer && ComponentExists())
{
- GetComponent()->FakeTimerBarPercentage = 0.f;
+ GetComponent()->ResetFakeTimerPercentage();
}
}
diff --git a/ChaosMod/Info.h b/ChaosMod/Info.h
index 308d22b0f..705c7f734 100644
--- a/ChaosMod/Info.h
+++ b/ChaosMod/Info.h
@@ -1,3 +1,3 @@
#pragma once
-#define MOD_VERSION "2.1.2"
\ No newline at end of file
+#define MOD_VERSION "2.2-dev"
\ No newline at end of file
diff --git a/ChaosMod/Main.cpp b/ChaosMod/Main.cpp
index 7b7bd1975..953220f30 100644
--- a/ChaosMod/Main.cpp
+++ b/ChaosMod/Main.cpp
@@ -11,6 +11,7 @@
#include "Components/DebugMenu.h"
#include "Components/DebugSocket.h"
+#include "Components/EffectDispatchTimer.h"
#include "Components/EffectDispatcher.h"
#include "Components/EffectShortcuts.h"
#include "Components/Failsafe.h"
@@ -61,26 +62,6 @@ static void ParseEffectsFile()
EffectConfig::ReadConfig("chaosmod/configs/effects.ini", g_EnabledEffects, { "chaosmod/effects.ini" });
}
-static void Reset()
-{
- if (ComponentExists())
- {
- GetComponent()->Reset();
- while (GetComponent()->IsClearingEffects())
- {
- GetComponent()->OnRun();
- WAIT(0);
- }
- }
-
- ClearEntityPool();
-
- for (auto component : g_Components)
- {
- component->OnModPauseCleanup();
- }
-}
-
static void Init()
{
// Attempt to print game build number
@@ -202,7 +183,9 @@ static void Init()
INIT_COMPONENT("LuaScripts", "Lua scripts", LuaScripts);
- INIT_COMPONENT("EffectDispatcher", "effects dispatcher", EffectDispatcher, timerColor, textColor, effectTimerColor);
+ INIT_COMPONENT("EffectDispatcher", "effects dispatcher", EffectDispatcher, textColor, effectTimerColor);
+
+ INIT_COMPONENT("EffectDispatchTimer", "effects dispatch timer", EffectDispatchTimer, timerColor);
INIT_COMPONENT("DebugMenu", "debug menu", DebugMenu);
@@ -237,9 +220,7 @@ static void MainRun()
Memory::RunLateHooks();
}
- g_MainThread = GetCurrentFiber();
-
- Reset();
+ g_MainThread = GetCurrentFiber();
ms_Flags.ToggleModState = g_OptionsManager.GetConfigValue({ "DisableStartup" }, OPTION_DEFAULT_DISABLE_STARTUP);
@@ -274,6 +255,7 @@ static void MainRun()
if (ComponentExists())
{
+ GetComponent()->SetTimerEnabled(false);
GetComponent()->Reset(
EffectDispatcher::ClearEffectsFlag_NoRestartPermanentEffects);
while (GetComponent()->IsClearingEffects())
@@ -283,7 +265,12 @@ static void MainRun()
}
}
- Reset();
+ ClearEntityPool();
+
+ for (auto component : g_Components)
+ {
+ component->OnModPauseCleanup();
+ }
}
else
{
@@ -313,6 +300,7 @@ static void MainRun()
if (ComponentExists())
{
+ GetComponent()->ResetTimer();
GetComponent()->Reset();
while (GetComponent()->IsClearingEffects())
{
@@ -384,9 +372,10 @@ namespace Main
}
else if (key == VK_OEM_PERIOD)
{
- if (ms_Flags.PauseTimerShortcutEnabled && ComponentExists())
+ if (ms_Flags.PauseTimerShortcutEnabled && ComponentExists())
{
- GetComponent()->PauseTimer = !GetComponent()->PauseTimer;
+ GetComponent()->SetTimerEnabled(
+ !GetComponent()->IsTimerEnabled());
}
}
else if (key == VK_OEM_COMMA)
diff --git a/ConfigApp/EffectConfig.xaml.cs b/ConfigApp/EffectConfig.xaml.cs
index 77d3f6f0a..4faed211f 100644
--- a/ConfigApp/EffectConfig.xaml.cs
+++ b/ConfigApp/EffectConfig.xaml.cs
@@ -34,7 +34,7 @@ public EffectConfig(string? effectId, EffectData? effectData, EffectInfo effectI
if (m_IsTimedEffect)
{
- effectconf_timer_type_enable.IsChecked = m_EffectData.TimedType != null;
+ effectconf_timer_type_enable.IsChecked = m_EffectData.TimedType.HasValue;
effectconf_timer_type.ItemsSource = new string[]
{
"Normal",
@@ -48,7 +48,7 @@ public EffectConfig(string? effectId, EffectData? effectData, EffectInfo effectI
EffectTimedType.Permanent => 2,
_ => 0,
};
- if (m_EffectData.CustomTime >= 0)
+ if (m_EffectData.CustomTime > 0)
{
effectconf_timer_time_enable.IsChecked = true;
effectconf_timer_time.Text = $"{m_EffectData.CustomTime}";
@@ -211,8 +211,8 @@ private void CheckEnableConfigurables()
effectconf_timer_time_enable.IsEnabled = false;
}
- effectconf_timer_type.IsEnabled = effectconf_timer_type_enable.IsChecked.GetValueOrDefault(false);
- effectconf_timer_time.IsEnabled = effectconf_timer_time_enable.IsChecked.GetValueOrDefault(false);
+ effectconf_timer_type.IsEnabled = effectconf_timer_type_enable.IsEnabled && effectconf_timer_type_enable.IsChecked.GetValueOrDefault(false);
+ effectconf_timer_time.IsEnabled = effectconf_timer_time_enable.IsEnabled && effectconf_timer_time_enable.IsChecked.GetValueOrDefault(false);
}
private void OnClicked(object sender, RoutedEventArgs e)
@@ -258,7 +258,7 @@ private void NoCopyPastePreviewExecuted(object sender, ExecutedRoutedEventArgs e
public EffectData GetNewData()
{
- if (effectconf_timer_type_enable.IsChecked.HasValue && effectconf_timer_type_enable.IsChecked.Value)
+ if (effectconf_timer_type_enable.IsChecked.GetValueOrDefault(false))
{
m_EffectData.TimedType = (object)effectconf_timer_type.SelectedIndex switch
{
diff --git a/ConfigApp/Info.cs b/ConfigApp/Info.cs
index 12c0897e8..46e527670 100644
--- a/ConfigApp/Info.cs
+++ b/ConfigApp/Info.cs
@@ -2,7 +2,7 @@
{
public static class Info
{
- public const string VERSION = "2.1.2";
+ public const string VERSION = "2.2-dev";
public const string WORKSHOP_DEFAULT_URL = "https://chaos.gopong.dev";
}
diff --git a/ConfigApp/Utils.cs b/ConfigApp/Utils.cs
index c01139f6b..c6f894fad 100644
--- a/ConfigApp/Utils.cs
+++ b/ConfigApp/Utils.cs
@@ -30,7 +30,7 @@ public static EffectData ValueStringToEffectData(string? value)
if (Enum.TryParse(values[1], out Effects.EffectTimedType timedType))
{
- effectData.TimedType = timedType;
+ effectData.TimedType = timedType != Effects.EffectTimedType.NotTimed ? timedType : null;
}
if (int.TryParse(values[2], out int customTime))
{