using Barotrauma.IO; using Microsoft.Xna.Framework; using System; using System.Collections.Generic; using System.Linq; namespace Barotrauma.Items.Components { partial class IdCard { public struct OwnerAppearance { public Sprite Portrait; public Vector2 SheetIndex; public JobPrefab JobPrefab; public List Attachments; public Color HairColor; public Color FacialHairColor; public Color SkinColor; public void ExtractJobPrefab(IReadOnlyDictionary tags) { if (!tags.TryGetValue("jobid".ToIdentifier(), out string jobId)) { return; } if (!jobId.IsNullOrEmpty()) { JobPrefab = JobPrefab.Get(jobId.ToIdentifier()); } } public void ExtractAppearance(CharacterInfo characterInfo, IdCard idCard) { int disguisedHairIndex = idCard.OwnerHairIndex; int disguisedBeardIndex = idCard.OwnerBeardIndex; int disguisedMoustacheIndex = idCard.OwnerMoustacheIndex; int disguisedFaceAttachmentIndex = idCard.OwnerFaceAttachmentIndex; Color hairColor = idCard.OwnerHairColor; Color facialHairColor = idCard.OwnerFacialHairColor; Color skinColor = idCard.OwnerSkinColor; var tags = idCard.OwnerTagSet; if ((characterInfo.HasSpecifierTags && !tags.Any())) { Portrait = null; Attachments = null; return; } if (characterInfo.Ragdoll.MainElement?.Elements() is { } limbElements) { foreach (ContentXElement limbElement in limbElements) { if (!limbElement.GetAttributeString("type", "").Equals("head", StringComparison.OrdinalIgnoreCase)) { continue; } ContentXElement spriteElement = limbElement.GetChildElement("sprite"); if (spriteElement == null) { continue; } ContentPath contentPath = spriteElement.GetAttributeContentPath("texture"); string spritePath = characterInfo.ReplaceVars(contentPath.Value); string fileName = Path.GetFileNameWithoutExtension(spritePath); //go through the files in the directory to find a matching sprite foreach (string file in Directory.GetFiles(Path.GetDirectoryName(spritePath))) { if (!file.EndsWith(".png", StringComparison.OrdinalIgnoreCase)) { continue; } string fileWithoutTags = Path.GetFileNameWithoutExtension(file); fileWithoutTags = fileWithoutTags.Split('[', ']').First(); if (fileWithoutTags != fileName) { continue; } Portrait = new Sprite(spriteElement, "", file) { RelativeOrigin = Vector2.Zero }; break; } break; } } if (characterInfo.Wearables != null) { float baldnessChance = 0.1f; List createElementList(WearableType wearableType, float emptyCommonness = 1.0f) => CharacterInfo.AddEmpty( characterInfo.FilterElements(characterInfo.Wearables, tags, wearableType), wearableType, emptyCommonness); var disguisedHairs = createElementList(WearableType.Hair, baldnessChance); var disguisedBeards = createElementList(WearableType.Beard); var disguisedMoustaches = createElementList(WearableType.Moustache); var disguisedFaceAttachments = createElementList(WearableType.FaceAttachment); ContentXElement getElementFromList(List list, int index) => CharacterInfo.IsValidIndex(index, list) ? list[index] : null; var disguisedHairElement = getElementFromList(disguisedHairs, disguisedHairIndex); var disguisedBeardElement = getElementFromList(disguisedBeards, disguisedBeardIndex); var disguisedMoustacheElement = getElementFromList(disguisedMoustaches, disguisedMoustacheIndex); var disguisedFaceAttachmentElement = getElementFromList(disguisedFaceAttachments, disguisedFaceAttachmentIndex); Attachments = new List(); void loadAttachments(List attachments, ContentXElement element, WearableType wearableType) { foreach (var s in element?.GetChildElements("sprite") ?? Enumerable.Empty()) { attachments.Add(new WearableSprite(s, wearableType)); } } loadAttachments(Attachments, disguisedFaceAttachmentElement, WearableType.FaceAttachment); loadAttachments(Attachments, disguisedBeardElement, WearableType.Beard); loadAttachments(Attachments, disguisedMoustacheElement, WearableType.Moustache); loadAttachments(Attachments, disguisedHairElement, WearableType.Hair); } HairColor = hairColor; FacialHairColor = facialHairColor; SkinColor = skinColor; } } public OwnerAppearance StoredOwnerAppearance = default; } }