This commit is contained in:
MountainFlash 2021-12-09 23:46:47 +05:30
commit 13ebe99862
No known key found for this signature in database
GPG Key ID: 6BDA200334E04E1A
16 changed files with 256 additions and 240 deletions

@ -1 +1 @@
Subproject commit 493afb80e59c1c97f4c0435dcfd81c07bf4a553c
Subproject commit cf93fb7ad93af74994f736db6cc134250e165a53

View File

@ -44,9 +44,9 @@ namespace FModel
}
if (!Directory.Exists(UserSettings.Default.OutputDirectory))
{
UserSettings.Default.OutputDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Output");
}
if (!Directory.Exists(UserSettings.Default.ModelDirectory))
UserSettings.Default.ModelDirectory = Path.Combine(UserSettings.Default.OutputDirectory, "Saves");
Directory.CreateDirectory(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FModel"));
Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, "Backups"));

View File

@ -1,8 +1,8 @@
using FModel.Properties;
using System;
using System.ComponentModel;
using System.Resources;
using System.Runtime.CompilerServices;
using FModel.Properties;
namespace FModel.Extensions
{
@ -47,12 +47,12 @@ namespace FModel.Extensions
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T ToEnum<T>(this string value, T defaultValue)
public static T ToEnum<T>(this string value, T defaultValue) where T : struct
{
if (!Enum.TryParse(typeof(T), value, true, out var ret))
if (!Enum.TryParse(value, true, out T ret))
return defaultValue;
return (T) ret;
return ret;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -81,4 +81,4 @@ namespace FModel.Extensions
return i == -1 ? (T) values.GetValue(values.Length - 1) : (T) values.GetValue(i);
}
}
}
}

View File

@ -6,8 +6,8 @@
<UseWPF>true</UseWPF>
<ApplicationIcon>FModel.ico</ApplicationIcon>
<Version>4.1.0</Version>
<AssemblyVersion>4.1.0.1</AssemblyVersion>
<FileVersion>4.1.0.1</FileVersion>
<AssemblyVersion>4.1.0.2</AssemblyVersion>
<FileVersion>4.1.0.2</FileVersion>
<IsPackable>false</IsPackable>
<IsPublishable>true</IsPublishable>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>

View File

@ -94,7 +94,7 @@
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="Export Data" Command="{Binding RightClickMenuCommand}">
<MenuItem Header="Export Raw Data" Command="{Binding RightClickMenuCommand}">
<MenuItem.CommandParameter>
<MultiBinding Converter="{x:Static converters:MultiParameterConverter.Instance}">
<Binding Source="Assets_Export_Data" />
@ -147,18 +147,12 @@
</Canvas>
</Viewbox>
</MenuItem.Icon>
<MenuItem Header="Export Data" IsCheckable="True" StaysOpenOnClick="True"
InputGestureText="{Binding AutoExportData, Source={x:Static local:Settings.UserSettings.Default}}"
IsChecked="{Binding IsAutoExportData, Source={x:Static local:Settings.UserSettings.Default}}" />
<MenuItem Header="Save Properties" IsCheckable="True" StaysOpenOnClick="True"
InputGestureText="{Binding AutoSaveProps, Source={x:Static local:Settings.UserSettings.Default}}"
IsChecked="{Binding IsAutoSaveProps, Source={x:Static local:Settings.UserSettings.Default}}" />
<MenuItem Header="Save Textures" IsCheckable="True" StaysOpenOnClick="True"
InputGestureText="{Binding AutoSaveTextures, Source={x:Static local:Settings.UserSettings.Default}}"
IsChecked="{Binding IsAutoSaveTextures, Source={x:Static local:Settings.UserSettings.Default}}" />
<MenuItem Header="Save Animations" IsCheckable="True" StaysOpenOnClick="True"
InputGestureText="{Binding AutoSaveAnimations, Source={x:Static local:Settings.UserSettings.Default}}"
IsChecked="{Binding IsAutoSaveAnimations, Source={x:Static local:Settings.UserSettings.Default}}" />
<MenuItem Header="Open Sounds" IsCheckable="True" StaysOpenOnClick="True"
InputGestureText="{Binding AutoOpenSounds, Source={x:Static local:Settings.UserSettings.Default}}"
IsChecked="{Binding IsAutoOpenSounds, Source={x:Static local:Settings.UserSettings.Default}}" />
@ -397,7 +391,7 @@
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Export Folder's Assets Data" Click="OnFolderExportClick">
<MenuItem Header="Export Folder's Assets Raw Data" Click="OnFolderExportClick">
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
<Canvas Width="24" Height="24">
@ -525,7 +519,7 @@
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Export Data" Command="{Binding DataContext.RightClickMenuCommand}">
<MenuItem Header="Export Raw Data" Command="{Binding DataContext.RightClickMenuCommand}">
<MenuItem.CommandParameter>
<MultiBinding Converter="{x:Static converters:MultiParameterConverter.Instance}">
<Binding Source="Assets_Export_Data" />
@ -799,19 +793,6 @@
</Viewbox>
</StatusBarItem>
<StatusBarItem Width="30" HorizontalContentAlignment="Stretch" ToolTip="Auto Export Data Enabled">
<StatusBarItem.Style>
<Style TargetType="StatusBarItem">
<Style.Triggers>
<DataTrigger Binding="{Binding IsAutoExportData, Source={x:Static local:Settings.UserSettings.Default}}" Value="False">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</StatusBarItem.Style>
<TextBlock HorizontalAlignment="Center" FontWeight="SemiBold" Text="DTA" />
</StatusBarItem>
<StatusBarItem Width="30" HorizontalContentAlignment="Stretch" ToolTip="Auto Save Properties Enabled">
<StatusBarItem.Style>
<Style TargetType="StatusBarItem">
@ -838,19 +819,6 @@
<TextBlock HorizontalAlignment="Center" FontWeight="SemiBold" Text="TEX" />
</StatusBarItem>
<StatusBarItem Width="35" HorizontalContentAlignment="Stretch" ToolTip="Auto Save Animations Enabled">
<StatusBarItem.Style>
<Style TargetType="StatusBarItem">
<Style.Triggers>
<DataTrigger Binding="{Binding IsAutoSaveAnimations, Source={x:Static local:Settings.UserSettings.Default}}" Value="False">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</StatusBarItem.Style>
<TextBlock HorizontalAlignment="Center" FontWeight="SemiBold" Text="ANM" />
</StatusBarItem>
<StatusBarItem Width="30" HorizontalContentAlignment="Stretch" ToolTip="Auto Open Sounds Enabled">
<StatusBarItem.Style>
<Style TargetType="StatusBarItem">

