Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Crossing Challenge component #3699

Merged
merged 3 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
621 changes: 621 additions & 0 deletions ChaosMod/Components/CrossingChallenge.cpp

Large diffs are not rendered by default.

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

#include <list>

#include "Component.h"
#include "Components/EffectDispatcher.h"
#include "Util/OptionsFile.h"
#include "Util/Text.h"
#include "Util/Events.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;

CHAOS_EVENT_LISTENER(EffectDispatcher::OnPreDispatchEffect) m_OnPreDispatchEffectListener;

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
1 change: 1 addition & 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
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& key, const std::string& value)
{
if (m_Options.contains(key))
{
m_Options[key] = value;
}
else
{
m_Options.emplace(key, value);
}
}
template <typename T> inline void SetValue(const std::string& key, T value)
{
SetValueString(key, 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);
}
}
}