'The Dark Pictures Anthology: House of Ashes' Wwise support (#632)

* 'The Dark Pictures Anthology: House of Ashes' Wwise support

* AnyItemMeetsConditionConverter.ConditionMode

---------

Co-authored-by: Asval <asval.contactme@gmail.com>
This commit is contained in:
Masusder 2026-01-19 20:33:32 +01:00 committed by GitHub
parent 86ec2a931e
commit b9315cc298
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 42 additions and 4 deletions

View File

@ -19,6 +19,7 @@ using CUE4Parse.FileProvider.Objects;
using CUE4Parse.FileProvider.Vfs;
using CUE4Parse.GameTypes.Aion2.Objects;
using CUE4Parse.GameTypes.AshEchoes.FileProvider;
using CUE4Parse.GameTypes.DPA.UE4.Assets.Exports.Wwise;
using CUE4Parse.GameTypes.KRD.Assets.Exports;
using CUE4Parse.MappingsProvider;
using CUE4Parse.UE4.AssetRegistry;
@ -1060,6 +1061,13 @@ public class CUE4ParseViewModel : ViewModel
TabControl.SelectedTab.AddImage(sourceFile.SubstringAfterLast('/'), false, bitmap, false, updateUi);
return false;
}
// The Dark Pictures Anthology: House of Ashes
case UExternalSource when (isNone || saveAudio) && pointer.Object.Value is UExternalSource externalSource:
{
var audioName = Path.GetFileNameWithoutExtension(externalSource.ExternalSourcePath);
SaveAndPlaySound(audioName, "wem", externalSource.Data?.WemFile ?? [], saveAudio);
return false;
}
case UAkAudioEvent when (isNone || saveAudio) && pointer.Object.Value is UAkAudioEvent audioEvent:
{

View File

@ -6,6 +6,7 @@ using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using CUE4Parse.FileProvider.Objects;
using CUE4Parse.GameTypes.DPA.UE4.Assets.Exports.Wwise;
using CUE4Parse.GameTypes.FN.Assets.Exports.DataAssets;
using CUE4Parse.UE4.Assets;
using CUE4Parse.UE4.Assets.Exports.Animation;
@ -200,7 +201,8 @@ public class GameFileViewModel(GameFile asset) : ViewModel
UCurveBase => EAssetCategory.CurveBase,
UWwiseAssetLibrary or USoundBase or UAkMediaAssetData or UAtomWaveBank or USoundAtomCue
or UAtomCueSheet or USoundAtomCueSheet or UFMODBank or UFMODEvent or UAkAudioType => EAssetCategory.Audio,
or UAtomCueSheet or USoundAtomCueSheet or UFMODBank or UFMODEvent or UAkAudioType
or UExternalSource or UExternalSourceBank => EAssetCategory.Audio,
UFileMediaSource => EAssetCategory.Video,
UFont or UFontFace => EAssetCategory.Font,

View File

@ -157,9 +157,10 @@
<MenuItem.IsEnabled>
<Binding Path="PlacementTarget.SelectedItems" RelativeSource="{RelativeSource AncestorType=ContextMenu}">
<Binding.Converter>
<converters:AnyItemMeetsConditionConverter>
<converters:AnyItemMeetsConditionConverter ConditionMode="Or">
<converters:AnyItemMeetsConditionConverter.Conditions>
<converters:ItemCategoryCondition Category="Texture" />
<converters:ItemCategoryCondition Category="ItemDefinitionBase" />
</converters:AnyItemMeetsConditionConverter.Conditions>
</converters:AnyItemMeetsConditionConverter>
</Binding.Converter>

View File

@ -14,18 +14,36 @@ public class AnyItemMeetsConditionConverter : IValueConverter
{
public Collection<IItemCondition> Conditions { get; } = [];
/// <summary>
/// Determines how multiple conditions are evaluated. Default is 'And'.
/// </summary>
public EConditionMode ConditionMode { get; set; } = EConditionMode.And;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not IEnumerable items || Conditions.Count == 0)
return false;
return items.OfType<GameFileViewModel>().Any(item => Conditions.All(c => c.Matches(item)));
Func<GameFileViewModel, bool> predicate = ConditionMode switch
{
EConditionMode.And => item => Conditions.All(condition => condition.Matches(item)),
EConditionMode.Or => item => Conditions.Any(condition => condition.Matches(item)),
_ => throw new ArgumentOutOfRangeException()
};
return items.OfType<GameFileViewModel>().Any(predicate);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public enum EConditionMode
{
And,
Or
}
}
public interface IItemCondition
@ -39,7 +57,16 @@ public class ItemCategoryCondition : IItemCondition
public bool Matches(GameFileViewModel item)
{
return item != null && item.AssetCategory.IsOfCategory(Category);
if (item == null) return false;
// if the specified category is a base category, check if the item's category is derived from it
if (Category.IsBaseCategory())
{
return item.AssetCategory.IsOfCategory(Category);
}
// if the specified category is a targeted non-base category, check for exact match
return item.AssetCategory == Category;
}
}