View File

@ -11,7 +11,6 @@ using FModel.Settings;
using FModel.ViewModels;
using FModel.Views;
using FModel.Views.Resources.Controls;
using ICSharpCode.AvalonEdit.Editing;
namespace FModel
{
@ -27,14 +26,10 @@ namespace FModel
public MainWindow()
{
CommandBindings.Add(new CommandBinding(new RoutedCommand("AutoExportData", typeof(MainWindow), new InputGestureCollection
{new KeyGesture(UserSettings.Default.AutoExportData.Key, UserSettings.Default.AutoExportData.Modifiers)}), OnAutoTriggerExecuted));
CommandBindings.Add(new CommandBinding(new RoutedCommand("AutoSaveProps", typeof(MainWindow), new InputGestureCollection
{new KeyGesture(UserSettings.Default.AutoSaveProps.Key, UserSettings.Default.AutoSaveProps.Modifiers)}), OnAutoTriggerExecuted));
CommandBindings.Add(new CommandBinding(new RoutedCommand("AutoSaveTextures", typeof(MainWindow), new InputGestureCollection
{new KeyGesture(UserSettings.Default.AutoSaveTextures.Key, UserSettings.Default.AutoSaveTextures.Modifiers)}), OnAutoTriggerExecuted));
CommandBindings.Add(new CommandBinding(new RoutedCommand("AutoSaveAnimations", typeof(MainWindow), new InputGestureCollection
{new KeyGesture(UserSettings.Default.AutoSaveAnimations.Key, UserSettings.Default.AutoSaveAnimations.Modifiers)}), OnAutoTriggerExecuted));
CommandBindings.Add(new CommandBinding(new RoutedCommand("AutoOpenSounds", typeof(MainWindow), new InputGestureCollection
{new KeyGesture(UserSettings.Default.AutoOpenSounds.Key, UserSettings.Default.AutoOpenSounds.Modifiers)}), OnAutoTriggerExecuted));
CommandBindings.Add(new CommandBinding(new RoutedCommand("ReloadMappings", typeof(MainWindow), new InputGestureCollection {new KeyGesture(Key.F12)}), OnMappingsReload));
@ -89,7 +84,7 @@ namespace FModel
private void OnWindowKeyDown(object sender, KeyEventArgs e)
{
if (e.OriginalSource is TextArea or TextBox)
if (e.OriginalSource is TextBox)
return;
if (_threadWorkerView.CanBeCanceled && e.Key == Key.Escape)
@ -135,18 +130,12 @@ namespace FModel
{
switch ((e.Command as RoutedCommand)?.Name)
{
case "AutoExportData":
UserSettings.Default.IsAutoExportData = !UserSettings.Default.IsAutoExportData;
break;
case "AutoSaveProps":
UserSettings.Default.IsAutoSaveProps = !UserSettings.Default.IsAutoSaveProps;
break;
case "AutoSaveTextures":
UserSettings.Default.IsAutoSaveTextures = !UserSettings.Default.IsAutoSaveTextures;
break;
case "AutoSaveAnimations":
UserSettings.Default.IsAutoSaveAnimations = !UserSettings.Default.IsAutoSaveAnimations;
break;
case "AutoOpenSounds":
UserSettings.Default.IsAutoOpenSounds = !UserSettings.Default.IsAutoOpenSounds;
break;

View File

@ -51,6 +51,13 @@ namespace FModel.Settings
set => SetProperty(ref _outputDirectory, value);
}
private string _modelDirectory;
public string ModelDirectory
{
get => _modelDirectory;
set => SetProperty(ref _modelDirectory, value);
}
private string _gameDirectory;
public string GameDirectory
{
@ -58,6 +65,20 @@ namespace FModel.Settings
set => SetProperty(ref _gameDirectory, value);
}
private bool _overwriteMapping;
public bool OverwriteMapping
{
get => _overwriteMapping;
set => SetProperty(ref _overwriteMapping, value);
}
private string _mappingFilePath;
public string MappingFilePath
{
get => _mappingFilePath;
set => SetProperty(ref _mappingFilePath, value);
}
private int _lastOpenedSettingTab;
public int LastOpenedSettingTab
{
@ -65,13 +86,6 @@ namespace FModel.Settings
set => SetProperty(ref _lastOpenedSettingTab, value);
}
private bool _isAutoExportData;
public bool IsAutoExportData
{
get => _isAutoExportData;
set => SetProperty(ref _isAutoExportData, value);
}
private bool _isAutoSaveProps;
public bool IsAutoSaveProps
{
@ -86,13 +100,6 @@ namespace FModel.Settings
set => SetProperty(ref _isAutoSaveTextures, value);
}
private bool _isAutoSaveAnimations;
public bool IsAutoSaveAnimations
{
get => _isAutoSaveAnimations;
set => SetProperty(ref _isAutoSaveAnimations, value);
}
private bool _isAutoOpenSounds = true;
public bool IsAutoOpenSounds
{
@ -436,35 +443,21 @@ namespace FModel.Settings
set => SetProperty(ref _assetRemoveTab, value);
}
private Hotkey _autoExportData = new(Key.F1);
public Hotkey AutoExportData
{
get => _autoExportData;
set => SetProperty(ref _autoExportData, value);
}
private Hotkey _autoSaveProps = new(Key.F2);
private Hotkey _autoSaveProps = new(Key.F1);
public Hotkey AutoSaveProps
{
get => _autoSaveProps;
set => SetProperty(ref _autoSaveProps, value);
}
private Hotkey _autoSaveTextures = new(Key.F3);
private Hotkey _autoSaveTextures = new(Key.F2);
public Hotkey AutoSaveTextures
{
get => _autoSaveTextures;
set => SetProperty(ref _autoSaveTextures, value);
}
private Hotkey _autoSaveAnimations = new(Key.F4);
public Hotkey AutoSaveAnimations
{
get => _autoSaveAnimations;
set => SetProperty(ref _autoSaveAnimations, value);
}
private Hotkey _autoOpenSounds = new(Key.F5);
private Hotkey _autoOpenSounds = new(Key.F3);
public Hotkey AutoOpenSounds
{
get => _autoOpenSounds;
@ -585,6 +578,13 @@ namespace FModel.Settings
}
}
private bool _saveAnimations;
public bool SaveAnimations
{
get => _saveAnimations;
set => SetProperty(ref _saveAnimations, value);
}
private bool _saveSkeletonAsMesh;
public bool SaveSkeletonAsMesh
{

View File

@ -297,35 +297,44 @@ namespace FModel.ViewModels
{
await _threadWorkerView.Begin(cancellationToken =>
{
var mappingsFolder = Path.Combine(UserSettings.Default.OutputDirectory, ".data");
var mappings = _apiEndpointView.BenbotApi.GetMappings(cancellationToken);
if (mappings is {Length: > 0})
if (UserSettings.Default.OverwriteMapping && File.Exists(UserSettings.Default.MappingFilePath))
{
foreach (var mapping in mappings)
{
if (mapping.Meta.CompressionMethod != "Oodle") continue;
var mappingPath = Path.Combine(mappingsFolder, mapping.FileName);
if (!File.Exists(mappingPath))
{
_apiEndpointView.BenbotApi.DownloadFile(mapping.Url, mappingPath);
}
Provider.MappingsContainer = new FileUsmapTypeMappingsProvider(mappingPath);
FLogger.AppendInformation();
FLogger.AppendText($"Mappings pulled from '{mapping.FileName}'", Constants.WHITE, true);
break;
}
Provider.MappingsContainer = new FileUsmapTypeMappingsProvider(UserSettings.Default.MappingFilePath);
FLogger.AppendInformation();
FLogger.AppendText($"Mappings pulled from '{UserSettings.Default.MappingFilePath.SubstringAfterLast("\\")}'", Constants.WHITE, true);
}
else
{
var latestUsmaps = new DirectoryInfo(mappingsFolder).GetFiles("*_oo.usmap");
if (Provider.MappingsContainer != null || latestUsmaps.Length <= 0) return;
var mappingsFolder = Path.Combine(UserSettings.Default.OutputDirectory, ".data");
var mappings = _apiEndpointView.BenbotApi.GetMappings(cancellationToken);
if (mappings is {Length: > 0})
{
foreach (var mapping in mappings)
{
if (mapping.Meta.CompressionMethod != "Oodle") continue;
var latestUsmapInfo = latestUsmaps.OrderBy(f => f.LastWriteTime).Last();
Provider.MappingsContainer = new FileUsmapTypeMappingsProvider(latestUsmapInfo.FullName);
FLogger.AppendWarning();
FLogger.AppendText($"Mappings pulled from '{latestUsmapInfo.Name}'", Constants.WHITE, true);
var mappingPath = Path.Combine(mappingsFolder, mapping.FileName);
if (!File.Exists(mappingPath))
{
_apiEndpointView.BenbotApi.DownloadFile(mapping.Url, mappingPath);
}
Provider.MappingsContainer = new FileUsmapTypeMappingsProvider(mappingPath);
FLogger.AppendInformation();
FLogger.AppendText($"Mappings pulled from '{mapping.FileName}'", Constants.WHITE, true);
break;
}
}
else
{
var latestUsmaps = new DirectoryInfo(mappingsFolder).GetFiles("*_oo.usmap");
if (Provider.MappingsContainer != null || latestUsmaps.Length <= 0) return;
var latestUsmapInfo = latestUsmaps.OrderBy(f => f.LastWriteTime).Last();
Provider.MappingsContainer = new FileUsmapTypeMappingsProvider(latestUsmapInfo.FullName);
FLogger.AppendWarning();
FLogger.AppendText($"Mappings pulled from '{latestUsmapInfo.Name}'", Constants.WHITE, true);
}
}
});
}
@ -627,9 +636,6 @@ namespace FModel.ViewModels
break;
}
}
if (UserSettings.Default.IsAutoExportData)
ExportData(fullPath);
}
public void ExtractAndScroll(string fullPath, string objectName)
@ -644,9 +650,6 @@ namespace FModel.ViewModels
if (!exports.Any(CheckExport))
TabControl.SelectedTab.Image = null;
if (UserSettings.Default.IsAutoExportData)
ExportData(fullPath);
}
private bool CheckExport(UObject export) // return true once you wanna stop searching for exports
@ -697,7 +700,7 @@ namespace FModel.ViewModels
case USkeletalMesh when UserSettings.Default.SaveSkeletalMeshes:
case UMaterialInstance when UserSettings.Default.SaveMaterials:
case USkeleton when UserSettings.Default.SaveSkeletonAsMesh:
case UAnimSequence when UserSettings.Default.IsAutoSaveAnimations:
case UAnimSequence when UserSettings.Default.SaveAnimations:
{
SaveExport(export);
return true;
@ -745,7 +748,7 @@ namespace FModel.ViewModels
private void SaveExport(UObject export)
{
var toSave = new Exporter(export, UserSettings.Default.TextureExportFormat, UserSettings.Default.LodExportFormat, UserSettings.Default.MeshExportFormat);
var toSaveDirectory = new DirectoryInfo(Path.Combine(UserSettings.Default.OutputDirectory, "Saves"));
var toSaveDirectory = new DirectoryInfo(UserSettings.Default.ModelDirectory);
if (toSave.TryWriteToDir(toSaveDirectory, out var savedFileName))
{
Log.Information("Successfully saved {FileName}", savedFileName);

View File

@ -1,10 +1,8 @@
using FModel.Framework;
using FModel.ViewModels.Commands;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using FModel.Settings;
using FModel.Framework;
using FModel.ViewModels.Commands;
namespace FModel.ViewModels
{
@ -20,6 +18,6 @@ namespace FModel.ViewModels
Modes = new ReadOnlyObservableCollection<ELoadingMode>(new ObservableCollection<ELoadingMode>(EnumerateLoadingModes()));
}
private IEnumerable<ELoadingMode> EnumerateLoadingModes() => Enum.GetValues(UserSettings.Default.LoadingMode.GetType()).Cast<ELoadingMode>();
private IEnumerable<ELoadingMode> EnumerateLoadingModes() => Enum.GetValues<ELoadingMode>();
}
}
}

