Skip to content

Commit

Permalink
Cutscene/Ped Randomizer: Option to use data file for cutscene peds.
Browse files Browse the repository at this point in the history
  • Loading branch information
Parik27 committed May 26, 2021
1 parent 607d3fe commit f04ddf1
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 80 deletions.
2 changes: 1 addition & 1 deletion build-count.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
379
390
6 changes: 5 additions & 1 deletion config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ EnableFastSkips = false # Mission skips will be enabled after failing the missio
#######################################################
[PedRandomizer]

RandomizePlayer = true

ForcedPed = ""
ForcedClipset = ""

EnableNSFWModels = false
RandomizePlayer = true
UseCutsceneModelsFile = false
30 changes: 17 additions & 13 deletions lib/CDispatchService.hh
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,29 @@

enum class eDispatchId : uint32_t
{
CPoliceAutomobileDispatch = 1,
CWantedHelicopterDispatch = 2,
CFireDepartmentDispatch = 3,
CSwatAutomobileDispatch = 4,
CAmbulanceDepartmentDispatch = 5,
CPoliceRidersDispatch = 6,
CPoliceVehicleRequest = 7,
CPoliceRoadBlockDispatch = 8,
CGangDispatch = 11,
CSwatHelicopterDispatch = 12,
CPoliceBoatDispatch = 13,
CArmyVehicleDispatch = 14
DT_Invalid = 0,
DT_PoliceAutomobile,
DT_PoliceHelicopter,
DT_FireDepartment,
DT_SwatAutomobile,
DT_AmbulanceDepartment,
DT_PoliceRiders,
DT_PoliceVehicleRequest,
DT_PoliceRoadBlock,
DT_PoliceAutomobileWaitPulledOver,
DT_PoliceAutomobileWaitCruising,
DT_Gangs,
DT_SwatHelicopter,
DT_PoliceBoat,
DT_ArmyVehicle,
DT_BikerBackup
};

class CDispatchService
{
public:
void ** vft;
enum eDispatchId eId;
eDispatchId eId;
uint32_t field_0xc;
atArray<> field_0x10;
uint32_t field_0x1c;
Expand Down
8 changes: 7 additions & 1 deletion lib/CStreaming.hh
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,20 @@ public:
return index;
}

static inline uint32_t
GetModelHash (uint32_t index)
{
return GetModelByIndex (index)->m_nHash;
}

template <typename T>
static inline T *
GetModelAndIndexByHash (uint32_t hash, uint32_t &outIndex)
{
return static_cast<T *> (GetModelAndIndexByHash (hash, outIndex));
}

