diff --git a/FModel/Creator/Bases/MV/BaseFighter.cs b/FModel/Creator/Bases/MV/BaseFighter.cs index 47a51f8d..fc5da665 100644 --- a/FModel/Creator/Bases/MV/BaseFighter.cs +++ b/FModel/Creator/Bases/MV/BaseFighter.cs @@ -14,9 +14,9 @@ namespace FModel.Creator.Bases.MV; public class BaseFighter : UCreator { - private float _xOffset; - private float _yOffset; - private float _zoom; + private float _xOffset = 1f; + private float _yOffset = 1f; + private float _zoom = 1f; private readonly SKBitmap _pattern; private readonly SKBitmap _perk; @@ -30,7 +30,6 @@ public class BaseFighter : UCreator public BaseFighter(UObject uObject, EIconStyle style) : base(uObject, style) { - // https://cdn.discordapp.com/attachments/715640455068385422/1003052259917168700/unknown.png Width = 1024; DisplayNamePaint.TextAlign = SKTextAlign.Left; DisplayNamePaint.TextSize = 100; @@ -60,11 +59,14 @@ public class BaseFighter : UCreator _zoom = Math.Clamp(portrait.ScalarParameterValues.FirstOrDefault(x => x.ParameterInfo.Name.Text == "Zoom")?.ParameterValue ?? 1f, 0, 1); Preview = Utils.GetBitmap(portrait); } + else if (Object.TryGetValue(out FSoftObjectPath portraitTexture, "NewCharacterSelectPortraitTexture", "HUDPortraitTexture")) + Preview = Utils.GetBitmap(portraitTexture); if (Object.TryGetValue(out FText displayName, "DisplayName")) DisplayName = displayName.Text; GetFighterClassInfo(Object.GetOrDefault("Class", EFighterClass.Support)); + _fighterType.Item2.Add(GetFighterType(Object.GetOrDefault("Type", EFighterType.Horizontal))); if (Object.TryGetValue(out FText property, "Property")) _fighterType.Item2.Add(property.Text); @@ -136,6 +138,17 @@ public class BaseFighter : UCreator _fighterType.Item2.Add(displayName.Text); } + private string GetFighterType(EFighterType typ) + { + return typ switch + { + EFighterType.Horizontal => Utils.GetLocalizedResource("", "97A60DD54AA23D4B93D5B891F729BF5C", "Horizontal"), + EFighterType.Vertical => Utils.GetLocalizedResource("", "2C55443D47164019BE73A5ABDC670F36", "Vertical"), + EFighterType.Hybrid => Utils.GetLocalizedResource("", "B980C82D40FF37FD359C74A339CE1B3A", "Hybrid"), + _ => typ.ToString() + }; + } + private new void DrawBackground(SKCanvas c) { c.DrawRect(new SKRect(0, 0, Width, Height), @@ -189,7 +202,9 @@ public class BaseFighter : UCreator private void DrawFighterInfo(SKCanvas c) { - c.DrawBitmap(_fighterType.Item1, new SKRect(50, 112.5f, 98, 160.5f), ImagePaint); + if (_fighterType.Item1 != null) + c.DrawBitmap(_fighterType.Item1, new SKRect(50, 112.5f, 98, 160.5f), ImagePaint); + c.DrawText(string.Join(" | ", _fighterType.Item2), 98, 145, DescriptionPaint); } @@ -202,6 +217,7 @@ public class BaseFighter : UCreator ImagePaint.ImageFilter = null; ImagePaint.BlendMode = SKBlendMode.SoftLight; c.DrawBitmap(_perk, new SKRect(x, y, x + size / 2, y + size / 2), ImagePaint); + if (_recommendedPerks.Count < 1) return; ImagePaint.BlendMode = SKBlendMode.SrcOver; ImagePaint.ImageFilter = SKImageFilter.CreateDropShadow(0, 0, 2.5f, 2.5f, SKColors.Black); @@ -222,6 +238,7 @@ public class BaseFighter : UCreator ImagePaint.ImageFilter = null; ImagePaint.BlendMode = SKBlendMode.SoftLight; c.DrawBitmap(_emote, new SKRect(x, y - size / 2, x + size / 2, y), ImagePaint); + if (_availableTaunts.Count < 1) return; ImagePaint.BlendMode = SKBlendMode.SrcOver; ImagePaint.ImageFilter = SKImageFilter.CreateDropShadow(0, 0, 1.5f, 1.5f, SKColors.Black); @@ -242,6 +259,7 @@ public class BaseFighter : UCreator ImagePaint.ImageFilter = null; ImagePaint.BlendMode = SKBlendMode.SoftLight; c.DrawBitmap(_skin, new SKRect(x, y, x + size / 4, y + size / 4), ImagePaint); + if (_skins.Count < 1) return; ImagePaint.BlendMode = SKBlendMode.SrcOver; ImagePaint.ImageFilter = SKImageFilter.CreateDropShadow(0, 0, 1.5f, 1.5f, SKColors.Black); @@ -262,3 +280,10 @@ public enum EFighterClass : byte Assassin = 1, Support = 0 // Default } + +public enum EFighterType : byte +{ + Hybrid = 2, + Vertical = 1, + Horizontal = 0 // Default +} diff --git a/FModel/Creator/Bases/MV/BaseMultiversusIcon.cs b/FModel/Creator/Bases/MV/BaseMultiVersusIcon.cs similarity index 50% rename from FModel/Creator/Bases/MV/BaseMultiversusIcon.cs rename to FModel/Creator/Bases/MV/BaseMultiVersusIcon.cs index a25c044b..85cc1117 100644 --- a/FModel/Creator/Bases/MV/BaseMultiversusIcon.cs +++ b/FModel/Creator/Bases/MV/BaseMultiVersusIcon.cs @@ -1,5 +1,4 @@ using CUE4Parse.UE4.Assets.Exports; -using CUE4Parse.UE4.Assets.Exports.Material; using CUE4Parse.UE4.Objects.Core.i18N; using CUE4Parse.UE4.Objects.Core.Math; using CUE4Parse.UE4.Objects.UObject; @@ -8,71 +7,50 @@ using SkiaSharp; namespace FModel.Creator.Bases.MV; -public class BaseMultiversusIcon : BaseIcon +public class BaseMultiVersusIcon : BaseIcon { - public BaseMultiversusIcon(UObject uObject, EIconStyle style) : base(uObject, style) + public BaseMultiVersusIcon(UObject uObject, EIconStyle style) : base(uObject, style) { + DefaultPreview = Utils.GetBitmap("MultiVersus/Content/Panda_Main/UI/PreMatch/Images/DiamondPortraits/0010_Random.0010_Random"); } public override void ParseForInfo() { - if (Object.TryGetValue(out var backgroundColor, "BackgroundColor")) - { - var bgColor = SKColor.Parse(backgroundColor.Hex); - Background = new[] { bgColor, bgColor }; - } - else if (Object.TryGetValue(out var rarity, "Rarity")) - { - Background = GetRarityBackground(rarity.ToString()); - Border = new[] { GetRarityBorder(rarity.ToString()) }; - } + var rarity = Object.GetOrDefault("Rarity", new FName("ERewardRarity::None")); + Background = GetRarityBackground(rarity.ToString()); + Border = new[] { GetRarityBorder(rarity.ToString()) }; - if (Object.TryGetValue(out var nameColor, "DisplayNameColor")) - { - Border = new[] { SKColor.Parse(nameColor.Hex) }; - } - - if (Object.TryGetValue(out var rewardThumbnail, "RewardThumbnail")) + if (Object.TryGetValue(out FSoftObjectPath rewardThumbnail, "RewardThumbnail", "DisplayTextureRef")) Preview = Utils.GetBitmap(rewardThumbnail); + else if (Object.TryGetValue(out FPackageIndex icon, "Icon")) + Preview = Utils.GetBitmap(icon); - else if (Object.TryGetValue(out var portaitPtr, "CollectionsPortraitMaterial", "CharacterSelectPortraitMaterial") - && portaitPtr.TryLoad(out var portait)) - Preview = Utils.GetBitmap(portait); - - else if (Object.TryGetValue(out var skins, "Skins") && - skins[0].TryLoad(out var defaultSkin) && - defaultSkin.TryGetValue(out var skinRewardThumb, "RewardThumbnail")) - Preview = Utils.GetBitmap(skinRewardThumb); - - else if (Object.TryGetValue(out var eogPortrait, "EOGPortrait")) - Preview = Utils.GetBitmap(eogPortrait); - - if (Object.TryGetValue(out var displayName, "DisplayName")) + if (Object.TryGetValue(out FText displayName, "DisplayName")) DisplayName = displayName.Text; + if (Object.TryGetValue(out FText description, "Description")) + Description = Utils.RemoveHtmlTags(description.Text); - if (Object.TryGetValue(out var description, "Overview", "Bio")) - Description = description.Text; - - if (Object.TryGetValue(out var property, "Property")) - ShortDescription = property.Text; - - if (Object.TryGetValue(out var unlockLocation, "UnlockLocation")) - CosmeticSource = unlockLocation.ToString().Split("::")[1]; + if (Object.TryGetValue(out int xpValue, "XPValue")) + DisplayName += $" (+{xpValue})"; } - private static SKColor[] GetRarityBackground(string rarity) - { - string rarityName = rarity.Split("::")[1]; + // public override SKBitmap[] Draw() + // { + // // dedicated design here, use : UCreator + // throw new System.NotImplementedException(); + // } - switch (rarityName) // the colors here are the base color and brighter color that the game uses for rarities from the "Rarity to Color" blueprint function + private SKColor[] GetRarityBackground(string rarity) + { + switch (rarity.Split("::")[1]) // the colors here are the base color and brighter color that the game uses for rarities from the "Rarity to Color" blueprint function { - case "Common": + case "Common": return new[] { SKColor.Parse(new FLinearColor(0.068478f, 0.651406f, 0.016807f, 1.000000f).Hex), SKColor.Parse(new FLinearColor(0.081422f, 1.000000f, 0.000000f, 1.000000f).Hex) }; - case "Rare": + case "Rare": return new[] { SKColor.Parse(new FLinearColor(0.035911f, 0.394246f, 0.900000f, 1.000000f).Hex), @@ -100,11 +78,9 @@ public class BaseMultiversusIcon : BaseIcon } } - private static SKColor GetRarityBorder(string rarity) + private SKColor GetRarityBorder(string rarity) { - string rarityName = rarity.Split("::")[1]; - - switch (rarityName) // the colors here are the desaturated versions of the rarity colors + switch (rarity.Split("::")[1]) // the colors here are the desaturated versions of the rarity colors { case "Common": return SKColor.Parse(new FLinearColor(0.172713f, 0.651406f, 0.130281f, 1.000000f).Hex); diff --git a/FModel/Creator/CreatorPackage.cs b/FModel/Creator/CreatorPackage.cs index 4bf2b4e1..678dee48 100644 --- a/FModel/Creator/CreatorPackage.cs +++ b/FModel/Creator/CreatorPackage.cs @@ -178,8 +178,20 @@ public class CreatorPackage : IDisposable case "CharacterData": creator = new BaseFighter(_object, _style); return true; + case "PerkGroup": + creator = null; + return true; + case "StatTrackingBundleData": + case "HydraSyncedDataAsset": + case "CharacterGiftData": + case "ProfileIconData": + case "RingOutVfxData": + case "BannerData": + case "EmoteData": + case "TauntData": case "SkinData": - creator = new BaseMultiversusIcon(_object, _style); + case "PerkData": + creator = new BaseMultiVersusIcon(_object, _style); return true; // Battle Breakers case "WExpGenericAccountItemDefinition": diff --git a/FModel/Creator/Typefaces.cs b/FModel/Creator/Typefaces.cs index 8527d23e..ef7afd25 100644 --- a/FModel/Creator/Typefaces.cs +++ b/FModel/Creator/Typefaces.cs @@ -44,7 +44,9 @@ public class Typefaces // Multiversus private const string _MULTIVERSUS_BASE_PATH = "/Game/Panda_Main/UI/Fonts/"; private const string _NORMS_STD_CONDENSED_BLACK = "Norms/TT_Norms_Std_Condensed_Black"; + private const string _XIANGHEHEI_SC_PRO_BLACK = "XiangHeHei_SC/MXiangHeHeiSCPro-Black"; private const string _NORMS_STD_CONDENSED_BOLD = "Norms/TT_Norms_Std_Condensed_Bold"; + private const string _XIANGHEHEI_SC_PRO_HEAVY = "XiangHeHei_SC/MXiangHeHeiSCPro-Heavy"; // Spellbreak private const string _SPELLBREAK_BASE_PATH = "/Game/UI/Fonts/"; @@ -200,8 +202,16 @@ public class Typefaces } case FGame.Multiversus: { - DisplayName = OnTheFly(_MULTIVERSUS_BASE_PATH + _NORMS_STD_CONDENSED_BLACK + _EXT); - Description = OnTheFly(_MULTIVERSUS_BASE_PATH + _NORMS_STD_CONDENSED_BOLD + _EXT); + DisplayName = OnTheFly(_MULTIVERSUS_BASE_PATH + language switch + { + ELanguage.Chinese => _XIANGHEHEI_SC_PRO_BLACK, + _ => _NORMS_STD_CONDENSED_BLACK + } + _EXT); + Description = OnTheFly(_MULTIVERSUS_BASE_PATH + language switch + { + ELanguage.Chinese => _XIANGHEHEI_SC_PRO_HEAVY, + _ => _NORMS_STD_CONDENSED_BOLD + } + _EXT); break; } default: diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs index afb5ce54..83238348 100644 --- a/FModel/MainWindow.xaml.cs +++ b/FModel/MainWindow.xaml.cs @@ -66,7 +66,9 @@ public partial class MainWindow await _applicationView.CUE4Parse.Initialize(); await _applicationView.AesManager.InitAes(); await _applicationView.AesManager.UpdateProvider(true); +#if !DEBUG await _applicationView.CUE4Parse.InitInformation(); +#endif await _applicationView.CUE4Parse.InitBenMappings(); await _applicationView.InitVgmStream(); await _applicationView.InitOodle();