| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 |
- using Godot;
- using System;
- using System.Collections.Generic;
- using System.Text.Json.Serialization;
- namespace AvatarDoll
- {
- /// <summary>
- /// Avatar作者的元信息
- /// </summary>
- [Serializable]
- public struct Metadata
- {
- [JsonInclude] public string Author { get; set; }
- [JsonInclude] public string Introduction { get; set; }
- [JsonInclude] public string Version { get; set; }
- [JsonInclude] public string Link { get; set; }
- }
-
- [Serializable]
- public struct PartState
- {
- public PartState() { }
-
- [JsonInclude] public string Name { get; set; } = "";
- [JsonInclude] public PartScope Scope { get; set; } = 0;
- [JsonInclude] public byte Default { get; set; } = 0;
- [JsonInclude] public List<string> Values { get; set; } = new();
- [JsonInclude] public List<bool> Required { get; set; } = new();
-
- public override bool Equals(object obj)
- {
- return obj is PartState state && Equals(state);
- }
-
- public bool Equals(PartState other)
- {
- return Name == other.Name &&
- Scope == other.Scope &&
- Default == other.Default &&
- System.Linq.Enumerable.SequenceEqual(Values, other.Values) &&
- System.Linq.Enumerable.SequenceEqual(Required, other.Required);
- }
- }
-
- /// <summary>
- /// Avatar配置项
- /// </summary>
- [Serializable]
- public struct ProjectSettings
- {
- public ProjectSettings() { }
- [JsonInclude] public int MaxBodySlotCost { get; set; } = 5;
- [JsonInclude] public List<PartState> States { get; set; } = new();
-
- public static int GetStatusesCode(ProjectSettings settings)
- {
- int finalHash = 0;
- foreach (var state in settings.States)
- {
- int listHash = 0;
- foreach (var value in state.Required)
- {
- int valueHash = value ? 1 : 0;
- listHash = CombineHashes(listHash, valueHash);
- }
- finalHash = CombineHashes(finalHash, listHash);
- }
- return finalHash;
- }
- private static int CombineHashes(int h1, int h2)
- {
- long hash = 2166136261L;
-
- hash = (hash ^ (h1 & 0xFF)) * 16777619;
- hash = (hash ^ ((h1 >> 8) & 0xFF)) * 16777619;
- hash = (hash ^ ((h1 >> 16) & 0xFF)) * 16777619;
- hash = (hash ^ ((h1 >> 24) & 0xFF)) * 16777619;
-
- hash = (hash ^ (h2 & 0xFF)) * 16777619;
- hash = (hash ^ ((h2 >> 8) & 0xFF)) * 16777619;
- hash = (hash ^ ((h2 >> 16) & 0xFF)) * 16777619;
- hash = (hash ^ ((h2 >> 24) & 0xFF)) * 16777619;
-
- return (int)(hash & 0x7FFFFFFF);
- }
-
- public override bool Equals(object obj)
- {
- return obj is ProjectSettings settings && Equals(settings);
- }
-
- public bool Equals(ProjectSettings other)
- {
- bool equal = MaxBodySlotCost == other.MaxBodySlotCost
- && States.Count == other.States.Count;
- if (equal == false) return false;
-
- for (int i = 0; i < States.Count; i++)
- equal &= States[i].Equals(other.States[i]);
- return equal;
- }
-
- public override int GetHashCode()
- {
- return GetStatusesCode(this);
- }
- }
-
- /// <summary>
- ///
- /// </summary>
- [Serializable]
- public struct PaletteColor
- {
- [JsonInclude] public float R { get; set; }
- [JsonInclude] public float G { get; set; }
- [JsonInclude] public float B { get; set; }
- [JsonInclude] public float A { get; set; }
-
- public PaletteColor(float r, float g, float b, float a = 1.0f) { R = r; G = g; B = b; A = a; }
- public PaletteColor(Godot.Color color) { R = color.R; G = color.G; B = color.B; A = color.A; }
-
- public static implicit operator Godot.Color(PaletteColor color) { return new Godot.Color(color.R, color.G, color.B, color.A); }
- public static implicit operator PaletteColor(Godot.Color color) { return new PaletteColor(color); }
-
- public override bool Equals(object obj)
- {
- if (obj is PaletteColor other)
- {
- return (double) this.R == (double) other.R && (double) this.G == (double) other.G && (double) this.B == (double) other.B && (double) this.A == (double) other.A;
- }
- return false;
- }
-
- public override int GetHashCode()
- {
- return HashCode.Combine(R, G, B, A);
- }
- }
-
- /// <summary>
- /// 图片调色参数
- /// </summary>
- [Serializable]
- public struct PaletteParam()
- {
- [JsonInclude] public int ElementIndex = -1;
- [JsonInclude] public PaletteColor BasicColor { get; set; } = new PaletteColor(0,0,0,0);
- [JsonInclude] public int Tolerance = 0;
- [JsonInclude] public PaletteColor ModulateColor { get; set; } = new PaletteColor(0,0,0,0);
- [JsonInclude] public int BlendMode = 0;
-
- public override bool Equals(object obj)
- {
- return obj is PaletteParam other && Equals(other);
- }
- public bool Equals(PaletteParam other)
- {
- return BasicColor.Equals(other.BasicColor) &&
- ModulateColor.Equals(other.ModulateColor) &&
- Tolerance == other.Tolerance &&
- BlendMode == other.BlendMode;
- }
-
- public override int GetHashCode()
- {
- return HashCode.Combine(ElementIndex, Tolerance, BlendMode, BasicColor.GetHashCode(), ModulateColor.GetHashCode());
- }
- }
-
- /// <summary>
- /// 调色板。用于保存其他上色方案,且可以指定不同配色下的别名
- /// </summary>
- [Serializable]
- public struct Palette()
- {
- [JsonInclude] public uint Guid { get; set; } = 0;
- [JsonInclude] public string Name { get; set; }
- [JsonInclude] public string Introduction { get; set; }
-
- [JsonInclude] public List<ThemeColor> ThemeColors { get; set; } = [];
- [JsonInclude] public List<PaletteParam> IconPaletteParams { get; set; } = [];
- [JsonInclude] public List<PaletteParam> ElementPaletteParams { get; set; } = [];
- }
-
- /// <summary>
- /// Avatar的某个元素的集合,可以是一个身形,或者一个脸型,一件服装等
- /// 例如对于头发,就是一个发型在所有Pose下的样子的集合。脸型、服装等同理
- /// </summary>
- [Serializable]
- public class AvatarPart()
- {
- [JsonInclude] public uint Guid { get; set; } = 0;
- [JsonInclude] public string Name { get; set; }
- [JsonInclude] public int IconAssetId { get; set; }
- [JsonInclude] public string Introduction { get; set; }
-
- [JsonInclude] public List<ThemeColor> ThemeColors { get; set; } = [];
- /// <summary>
- /// 调色板。如果该服装有除了默认颜色外的其他上色方案,可以在这里保存
- /// </summary>
- [JsonInclude] public List<Palette> Palettes { get; set; } = [];
-
- /// <summary>
- /// 每个pose的数据
- /// key: PoseID
- /// value: AvatarPoses是个AvatarPosePart数组。 例如一个装备在站立状态下的pose图可能由多张图片组合而成
- /// </summary>
- [JsonInclude] public Dictionary<string, List<AvatarElement>> Elements { get; set; } = new();
- public override bool Equals(object obj)
- {
- return obj is AvatarPart other && Equals(other);
- }
- public bool Equals(AvatarPart obj)
- {
- bool equal = true;
- equal &= Name == obj.Name;
- equal &= IconAssetId == obj.IconAssetId;
- equal &= Introduction == obj.Introduction;
- equal &= Palettes.Count == obj.Palettes.Count;
- if (equal == false) return false;
- for (int i = 0; i < Palettes.Count; ++i)
- {
- equal &= Palettes[i].Guid == obj.Palettes[i].Guid;
- equal &= Palettes[i].Name == obj.Palettes[i].Name;
- equal &= Palettes[i].Introduction == obj.Palettes[i].Introduction;
- equal &= Palettes[i].IconPaletteParams.Count == obj.Palettes[i].IconPaletteParams.Count;
- equal &= Palettes[i].ElementPaletteParams.Count == obj.Palettes[i].ElementPaletteParams.Count;
- if (equal == false) return false;
-
- for (int j = 0; j < Palettes[i].IconPaletteParams.Count; ++j)
- equal &= Palettes[i].IconPaletteParams[j].Equals(obj.Palettes[i].IconPaletteParams[j]);
- for (int j = 0; j < Palettes[i].ElementPaletteParams.Count; ++j)
- equal &= Palettes[i].ElementPaletteParams[j].Equals(obj.Palettes[i].ElementPaletteParams[j]);
-
- if (equal == false) return false;
- }
- equal &= Elements.Count == obj.Elements.Count;
- foreach (var pair in Elements)
- {
- equal &= obj.Elements.ContainsKey(pair.Key);
- equal &= pair.Value.Count == obj.Elements[pair.Key].Count;
- if (equal == false) return false;
-
- for (int i = 0; i < pair.Value.Count; ++i)
- equal &= obj.Elements[pair.Key][i].Equals(pair.Value[i]);
- if (equal == false) return false;
- }
- return equal;
- }
-
- public override int GetHashCode() { return (int)Guid; }
- }
- /// <summary>
- /// 一张Asset图片在pose中的偏移和层级等数据
- /// </summary>
- [Serializable]
- public struct AvatarElement
- {
- [JsonInclude] public int AssetId { get; set; }
- [JsonInclude] public int Layer { get; set; }
- [JsonInclude] public int LayerOffset { get; set; }
- [JsonInclude] public float PositionX { get; set; }
- [JsonInclude] public float PositionY { get; set; }
- [JsonInclude] public float Rotation { get; set; }
- [JsonInclude] public float ScaleX { get; set; }
- [JsonInclude] public float ScaleY { get; set; }
- [JsonInclude] public float Skew { get; set; }
- }
-
- [Serializable]
- public class AvatarBody() : AvatarPart { }
-
- [Serializable]
- public class AvatarHead(): AvatarPart { }
-
- [Serializable]
- public class AvatarHair(): AvatarPart { }
-
- [Serializable]
- public class AvatarFace() : AvatarPart { }
-
- [Serializable]
- public struct ClothClasses : IEquatable<ClothClasses>
- {
- [JsonInclude] public int Hash { get; set; }
-
- public EClothClasses_Type1 Type1()
- {
- return (EClothClasses_Type1)((Hash >> 16) & 0xFFFF);
- }
- public void SetType1(EClothClasses_Type1 value)
- {
- Hash = ((Hash & 0x0000FFFF) | (((short)value & 0xFFFF) << 16));
- }
- public short Type2()
- {
- return (short)(Hash & 0xFFFF);
- }
-
- public void SetType2(short value)
- {
- Hash = (int)((Hash & 0xFFFF0000u) | (uint)(value & 0xFFFF));
- }
- public ClothClasses(int hash)
- {
- Hash = hash;
- }
-
- public ClothClasses(EClothClasses_Type1 type1, short type2)
- {
- Hash = (((short)type1 & 0xFFFF) << 16) | (type2 & 0xFFFF);
- }
- public static implicit operator ClothClasses(int hash) => new ClothClasses(hash);
-
- public static implicit operator int(ClothClasses clothClasses) => clothClasses.Hash;
-
- public override bool Equals(object obj)
- {
- return obj is ClothClasses other && this.Hash == other.Hash;
- }
- public bool Equals(ClothClasses other)
- {
- return Hash == other.Hash;
- }
- public override int GetHashCode() => Hash;
- public static bool operator ==(ClothClasses left, ClothClasses right)
- {
- return left.Equals(right);
- }
- public static bool operator !=(ClothClasses left, ClothClasses right)
- {
- return !(left == right);
- }
- }
-
- /// <summary>
- /// 角色服装数据
- /// </summary>
- [Serializable]
- public class AvatarCloth() : AvatarPart
- {
- /// <summary>
- /// 服装分类
- /// </summary>
- [JsonInclude] public ClothClasses ClothClasses = new();
-
- /// <summary>
- /// 占用的身体槽。例如连衣裙会同时占用上身和下身的槽位,使得不能再穿其他上衣。
- /// key: BodySlot.Hash
- /// value: cost
- /// </summary>
- [JsonInclude] public Dictionary<int, int> BodySlotCost { get; set; } = new();
-
- public override bool Equals(object obj) { return obj is AvatarCloth other && Equals(other); }
- public bool Equals(AvatarCloth obj)
- {
- bool equal = base.Equals(obj);
- equal &= ClothClasses.Equals(obj.ClothClasses);
- equal &= BodySlotCost.Count == obj.BodySlotCost.Count;
- if (equal == false) return false;
-
- equal &= BodySlotCost.Count == obj.BodySlotCost.Count;
- foreach (var pair in BodySlotCost)
- {
- equal &= obj.BodySlotCost.ContainsKey(pair.Key);
- if (equal == false) return false;
-
- equal &= obj.BodySlotCost[pair.Key] == pair.Value;
- if (equal == false) return false;
- }
- return equal;
- }
-
- public override int GetHashCode() { return (int)Guid; }
- }
-
- [Serializable]
- public struct AvatarDollData()
- {
- [JsonInclude] public int FormatVersion { get; set; } = 0;
- [JsonInclude] public Metadata Metadata = new();
- [JsonInclude] public ProjectSettings Settings = new();
-
- /// <summary>
- /// Asset资源映射表
- /// 把AssetID对应到文件
- /// </summary>
- [JsonInclude] public Dictionary<int, string> AssetMap { get; set; } = new();
- [JsonInclude] public List<AvatarBody> Bodies { get; set; } = [];
- [JsonInclude] public List<AvatarHead> Heads { get; set; } = [];
- [JsonInclude] public List<AvatarHair> Hairs { get; set; } = [];
- [JsonInclude] public List<AvatarFace> Faces { get; set; } = [];
- [JsonInclude] public List<AvatarCloth> Clothes { get; set; } = [];
-
- public override bool Equals(object obj)
- {
- return obj is AvatarDollData other && Equals(other);
- }
- public bool Equals(AvatarDollData data)
- {
- bool equal = true;
- equal &= FormatVersion == data.FormatVersion;
- equal &= Metadata.Equals(data.Metadata);
- equal &= AssetMap.Count == data.AssetMap.Count;
- foreach (var pair in AssetMap)
- {
- equal &= data.AssetMap.ContainsKey(pair.Key);
- equal &= pair.Value == data.AssetMap[pair.Key];
- }
-
- equal &= Bodies.Count == data.Bodies.Count;
- for (int i = 0; i < data.Bodies.Count; ++i)
- equal &= Bodies[i].Equals(data.Bodies[i]);
-
- equal &= Faces.Count == data.Faces.Count;
- for (int i = 0; i < data.Faces.Count; ++i)
- equal &= Faces[i].Equals(data.Faces[i]);
- equal &= Hairs.Count == data.Hairs.Count;
- for (int i = 0; i < data.Hairs.Count; ++i)
- equal &= Hairs[i].Equals(data.Hairs[i]);
-
- equal &= Clothes.Count == data.Clothes.Count;
- for (int i = 0; i < data.Clothes.Count; ++i)
- equal &= Clothes[i].Equals(data.Clothes[i]);
- return equal;
- }
-
-
- }
-
- }
|