diff --git a/CUE4Parse b/CUE4Parse
index c2535e18..70d41700 160000
--- a/CUE4Parse
+++ b/CUE4Parse
@@ -1 +1 @@
-Subproject commit c2535e18b0dd26c8173c73ba26f58d0c55afc0b8
+Subproject commit 70d417009d729260486d905eb5d10f45c78cfec7
diff --git a/FModel/App.xaml.cs b/FModel/App.xaml.cs
index 75802e98..c0692264 100644
--- a/FModel/App.xaml.cs
+++ b/FModel/App.xaml.cs
@@ -80,6 +80,7 @@ namespace FModel
Icon = MessageBoxImage.Error,
Buttons = new[]
{
+ MessageBoxButtons.Custom("Reset Settings", EErrorKind.ResetSettings),
MessageBoxButtons.Custom("Restart", EErrorKind.Restart),
MessageBoxButtons.Custom("OK", EErrorKind.Ignore)
},
@@ -89,6 +90,9 @@ namespace FModel
MessageBox.Show(messageBox);
if (messageBox.Result == MessageBoxResult.Custom && (EErrorKind) messageBox.ButtonPressed.Id != EErrorKind.Ignore)
{
+ if ((EErrorKind) messageBox.ButtonPressed.Id == EErrorKind.ResetSettings)
+ UserSettings.Delete();
+
ApplicationService.ApplicationView.Restart();
}
diff --git a/FModel/Creator/Bases/FN/BaseIcon.cs b/FModel/Creator/Bases/FN/BaseIcon.cs
index 3f553928..be861db1 100644
--- a/FModel/Creator/Bases/FN/BaseIcon.cs
+++ b/FModel/Creator/Bases/FN/BaseIcon.cs
@@ -61,7 +61,7 @@ namespace FModel.Creator.Bases.FN
if (Object.TryGetValue(out FText shortDescription, "ShortDescription", "UIDisplaySubName"))
ShortDescription = shortDescription.Text;
else if (Object.ExportType.Equals("AthenaItemWrapDefinition", StringComparison.OrdinalIgnoreCase))
- ShortDescription = "Wrap";
+ ShortDescription = Utils.GetLocalizedResource("Fort.Cosmetics", "ItemWrapShortDescription", "Wrap");
// Only works on non-cataba designs
if (Object.TryGetValue(out FStructFallback eventArrowColor, "EventArrowColor") &&
diff --git a/FModel/Enums.cs b/FModel/Enums.cs
index 46004c12..802d5839 100644
--- a/FModel/Enums.cs
+++ b/FModel/Enums.cs
@@ -11,9 +11,9 @@ namespace FModel
public enum EErrorKind
{
- Close,
Ignore,
- Restart
+ Restart,
+ ResetSettings
}
public enum SettingsOut
diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj
index 43f84da0..d040aea5 100644
--- a/FModel/FModel.csproj
+++ b/FModel/FModel.csproj
@@ -6,8 +6,8 @@
true
FModel.ico
4.0.0
- 4.0.0.0
- 4.0.0.0
+ 4.0.0.1
+ 4.0.0.1
false
true
win-x64
diff --git a/FModel/Settings/UserSettings.cs b/FModel/Settings/UserSettings.cs
index 039706d5..06b36fe9 100644
--- a/FModel/Settings/UserSettings.cs
+++ b/FModel/Settings/UserSettings.cs
@@ -29,6 +29,11 @@ namespace FModel.Settings
File.WriteAllText(FilePath, JsonConvert.SerializeObject(Default, Formatting.Indented));
}
+ public static void Delete()
+ {
+ if (File.Exists(FilePath)) File.Delete(FilePath);
+ }
+
private string _outputDirectory;
public string OutputDirectory
{
diff --git a/FModel/ViewModels/ApiEndpoints/BenbotApiEndpoint.cs b/FModel/ViewModels/ApiEndpoints/BenbotApiEndpoint.cs
index 34533f74..72856184 100644
--- a/FModel/ViewModels/ApiEndpoints/BenbotApiEndpoint.cs
+++ b/FModel/ViewModels/ApiEndpoints/BenbotApiEndpoint.cs
@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using System.IO;
+using System.IO;
using System.Threading;
using System.Threading.Tasks;
using FModel.ViewModels.ApiEndpoints.Models;
@@ -16,7 +15,7 @@ namespace FModel.ViewModels.ApiEndpoints
public async Task GetAesKeysAsync(CancellationToken token)
{
- var request = new RestRequest("https://benbotfn.tk/api/v2/aes", Method.GET)
+ var request = new RestRequest("https://benbot.app/api/v2/aes", Method.GET)
{
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
};
@@ -32,7 +31,7 @@ namespace FModel.ViewModels.ApiEndpoints
public async Task GetMappingsAsync(CancellationToken token)
{
- var request = new RestRequest("https://benbotfn.tk/api/v1/mappings", Method.GET)
+ var request = new RestRequest("https://benbot.app/api/v1/mappings", Method.GET)
{
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
};
diff --git a/FModel/ViewModels/ApiEndpoints/FModelApi.cs b/FModel/ViewModels/ApiEndpoints/FModelApi.cs
index 7dcb795a..acff5a6e 100644
--- a/FModel/ViewModels/ApiEndpoints/FModelApi.cs
+++ b/FModel/ViewModels/ApiEndpoints/FModelApi.cs
@@ -53,17 +53,17 @@ namespace FModel.ViewModels.ApiEndpoints
return _infos ?? GetInfosAsync(token, updateMode).GetAwaiter().GetResult();
}
- public async Task GetBackupsAsync(CancellationToken token, FGame game)
+ public async Task GetBackupsAsync(CancellationToken token, string gameName)
{
- var request = new RestRequest($"https://api.fmodel.app/v1/backups/{game}", Method.GET);
+ var request = new RestRequest($"https://api.fmodel.app/v1/backups/{gameName}", Method.GET);
var response = await _client.ExecuteAsync(request, token).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, request.Resource);
return response.Data;
}
- public Backup[] GetBackups(CancellationToken token, FGame game)
+ public Backup[] GetBackups(CancellationToken token, string gameName)
{
- return _backups ??= GetBackupsAsync(token, game).GetAwaiter().GetResult();
+ return _backups ??= GetBackupsAsync(token, gameName).GetAwaiter().GetResult();
}
public async Task GetDesignAsync(string designName)
diff --git a/FModel/ViewModels/BackupManagerViewModel.cs b/FModel/ViewModels/BackupManagerViewModel.cs
index 69777b40..8e4b3693 100644
--- a/FModel/ViewModels/BackupManagerViewModel.cs
+++ b/FModel/ViewModels/BackupManagerViewModel.cs
@@ -23,7 +23,7 @@ namespace FModel.ViewModels
private ThreadWorkerViewModel _threadWorkerView => ApplicationService.ThreadWorkerView;
private ApiEndpointViewModel _apiEndpointView => ApplicationService.ApiEndpointView;
private ApplicationViewModel _applicationView => ApplicationService.ApplicationView;
- private readonly FGame _game;
+ private readonly string _gameName;
private Backup _selectedBackup;
public Backup SelectedBackup
@@ -35,9 +35,9 @@ namespace FModel.ViewModels
public ObservableCollection Backups { get; }
public ICollectionView BackupsView { get; }
- public BackupManagerViewModel(FGame game)
+ public BackupManagerViewModel(string gameName)
{
- _game = game;
+ _gameName = gameName;
Backups = new ObservableCollection();
BackupsView = new ListCollectionView(Backups) {SortDescriptions = {new SortDescription("FileName", ListSortDirection.Ascending)}};
}
@@ -46,7 +46,7 @@ namespace FModel.ViewModels
{
await _threadWorkerView.Begin(cancellationToken =>
{
- var backups = _apiEndpointView.FModelApi.GetBackups(cancellationToken, _game);
+ var backups = _apiEndpointView.FModelApi.GetBackups(cancellationToken, _gameName);
if (backups == null) return;
Application.Current.Dispatcher.Invoke(() =>
@@ -62,7 +62,7 @@ namespace FModel.ViewModels
await _threadWorkerView.Begin(_ =>
{
var backupFolder = Path.Combine(UserSettings.Default.OutputDirectory, "Backups");
- var fileName = $"{_game}_{DateTime.Now:MMddyyyy}.fbkp";
+ var fileName = $"{_gameName}_{DateTime.Now:MMddyyyy}.fbkp";
var fullPath = Path.Combine(backupFolder, fileName);
using var fileStream = new FileStream(fullPath, FileMode.Create);
diff --git a/FModel/ViewModels/Commands/MenuCommand.cs b/FModel/ViewModels/Commands/MenuCommand.cs
index b5f839f1..237f386c 100644
--- a/FModel/ViewModels/Commands/MenuCommand.cs
+++ b/FModel/ViewModels/Commands/MenuCommand.cs
@@ -24,7 +24,7 @@ namespace FModel.ViewModels.Commands
Helper.OpenWindow("AES Manager", () => new AesManager().Show());
break;
case "Directory_Backup":
- Helper.OpenWindow("Backup Manager", () => new BackupManager(contextViewModel.CUE4Parse.Game).Show());
+ Helper.OpenWindow("Backup Manager", () => new BackupManager(contextViewModel.CUE4Parse.Provider.GameName).Show());
break;
case "Views_AudioPlayer":
Helper.OpenWindow("Audio Player", () => new AudioPlayer().Show());
diff --git a/FModel/ViewModels/MapViewerViewModel.cs b/FModel/ViewModels/MapViewerViewModel.cs
index 759a6799..dc57dde4 100644
--- a/FModel/ViewModels/MapViewerViewModel.cs
+++ b/FModel/ViewModels/MapViewerViewModel.cs
@@ -28,6 +28,13 @@ namespace FModel.ViewModels
get => _showCities;
set => SetProperty(ref _showCities, value, nameof(ShowCities));
}
+
+ private bool _showLandmarks;
+ public bool ShowLandmarks
+ {
+ get => _showLandmarks;
+ set => SetProperty(ref _showLandmarks, value, nameof(ShowLandmarks));
+ }
private bool _showPatrolPaths;
public bool ShowPatrolPaths
@@ -49,6 +56,13 @@ namespace FModel.ViewModels
get => _citiesImage;
set => SetProperty(ref _citiesImage, value);
}
+
+ private BitmapImage _landmarksImage;
+ public BitmapImage LandmarksImage
+ {
+ get => _landmarksImage;
+ set => SetProperty(ref _landmarksImage, value);
+ }
private BitmapImage _patrolPathImage;
public BitmapImage PatrolPathImage
@@ -81,6 +95,8 @@ namespace FModel.ViewModels
c.DrawBitmap(_mapBitmap, 0, 0);
if (ShowCities)
c.DrawBitmap(_citiesBitmap, 0, 0);
+ if (ShowLandmarks)
+ c.DrawBitmap(_landmarksBitmap, 0, 0);
if (ShowPatrolPaths)
c.DrawBitmap(_patrolPathBitmap, 0, 0);
@@ -98,7 +114,12 @@ namespace FModel.ViewModels
{
switch (propertyName)
{
- case nameof(ShowCities) when _citiesBitmap == null && _mapBitmap != null:
+ case nameof(ShowCities) when _citiesBitmap == null && _landmarksBitmap == null && _mapBitmap != null:
+ {
+ await LoadCities();
+ break;
+ }
+ case nameof(ShowLandmarks) when _landmarksBitmap == null && _citiesBitmap == null && _mapBitmap != null:
{
await LoadCities();
break;
@@ -127,6 +148,7 @@ namespace FModel.ViewModels
private const int WorldRadius = 135000;
private SKBitmap _mapBitmap;
private SKBitmap _citiesBitmap;
+ private SKBitmap _landmarksBitmap;
private SKBitmap _patrolPathBitmap;
private readonly SKBitmap _pinBitmap =
SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/pin.png"))?.Stream);
@@ -141,7 +163,7 @@ namespace FModel.ViewModels
private readonly SKPaint _pathPaint = new()
{
IsAntialias = true, FilterQuality = SKFilterQuality.High, IsStroke = true,
- Style = SKPaintStyle.Stroke, StrokeWidth = 5, Color = SKColors.Red,
+ Style = SKPaintStyle.Stroke, StrokeWidth = 10, Color = SKColors.Red,
ImageFilter = SKImageFilter.CreateDropShadow(4, 4, 8, 8, SKColors.Black)
};
@@ -173,27 +195,38 @@ namespace FModel.ViewModels
await _threadWorkerView.Begin(_ =>
{
_citiesBitmap = new SKBitmap(_mapBitmap.Width, _mapBitmap.Height, SKColorType.Rgba8888, SKAlphaType.Premul);
- using var c = new SKCanvas(_citiesBitmap);
+ _landmarksBitmap = new SKBitmap(_mapBitmap.Width, _mapBitmap.Height, SKColorType.Rgba8888, SKAlphaType.Premul);
+ using var cities = new SKCanvas(_citiesBitmap);
+ using var landmarks = new SKCanvas(_landmarksBitmap);
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") ||
- !poiData.TryGetValue(out FVector worldLocation, "WorldLocation") ||
- discoveryQuest.AssetPathName.Text.Contains("Landmarks")) continue;
+ !poiData.TryGetValue(out FText text, "Text") || string.IsNullOrEmpty(text.Text) ||
+ !poiData.TryGetValue(out FVector worldLocation, "WorldLocation")) continue;
+
var shaper = new CustomSKShaper(_imagePaint.Typeface);
var shapedText = shaper.Shape(text.Text, _imagePaint);
-
var vector = GetMapPosition(worldLocation);
- c.DrawPoint(vector.X, vector.Y, _pathPaint);
- c.DrawBitmap(_cityPinBitmap, vector.X - 50, vector.Y - 90, _imagePaint);
- c.DrawShapedText(shaper, text.Text, vector.X - shapedText.Points[^1].X / 2, vector.Y - 12.5F, _imagePaint);
+
+ if (discoveryQuest.AssetPathName.Text.Contains("landmarks", StringComparison.OrdinalIgnoreCase))
+ {
+ landmarks.DrawPoint(vector.X, vector.Y, _pathPaint);
+ landmarks.DrawShapedText(shaper, text.Text, vector.X - shapedText.Points[^1].X / 2, vector.Y - 12.5F, _imagePaint);
+ }
+ else
+ {
+ cities.DrawPoint(vector.X, vector.Y, _pathPaint);
+ cities.DrawBitmap(_cityPinBitmap, vector.X - 50, vector.Y - 90, _imagePaint);
+ cities.DrawShapedText(shaper, text.Text, vector.X - shapedText.Points[^1].X / 2, vector.Y - 12.5F, _imagePaint);
+ }
}
}
CitiesImage = GetImageSource(_citiesBitmap);
+ LandmarksImage = GetImageSource(_landmarksBitmap);
});
}
diff --git a/FModel/Views/About.xaml b/FModel/Views/About.xaml
index 4e154043..794eaef4 100644
--- a/FModel/Views/About.xaml
+++ b/FModel/Views/About.xaml
@@ -41,7 +41,7 @@
+ Text="Maiky ♥, HYPEX ♥, VenomLeaks ♥, JayKey ♥, Fevers ♥, Netu ♥, TheGameVlog ♥, Quentin ♥, Laggy ♥, s0ll ♥, RazTracker, Mikey, kyle, Yanteh, Shiina, SexyNutella, Alexander, Jinx, Tector, imatrix, LamZykoss, Frenzy Leaks, LlamaLeaks, XTigerHyperX, FunGames, WeLoveFortnite." />
diff --git a/FModel/Views/BackupManager.xaml.cs b/FModel/Views/BackupManager.xaml.cs
index 7e4a48b0..f7442e9b 100644
--- a/FModel/Views/BackupManager.xaml.cs
+++ b/FModel/Views/BackupManager.xaml.cs
@@ -7,9 +7,9 @@ namespace FModel.Views
{
private readonly BackupManagerViewModel _viewModel;
- public BackupManager(FGame game)
+ public BackupManager(string gameName)
{
- DataContext = _viewModel = new BackupManagerViewModel(game);
+ DataContext = _viewModel = new BackupManagerViewModel(gameName);
InitializeComponent();
}
diff --git a/FModel/Views/MapViewer.xaml b/FModel/Views/MapViewer.xaml
index ec43f572..f21ef599 100644
--- a/FModel/Views/MapViewer.xaml
+++ b/FModel/Views/MapViewer.xaml
@@ -29,6 +29,8 @@
+
@@ -43,6 +45,8 @@
Visibility="{Binding IsReady, Converter={StaticResource BoolToVisibilityConverter}}" />
+