View File

@ -89,11 +89,11 @@ namespace FModel.ViewModels
set => SetProperty(ref _brVendingMachines, value, "ApolloGameplay_VendingMachines");
}
private bool _brFireflies;
public bool BrFireflies
private bool _brBountyBoards;
public bool BrBountyBoards
{
get => _brFireflies;
set => SetProperty(ref _brFireflies, value, "ApolloGameplay_Fireflies");
get => _brBountyBoards;
set => SetProperty(ref _brBountyBoards, value, "ApolloGameplay_BountyBoards");
}
private bool _prLandmarks;
@ -267,8 +267,8 @@ namespace FModel.ViewModels
case "ApolloGameplay_VendingMachines":
await LoadBrVendingMachines();
break;
case "ApolloGameplay_Fireflies":
await LoadFireflies();
case "ApolloGameplay_BountyBoards":
await LoadBountyBoards();
break;
case "PapayaGameplay_CannonballGame":
await LoadCannonballGame();
@ -374,13 +374,10 @@ namespace FModel.ViewModels
await _threadWorkerView.Begin(_ =>
{
// if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerBR.Default__UIMapManagerBR_C", out UObject mapManager) ||
// !mapManager.TryGetValue(out UObject mapMaterial, "MapMaterial") ||
// !mapMaterial.TryGetValue(out FStructFallback cachedExpressionData, "CachedExpressionData") ||
// !cachedExpressionData.TryGetValue(out FStructFallback parameters, "Parameters") ||
// !parameters.TryGetValue(out UTexture2D[] textureValues, "TextureValues")) return;
if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerBR.Default__UIMapManagerBR_C", out UObject mapManager) ||
!mapManager.TryGetValue(out UMaterial mapMaterial, "MapMaterial") || mapMaterial.ReferencedTextures.Count < 1) return;
_bitmaps[0][_FIRST_BITMAP] = new MapLayer{Layer = Utils.GetBitmap("FortniteGame/Content/Athena/Apollo/Maps/UI/Apollo_Terrain_Minimap.Apollo_Terrain_Minimap"), IsEnabled = true};
_bitmaps[0][_FIRST_BITMAP] = new MapLayer{Layer = Utils.GetBitmap(mapMaterial.ReferencedTextures[0] as UTexture2D), IsEnabled = true};
_brMiniMapImage = GetImageSource(_bitmaps[0][_FIRST_BITMAP].Layer);
});
}
@ -392,11 +389,10 @@ namespace FModel.ViewModels
await _threadWorkerView.Begin(_ =>
{
// if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerPapaya.Default__UIMapManagerPapaya_C", out UObject mapManager) ||
// !mapManager.TryGetValue(out UMaterial mapMaterial, "MapMaterial") ||
// mapMaterial.ReferencedTextures.Count < 1) return;
if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerPapaya.Default__UIMapManagerPapaya_C", out UObject mapManager) ||
!mapManager.TryGetValue(out UMaterial mapMaterial, "MapMaterial") || mapMaterial.ReferencedTextures.Count < 1) return;
_bitmaps[1][_FIRST_BITMAP] = new MapLayer{Layer = Utils.GetBitmap("FortniteGame/Content/Athena/Apollo/Maps/Special/Papaya/UI/MiniMapPapaya.MiniMapPapaya"), IsEnabled = true};
_bitmaps[1][_FIRST_BITMAP] = new MapLayer{Layer = Utils.GetBitmap(mapMaterial.ReferencedTextures[0] as UTexture2D), IsEnabled = true};
_prMiniMapImage = GetImageSource(_bitmaps[1][_FIRST_BITMAP].Layer);
});
}
@ -808,19 +804,19 @@ namespace FModel.ViewModels
});
}
private async Task LoadFireflies()
private async Task LoadBountyBoards()
{
await _threadWorkerView.Begin(_ =>
{
_fillPaint.StrokeWidth = 5;
var firefliesBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul);
using var c = new SKCanvas(firefliesBitmap);
var bountyBoardsBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul);
using var c = new SKCanvas(bountyBoardsBitmap);
var exports = Utils.LoadExports("FortniteGame/Content/Athena/Apollo/Maps/Special/ItemCollections/Apollo_Item_Fireflies");
var exports = Utils.LoadExports("Bounties/Maps/BB_Overlay_S19_ServiceStations.umap");
foreach (var export in exports)
{
if (!export.ExportType.Equals("BP_BGACSpawner_Fireflies_C", StringComparison.OrdinalIgnoreCase)) continue;
var displayName = $"FF_{export.Name["BP_BGACSpawnerFireFlies".Length..]}";
if (!export.ExportType.Equals("B_Bounties_Spawner_BountyBoard_C", StringComparison.OrdinalIgnoreCase)) continue;
var displayName = $"BountyBoard_{export.Name["BP_BountyBoard_C_".Length..]}";
if (!export.TryGetValue(out FPackageIndex rootComponent, "RootComponent") ||
!Utils.TryGetPackageIndexExport(rootComponent, out UObject uObject) ||
@ -832,7 +828,7 @@ namespace FModel.ViewModels
c.DrawText(displayName, vector.X, vector.Y - 12.5F, _textPaint);
}
_bitmaps[0]["ApolloGameplay_Fireflies"] = new MapLayer {Layer = firefliesBitmap, IsEnabled = false};
_bitmaps[0]["ApolloGameplay_BountyBoards"] = new MapLayer {Layer = bountyBoardsBitmap, IsEnabled = false};
});
}