template <typename T>
template <typename T = CBaseModelInfo>
static inline T *
GetModelByHash (uint32_t hash)
{
Expand Down
6 changes: 5 additions & 1 deletion src/common/configDefault.hh
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ EnableFastSkips = false # Mission skips will be enabled after failing the missio
#######################################################
[PedRandomizer]
RandomizePlayer = true
ForcedPed = ""
ForcedClipset = ""
EnableNSFWModels = false
RandomizePlayer = true
UseCutsceneModelsFile = false
)";
52 changes: 8 additions & 44 deletions src/misc/cutscenes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "common/logger.hh"
#include "common/common.hh"
#include "common/config.hh"
#include "common/parser.hh"
#include "injector/injector.hpp"
#include "CPed.hh"
#include "peds/peds_Compatibility.hh"
Expand All @@ -20,55 +21,21 @@ void (*VisitTopLevelStructure_37027e) (parInstanceVisitor *,

class CutSceneRandomizer
{
/*******************************************************/
static std::vector<std::vector<uint32_t>> &
GetModelsList ()
{
static std::vector<std::vector<uint32_t>> mModels;
return mModels;
}
inline static char PropsFileName[] = "CutsceneModelsProps.txt";
using PropsRandomizer
= DataFileBasedModelRandomizer<PropsFileName,
CStreaming::GetModelByHash<>>;

inline static PropsRandomizer sm_Randomizer;

/*******************************************************/
static uint32_t
GetRandomModel (uint32_t modelHash)
{
for (const auto &i : GetModelsList ())
{
if (DoesElementExist (i, modelHash))
return GetRandomElement (i);
}

sm_Randomizer.RandomizeObject (modelHash);
return modelHash;
}

/*******************************************************/
static bool
InitialiseModelData ()
{
FILE *modelsFile = Rainbomizer::Common::GetRainbomizerDataFile (
"CutsceneModelsProps.txt");
GetModelsList ().clear ();

if (!modelsFile)
return false;

char line[512] = {0};
GetModelsList ().push_back ({});
while (fgets (line, 512, modelsFile))
{
if (strlen (line) < 2)
{
GetModelsList ().push_back ({});
continue;
}

line[strcspn (line, "\n")] = 0;
GetModelsList ().back ().push_back (rage::atStringHash (line));
}

return true;
}

/*******************************************************/
static void
RandomizeCutScene (parInstanceVisitor *visitor, cutfCutsceneFile2 *file)
Expand Down Expand Up @@ -117,9 +84,6 @@ class CutSceneRandomizer

InitialiseAllComponents ();

if (!InitialiseModelData ())
return;

RegisterHook ("8d ? ? 20 0f ba e8 10 89 44 ? ? e8", 12,
VisitTopLevelStructure_37027e, RandomizeCutScene);
}
Expand Down
60 changes: 55 additions & 5 deletions src/peds/peds.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
#include <utility>

#include <common/config.hh>
#include <common/parser.hh>

#include "CModelInfo.hh"
#include "common/logger.hh"
#include "peds_Compatibility.hh"
#include "peds_Streaming.hh"
#include "peds_PlayerFixes.hh"
Expand All @@ -19,18 +22,24 @@ class PedRandomizer
inline static std::mutex CreatePedMutex;
inline static bool bSkipNextPedRandomization = false;

constexpr static const char PedsFileName[] = "CutsceneModelsPeds.txt";
using CutsPedsRandomizer
= DataFileBasedModelRandomizer<PedsFileName,
CStreaming::GetModelByHash<>>;

using ModelSwapper = PedRandomizer_ModelSwapper;

static auto &
Config ()
{
static struct Config
{
std::string ForcedPed = "";
std::string ForcedClipset = "";
uint32_t ForcedPedHash = -1;
bool EnableNSFWModels = false;
bool RandomizePlayer = true;
std::string ForcedPed = "";
std::string ForcedClipset = "";
uint32_t ForcedPedHash = -1;
bool EnableNSFWModels = false;
bool RandomizePlayer = true;
bool UseCutsceneModelsFile = false;
} m_Config;

return m_Config;
Expand Down Expand Up @@ -106,6 +115,39 @@ class PedRandomizer
return ped;
}

/*******************************************************/
template <auto &CCutsceneAnimatedActorEntity__CreatePed>
static void
RandomizeCutscenePeds (class CCutsceneAnimatedActorEntity *entity,
uint32_t model, bool p3)
{
static CutsPedsRandomizer sm_Randomizer;

// Randomize model (remember model here is the idx, so convert to hash)
uint32_t hash = CStreaming::GetModelHash (model);
sm_Randomizer.RandomizeObject (hash);

// Load the new model
uint32_t newModel = CStreaming::GetModelIndex (hash);
if (!CStreaming::HasModelLoaded (newModel))
{
Rainbomizer::Logger::LogMessage ("Trying to load model: %x",
hash);

CStreaming::RequestModel (newModel, 0);
CStreaming::LoadAllObjects (false);
}

if (CStreaming::HasModelLoaded (newModel))
{
model = newModel;
bSkipNextPedRandomization = true;
}

// Spawn the ped
CCutsceneAnimatedActorEntity__CreatePed (entity, model, p3);
}

public:
/*******************************************************/
PedRandomizer ()
Expand All @@ -114,6 +156,8 @@ class PedRandomizer
if (!ConfigManager::ReadConfig (
"PedRandomizer", std::pair ("ForcedPed", &Config ().ForcedPed),
std::pair ("RandomizePlayer", &Config ().RandomizePlayer),
std::pair ("UseCutsceneModelsFile",
&Config ().UseCutsceneModelsFile),
std::pair ("ForcedClipset", &Config ().ForcedClipset)))
return;

Expand All @@ -127,6 +171,12 @@ class PedRandomizer
CPedFactory_CreateNonCopPed_5c6,
RandomizePed<CPedFactory_CreateNonCopPed_5c6>);

if (Config ().UseCutsceneModelsFile)
REGISTER_HOOK ("85 ff 75 ? 45 8a c4 e8 ? ? ? ? 45 84 e4 74", 7,
RandomizeCutscenePeds, void,
class CCutsceneAnimatedActorEntity *, uint32_t,
bool);

REGISTER_HOOK (
"88 44 ? ? 40 88 7c ? ? e8 ? ? ? ? ? 8b d8 ? 85 c0 0f 84", 9,
RandomizePed, CPed *, CPedFactory *, uint8_t *, uint32_t, uint64_t,
Expand Down
26 changes: 12 additions & 14 deletions src/vehicles/dispatch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,25 +87,23 @@ class DispatchRandomizer
switch (service->eId)
{

case eDispatchId::CPoliceAutomobileDispatch:
case eDispatchId::CArmyVehicleDispatch:
case eDispatchId::CSwatAutomobileDispatch:
case eDispatchId::CPoliceRidersDispatch:
case eDispatchId::CPoliceVehicleRequest:
case eDispatchId::DT_PoliceAutomobile:
case eDispatchId::DT_ArmyVehicle:
case eDispatchId::DT_SwatAutomobile:
case eDispatchId::DT_PoliceRiders:
case eDispatchId::DT_PoliceVehicleRequest:
return GetRandomVehicleForPoliceAutomobile ();

case eDispatchId::CWantedHelicopterDispatch:
case eDispatchId::CSwatHelicopterDispatch:
case eDispatchId::DT_PoliceHelicopter:
case eDispatchId::DT_SwatHelicopter:
return GetRandomPoliceHelicopter ();

case eDispatchId::CPoliceBoatDispatch:
return GetRandomBoat ();
break;
case eDispatchId::DT_PoliceBoat: return GetRandomBoat (); break;

case eDispatchId::CFireDepartmentDispatch:
case eDispatchId::CAmbulanceDepartmentDispatch:
case eDispatchId::CGangDispatch:
case eDispatchId::CPoliceRoadBlockDispatch:
case eDispatchId::DT_FireDepartment:
case eDispatchId::DT_AmbulanceDepartment:
case eDispatchId::DT_Gangs:
case eDispatchId::DT_PoliceRoadBlock:
default: return GetRandomVehicle ();
}

Expand Down

0 comments on commit f04ddf1

Please sign in to comment.