Skip to content

Commit a5ce6c2

Browse files
committed
Clothes Randomizer: Initial Implementation
1 parent f30ddc6 commit a5ce6c2

File tree

3 files changed

+153
-0
lines changed

3 files changed

+153
-0
lines changed

src/peds/clothes.cc

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#include "CPed.hh"
2+
#include "peds/clothes_Queue.hh"
3+
#include <Utils.hh>
4+
#include <CTheScripts.hh>
5+
6+
#include <common/config.hh>
7+
#include <common/logger.hh>
8+
#include <common/minhook.hh>
9+
#include <common/events.hh>
10+
11+
using namespace NativeLiterals;
12+
13+
class ClothesRandomizer
14+
{
15+
using Queue = ClothesRandomizer_Queue;
16+
17+
inline static bool m_CurrentlyRandomizing = false;
18+
19+
static constexpr uint32_t DRAWABLE_NATIVE
20+
= "GET_NUMBER_OF_PED_DRAWABLE_VARIATIONS"_joaat;
21+
static constexpr uint32_t TEXTURE_NATIVE
22+
= "GET_NUMBER_OF_PED_TEXTURE_VARIATIONS"_joaat;
23+
static constexpr uint32_t PROP_DRAW_NATIVE
24+
= "GET_NUMBER_OF_PED_PROP_DRAWABLE_VARIATIONS"_joaat;
25+
static constexpr uint32_t PROP_TEX_NATIVE
26+
= "GET_NUMBER_OF_PED_PROP_TEXTURE_VARIATIONS"_joaat;
27+
28+
29+
/*******************************************************/
30+
template <uint32_t NativeHash, typename... Args>
31+
static uint32_t
32+
Random (Args... args)
33+
{
34+
uint32_t max
35+
= NativeManager::InvokeNative<uint32_t> (NativeHash, args...);
36+
37+
return max == 0 ? 0 : RandomInt (max - 1);
38+
}
39+
40+
/*******************************************************/
41+
static void
42+
RandomizeComponent (uint32_t ped, int comp)
43+
{
44+
45+
int drawable = Random<DRAWABLE_NATIVE> (ped, comp);
46+
int texture = Random<TEXTURE_NATIVE> (ped, comp, drawable);
47+
48+
"SET_PED_COMPONENT_VARIATION"_n(ped, comp, drawable, texture,
49+
RandomInt (3));
50+
51+
if (comp >= 4)
52+
return;
53+
54+
int propDrawable = Random<PROP_DRAW_NATIVE> (ped, comp);
55+
int propTexture = Random<PROP_TEX_NATIVE> (ped, comp, propDrawable);
56+
57+
"SET_PED_PROP_INDEX"_n(ped, comp, propDrawable, propTexture, 1);
58+
}
59+
60+
/*******************************************************/
61+
static bool
62+
RandomizePedClothes (uint32_t ped)
63+
{
64+
for (int i = 0; i < 12; i++)
65+
RandomizeComponent(ped, i);
66+
67+
return true;
68+
}
69+
70+
/*******************************************************/
71+
static void
72+
ProcessUpgradesQueue (uint64_t *, uint64_t *, scrProgram *,
73+
scrThreadContext *ctx)
74+
{
75+
if (ctx->m_nScriptHash != "main"_joaat)
76+
return;
77+
78+
std::lock_guard guard (Queue::mMutex);
79+
80+
if (!Queue::mData.size())
81+
return;
82+
83+
m_CurrentlyRandomizing = true;
84+
if (RandomizePedClothes (Queue::mData.back ()))
85+
Queue::mData.pop_back ();
86+
m_CurrentlyRandomizing = false;
87+
}
88+
89+
/*******************************************************/
90+
template<auto& CPed__GetComponentVariation>
91+
static void ChangeClothesEvent (CPed* p1, uint32_t p2, uint8_t p3, uint32_t* p4, uint32_t* p5)
92+
{
93+
if (!m_CurrentlyRandomizing)
94+
Queue::Add (p1);
95+
96+
CPed__GetComponentVariation (p1, p2, p3, p4, p5);
97+
}
98+
99+
public:
100+
ClothesRandomizer ()
101+
{
102+
RB_C_DO_CONFIG_NO_OPTIONS ("ClothesRandomizer");
103+
104+
Rainbomizer::Events ().OnRunThread += ProcessUpgradesQueue;
105+
Rainbomizer::Events ().OnFade +=
106+
[] { Queue::Add (int ("PLAYER_PED_ID"_n())); };
107+
108+
REGISTER_HOOK ("89 44 ? ? e8 ? ? ? ? ? 8b ? ? ? 8b ? ? ? 8d ? ? ? 81 c2", 4,
109+
ChangeClothesEvent, void, CPed*, uint32_t, uint8_t, uint32_t*, uint32_t*);
110+
}
111+
} g_ClothesRandomizer;

src/peds/clothes_Queue.hh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include <vector>
4+
#include <mutex>
5+
#include <cstdint>
6+
7+
#include <CTheScripts.hh>
8+
#include <CPed.hh>
9+
10+
class ClothesRandomizer_Queue
11+
{
12+
inline static std::vector<uint32_t> mData;
13+
inline static std::mutex mMutex;
14+
15+
public:
16+
/*******************************************************/
17+
static void
18+
Add (CPed *ped)
19+
{
20+
Add (fwScriptGuid::CreateGuid (ped));
21+
}
22+
23+
/*******************************************************/
24+
static void
25+
Add (uint32_t idx)
26+
{
27+
std::lock_guard guard (mMutex);
28+
for (auto i : mData)
29+
{
30+
if (i == idx)
31+
return;
32+
}
33+
34+
mData.push_back (idx);
35+
}
36+
37+
friend class ClothesRandomizer;
38+
};

src/peds/peds.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "peds.hh"
2+
#include "clothes_Queue.hh"
23

34
#include <cstdint>
45
#include <mutex>
@@ -13,6 +14,7 @@
1314
#include "CModelInfo.hh"
1415
#include "Utils.hh"
1516
#include "common/logger.hh"
17+
#include "peds/clothes_Queue.hh"
1618

1719
#include <CStreaming.hh>
1820

@@ -134,6 +136,8 @@ class PedRandomizer
134136
ped, PR::Config ().RandomizeSpecialAbility,
135137
PR::Config ().IncludeUnusedAbilities);
136138

139+
ClothesRandomizer_Queue::Add (ped);
140+
137141
return ped;
138142
}
139143

0 commit comments

Comments
 (0)