diff --git a/AssetEditor.sln b/AssetEditor.sln
index aab7a3425..0957bed5d 100644
--- a/AssetEditor.sln
+++ b/AssetEditor.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.5.33516.290
+# Visual Studio Version 18
+VisualStudioVersion = 18.0.11111.16 d18.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Testing", "Testing", "{18424B6A-CB8A-4CE1-935C-72459F31521B}"
EndProject
@@ -90,6 +90,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Editors.DatabaseEditor", "E
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utility.DatabaseSchemaGenerator", "Editors\DatabaseEditor\Utility.DatabaseSchemaGenerator\Utility.DatabaseSchemaGenerator.csproj", "{0298ED36-AE77-4CC3-9A46-40D700A3C225}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Audio", "Audio", "{4D35FFE2-8490-4694-8981-654016F2BD3D}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -232,7 +234,7 @@ Global
{CAEB33BF-48DF-4388-BE6B-7D7ABBB9414B} = {07AC615B-A8FC-4E1A-BDD5-BC11452429A0}
{EAFBC3D8-A146-4BA3-8024-DE4E20D3C884} = {07AC615B-A8FC-4E1A-BDD5-BC11452429A0}
{8E55B123-C8E5-4D65-AAAA-C4DC4713CB8E} = {07AC615B-A8FC-4E1A-BDD5-BC11452429A0}
- {410AC3F4-021C-4993-BCCA-1810D153075D} = {07AC615B-A8FC-4E1A-BDD5-BC11452429A0}
+ {410AC3F4-021C-4993-BCCA-1810D153075D} = {4D35FFE2-8490-4694-8981-654016F2BD3D}
{4FA1E72D-8764-4E6E-8C3A-B6BFE0821B5C} = {07AC615B-A8FC-4E1A-BDD5-BC11452429A0}
{F513A090-CC3F-4DB4-8332-50EB3FDA5A37} = {07AC615B-A8FC-4E1A-BDD5-BC11452429A0}
{0B14A236-AAE0-4E9B-A41E-4AF9DD976BA7} = {18424B6A-CB8A-4CE1-935C-72459F31521B}
@@ -257,6 +259,7 @@ Global
{5A4DFCA4-6884-49D2-BA24-A9C8676A0C77} = {07AC615B-A8FC-4E1A-BDD5-BC11452429A0}
{BEE61E8C-B25D-4982-9C42-6131AED41B48} = {5A4DFCA4-6884-49D2-BA24-A9C8676A0C77}
{0298ED36-AE77-4CC3-9A46-40D700A3C225} = {5A4DFCA4-6884-49D2-BA24-A9C8676A0C77}
+ {4D35FFE2-8490-4694-8981-654016F2BD3D} = {07AC615B-A8FC-4E1A-BDD5-BC11452429A0}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AB5968F3-98ED-4AFF-98EA-0DBEDCACADF2}
diff --git a/AssetEditor/AssetEditor.csproj b/AssetEditor/AssetEditor.csproj
index 0042bb0d1..8c81e80bb 100644
--- a/AssetEditor/AssetEditor.csproj
+++ b/AssetEditor/AssetEditor.csproj
@@ -28,6 +28,14 @@
+
+
+ Content\%(RecursiveDir)%(Filename)%(Extension)
+ PreserveNewest
+ Always
+
+
+
embedded
AssetEdCommunity
@@ -43,22 +51,19 @@
-
-
+ Make sure any documentation comments which are included in code get checked for syntax during the build, but do
+ not report warnings for missing comments.
+ CS1573: Parameter 'parameter' has no matching param tag in the XML comment for 'parameter' (but other parameters do)
+ CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+ CS1712: Type parameter 'type_parameter' has no matching typeparam tag in the XML comment on 'type_or_member' (but other type parameters do)
+ -->
False
$(NoWarn),1573,1591,1712
-
\ No newline at end of file
diff --git a/AssetEditor/ViewModels/SettingsViewModel.cs b/AssetEditor/ViewModels/SettingsViewModel.cs
index f29543ab6..aa7c8ef94 100644
--- a/AssetEditor/ViewModels/SettingsViewModel.cs
+++ b/AssetEditor/ViewModels/SettingsViewModel.cs
@@ -37,12 +37,12 @@ public SettingsViewModel(ApplicationSettingsService settingsService)
RenderEngineBackgroundColours = new ObservableCollection((BackgroundColour[])Enum.GetValues(typeof(BackgroundColour)));
CurrentRenderEngineBackgroundColour = _settingsService.CurrentSettings.RenderEngineBackgroundColour;
StartMaximised = _settingsService.CurrentSettings.StartMaximised;
- Games = new ObservableCollection(GameInformationDatabase.Games.OrderBy(g => g.DisplayName).Select(g => g.Type));
+ Games = new ObservableCollection(GameInformationDatabase.Games.Values.OrderBy(game => game.DisplayName).Select(game => game.Type));
CurrentGame = _settingsService.CurrentSettings.CurrentGame;
LoadCaPacksByDefault = _settingsService.CurrentSettings.LoadCaPacksByDefault;
ShowCAWemFiles = _settingsService.CurrentSettings.ShowCAWemFiles;
OnlyLoadLod0ForReferenceMeshes = _settingsService.CurrentSettings.OnlyLoadLod0ForReferenceMeshes;
- foreach (var game in GameInformationDatabase.Games.OrderBy(g => g.DisplayName))
+ foreach (var game in GameInformationDatabase.Games.Values.OrderBy(game => game.DisplayName))
{
GameDirectores.Add(
new GamePathItem()
@@ -56,7 +56,8 @@ public SettingsViewModel(ApplicationSettingsService settingsService)
}
- [RelayCommand] private void Save()
+ [RelayCommand]
+ private void Save()
{
_settingsService.CurrentSettings.Theme = CurrentTheme;
_settingsService.CurrentSettings.RenderEngineBackgroundColour = CurrentRenderEngineBackgroundColour;
@@ -73,7 +74,8 @@ [RelayCommand] private void Save()
MessageBox.Show("Please restart the tool after updating settings!");
}
- [RelayCommand] private void Browse()
+ [RelayCommand]
+ private void Browse()
{
var dialog = new OpenFileDialog();
dialog.Filter = "Executable files (*.exe)|*.exe";
diff --git a/Audio b/Audio
new file mode 100644
index 000000000..e69de29bb
diff --git a/Editors/Audio/AudioEditor/AudioEditorService.cs b/Editors/Audio/AudioEditor/AudioEditorService.cs
deleted file mode 100644
index 7a0f5c19c..000000000
--- a/Editors/Audio/AudioEditor/AudioEditorService.cs
+++ /dev/null
@@ -1,431 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using Editors.Audio.AudioEditor.AudioFilesExplorer;
-using Editors.Audio.AudioEditor.AudioProjectData;
-using Editors.Audio.AudioEditor.AudioProjectEditor;
-using Editors.Audio.AudioEditor.AudioProjectExplorer;
-using Editors.Audio.AudioEditor.AudioProjectViewer;
-using Editors.Audio.AudioEditor.AudioSettings;
-using Editors.Audio.AudioEditor.DataGrids;
-using Editors.Audio.AudioProjectCompiler;
-using Editors.Audio.GameSettings.Warhammer3;
-using Serilog;
-using Shared.Core.ErrorHandling;
-using Shared.Core.PackFiles;
-using Shared.Core.PackFiles.Models;
-using Shared.Core.Services;
-using static Editors.Audio.GameSettings.Warhammer3.DialogueEvents;
-using static Editors.Audio.GameSettings.Warhammer3.StateGroups;
-using TreeNode = Editors.Audio.AudioEditor.AudioProjectExplorer.TreeNode;
-
-namespace Editors.Audio.AudioEditor
-{
- public class AudioEditorService : IAudioEditorService
- {
- readonly ILogger _logger = Logging.Create();
-
- private readonly IPackFileService _packFileService;
- private readonly IFileSaveService _fileSaveService;
- private readonly IStandardDialogs _standardDialogs;
- private readonly IntegrityChecker _integrityChecker;
- private readonly CompilerDataProcessor _compilerDataProcessor;
- private readonly SoundBankGenerator _soundBankGenerator;
- private readonly WemGenerator _wemGenerator;
- private readonly DatGenerator _datGenerator;
-
- public AudioEditorService(
- IPackFileService packFileService,
- IFileSaveService fileSaveService,
- IStandardDialogs standardDialogs,
- IntegrityChecker integrityChecker,
- CompilerDataProcessor compilerDataProcessor,
- SoundBankGenerator soundBankGenerator,
- WemGenerator wemGenerator,
- DatGenerator datGenerator)
- {
- _packFileService = packFileService;
- _fileSaveService = fileSaveService;
- _standardDialogs = standardDialogs;
- _integrityChecker = integrityChecker;
- _compilerDataProcessor = compilerDataProcessor;
- _soundBankGenerator = soundBankGenerator;
- _wemGenerator = wemGenerator;
- _datGenerator = datGenerator;
- }
-
- public AudioProject AudioProject { get; set; }
- public string AudioProjectFileName { get; set; }
- public string AudioProjectDirectory { get; set; }
- public AudioEditorViewModel AudioEditorViewModel { get; set; }
- public AudioProjectExplorerViewModel AudioProjectExplorerViewModel { get; set; }
- public AudioFilesExplorerViewModel AudioFilesExplorerViewModel { get; set; }
- public AudioProjectEditorViewModel AudioProjectEditorViewModel { get; set; }
- public AudioProjectViewerViewModel AudioProjectViewerViewModel { get; set; }
- public AudioSettingsViewModel AudioSettingsViewModel { get; set; }
- public Dictionary> ModdedStatesByStateGroupLookup { get; set; } = [];
- public Dictionary> DialogueEventsWithStateGroupsWithIntegrityError { get; set; } = [];
- public Dictionary DialogueEventSoundBankFiltering { get; set; } = []; // TODO: Check if unused? Also check for other unused functions.
-
- public void SaveAudioProject()
- {
- var audioProject = GetAudioProjectWithoutUnusedObjects();
-
- var options = new JsonSerializerOptions
- {
- DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
- WriteIndented = true
- };
- var audioProjectJson = JsonSerializer.Serialize(audioProject, options);
- var audioProjectFileName = $"{AudioProjectFileName}.aproj";
- var audioProjectFilePath = $"{AudioProjectDirectory}\\{audioProjectFileName}";
- var packFile = PackFile.CreateFromASCII(audioProjectFileName, audioProjectJson);
- _fileSaveService.Save(audioProjectFilePath, packFile.DataSource.ReadData(), true);
-
- _logger.Here().Information($"Saved Audio Project file: {AudioProjectDirectory}\\{AudioProjectFileName}.aproj");
- }
-
- public void LoadAudioProject(AudioEditorViewModel audioEditorViewModel)
- {
- var result = _standardDialogs.DisplayBrowseDialog([".aproj"]);
- if (result.Result)
- {
- var filePath = _packFileService.GetFullPath(result.File);
- var fileName = Path.GetFileName(filePath);
- var fileType = Path.GetExtension(filePath);
- var file = _packFileService.FindFile(filePath);
- var bytes = file.DataSource.ReadData();
- var audioProjectJson = Encoding.UTF8.GetString(bytes);
-
- audioEditorViewModel.AudioProjectExplorerViewModel.AudioProjectExplorerLabel = $"Audio Project Explorer - {DataGridHelpers.AddExtraUnderscoresToString(fileName)}";
-
- // Reset data
- audioEditorViewModel.ResetAudioEditorData();
- ResetAudioProject();
-
- // Set the AudioProject
- var savedProject = JsonSerializer.Deserialize(audioProjectJson);
- AudioProjectFileName = fileName.Replace(fileType, string.Empty);
- AudioProjectDirectory = filePath.Replace($"\\{fileName}", string.Empty);
-
- // Initialise a full Audio Project and merge the saved Audio Project with it
- InitialiseAudioProject(AudioProjectFileName, AudioProjectDirectory, savedProject.Language);
- MergeSavedAudioProjectIntoAudioProjectWithUnusedItems(savedProject);
-
- // Initialise data after AudioProject is set so it uses the correct instance
- audioEditorViewModel.InitialiseAudioEditorData();
-
- // Get the Modded States and prepare them for being added to the DataGrid ComboBoxes
- BuildModdedStatesByStateGroupLookup(AudioProject.StateGroups, ModdedStatesByStateGroupLookup);
-
- _integrityChecker.CheckAudioProjectDialogueEventIntegrity(this);
-
- _logger.Here().Information($"Loaded Audio Project: {fileName}");
- }
- }
-
- public void InitialiseAudioProject(string fileName, string directory, string language)
- {
- AudioEditorViewModel.AudioProjectExplorerViewModel.AudioProjectExplorerLabel = $"Audio Project Explorer - {DataGridHelpers.AddExtraUnderscoresToString(fileName)}";
-
- AudioProjectFileName = fileName;
- AudioProjectDirectory = directory;
- AudioProject.Language = language;
-
- InitialiseSoundBanks();
-
- InitialiseModdedStatesGroups();
-
- SortSoundBanksAlphabetically();
-
- AudioEditorViewModel.AudioProjectExplorerViewModel.CreateAudioProjectTree();
- }
-
- public void CompileAudioProject()
- {
- var audioProject = GetAudioProjectWithoutUnusedObjects();
-
- SaveAudioProject();
-
- if (audioProject.SoundBanks == null)
- return;
-
- var audioProjectFileName = AudioProjectFileName.Replace(" ", "_");
- _compilerDataProcessor.SetSoundBankData(audioProject, audioProjectFileName);
-
- // We set the data from the bottom up, so Sounds, then Actions, then Events to ensure that IDs are generated before they're referenced.
- // For example IDs set in Sounds / Sound Containers are used in Actions, and IDs set in Actions are used in Events.
- _compilerDataProcessor.SetInitialSourceData(audioProject);
-
- if (audioProject.SoundBanks.Any(soundBank => soundBank.ActionEvents != null))
- {
- _compilerDataProcessor.CreateStopActionEvents(audioProject);
- _compilerDataProcessor.SetActionData(audioProject);
- _compilerDataProcessor.SetActionEventData(audioProject);
- }
-
- if (audioProject.SoundBanks.Any(soundBank => soundBank.DialogueEvents != null))
- {
- _compilerDataProcessor.SetStatesData(audioProject);
- _compilerDataProcessor.SetDialogueEventData(audioProject);
- }
-
- _wemGenerator.GenerateWems(audioProject);
-
- _compilerDataProcessor.SetRemainingSourceData(audioProject);
-
- _wemGenerator.SaveWemsToPack(audioProject);
-
- _soundBankGenerator.GenerateSoundBanks(audioProject);
-
- _datGenerator.GenerateDatFiles(audioProject, audioProjectFileName);
-
- SaveCompiledAudioProjectToPack(audioProject);
- }
-
- private void InitialiseSoundBanks()
- {
- var soundBanks = Enum.GetValues()
- .Select(soundBankSubtype => new SoundBank
- {
- Name = SoundBanks.GetSoundBankSubTypeString(soundBankSubtype),
- SoundBankType = SoundBanks.GetSoundBankSubType(soundBankSubtype)
- })
- .ToList();
-
- AudioProject.SoundBanks = [];
-
- foreach (var soundBankSubtype in Enum.GetValues())
- {
- var soundBank = new SoundBank
- {
- Name = SoundBanks.GetSoundBankSubTypeString(soundBankSubtype),
- SoundBankType = SoundBanks.GetSoundBankSubType(soundBankSubtype)
- };
-
- if (soundBank.SoundBankType == SoundBanks.Wh3SoundBankType.ActionEventSoundBank)
- soundBank.ActionEvents = [];
- else
- {
- soundBank.DialogueEvents = [];
-
- var filteredDialogueEvents = DialogueEventData
- .Where(dialogueEvent => dialogueEvent.SoundBank == SoundBanks.GetSoundBankSubtype(soundBank.Name));
-
- foreach (var dialogueData in filteredDialogueEvents)
- {
- var dialogueEvent = new DialogueEvent
- {
- Name = dialogueData.Name,
- StatePaths = []
- };
- soundBank.DialogueEvents.Add(dialogueEvent);
- }
- }
-
- AudioProject.SoundBanks.Add(soundBank);
- }
- }
-
- private void InitialiseModdedStatesGroups()
- {
- AudioProject.StateGroups = [];
-
- foreach (var moddedStateGroup in ModdedStateGroups)
- {
- var stateGroup = new StateGroup { Name = moddedStateGroup, States = [] };
- AudioProject.StateGroups.Add(stateGroup);
- }
- }
-
- public void SortSoundBanksAlphabetically()
- {
- var sortedSoundBanks = AudioProject.SoundBanks.OrderBy(soundBank => soundBank.Name).ToList();
-
- AudioProject.SoundBanks.Clear();
-
- foreach (var soundBank in sortedSoundBanks)
- AudioProject.SoundBanks.Add(soundBank);
- }
-
- public void BuildModdedStatesByStateGroupLookup(List moddedStateGroups, Dictionary> moddedStatesByStateGroupLookup)
- {
- if (moddedStatesByStateGroupLookup == null)
- moddedStatesByStateGroupLookup = new Dictionary>();
- else
- moddedStatesByStateGroupLookup.Clear();
-
- foreach (var stateGroup in moddedStateGroups)
- {
- if (stateGroup.States != null && stateGroup.States.Count > 0)
- {
- foreach (var state in stateGroup.States)
- {
- if (!moddedStatesByStateGroupLookup.ContainsKey(stateGroup.Name))
- moddedStatesByStateGroupLookup[stateGroup.Name] = new List();
-
- moddedStatesByStateGroupLookup[stateGroup.Name].Add(state.Name);
- }
- }
- }
- }
-
- private AudioProject GetAudioProjectWithoutUnusedObjects()
- {
- var usedSoundBanksList = AudioProject.SoundBanks
- .Where(soundBank => soundBank != null)
- .Select(soundBank =>
- {
- var dialogueEvents = (soundBank.DialogueEvents ?? Enumerable.Empty())
- .Where(dialogueEvent => dialogueEvent.StatePaths != null && dialogueEvent.StatePaths.Count != 0)
- .ToList();
-
- var actionEvents = (soundBank.ActionEvents ?? Enumerable.Empty())
- .Where(actionEvent => actionEvent.Sound != null || actionEvent.RandomSequenceContainer != null)
- .ToList();
-
- return new SoundBank
- {
- Name = soundBank.Name,
- SoundBankType = soundBank.SoundBankType,
- DialogueEvents = dialogueEvents.Count != 0
- ? new List(dialogueEvents)
- : null,
- ActionEvents = actionEvents.Count != 0
- ? new List(actionEvents)
- : null
- };
- })
- .Where(soundBank => soundBank.DialogueEvents != null && soundBank.DialogueEvents.Any() || soundBank.ActionEvents != null && soundBank.ActionEvents.Any())
- .ToList();
-
- var soundBanksResult = usedSoundBanksList.Count != 0
- ? new List(usedSoundBanksList)
- : null;
-
- var usedStateGroupsList = (AudioProject.StateGroups ?? new List())
- .Where(stateGroup => stateGroup.States != null && stateGroup.States.Count != 0)
- .ToList();
-
- var stateGroupsResult = usedStateGroupsList.Count != 0
- ? new List(usedStateGroupsList)
- : null;
-
- return new AudioProject
- {
- Language = AudioProject.Language,
- SoundBanks = soundBanksResult,
- StateGroups = stateGroupsResult
- };
- }
-
- private void MergeSavedAudioProjectIntoAudioProjectWithUnusedItems(AudioProject savedProject)
- {
- if (savedProject == null)
- return;
-
- if (!string.IsNullOrEmpty(savedProject.Language))
- AudioProject.Language = savedProject.Language;
-
- if (savedProject.SoundBanks != null)
- {
- foreach (var savedSoundBank in savedProject.SoundBanks)
- {
- var soundBank = AudioProject.SoundBanks.FirstOrDefault(soundBank => soundBank.Name == savedSoundBank.Name);
- if (soundBank != null)
- {
- if (savedSoundBank.DialogueEvents != null)
- {
- foreach (var savedDialogueEvent in savedSoundBank.DialogueEvents)
- {
- var dialogueEvent = soundBank.DialogueEvents.FirstOrDefault(dialogueEvent => dialogueEvent.Name == savedDialogueEvent.Name);
- if (dialogueEvent != null)
- dialogueEvent.StatePaths = savedDialogueEvent.StatePaths;
- else
- soundBank.DialogueEvents.Add(savedDialogueEvent);
- }
- }
-
- if (savedSoundBank.ActionEvents != null)
- {
- foreach (var savedActionEvent in savedSoundBank.ActionEvents)
- {
- var actionEvent = soundBank.ActionEvents.FirstOrDefault(actionEvent => actionEvent.Name == savedActionEvent.Name);
- if (actionEvent != null)
- {
- if (actionEvent.Sound != null)
- savedActionEvent.Sound = savedActionEvent.Sound;
- else
- actionEvent.RandomSequenceContainer = savedActionEvent.RandomSequenceContainer;
- }
- else
- soundBank.ActionEvents.Add(savedActionEvent);
- }
- }
- }
- else
- AudioProject.SoundBanks.Add(savedSoundBank);
- }
- }
-
- if (savedProject.StateGroups != null)
- {
- foreach (var savedStateGroup in savedProject.StateGroups)
- {
- var stateGroup = AudioProject.StateGroups.FirstOrDefault(stateGroup => stateGroup.Name == savedStateGroup.Name);
- if (stateGroup != null)
- {
- if (savedStateGroup.States != null && savedStateGroup.States.Count != 0)
- stateGroup.States = savedStateGroup.States;
- }
- else
- AudioProject.StateGroups.Add(savedStateGroup);
- }
- }
- }
-
- private void SaveCompiledAudioProjectToPack(AudioProject audioProject)
- {
- var options = new JsonSerializerOptions
- {
- DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
- WriteIndented = true
- };
- var audioProjectJson = JsonSerializer.Serialize(audioProject, options);
- var audioProjectFileName = $"{AudioProjectFileName}_compiled.json";
- var audioProjectFilePath = $"{AudioProjectDirectory}\\{audioProjectFileName}";
- var packFile = PackFile.CreateFromASCII(audioProjectFileName, audioProjectJson);
- _fileSaveService.Save(audioProjectFilePath, packFile.DataSource.ReadData(), true);
- }
-
- public void ResetAudioProject()
- {
- AudioProject = new AudioProject();
- }
-
- public TreeNode GetSelectedExplorerNode()
- {
- return AudioProjectExplorerViewModel._selectedAudioProjectTreeNode;
- }
-
- public ObservableCollection> GetEditorDataGrid()
- {
- return AudioProjectEditorViewModel.AudioProjectEditorDataGrid;
- }
-
- public ObservableCollection> GetViewerDataGrid()
- {
- return AudioProjectViewerViewModel.AudioProjectViewerDataGrid;
- }
-
- public ObservableCollection> GetSelectedViewerRows()
- {
- return AudioProjectViewerViewModel.SelectedDataGridRows;
- }
- }
-}
diff --git a/Editors/Audio/AudioEditor/AudioEditorView.xaml.cs b/Editors/Audio/AudioEditor/AudioEditorView.xaml.cs
deleted file mode 100644
index fae94b14b..000000000
--- a/Editors/Audio/AudioEditor/AudioEditorView.xaml.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.Windows.Controls;
-using System.Windows.Input;
-
-namespace Editors.Audio.AudioEditor
-{
- public partial class AudioEditorView : UserControl
- {
- public AudioEditorViewModel ViewModel => DataContext as AudioEditorViewModel;
-
- public AudioEditorView()
- {
- InitializeComponent();
- PreviewKeyDown += AudioProjectViewerView_PreviewKeyDown;
-
- }
-
- private void AudioProjectViewerView_PreviewKeyDown(object sender, KeyEventArgs e)
- {
- if (Keyboard.Modifiers == ModifierKeys.Control)
- {
- if (e.Key == Key.C)
- {
- ViewModel?.AudioProjectViewerViewModel.CopyRows();
- e.Handled = true;
- }
- else if (e.Key == Key.V)
- {
- ViewModel?.AudioProjectViewerViewModel.PasteRows();
- e.Handled = true;
- }
- }
-
- if (e.Key == Key.Delete)
- {
- ViewModel?.AudioProjectViewerViewModel.RemoveAudioProjectViewerDataGridRow();
- e.Handled = true;
- }
- }
- }
-}
diff --git a/Editors/Audio/AudioEditor/AudioEditorViewModel.cs b/Editors/Audio/AudioEditor/AudioEditorViewModel.cs
deleted file mode 100644
index 903048d06..000000000
--- a/Editors/Audio/AudioEditor/AudioEditorViewModel.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-using CommunityToolkit.Mvvm.ComponentModel;
-using CommunityToolkit.Mvvm.Input;
-using Editors.Audio.AudioEditor.AudioFilesExplorer;
-using Editors.Audio.AudioEditor.AudioProjectEditor;
-using Editors.Audio.AudioEditor.AudioProjectExplorer;
-using Editors.Audio.AudioEditor.AudioProjectViewer;
-using Editors.Audio.AudioEditor.AudioSettings;
-using Editors.Audio.AudioEditor.NewAudioProject;
-using Shared.Core.PackFiles;
-using Shared.Core.Services;
-using Shared.Core.ToolCreation;
-using static Editors.Audio.GameSettings.Warhammer3.DialogueEvents;
-
-namespace Editors.Audio.AudioEditor
-{
- public partial class AudioEditorViewModel : ObservableObject, IEditorInterface
- {
- public AudioProjectExplorerViewModel AudioProjectExplorerViewModel { get; }
- public AudioFilesExplorerViewModel AudioFilesExplorerViewModel { get; }
- public AudioProjectEditorViewModel AudioProjectEditorViewModel { get; }
- public AudioProjectViewerViewModel AudioProjectViewerViewModel { get; }
- public AudioSettingsViewModel AudioSettingsViewModel { get; }
-
- private readonly IPackFileService _packFileService;
- private readonly IStandardDialogs _standardDialogs;
- private readonly IAudioEditorService _audioEditorService;
- private readonly IntegrityChecker _integrityChecker;
-
- public string DisplayName { get; set; } = "Audio Editor";
-
- public AudioEditorViewModel(
- AudioProjectExplorerViewModel audioProjectExplorerViewModel,
- AudioFilesExplorerViewModel audioFilesExplorerViewModel,
- AudioProjectEditorViewModel audioProjectEditorViewModel,
- AudioProjectViewerViewModel audioProjectViewerViewModel,
- AudioSettingsViewModel audioSettingsViewModel,
- IPackFileService packFileService,
- IStandardDialogs standardDialogs,
- IAudioEditorService audioEditorService,
- IntegrityChecker integrityChecker)
- {
- _packFileService = packFileService;
- _standardDialogs = standardDialogs;
- _audioEditorService = audioEditorService;
- _integrityChecker = integrityChecker;
-
- AudioProjectExplorerViewModel = audioProjectExplorerViewModel;
- AudioFilesExplorerViewModel = audioFilesExplorerViewModel;
- AudioProjectEditorViewModel = audioProjectEditorViewModel;
- AudioProjectViewerViewModel = audioProjectViewerViewModel;
- AudioSettingsViewModel = audioSettingsViewModel;
-
- InitialiseAudioEditorData();
-
- InitialiseAudioEditorService();
-
- _integrityChecker.CheckDialogueEventIntegrity(DialogueEventData);
- }
-
- [RelayCommand] public void NewAudioProject()
- {
- NewAudioProjectWindow.Show(_packFileService, _audioEditorService, _standardDialogs);
- }
-
- [RelayCommand] public void SaveAudioProject()
- {
- _audioEditorService.SaveAudioProject();
- }
-
- [RelayCommand] public void LoadAudioProject()
- {
- _audioEditorService.LoadAudioProject(this);
- }
-
- [RelayCommand] public void CompileAudioProject()
- {
- _audioEditorService.CompileAudioProject();
- }
-
- public void InitialiseAudioEditorData()
- {
- AudioProjectEditorViewModel.AudioProjectEditorDataGrid = [];
- AudioProjectViewerViewModel.AudioProjectViewerDataGrid = [];
- AudioProjectViewerViewModel.SelectedDataGridRows = [];
- AudioProjectViewerViewModel.CopiedDataGridRows = [];
- AudioProjectExplorerViewModel.DialogueEventPresets = [];
- }
- private void InitialiseAudioEditorService()
- {
- _audioEditorService.AudioEditorViewModel = this;
- _audioEditorService.AudioProjectExplorerViewModel = AudioProjectExplorerViewModel;
- _audioEditorService.AudioFilesExplorerViewModel = AudioFilesExplorerViewModel;
- _audioEditorService.AudioProjectEditorViewModel = AudioProjectEditorViewModel;
- _audioEditorService.AudioProjectViewerViewModel = AudioProjectViewerViewModel;
- _audioEditorService.AudioSettingsViewModel = AudioSettingsViewModel;
- }
- public void ResetAudioEditorData()
- {
- AudioProjectEditorViewModel.AudioProjectEditorDataGrid = null;
- AudioProjectViewerViewModel.AudioProjectViewerDataGrid = null;
- AudioProjectViewerViewModel.SelectedDataGridRows = null;
- AudioProjectViewerViewModel.CopiedDataGridRows = null;
- AudioProjectExplorerViewModel._selectedAudioProjectTreeNode = null;
- AudioProjectExplorerViewModel.AudioProjectTree.Clear();
- }
-
- public void Close()
- {
- ResetAudioEditorData();
- _audioEditorService.ResetAudioProject();
- }
- }
-}
diff --git a/Editors/Audio/AudioEditor/AudioFilesExplorer/AudioFilesExplorerView.xaml.cs b/Editors/Audio/AudioEditor/AudioFilesExplorer/AudioFilesExplorerView.xaml.cs
deleted file mode 100644
index c772317a2..000000000
--- a/Editors/Audio/AudioEditor/AudioFilesExplorer/AudioFilesExplorerView.xaml.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System.Windows;
-using System.Windows.Controls;
-
-namespace Editors.Audio.AudioEditor.AudioFilesExplorer
-{
- public partial class AudioFilesExplorerView : UserControl
- {
- public AudioFilesExplorerView()
- {
- InitializeComponent();
- }
-
- private void ClearButtonClick(object sender, RoutedEventArgs e)
- {
- FilterTextBoxItem.Focus();
- }
- }
-}
diff --git a/Editors/Audio/AudioEditor/AudioFilesExplorer/AudioFilesExplorerViewModel.cs b/Editors/Audio/AudioEditor/AudioFilesExplorer/AudioFilesExplorerViewModel.cs
deleted file mode 100644
index 59e336ebc..000000000
--- a/Editors/Audio/AudioEditor/AudioFilesExplorer/AudioFilesExplorerViewModel.cs
+++ /dev/null
@@ -1,308 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Collections.Specialized;
-using System.Linq;
-using CommunityToolkit.Mvvm.ComponentModel;
-using CommunityToolkit.Mvvm.Input;
-using Editors.Audio.AudioEditor.AudioSettings;
-using Editors.Audio.AudioEditor.DataGrids;
-using Editors.Audio.AudioEditor.Events;
-using Editors.Audio.Utility;
-using Shared.Core.Events;
-using Shared.Core.Misc;
-using Shared.Core.PackFiles;
-using Shared.Core.PackFiles.Models;
-using Shared.Core.ToolCreation;
-
-namespace Editors.Audio.AudioEditor.AudioFilesExplorer
-{
- public partial class AudioFilesExplorerViewModel : ObservableObject, IEditorInterface
- {
- private readonly IEventHub _eventHub;
- private readonly IPackFileService _packFileService;
- private readonly IAudioEditorService _audioEditorService;
- private readonly SoundPlayer _soundPlayer;
-
- public string DisplayName { get; set; } = "Audio Files Explorer";
-
- [ObservableProperty] private string _audioFilesExplorerLabel;
- [ObservableProperty] private bool _isAddAudioFilesButtonEnabled = false;
- [ObservableProperty] private bool _isPlayAudioButtonEnabled = false;
- [ObservableProperty] private string _searchQuery;
- [ObservableProperty] private ObservableCollection _audioFilesTree;
- private ObservableCollection _unfilteredTree;
-
- public ObservableCollection SelectedTreeNodes { get; set; } = new ObservableCollection();
-
- public AudioFilesExplorerViewModel(IEventHub eventHub, IPackFileService packFileService, IAudioEditorService audioEditorService, SoundPlayer soundPlayer)
- {
- _eventHub = eventHub;
- _packFileService = packFileService;
- _audioEditorService = audioEditorService;
- _soundPlayer = soundPlayer;
-
- SelectedTreeNodes.CollectionChanged += OnSelectedTreeNodesChanged;
-
- AudioFilesExplorerLabel = $"{DisplayName}";
-
- Initialise();
-
- _eventHub.Register(this, OnSelectedNodeChanged);
- }
-
- private void Initialise()
- {
- var editablePack = _packFileService.GetEditablePack();
-
- if (editablePack == null)
- return;
-
- AudioFilesExplorerLabel = $"{DisplayName} - {DataGridHelpers.AddExtraUnderscoresToString(editablePack.Name)}";
-
- CreateAudioFilesTree(editablePack);
- }
-
- public void OnSelectedNodeChanged(NodeSelectedEvent nodeSelectedEvent)
- {
- ResetButtonEnablement();
- SetButtonEnablement();
- }
-
- private void OnSelectedTreeNodesChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- if (e.Action == NotifyCollectionChangedAction.Add)
- {
- foreach (TreeNode addedNode in e.NewItems)
- {
- if (addedNode.NodeType != NodeType.WavFile)
- SelectedTreeNodes.Remove(addedNode);
- }
- }
-
- SetButtonEnablement();
- }
-
- partial void OnSearchQueryChanged(string value)
- {
- if (string.IsNullOrWhiteSpace(SearchQuery))
- ResetTree();
- else
- AudioFilesTree = FilterFileTree(SearchQuery);
- }
-
- private void CreateAudioFilesTree(PackFileContainer editablePack)
- {
- var wavFilePaths = editablePack.FileList
- .Where(x => x.Key.EndsWith(".wav", StringComparison.OrdinalIgnoreCase))
- .Select(x => x.Key.Split('\\'))
- .ToList();
-
- var uniqueDirectoryPaths = wavFilePaths
- .Select(parts => string.Join("\\", parts.Take(parts.Length - 1)))
- .Where(path => !string.IsNullOrWhiteSpace(path)) // remove the empty (pack) directory
- .ToHashSet();
-
- var nodeDictionary = new Dictionary();
- var rootNodes = new ObservableCollection();
-
- foreach (var directoryPath in uniqueDirectoryPaths)
- AddDirectoryToTree(rootNodes, directoryPath, nodeDictionary);
-
- foreach (var filePathParts in wavFilePaths)
- AddFileToTree(filePathParts, nodeDictionary, rootNodes);
-
- AudioFilesTree = rootNodes;
- _unfilteredTree = new ObservableCollection(AudioFilesTree);
- }
-
- private static void AddDirectoryToTree(ObservableCollection rootNodes, string directoryPath, Dictionary nodeDictionary)
- {
- var currentPath = string.Empty;
- TreeNode currentNode = null;
-
- foreach (var directory in directoryPath.Split('\\'))
- {
- if (string.IsNullOrEmpty(currentPath))
- currentPath = directory;
- else
- currentPath = $"{currentPath}\\{directory}";
-
- if (!nodeDictionary.TryGetValue(currentPath, out var directoryNode))
- {
- directoryNode = new TreeNode
- {
- Name = directory,
- NodeType = NodeType.Directory,
- FilePath = currentPath,
- Children = new ObservableCollection()
- };
-
- if (currentNode == null)
- rootNodes.Add(directoryNode);
- else
- currentNode.Children.Add(directoryNode);
-
- nodeDictionary[currentPath] = directoryNode;
- }
-
- currentNode = directoryNode;
- }
- }
-
- private static void AddFileToTree(string[] filePathParts, Dictionary nodeDictionary, ObservableCollection rootNodes)
- {
- if (filePathParts.Length == 1)
- {
- var fileNode = new TreeNode
- {
- Name = filePathParts[0],
- NodeType = NodeType.WavFile,
- FilePath = filePathParts[0]
- };
- rootNodes.Add(fileNode);
- nodeDictionary[filePathParts[0]] = fileNode;
- return;
- }
-
- var directoryPath = string.Join("\\", filePathParts.Take(filePathParts.Length - 1));
- if (nodeDictionary.TryGetValue(directoryPath, out var directoryNode))
- {
- var fileNode = new TreeNode
- {
- Name = filePathParts[^1],
- NodeType = NodeType.WavFile,
- FilePath = string.Join("\\", filePathParts)
- };
- directoryNode.Children.Add(fileNode);
- nodeDictionary[fileNode.FilePath] = fileNode;
- }
- }
-
- private void ResetTree()
- {
- AudioFilesTree = new ObservableCollection(_unfilteredTree);
- }
-
- private ObservableCollection FilterFileTree(string query)
- {
- var filteredTree = new ObservableCollection();
-
- foreach (var treeNode in _unfilteredTree)
- {
- var filteredNode = FilterTreeNode(treeNode, query);
- if (filteredNode != null)
- filteredTree.Add(filteredNode);
- }
-
- return filteredTree;
- }
-
- private static TreeNode FilterTreeNode(TreeNode node, string query)
- {
- var matchesQuery = node.Name.Contains(query, StringComparison.OrdinalIgnoreCase);
- var filteredChildren = node.Children
- .Select(child => FilterTreeNode(child, query))
- .Where(child => child != null)
- .ToList();
-
- if (matchesQuery || filteredChildren.Count != 0)
- {
- var filteredNode = new TreeNode
- {
- Name = node.Name,
- NodeType = node.NodeType,
- Parent = node.Parent,
- Children = new ObservableCollection(filteredChildren),
- IsNodeExpanded = true
- };
- return filteredNode;
- }
-
- return null;
- }
-
- [RelayCommand] public void CollapseOrExpandAudioFilesTree()
- {
- if (AudioFilesTree == null || AudioFilesTree.Count == 0)
- return;
-
- var isExpanded = AudioFilesTree.Any(node => node.IsNodeExpanded);
-
- foreach (var rootNode in AudioFilesTree)
- ToggleNodeExpansion(rootNode, !isExpanded);
- }
-
- private static void ToggleNodeExpansion(TreeNode node, bool shouldExpand)
- {
- node.IsNodeExpanded = shouldExpand;
-
- foreach (var child in node.Children)
- ToggleNodeExpansion(child, shouldExpand);
- }
-
- [RelayCommand] public void AddAudioFilesToAudioProjectEditor()
- {
- _audioEditorService.AudioSettingsViewModel.AudioFiles.Clear();
-
- foreach (var wavFile in SelectedTreeNodes)
- {
- _audioEditorService.AudioEditorViewModel.AudioSettingsViewModel.AudioFiles.Add(new AudioFile
- {
- FileName = wavFile.Name,
- FilePath = wavFile.FilePath
- });
- }
-
- _audioEditorService.AudioSettingsViewModel.SetAudioSettingsEnablementAndVisibility();
- _audioEditorService.AudioSettingsViewModel.ResetShowSettingsFromAudioProjectViewer();
- _audioEditorService.AudioProjectEditorViewModel.SetAddRowButtonEnablement();
- }
-
- [RelayCommand] public void PlayWavFile()
- {
- if (!IsPlayAudioButtonEnabled)
- return;
-
- var wavFileNode = SelectedTreeNodes[0];
- var wavFile = _packFileService.FindFile(wavFileNode.FilePath);
- var wavFileName = $"{wavFileNode.Name}";
-
- _soundPlayer.ExportFileToAEFolder(wavFileName, wavFile.DataSource.ReadData());
-
- var audioFolderName = $"{DirectoryHelper.Temp}\\Audio";
- var wavFilePath = $"{audioFolderName}\\{wavFileName}";
-
- _soundPlayer.PlayWav(wavFilePath);
- }
-
- [RelayCommand] public void ClearText()
- {
- SearchQuery = "";
- }
-
- public void SetButtonEnablement()
- {
- IsPlayAudioButtonEnabled = SelectedTreeNodes.Count == 1;
-
- var selectedNode = _audioEditorService.GetSelectedExplorerNode();
- if (selectedNode == null)
- return;
-
- if (SelectedTreeNodes.Count > 0)
- {
- if (selectedNode.NodeType == AudioProjectExplorer.NodeType.ActionEventSoundBank || selectedNode.NodeType == AudioProjectExplorer.NodeType.DialogueEvent)
- IsAddAudioFilesButtonEnabled = true;
- }
- else
- IsAddAudioFilesButtonEnabled = false;
- }
-
- public void ResetButtonEnablement()
- {
- IsAddAudioFilesButtonEnabled = false;
- }
-
- public void Close() {}
- }
-}
diff --git a/Editors/Audio/AudioEditor/AudioFilesExplorer/MultiSelectTreeView.cs b/Editors/Audio/AudioEditor/AudioFilesExplorer/MultiSelectTreeView.cs
deleted file mode 100644
index 2c582ca7b..000000000
--- a/Editors/Audio/AudioEditor/AudioFilesExplorer/MultiSelectTreeView.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Input;
-using System.Windows.Media;
-
-namespace Editors.Audio.AudioEditor.AudioFilesExplorer
-{
- public class MultiSelectTreeView : TreeView
- {
- public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register("SelectedItems", typeof(IList), typeof(MultiSelectTreeView), new PropertyMetadata(new ArrayList(), OnSelectedItemsChanged));
- public static readonly DependencyProperty IsMultiSelectedProperty = DependencyProperty.RegisterAttached("IsMultiSelected", typeof(bool), typeof(MultiSelectTreeView), new PropertyMetadata(false));
-
- private TreeNode _anchorItem;
-
- public IList SelectedItems
- {
- get { return (IList)GetValue(SelectedItemsProperty); }
- set { SetValue(SelectedItemsProperty, value); }
- }
-
- public MultiSelectTreeView()
- {
- if (SelectedItems is INotifyCollectionChanged collection)
- collection.CollectionChanged += OnSelectedItemsCollectionChanged;
-
- PreviewMouseDown += MultiSelectTreeView_PreviewMouseDown;
- }
-
- private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is MultiSelectTreeView treeView)
- treeView.UpdateSelectionStates();
- }
-
- private void OnSelectedItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
- {
- UpdateSelectionStates();
- }
-
- public static bool GetIsMultiSelected(DependencyObject obj)
- {
- return (bool)obj.GetValue(IsMultiSelectedProperty);
- }
-
- public static void SetIsMultiSelected(DependencyObject obj, bool value)
- {
- obj.SetValue(IsMultiSelectedProperty, value);
- }
-
- private void MultiSelectTreeView_PreviewMouseDown(object sender, MouseButtonEventArgs e)
- {
- if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
- {
- var clickedItem = GetTreeViewItemUnderMouse(e);
- if (clickedItem?.DataContext is TreeNode clickedNode)
- {
- if (SelectedItems.Contains(clickedNode))
- {
- SelectedItems.Remove(clickedNode);
-
- if (_anchorItem == clickedNode)
- {
- _anchorItem = null;
- clickedItem.IsSelected = false;
- }
- }
- else
- {
- SelectedItems.Add(clickedNode);
- _anchorItem ??= clickedNode;
- }
-
- UpdateSelectionStates();
- e.Handled = true;
- }
- }
- }
-
- protected override void OnSelectedItemChanged(RoutedPropertyChangedEventArgs