View File

@ -140,6 +140,7 @@ namespace FModel.ViewModels
}
});
if (AppendMode && CanAppend) return;
SelectedModel = p;
Cam.UpDirection = new Vector3D(0, 1, 0);
Cam.Position = p.Position;
@ -201,36 +202,18 @@ namespace FModel.ViewModels
}
}
public bool CheckIfSaved(string path)
{
if (File.Exists(path))
{
Log.Information("Successfully saved {FileName}", path);
FLogger.AppendInformation();
FLogger.AppendText($"Successfully saved {path}", Constants.WHITE, true);
return true;
}
else
{
Log.Error("{FileName} could not be saved", path);
FLogger.AppendError();
FLogger.AppendText($"Could not save '{path}'", Constants.WHITE, true);
return false;
}
}
public void SaveAsScene()
{
if (_loadedModels.Count < 1) return;
var fileBrowser = new VistaSaveFileDialog()
var fileBrowser = new VistaSaveFileDialog
{
Title = "Save Loaded Models As...",
DefaultExt = ".glb",
Filter = "glTF Binary File (*.glb)|*.glb|glTF ASCII File (*.gltf)|*.gltf|All Files(*.*)|*.*",
AddExtension = true,
OverwritePrompt = true,
CheckPathExists = true,
CheckPathExists = true
};
if (fileBrowser.ShowDialog() == false || string.IsNullOrEmpty(fileBrowser.FileName)) return;
@ -289,8 +272,7 @@ namespace FModel.ViewModels
if (!CheckIfSaved(fileName)) return;
foreach (var materialExport in materialExports)
{
materialExport.TryWriteToDir(new DirectoryInfo(StringUtils.SubstringBeforeWithLast(fileName, '\\')),
out var _);
materialExport.TryWriteToDir(new DirectoryInfo(StringUtils.SubstringBeforeWithLast(fileName, '\\')), out _);
}
}
@ -606,6 +588,22 @@ namespace FModel.ViewModels
return input.Replace('-', '_');
}
private bool CheckIfSaved(string path)
{
if (File.Exists(path))
{
Log.Information("Successfully saved {FileName}", path);
FLogger.AppendInformation();
FLogger.AppendText($"Successfully saved {path}", Constants.WHITE, true);
return true;
}
Log.Error("{FileName} could not be saved", path);
FLogger.AppendError();
FLogger.AppendText($"Could not save '{path}'", Constants.WHITE, true);
return false;
}
public void Clear()
{
foreach (var g in _loadedModels.ToList())

View File

@ -1,7 +1,6 @@
using System;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using CUE4Parse.UE4.Objects.Core.Misc;
using CUE4Parse.UE4.Objects.Core.Serialization;
@ -134,6 +133,7 @@ namespace FModel.ViewModels
private readonly FGame _game;
private Game _gamePreset;
private string _outputSnapshot;
private string _modelSnapshot;
private string _gameSnapshot;
private EUpdateMode _updateModeSnapshot;
private string _presetSnapshot;
@ -155,6 +155,7 @@ namespace FModel.ViewModels
public void Initialize()
{
_outputSnapshot = UserSettings.Default.OutputDirectory;
_modelSnapshot = UserSettings.Default.ModelDirectory;
_gameSnapshot = UserSettings.Default.GameDirectory;
_updateModeSnapshot = UserSettings.Default.UpdateMode;
_presetSnapshot = UserSettings.Default.Presets[_game];
@ -242,6 +243,7 @@ namespace FModel.ViewModels
if (_ueGameSnapshot != SelectedUeGame || // combobox
_customVersionsSnapshot != SelectedCustomVersions || _optionsSnapshot != SelectedOptions ||
_outputSnapshot != UserSettings.Default.OutputDirectory || // textbox
_modelSnapshot != UserSettings.Default.ModelDirectory || // textbox
_gameSnapshot != UserSettings.Default.GameDirectory) // textbox
ret = SettingsOut.Restart;
@ -268,19 +270,19 @@ namespace FModel.ViewModels
return ret;
}
private IEnumerable<EUpdateMode> EnumerateUpdateModes() => Enum.GetValues(SelectedUpdateMode.GetType()).Cast<EUpdateMode>();
private IEnumerable<EUpdateMode> EnumerateUpdateModes() => Enum.GetValues<EUpdateMode>();
private IEnumerable<string> EnumeratePresets()
{
yield return Constants._NO_PRESET_TRIGGER;
}
private IEnumerable<EGame> EnumerateUeGames() => Enum.GetValues(SelectedUeGame.GetType()).Cast<EGame>();
private IEnumerable<ELanguage> EnumerateAssetLanguages() => Enum.GetValues(SelectedAssetLanguage.GetType()).Cast<ELanguage>();
private IEnumerable<EAesReload> EnumerateAesReloads() => Enum.GetValues(SelectedAesReload.GetType()).Cast<EAesReload>();
private IEnumerable<EDiscordRpc> EnumerateDiscordRpcs() => Enum.GetValues(SelectedDiscordRpc.GetType()).Cast<EDiscordRpc>();
private IEnumerable<ECompressedAudio> EnumerateCompressedAudios() => Enum.GetValues(SelectedCompressedAudio.GetType()).Cast<ECompressedAudio>();
private IEnumerable<EIconStyle> EnumerateCosmeticStyles() => Enum.GetValues(SelectedCosmeticStyle.GetType()).Cast<EIconStyle>();
private IEnumerable<EMeshFormat> EnumerateMeshExportFormat() => Enum.GetValues(SelectedMeshExportFormat.GetType()).Cast<EMeshFormat>();
private IEnumerable<ELodFormat> EnumerateLodExportFormat() => Enum.GetValues(SelectedLodExportFormat.GetType()).Cast<ELodFormat>();
private IEnumerable<ETextureFormat> EnumerateTextureExportFormat() => Enum.GetValues(SelectedTextureExportFormat.GetType()).Cast<ETextureFormat>();
private IEnumerable<EGame> EnumerateUeGames() => Enum.GetValues<EGame>();
private IEnumerable<ELanguage> EnumerateAssetLanguages() => Enum.GetValues<ELanguage>();
private IEnumerable<EAesReload> EnumerateAesReloads() => Enum.GetValues<EAesReload>();
private IEnumerable<EDiscordRpc> EnumerateDiscordRpcs() => Enum.GetValues<EDiscordRpc>();
private IEnumerable<ECompressedAudio> EnumerateCompressedAudios() => Enum.GetValues<ECompressedAudio>();
private IEnumerable<EIconStyle> EnumerateCosmeticStyles() => Enum.GetValues<EIconStyle>();
private IEnumerable<EMeshFormat> EnumerateMeshExportFormat() => Enum.GetValues<EMeshFormat>();
private IEnumerable<ELodFormat> EnumerateLodExportFormat() => Enum.GetValues<ELodFormat>();
private IEnumerable<ETextureFormat> EnumerateTextureExportFormat() => Enum.GetValues<ETextureFormat>();
}
}

