Skip to content

Commit

Permalink
Added Crossing Challenge component
Browse files Browse the repository at this point in the history
Allows to set starting and ending point; controls respawning at the start on death and shows a congratulatory message upon reaching the end.
Also fixed a few bugs in the process.
  • Loading branch information
Regynate committed Jan 23, 2025
1 parent 51b4994 commit a0d2285
Show file tree
Hide file tree
Showing 8 changed files with 797 additions and 6 deletions.
616 changes: 616 additions & 0 deletions ChaosMod/Components/CrossingChallenge.cpp

Large diffs are not rendered by default.

105 changes: 105 additions & 0 deletions ChaosMod/Components/CrossingChallenge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#pragma once

#include <list>

#include "Component.h"
#include "Util/OptionsFile.h"
#include "Util/Text.h"

#define SPLASH_TEXT_DUR_SECS 10

class CrossingChallenge : public Component
{
private:
struct WeaponInfo
{
Hash hash;
int ammo;
};

OptionsFile m_ConfigFile { "chaosmod/configs/crossing.ini", { "chaosmod/crossing.ini" } };

bool m_Enabled = false;

int m_HelpMessageTick = -1;

bool m_CaptureStartFlag = false;
bool m_CaptureEndFlag = false;

int m_StartedState = 0;

bool m_WaitingConfirm = false;

bool m_StartEnabled = false;
Vector3 m_StartLocation = Vector3();
Hash m_StartVehicleHash = 0;
float m_StartHeading = 0.f;
float m_StartCameraHeading = 0.f;
Hash m_StartWeatherType1 = 0;
Hash m_StartWeatherType2 = 0;
float m_StartWeatherPercent = 0.f;
int m_ClockHours = 0;
int m_ClockMinutes = 0;
int m_ClockSeconds = 0;
std::vector<WeaponInfo> m_StartWeapons;

bool m_EndEnabled = false;
Vector3 m_EndLocation = Vector3();
float m_EndRadius = 0.f;

int m_ButtonsScaleformHandle = 0;
bool m_ButtonsScaleformLoading = false;

int m_PassedScaleformHandle = 0;
bool m_PassedScaleformLoading = false;
int m_PassedScaleformTick = 0;
bool m_PassedTransitionStarted = false;

Blip m_StartBlip = 0;
Blip m_EndBlip = 0;

DWORD m_TickCount = 0;
DWORD m_LastTick = 0;
int m_EffectsCount = 0;
bool m_TimerStarted = 0;

void ShowHint(const std::string &text);

void SetStartParams();
void ControlRespawn();

int m_PassedState = 0;

bool CheckEndReached() const;
void ShowPassedScaleform();
void ControlPassed();

void SaveConfig();

void CaptureStart();
void CaptureEnd();
void IncreaseEndRadius();
void DecreaseEndRadius();
bool IsEndValid() const;
void ShowEndCylinder() const;
void ShowHelpButtons();
void ShowBlips();

void ShowProgress() const;

public:
CrossingChallenge();

virtual void OnRun() override;
virtual void OnModPauseCleanup() override;
virtual void OnKeyInput(DWORD key, bool repeated, bool isUpNow, bool isCtrlPressed, bool isShiftPressed,
bool isAltPressed) override;
inline void IncrementEffects()
{
m_EffectsCount++;
}

template <class T>
requires std::is_base_of_v<Component, T>
friend struct ComponentHolder;
};
1 change: 1 addition & 0 deletions ChaosMod/Components/EffectDispatchTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ void EffectDispatchTimer::ResetTimer()
{
m_TimerPercentage = 0.f;
m_Timer = GetTickCount64();
m_DistanceChaosState.SavedPosition = GET_ENTITY_COORDS(PLAYER_PED_ID(), false);
}

int EffectDispatchTimer::GetRemainingTimerTime() const
Expand Down
3 changes: 3 additions & 0 deletions ChaosMod/Components/EffectDispatcher.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <stdafx.h>

