using Content.Shared.Humanoid; using Content.Shared.Humanoid.Markings; using Content.Shared.Humanoid.Prototypes; using Content.Shared.Preferences; using Content.Shared.Verbs; using Robust.Shared.GameObjects.Components.Localization; namespace Content.Server.Humanoid; public sealed partial class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem { [Dependency] private readonly MarkingManager _markingManager = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnMarkingsSet); SubscribeLocalEvent(OnBaseLayersSet); SubscribeLocalEvent>(OnVerbsRequest); } // this was done enough times that it only made sense to do it here /// /// Clones a humanoid's appearance to a target mob, provided they both have humanoid components. /// /// Source entity to fetch the original appearance from. /// Target entity to apply the source entity's appearance to. /// Source entity's humanoid component. /// Target entity's humanoid component. public void CloneAppearance(EntityUid source, EntityUid target, HumanoidAppearanceComponent? sourceHumanoid = null, HumanoidAppearanceComponent? targetHumanoid = null) { if (!Resolve(source, ref sourceHumanoid) || !Resolve(target, ref targetHumanoid)) { return; } targetHumanoid.Species = sourceHumanoid.Species; targetHumanoid.SkinColor = sourceHumanoid.SkinColor; targetHumanoid.EyeColor = sourceHumanoid.EyeColor; targetHumanoid.Age = sourceHumanoid.Age; SetSex(target, sourceHumanoid.Sex, false, targetHumanoid); targetHumanoid.CustomBaseLayers = new(sourceHumanoid.CustomBaseLayers); targetHumanoid.MarkingSet = new(sourceHumanoid.MarkingSet); targetHumanoid.Gender = sourceHumanoid.Gender; if (TryComp(target, out var grammar)) { grammar.Gender = sourceHumanoid.Gender; } Dirty(target, targetHumanoid); } /// /// Removes a marking from a humanoid by ID. /// /// Humanoid mob's UID /// The marking to try and remove. /// Whether to immediately sync this to the humanoid /// Humanoid component of the entity public void RemoveMarking(EntityUid uid, string marking, bool sync = true, HumanoidAppearanceComponent? humanoid = null) { if (!Resolve(uid, ref humanoid) || !_markingManager.Markings.TryGetValue(marking, out var prototype)) { return; } humanoid.MarkingSet.Remove(prototype.MarkingCategory, marking); if (sync) Dirty(uid, humanoid); } /// /// Removes a marking from a humanoid by category and index. /// /// Humanoid mob's UID /// Category of the marking /// Index of the marking /// Humanoid component of the entity public void RemoveMarking(EntityUid uid, MarkingCategories category, int index, HumanoidAppearanceComponent? humanoid = null) { if (index < 0 || !Resolve(uid, ref humanoid) || !humanoid.MarkingSet.TryGetCategory(category, out var markings) || index >= markings.Count) { return; } humanoid.MarkingSet.Remove(category, index); Dirty(uid, humanoid); } /// /// Sets the marking ID of the humanoid in a category at an index in the category's list. /// /// Humanoid mob's UID /// Category of the marking /// Index of the marking /// The marking ID to use /// Humanoid component of the entity public void SetMarkingId(EntityUid uid, MarkingCategories category, int index, string markingId, HumanoidAppearanceComponent? humanoid = null) { if (index < 0 || !_markingManager.MarkingsByCategory(category).TryGetValue(markingId, out var markingPrototype) || !Resolve(uid, ref humanoid) || !humanoid.MarkingSet.TryGetCategory(category, out var markings) || index >= markings.Count) { return; } var marking = markingPrototype.AsMarking(); for (var i = 0; i < marking.MarkingColors.Count && i < markings[index].MarkingColors.Count; i++) { marking.SetColor(i, markings[index].MarkingColors[i]); } humanoid.MarkingSet.Replace(category, index, marking); Dirty(uid, humanoid); } /// /// Sets the marking colors of the humanoid in a category at an index in the category's list. /// /// Humanoid mob's UID /// Category of the marking /// Index of the marking /// The marking colors to use /// Humanoid component of the entity public void SetMarkingColor(EntityUid uid, MarkingCategories category, int index, List colors, HumanoidAppearanceComponent? humanoid = null) { if (index < 0 || !Resolve(uid, ref humanoid) || !humanoid.MarkingSet.TryGetCategory(category, out var markings) || index >= markings.Count) { return; } for (var i = 0; i < markings[index].MarkingColors.Count && i < colors.Count; i++) { markings[index].SetColor(i, colors[i]); } Dirty(uid, humanoid); } }