View File

@ -37,8 +37,8 @@
<!-- DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.MapViewer}}}" IsEnabled="{Binding IsReady}" /> -->
<CheckBox Content="Weapon-o-matic/Mending Machines" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" IsChecked="{Binding MapViewer.BrVendingMachines}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.MapViewer}}}" IsEnabled="{Binding IsReady}" />
<!-- <CheckBox Content="Fireflies" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" IsChecked="{Binding MapViewer.BrFireflies}" -->
<!-- DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.MapViewer}}}" IsEnabled="{Binding IsReady}" /> -->
<CheckBox Content="Bounty Boards" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" IsChecked="{Binding MapViewer.BrBountyBoards}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.MapViewer}}}" IsEnabled="{Binding IsReady}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="PrTemplate">

View File

@ -44,7 +44,7 @@
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Models" VerticalAlignment="Center" Margin="0 0 0 10" />
<ComboBox Grid.Row="0" Grid.Column="2" Style="{StaticResource ModelsComboBox}" />
<ComboBox Grid.Row="0" Grid.Column="2" Style="{StaticResource ModelsComboBox}" IsEnabled="{Binding IsReady}" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="Triangles" VerticalAlignment="Center" Margin="0 0 0 10" />
<TextBlock Grid.Row="1" Grid.Column="2" Text="{Binding ModelViewer.SelectedModel.TriangleCount, FallbackValue=0, StringFormat={}{0:### ### ### ###}}" VerticalAlignment="Center" HorizontalAlignment="Right" />
@ -64,20 +64,21 @@
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="Focus" Click="OnFocusClick" />
<ToggleButton Grid.Row="0" Grid.Column="2" IsChecked="{Binding ModelViewer.AppendMode}" Style="{DynamicResource {x:Static adonisUi:Styles.ToolbarToggleButton}}">
<Button Grid.Row="0" Grid.Column="0" Content="Focus" Click="OnFocusClick" IsEnabled="{Binding IsReady}" />
<ToggleButton Grid.Row="0" Grid.Column="2" IsChecked="{Binding ModelViewer.AppendMode}" IsEnabled="{Binding IsReady}"
Style="{DynamicResource {x:Static adonisUi:Styles.ToolbarToggleButton}}">
<TextBlock Text="{Binding IsChecked, Converter={x:Static converters:BoolToToggleConverter.Instance},
StringFormat={}Append {0}, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ToggleButton}}}" />
</ToggleButton>
<Button Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" Click="Save"
<Button Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" Click="Save" IsEnabled="{Binding IsReady}"
Style="{DynamicResource {x:Static adonisUi:Styles.AccentButton}}">
<TextBlock Text="{Binding ModelViewer.LoadedModelsView.Count, StringFormat={}Save All Loaded Models ({0})}" />
</Button>
</Grid>
</Grid>
<Separator DockPanel.Dock="Top" Tag="MATERIALS" Style="{StaticResource CustomSeparator}" />
<ListBox x:Name="MaterialsListName" DockPanel.Dock="Top" Style="{StaticResource MaterialsListBox}">
<ListBox x:Name="MaterialsListName" DockPanel.Dock="Top" Style="{StaticResource MaterialsListBox}" IsEnabled="{Binding IsReady}">
<ListBox.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Copy Name" Click="OnCopyClick">