#include "Components/CrossingChallenge.h"
#include "Components/EffectDispatchTimer.h"
#include "Components/EffectDispatcher.h"
#include "Components/EffectSound/EffectSoundManager.h"
Expand Down Expand Up @@ -525,6 +526,8 @@ void EffectDispatcher::DispatchEffect(const EffectIdentifier &effectId, Dispatch
const std::string &suffix)
{
EffectDispatchQueue.push({ .Id = effectId, .Suffix = suffix, .Flags = dispatchEffectFlags });
if (ComponentExists<CrossingChallenge>())
GetComponent<CrossingChallenge>()->IncrementEffects();
}

void EffectDispatcher::DispatchRandomEffect(DispatchEffectFlags dispatchEffectFlags, const std::string &suffix)
Expand Down
31 changes: 26 additions & 5 deletions ChaosMod/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "Main.h"

#include "Components/CrossingChallenge.h"
#include "Components/DebugMenu.h"
#include "Components/DebugSocket.h"
#include "Components/EffectDispatchTimer.h"
Expand Down Expand Up @@ -31,6 +32,7 @@ static struct
bool ClearEffectsShortcutEnabled = false;
bool ToggleModShortcutEnabled = false;
bool ToggleModState = false;
bool DisableMod = false;
bool PauseTimerShortcutEnabled = false;
bool HaveLateHooksRan = false;
bool AntiSoftlockShortcutEnabled = false;
Expand Down Expand Up @@ -204,6 +206,8 @@ static void Init()

INIT_COMPONENT("HelpTextQueue", "script help text queue", HelpTextQueue);

INIT_COMPONENT("CrossingChallenge", "Crossing Challenge", CrossingChallenge);

#ifdef WITH_DEBUG_PANEL_SUPPORT
if (DoesFeatureFlagExist("enabledebugsocket"))
INIT_COMPONENT("DebugSocket", "Debug Websocket", DebugSocket);
Expand All @@ -227,6 +231,15 @@ static void MainRun()

ms_Flags.ToggleModState = g_OptionsManager.GetConfigValue({ "DisableStartup" }, OPTION_DEFAULT_DISABLE_STARTUP);

if (!g_Components.empty())
{
for (auto component : g_Components)
component->OnModPauseCleanup();

g_Components.clear();
}
ClearEntityPool();

Init();

bool isDisabled = false;
Expand All @@ -246,10 +259,8 @@ static void MainRun()
}
}

if (ms_Flags.ToggleModState)
if (ms_Flags.ToggleModState || ms_Flags.DisableMod)
{
ms_Flags.ToggleModState = false;

if (!isDisabled)
{
isDisabled = true;
Expand All @@ -273,7 +284,7 @@ static void MainRun()
for (auto component : g_Components)
component->OnModPauseCleanup();
}
else
else if (ms_Flags.ToggleModState)
{
isDisabled = false;

Expand All @@ -288,6 +299,9 @@ static void MainRun()
// Restart the main part of the mod completely
Init();
}

ms_Flags.ToggleModState = false;
ms_Flags.DisableMod = false;
}

if (isDisabled)
Expand Down Expand Up @@ -323,8 +337,8 @@ static void MainRun()

for (auto component : g_Components)
component->OnRun();
}
}
}

namespace Main
{
Expand All @@ -337,6 +351,8 @@ namespace Main

void OnCleanup()
{
for (auto component : g_Components)
component->OnModPauseCleanup();
}

void OnKeyboardInput(DWORD key, WORD repeats, BYTE scanCode, BOOL isExtended, BOOL isWithAlt, BOOL wasDownBefore,
Expand Down Expand Up @@ -391,4 +407,9 @@ namespace Main
for (auto component : g_Components)
component->OnKeyInput(key, wasDownBefore, isUpNow, isCtrlPressed, isShiftPressed, isWithAlt);
}

void Stop()
{
ms_Flags.DisableMod = true;
}
}
1 change: 1 addition & 0 deletions ChaosMod/Main.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ namespace Main
void OnCleanup();
void OnKeyboardInput(DWORD key, WORD repeats, BYTE scanCode, BOOL isExtended, BOOL isWithAlt, BOOL wasDownBefore,
BOOL isUpNow);
void Stop();
}
39 changes: 38 additions & 1 deletion ChaosMod/Util/OptionsFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ class OptionsFile
{
private:
const char *m_FileName;
const char *m_FoundFileName;
std::vector<const char *> m_CompatFileNames;
std::unordered_map<std::string, std::string> m_Options;

public:
OptionsFile(const char *fileName, std::vector<const char *> compatFileNames = {})
: m_FileName(fileName), m_CompatFileNames(compatFileNames)
: m_FileName(fileName), m_CompatFileNames(compatFileNames), m_FoundFileName("")
{
Reset();
}
Expand Down Expand Up @@ -57,13 +58,33 @@ class OptionsFile
bool dataRead = false;
for (auto compatFileName : m_CompatFileNames)
if ((dataRead = readData(compatFileName)))
{
m_FoundFileName = compatFileName;
break;
}

if (!dataRead)
LOG("Config file " << m_FileName << " not found!");
}
}

