Skip to content

Commit 128c808

Browse files
committed
feat(extra-natives-rdr3): Allow scenario usage without gender check
1 parent 2aefad7 commit 128c808

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

code/components/extra-natives-rdr3/src/NativeFixes.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,21 @@
1010

1111
#include <ScriptEngine.h>
1212
#include <Hooking.h>
13+
#include "Hooking.Stubs.h"
1314
#include <scrEngine.h>
1415
#include <CrossBuildRuntime.h>
1516
#include "RageParser.h"
1617
#include "ScriptWarnings.h"
1718
#include <EntitySystem.h>
19+
#include <CoreConsole.h>
1820
#include <vector>
1921

2022
static bool* g_textCentre;
2123
static bool* g_textDropshadow;
2224

25+
static bool g_skipScenarioMaleCheck = false;
26+
static bool g_skipScenarioFemaleCheck = false;
27+
2328
struct netObject
2429
{
2530
char pad[64]; // +0
@@ -149,6 +154,44 @@ static void FixPedCombatAttributes()
149154
});
150155
}
151156

157+
static InitFunction initFunction([]()
158+
{
159+
static ConVar<bool> g_skipScenarioMaleCheckConVar("sv_skipScenarioMaleCheck", ConVar_Replicated, false, &g_skipScenarioMaleCheck);
160+
static ConVar<bool> g_skipScenarioFemaleCheckConVar("sv_skipScenarioFemaleCheck", ConVar_Replicated, false, &g_skipScenarioFemaleCheck);
161+
});
162+
163+
static hook::cdecl_stub<bool(CPed* ped)> hasPlayerComponent([]()
164+
{
165+
return hook::get_pattern("0F 95 C0 C3 48 83 EC ? 83 F9", -40);
166+
});
167+
168+
169+
static bool (*g_origCAIConditionIsMale)(void* self, void* context);
170+
static bool CAIConditionIsMale(void* self, void* context)
171+
{
172+
int v3 = *(int*)((char*)self + 16);
173+
CPed* ped = *(CPed**)((char*)context + 192 + (8 * v3));
174+
175+
if (g_skipScenarioMaleCheck && ped && hasPlayerComponent(ped))
176+
{
177+
return true;
178+
}
179+
return g_origCAIConditionIsMale(self, context);
180+
}
181+
182+
static bool (*g_origCAIConditionIsFemale)(void* self, void* context);
183+
static bool CAIConditionIsFemale(void* self, void* context)
184+
{
185+
int v3 = *(int*)((char*)self + 16);
186+
CPed* ped = *(CPed**)((char*)context + 192 + (8 * v3));
187+
188+
if (g_skipScenarioFemaleCheck && ped && hasPlayerComponent(ped))
189+
{
190+
return true;
191+
}
192+
return g_origCAIConditionIsFemale(self, context);
193+
}
194+
152195
static HookFunction hookFunction([]()
153196
{
154197
{
@@ -216,4 +259,10 @@ static HookFunction hookFunction([]()
216259
// mov rax, [r14] (restore rax value from r14)
217260
hook::put((char*)location + 10, 0x068B49);
218261
}
262+
263+
{
264+
// Allow players to use scenario without checking the gender
265+
g_origCAIConditionIsFemale = hook::trampoline(hook::get_pattern("48 F7 DA 48 1B C0 48 23 C1 8A 40 ? C0 E8 ? F6 D0 24 ? EB ? 49 8B C8", -0x30), CAIConditionIsFemale);
266+
g_origCAIConditionIsMale = hook::trampoline(hook::get_pattern("48 F7 DA 48 1B C0 48 23 C1 8A 40 ? C0 E8 ? 24 ? EB", -0x4F), CAIConditionIsMale);
267+
}
219268
});

0 commit comments

Comments
 (0)