mirror of
https://github.com/4sval/FModel.git
synced 2026-04-22 01:27:43 -05:00
New NPC design, minimal compared to original
This commit is contained in:
parent
9c2a899c35
commit
fb33536c26
|
|
@ -1 +1 @@
|
|||
Subproject commit 3df254b665420e05978f61441659c69d2a40411f
|
||||
Subproject commit 906641f95baaa7e269d96851c6b17e5fb8059abe
|
||||
228
FModel/Creator/Bases/FN/BaseTandem.cs
Normal file
228
FModel/Creator/Bases/FN/BaseTandem.cs
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
using System;
|
||||
using System.Windows;
|
||||
using CUE4Parse.UE4.Assets.Exports;
|
||||
using CUE4Parse.UE4.Objects.Core.i18N;
|
||||
using CUE4Parse.UE4.Objects.UObject;
|
||||
using CUE4Parse.UE4.Versions;
|
||||
using FModel.Framework;
|
||||
using FModel.Settings;
|
||||
using SkiaSharp;
|
||||
using SkiaSharp.HarfBuzz;
|
||||
|
||||
namespace FModel.Creator.Bases.FN
|
||||
{
|
||||
public class BaseTandem : BaseIcon
|
||||
{
|
||||
private string _generalDescription, _additionalDescription;
|
||||
|
||||
public BaseTandem(UObject uObject, EIconStyle style) : base(uObject, style)
|
||||
{
|
||||
DefaultPreview = Utils.GetBitmap("FortniteGame/Content/UI/Foundation/Textures/BattleRoyale/FeaturedItems/Outfit/T-AthenaSoldiers-CID-883-Athena-Commando-M-ChOneJonesy.T-AthenaSoldiers-CID-883-Athena-Commando-M-ChOneJonesy");
|
||||
Margin = 0;
|
||||
Width = 690;
|
||||
Height = 1080;
|
||||
}
|
||||
|
||||
public override void ParseForInfo()
|
||||
{
|
||||
base.ParseForInfo();
|
||||
|
||||
string sidePanel = string.Empty, entryList = string.Empty;
|
||||
|
||||
if (Object.TryGetValue(out FSoftObjectPath sidePanelIcon, "SidePanelIcon"))
|
||||
sidePanel = sidePanelIcon.AssetPathName.Text;
|
||||
if (Object.TryGetValue(out FSoftObjectPath entryListIcon, "EntryListIcon"))
|
||||
entryList = entryListIcon.AssetPathName.Text;
|
||||
|
||||
// Overrides for generic "default" images Epic uses for Quest-only or unfinished NPCs
|
||||
if (sidePanel.Contains("Clown") && entryList.Contains("Clown"))
|
||||
Preview = null;
|
||||
else if (sidePanel.Contains("Bane") && !Object.Name.Contains("Sorana"))
|
||||
Preview = Utils.GetBitmap(entryList);
|
||||
else if (!string.IsNullOrWhiteSpace(sidePanel) && !sidePanel.Contains("Clown"))
|
||||
Preview = Utils.GetBitmap(sidePanel);
|
||||
else if ((string.IsNullOrWhiteSpace(sidePanel) || sidePanel.Contains("Clown")) && !string.IsNullOrWhiteSpace(entryList))
|
||||
Preview = Utils.GetBitmap(entryList);
|
||||
|
||||
if (Object.TryGetValue(out FText genDesc, "GeneralDescription"))
|
||||
_generalDescription = genDesc.Text;
|
||||
if (Object.TryGetValue(out FText addDesc, "AdditionalDescription"))
|
||||
_additionalDescription = addDesc.Text;
|
||||
}
|
||||
|
||||
public override SKImage Draw()
|
||||
{
|
||||
using var ret = new SKBitmap(Width, Height, SKColorType.Rgba8888, SKAlphaType.Opaque);
|
||||
using var c = new SKCanvas(ret);
|
||||
|
||||
DrawBackground(c);
|
||||
DrawPreview(c);
|
||||
DrawHaze(c);
|
||||
|
||||
// Korean is slightly smaller than other languages, so the font size is increased slightly
|
||||
DrawName(c);
|
||||
DrawGeneralDescription(c);
|
||||
DrawAdditionalDescription(c);
|
||||
|
||||
return SKImage.FromBitmap(ret);
|
||||
}
|
||||
|
||||
private readonly SKPaint _panelPaint = new() { IsAntialias = true, FilterQuality = SKFilterQuality.High, Color = SKColor.Parse("#0045C7") };
|
||||
|
||||
private new void DrawBackground(SKCanvas c)
|
||||
{
|
||||
c.DrawBitmap(SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/npcleftside.png"))?.Stream).Resize(Width, Height), 0, 0, new SKPaint { IsAntialias = false, FilterQuality = SKFilterQuality.None, ImageFilter = SKImageFilter.CreateBlur(0, 25) });
|
||||
|
||||
using var rect1 = new SKPath { FillType = SKPathFillType.EvenOdd };
|
||||
_panelPaint.Color = SKColor.Parse("#002A8C");
|
||||
rect1.MoveTo(29, 0);
|
||||
rect1.LineTo(62, Height);
|
||||
rect1.LineTo(Width, Height);
|
||||
rect1.LineTo(Width, 0);
|
||||
rect1.LineTo(29, 0);
|
||||
rect1.Close();
|
||||
c.DrawPath(rect1, _panelPaint);
|
||||
|
||||
_panelPaint.Shader = SKShader.CreateLinearGradient(new SKPoint(29, 0), new SKPoint(Width, Height),
|
||||
new[] { SKColor.Parse("#002A8C") }, SKShaderTileMode.Clamp);
|
||||
c.DrawPath(rect1, _panelPaint);
|
||||
|
||||
_panelPaint.Shader = SKShader.CreateRadialGradient(new SKPoint(348, 196), 300, new[] { SKColor.Parse("#0049CE"), SKColor.Parse("#002A8C") }, SKShaderTileMode.Clamp);
|
||||
c.DrawPath(rect1, _panelPaint);
|
||||
|
||||
using var rect2 = new SKPath { FillType = SKPathFillType.EvenOdd };
|
||||
|
||||
rect2.MoveTo(10, 0);
|
||||
rect2.LineTo(30, 0);
|
||||
rect2.LineTo(63, Height);
|
||||
rect2.LineTo(56, Height);
|
||||
rect2.LineTo(10, 0);
|
||||
rect2.Close();
|
||||
c.DrawPath(rect2, _panelPaint);
|
||||
|
||||
_panelPaint.Shader = SKShader.CreateLinearGradient(new SKPoint(10, 0), new SKPoint(62, Height),
|
||||
new[] { SKColor.Parse("#0045C7") }, SKShaderTileMode.Clamp);
|
||||
c.DrawPath(rect2, _panelPaint);
|
||||
}
|
||||
|
||||
private new void DrawPreview(SKCanvas c)
|
||||
{
|
||||
var previewToUse = Preview ?? DefaultPreview;
|
||||
|
||||
if (Preview == null)
|
||||
{
|
||||
previewToUse = DefaultPreview;
|
||||
ImagePaint.BlendMode = SKBlendMode.DstOut;
|
||||
ImagePaint.Color = SKColor.Parse("#00175F");
|
||||
}
|
||||
|
||||
var x = -125;
|
||||
|
||||
switch (previewToUse.Width)
|
||||
{
|
||||
case 512 when previewToUse.Height == 1024:
|
||||
previewToUse = previewToUse.ResizeWithRatio(500, 1000);
|
||||
x = 100;
|
||||
break;
|
||||
case 512 when previewToUse.Height == 512:
|
||||
previewToUse = previewToUse.Resize(512);
|
||||
x = 125;
|
||||
break;
|
||||
default:
|
||||
previewToUse = previewToUse.Resize(1000, 1000);
|
||||
break;
|
||||
}
|
||||
|
||||
c.DrawBitmap(previewToUse, x, 30, ImagePaint);
|
||||
}
|
||||
|
||||
private void DrawHaze(SKCanvas c)
|
||||
{
|
||||
using var rect1 = new SKPath { FillType = SKPathFillType.EvenOdd };
|
||||
rect1.MoveTo(29, 0);
|
||||
rect1.LineTo(62, Height);
|
||||
rect1.LineTo(Width, Height);
|
||||
rect1.LineTo(Width, 0);
|
||||
rect1.LineTo(29, 0);
|
||||
rect1.Close();
|
||||
|
||||
_panelPaint.Shader = SKShader.CreateLinearGradient(new SKPoint(343, 0), new SKPoint(343, Height),
|
||||
new[] { SKColors.Transparent, SKColor.Parse("#001E70FF"), SKColor.Parse("#001E70").WithAlpha(200), SKColor.Parse("#001E70").WithAlpha(245), SKColor.Parse("#001E70") }, new[] { 0, (float) .1, (float) .65, (float) .85, 1 }, SKShaderTileMode.Clamp);
|
||||
c.DrawPath(rect1, _panelPaint);
|
||||
}
|
||||
|
||||
private void DrawName(SKCanvas c)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(DisplayName)) return;
|
||||
|
||||
DisplayNamePaint.TextSize = UserSettings.Default.AssetLanguage switch
|
||||
{
|
||||
ELanguage.Korean => 56,
|
||||
_ => 42
|
||||
};
|
||||
|
||||
DisplayNamePaint.TextScaleX = (float) 1.1;
|
||||
DisplayNamePaint.Color = SKColors.White;
|
||||
DisplayNamePaint.TextSkewX = (float) -.25;
|
||||
DisplayNamePaint.TextAlign = SKTextAlign.Left;
|
||||
|
||||
var typeface = Utils.Typefaces.TandemDisplayName;
|
||||
if (typeface == Utils.Typefaces.Default)
|
||||
{
|
||||
DisplayNamePaint.TextSize = 30;
|
||||
}
|
||||
|
||||
DisplayNamePaint.Typeface = typeface;
|
||||
var shaper = new CustomSKShaper(DisplayNamePaint.Typeface);
|
||||
c.DrawShapedText(shaper, DisplayName.ToUpper(), 97, 900, DisplayNamePaint);
|
||||
}
|
||||
|
||||
private void DrawGeneralDescription(SKCanvas c)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_generalDescription)) return;
|
||||
|
||||
DescriptionPaint.TextSize = UserSettings.Default.AssetLanguage switch
|
||||
{
|
||||
ELanguage.Korean => 20,
|
||||
_ => 17
|
||||
};
|
||||
|
||||
DescriptionPaint.Color = SKColor.Parse("#00FFFB");
|
||||
DescriptionPaint.TextAlign = SKTextAlign.Left;
|
||||
|
||||
var typeface = Utils.Typefaces.TandemGenDescription;
|
||||
if (typeface == Utils.Typefaces.Default)
|
||||
{
|
||||
DescriptionPaint.TextSize = 21;
|
||||
}
|
||||
|
||||
DescriptionPaint.Typeface = typeface;
|
||||
var shaper = new CustomSKShaper(DescriptionPaint.Typeface);
|
||||
c.DrawShapedText(shaper, _generalDescription.ToUpper(), 97, 930, DescriptionPaint);
|
||||
}
|
||||
|
||||
private void DrawAdditionalDescription(SKCanvas c)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_additionalDescription)) return;
|
||||
|
||||
DescriptionPaint.TextSize = UserSettings.Default.AssetLanguage switch
|
||||
{
|
||||
ELanguage.Korean => 22,
|
||||
_ => 18
|
||||
};
|
||||
|
||||
DescriptionPaint.Color = SKColor.Parse("#89D8FF");
|
||||
DescriptionPaint.TextAlign = SKTextAlign.Left;
|
||||
|
||||
var typeface = Utils.Typefaces.TandemAddDescription;
|
||||
if (typeface == Utils.Typefaces.Default)
|
||||
{
|
||||
DescriptionPaint.TextSize = 20;
|
||||
}
|
||||
|
||||
DescriptionPaint.Typeface = typeface;
|
||||
Utils.DrawMultilineText(c, _additionalDescription, Width, 0, SKTextAlign.Left,
|
||||
new SKRect(97, 960, Width - 10, Height), DescriptionPaint, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -112,8 +112,10 @@ namespace FModel.Creator
|
|||
_ => new BaseIcon(_object, _style)
|
||||
};
|
||||
return true;
|
||||
case "FortTrapItemDefinition":
|
||||
case "FortTandemCharacterData":
|
||||
creator = new BaseTandem(_object, _style);
|
||||
return true;
|
||||
case "FortTrapItemDefinition":
|
||||
case "FortSpyTechItemDefinition":
|
||||
case "FortAccoladeItemDefinition":
|
||||
case "FortContextTrapItemDefinition":
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace FModel.Creator
|
|||
{
|
||||
public class Typefaces
|
||||
{
|
||||
private readonly Uri _BURBANK_BIG_CONDENSED_BOLD = new Uri("pack://application:,,,/Resources/BurbankBigCondensed-Bold.ttf");
|
||||
private readonly Uri _BURBANK_BIG_CONDENSED_BOLD = new("pack://application:,,,/Resources/BurbankBigCondensed-Bold.ttf");
|
||||
private const string _EXT = ".ufont";
|
||||
|
||||
// FortniteGame
|
||||
|
|
@ -48,7 +48,7 @@ namespace FModel.Creator
|
|||
private const string _NANUM_GOTHIC = "NanumGothic";
|
||||
private const string _QUADRAT_BOLD = "Quadrat_Bold";
|
||||
private const string _SEGOE_BOLD_ITALIC = "Segoe_Bold_Italic";
|
||||
|
||||
|
||||
// WorldExplorers
|
||||
private const string _BATTLE_BREAKERS_BASE_PATH = "/Game/UMG/Fonts/Faces/";
|
||||
private const string _HEMIHEAD426 = "HemiHead426";
|
||||
|
|
@ -66,6 +66,9 @@ namespace FModel.Creator
|
|||
public readonly SKTypeface Bottom; // must be null for non-latin base languages
|
||||
public readonly SKTypeface Bundle;
|
||||
public readonly SKTypeface BundleNumber;
|
||||
public readonly SKTypeface TandemDisplayName;
|
||||
public readonly SKTypeface TandemGenDescription;
|
||||
public readonly SKTypeface TandemAddDescription;
|
||||
|
||||
public Typefaces(CUE4ParseViewModel viewModel)
|
||||
{
|
||||
|
|
@ -91,12 +94,11 @@ namespace FModel.Creator
|
|||
};
|
||||
if (viewModel.Provider.TrySaveAsset(namePath + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
DisplayName = SKTypeface.FromStream(m);
|
||||
}
|
||||
else DisplayName = Default;
|
||||
|
||||
|
||||
var descriptionPath = _FORTNITE_BASE_PATH +
|
||||
language switch
|
||||
{
|
||||
|
|
@ -109,12 +111,11 @@ namespace FModel.Creator
|
|||
};
|
||||
if (viewModel.Provider.TrySaveAsset(descriptionPath + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
Description = SKTypeface.FromStream(m);
|
||||
}
|
||||
else Description = Default;
|
||||
|
||||
|
||||
var bottomPath = _FORTNITE_BASE_PATH +
|
||||
language switch
|
||||
{
|
||||
|
|
@ -127,20 +128,18 @@ namespace FModel.Creator
|
|||
};
|
||||
if (viewModel.Provider.TrySaveAsset(bottomPath + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
Bottom = SKTypeface.FromStream(m);
|
||||
}
|
||||
// else keep it null
|
||||
|
||||
|
||||
if (viewModel.Provider.TrySaveAsset(_FORTNITE_BASE_PATH + _BURBANK_BIG_CONDENSED_BLACK + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
BundleNumber = SKTypeface.FromStream(m);
|
||||
}
|
||||
else BundleNumber = Default;
|
||||
|
||||
|
||||
var bundleNamePath = _FORTNITE_BASE_PATH +
|
||||
language switch
|
||||
{
|
||||
|
|
@ -154,11 +153,63 @@ namespace FModel.Creator
|
|||
};
|
||||
if (viewModel.Provider.TrySaveAsset(bundleNamePath + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
Bundle = SKTypeface.FromStream(m);
|
||||
}
|
||||
else Bundle = BundleNumber;
|
||||
|
||||
var tandemDisplayNamePath = _FORTNITE_BASE_PATH +
|
||||
language switch
|
||||
{
|
||||
ELanguage.Korean => _ASIA_ERINM,
|
||||
ELanguage.Russian => _BURBANK_BIG_CONDENSED_BLACK,
|
||||
ELanguage.Japanese => _NIS_JYAU,
|
||||
ELanguage.Arabic => _NOTO_SANS_ARABIC_BLACK,
|
||||
ELanguage.TraditionalChinese => _NOTO_SANS_TC_BLACK,
|
||||
ELanguage.Chinese => _NOTO_SANS_SC_BLACK,
|
||||
_ => _BURBANK_BIG_REGULAR_BLACK
|
||||
};
|
||||
if (viewModel.Provider.TrySaveAsset(tandemDisplayNamePath + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
TandemDisplayName = SKTypeface.FromStream(m);
|
||||
}
|
||||
else TandemDisplayName = Default;
|
||||
|
||||
var tandemGeneralDescPath = _FORTNITE_BASE_PATH +
|
||||
language switch
|
||||
{
|
||||
ELanguage.Korean => _ASIA_ERINM,
|
||||
ELanguage.Japanese => _NIS_JYAU,
|
||||
ELanguage.Arabic => _NOTO_SANS_ARABIC_BLACK,
|
||||
ELanguage.TraditionalChinese => _NOTO_SANS_TC_BLACK,
|
||||
ELanguage.Chinese => _NOTO_SANS_SC_BLACK,
|
||||
_ => _BURBANK_SMALL_BLACK
|
||||
};
|
||||
if (viewModel.Provider.TrySaveAsset(tandemGeneralDescPath + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
TandemGenDescription = SKTypeface.FromStream(m);
|
||||
}
|
||||
else TandemGenDescription = Default;
|
||||
|
||||
var tandemAdditionalDescPath = _FORTNITE_BASE_PATH +
|
||||
language switch
|
||||
{
|
||||
ELanguage.Korean => _ASIA_ERINM,
|
||||
ELanguage.Japanese => _NIS_JYAU,
|
||||
ELanguage.Arabic => _NOTO_SANS_ARABIC_BLACK,
|
||||
ELanguage.TraditionalChinese => _NOTO_SANS_TC_BLACK,
|
||||
ELanguage.Chinese => _NOTO_SANS_SC_BLACK,
|
||||
_ => _BURBANK_SMALL_BOLD
|
||||
};
|
||||
if (viewModel.Provider.TrySaveAsset(tandemAdditionalDescPath + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
TandemAddDescription = SKTypeface.FromStream(m);
|
||||
}
|
||||
else TandemAddDescription = Default;
|
||||
|
||||
break;
|
||||
}
|
||||
case FGame.WorldExplorers:
|
||||
|
|
@ -174,7 +225,7 @@ namespace FModel.Creator
|
|||
};
|
||||
if (viewModel.Provider.TrySaveAsset(namePath + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
DisplayName = SKTypeface.FromStream(m);
|
||||
}
|
||||
else DisplayName = Default;
|
||||
|
|
@ -190,7 +241,7 @@ namespace FModel.Creator
|
|||
};
|
||||
if (viewModel.Provider.TrySaveAsset(descriptionPath + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
Description = SKTypeface.FromStream(m);
|
||||
}
|
||||
else Description = Default;
|
||||
|
|
@ -209,14 +260,14 @@ namespace FModel.Creator
|
|||
{
|
||||
if (viewModel.Provider.TrySaveAsset(_SPELLBREAK_BASE_PATH + _QUADRAT_BOLD + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
DisplayName = SKTypeface.FromStream(m);
|
||||
}
|
||||
else DisplayName = Default;
|
||||
|
||||
if (viewModel.Provider.TrySaveAsset(_SPELLBREAK_BASE_PATH + _MONTSERRAT_SEMIBOLD + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
Description = SKTypeface.FromStream(m);
|
||||
}
|
||||
else Description = Default;
|
||||
|
|
@ -241,8 +292,8 @@ namespace FModel.Creator
|
|||
public SKTypeface OnTheFly(string path)
|
||||
{
|
||||
if (!_viewModel.Provider.TrySaveAsset(path, out var data)) return Default;
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
var m = new MemoryStream(data) { Position = 0 };
|
||||
return SKTypeface.FromStream(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@
|
|||
<None Remove="Resources\delete.png" />
|
||||
<None Remove="Resources\edit.png" />
|
||||
<None Remove="Resources\go_to_directory.png" />
|
||||
<None Remove="Resources\npcleftside.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
@ -187,6 +188,7 @@
|
|||
<Resource Include="Resources\edit.png" />
|
||||
<Resource Include="Resources\go_to_directory.png" />
|
||||
<Resource Include="Resources\approaching_storm_cubemap.dds" />
|
||||
<Resource Include="Resources\npcleftside.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
BIN
FModel/Resources/npcleftside.png
Normal file
BIN
FModel/Resources/npcleftside.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 257 KiB |
Loading…
Reference in New Issue
Block a user