View File

@ -37,6 +37,8 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@ -74,9 +76,9 @@
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="4" Grid.Column="0" Text="Discord Rich Presence" VerticalAlignment="Center" Margin="0 0 0 5" />
<TextBlock Grid.Row="4" Grid.Column="0" Text="Discord Rich Presence" VerticalAlignment="Center" />
<ComboBox Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="3" ItemsSource="{Binding SettingsView.DiscordRpcs}" SelectedItem="{Binding SettingsView.SelectedDiscordRpc, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" Margin="0 0 0 5">
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={x:Static converters:EnumToStringConverter.Instance}}" />
@ -114,13 +116,8 @@
<Button Grid.Column="2" Content="Options" Click="OpenOptions" />
</Grid>
<TextBlock Grid.Row="9" Grid.Column="0" Text="Keep Directory Structure" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Auto Export &#38; Save assets inside their game directory" />
<CheckBox Grid.Row="9" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
IsChecked="{Binding KeepDirectoryStructure, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}"
Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Margin="0 5 0 10"/>
<TextBlock Grid.Row="10" Grid.Column="0" Text="Compressed Audio" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="What to do when encountering a compressed audio file" />
<ComboBox Grid.Row="10" Grid.Column="2" Grid.ColumnSpan="3" ItemsSource="{Binding SettingsView.CompressedAudios}" SelectedItem="{Binding SettingsView.SelectedCompressedAudio, Mode=TwoWay}"
<TextBlock Grid.Row="9" Grid.Column="0" Text="Compressed Audio" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="What to do when encountering a compressed audio file" />
<ComboBox Grid.Row="9" Grid.Column="2" Grid.ColumnSpan="3" ItemsSource="{Binding SettingsView.CompressedAudios}" SelectedItem="{Binding SettingsView.SelectedCompressedAudio, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" Margin="0 0 0 5">
<ComboBox.ItemTemplate>
<DataTemplate>
@ -129,7 +126,7 @@
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="11" Grid.Column="0" Text="AES Reload at Launch" VerticalAlignment="Center" Margin="0 0 0 5"
<TextBlock Grid.Row="10" Grid.Column="0" Text="AES Reload at Launch" VerticalAlignment="Center" Margin="0 0 0 5"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<TextBlock.Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
@ -142,7 +139,7 @@
</Style>
</TextBlock.Style>
</TextBlock>
<ComboBox Grid.Row="11" Grid.Column="2" Grid.ColumnSpan="3" ItemsSource="{Binding SettingsView.AesReloads}" SelectedItem="{Binding SettingsView.SelectedAesReload, Mode=TwoWay}"
<ComboBox Grid.Row="10" Grid.Column="2" Grid.ColumnSpan="3" ItemsSource="{Binding SettingsView.AesReloads}" SelectedItem="{Binding SettingsView.SelectedAesReload, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" Margin="0 0 0 5">
<ComboBox.Style>
<Style TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}">
@ -160,6 +157,45 @@
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="11" Grid.Column="0" Text="Keep Directory Structure" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Auto Export &#38; Save assets inside their game directory" />
<CheckBox Grid.Row="11" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
IsChecked="{Binding KeepDirectoryStructure, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" Margin="0 5 0 10"/>
<TextBlock Grid.Row="12" Grid.Column="0" Text="Overwrite Mapping File" VerticalAlignment="Center" Margin="0 0 0 5"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<TextBlock.Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<CheckBox Grid.Row="12" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
IsChecked="{Binding OverwriteMapping, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" Margin="0 5 0 10"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<CheckBox.Style>
<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
</CheckBox>
<TextBlock Grid.Row="13" Grid.Column="0" Text="Mapping File Path" VerticalAlignment="Center" Margin="0 0 0 5"
Visibility="{Binding OverwriteMapping, Source={x:Static local:Settings.UserSettings.Default}, Converter={StaticResource BoolToVisibilityConverter}}" />
<TextBox Grid.Row="13" Grid.Column="2" Text="{Binding MappingFilePath, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0 0 0 5"
Visibility="{Binding OverwriteMapping, Source={x:Static local:Settings.UserSettings.Default}, Converter={StaticResource BoolToVisibilityConverter}}"/>
<Button Grid.Row="13" Grid.Column="4" Content="..." HorizontalAlignment="Right" Click="OnBrowseMappings" Margin="0 0 0 5"
Visibility="{Binding OverwriteMapping, Source={x:Static local:Settings.UserSettings.Default}, Converter={StaticResource BoolToVisibilityConverter}}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="CreatorTemplate">
@ -237,15 +273,24 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Mesh Format" VerticalAlignment="Center" Margin="0 0 0 5" />
<ComboBox Grid.Row="0" Grid.Column="2" ItemsSource="{Binding SettingsView.MeshExportFormats}" SelectedItem="{Binding SettingsView.SelectedMeshExportFormat, Mode=TwoWay}"
<TextBlock Grid.Row="0" Grid.Column="0" Text="Model Saving Directory *" VerticalAlignment="Center" Margin="0 0 0 5"
ToolTip="This will be the directory where Meshes, Materials and Animations will be saved" />
<TextBox Grid.Row="0" Grid.Column="2" Text="{Binding ModelDirectory, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0 0 0 5" />
<Button Grid.Row="0" Grid.Column="4" Content="..." HorizontalAlignment="Right" Click="OnBrowseModels" Margin="0 0 0 5" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="Mesh Format" VerticalAlignment="Center" Margin="0 0 0 5" />
<ComboBox Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="3" ItemsSource="{Binding SettingsView.MeshExportFormats}" SelectedItem="{Binding SettingsView.SelectedMeshExportFormat, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" Margin="0 0 0 5">
<ComboBox.ItemTemplate>
<DataTemplate>
@ -254,8 +299,8 @@
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Level Of Detail Format" VerticalAlignment="Center" Margin="0 0 0 5" />
<ComboBox Grid.Row="1" Grid.Column="2" ItemsSource="{Binding SettingsView.LodExportFormats}" SelectedItem="{Binding SettingsView.SelectedLodExportFormat, Mode=TwoWay}"
<TextBlock Grid.Row="2" Grid.Column="0" Text="Level Of Detail Format" VerticalAlignment="Center" Margin="0 0 0 5" />
<ComboBox Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="3" ItemsSource="{Binding SettingsView.LodExportFormats}" SelectedItem="{Binding SettingsView.SelectedLodExportFormat, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" Margin="0 0 0 5">
<ComboBox.ItemTemplate>
<DataTemplate>
@ -264,8 +309,8 @@
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="2" Grid.Column="0" Text="Preview in Model Viewer" VerticalAlignment="Center" Margin="0 0 0 5" />
<UniformGrid Grid.Row="2" Grid.Column="2" HorizontalAlignment="Stretch" Rows="1" Columns="3" Margin="0 5 0 5">
<TextBlock Grid.Row="3" Grid.Column="0" Text="Preview in Model Viewer" VerticalAlignment="Center" Margin="0 0 0 5" />
<UniformGrid Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" Rows="1" Columns="3" Margin="0 5 0 10">
<CheckBox Content="Static Meshes" HorizontalAlignment="Left"
IsChecked="{Binding PreviewStaticMeshes, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}"/>
<CheckBox Content="Skeletal Meshes" HorizontalAlignment="Center"
@ -274,8 +319,8 @@
IsChecked="{Binding PreviewMaterials, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}"/>
</UniformGrid>
<TextBlock Grid.Row="3" Grid.Column="0" Text="Auto-Save without Previewing" VerticalAlignment="Center" Margin="0 0 0 5" />
<UniformGrid Grid.Row="3" Grid.Column="2" HorizontalAlignment="Stretch" Rows="1" Columns="3" Margin="0 5 0 5">
<TextBlock Grid.Row="4" Grid.Column="0" Text="Auto-Save without Previewing" VerticalAlignment="Center" Margin="0 0 0 5" />
<UniformGrid Grid.Row="4" Grid.Column="2" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" Rows="1" Columns="3" Margin="0 5 0 10">
<CheckBox Content="Static Meshes" HorizontalAlignment="Left"
IsChecked="{Binding SaveStaticMeshes, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
<CheckBox Content="Skeletal Meshes" HorizontalAlignment="Center"
@ -284,15 +329,20 @@
IsChecked="{Binding SaveMaterials, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}"/>
</UniformGrid>
<TextBlock Grid.Row="4" Grid.Column="0" Text="Save Skeletons as Empty Meshes" VerticalAlignment="Center" Margin="0 0 0 5" />
<CheckBox Grid.Row="4" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
<TextBlock Grid.Row="5" Grid.Column="0" Text="Auto-Save Animations" VerticalAlignment="Center" Margin="0 0 0 5" />
<CheckBox Grid.Row="5" Grid.Column="2" Grid.ColumnSpan="3" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
IsChecked="{Binding SaveAnimations, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}"
Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Margin="0 5 0 5"/>
<TextBlock Grid.Row="6" Grid.Column="0" Text="Save Skeletons as Empty Meshes" VerticalAlignment="Center" />
<CheckBox Grid.Row="6" Grid.Column="2" Grid.ColumnSpan="3" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
IsChecked="{Binding SaveSkeletonAsMesh, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}"
Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Margin="0 5 0 10"/>
Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Margin="0 5 0 0"/>
<Separator Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="3" Style="{StaticResource CustomSeparator}" />
<Separator Grid.Row="7" Grid.Column="0" Grid.ColumnSpan="5" Style="{StaticResource CustomSeparator}" />
<TextBlock Grid.Row="6" Grid.Column="0" Text="Texture Format" VerticalAlignment="Center" Margin="0 0 0 5" />
<ComboBox Grid.Row="6" Grid.Column="2" ItemsSource="{Binding SettingsView.TextureExportFormats}" SelectedItem="{Binding SettingsView.SelectedTextureExportFormat, Mode=TwoWay}"
<TextBlock Grid.Row="8" Grid.Column="0" Text="Texture Format" VerticalAlignment="Center" Margin="0 0 0 5" />
<ComboBox Grid.Row="8" Grid.Column="2" Grid.ColumnSpan="3" ItemsSource="{Binding SettingsView.TextureExportFormats}" SelectedItem="{Binding SettingsView.SelectedTextureExportFormat, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" Margin="0 0 0 5">
<ComboBox.ItemTemplate>
<DataTemplate>
@ -321,8 +371,6 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@ -354,35 +402,29 @@
<Separator Grid.Row="7" Grid.Column="0" Grid.ColumnSpan="3" Style="{StaticResource CustomSeparator}" />
<TextBlock Grid.Row="8" Grid.Column="0" Text="Auto Export Data *" VerticalAlignment="Center" Margin="0 0 0 5" />
<TextBlock Grid.Row="8" Grid.Column="0" Text="Auto Save Properties *" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="8" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
HotKey="{Binding AutoExportData, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
<TextBlock Grid.Row="9" Grid.Column="0" Text="Auto Save Properties *" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="9" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
HotKey="{Binding AutoSaveProps, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
<TextBlock Grid.Row="10" Grid.Column="0" Text="Auto Save Textures *" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="10" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
<TextBlock Grid.Row="9" Grid.Column="0" Text="Auto Save Textures *" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="9" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
HotKey="{Binding AutoSaveTextures, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
<TextBlock Grid.Row="11" Grid.Column="0" Text="Auto Save Animations *" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="11" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
HotKey="{Binding AutoSaveAnimations, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
<TextBlock Grid.Row="12" Grid.Column="0" Text="Auto Open Sounds *" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="12" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
<TextBlock Grid.Row="10" Grid.Column="0" Text="Auto Open Sounds *" VerticalAlignment="Center" />
<controls:HotkeyTextBox Grid.Row="10" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}"
HotKey="{Binding AutoOpenSounds, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
<Separator Grid.Row="13" Grid.Column="0" Grid.ColumnSpan="3" Style="{StaticResource CustomSeparator}" />
<Separator Grid.Row="11" Grid.Column="0" Grid.ColumnSpan="3" Style="{StaticResource CustomSeparator}" />
<TextBlock Grid.Row="14" Grid.Column="0" Text="Add Audio File" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="14" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
<TextBlock Grid.Row="12" Grid.Column="0" Text="Add Audio File" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="12" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
HotKey="{Binding AddAudio, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
<TextBlock Grid.Row="15" Grid.Column="0" Text="Play / Pause Current Audio" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="15" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
<TextBlock Grid.Row="13" Grid.Column="0" Text="Play / Pause Current Audio" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="13" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
HotKey="{Binding PlayPauseAudio, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
<TextBlock Grid.Row="16" Grid.Column="0" Text="Previous Audio" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="16" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
<TextBlock Grid.Row="14" Grid.Column="0" Text="Previous Audio" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="14" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
HotKey="{Binding PreviousAudio, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
<TextBlock Grid.Row="17" Grid.Column="0" Text="Next Audio" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="17" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
<TextBlock Grid.Row="15" Grid.Column="0" Text="Next Audio" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="15" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
HotKey="{Binding NextAudio, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
</Grid>
</DataTemplate>

