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

Add effects "Hello, this is Agatha" & "Dave Here" #3528

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions ChaosMod/ChaosMod.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
<ClCompile Include="Components\DebugMenu.cpp" />
<ClCompile Include="Components\DebugSocket.cpp" />
<ClCompile Include="Components\EffectShortcuts.cpp" />
<ClCompile Include="Components\Globals.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="Components\EffectDispatcher.cpp" />
<ClCompile Include="Effects\db\Meta\MetaAdditionalEffects.cpp" />
Expand All @@ -115,6 +116,7 @@
<ClCompile Include="Effects\db\Misc\MiscNoWaypoint.cpp" />
<ClCompile Include="Effects\db\Misc\MiscPause.cpp" />
<ClCompile Include="Effects\db\Misc\MiscPayRespects.cpp" />
<ClCompile Include="Effects\db\Misc\MiscPhoneCall.cpp" />
<ClCompile Include="Effects\db\Misc\MiscPortraitMode.cpp" />
<ClCompile Include="Effects\db\Misc\MiscNoSky.cpp" />
<ClCompile Include="Effects\db\Misc\MiscRampJam.cpp" />
Expand Down Expand Up @@ -413,6 +415,7 @@
<ClInclude Include="Components\DebugSocket.h" />
<ClInclude Include="Components\EffectDispatcher.h" />
<ClInclude Include="Components\EffectShortcuts.h" />
<ClInclude Include="Components\Globals.h" />
<ClInclude Include="Effects\EffectCategory.h" />
<ClInclude Include="Effects\EffectConfig.h" />
<ClInclude Include="Effects\EffectAttributes.h" />
Expand Down
71 changes: 71 additions & 0 deletions ChaosMod/Components/Globals.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <stdafx.h>

#include "Globals.h"

#include "Lib/scrThread.h"

#include "Memory/Script.h"

std::map<std::string, int> Globals::m_GlobalsIndexMap = {};
static std::vector<GlobalRegistration> m_GlobalsRegistration = {};

Globals::Globals() : Component()
{
REGISTER_GLOBAL("CellPhoneState", "dialogue_handler",
"2D 00 02 00 ? 52 ? ? 41 ? 72 08 2A 06 56 ? ? 52 ? ? 41 ? 71 08 20 56 ? ? 72", 6,
GlobalPatternIdiom::GLOBAL_U16);

REGISTER_GLOBAL("CellPhoneLock", "dialogue_handler",
"72 54 ? ? 5d ? ? ? 71 2c ? ? ? 2b 72 54 ? ? 77 54 ? ? 52 ? ? 25 ? 2c ? ? ? 53 ? ? 06 56 ? ? 52 ? ? 76", 2,
GlobalPatternIdiom::GLOBAL_U16);


m_SearchGlobalsListener.Register(
Hooks::OnScriptThreadRun,
[&](rage::scrThread *thread)
{
// Save a f**k-tonne of CPU resources by destructing the event listener when we no longer have anymore globals to find
if (m_GlobalsRegistration.size() <= 0)
{
m_SearchGlobalsListener.~ChaosEventListener();
return true;
}

auto match =
std::find_if(m_GlobalsRegistration.begin(), m_GlobalsRegistration.end(),
[&thread](GlobalRegistration &reg) { return reg.m_ScriptName == thread->GetName(); });

if (match == m_GlobalsRegistration.end())
return true;

GlobalRegistration searchedGlobal = *match;

auto program = Memory::ScriptThreadToProgram(thread);
if (program->m_CodeBlocks)
{
Handle handle = Memory::FindScriptPattern(searchedGlobal.m_Pattern, program);

if (!handle.IsValid())
{
LOG("Failed to find global \"" << searchedGlobal.m_Name << "\"");
}
else
{
int globalIndex;

if (searchedGlobal.m_PatternIdiom == GlobalPatternIdiom::GLOBAL_U16)
globalIndex = handle.At(searchedGlobal.m_Offset).Value<uint16_t>() & 0xFFFFFF;
else
globalIndex = handle.At(searchedGlobal.m_Offset).Value<uint32_t>() & 0xFFFFFF;

Globals::SetGlobalIndex(searchedGlobal.m_Name, globalIndex);

LOG("Found global \"" << searchedGlobal.m_Name << "\" (Global: " << globalIndex << ")");
}
}

m_GlobalsRegistration.erase(match);

return true;
});
}
66 changes: 66 additions & 0 deletions ChaosMod/Components/Globals.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once

#include "Components/Component.h"

#include "Memory/Hooks/ScriptThreadRunHook.h"

#include <map>
#include <vector>

enum GlobalPatternIdiom : uint8_t
{
GLOBAL_U16,
GLOBAL_U24
};

struct GlobalRegistration
{
public:
std::string m_Name;
std::string m_ScriptName;
std::string m_Pattern;
int m_Offset;
GlobalPatternIdiom m_PatternIdiom;

GlobalRegistration(std::string name, std::string scriptName, std::string pattern, int offset,
GlobalPatternIdiom patternIdiom)
: m_Name(name), m_ScriptName(scriptName), m_Pattern(pattern), m_Offset(offset), m_PatternIdiom(patternIdiom)
{
}
};

class Globals : public Component
{
private:
static std::map<std::string, int> m_GlobalsIndexMap;

CHAOS_EVENT_LISTENER(Hooks::OnScriptThreadRun) m_SearchGlobalsListener;

protected:
Globals();

public:
static void SetGlobalIndex(std::string name, int index)
{
m_GlobalsIndexMap.emplace(name, index);
}

template <typename T> static T *GetGlobalAddr(std::string name)
{
if (!m_GlobalsIndexMap.contains(name))
{
return nullptr;
}

auto it = m_GlobalsIndexMap.at(name);

return reinterpret_cast<T *>(Memory::GetGlobalPtr(it));
}

template <class T>
requires std::is_base_of_v<Component, T>
friend struct ComponentHolder;
};

#define REGISTER_GLOBAL(name, scriptName, pattern, patternOffset, patternIdiom) \
m_GlobalsRegistration.push_back({ name, scriptName, pattern, patternOffset, patternIdiom })
Loading