diff --git a/CUE4Parse b/CUE4Parse
index 699dbd44..822dc9bf 160000
--- a/CUE4Parse
+++ b/CUE4Parse
@@ -1 +1 @@
-Subproject commit 699dbd44389e3543e7c09875e0a1b518b0dd05da
+Subproject commit 822dc9bf39d793a4005c2eb9ba53721c10b791da
diff --git a/FModel/Creator/CreatorPackage.cs b/FModel/Creator/CreatorPackage.cs
index ee169896..7c2b154b 100644
--- a/FModel/Creator/CreatorPackage.cs
+++ b/FModel/Creator/CreatorPackage.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using CUE4Parse.UE4.Assets.Exports;
using FModel.Creator.Bases;
@@ -30,7 +31,7 @@ public class CreatorPackage : IDisposable
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool TryConstructCreator(out UCreator creator)
+ public bool TryConstructCreator([MaybeNullWhen(false)] out UCreator creator)
{
switch (_exportType)
{
diff --git a/FModel/Extensions/CUE4ParseExtensions.cs b/FModel/Extensions/CUE4ParseExtensions.cs
index 7254564e..463a668e 100644
--- a/FModel/Extensions/CUE4ParseExtensions.cs
+++ b/FModel/Extensions/CUE4ParseExtensions.cs
@@ -2,6 +2,8 @@
using CUE4Parse.FileProvider;
using CUE4Parse.FileProvider.Objects;
using CUE4Parse.UE4.Assets;
+using CUE4Parse.UE4.Objects.UObject;
+using FModel.Settings;
namespace FModel.Extensions;
@@ -9,35 +11,57 @@ public static class CUE4ParseExtensions
{
public class LoadPackageResult
{
+ // more than 1 export per page currently break the inner package navigation feature
+ // if you have 1k exports per page, at page 2, you click on export index 932
+ // it will find the export index 932 in the current page, which would realistically be 1932
+ // fix would be to use InclusiveStart and ExclusiveEnd to determine the page the export index is in
+ // giving the document access to this would fix the issue and we could re-use Package instead of reloading it but it's quite a bit of work atm
+
private const int PaginationThreshold = 5000;
private const int MaxExportPerPage = 1;
public IPackage Package;
+ public int RequestedIndex;
+
public bool IsPaginated => Package.ExportMapLength >= PaginationThreshold;
- public int InclusiveStart;
+ ///
+ /// index of the first export on the current page
+ /// this index is the starting point for additional data preview
+ ///
+ /// it can be >0 even if is false if we want to focus data preview on a specific export
+ /// in this case, we will display all exports but only the focused one will be checked for data preview
+ ///
+ public int InclusiveStart => Math.Max(0, RequestedIndex - RequestedIndex % MaxExportPerPage);
+ ///
+ /// last exclusive export index of the current page
+ ///
public int ExclusiveEnd => IsPaginated
? Math.Min(InclusiveStart + MaxExportPerPage, Package.ExportMapLength)
: Package.ExportMapLength;
+ public int PageSize => ExclusiveEnd - InclusiveStart;
- private int CurrentPage => (InclusiveStart + 1) / MaxExportPerPage;
- private int LastPage => Math.Max(1, (Package.ExportMapLength + MaxExportPerPage - 1) / MaxExportPerPage);
- private int PageSize => ExclusiveEnd - InclusiveStart;
+ public string TabTitleExtra => IsPaginated ? $"Export{(PageSize > 1 ? "s" : "")} {InclusiveStart}{(PageSize > 1 ? $"-{ExclusiveEnd - 1}" : "")} of {Package.ExportMapLength - 1}" : null;
- public string TabTitleExtra => IsPaginated ? $"Page {CurrentPage}/{LastPage}" : null;
-
- public object GetDisplayData(bool save = false) => !save ? Package.GetExports(InclusiveStart, PageSize) : Package.GetExports();
+ ///
+ /// display all exports unless paginated
+ ///
+ /// if we save the data we will display all exports even if is true
+ ///
+ public object GetDisplayData(bool save = false) => !save && IsPaginated
+ ? Package.GetExports(InclusiveStart, PageSize)
+ : Package.GetExports();
}
public static LoadPackageResult GetLoadPackageResult(this IFileProvider provider, GameFile file, string objectName = null)
{
var result = new LoadPackageResult { Package = provider.LoadPackage(file) };
- if (result.IsPaginated)
+ if (result.IsPaginated || (result.Package.HasFlags(EPackageFlags.PKG_ContainsMap) && UserSettings.Default.PreviewWorlds)) // focus on UWorld if it's a map we want to preview
{
- result.InclusiveStart = result.Package.GetExportIndex(file.NameWithoutExtension);
+ result.RequestedIndex = result.Package.GetExportIndex(file.NameWithoutExtension);
if (objectName != null)
{
- result.InclusiveStart = int.TryParse(objectName, out var index) ? index : result.Package.GetExportIndex(objectName);
+ result.RequestedIndex = int.TryParse(objectName, out var index) ? index : result.Package.GetExportIndex(objectName);
}
}
diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs
index 23cdc2d2..4597519a 100644
--- a/FModel/MainWindow.xaml.cs
+++ b/FModel/MainWindow.xaml.cs
@@ -83,9 +83,9 @@ public partial class MainWindow
).ConfigureAwait(false);
#if DEBUG
- await _threadWorkerView.Begin(cancellationToken =>
- _applicationView.CUE4Parse.Extract(cancellationToken,
- _applicationView.CUE4Parse.Provider["FortniteGame/Plugins/GameFeatures/BRMapCh6/Content/Maps/Hermes_Terrain.umap"]));
+ // await _threadWorkerView.Begin(cancellationToken =>
+ // _applicationView.CUE4Parse.Extract(cancellationToken,
+ // _applicationView.CUE4Parse.Provider["FortniteGame/Plugins/GameFeatures/MeshCosmetics/Content/Jumpsuit/F_MED_Jumpsuit_Scrap/CO/CO_F_MED_Jumpsuit_Scrap.uasset"]));
// await _threadWorkerView.Begin(cancellationToken =>
// _applicationView.CUE4Parse.Extract(cancellationToken,
// "RED/Content/Chara/ABA/Costume01/Animation/Charaselect/body/stand_body01.uasset"));
diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs
index eed30718..4a820a62 100644
--- a/FModel/ViewModels/CUE4ParseViewModel.cs
+++ b/FModel/ViewModels/CUE4ParseViewModel.cs
@@ -138,12 +138,12 @@ public class CUE4ParseViewModel : ViewModel
{
case Constants._FN_LIVE_TRIGGER:
{
- Provider = new StreamedFileProvider("FortniteLive", true, versionContainer);
+ Provider = new StreamedFileProvider("FortniteLive", versionContainer);
break;
}
case Constants._VAL_LIVE_TRIGGER:
{
- Provider = new StreamedFileProvider("ValorantLive", true, versionContainer);
+ Provider = new StreamedFileProvider("ValorantLive", versionContainer);
break;
}
default:
@@ -155,12 +155,12 @@ public class CUE4ParseViewModel : ViewModel
[
new(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\StateOfDecay2\\Saved\\Paks"),
new(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\StateOfDecay2\\Saved\\DisabledPaks")
- ], SearchOption.AllDirectories, true, versionContainer),
+ ], SearchOption.AllDirectories, versionContainer),
"eFootball" => new DefaultFileProvider(new DirectoryInfo(gameDirectory),
[
new(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\KONAMI\\eFootball\\ST\\Download")
- ], SearchOption.AllDirectories, true, versionContainer),
- _ => new DefaultFileProvider(gameDirectory, SearchOption.AllDirectories, true, versionContainer)
+ ], SearchOption.AllDirectories, versionContainer),
+ _ => new DefaultFileProvider(gameDirectory, SearchOption.AllDirectories, versionContainer)
};
break;
diff --git a/FModel/Views/Resources/Controls/Aed/GamePathVisualLineText.cs b/FModel/Views/Resources/Controls/Aed/GamePathVisualLineText.cs
index d642a47e..ea19954c 100644
--- a/FModel/Views/Resources/Controls/Aed/GamePathVisualLineText.cs
+++ b/FModel/Views/Resources/Controls/Aed/GamePathVisualLineText.cs
@@ -70,7 +70,7 @@ public class GamePathVisualLineText : VisualLineText
{
var obj = gamePath.SubstringAfterLast('.');
var package = gamePath.SubstringBeforeLast('.');
- var fullPath = _applicationView.CUE4Parse.Provider.FixPath(package, StringComparison.Ordinal);
+ var fullPath = _applicationView.CUE4Parse.Provider.FixPath(package);
var firstLine = a.ParentVisualLine.Document.GetLineByNumber(2);
if (a.ParentVisualLine.Document.FileName.Equals(fullPath.SubstringBeforeLast('.'), StringComparison.OrdinalIgnoreCase) &&
diff --git a/FModel/Views/Resources/Controls/ImagePopout.xaml b/FModel/Views/Resources/Controls/ImagePopout.xaml
index 31bf8301..b28330aa 100644
--- a/FModel/Views/Resources/Controls/ImagePopout.xaml
+++ b/FModel/Views/Resources/Controls/ImagePopout.xaml
@@ -15,7 +15,9 @@
-
-
+
+
+
+
diff --git a/FModel/Views/Snooper/Shading/Material.cs b/FModel/Views/Snooper/Shading/Material.cs
index 05d7e354..a3e58d49 100644
--- a/FModel/Views/Snooper/Shading/Material.cs
+++ b/FModel/Views/Snooper/Shading/Material.cs
@@ -80,7 +80,7 @@ public class Material : IDisposable
Normals = [new Texture(new FLinearColor(0.5f, 0.5f, 1f, 1f))];
SpecularMasks = [new Texture(new FLinearColor(1f, 0.5f, 0.5f, 1f))];
Emissive = new Texture[1];
- DiffuseColor = [Vector4.One];
+ DiffuseColor = FillColors(1, Diffuse, CMaterialParams2.DiffuseColors, Vector4.One);
EmissiveColor = [Vector4.One];
}
else