View File

@ -1,9 +1,11 @@
using System.IO;
using System.Windows;
using System.Windows.Controls;
using FModel.Services;
using FModel.Settings;
using FModel.ViewModels;
using FModel.Views.Resources.Controls;
using Microsoft.Win32;
using Ookii.Dialogs.Wpf;
namespace FModel.Views
@ -48,14 +50,31 @@ namespace FModel.Views
}
}
private void OnBrowseOutput(object sender, RoutedEventArgs e)
{
if (TryBrowse(out var path)) UserSettings.Default.OutputDirectory = path;
}
private void OnBrowseDirectories(object sender, RoutedEventArgs e)
{
if (TryBrowse(out var path)) UserSettings.Default.GameDirectory = path;
}
private void OnBrowseOutput(object sender, RoutedEventArgs e)
private void OnBrowseModels(object sender, RoutedEventArgs e)
{
if (TryBrowse(out var path)) UserSettings.Default.OutputDirectory = path;
if (TryBrowse(out var path)) UserSettings.Default.ModelDirectory = path;
}
private async void OnBrowseMappings(object sender, RoutedEventArgs e)
{
var openFileDialog = new OpenFileDialog
{
Title = "Select a mapping file",
InitialDirectory = Path.Combine(UserSettings.Default.OutputDirectory, ".data"),
Filter = "USMAP Files (*.usmap)|*.usmap|All Files (*.*)|*.*"
};
if (!(bool) openFileDialog.ShowDialog()) return;
UserSettings.Default.MappingFilePath = openFileDialog.FileName;
await _applicationView.CUE4Parse.InitBenMappings();
}
private bool TryBrowse(out string path)