diff --git a/CpkTools/CpkTools.csproj b/CpkTools/CpkTools.csproj
index 25e0346..0af915f 100644
--- a/CpkTools/CpkTools.csproj
+++ b/CpkTools/CpkTools.csproj
@@ -8,7 +8,6 @@
-
diff --git a/CpkTools/Model/Cpk.cs b/CpkTools/Model/Cpk.cs
index e81b123..24d3482 100644
--- a/CpkTools/Model/Cpk.cs
+++ b/CpkTools/Model/Cpk.cs
@@ -18,7 +18,9 @@ public sealed class Cpk {
private Memory _tocPacket;
private Memory _itocPacket;
private Memory _etocPacket;
+#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value
private Memory _gtocPacket;
+#pragma warning restore CS0649 // Field is never assigned to, and will always have its default value
private ulong _tocOffset = ulong.MaxValue;
private ulong _etocOffset = ulong.MaxValue;
private ulong _itocOffset = ulong.MaxValue;
diff --git a/ParLibrary/ParLibrary.csproj b/ParLibrary/ParLibrary.csproj
index 9a4a075..c51de85 100644
--- a/ParLibrary/ParLibrary.csproj
+++ b/ParLibrary/ParLibrary.csproj
@@ -9,7 +9,6 @@
-
diff --git a/ShinRyuModManager-CE/GameModel.cs b/ShinRyuModManager-CE/GameModel.cs
index 774b1ee..1186e3b 100644
--- a/ShinRyuModManager-CE/GameModel.cs
+++ b/ShinRyuModManager-CE/GameModel.cs
@@ -401,4 +401,96 @@ public static void DoUBIKProcedure(MLO mlo) {
par.Dispose();
}
+
+ public static void DoYK3HActProcedure(MLO mlo, string codename) {
+ var hactDir = new DirectoryInfo(GamePath.DataPath).EnumerateDirectories().FirstOrDefault(x => x.Name.StartsWith("hact_"))?.FullName;
+
+ if (string.IsNullOrEmpty(hactDir))
+ return;
+
+ var haveTalk = mlo.Files.Any(x => x.Name.Contains("/hact_"));
+
+ if (!haveTalk)
+ return;
+
+ var rootHActDir = Path.Combine(GamePath.ParlessDir, "hact_" + codename);
+
+ Directory.CreateDirectory(rootHActDir);
+
+ // This is really bad but it will have to do:
+ // Get the smallest hact in the hact dir
+ // Use that as a dummy file.
+ // Our created pars inf load the game for some reason.
+ var smallestHAct = new DirectoryInfo(hactDir)
+ .EnumerateFiles("*.par", SearchOption.TopDirectoryOnly)
+ .OrderBy(f => f.Length)
+ .First();
+
+ foreach (var mod in mlo.Mods) {
+ var modPath = GamePath.GetModDirectory(mod);
+ var hActDirPath = Directory.EnumerateDirectories(modPath).FirstOrDefault(x => x.Contains("hact_"));
+
+ if (string.IsNullOrEmpty(hActDirPath))
+ continue;
+
+ var hActDir = new DirectoryInfo(hActDirPath);
+
+ foreach (var dir in hActDir.EnumerateDirectories()) {
+ var dummyParDir = new DirectoryInfo(rootHActDir);
+
+ if (!dummyParDir.Exists)
+ dummyParDir.Create();
+
+ var dummyParPath = new FileInfo(Path.Combine(dummyParDir.FullName, dir.Name + ".par"));
+ File.Copy(smallestHAct.FullName, dummyParPath.FullName, true);
+ }
+ }
+ }
+
+ public static void DoTalkProcedureYK3(MLO mlo, string codename) {
+ var hactDir = new DirectoryInfo(GamePath.DataPath).GetDirectories().FirstOrDefault(x => x.Name.StartsWith("hact_"))?.FullName;
+
+ if (string.IsNullOrEmpty(hactDir))
+ return;
+
+ var haveTalk = mlo.Files.Any(x => x.Name.Contains("/talk_"));
+
+ if (!haveTalk)
+ return;
+
+ var rootTalkDir = Path.Combine(GamePath.ParlessDir, "talk_" + codename);
+
+ if (!Directory.Exists(rootTalkDir))
+ Directory.CreateDirectory(rootTalkDir);
+
+ //This is really bad but it will have to do:
+ //Get the smallest hact in the hact dir
+ //Use that as a dummy file.
+ //Our created pars inf load the game for some reason.
+ var smallestHAct = new DirectoryInfo(hactDir)
+ .GetFiles("*.par", SearchOption.TopDirectoryOnly)
+ .OrderBy(f => f.Length)
+ .First();
+
+ foreach (var mod in mlo.Mods) {
+ var modPath = GamePath.GetModDirectory(mod);
+ var talkDirs = Directory.EnumerateDirectories(modPath).Where(x => x.Contains("talk_"));
+
+ foreach (var modTalkDir in talkDirs) {
+ var talksDirs = new DirectoryInfo(modTalkDir).EnumerateDirectories();
+
+ foreach (var talkCategory in talksDirs) {
+ foreach (var talkDir in talkCategory.EnumerateDirectories()) {
+ var dummyParDir = new DirectoryInfo(Path.Combine(rootTalkDir, talkCategory.Name));
+
+ if (!dummyParDir.Exists)
+ dummyParDir.Create();
+
+ var dummyParPath = new FileInfo(Path.Combine(dummyParDir.FullName, talkDir.Name + ".par"));
+ File.Copy(smallestHAct.FullName, dummyParPath.FullName, true);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs b/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs
index 3938f48..684a26a 100644
--- a/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs
+++ b/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs
@@ -176,7 +176,7 @@ public void AddFiles(string path, string check) {
}
}
- if (GamePath.CurrentGame >= Game.Yakuza6) {
+ if (GamePath.CurrentGame >= Game.Yakuza6 && GamePath.CurrentGame != Game.YakuzaKiwami3) {
//Dragon Engine talks use pars directly for these
if (path.Contains("talk_")) {
if (char.IsDigit(basename[0]) || check == "cmn") {
diff --git a/ShinRyuModManager-CE/Program.cs b/ShinRyuModManager-CE/Program.cs
index f8cc363..f73adf0 100644
--- a/ShinRyuModManager-CE/Program.cs
+++ b/ShinRyuModManager-CE/Program.cs
@@ -388,7 +388,8 @@ internal static async Task RunGeneration(List mods) {
break;
case Game.YakuzaKiwami3:
- GameModel.DoDEHActProcedure(result, "bis");
+ GameModel.DoYK3HActProcedure(result, "bis");
+ GameModel.DoTalkProcedureYK3(result, "bis");
break;
}
diff --git a/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj b/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj
index e1d5e26..29fc650 100644
--- a/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj
+++ b/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj
@@ -14,7 +14,7 @@
true
- 1.4.1
+ 1.4.2
$(AssemblyVersion)
ShinRyuModManager-CE
SRMM Studio
diff --git a/ShinRyuModManager-CE/UserInterface/Assets/changelog.md b/ShinRyuModManager-CE/UserInterface/Assets/changelog.md
index 4292b06..6d28ec6 100644
--- a/ShinRyuModManager-CE/UserInterface/Assets/changelog.md
+++ b/ShinRyuModManager-CE/UserInterface/Assets/changelog.md
@@ -1,4 +1,9 @@
-> ### **%{color:gold} Version 1.4.1 %** ###
+> ### **%{color:gold} Version 1.4.2 %** ###
+* Implemented **experimental** Talk and HAct repack methods from SRMM 4.7.6
+
+---
+
+> ### **%{color:orange} Version 1.4.1 %** ###
* Yakuza Kiwami 3 Support
* Fixed PYIH gmt hash lookup
* Fixed bug when removing an installed mod
diff --git a/Utils/GamePath.cs b/Utils/GamePath.cs
index 093456e..c26c83b 100644
--- a/Utils/GamePath.cs
+++ b/Utils/GamePath.cs
@@ -25,7 +25,7 @@ static GamePath() {
ParlessDir = Path.Combine(ModsPath, "Parless");
ExternalModsPath = Path.Combine(ModsPath, Constants.EXTERNAL_MODS);
LibrariesPath = Path.Combine(FullGamePath, LIBRARIES);
- LocalLibrariesPath = Path.Combine(GamePath.LibrariesPath, Constants.LIBRARIES_INFO_REPO_FILE_PATH);
+ LocalLibrariesPath = Path.Combine(LibrariesPath, Constants.LIBRARIES_INFO_REPO_FILE_PATH);
// Try to get game
foreach (var file in Directory.GetFiles(FullGamePath, "*.exe")) {