Skip to content

Commit

Permalink
Add replace_traintrack_file manifest statement and 90% of patch to ut…
Browse files Browse the repository at this point in the history
…ilize it; patch just needs the pattern of the native that loads traintracks.xml
  • Loading branch information
Sage-of-Mirrors committed Mar 19, 2024
1 parent 8b93ef2 commit af7c525
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
6 changes: 6 additions & 0 deletions code/components/citizen-resources-gta/src/ResourcesTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ namespace streaming
void RemoveDataFileFromLoadList(const std::string& type, const std::string& path);

void SetNextLevelPath(const std::string& path);
void SetTrainTrackFilePath(const std::string& path);
}
#endif

Expand Down Expand Up @@ -188,6 +189,11 @@ static InitFunction initFunction([] ()
streaming::SetNextLevelPath(resourceRoot + meta.second);
}

for (auto& meta : metaData->GetEntries("replace_traintrack_file"))
{
streaming::SetTrainTrackFilePath(resourceRoot + meta.second);
}

if (!RangeLengthMatches(metaData->GetEntries("data_file"), metaData->GetEntries("data_file_extra")))
{
GlobalError("data_file entry count mismatch in resource %s", resource->GetName());
Expand Down
50 changes: 50 additions & 0 deletions code/components/gta-core-rdr3/src/PatchTrainTrackFileOverride.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <StdInc.h>
#include <Hooking.h>

#include "Hooking.Stubs.h"
#include "Hooking.Patterns.h"

static std::string g_overrideTrainTrackFile = "";

//
// The nodes that define the various railroads that trains can follow are defined by *.dat files stored at common:/data/levels/rdr3/.
// These *.dat files are in turn referenced by filename by traintracks.xml, which is also at common:/data/levels/rdr3/.
// The mounter for traintracks.xml, CTrainConfigFileMounter, does not clear the array of track data on subsequent calls; it simply
// adds the tracks to the end of the array. This is an issue, because in order for custom tracks to interface properly with the base-game tracks,
// both of them must be modified to reference each other; and as it stands, there is no way to straight-up replace base-game track data short
// of replacing the level meta... but there are blocking issues on getting that to work with RDR3, so that is not currently an option.
//
// So here we introduce an fxmanifest statement, "replace_traintrack_file", which takes the path to a custom traintracks.xml and stores
// it to a global variable. CTrainConfigFileMounter is then patched to check if this global is empty, and if so, the track loading function
// is passed the path to the base-game traintracks.xml. Otherwise, the function is given the path to the custom XML file in the resource
// it is located in.
//

namespace streaming
{
void DLL_EXPORT SetTrainTrackFilePath(const std::string& path)
{
g_overrideTrainTrackFile = path;
}
}

static void (*g_origLoadTrainTracks)(void*);
static void LoadTrainTracks(void* a1)
{
if (g_overrideTrainTrackFile.empty())
{
g_origLoadTrainTracks(a1);
}
else
{
g_origLoadTrainTracks(g_overrideTrainTrackFile.data());
}
}

static HookFunction hookFunction([]()
{
{
auto location = hook::get_pattern("");
g_origLoadTrainTracks = hook::trampoline(location, LoadTrainTracks);
}
});

0 comments on commit af7c525

Please sign in to comment.