saving this

This commit is contained in:
iAmAsval 2021-06-05 00:50:55 +02:00
parent af72bd00fa
commit a80052ef77
10 changed files with 85 additions and 56 deletions

@ -1 +1 @@
Subproject commit 038f373650a2e7b05506d10060fe79e136b23eb8
Subproject commit f17ea8bbf946a8319758759118c1e46b863eab33

View File

@ -1,5 +1,4 @@
using System.Linq;
using CUE4Parse.UE4.Assets.Exports;
using CUE4Parse.UE4.Assets.Exports;
using CUE4Parse.UE4.Objects.GameplayTags;
using CUE4Parse.UE4.Objects.UObject;
using CUE4Parse.UE4.Versions;
@ -21,7 +20,6 @@ namespace FModel.Creator.Bases.FN
private string _source;
private string _season;
private bool _lowerDrawn;
private bool _hasStyle;
public BaseCommunity(UObject uObject, EIconStyle style, string designName) : base(uObject, style)
{
@ -89,8 +87,9 @@ namespace FModel.Creator.Bases.FN
Description += GetCosmeticSet(set.Text, _design.DrawSetShort);
if (_design.DrawSeason && gameplayTags.TryGetGameplayTag("Cosmetics.Filter.Season.", out var season))
_season = GetCosmeticSeason(season.Text, _design.DrawSeasonShort);
if (gameplayTags.Any(x => x.Text.StartsWith("Cosmetics.UserFacingFlags.")))
_hasStyle = true;
var triggers = _design.GameplayTags.DrawCustomOnly ? new[] {"Cosmetics.UserFacingFlags."} : new[] {"Cosmetics.UserFacingFlags.", "Homebase.Class.", "NPC.CharacterType.Survivor.Defender."};
GetUserFacingFlags(gameplayTags.GetAllGameplayTags(triggers));
}
private string GetCosmeticSet(string setName, bool bShort)
@ -291,7 +290,7 @@ namespace FModel.Creator.Bases.FN
private void DrawUserFacingFlags(SKCanvas c, bool customOnly)
{
if (!_hasStyle) return;
if (UserFacingFlags == null || UserFacingFlags.Count < 1) return;
if (customOnly)
{
c.DrawBitmap(_design.GameplayTags.Custom, 0, 0, ImagePaint);

View File

@ -23,7 +23,7 @@ namespace FModel.Creator.Bases.FN
public SKBitmap SeriesBackground { get; protected set; }
protected string ShortDescription { get; set; }
protected string CosmeticSource { get; set; }
protected SKBitmap[] UserFacingFlags { get; set; }
protected Dictionary<string, SKBitmap> UserFacingFlags { get; set; }
public BaseIcon(UObject uObject, EIconStyle style) : base(uObject, style)
{
@ -269,24 +269,24 @@ namespace FModel.Creator.Bases.FN
if (!itemCategories.TryGetValue(out FStructFallback[] tertiaryCategories, "TertiaryCategories"))
return;
UserFacingFlags = new SKBitmap[userFacingFlags.Count];
for (var i = 0; i < UserFacingFlags.Length; i++)
UserFacingFlags = new Dictionary<string, SKBitmap>(userFacingFlags.Count);
foreach (var flag in userFacingFlags)
{
if (userFacingFlags[i].Equals("Cosmetics.UserFacingFlags.HasUpgradeQuests", StringComparison.OrdinalIgnoreCase))
if (flag.Equals("Cosmetics.UserFacingFlags.HasUpgradeQuests", StringComparison.OrdinalIgnoreCase))
{
if (Object.ExportType.Equals("AthenaPetCarrierItemDefinition", StringComparison.OrdinalIgnoreCase))
UserFacingFlags[i] = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T-Icon-Pets-64.png"))?.Stream);
else UserFacingFlags[i] = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T-Icon-Quests-64.png"))?.Stream);
UserFacingFlags[flag] = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T-Icon-Pets-64.png"))?.Stream);
else UserFacingFlags[flag] = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T-Icon-Quests-64.png"))?.Stream);
}
else
{
foreach (var category in tertiaryCategories)
{
if (category.TryGetValue(out FGameplayTagContainer tagContainer, "TagContainer") && tagContainer.TryGetGameplayTag(userFacingFlags[i], out _) &&
if (category.TryGetValue(out FGameplayTagContainer tagContainer, "TagContainer") && tagContainer.TryGetGameplayTag(flag, out _) &&
category.TryGetValue(out FStructFallback categoryBrush, "CategoryBrush") && categoryBrush.TryGetValue(out FStructFallback brushXxs, "Brush_XXS") &&
brushXxs.TryGetValue(out FPackageIndex resourceObject, "ResourceObject") && Utils.TryGetPackageIndexExport(resourceObject, out UTexture2D texture))
{
UserFacingFlags[i] = Utils.GetBitmap(texture);
UserFacingFlags[flag] = Utils.GetBitmap(texture);
}
}
}
@ -299,7 +299,7 @@ namespace FModel.Creator.Bases.FN
const int size = 25;
var x = Margin * (int) 2.5;
foreach (var flag in UserFacingFlags)
foreach (var flag in UserFacingFlags.Values)
{
if (flag == null) continue;

View File

@ -78,8 +78,6 @@
<None Remove="Resources\T_ReloadTime_Weapon_Stats.png" />
<None Remove="Resources\T-Icon-Pets-64.png" />
<None Remove="Resources\T-Icon-Quests-64.png" />
<None Remove="Resources\city_pin.png" />
<None Remove="Resources\pin.png" />
<None Remove="Resources\Default.png" />
<None Remove="Resources\NoBackground.png" />
<None Remove="Resources\NoText.png" />
@ -170,8 +168,6 @@
<Resource Include="Resources\T_ReloadTime_Weapon_Stats.png" />
<Resource Include="Resources\T-Icon-Pets-64.png" />
<Resource Include="Resources\T-Icon-Quests-64.png" />
<Resource Include="Resources\city_pin.png" />
<Resource Include="Resources\pin.png" />
<Resource Include="Resources\Default.png" />
<Resource Include="Resources\NoBackground.png" />
<Resource Include="Resources\NoText.png" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using CUE4Parse.UE4.Assets.Exports;
@ -13,8 +14,15 @@ using SkiaSharp;
namespace FModel.ViewModels
{
public class MapLayer
{
public SKBitmap Layer;
public bool IsEnabled;
}
public class MapViewerViewModel : ViewModel
{
private const string _FIRST_BITMAP = "mapBase";
private ThreadWorkerViewModel _threadWorkerView => ApplicationService.ThreadWorkerView;
private int _mapIndex = -1;
@ -48,13 +56,23 @@ namespace FModel.ViewModels
get => _mapImage;
set => SetProperty(ref _mapImage, value);
}
private BitmapImage _layerImage;
public BitmapImage LayerImage
{
get => _layerImage;
set => SetProperty(ref _layerImage, value);
}
private readonly List<SKBitmap>[] _bitmaps; // first bitmap is the displayed map, others are overlays of the map
private readonly Dictionary<string, MapLayer>[] _bitmaps; // first bitmap is the displayed map, others are overlays of the map
private readonly CUE4ParseViewModel _cue4Parse;
public MapViewerViewModel(CUE4ParseViewModel cue4Parse)
{
_bitmaps = new[] {new List<SKBitmap>(), new List<SKBitmap>()};
_bitmaps = new[]
{
new Dictionary<string, MapLayer>(),
new Dictionary<string, MapLayer>()
};
_cue4Parse = cue4Parse;
}
@ -69,27 +87,35 @@ namespace FModel.ViewModels
public BitmapImage GetImageToSave()
{
var ret = new SKBitmap(_bitmaps[MapIndex][0].Width, _bitmaps[MapIndex][0].Height, SKColorType.Rgba8888, SKAlphaType.Premul);
var ret = new SKBitmap(_bitmaps[MapIndex][_FIRST_BITMAP].Layer.Width, _bitmaps[MapIndex][_FIRST_BITMAP].Layer.Height, SKColorType.Rgba8888, SKAlphaType.Premul);
using var c = new SKCanvas(ret);
c.DrawBitmap(_bitmaps[MapIndex][0], 0, 0);
foreach (var layer in _bitmaps[MapIndex].Values.Where(layer => layer.IsEnabled))
{
c.DrawBitmap(layer.Layer, 0, 0);
}
return GetImageSource(ret);
}
protected override bool SetProperty<T>(ref T storage, T value, string propertyName = null)
public async Task GenericToggle(string key, bool enabled)
{
var ret = base.SetProperty(ref storage, value, propertyName);
CheckForStuffToDraw(propertyName);
return ret;
if (_bitmaps[MapIndex].TryGetValue(key, out var layer) && layer.Layer != null)
{
layer.IsEnabled = enabled;
}
else // load layer
{
switch (key)
{
}
}
}
private async void CheckForStuffToDraw(string propertyName = null)
protected override bool SetProperty<T>(ref T storage, T value, string propertyName = null) // don't delete, else nothing will update for some reason
{
switch (propertyName)
{
}
return base.SetProperty(ref storage, value, propertyName);
}
private BitmapImage GetImageSource(SKBitmap bitmap)
@ -120,14 +146,14 @@ namespace FModel.ViewModels
private FVector2D GetMapPosition(FVector vector)
{
var nx = (vector.Y + _mapRadius) / (_mapRadius * 2) * _bitmaps[MapIndex][0].Width;
var ny = (1 - (vector.X + _mapRadius) / (_mapRadius * 2)) * _bitmaps[MapIndex][0].Height;
var nx = (vector.Y + _mapRadius) / (_mapRadius * 2) * _bitmaps[MapIndex][_FIRST_BITMAP].Layer.Width;
var ny = (1 - (vector.X + _mapRadius) / (_mapRadius * 2)) * _bitmaps[MapIndex][_FIRST_BITMAP].Layer.Height;
return new FVector2D(nx, ny);
}
private async Task LoadBrMiniMap()
{
if (_bitmaps[0].Count > 0) return;
if (_bitmaps[0].TryGetValue(_FIRST_BITMAP, out var layer) && layer.Layer != null) return;
await _threadWorkerView.Begin(_ =>
{
if (!Utils.TryLoadObject("FortniteGame/Content/UI/IngameMap/UIMapManagerBR.Default__UIMapManagerBR_C", out UObject mapManager) ||
@ -136,22 +162,22 @@ namespace FModel.ViewModels
!cachedExpressionData.TryGetValue(out FStructFallback parameters, "Parameters") ||
!parameters.TryGetValue(out UTexture2D[] textureValues, "TextureValues")) return;
_bitmaps[0].Add(Utils.GetBitmap(textureValues[0]));
_brMiniMapImage = GetImageSource(_bitmaps[0][0]);
_bitmaps[0][_FIRST_BITMAP] = new MapLayer{Layer = Utils.GetBitmap(textureValues[0]), IsEnabled = true};
_brMiniMapImage = GetImageSource(_bitmaps[0][_FIRST_BITMAP].Layer);
});
}
private async Task LoadPrMiniMap()
{
if (_bitmaps[1].Count > 0) return;
if (_bitmaps[1].TryGetValue(_FIRST_BITMAP, out var layer) && layer.Layer != null) return;
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;
_bitmaps[1].Add(Utils.GetBitmap(mapMaterial.ReferencedTextures[0] as UTexture2D));
_prMiniMapImage = GetImageSource(_bitmaps[1][0]);
_bitmaps[1][_FIRST_BITMAP] = new MapLayer{Layer = Utils.GetBitmap(mapMaterial.ReferencedTextures[0] as UTexture2D), IsEnabled = true};
_prMiniMapImage = GetImageSource(_bitmaps[1][_FIRST_BITMAP].Layer);
});
}
}

View File

@ -22,23 +22,23 @@
<controls:OnTagDataTemplateSelector x:Key="TagTemplateSelector" />
<DataTemplate x:Key="BrTemplate">
<StackPanel VerticalAlignment="Center" Margin="50">
<CheckBox Content="Show Cities" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="Show Landmarks" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="Show NPCs Path" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="ApolloGameplay_MapPoi" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="ApolloGameplay_MapLandmark" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="ApolloGameplay_PatrolPath" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="PrTemplate">
<StackPanel VerticalAlignment="Center" Margin="25 0">
<CheckBox Content="PapayaGameplay_CannonballGame" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="PapayaGameplay_SkydiveGame" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="PapayaGameplay_ShootingTargets" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="PapayaGameplay_ParkourGame" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="PapayaGameplay_TimeTrials" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="PapayaGameplay_VendingMachines" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="PapayaGameplay_MusicBlocks" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="PapayaEffects_Concert" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="PapayaAudio_StageVolumes" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="PapayaEffects_Directionals" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
<CheckBox Content="PapayaGameplay_CannonballGame" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="PapayaGameplay_SkydiveGame" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="PapayaGameplay_ShootingTargets" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="PapayaGameplay_ParkourGame" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="PapayaGameplay_TimeTrials" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="PapayaGameplay_VendingMachines" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="PapayaGameplay_MusicBlocks" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="PapayaEffects_Concert" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="PapayaAudio_StageVolumes" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
<CheckBox Content="PapayaEffects_Directionals" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" Checked="ToggleOnChange" Unchecked="ToggleOnChange" />
</StackPanel>
</DataTemplate>
</ResourceDictionary>
@ -99,6 +99,8 @@
<TextBlock Text="Minimap is loading, please wait..." HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Image UseLayoutRounding="True" Source="{Binding MapViewer.MapImage}" HorizontalAlignment="Right" VerticalAlignment="Center"
Visibility="{Binding IsReady, Converter={StaticResource BoolToVisibilityConverter}}" />
<Image UseLayoutRounding="True" Source="{Binding MapViewer.LayerImage}" HorizontalAlignment="Right" VerticalAlignment="Center"
Visibility="{Binding IsReady, Converter={StaticResource BoolToVisibilityConverter}}" />
</Grid>
</Grid>
</adonisControls:AdonisWindow>

View File

@ -74,5 +74,11 @@ namespace FModel.Views
break;
}
}
private async void ToggleOnChange(object sender, RoutedEventArgs e)
{
if (sender is not CheckBox checkBox) return;
await _applicationView.MapViewer.GenericToggle(checkBox.Content.ToString(), checkBox.IsChecked ?? true);
}
}
}

View File

@ -45,11 +45,11 @@
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Output Directory *" VerticalAlignment="Center" Margin="0 0 0 5" />
<TextBox Grid.Row="0" Grid.Column="2" Text="{Binding OutputDirectory, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" Margin="0 0 0 5" />
<TextBox Grid.Row="0" Grid.Column="2" Text="{Binding OutputDirectory, 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="OnBrowseOutput" Margin="0 0 0 5" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="Game Directory *" VerticalAlignment="Center" Margin="0 0 0 5" />
<TextBox Grid.Row="1" Grid.Column="2" Text="{Binding GameDirectory, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" Margin="0 0 0 5" />
<TextBox Grid.Row="1" Grid.Column="2" Text="{Binding GameDirectory, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0 0 0 5" />
<Button Grid.Row="1" Grid.Column="4" Content="..." HorizontalAlignment="Right" Click="OnBrowseDirectories" Margin="0 0 0 5" />
<TextBlock Grid.Row="2" Grid.Column="0" Text="Update Mode" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Receive updates each time a new release is pushed to GitHub&#10;Receive updates each time a new commit is pushed to GitHub" />