Moves HumanoidAppearanceComponent to ECS (#4855)

* Moves HumanoidCharacterAppearance to ECS

* Makes HumanoidAppearanceSystem work over networks

* Makes HumanoidAppearanceSystem more efficient

* Cleans up the files

* Updates privacy on a couple of functions

* Fixes a few using references, renames a file

* Makes HumanoidAppearanceSystem more cleaner

* Fixes Magic Mirror

* Cleanup

* HumanoidAppearanceComponent now has a friend

SharedHumanoidAppearanceSystem is only allowed to act on this, now

* Fixes the Body-HumanoidAppearance ECS scaffolding

* a little cleanup never hurt anybody

* quick fix for magic mirror appearance access

* Replaces a networked event with a local one

This one was... causing bugs
This commit is contained in:
Flipp Syder
2021-10-16 15:28:02 -07:00
committed by GitHub
parent f69575e15a
commit 7dc6b95a10
17 changed files with 275 additions and 240 deletions

View File

@@ -1,85 +1,61 @@
using Content.Client.Cuffs.Components;
using Content.Shared.Body.Components;
using Content.Shared.Body.Part;
using Content.Shared.CharacterAppearance;
using Content.Shared.CharacterAppearance.Components;
using Content.Shared.CharacterAppearance.Systems;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Prototypes;
namespace Content.Client.CharacterAppearance
namespace Content.Client.CharacterAppearance.Systems
{
[RegisterComponent]
public sealed class HumanoidAppearanceComponent : SharedHumanoidAppearanceComponent, IBodyPartAdded, IBodyPartRemoved
public class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
{
[Dependency] private readonly SpriteAccessoryManager _accessoryManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
public override HumanoidCharacterAppearance Appearance
public override void Initialize()
{
get => base.Appearance;
set
{
base.Appearance = value;
UpdateLooks();
}
base.Initialize();
SubscribeLocalEvent<HumanoidAppearanceComponent, ChangedHumanoidAppearanceEvent>(UpdateLooks);
SubscribeLocalEvent<HumanoidAppearanceBodyPartAddedEvent>(BodyPartAdded);
SubscribeLocalEvent<HumanoidAppearanceBodyPartRemovedEvent>(BodyPartRemoved);
}
public override Sex Sex
private void UpdateLooks(EntityUid uid, HumanoidAppearanceComponent component, ChangedHumanoidAppearanceEvent args)
{
get => base.Sex;
set
{
base.Sex = value;
UpdateLooks();
}
}
protected override void Startup()
{
base.Startup();
UpdateLooks();
}
private void UpdateLooks()
{
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
if (Appearance == null ||
!Owner.TryGetComponent(out SpriteComponent? sprite))
{
if(!EntityManager.TryGetComponent(uid, out SpriteComponent? sprite))
return;
}
if (Owner.TryGetComponent(out SharedBodyComponent? body))
if (EntityManager.TryGetComponent(uid, out SharedBodyComponent? body))
{
foreach (var (part, _) in body.Parts)
{
if (!part.Owner.TryGetComponent(out SpriteComponent? partSprite))
if (part.Owner.TryGetComponent(out SpriteComponent? partSprite))
{
continue;
partSprite!.Color = component.Appearance.SkinColor;
}
partSprite.Color = Appearance.SkinColor;
}
}
sprite.LayerSetColor(HumanoidVisualLayers.Hair,
CanColorHair ? Appearance.HairColor : Color.White);
component.CanColorHair ? component.Appearance.HairColor : Color.White);
sprite.LayerSetColor(HumanoidVisualLayers.FacialHair,
CanColorFacialHair ? Appearance.FacialHairColor : Color.White);
component.CanColorFacialHair ? component.Appearance.FacialHairColor : Color.White);
sprite.LayerSetColor(HumanoidVisualLayers.Eyes, Appearance.EyeColor);
sprite.LayerSetColor(HumanoidVisualLayers.Eyes, component.Appearance.EyeColor);
sprite.LayerSetState(HumanoidVisualLayers.Chest, Sex == Sex.Male ? "torso_m" : "torso_f");
sprite.LayerSetState(HumanoidVisualLayers.Head, Sex == Sex.Male ? "head_m" : "head_f");
sprite.LayerSetState(HumanoidVisualLayers.Chest, component.Sex == Sex.Male ? "torso_m" : "torso_f");
sprite.LayerSetState(HumanoidVisualLayers.Head, component.Sex == Sex.Male ? "head_m" : "head_f");
if (sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out _))
sprite.LayerSetVisible(HumanoidVisualLayers.StencilMask, Sex == Sex.Female);
sprite.LayerSetVisible(HumanoidVisualLayers.StencilMask, component.Sex == Sex.Female);
if (Owner.TryGetComponent<CuffableComponent>(out var cuffed))
if (EntityManager.TryGetComponent<CuffableComponent>(uid, out var cuffed))
{
sprite.LayerSetVisible(HumanoidVisualLayers.Handcuffs, !cuffed.CanStillInteract);
}
@@ -88,16 +64,16 @@ namespace Content.Client.CharacterAppearance
sprite.LayerSetVisible(HumanoidVisualLayers.Handcuffs, false);
}
var hairStyle = Appearance.HairStyleId;
var hairStyle = component.Appearance.HairStyleId;
if (string.IsNullOrWhiteSpace(hairStyle) ||
!_accessoryManager.IsValidAccessoryInCategory(hairStyle, CategoriesHair))
!_accessoryManager.IsValidAccessoryInCategory(hairStyle, component.CategoriesHair))
{
hairStyle = HairStyles.DefaultHairStyle;
}
var facialHairStyle = Appearance.FacialHairStyleId;
var facialHairStyle = component.Appearance.FacialHairStyleId;
if (string.IsNullOrWhiteSpace(facialHairStyle) ||
!_accessoryManager.IsValidAccessoryInCategory(facialHairStyle, CategoriesFacialHair))
!_accessoryManager.IsValidAccessoryInCategory(facialHairStyle, component.CategoriesFacialHair))
{
facialHairStyle = HairStyles.DefaultFacialHairStyle;
}
@@ -109,37 +85,40 @@ namespace Content.Client.CharacterAppearance
sprite.LayerSetSprite(HumanoidVisualLayers.FacialHair, facialHairPrototype.Sprite);
}
public void BodyPartAdded(BodyPartAddedEventArgs args)
// Scaffolding until Body is moved to ECS.
private void BodyPartAdded(HumanoidAppearanceBodyPartAddedEvent args)
{
if (!Owner.TryGetComponent(out SpriteComponent? sprite))
if(!EntityManager.TryGetEntity(args.Uid, out var owner)) return;
if (!owner.TryGetComponent(out SpriteComponent? sprite))
{
return;
}
if (!args.Part.Owner.HasComponent<SpriteComponent>())
if (!args.Args.Part.Owner.HasComponent<SpriteComponent>())
{
return;
}
var layers = args.Part.ToHumanoidLayers();
var layers = args.Args.Part.ToHumanoidLayers();
// TODO BODY Layer color, sprite and state
foreach (var layer in layers)
sprite.LayerSetVisible(layer, true);
}
public void BodyPartRemoved(BodyPartRemovedEventArgs args)
private void BodyPartRemoved(HumanoidAppearanceBodyPartRemovedEvent args)
{
if (!Owner.TryGetComponent(out SpriteComponent? sprite))
if(!EntityManager.TryGetEntity(args.Uid, out var owner)) return;
if (!owner.TryGetComponent(out SpriteComponent? sprite))
{
return;
}
if (!args.Part.Owner.HasComponent<SpriteComponent>())
if (!args.Args.Part.Owner.HasComponent<SpriteComponent>())
{
return;
}
var layers = args.Part.ToHumanoidLayers();
var layers = args.Args.Part.ToHumanoidLayers();
// TODO BODY Layer color, sprite and state
foreach (var layer in layers)
sprite.LayerSetVisible(layer, false);