inline void WriteFile()
{
std::ofstream file(m_FoundFileName, std::ofstream::out | std::ofstream::trunc);
if (!file)
{
LOG("Couldn't write config file " << m_FileName);
return;
}
for (auto &[key, value] : m_Options)
file << key << "=" << value << std::endl;
}

template <typename T> inline T ReadValue(const std::string &key, T defaultValue) const
{
return ReadValue(std::vector<std::string> { key }, defaultValue);
}

template <typename T> inline T ReadValue(const std::vector<std::string> &keys, T defaultValue) const
{
for (const auto &key : keys)
Expand Down Expand Up @@ -93,4 +114,20 @@ class OptionsFile

return defaultValue;
}

inline void SetValueString(const std::string& szKey, const std::string& value)
{
if (m_Options.contains(szKey))
{
m_Options[szKey] = value;
}
else
{
m_Options.emplace(szKey, value);
}
}
template <typename T> inline void SetValue(const std::string& szKey, T value)
{
SetValueString(szKey, std::to_string(value));
}
};
7 changes: 7 additions & 0 deletions ConfigApp/Tabs/MiscTab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class MiscTab : Tab
private CheckBox? m_EnableDistanceBasedDispatch = null;
private TextBox? m_DistanceBasedDispatchDistance = null;
private ComboBox? m_DistanceBasedDispatchType = null;
private CheckBox? m_EnableCrossingChallenge = null;

private static ColorPicker GenerateCommonColorPicker(Color defaultColor)
{
Expand Down Expand Up @@ -125,6 +126,9 @@ protected override void InitContent()
"Displacement"
}
});
grid.PopRow();

grid.PushRowSpacedPair("Enable Crossing Challenge™", m_EnableCrossingChallenge = Utils.GenerateCommonCheckBox());

scrollViewer.Content = grid.Grid;

Expand Down Expand Up @@ -182,6 +186,8 @@ public override void OnLoadValues()
m_DistanceBasedDispatchDistance.Text = OptionsManager.ConfigFile.ReadValue("DistanceToActivateEffect", "250");
if (m_DistanceBasedDispatchType is not null)
m_DistanceBasedDispatchType.SelectedIndex = OptionsManager.ConfigFile.ReadValueInt("DistanceType", 0);
if (m_EnableCrossingChallenge is not null)
m_EnableCrossingChallenge.IsChecked = OptionsManager.ConfigFile.ReadValueBool("EnableCrossingChallenge", false);
}

public override void OnSaveValues()
Expand All @@ -208,6 +214,7 @@ public override void OnSaveValues()
OptionsManager.ConfigFile.WriteValue("EnableDistanceBasedEffectDispatch", m_EnableDistanceBasedDispatch?.IsChecked);
OptionsManager.ConfigFile.WriteValue("DistanceToActivateEffect", m_DistanceBasedDispatchDistance?.Text);
OptionsManager.ConfigFile.WriteValue("DistanceType", m_DistanceBasedDispatchType?.SelectedIndex);
OptionsManager.ConfigFile.WriteValue("EnableCrossingChallenge", m_EnableCrossingChallenge?.IsChecked);
}
}
}

0 comments on commit a0d2285

Please sign in to comment.