diff --git a/CUE4Parse b/CUE4Parse index 1f6ce163..03adf9bf 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 1f6ce1632134663c1dcc9467bdf05c0b486110ea +Subproject commit 03adf9bfeddeda725cbbdfa7951e51ff61f0801d diff --git a/FModel/Creator/Bases/FN/BaseIconStats.cs b/FModel/Creator/Bases/FN/BaseIconStats.cs index 4ee9a578..e0fbc220 100644 --- a/FModel/Creator/Bases/FN/BaseIconStats.cs +++ b/FModel/Creator/Bases/FN/BaseIconStats.cs @@ -52,7 +52,7 @@ public override void ParseForInfo() foreach (var poi in challengeMapPoiData) { if (!poi.TryGetValue(out FStructFallback locationTag, "LocationTag") || !locationTag.TryGetValue(out FName tagName, "TagName") || - !tagName.Text.Equals(location.Text, StringComparison.OrdinalIgnoreCase) || !poi.TryGetValue(out FText text, "Text")) continue; + tagName != location.TagName || !poi.TryGetValue(out FText text, "Text")) continue; locationName = text.Text; break; @@ -92,7 +92,11 @@ public override void ParseForInfo() _statistics.Add(new IconStat(Utils.GetLocalizedResource("", "35D04D1B45737BEA25B69686D9E085B9", "Damage"), dmgPb * multiplier, 200)); } - if (weaponRowValue.TryGetValue(out float dmgCritical, "DamageZone_Critical")) + if (weaponRowValue.TryGetValue(out float mdpc, "MaxDamagePerCartridge") && mdpc >= 0f) + { + _statistics.Add(new IconStat(Utils.GetLocalizedResource("", "0DEF2455463B008C4499FEA03D149EDF", "Headshot Damage"), mdpc, 200)); + } + else if (weaponRowValue.TryGetValue(out float dmgCritical, "DamageZone_Critical")) { _statistics.Add(new IconStat(Utils.GetLocalizedResource("", "0DEF2455463B008C4499FEA03D149EDF", "Headshot Damage"), dmgPb * dmgCritical * multiplier, 200)); } diff --git a/FModel/Creator/Typefaces.cs b/FModel/Creator/Typefaces.cs index c562d70f..e8336690 100644 --- a/FModel/Creator/Typefaces.cs +++ b/FModel/Creator/Typefaces.cs @@ -21,7 +21,6 @@ public class Typefaces private const string _BURBANK_BIG_REGULAR_BOLD = "BurbankBigRegular-Bold"; // official fortnite ig private const string _BURBANK_SMALL_MEDIUM = "BurbankSmall-Medium"; private const string _DROID_SANS_FORTNITE_SUBSET = "DroidSans-Fortnite-Subset"; - private const string _NIS_JYAU = "NIS_JYAU"; // japanese fortnite private const string _NOTO_COLOR_EMOJI = "NotoColorEmoji"; private const string _NOTO_SANS_BOLD = "NotoSans-Bold"; private const string _NOTO_SANS_FORTNITE_BOLD = "NotoSans-Fortnite-Bold"; @@ -32,7 +31,7 @@ public class Typefaces private const string _NOTO_SANS_ARABIC_BLACK = "NotoSansArabic-Black"; // arabic fortnite private const string _NOTO_SANS_ARABIC_BOLD = "NotoSansArabic-Bold"; private const string _NOTO_SANS_ARABIC_REGULAR = "NotoSansArabic-Regular"; - private const string _NOTO_SANS_JP_BOLD = "NotoSansJP-Bold"; + private const string _NOTO_SANS_JP_BOLD = "NotoSansJP-Bold"; // japanese fortnite private const string _NOTO_SANS_KR_REGULAR = "NotoSansKR-Regular"; private const string _NOTO_SANS_SC_BLACK = "NotoSansSC-Black"; // simplified chinese fortnite private const string _NOTO_SANS_SC_REGULAR = "NotoSansSC-Regular"; @@ -77,7 +76,7 @@ public Typefaces(CUE4ParseViewModel viewModel) { ELanguage.Korean => _ASIA_ERINM, ELanguage.Russian => _BURBANK_BIG_CONDENSED_BLACK, - ELanguage.Japanese => _NIS_JYAU, + ELanguage.Japanese => _NOTO_SANS_JP_BOLD, ELanguage.Arabic => _NOTO_SANS_ARABIC_BLACK, ELanguage.TraditionalChinese => _NOTO_SANS_TC_BLACK, ELanguage.Chinese => _NOTO_SANS_SC_BLACK, @@ -113,7 +112,7 @@ public Typefaces(CUE4ParseViewModel viewModel) { ELanguage.Korean => _ASIA_ERINM, ELanguage.Russian => _BURBANK_BIG_CONDENSED_BLACK, - ELanguage.Japanese => _NIS_JYAU, + ELanguage.Japanese => _NOTO_SANS_JP_BOLD, ELanguage.Arabic => _NOTO_SANS_ARABIC_BLACK, ELanguage.TraditionalChinese => _NOTO_SANS_TC_BLACK, ELanguage.Chinese => _NOTO_SANS_SC_BLACK, @@ -125,7 +124,7 @@ public Typefaces(CUE4ParseViewModel viewModel) { ELanguage.Korean => _ASIA_ERINM, ELanguage.Russian => _BURBANK_BIG_CONDENSED_BLACK, - ELanguage.Japanese => _NIS_JYAU, + ELanguage.Japanese => _NOTO_SANS_JP_BOLD, ELanguage.Arabic => _NOTO_SANS_ARABIC_BLACK, ELanguage.TraditionalChinese => _NOTO_SANS_TC_BLACK, ELanguage.Chinese => _NOTO_SANS_SC_BLACK, @@ -136,7 +135,7 @@ public Typefaces(CUE4ParseViewModel viewModel) language switch { ELanguage.Korean => _ASIA_ERINM, - ELanguage.Japanese => _NIS_JYAU, + ELanguage.Japanese => _NOTO_SANS_JP_BOLD, ELanguage.Arabic => _NOTO_SANS_ARABIC_BLACK, ELanguage.TraditionalChinese => _NOTO_SANS_TC_BLACK, ELanguage.Chinese => _NOTO_SANS_SC_BLACK, @@ -147,7 +146,7 @@ public Typefaces(CUE4ParseViewModel viewModel) language switch { ELanguage.Korean => _ASIA_ERINM, - ELanguage.Japanese => _NIS_JYAU, + ELanguage.Japanese => _NOTO_SANS_JP_BOLD, ELanguage.Arabic => _NOTO_SANS_ARABIC_BLACK, ELanguage.TraditionalChinese => _NOTO_SANS_TC_BLACK, ELanguage.Chinese => _NOTO_SANS_SC_BLACK, diff --git a/FModel/MainWindow.xaml b/FModel/MainWindow.xaml index 047dd61b..b9952ffd 100644 --- a/FModel/MainWindow.xaml +++ b/FModel/MainWindow.xaml @@ -126,25 +126,6 @@ - - - - - - - - - - - - - - - - - - - diff --git a/FModel/ViewModels/Commands/MenuCommand.cs b/FModel/ViewModels/Commands/MenuCommand.cs index 61e79d37..7a510915 100644 --- a/FModel/ViewModels/Commands/MenuCommand.cs +++ b/FModel/ViewModels/Commands/MenuCommand.cs @@ -42,9 +42,6 @@ public override async void Execute(ApplicationViewModel contextViewModel, object case "Views_AudioPlayer": Helper.OpenWindow("Audio Player", () => new AudioPlayer().Show()); break; - case "Views_MapViewer": - Helper.OpenWindow("Map Viewer", () => new MapViewer().Show()); - break; case "Views_ImageMerger": Helper.OpenWindow("Image Merger", () => new ImageMerger().Show()); break; diff --git a/FModel/ViewModels/MapViewerViewModel.cs b/FModel/ViewModels/MapViewerViewModel.cs deleted file mode 100644 index e30d76fa..00000000 --- a/FModel/ViewModels/MapViewerViewModel.cs +++ /dev/null @@ -1,876 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using System.Windows.Media.Imaging; -using CUE4Parse.UE4.Assets.Exports; -using CUE4Parse.UE4.Assets.Exports.Engine; -using CUE4Parse.UE4.Assets.Exports.Material; -using CUE4Parse.UE4.Assets.Exports.Texture; -using CUE4Parse.UE4.Assets.Objects; -using CUE4Parse.UE4.Objects.Core.i18N; -using CUE4Parse.UE4.Objects.Core.Math; -using CUE4Parse.UE4.Objects.GameplayTags; -using CUE4Parse.UE4.Objects.UObject; -using FModel.Creator; -using FModel.Extensions; -using FModel.Framework; -using FModel.Services; -using SkiaSharp; -using SkiaSharp.HarfBuzz; - -namespace FModel.ViewModels; - -public class MapLayer -{ - public SKBitmap Layer; - public bool IsEnabled; -} - -public enum EWaypointType -{ - Parkour, - TimeTrials -} - -public class MapViewerViewModel : ViewModel -{ - private ThreadWorkerViewModel _threadWorkerView => ApplicationService.ThreadWorkerView; - private DiscordHandler _discordHandler => DiscordService.DiscordHandler; - - #region BINDINGS - - private bool _brPois; - public bool BrPois - { - get => _brPois; - set => SetProperty(ref _brPois, value, "ApolloGameplay_MapPois"); - } - - private bool _brLandmarks; - public bool BrLandmarks - { - get => _brLandmarks; - set => SetProperty(ref _brLandmarks, value, "ApolloGameplay_MapLandmarks"); - } - - private bool _brTagsLocation; - public bool BrTagsLocation - { - get => _brTagsLocation; - set => SetProperty(ref _brTagsLocation, value, "ApolloGameplay_TagsLocation"); - } - - private bool _brPatrolsPath; - public bool BrPatrolsPath - { - get => _brPatrolsPath; - set => SetProperty(ref _brPatrolsPath, value, "ApolloGameplay_PatrolsPath"); - } - - private bool _brUpgradeBenches; - public bool BrUpgradeBenches - { - get => _brUpgradeBenches; - set => SetProperty(ref _brUpgradeBenches, value, "ApolloGameplay_UpgradeBenches"); - } - - private bool _brPhonebooths; - public bool BrPhonebooths - { - get => _brPhonebooths; - set => SetProperty(ref _brPhonebooths, value, "ApolloGameplay_Phonebooths"); - } - - private bool _brVendingMachines; - public bool BrVendingMachines - { - get => _brVendingMachines; - set => SetProperty(ref _brVendingMachines, value, "ApolloGameplay_VendingMachines"); - } - - private bool _brBountyBoards; - public bool BrBountyBoards - { - get => _brBountyBoards; - set => SetProperty(ref _brBountyBoards, value, "ApolloGameplay_BountyBoards"); - } - - private bool _prLandmarks; - public bool PrLandmarks - { - get => _prLandmarks; - set => SetProperty(ref _prLandmarks, value, "PapayaGameplay_MapLandmarks"); - } - - private bool _prCannonball; - public bool PrCannonball - { - get => _prCannonball; - set => SetProperty(ref _prCannonball, value, "PapayaGameplay_CannonballGame"); - } - - private bool _prSkydive; - public bool PrSkydive - { - get => _prSkydive; - set => SetProperty(ref _prSkydive, value, "PapayaGameplay_SkydiveGame"); - } - - private bool _prShootingTargets; - public bool PrShootingTargets - { - get => _prShootingTargets; - set => SetProperty(ref _prShootingTargets, value, "PapayaGameplay_ShootingTargets"); - } - - private bool _prParkour; - public bool PrParkour - { - get => _prParkour; - set => SetProperty(ref _prParkour, value, "PapayaGameplay_ParkourGame"); - } - - private bool _prTimeTrials; - public bool PrTimeTrials - { - get => _prTimeTrials; - set => SetProperty(ref _prTimeTrials, value, "PapayaGameplay_TimeTrials"); - } - - private bool _prVendingMachines; - public bool PrVendingMachines - { - get => _prVendingMachines; - set => SetProperty(ref _prVendingMachines, value, "PapayaGameplay_VendingMachines"); - } - - private bool _prMusicBlocks; - public bool PrMusicBlocks - { - get => _prMusicBlocks; - set => SetProperty(ref _prMusicBlocks, value, "PapayaGameplay_MusicBlocks"); - } - - #endregion - - #region BITMAP IMAGES - - private BitmapImage _brMiniMapImage; - private BitmapImage _prMiniMapImage; - private BitmapImage _mapImage; - public BitmapImage MapImage - { - get => _mapImage; - set => SetProperty(ref _mapImage, value); - } - - private BitmapImage _brLayerImage; - private BitmapImage _prLayerImage; - private BitmapImage _layerImage; - public BitmapImage LayerImage - { - get => _layerImage; - set => SetProperty(ref _layerImage, value); - } - - private const int _widthHeight = 2048; - private const int _brRadius = 160000; - private const int _prRadius = 51000; - private int _mapIndex; - public int MapIndex // 0 is BR, 1 is PR - { - get => _mapIndex; - set - { - SetProperty(ref _mapIndex, value); - TriggerChange(); - } - } - - #endregion - - private const string _FIRST_BITMAP = "MapCheck"; - private readonly Dictionary[] _bitmaps; // first bitmap is the displayed map, others are overlays of the map - private readonly CUE4ParseViewModel _cue4Parse; - - public MapViewerViewModel(CUE4ParseViewModel cue4Parse) - { - _bitmaps = new[] - { - new Dictionary(), - new Dictionary() - }; - _cue4Parse = cue4Parse; - } - - public async void Initialize() - { - Utils.Typefaces ??= new Typefaces(_cue4Parse); - _textPaint.Typeface = _fillPaint.Typeface = Utils.Typefaces.Bottom ?? Utils.Typefaces.DisplayName; - await LoadBrMiniMap(); - await LoadPrMiniMap(); - TriggerChange(); - } - - public BitmapImage GetImageToSave() => GetImageSource(GetLayerBitmap(true)); - - private SKBitmap GetLayerBitmap(bool withMap) - { - var ret = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(ret); - - foreach (var (key, value) in _bitmaps[MapIndex]) - { - if (!value.IsEnabled || !withMap && key == _FIRST_BITMAP) - continue; - - c.DrawBitmap(value.Layer, new SKRect(0, 0, _widthHeight, _widthHeight)); - } - - return ret; - } - - protected override bool SetProperty(ref T storage, T value, string propertyName = null) // don't delete, else nothing will update for some reason - { - var ret = base.SetProperty(ref storage, value, propertyName); - if (bool.TryParse(value.ToString(), out var b)) GenericToggle(propertyName, b); - return ret; - } - - private async void GenericToggle(string key, bool enabled) - { - if (_bitmaps[MapIndex].TryGetValue(key, out var layer) && layer.Layer != null) - { - layer.IsEnabled = enabled; - } - else if (enabled) // load layer - { - switch (key) - { - case "ApolloGameplay_MapPois": - case "ApolloGameplay_MapLandmarks": - case "PapayaGameplay_MapLandmarks": - await LoadQuestIndicatorData(); - break; - case "ApolloGameplay_TagsLocation": - await LoadTagsLocation(); - break; - case "ApolloGameplay_PatrolsPath": - await LoadPatrolsPath(); - break; - case "ApolloGameplay_UpgradeBenches": - await LoadUpgradeBenches(); - break; - case "ApolloGameplay_Phonebooths": - await LoadPhonebooths(); - break; - case "ApolloGameplay_VendingMachines": - await LoadBrVendingMachines(); - break; - case "ApolloGameplay_BountyBoards": - await LoadBountyBoards(); - break; - case "PapayaGameplay_CannonballGame": - await LoadCannonballGame(); - break; - case "PapayaGameplay_SkydiveGame": - await LoadSkydiveGame(); - break; - case "PapayaGameplay_ShootingTargets": - await LoadShootingTargets(); - break; - case "PapayaGameplay_ParkourGame": - await LoadWaypoint(EWaypointType.Parkour); - break; - case "PapayaGameplay_TimeTrials": - await LoadWaypoint(EWaypointType.TimeTrials); - break; - case "PapayaGameplay_VendingMachines": - await LoadPrVendingMachines(); - break; - case "PapayaGameplay_MusicBlocks": - await LoadMusicBlocks(); - break; - } - - _bitmaps[MapIndex][key].IsEnabled = true; - } - - switch (MapIndex) - { - case 0: - _brLayerImage = GetImageSource(GetLayerBitmap(false)); - break; - case 1: - _prLayerImage = GetImageSource(GetLayerBitmap(false)); - break; - } - - TriggerChange(); - } - - private BitmapImage GetImageSource(SKBitmap bitmap) - { - if (bitmap == null) return null; - using var data = bitmap.Encode(SKEncodedImageFormat.Png, 100); - using var stream = data.AsStream(); - var image = new BitmapImage(); - image.BeginInit(); - image.CacheOption = BitmapCacheOption.OnLoad; - image.StreamSource = stream; - image.EndInit(); - image.Freeze(); - return image; - } - - private void TriggerChange() - { - var layerCount = _bitmaps[_mapIndex].Count(x => x.Value.IsEnabled); - var layerString = $"{layerCount} Layer{(layerCount > 1 ? "s" : "")}"; - switch (_mapIndex) - { - case 0: - _discordHandler.UpdateButDontSavePresence(null, $"Map Viewer: Battle Royale ({layerString})"); - _mapImage = _brMiniMapImage; - _layerImage = _brLayerImage; - break; - case 1: - _discordHandler.UpdateButDontSavePresence(null, $"Map Viewer: Party Royale ({layerString})"); - _mapImage = _prMiniMapImage; - _layerImage = _prLayerImage; - break; - } - - RaisePropertyChanged(nameof(MapImage)); - RaisePropertyChanged(nameof(LayerImage)); - } - - private readonly SKPaint _textPaint = new() - { - IsAntialias = true, FilterQuality = SKFilterQuality.High, - Color = SKColors.White, TextAlign = SKTextAlign.Center, TextSize = 26 - }; - - private readonly SKPaint _fillPaint = new() - { - IsAntialias = true, FilterQuality = SKFilterQuality.High, - IsStroke = true, Color = SKColors.Black, TextSize = 26, - TextAlign = SKTextAlign.Center - }; - - private readonly SKPaint _pathPaint = new() - { - IsAntialias = true, FilterQuality = SKFilterQuality.High, IsStroke = true, - Style = SKPaintStyle.Stroke, StrokeWidth = 5, Color = SKColors.Red, - ImageFilter = SKImageFilter.CreateDropShadow(4, 4, 8, 8, SKColors.Black) - }; - - private FVector2D GetMapPosition(FVector vector, int mapRadius) - { - const int wh = 2048 + 128 + 32; - var nx = (vector.Y + mapRadius) / (mapRadius * 2) * wh; - var ny = (1 - (vector.X + mapRadius) / (mapRadius * 2)) * wh; - return new FVector2D(nx, ny); - } - - private async Task LoadBrMiniMap() - { - if (_bitmaps[0].TryGetValue(_FIRST_BITMAP, out var brMap) && brMap.Layer != null) - return; // if map already loaded - - await _threadWorkerView.Begin(_ => - { - if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerBR.Default__UIMapManagerBR_C", out UObject mapManager) || - !mapManager.TryGetValue(out UMaterial mapMaterial, "MapMaterial")) return; - var midTex = mapMaterial.GetFirstTexture(); - if ((midTex?.Name ?? string.Empty).Contains("Mask")) - midTex = mapMaterial.GetTextureAtIndex(1); - - if (midTex is not UTexture2D tex) return; - _bitmaps[0][_FIRST_BITMAP] = new MapLayer { Layer = Utils.GetBitmap(tex), IsEnabled = true }; - _brMiniMapImage = GetImageSource(_bitmaps[0][_FIRST_BITMAP].Layer); - }); - } - - private async Task LoadPrMiniMap() - { - if (_bitmaps[1].TryGetValue(_FIRST_BITMAP, out var prMap) && prMap.Layer != null) - return; // if map already loaded - - await _threadWorkerView.Begin(_ => - { - if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerPapaya.Default__UIMapManagerPapaya_C", out UObject mapManager) || - !mapManager.TryGetValue(out UMaterial mapMaterial, "MapMaterial") || mapMaterial.GetFirstTexture() is not UTexture2D tex) return; - - _bitmaps[1][_FIRST_BITMAP] = new MapLayer { Layer = Utils.GetBitmap(tex), IsEnabled = true }; - _prMiniMapImage = GetImageSource(_bitmaps[1][_FIRST_BITMAP].Layer); - }); - } - - private async Task LoadQuestIndicatorData() - { - await _threadWorkerView.Begin(_ => - { - var poisBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - var brLandmarksBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - var prLandmarksBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var pois = new SKCanvas(poisBitmap); - using var brLandmarks = new SKCanvas(brLandmarksBitmap); - using var prLandmarks = new SKCanvas(prLandmarksBitmap); - - if (Utils.TryLoadObject("FortniteGame/Content/Quests/QuestIndicatorData", out UObject indicatorData) && - indicatorData.TryGetValue(out FStructFallback[] challengeMapPoiData, "ChallengeMapPoiData")) - { - foreach (var poiData in challengeMapPoiData) - { - if (!poiData.TryGetValue(out FSoftObjectPath discoveryQuest, "DiscoveryQuest") || - !poiData.TryGetValue(out FText text, "Text") || string.IsNullOrEmpty(text.Text) || - !poiData.TryGetValue(out FVector worldLocation, "WorldLocation") || - !poiData.TryGetValue(out FName discoverBackend, "DiscoverObjectiveBackendName")) continue; - - var shaper = new CustomSKShaper(_textPaint.Typeface); - if (discoverBackend.Text.Contains("papaya", StringComparison.OrdinalIgnoreCase)) - { - _fillPaint.StrokeWidth = 5; - var vector = GetMapPosition(worldLocation, _prRadius); - prLandmarks.DrawPoint(vector.X, vector.Y, _pathPaint); - prLandmarks.DrawShapedText(shaper, text.Text, vector.X, vector.Y - 12.5F, _fillPaint); - prLandmarks.DrawShapedText(shaper, text.Text, vector.X, vector.Y - 12.5F, _textPaint); - } - else if (discoveryQuest.AssetPathName.Text.Contains("landmarks", StringComparison.OrdinalIgnoreCase)) - { - _fillPaint.StrokeWidth = 5; - var vector = GetMapPosition(worldLocation, _brRadius); - brLandmarks.DrawPoint(vector.X, vector.Y, _pathPaint); - brLandmarks.DrawShapedText(shaper, text.Text, vector.X, vector.Y - 12.5F, _fillPaint); - brLandmarks.DrawShapedText(shaper, text.Text, vector.X, vector.Y - 12.5F, _textPaint); - } - else - { - _fillPaint.StrokeWidth = 10; - var vector = GetMapPosition(worldLocation, _brRadius); - pois.DrawShapedText(shaper, text.Text.ToUpperInvariant(), vector.X, vector.Y, _fillPaint); - pois.DrawShapedText(shaper, text.Text.ToUpperInvariant(), vector.X, vector.Y, _textPaint); - } - } - } - - _bitmaps[0]["ApolloGameplay_MapPois"] = new MapLayer { Layer = poisBitmap, IsEnabled = false }; - _bitmaps[0]["ApolloGameplay_MapLandmarks"] = new MapLayer { Layer = brLandmarksBitmap, IsEnabled = false }; - _bitmaps[1]["PapayaGameplay_MapLandmarks"] = new MapLayer { Layer = prLandmarksBitmap, IsEnabled = false }; - }); - } - - private async Task LoadPatrolsPath() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var patrolsPathBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(patrolsPathBitmap); - - var exports = Utils.LoadExports("/NPCLibrary/LevelOverlays/Artemis_Overlay_S22_NPCLibrary"); - foreach (var export in exports) - { - if (!export.ExportType.Equals("FortAthenaPatrolPath", StringComparison.OrdinalIgnoreCase) || - !export.TryGetValue(out FPackageIndex[] patrolPoints, "PatrolPoints")) continue; - - var displayName = export.Name["FortAthenaPatrolPath_".Length..]; - if (export.TryGetValue(out FGameplayTagContainer gameplayTags, "GameplayTags") && gameplayTags.GameplayTags.Length > 0) - displayName = gameplayTags.GameplayTags[0].Text["Athena.AI.SpawnLocation.Tandem.".Length..]; - - if (!Utils.TryGetPackageIndexExport(patrolPoints[0], out UObject uObject) || - !uObject.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out uObject) || - !uObject.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var path = new SKPath(); - var vector = GetMapPosition(relativeLocation, _brRadius); - path.MoveTo(vector.X, vector.Y); - - for (var i = 1; i < patrolPoints.Length; i++) - { - if (!Utils.TryGetPackageIndexExport(patrolPoints[i], out uObject) || - !uObject.TryGetValue(out rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out uObject) || - !uObject.TryGetValue(out relativeLocation, "RelativeLocation")) continue; - - vector = GetMapPosition(relativeLocation, _brRadius); - path.LineTo(vector.X, vector.Y); - } - - c.DrawPath(path, _pathPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[0]["ApolloGameplay_PatrolsPath"] = new MapLayer { Layer = patrolsPathBitmap, IsEnabled = false }; - }); - } - - private async Task LoadCannonballGame() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var cannonballBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(cannonballBitmap); - - var exports = Utils.LoadExports("/PapayaGameplay/LevelOverlays/PapayaGameplay_CannonballGame"); - foreach (var export in exports) - { - if (!export.ExportType.Equals("BP_CannonballGame_Target_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("CannonballGame_VehicleSpawner_C", StringComparison.OrdinalIgnoreCase)) continue; - - if (!export.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out UObject uObject) || - !uObject.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var displayName = Utils.GetLocalizedResource("", "D998BEF44F051E0885C6C58565934BEA", "Cannonball"); - var vector = GetMapPosition(relativeLocation, _prRadius); - - c.DrawPoint(vector.X, vector.Y, _pathPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[1]["PapayaGameplay_CannonballGame"] = new MapLayer { Layer = cannonballBitmap, IsEnabled = false }; - }); - } - - private async Task LoadSkydiveGame() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var skydiveBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(skydiveBitmap); - - var exports = Utils.LoadExports("/PapayaGameplay/LevelOverlays/PapayaGameplay_SkydiveGame"); - foreach (var export in exports) - { - if (!export.ExportType.Equals("BP_Waypoint_Papaya_Skydive_Start_C", StringComparison.OrdinalIgnoreCase)) continue; - - if (!export.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !export.TryGetValue(out FText minigameActivityName, "MinigameActivityName") || - !Utils.TryGetPackageIndexExport(rootComponent, out UObject uObject) || - !uObject.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var vector = GetMapPosition(relativeLocation, _prRadius); - - c.DrawPoint(vector.X, vector.Y, _pathPaint); - c.DrawText(minigameActivityName.Text, vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText(minigameActivityName.Text, vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[1]["PapayaGameplay_SkydiveGame"] = new MapLayer { Layer = skydiveBitmap, IsEnabled = false }; - }); - } - - private async Task LoadShootingTargets() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var shootingTargetsBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(shootingTargetsBitmap); - - var bDone = false; - var exports = Utils.LoadExports("/PapayaGameplay/LevelOverlays/PapayaGameplay_ShootingTargets"); - foreach (var export in exports) - { - if (!export.ExportType.Equals("PapayaShootingTarget_C", StringComparison.OrdinalIgnoreCase)) continue; - - if (!export.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out UObject uObject) || - !uObject.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var vector = GetMapPosition(relativeLocation, _prRadius); - c.DrawPoint(vector.X, vector.Y, _pathPaint); - if (bDone) continue; - - bDone = true; - c.DrawText("Shooting Target", vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText("Shooting Target", vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[1]["PapayaGameplay_ShootingTargets"] = new MapLayer { Layer = shootingTargetsBitmap, IsEnabled = false }; - }); - } - - private async Task LoadWaypoint(EWaypointType type) - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var waypointBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(waypointBitmap); - - string file; - string name; - switch (type) - { - case EWaypointType.Parkour: - file = "PapayaGameplay_ParkourGame"; - name = "Parkour"; - break; - case EWaypointType.TimeTrials: - file = "PapayaGameplay_TimeTrials"; - name = "Time Trials"; - break; - default: - throw new ArgumentOutOfRangeException(nameof(type), type, null); - } - - var path = new SKPath(); - var exports = Utils.LoadExports($"/PapayaGameplay/LevelOverlays/{file}"); - foreach (var export in exports) - { - if (!export.ExportType.Equals("BP_Waypoint_Parent_Papaya_C", StringComparison.OrdinalIgnoreCase)) continue; - - if (!export.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out UObject root) || - !root.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var vector = GetMapPosition(relativeLocation, _prRadius); - if (path.IsEmpty || export.TryGetValue(out bool startsTrial, "StartsTrial") && startsTrial) - { - path.MoveTo(vector.X, vector.Y); - c.DrawText(name, vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText(name, vector.X, vector.Y - 12.5F, _textPaint); - } - else if (export.TryGetValue(out bool endsTrial, "EndsTrial") && endsTrial) - { - path.LineTo(vector.X, vector.Y); - c.DrawPath(path, _pathPaint); - path = new SKPath(); - } - else path.LineTo(vector.X, vector.Y); - } - - _bitmaps[1][file] = new MapLayer { Layer = waypointBitmap, IsEnabled = false }; - }); - } - - private async Task LoadPrVendingMachines() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var set = new HashSet(); - var timeTrialsBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(timeTrialsBitmap); - - var exports = Utils.LoadExports("/PapayaGameplay/LevelOverlays/PapayaGameplay_VendingMachines"); - foreach (var export in exports) - { - if (!export.ExportType.Equals("B_Papaya_VendingMachine_Boat_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_BoogieBomb_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_Burger_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_CrashPad_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_FishingPole_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_Grappler_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_Jetpack_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_PaintGrenade_Blue_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_PaintGrenade_Red_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_PaintLauncher_Blue_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_PaintLauncher_Red_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_PlungerBow_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_Quad_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Papaya_VendingMachine_Tomato_C", StringComparison.OrdinalIgnoreCase)) continue; - - if (!export.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out UObject root) || - !root.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var name = export.ExportType.SubstringAfter("B_Papaya_VendingMachine_").SubstringBeforeLast("_C"); - var vector = GetMapPosition(relativeLocation, _prRadius); - c.DrawPoint(vector.X, vector.Y, _pathPaint); - if (!set.Add(name)) continue; - - c.DrawText(name, vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText(name, vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[1]["PapayaGameplay_VendingMachines"] = new MapLayer { Layer = timeTrialsBitmap, IsEnabled = false }; - }); - } - - private async Task LoadMusicBlocks() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var shootingTargetsBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(shootingTargetsBitmap); - - var bDone = false; - var exports = Utils.LoadExports("/PapayaGameplay/LevelOverlays/PapayaGameplay_MusicBlocks"); - foreach (var export in exports) - { - if (!export.ExportType.Equals("MusicBlock_Piano3_Papaya_C", StringComparison.OrdinalIgnoreCase)) continue; - - if (!export.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out UObject uObject) || - !uObject.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var vector = GetMapPosition(relativeLocation, _prRadius); - c.DrawPoint(vector.X, vector.Y, _pathPaint); - if (bDone) continue; - - bDone = true; - c.DrawText("Music Blocks", vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText("Music Blocks", vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[1]["PapayaGameplay_MusicBlocks"] = new MapLayer { Layer = shootingTargetsBitmap, IsEnabled = false }; - }); - } - - private async Task LoadUpgradeBenches() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var upgradeBenchesBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(upgradeBenchesBitmap); - - var exports = Utils.LoadExports("/NPCLibrary/LevelOverlays/Artemis_Overlay_S19_UpgradeBenches"); - foreach (var export in exports) - { - if (!export.ExportType.Equals("B_Athena_Spawner_UpgradeStation_C", StringComparison.OrdinalIgnoreCase)) continue; - var displayName = export.Name["B_Athena_Spawner_".Length..]; - - if (!export.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out UObject uObject) || - !uObject.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var vector = GetMapPosition(relativeLocation, _brRadius); - c.DrawPoint(vector.X, vector.Y, _pathPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[0]["ApolloGameplay_UpgradeBenches"] = new MapLayer { Layer = upgradeBenchesBitmap, IsEnabled = false }; - }); - } - - private async Task LoadPhonebooths() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var phoneboothsBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(phoneboothsBitmap); - - var exports = Utils.LoadExports("/NPCLibrary/LevelOverlays/Apollo_Terrain_NPCLibrary_Stations_Phonebooths"); - foreach (var export in exports) - { - if (!export.ExportType.Equals("B_Athena_Spawner_Payphone_C", StringComparison.OrdinalIgnoreCase)) continue; - var displayName = export.Name["B_Athena_Spawner_".Length..]; - - if (!export.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out UObject uObject) || - !uObject.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var vector = GetMapPosition(relativeLocation, _brRadius); - c.DrawPoint(vector.X, vector.Y, _pathPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[0]["ApolloGameplay_Phonebooths"] = new MapLayer { Layer = phoneboothsBitmap, IsEnabled = false }; - }); - } - - private async Task LoadBrVendingMachines() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var vendingMachinesBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(vendingMachinesBitmap); - - var exports = Utils.LoadExports("/NPCLibrary/LevelOverlays/Artemis_Overlay_S19_ServiceStations"); - foreach (var export in exports) - { - if (!export.ExportType.Equals("B_Athena_Spawner_VendingMachine_MendingOnly_C", StringComparison.OrdinalIgnoreCase) && - !export.ExportType.Equals("B_Athena_Spawner_VendingMachine_Random_C", StringComparison.OrdinalIgnoreCase)) continue; - var displayName = $"{(export.ExportType.Contains("Mending") ? "MM" : "WOM")}_{export.Name["B_Athena_Spawner_VendingMachine_Random".Length..]}"; - - if (!export.TryGetValue(out FPackageIndex rootComponent, "RootComponent") || - !Utils.TryGetPackageIndexExport(rootComponent, out UObject uObject) || - !uObject.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var vector = GetMapPosition(relativeLocation, _brRadius); - c.DrawPoint(vector.X, vector.Y, _pathPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[0]["ApolloGameplay_VendingMachines"] = new MapLayer { Layer = vendingMachinesBitmap, IsEnabled = false }; - }); - } - - private async Task LoadBountyBoards() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - var bountyBoardsBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(bountyBoardsBitmap); - - var exports = Utils.LoadExports("/Bounties/Maps/BB_Overlay_ServiceStations"); - foreach (var export in exports) - { - 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) || - !uObject.TryGetValue(out FVector relativeLocation, "RelativeLocation")) continue; - - var vector = GetMapPosition(relativeLocation, _brRadius); - c.DrawPoint(vector.X, vector.Y, _pathPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[0]["ApolloGameplay_BountyBoards"] = new MapLayer { Layer = bountyBoardsBitmap, IsEnabled = false }; - }); - } - - private async Task LoadTagsLocation() - { - await _threadWorkerView.Begin(_ => - { - _fillPaint.StrokeWidth = 5; - if (!Utils.TryLoadObject("FortniteGame/Content/Quests/QuestTagToLocationDataRows.QuestTagToLocationDataRows", out UDataTable locationData)) - return; - - var tagsLocationBitmap = new SKBitmap(_widthHeight, _widthHeight, SKColorType.Rgba8888, SKAlphaType.Premul); - using var c = new SKCanvas(tagsLocationBitmap); - - foreach (var (key, uObject) in locationData.RowMap) - { - if (key.Text.StartsWith("Athena.Location.POI", StringComparison.OrdinalIgnoreCase) || - key.Text.StartsWith("Athena.Location.Unnamed", StringComparison.OrdinalIgnoreCase) || - key.Text.Contains(".Tandem.", StringComparison.OrdinalIgnoreCase) || - !uObject.TryGetValue(out FVector worldLocation, "WorldLocation")) continue; - - var parts = key.Text.Split('.'); - var displayName = parts[^2]; - if (!int.TryParse(parts[^1], out var _)) - displayName += " " + parts[^1]; - - var vector = GetMapPosition(worldLocation, _brRadius); - c.DrawPoint(vector.X, vector.Y, _pathPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _fillPaint); - c.DrawText(displayName, vector.X, vector.Y - 12.5F, _textPaint); - } - - _bitmaps[0]["ApolloGameplay_TagsLocation"] = new MapLayer { Layer = tagsLocationBitmap, IsEnabled = false }; - }); - } -} diff --git a/FModel/Views/MapViewer.xaml b/FModel/Views/MapViewer.xaml deleted file mode 100644 index e4d4b0a3..00000000 --- a/FModel/Views/MapViewer.xaml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -