FModel/FModel/Creator/Bases/FN/BaseCommunity.cs
2022-07-29 15:31:52 -04:00

276 lines
9.9 KiB
C#

using CUE4Parse.UE4.Assets.Exports;
using CUE4Parse.UE4.Objects.GameplayTags;
using CUE4Parse.UE4.Objects.UObject;
using CUE4Parse.UE4.Versions;
using CUE4Parse_Fortnite.Enums;
using FModel.Extensions;
using FModel.Framework;
using FModel.Services;
using FModel.Settings;
using FModel.ViewModels.ApiEndpoints.Models;
using SkiaSharp;
using SkiaSharp.HarfBuzz;
namespace FModel.Creator.Bases.FN;
public class BaseCommunity : BaseIcon
{
private readonly CommunityDesign _design;
private string _rarityName;
private string _source;
private string _season;
private bool _lowerDrawn;
public BaseCommunity(UObject uObject, EIconStyle style, string designName) : base(uObject, style)
{
Margin = 0;
_lowerDrawn = false;
_design = ApplicationService.ApiEndpointView.FModelApi.GetDesign(designName);
}
public override void ParseForInfo()
{
ParseForReward(UserSettings.Default.CosmeticDisplayAsset);
if (Object.TryGetValue(out FPackageIndex series, "Series") && Utils.TryGetPackageIndexExport(series, out UObject export))
_rarityName = export.Name;
else
_rarityName = Object.GetOrDefault("Rarity", EFortRarity.Uncommon).GetDescription();
if (Object.TryGetValue(out FGameplayTagContainer gameplayTags, "GameplayTags"))
CheckGameplayTags(gameplayTags);
if (Object.TryGetValue(out FPackageIndex cosmeticItem, "cosmetic_item"))
CosmeticSource = cosmeticItem.Name.ToUpper();
DisplayName = DisplayName.ToUpper();
Description = Description.ToUpper();
}
public override SKBitmap[] Draw()
{
var ret = new SKBitmap(Width, Height, SKColorType.Rgba8888, SKAlphaType.Premul);
using var c = new SKCanvas(ret);
if (_design == null)
{
base.Draw(c);
}
else
{
DrawBackground(c);
DrawPreview(c);
DrawTextBackground(c);
DrawDisplayName(c);
DrawDescription(c);
if (_design.DrawSeason && _design.Fonts.TryGetValue("Season", out var font))
DrawToBottom(c, font, _season);
if (_design.DrawSource && _design.Fonts.TryGetValue("Source", out font))
DrawToBottom(c, font, _source);
DrawUserFacingFlags(c, _design.GameplayTags.DrawCustomOnly);
}
return new[] { ret };
}
private void CheckGameplayTags(FGameplayTagContainer gameplayTags)
{
if (_design == null) return;
if (_design.DrawSource)
{
if (gameplayTags.TryGetGameplayTag("Cosmetics.Source.", out var source))
_source = source.Text["Cosmetics.Source.".Length..].ToUpper();
else if (gameplayTags.TryGetGameplayTag("Athena.ItemAction.", out var action))
_source = action.Text["Athena.ItemAction.".Length..].ToUpper();
}
if (_design.DrawSet && gameplayTags.TryGetGameplayTag("Cosmetics.Set.", out var set))
Description += GetCosmeticSet(set.Text, _design.DrawSetShort);
if (_design.DrawSeason && gameplayTags.TryGetGameplayTag("Cosmetics.Filter.Season.", out var season))
_season = GetCosmeticSeason(season.Text, _design.DrawSeasonShort);
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)
{
return bShort ? setName["Cosmetics.Set.".Length..] : base.GetCosmeticSet(setName);
}
private string GetCosmeticSeason(string seasonNumber, bool bShort)
{
if (!bShort) return base.GetCosmeticSeason(seasonNumber);
var s = seasonNumber["Cosmetics.Filter.Season.".Length..];
var number = int.Parse(s);
switch (number)
{
case 10:
s = "X";
break;
case > 18:
number += 2;
s = number.ToString();
break;
}
return $"C{number / 10 + 1} S{s[^1..]}";
}
private new void DrawBackground(SKCanvas c)
{
if (_design.Rarities.TryGetValue(_rarityName, out var rarity))
{
c.DrawBitmap(rarity.Background, 0, 0, ImagePaint);
c.DrawBitmap(rarity.Upper, 0, 0, ImagePaint);
}
else
{
base.DrawBackground(c);
}
}
private new void DrawTextBackground(SKCanvas c)
{
if (!_lowerDrawn && string.IsNullOrEmpty(DisplayName) && string.IsNullOrEmpty(Description)) return;
_lowerDrawn = true;
if (_design.Rarities.TryGetValue(_rarityName, out var rarity))
{
c.DrawBitmap(rarity.Lower, 0, 0, ImagePaint);
}
else
{
base.DrawTextBackground(c);
}
}
private new void DrawDisplayName(SKCanvas c)
{
if (string.IsNullOrEmpty(DisplayName)) return;
if (_design.Fonts.TryGetValue(nameof(DisplayName), out var font))
{
DisplayNamePaint.TextSize = font.FontSize;
DisplayNamePaint.TextScaleX = font.FontScale;
DisplayNamePaint.Color = font.FontColor;
DisplayNamePaint.TextSkewX = font.SkewValue;
DisplayNamePaint.TextAlign = font.Alignment;
if (font.ShadowValue > 0)
DisplayNamePaint.ImageFilter = SKImageFilter.CreateDropShadow(2, 2, 4, 4, new SKColor(0, 0, 0, font.ShadowValue));
if (font.Typeface.TryGetValue(UserSettings.Default.AssetLanguage, out var path) ||
font.Typeface.TryGetValue(ELanguage.English, out path))
DisplayNamePaint.Typeface = Utils.Typefaces.OnTheFly(path);
while (DisplayNamePaint.MeasureText(DisplayName) > Width - Margin * 2)
{
DisplayNamePaint.TextSize -= 1;
}
var shaper = new CustomSKShaper(DisplayNamePaint.Typeface);
var shapedText = shaper.Shape(DisplayName, DisplayNamePaint);
var x = font.Alignment switch
{
SKTextAlign.Center => (Width - shapedText.Points[^1].X) / 2f,
_ => font.X
};
c.DrawShapedText(shaper, DisplayName, x, font.Y, DisplayNamePaint);
}
else
{
base.DrawDisplayName(c);
}
}
private new void DrawDescription(SKCanvas c)
{
if (string.IsNullOrEmpty(Description)) return;
if (_design.Fonts.TryGetValue(nameof(Description), out var font))
{
DescriptionPaint.TextSize = font.FontSize;
DescriptionPaint.TextScaleX = font.FontScale;
DescriptionPaint.Color = font.FontColor;
DescriptionPaint.TextSkewX = font.SkewValue;
DescriptionPaint.TextAlign = font.Alignment;
if (font.ShadowValue > 0)
DescriptionPaint.ImageFilter = SKImageFilter.CreateDropShadow(2, 2, 4, 4, new SKColor(0, 0, 0, font.ShadowValue));
if (font.Typeface.TryGetValue(UserSettings.Default.AssetLanguage, out var path) ||
font.Typeface.TryGetValue(ELanguage.English, out path))
DescriptionPaint.Typeface = Utils.Typefaces.OnTheFly(path);
while (DescriptionPaint.MeasureText(Description) > Width - Margin * 2)
{
DescriptionPaint.TextSize -= 1;
}
var shaper = new CustomSKShaper(DescriptionPaint.Typeface);
var shapedText = shaper.Shape(Description, DescriptionPaint);
var x = font.Alignment switch
{
SKTextAlign.Center => (Width - shapedText.Points[^1].X) / 2f,
_ => font.X
};
if (font.MaxLineCount < 2)
{
c.DrawShapedText(shaper, Description, x, font.Y, DescriptionPaint);
}
else
{
Utils.DrawMultilineText(c, Description, Width - Margin * 2, Margin, DescriptionPaint.TextAlign,
new SKRect(Margin, font.Y, Width - Margin, Height), DescriptionPaint, out _);
}
}
else
{
base.DrawDescription(c);
}
}
private void DrawToBottom(SKCanvas c, FontDesign font, string text)
{
if (string.IsNullOrEmpty(text)) return;
if (!_lowerDrawn)
{
_lowerDrawn = true;
DrawTextBackground(c);
}
DisplayNamePaint.TextSize = font.FontSize;
DisplayNamePaint.TextScaleX = font.FontScale;
DisplayNamePaint.Color = font.FontColor;
DisplayNamePaint.TextSkewX = font.SkewValue;
DisplayNamePaint.TextAlign = font.Alignment;
if (font.ShadowValue > 0)
DisplayNamePaint.ImageFilter = SKImageFilter.CreateDropShadow(2, 2, 4, 4, new SKColor(0, 0, 0, font.ShadowValue));
if (font.Typeface.TryGetValue(UserSettings.Default.AssetLanguage, out var path) ||
font.Typeface.TryGetValue(ELanguage.English, out path))
DisplayNamePaint.Typeface = Utils.Typefaces.OnTheFly(path);
var shaper = new CustomSKShaper(DisplayNamePaint.Typeface);
var shapedText = shaper.Shape(text, DisplayNamePaint);
var x = font.Alignment switch
{
SKTextAlign.Center => (Width - shapedText.Points[^1].X) / 2f,
SKTextAlign.Right => font.X - DisplayNamePaint.MeasureText(text),
_ => font.X
};
c.DrawShapedText(shaper, text, x, font.Y, DisplayNamePaint);
}
private void DrawUserFacingFlags(SKCanvas c, bool customOnly)
{
if (UserFacingFlags == null || UserFacingFlags.Count < 1) return;
if (customOnly)
{
c.DrawBitmap(_design.GameplayTags.Custom, 0, 0, ImagePaint);
}
else
{
// add size to api
// draw
}
}
}