From 8f94412d6c902e5a05a569fe4f3886d62b47418f Mon Sep 17 00:00:00 2001 From: Reguas <64607261+Reguas@users.noreply.github.com> Date: Mon, 27 Jan 2025 18:53:44 +0300 Subject: [PATCH 1/4] Added effects "Time Based Timer" and "Distance Based Timer" --- ChaosMod/Components/EffectDispatchTimer.cpp | 59 ++++++++++++--- ChaosMod/Components/EffectDispatchTimer.h | 5 ++ ChaosMod/Components/MetaModifiers.h | 4 ++ .../Condition/ConditionUsingDistanceTimer.cpp | 11 +++ .../Condition/ConditionUsingTimeTimer.cpp | 11 +++ ChaosMod/Effects/Condition/EffectCondition.h | 2 + ChaosMod/Effects/db/Meta/MetaTimerMode.cpp | 71 +++++++++++++++++++ ChaosMod/Util/TimerMode.h | 6 ++ ConfigApp/Effects.cs | 2 + 9 files changed, 160 insertions(+), 11 deletions(-) create mode 100644 ChaosMod/Effects/Condition/ConditionUsingDistanceTimer.cpp create mode 100644 ChaosMod/Effects/Condition/ConditionUsingTimeTimer.cpp create mode 100644 ChaosMod/Effects/db/Meta/MetaTimerMode.cpp create mode 100644 ChaosMod/Util/TimerMode.h diff --git a/ChaosMod/Components/EffectDispatchTimer.cpp b/ChaosMod/Components/EffectDispatchTimer.cpp index 7988544c2..b9c8a64f1 100644 --- a/ChaosMod/Components/EffectDispatchTimer.cpp +++ b/ChaosMod/Components/EffectDispatchTimer.cpp @@ -26,9 +26,13 @@ void EffectDispatchTimer::UpdateTimer(int deltaTime) if (!m_EnableTimer || (ComponentExists() && GetComponent()->DisableChaos)) return; + int effectSpawnTime = ComponentExists() && GetComponent()->TimeToDispatchEffect > 0 + ? GetComponent()->TimeToDispatchEffect + : m_EffectSpawnTime; + m_TimerPercentage += deltaTime * (!ComponentExists() ? 1.f : GetComponent()->TimerSpeedModifier) - / m_EffectSpawnTime / 1000.f; + / effectSpawnTime / 1000.f; if (m_TimerPercentage >= 1.f && m_DispatchEffectsOnTimer && ComponentExists()) { @@ -66,14 +70,22 @@ void EffectDispatchTimer::UpdateTravelledDistance() return; } + int effectSpawnDistance = + ComponentExists() && GetComponent()->DistanceToDispatchEffect > 0 + ? GetComponent()->DistanceToDispatchEffect + : m_DistanceChaosState.DistanceToActivateEffect; + 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) + m_TimerPercentage = + (distance * (ComponentExists() ? GetComponent()->TimerSpeedModifier : 1.f)) + / effectSpawnDistance; + + if (m_TimerPercentage >= 1.f) { if (m_DispatchEffectsOnTimer && ComponentExists()) { @@ -86,17 +98,13 @@ void EffectDispatchTimer::UpdateTravelledDistance() 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; + / effectSpawnDistance; if (m_TimerPercentage >= 1.f && m_DispatchEffectsOnTimer && ComponentExists()) { @@ -121,6 +129,21 @@ void EffectDispatchTimer::SetTimerEnabled(bool state) m_EnableTimer = state; } +int EffectDispatchTimer::GetDefaultEffectSpawnTime() const +{ + return m_EffectSpawnTime; +} + +int EffectDispatchTimer::GetDefaultEffectSpawnDistance() const +{ + return m_DistanceChaosState.DistanceToActivateEffect; +} + +void EffectDispatchTimer::ResetSavedPosition() +{ + m_DistanceChaosState.SavedPosition = GET_ENTITY_COORDS(PLAYER_PED_ID(), false); +} + std::uint64_t EffectDispatchTimer::GetTimer() const { return m_Timer; @@ -203,10 +226,24 @@ void EffectDispatchTimer::OnRun() if (!m_PauseTimer) { - if (m_DistanceChaosState.EnableDistanceBasedEffectDispatch) - UpdateTravelledDistance(); - else + const TimerMode modeOverride = + ComponentExists() ? GetComponent()->OverrideTimerMode : TimerMode::None; + + switch (modeOverride) + { + case TimerMode::Time: UpdateTimer(deltaTime); + break; + case TimerMode::Distance: + UpdateTravelledDistance(); + break; + default: + if (m_DistanceChaosState.EnableDistanceBasedEffectDispatch) + UpdateTravelledDistance(); + else + UpdateTimer(deltaTime); + break; + } } m_Timer = curTime; diff --git a/ChaosMod/Components/EffectDispatchTimer.h b/ChaosMod/Components/EffectDispatchTimer.h index c45f7b9eb..9cf4c26b6 100644 --- a/ChaosMod/Components/EffectDispatchTimer.h +++ b/ChaosMod/Components/EffectDispatchTimer.h @@ -38,6 +38,11 @@ class EffectDispatchTimer : public Component bool IsTimerEnabled() const; void SetTimerEnabled(bool state); + int GetDefaultEffectSpawnTime() const; + int GetDefaultEffectSpawnDistance() const; + + void ResetSavedPosition(); + std::uint64_t GetTimer() const; void ResetTimer(); diff --git a/ChaosMod/Components/MetaModifiers.h b/ChaosMod/Components/MetaModifiers.h index d82825421..3dc20f4ce 100644 --- a/ChaosMod/Components/MetaModifiers.h +++ b/ChaosMod/Components/MetaModifiers.h @@ -1,6 +1,7 @@ #pragma once #include "Components/Component.h" +#include "Util/TimerMode.h" #include @@ -13,4 +14,7 @@ class MetaModifiers : public Component bool HideChaosUI = false; bool DisableChaos = false; bool FlipChaosUI = false; + TimerMode OverrideTimerMode = TimerMode::None; + int TimeToDispatchEffect = 0; + int DistanceToDispatchEffect = 0; }; \ No newline at end of file diff --git a/ChaosMod/Effects/Condition/ConditionUsingDistanceTimer.cpp b/ChaosMod/Effects/Condition/ConditionUsingDistanceTimer.cpp new file mode 100644 index 000000000..5d2e2c2d6 --- /dev/null +++ b/ChaosMod/Effects/Condition/ConditionUsingDistanceTimer.cpp @@ -0,0 +1,11 @@ +#include + +#include "Components/EffectDispatchTimer.h" +#include "Effects/Condition/EffectCondition.h" + +static bool OnCondition() +{ + return ComponentExists() && GetComponent()->IsUsingDistanceBasedDispatch(); +} + +REGISTER_EFFECT_CONDITION(EffectConditionType::UsingDistanceTimer, OnCondition); \ No newline at end of file diff --git a/ChaosMod/Effects/Condition/ConditionUsingTimeTimer.cpp b/ChaosMod/Effects/Condition/ConditionUsingTimeTimer.cpp new file mode 100644 index 000000000..938deb88e --- /dev/null +++ b/ChaosMod/Effects/Condition/ConditionUsingTimeTimer.cpp @@ -0,0 +1,11 @@ +#include + +#include "Components/EffectDispatchTimer.h" +#include "Effects/Condition/EffectCondition.h" + +static bool OnCondition() +{ + return ComponentExists() && !GetComponent()->IsUsingDistanceBasedDispatch(); +} + +REGISTER_EFFECT_CONDITION(EffectConditionType::UsingTimeTimer, OnCondition); \ No newline at end of file diff --git a/ChaosMod/Effects/Condition/EffectCondition.h b/ChaosMod/Effects/Condition/EffectCondition.h index b7cd5527c..d8f7ec511 100644 --- a/ChaosMod/Effects/Condition/EffectCondition.h +++ b/ChaosMod/Effects/Condition/EffectCondition.h @@ -7,6 +7,8 @@ enum class EffectConditionType { None, VotingEnabled, // Voting is enabled + UsingDistanceTimer, + UsingTimeTimer, }; #define REGISTER_EFFECT_CONDITION(conditionType, condition) \ diff --git a/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp b/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp new file mode 100644 index 000000000..67638db96 --- /dev/null +++ b/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp @@ -0,0 +1,71 @@ +/* + Effects by Regynate +*/ + +#include + +#include "Components/MetaModifiers.h" +#include "Effects/Register/RegisterEffect.h" +#include + +static void OnStop() +{ + if (ComponentExists()) + GetComponent()->OverrideTimerMode = TimerMode::None; + GetComponent()->DistanceToDispatchEffect = 0; + GetComponent()->TimeToDispatchEffect = 0; + if (ComponentExists()) + GetComponent()->ResetSavedPosition(); +} + +static void OnTick_Time() +{ + if (ComponentExists()) + GetComponent()->OverrideTimerMode = TimerMode::Time; + + int defaultDistance = ComponentExists() + ? GetComponent()->GetDefaultEffectSpawnDistance() + : 0; + GetComponent()->TimeToDispatchEffect = defaultDistance ? defaultDistance / 10 : 30; +} + +// clang-format off +REGISTER_EFFECT(nullptr, OnStop, OnTick_Time, + { + .Name = "Time Based Timer", + .Id = "meta_timer_timebased", + .IsTimed = true, + .IncompatibleWith = { "meta_timer_distancebased" }, + .ExecutionType = EffectExecutionType::Meta, + .ConditionType = EffectConditionType::UsingDistanceTimer + } +); +// clang-format on + +static void OnTick_Distance() +{ + if (ComponentExists()) + GetComponent()->OverrideTimerMode = TimerMode::Distance; + int defaultTime = + ComponentExists() ? GetComponent()->GetDefaultEffectSpawnTime() : 0; + GetComponent()->DistanceToDispatchEffect = defaultTime ? defaultTime * 10 : 300; +} + +static void OnStart_Distance() +{ + if (ComponentExists()) + GetComponent()->ResetSavedPosition(); +} + +// clang-format off +REGISTER_EFFECT(OnStart_Distance, OnStop, OnTick_Distance, + { + .Name = "Distance Based Timer", + .Id = "meta_timer_distancebased", + .IsTimed = true, + .IncompatibleWith = { "meta_timer_timebased" }, + .ExecutionType = EffectExecutionType::Meta, + .ConditionType = EffectConditionType::UsingTimeTimer + } +); +// clang-format on \ No newline at end of file diff --git a/ChaosMod/Util/TimerMode.h b/ChaosMod/Util/TimerMode.h new file mode 100644 index 000000000..d977740c8 --- /dev/null +++ b/ChaosMod/Util/TimerMode.h @@ -0,0 +1,6 @@ +enum class TimerMode +{ + None, + Time, + Distance +}; \ No newline at end of file diff --git a/ConfigApp/Effects.cs b/ConfigApp/Effects.cs index b6ac78741..dffd615be 100644 --- a/ConfigApp/Effects.cs +++ b/ConfigApp/Effects.cs @@ -414,6 +414,8 @@ public enum EffectTimedType { "screen_hueshift", new EffectInfo("Hue Shift", EffectCategory.Screen, true) }, { "player_copyforce", new EffectInfo("Use The Force", EffectCategory.Player, true, true) }, { "player_tptowaypointopposite", new EffectInfo("Teleport To The Opposite Side Of Waypoint", EffectCategory.Player) }, + { "meta_timer_distancebased", new EffectInfo("Distance Based Timer", EffectCategory.Meta, true) }, + { "meta_timer_timebased", new EffectInfo("Time Based Timer", EffectCategory.Meta, true) }, }; } } From d1617f9c7137b3b9c8470a44a8a8efb57ea54e4c Mon Sep 17 00:00:00 2001 From: Reguas <64607261+Reguas@users.noreply.github.com> Date: Mon, 27 Jan 2025 22:00:58 +0300 Subject: [PATCH 2/4] Timer mode effects: fix for MetaModifiers existence check --- ChaosMod/Effects/db/Meta/MetaTimerMode.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp b/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp index 67638db96..ff64ad7f4 100644 --- a/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp +++ b/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp @@ -10,8 +10,10 @@ static void OnStop() { - if (ComponentExists()) - GetComponent()->OverrideTimerMode = TimerMode::None; + if (!ComponentExists()) + return; + + GetComponent()->OverrideTimerMode = TimerMode::None; GetComponent()->DistanceToDispatchEffect = 0; GetComponent()->TimeToDispatchEffect = 0; if (ComponentExists()) @@ -20,8 +22,10 @@ static void OnStop() static void OnTick_Time() { - if (ComponentExists()) - GetComponent()->OverrideTimerMode = TimerMode::Time; + if (!ComponentExists()) + return; + + GetComponent()->OverrideTimerMode = TimerMode::Time; int defaultDistance = ComponentExists() ? GetComponent()->GetDefaultEffectSpawnDistance() @@ -44,8 +48,10 @@ REGISTER_EFFECT(nullptr, OnStop, OnTick_Time, static void OnTick_Distance() { - if (ComponentExists()) - GetComponent()->OverrideTimerMode = TimerMode::Distance; + if (!ComponentExists()) + return; + + GetComponent()->OverrideTimerMode = TimerMode::Distance; int defaultTime = ComponentExists() ? GetComponent()->GetDefaultEffectSpawnTime() : 0; GetComponent()->DistanceToDispatchEffect = defaultTime ? defaultTime * 10 : 300; From 938d945e59cff00a38332cb0656d86f9f6b5aea1 Mon Sep 17 00:00:00 2001 From: Regynate <64607261+Regynate@users.noreply.github.com> Date: Fri, 31 Jan 2025 13:15:47 +0300 Subject: [PATCH 3/4] Expose MetaModifiers::TimeToDispatchEffect and MetaModifiers::DistanceToDispatchEffect to Lua runtime --- ChaosMod/Components/EffectDispatchTimer.cpp | 2 +- ChaosMod/Components/LuaScripts.cpp | 3 ++- ChaosMod/Components/MetaModifiers.h | 2 +- ChaosMod/Effects/db/Meta/MetaTimerMode.cpp | 6 +++--- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ChaosMod/Components/EffectDispatchTimer.cpp b/ChaosMod/Components/EffectDispatchTimer.cpp index 51b0fa2a5..1ca8e5a67 100644 --- a/ChaosMod/Components/EffectDispatchTimer.cpp +++ b/ChaosMod/Components/EffectDispatchTimer.cpp @@ -228,7 +228,7 @@ void EffectDispatchTimer::OnRun() if (!m_PauseTimer) { const TimerMode modeOverride = - ComponentExists() ? GetComponent()->OverrideTimerMode : TimerMode::None; + ComponentExists() ? GetComponent()->TimerModeOverride : TimerMode::None; switch (modeOverride) { diff --git a/ChaosMod/Components/LuaScripts.cpp b/ChaosMod/Components/LuaScripts.cpp index c765a534f..59c63b4f8 100644 --- a/ChaosMod/Components/LuaScripts.cpp +++ b/ChaosMod/Components/LuaScripts.cpp @@ -580,7 +580,8 @@ void LuaScripts::SetupGlobalState() auto metaModifiersMetaTable = m_GlobalState.create_table_with( "EffectDurationModifier", P(EffectDurationModifier), "TimerSpeedModifier", P(TimerSpeedModifier), "AdditionalEffectsToDispatch", P(AdditionalEffectsToDispatch), "HideChaosUI", P(HideChaosUI), - "DisableChaos", P(DisableChaos), "FlipChaosUI", P(FlipChaosUI)); + "DisableChaos", P(DisableChaos), "FlipChaosUI", P(FlipChaosUI), "TimeToDispatchEffect", + P(TimeToDispatchEffect), "DistanceToDispatchEffect", P(DistanceToDispatchEffect)); #undef P metaModifiersMetaTable[sol::meta_function::new_index] = [] {}; metaModifiersMetaTable[sol::meta_function::index] = metaModifiersMetaTable; diff --git a/ChaosMod/Components/MetaModifiers.h b/ChaosMod/Components/MetaModifiers.h index 9c24f99f7..183110e19 100644 --- a/ChaosMod/Components/MetaModifiers.h +++ b/ChaosMod/Components/MetaModifiers.h @@ -16,7 +16,7 @@ class MetaModifiers : public Component bool DisableChaos = false; bool FlipChaosUI = false; VotingMode VotingModeOverride = VotingMode::None; - TimerMode OverrideTimerMode = TimerMode::None; + TimerMode TimerModeOverride = TimerMode::None; int TimeToDispatchEffect = 0; int DistanceToDispatchEffect = 0; }; \ No newline at end of file diff --git a/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp b/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp index ff64ad7f4..29100ecf4 100644 --- a/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp +++ b/ChaosMod/Effects/db/Meta/MetaTimerMode.cpp @@ -13,7 +13,7 @@ static void OnStop() if (!ComponentExists()) return; - GetComponent()->OverrideTimerMode = TimerMode::None; + GetComponent()->TimerModeOverride = TimerMode::None; GetComponent()->DistanceToDispatchEffect = 0; GetComponent()->TimeToDispatchEffect = 0; if (ComponentExists()) @@ -25,7 +25,7 @@ static void OnTick_Time() if (!ComponentExists()) return; - GetComponent()->OverrideTimerMode = TimerMode::Time; + GetComponent()->TimerModeOverride = TimerMode::Time; int defaultDistance = ComponentExists() ? GetComponent()->GetDefaultEffectSpawnDistance() @@ -51,7 +51,7 @@ static void OnTick_Distance() if (!ComponentExists()) return; - GetComponent()->OverrideTimerMode = TimerMode::Distance; + GetComponent()->TimerModeOverride = TimerMode::Distance; int defaultTime = ComponentExists() ? GetComponent()->GetDefaultEffectSpawnTime() : 0; GetComponent()->DistanceToDispatchEffect = defaultTime ? defaultTime * 10 : 300; From fc64ee1adff4c903f9fc4ef5dbd5ee068fc3b647 Mon Sep 17 00:00:00 2001 From: Regynate <64607261+Regynate@users.noreply.github.com> Date: Mon, 3 Feb 2025 10:35:38 +0300 Subject: [PATCH 4/4] Added Lua entries for VotingModeOverride and TimerModeOverride --- ChaosMod/Components/LuaScripts.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ChaosMod/Components/LuaScripts.cpp b/ChaosMod/Components/LuaScripts.cpp index 59c63b4f8..52c1ecadd 100644 --- a/ChaosMod/Components/LuaScripts.cpp +++ b/ChaosMod/Components/LuaScripts.cpp @@ -555,6 +555,11 @@ void LuaScripts::SetupGlobalState() "Integer", LuaNativeReturnType::Int, "String", LuaNativeReturnType::String, "Float", LuaNativeReturnType::Float, "Vector3", LuaNativeReturnType::Vector3); + m_GlobalState.new_enum("TimerMode", "None", TimerMode::None, "Time", TimerMode::Time, "Distance", TimerMode::Distance); + + m_GlobalState.new_enum("VotingMode", "None", VotingMode::None, "Majority", VotingMode::Majority, "Percentage", + VotingMode::Percentage, "Antimajority", VotingMode::Antimajority); + if (ComponentExists()) { auto getMetaModFactory = [](T &modifier) @@ -580,8 +585,9 @@ void LuaScripts::SetupGlobalState() auto metaModifiersMetaTable = m_GlobalState.create_table_with( "EffectDurationModifier", P(EffectDurationModifier), "TimerSpeedModifier", P(TimerSpeedModifier), "AdditionalEffectsToDispatch", P(AdditionalEffectsToDispatch), "HideChaosUI", P(HideChaosUI), - "DisableChaos", P(DisableChaos), "FlipChaosUI", P(FlipChaosUI), "TimeToDispatchEffect", - P(TimeToDispatchEffect), "DistanceToDispatchEffect", P(DistanceToDispatchEffect)); + "DisableChaos", P(DisableChaos), "FlipChaosUI", P(FlipChaosUI), "VotingModeOverride", P(VotingModeOverride), + "TimerModeOverride", P(TimerModeOverride), "TimeToDispatchEffect", P(TimeToDispatchEffect), + "DistanceToDispatchEffect", P(DistanceToDispatchEffect)); #undef P metaModifiersMetaTable[sol::meta_function::new_index] = [] {}; metaModifiersMetaTable[sol::meta_function::index] = metaModifiersMetaTable;