Skip to content

Commit

Permalink
ChaosMod: (Un-)break a bunch of stuff
Browse files Browse the repository at this point in the history
Simplified the ActiveEffect timer logic

Unbroke Debug builds

Some other stuff idfk
  • Loading branch information
pongo1231 committed Jan 16, 2025
1 parent db69426 commit fe33cc5
Show file tree
Hide file tree
Showing 16 changed files with 75 additions and 81 deletions.
3 changes: 2 additions & 1 deletion ChaosMod/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ target_precompile_headers(ChaosMod PUBLIC stdafx.cpp)
set_target_properties(ChaosMod PROPERTIES SUFFIX ".asi")
set_target_properties(ChaosMod PROPERTIES CXX_STANDARD 20)

target_compile_definitions(ChaosMod PUBLIC $<$<CONFIG:Debug>:_DEBUG>)
target_compile_definitions(ChaosMod PUBLIC $<$<CONFIG:Debug>:CHAOSDEBUG>)
target_compile_definitions(ChaosMod PUBLIC NDEBUG)

set(include_dirs ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/../vendor ${PROJECT_SOURCE_DIR}/../vendor/lua/include)
set(link_libs shv minhook lua54 winmm d3dcompiler xinput)
Expand Down
15 changes: 7 additions & 8 deletions ChaosMod/Components/EffectDispatchTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ EffectDispatchTimer::EffectDispatchTimer(const std::array<BYTE, 3> &timerColor)

