mirror of
https://github.com/aelurum/AssetStudio.git
synced 2025-05-25 05:40:21 -04:00
150 lines
6.1 KiB
C#
150 lines
6.1 KiB
C#
using Arknights.AvgCharHubMono;
|
|
using AssetStudio;
|
|
using AssetStudioGUI;
|
|
using SixLabors.ImageSharp;
|
|
using System.Linq;
|
|
using System;
|
|
using System.Collections.Specialized;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace Arknights
|
|
{
|
|
internal class AvgSprite
|
|
{
|
|
public Texture2D FaceSpriteAlphaTexture { get; }
|
|
public Texture2D FullTexture { get; }
|
|
public Texture2D FullAlphaTexture { get; }
|
|
public Point FacePos { get; }
|
|
public Size FaceSize { get; }
|
|
public string Alias { get; }
|
|
public bool IsWholeBodySprite { get; }
|
|
public bool IsFaceSprite { get; }
|
|
public bool IsHubParsed { get; }
|
|
|
|
private AvgSpriteConfig GetCurSpriteGroup(AvgSpriteConfigGroup spriteHubDataGrouped, long spriteItemID, string spriteName)
|
|
{
|
|
if (spriteHubDataGrouped.SpriteGroups.Length > 1)
|
|
{
|
|
if (!string.IsNullOrEmpty(spriteName))
|
|
{
|
|
var groupFromName = int.TryParse(spriteName?.Substring(spriteName.IndexOf('$') + 1, 1), out int groupIndex);
|
|
if (groupFromName)
|
|
{
|
|
return spriteHubDataGrouped.SpriteGroups[groupIndex - 1];
|
|
}
|
|
}
|
|
return spriteHubDataGrouped.SpriteGroups.FirstOrDefault(x => x.Sprites.Any(y => y.Sprite.m_PathID == spriteItemID));
|
|
}
|
|
else
|
|
{
|
|
return spriteHubDataGrouped.SpriteGroups[0];
|
|
}
|
|
}
|
|
|
|
private bool TryGetSpriteHub(AssetItem assetItem, out AvgSpriteConfig spriteHubData)
|
|
{
|
|
spriteHubData = null;
|
|
var scriptAssets = Studio.exportableAssets.FindAll(x =>
|
|
x.Type == ClassIDType.MonoBehaviour
|
|
&& x.Container == assetItem.Container);
|
|
if (scriptAssets.Count == 0)
|
|
{
|
|
Logger.Warning("No MonoBehaviours were found.");
|
|
return false;
|
|
}
|
|
|
|
OrderedDictionary spriteHubDict = null;
|
|
var isGrouped = false;
|
|
foreach (var scriptAsset in scriptAssets)
|
|
{
|
|
var scriptAssetDict = ((MonoBehaviour)scriptAsset.Asset).ToType();
|
|
if (scriptAssetDict == null)
|
|
{
|
|
Logger.Warning("MonoBehaviour is not readable.");
|
|
return false;
|
|
}
|
|
|
|
if (scriptAssetDict.Contains("spriteGroups"))
|
|
{
|
|
spriteHubDict = scriptAssetDict;
|
|
isGrouped = true;
|
|
break;
|
|
}
|
|
if (scriptAssetDict.Contains("sprites"))
|
|
{
|
|
spriteHubDict = scriptAssetDict;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (spriteHubDict == null)
|
|
{
|
|
Logger.Warning("AVGCharacterSpriteHub is not readable.");
|
|
return false;
|
|
}
|
|
|
|
var spriteHubJson = JsonConvert.SerializeObject(spriteHubDict);
|
|
if (isGrouped)
|
|
{
|
|
var groupedSpriteHub = JsonConvert.DeserializeObject<AvgSpriteConfigGroup>(spriteHubJson);
|
|
spriteHubData = GetCurSpriteGroup(groupedSpriteHub, assetItem.m_PathID, assetItem.Text);
|
|
}
|
|
else
|
|
{
|
|
spriteHubData = JsonConvert.DeserializeObject<AvgSpriteConfig>(spriteHubJson);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public AvgSprite(AssetItem assetItem)
|
|
{
|
|
if (TryGetSpriteHub(assetItem, out var spriteHubData))
|
|
{
|
|
IsHubParsed = spriteHubData?.Sprites.Length > 0;
|
|
}
|
|
if (IsHubParsed)
|
|
{
|
|
var curSpriteData = spriteHubData.Sprites.FirstOrDefault(x => x.Sprite.m_PathID == assetItem.m_PathID);
|
|
|
|
if (curSpriteData == null)
|
|
{
|
|
Studio.StatusStripUpdate($"Sprite \"{assetItem.Text}\" was not found in the avg sprite hub.");
|
|
return;
|
|
}
|
|
|
|
Alias = curSpriteData.Alias;
|
|
IsWholeBodySprite = curSpriteData.IsWholeBody;
|
|
|
|
if (spriteHubData.FaceSize.X > 0 && spriteHubData.FaceSize.Y > 0) //If face data exist
|
|
{
|
|
var fullTexSpriteData = spriteHubData.Sprites.Last(); //Last sprite item in the list usually contains PathID of Sprite with full texture
|
|
|
|
var curSprite = (Sprite)assetItem.Asset;
|
|
IsFaceSprite = curSprite.m_Rect.width <= 256 && curSprite.m_Rect.height <= 256 && curSprite.m_PathID != fullTexSpriteData.Sprite.m_PathID;
|
|
|
|
var curSpriteAlphaID = curSpriteData.AlphaTex.m_PathID;
|
|
var curSpriteAlphaTex = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == curSpriteAlphaID)?.Asset;
|
|
if (curSpriteAlphaTex != null)
|
|
{
|
|
FaceSpriteAlphaTexture = IsFaceSprite ? curSpriteAlphaTex : null;
|
|
fullTexSpriteData = IsFaceSprite ? fullTexSpriteData : curSpriteData;
|
|
}
|
|
var fullTexSpriteID = fullTexSpriteData.Sprite.m_PathID;
|
|
var fullTexAlphaID = fullTexSpriteData.AlphaTex.m_PathID;
|
|
var fullTexSprite = (Sprite)Studio.exportableAssets.Find(x => x.m_PathID == fullTexSpriteID).Asset;
|
|
|
|
FullTexture = fullTexSprite.m_RD.texture.TryGet(out var fullTex) ? fullTex : null;
|
|
FullAlphaTexture = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == fullTexAlphaID)?.Asset;
|
|
FacePos = new Point((int)Math.Round(spriteHubData.FacePos.X), (int)Math.Round(spriteHubData.FacePos.Y));
|
|
FaceSize = new Size((int)Math.Round(spriteHubData.FaceSize.X), (int)Math.Round(spriteHubData.FaceSize.Y));
|
|
}
|
|
else
|
|
{
|
|
FullAlphaTexture = (Texture2D)Studio.exportableAssets.Find(x => x.m_PathID == curSpriteData.AlphaTex.m_PathID)?.Asset;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|