void EffectDispatchTimer::UpdateTimer(int deltaTime)
{
if (!m_EnableTimer || (ComponentExists<MetaModifiers>() && GetComponent<MetaModifiers>()->DisableChaos))
return;

m_TimerPercentage += deltaTime
* (ComponentExists<MetaModifiers>() ? GetComponent<MetaModifiers>()->TimerSpeedModifier : 1.f)
/ m_EffectSpawnTime / 1000;
Expand All @@ -44,7 +47,7 @@ void EffectDispatchTimer::UpdateTravelledDistance()
auto player = PLAYER_PED_ID();
auto position = GET_ENTITY_COORDS(player, false);

if (ComponentExists<MetaModifiers>() && GetComponent<MetaModifiers>()->DisableChaos)
if (!m_EnableTimer || (ComponentExists<MetaModifiers>() && GetComponent<MetaModifiers>()->DisableChaos))
{
m_DistanceChaosState.SavedPosition = position;
return;
Expand Down Expand Up @@ -160,13 +163,9 @@ void EffectDispatchTimer::OnRun()
{
auto currentUpdateTime = GetTickCount64();

if (!m_EnableTimer || (ComponentExists<MetaModifiers>() && GetComponent<MetaModifiers>()->DisableChaos))
{
m_Timer = std::numeric_limits<std::uint64_t>::max();
return;
}

if (m_DrawTimerBar && (!ComponentExists<MetaModifiers>() || !GetComponent<MetaModifiers>()->HideChaosUI))
if (m_EnableTimer && m_DrawTimerBar
&& (!ComponentExists<MetaModifiers>() || !GetComponent<MetaModifiers>()->HideChaosUI)
&& (!ComponentExists<MetaModifiers>() || !GetComponent<MetaModifiers>()->DisableChaos))
{
float percentage = m_FakeTimerPercentage != 0.f ? m_FakeTimerPercentage : m_TimerPercentage;

Expand Down
71 changes: 30 additions & 41 deletions ChaosMod/Components/EffectDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define EFFECT_TEXT_INNER_SPACING_MAX .075f
#define EFFECT_TEXT_TOP_SPACING .2f
#define EFFECT_TEXT_TOP_SPACING_EXTRA .35f
#define EFFECT_NONTIMED_TIMER_SPEEDUP_MIN_EFFECTS 3

static void _DispatchEffect(EffectDispatcher *effectDispatcher, const EffectDispatcher::EffectDispatchEntry &entry)
{
Expand All @@ -26,7 +27,11 @@ static void _DispatchEffect(EffectDispatcher *effectDispatcher, const EffectDisp
if (!effectDispatcher->OnPreDispatchEffect.Fire(entry.Identifier))
return;

LOG("Dispatching effect \"" << effectData.Name << "\"");
LOG("Dispatching effect \"" << effectData.Name << "\""
#ifdef CHAOSDEBUG
<< " (" << effectData.Id << ")"
#endif
);

// Increase weight for all effects first
for (auto &[effectId, effectData] : g_EnabledEffects)
Expand Down Expand Up @@ -139,12 +144,14 @@ static void _DispatchEffect(EffectDispatcher *effectDispatcher, const EffectDisp
effectDuration = effectData.CustomTime;
break;
default:
effectDuration = -1;
effectDuration = effectData.IsMeta() ? effectDispatcher->SharedState.MetaEffectTimedDur
: effectDispatcher->SharedState.EffectTimedDur;
break;
}

auto &activeEffect = effectDispatcher->SharedState.ActiveEffects.emplace_back(
entry.Identifier, registeredEffect, effectName.str(), effectData, effectDuration);
entry.Identifier, registeredEffect, effectName.str(), effectData, effectDuration,
effectData.TimedType != EffectTimedType::NotTimed);

playEffectDispatchSound(activeEffect);

Expand All @@ -171,11 +178,9 @@ static void _OnRunEffects(LPVOID data)
auto effectDispatcher = reinterpret_cast<EffectDispatcher *>(data);
while (true)
{
auto currentUpdateTime = GetTickCount64();
int deltaTime = currentUpdateTime
- (ComponentExists<EffectDispatchTimer>() ? GetComponent<EffectDispatchTimer>()->GetTimer() : 0);

// the game was paused
int deltaTime = GetTickCount64()
- (!ComponentExists<EffectDispatchTimer>() ? 0 : GetComponent<EffectDispatchTimer>()->GetTimer());
// The game was paused
if (deltaTime > 1000)
deltaTime = 0;

Expand Down Expand Up @@ -272,26 +277,21 @@ void EffectDispatcher::UpdateEffects(int deltaTime)
for (auto threadId : m_PermanentEffects)
EffectThreads::RunThread(threadId);

float adjustedDeltaTime = (float)deltaTime / 1000;
float adjustedDeltaTime = deltaTime / 1000.f;

int maxEffects =
std::min((int)(floor((1.0f - GetEffectTopSpace()) / EFFECT_TEXT_INNER_SPACING_MIN) - 1), m_MaxRunningEffects);
int activeEffects = 0;
int effectCountToCheckCleaning = 3;
int maxEffects = m_MaxRunningEffects;
int activeEffects = 0;
// Reverse order to ensure the effects on top of the list are removed if activeEffects > maxEffects
for (auto it = SharedState.ActiveEffects.rbegin(); it != SharedState.ActiveEffects.rend();)
{
auto &activeEffect = *it;

bool isEffectPaused = EffectThreads::IsThreadPaused(activeEffect.ThreadId);

if (!EffectThreads::DoesThreadExist(activeEffect.ThreadId))
{
if (activeEffect.MaxTime > 0.f
|| (activeEffect.MaxTime < 0.f
&& activeEffect.Timer >= 0.f /* Timer > 0 for non-timed effects = remove */))
if (activeEffect.IsTimed || activeEffect.Timer <= 0.f)
{
// Effect thread doesn't exist anymore so just remove the effect from list
DEBUG_LOG("Discarding ActiveEffect " << activeEffect.Identifier.GetEffectId());
it = static_cast<decltype(it)>(SharedState.ActiveEffects.erase(std::next(it).base()));
continue;
}
Expand All @@ -315,9 +315,8 @@ void EffectDispatcher::UpdateEffects(int deltaTime)
effectSharedData->EffectCompletionPercentage =
activeEffect.Timer <= 0.f ? 1.f : 1.f - activeEffect.Timer / activeEffect.MaxTime;

if (ComponentExists<EffectSoundManager>() && activeEffect.SoundId && !activeEffect.HasSetSoundOptions)
if (ComponentExists<EffectSoundManager>() && activeEffect.SoundId)
{
activeEffect.HasSetSoundOptions = true;
GetComponent<EffectSoundManager>()->SetSoundOptions(activeEffect.SoundId,
effectSharedData->EffectSoundPlayOptions);
}
Expand Down Expand Up @@ -346,34 +345,24 @@ void EffectDispatcher::UpdateEffects(int deltaTime)
}
}

if (activeEffect.MaxTime > 0.f)
{
if (isEffectPaused)
activeEffect.Timer -= adjustedDeltaTime;

else
activeEffect.Timer -=
adjustedDeltaTime
/ (ComponentExists<MetaModifiers>() ? GetComponent<MetaModifiers>()->EffectDurationModifier : 1.f);
}
else
{
float t = SharedState.EffectTimedDur, m = maxEffects, n = effectCountToCheckCleaning;
// Ensure non-timed effects stay on screen for a certain amount of time
activeEffect.Timer += adjustedDeltaTime / t
* (1.f + (t / 5 - 1) * std::max(0.f, SharedState.ActiveEffects.size() - n) / (m - n));
}
activeEffect.Timer -=
(adjustedDeltaTime
/ (!ComponentExists<MetaModifiers>() ? 1.f : GetComponent<MetaModifiers>()->EffectDurationModifier))
* (activeEffect.IsTimed
? 1.f
: std::max(1.f, .5f * (activeEffects - EFFECT_NONTIMED_TIMER_SPEEDUP_MIN_EFFECTS + 3)));

if ((activeEffect.MaxTime > 0.f && activeEffect.Timer <= 0.f)
|| (!activeEffect.IsMeta && activeEffects > maxEffects))
if (activeEffect.Timer <= 0.f || (!activeEffect.IsMeta && activeEffects > maxEffects))
{
if (activeEffect.Timer < -60.f)
{
// Effect took over 60 seconds to stop, forcibly stop it in a blocking manner
DEBUG_LOG("Tiemout reached, forcefully stopping effect " << activeEffect.Identifier.GetEffectId());
EffectThreads::StopThreadImmediately(activeEffect.ThreadId);
}
else if (!activeEffect.IsStopping)
{
DEBUG_LOG("Stopping effect " << activeEffect.Identifier.GetEffectId());
EffectThreads::StopThread(activeEffect.ThreadId);
activeEffect.IsStopping = true;
}
Expand Down Expand Up @@ -490,7 +479,7 @@ void EffectDispatcher::DrawEffectTexts()
ScreenTextAdjust::Right, { .0f, .915f });
}

if (effect.MaxTime > 0.f)
if (effect.IsTimed)
{
if (ComponentExists<MetaModifiers>() && GetComponent<MetaModifiers>()->FlipChaosUI)
{
Expand Down Expand Up @@ -639,7 +628,7 @@ void EffectDispatcher::RegisterPermanentEffects()
auto *registeredEffect = GetRegisteredEffect(effectIdentifier);
if (registeredEffect)
{
auto threadId = EffectThreads::CreateThread(registeredEffect, true);
auto threadId = EffectThreads::CreateThread(registeredEffect);
m_PermanentEffects.push_back(threadId);
}
};
Expand Down
11 changes: 6 additions & 5 deletions ChaosMod/Components/EffectDispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ class EffectDispatcher : public Component
};
std::queue<EffectDispatchEntry> EffectDispatchQueue;

struct ActiveEffect
class ActiveEffect
{
public:
EffectIdentifier Identifier;

std::string Name;
Expand All @@ -46,6 +47,7 @@ class EffectDispatcher : public Component

float Timer = 0.f;
float MaxTime = 0.f;
bool IsTimed = false;

bool IsMeta = false;

Expand All @@ -56,18 +58,17 @@ class EffectDispatcher : public Component
bool HasSetSoundOptions = false;

ActiveEffect(const EffectIdentifier &effectIdentifier, RegisteredEffect *registeredEffect,
const std::string &name, const EffectData &effectData, float effectDuration)
const std::string &name, const EffectData &effectData, float effectDuration, bool isTimed)
{
Identifier = effectIdentifier;
Name = name;
FakeName = effectData.FakeName;
Timer = effectDuration;
MaxTime = effectDuration;
IsTimed = isTimed;
HideEffectName = effectData.ShouldHideRealNameOnStart();
IsMeta = effectData.IsMeta();

auto timedType = g_EnabledEffects.at(effectIdentifier).TimedType;
ThreadId = EffectThreads::CreateThread(registeredEffect, timedType != EffectTimedType::NotTimed);
ThreadId = EffectThreads::CreateThread(registeredEffect);
}
};
struct
Expand Down
1 change: 1 addition & 0 deletions ChaosMod/Components/EffectSound/EffectSound3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ void EffectSound3D::OnRun()
DWORD64 EffectSound3D::HandleSound(const std::string &soundFile)
{
auto &sound = m_Sounds[m_SoundIdCounter];
DEBUG_LOG("Playing sound for \"" << soundFile << "\" with ID " << m_SoundIdCounter);
if (ma_sound_init_from_file(&m_maEngine, soundFile.c_str(), MA_SOUND_FLAG_ASYNC, nullptr, nullptr, &sound.Handle)
!= MA_SUCCESS)
{
Expand Down
2 changes: 0 additions & 2 deletions ChaosMod/Components/LuaScripts.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

#include "Components/Component.h"

#include <numeric>

#define SOL_ALL_SAFETIES_ON 1
#define SOL_SAFE_NUMERICS 1
#include <sol/sol.hpp>
Expand Down
2 changes: 1 addition & 1 deletion ChaosMod/Components/SplashTexts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ SplashTexts::SplashTexts()

ShowSplash("Chaos Mod v" MOD_VERSION "\n\nSee credits.txt for a list of contributors", { .2f, .3f }, .65f,
{ 60, 245, 190 });
#ifdef _DEBUG
#ifdef CHAOSDEBUG
ShowSplash("DEBUG BUILD!", { .2f, .5f }, .7f, { 255, 0, 0 });
#endif

Expand Down
2 changes: 1 addition & 1 deletion ChaosMod/Components/Voting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ bool Voting::Init()
PROCESS_INFORMATION procInfo = {};

auto str = _wcsdup(VOTING_PROXY_START_ARGS);
#ifdef _DEBUG
#ifdef CHAOSDEBUG
DWORD attributes = NULL;
if (DoesFeatureFlagExist("forcenovotingconsole"))
attributes = CREATE_NO_WINDOW;
Expand Down
2 changes: 1 addition & 1 deletion ChaosMod/Effects/EffectConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ namespace EffectConfig
effectData.SetAttribute(EffectAttributes::IsMeta, effectInfo.ExecutionType == EffectExecutionType::Meta);
effectData.Name = effectInfo.Name;
effectData.SetAttribute(EffectAttributes::HideRealNameOnStart, effectInfo.HideRealNameOnStart);
#ifdef _DEBUG
#ifdef CHAOSDEBUG
effectData.ShortcutKeycode =
effectInfo.DebugShortcutKeycode ? effectInfo.DebugShortcutKeycode : configValues.Values.ShortcutKeycode;
#else
Expand Down
6 changes: 3 additions & 3 deletions ChaosMod/Effects/EffectThreads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ static auto _StopThreadImmediately(auto it)

namespace EffectThreads
{
LPVOID CreateThread(RegisteredEffect *effect, bool isTimed)
LPVOID CreateThread(RegisteredEffect *effect)
{
auto thread = std::make_unique<EffectThread>(effect, isTimed);
auto thread = std::make_unique<EffectThread>(effect);
auto threadId = thread->Thread;
m_Threads[threadId] = std::move(thread);
LOG(threadId);
DEBUG_LOG("Created Effect Thread " << threadId);

return threadId;
}
Expand Down
10 changes: 4 additions & 6 deletions ChaosMod/Effects/EffectThreads.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@ struct EffectThreadData
{
RegisteredEffect *Effect = nullptr;
bool HasOnStartExecuted = false;
bool IsRunning = false;
bool IsRunning = true;
bool HasStopped = false;

void *CallerFiber = nullptr;

EffectThreadSharedData SharedData;

EffectThreadData(RegisteredEffect *effect, bool isRunning) : Effect(effect), IsRunning(isRunning)
EffectThreadData(RegisteredEffect *effect) : Effect(effect)
{
}
};

namespace EffectThreads
{
LPVOID CreateThread(RegisteredEffect *effect, bool isTimed);
LPVOID CreateThread(RegisteredEffect *effect);

void StopThread(LPVOID threadId);
void StopThreadImmediately(LPVOID threadId);
Expand Down Expand Up @@ -75,7 +75,6 @@ inline void EffectThreadFunc(LPVOID data)
threadData.Effect->Tick();
}

SwitchToFiber(threadData.CallerFiber);
threadData.Effect->Stop();

threadData.HasStopped = true;
Expand All @@ -91,8 +90,7 @@ class EffectThread
LPVOID Thread = nullptr;
EffectThreadData ThreadData;

EffectThread(RegisteredEffect *effect, bool isTimed)
: ThreadData(effect, isTimed), Thread(CreateFiber(0, EffectThreadFunc, &ThreadData))
EffectThread(RegisteredEffect *effect) : ThreadData(effect), Thread(CreateFiber(0, EffectThreadFunc, &ThreadData))
{
}

Expand Down
2 changes: 1 addition & 1 deletion ChaosMod/Effects/EffectsInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct EffectInfo
bool IsTimed = false;
bool IsShortDuration = false;
bool HideRealNameOnStart = false;
#ifdef _DEBUG
#ifdef CHAOSDEBUG
int DebugShortcutKeycode = 0;
#endif
std::vector<std::string_view> IncompatibleWith;
Expand Down
2 changes: 1 addition & 1 deletion ChaosMod/Effects/db/Player/PlayerAutopilot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static void OnTick()
return;
}

#ifdef _DEBUG
#ifdef CHAOSDEBUG
// Draw debug go to line
if (ms_State == STATE_TO_COORDS)
{
Expand Down
8 changes: 3 additions & 5 deletions ChaosMod/Memory/Handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ using DWORD = unsigned long;
class Handle
{
private:
DWORD64 m_Addr;
uintptr_t m_Addr = 0;

public:
Handle() : m_Addr(0)
{
}
Handle(DWORD64 addr) : m_Addr(addr)
Handle() = default;
Handle(uintptr_t addr) : m_Addr(addr)
{
}

Expand Down
Loading

0 comments on commit fe33cc5

Please sign in to comment.