diff --git a/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs b/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs index 173aca24bf..5edbda7fd1 100644 --- a/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs +++ b/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs @@ -12,51 +12,63 @@ public sealed partial class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomal [Dependency] private DisplacementMapSystem _displacement = default!; [Dependency] private EntityQuery _visualsQuery = default!; + [Dependency] private EntityQuery _anomalyQuery = default!; public override void Initialize() { SubscribeLocalEvent(OnAfterHandleState); + SubscribeLocalEvent(OnVisualsAfterHandleState); SubscribeLocalEvent(OnCompShutdown); + SubscribeLocalEvent(OnVisualsShutdown); } - private void OnAfterHandleState(Entity ent, ref AfterAutoHandleStateEvent args) + private void UpdateVisuals(Entity ent) { if (!TryComp(ent, out var sprite)) return; - if (ent.Comp.FallbackSprite is null) + if (ent.Comp1.FallbackSprite is null) return; - var index = _sprite.LayerMapReserve((ent.Owner, sprite), ent.Comp.LayerMap); + var index = _sprite.LayerMapReserve((ent.Owner, sprite), ent.Comp1.LayerMap); if (TryComp(ent, out var humanoid) && - ent.Comp.SpeciesSprites.TryGetValue(humanoid.Species, out var speciesSprite)) + ent.Comp1.SpeciesSprites.TryGetValue(humanoid.Species, out var speciesSprite)) { _sprite.LayerSetSprite((ent.Owner, sprite), index, speciesSprite); } else { - _sprite.LayerSetSprite((ent.Owner, sprite), index, ent.Comp.FallbackSprite); + _sprite.LayerSetSprite((ent.Owner, sprite), index, ent.Comp1.FallbackSprite); } _sprite.LayerSetVisible((ent.Owner, sprite), index, true); sprite.LayerSetShader(index, "unshaded"); - if (_visualsQuery.TryGetComponent(ent, out var visuals) && visuals.Displacement != null) + if (ent.Comp2 != null && ent.Comp2.Displacement != null && ProtoMan.Resolve(ent.Comp2.Displacement, out var displacement)) { - if (ProtoMan.Resolve(visuals.Displacement, out var displacement)) - { - _displacement.TryAddDisplacement(displacement.Displacement, - (ent.Owner, sprite), - index, - ent.Comp.LayerMap, - out _); - } - else - { - _displacement.EnsureDisplacementIsNotOnSprite((ent.Owner, sprite), ent.Comp.LayerMap); - } + _displacement.TryAddDisplacement(displacement.Displacement, + (ent.Owner, sprite), + index, + ent.Comp1.LayerMap, + out _); } + else + { + _displacement.EnsureDisplacementIsNotOnSprite((ent.Owner, sprite), ent.Comp1.LayerMap); + } + } + + private void OnAfterHandleState(Entity ent, ref AfterAutoHandleStateEvent args) + { + _visualsQuery.TryGetComponent(ent.Owner, out var visuals); + UpdateVisuals((ent, ent.Comp, visuals)); + } + + private void OnVisualsAfterHandleState(Entity ent, ref AfterAutoHandleStateEvent args) + { + if (_anomalyQuery.TryGetComponent(ent.Owner, out var anomaly)) + UpdateVisuals((ent.Owner, anomaly, ent.Comp)); } private void OnCompShutdown(Entity ent, ref ComponentShutdown args) @@ -69,4 +81,17 @@ public sealed partial class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomal _displacement.EnsureDisplacementIsNotOnSprite((ent.Owner, sprite), ent.Comp.LayerMap); } + + private void OnVisualsShutdown(Entity ent, ref ComponentShutdown args) + { + if (!TryComp(ent, out var sprite)) + return; + + if (!TryComp(ent, out var anomaly)) + return; + + var index = _sprite.LayerMapGet((ent.Owner, sprite), anomaly.LayerMap); + + _displacement.EnsureDisplacementIsNotOnSprite((ent.Owner, sprite), anomaly.LayerMap); + } } diff --git a/Content.Client/Body/VisualBodySystem.cs b/Content.Client/Body/VisualBodySystem.cs index 76ae0eb56d..b1e29a2521 100644 --- a/Content.Client/Body/VisualBodySystem.cs +++ b/Content.Client/Body/VisualBodySystem.cs @@ -2,11 +2,13 @@ using System.Linq; using Content.Client.DisplacementMap; using Content.Shared.Body; using Content.Shared.CCVar; +using Content.Shared.DisplacementMap; using Content.Shared.Humanoid.Markings; using Content.Shared.Humanoid; using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Shared.Configuration; +using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Content.Client.Body; @@ -64,6 +66,7 @@ public sealed partial class VisualBodySystem : SharedVisualBodySystem if (Comp(ent).Body is not { } body) return; + RemoveVisual(ent, body); ApplyVisual(ent, body); } @@ -83,6 +86,11 @@ public sealed partial class VisualBodySystem : SharedVisualBodySystem ent.Comp.Layer, out _); } + + if (displacement == null) + { + _displacement.EnsureDisplacementIsNotOnSprite((target, Comp(target)), ent.Comp.Layer); + } } private void RemoveVisual(Entity ent, EntityUid target) @@ -124,9 +132,9 @@ public sealed partial class VisualBodySystem : SharedVisualBodySystem ApplyVisual(ent, body); } - protected override void SetOrganMarkings(Entity ent, Dictionary> markings) + protected override void SetOrganMarkings(Entity ent, Dictionary> markings, Dictionary displacement) { - base.SetOrganMarkings(ent, markings); + base.SetOrganMarkings(ent, markings, displacement); if (Comp(ent).Body is not { } body) return; @@ -135,9 +143,9 @@ public sealed partial class VisualBodySystem : SharedVisualBodySystem ApplyMarkings(ent, body); } - protected override void SetOrganAppearance(Entity ent, PrototypeLayerData data) + protected override void SetOrganAppearance(Entity ent, PrototypeLayerData data, ProtoId? displacement) { - base.SetOrganAppearance(ent, data); + base.SetOrganAppearance(ent, data, displacement); if (Comp(ent).Body is not { } body) return; diff --git a/Content.Client/DisplacementMap/DisplacementMapSystem.cs b/Content.Client/DisplacementMap/DisplacementMapSystem.cs index 738bf690cd..19a99fa510 100644 --- a/Content.Client/DisplacementMap/DisplacementMapSystem.cs +++ b/Content.Client/DisplacementMap/DisplacementMapSystem.cs @@ -14,6 +14,7 @@ public sealed partial class DisplacementMapSystem : EntitySystem //needs to be replaced later: see comment on line 48 private static readonly ProtoId UnshadedID = "unshaded"; + public static readonly ProtoId DisplacedUnshaded = "DisplacedDrawUnshaded"; private static string? BuildDisplacementLayerKey(object key) { @@ -126,6 +127,23 @@ public sealed partial class DisplacementMapSystem : EntitySystem if (displacementLayerKey is null) return false; - return _sprite.RemoveLayer(sprite.AsNullable(), displacementLayerKey, false); + if (_sprite.RemoveLayer(sprite.AsNullable(), displacementLayerKey, false)) + { + //TODO : this is a kinda janky workaround for the fact that the current rendering pipeline does not have + //proper support for multiple shaders on a given layer (or an ubershader to handle stacking all of the effects well) + //Same reason as where the displacement is added initially + var shader = sprite.Comp[key] is SpriteComponent.Layer layer && layer.ShaderPrototype == DisplacedUnshaded + ? SpriteSystem.UnshadedId.Id + : null; + + if (shader != null) + sprite.Comp.LayerSetShader(key, shader); + else + sprite.Comp.LayerSetShader(key, null, null); + + return true; + } + + return false; } } diff --git a/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs b/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs index 2d03abc843..449293b14c 100644 --- a/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs +++ b/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs @@ -29,8 +29,8 @@ public sealed partial class CreamPieSystem : SharedCreamPieSystem private void OnComponentShutdown(Entity ent, ref ComponentShutdown args) { - _sprite.RemoveLayer(ent.Owner, CreamPiedVisualLayer.Key); _displacement.EnsureDisplacementIsNotOnSprite((ent, Comp(ent)), CreamPiedVisualLayer.Key); + _sprite.RemoveLayer(ent.Owner, CreamPiedVisualLayer.Key); } private void OnAppearanceChange(Entity ent, ref AppearanceChangeEvent args) @@ -54,7 +54,6 @@ public sealed partial class CreamPieSystem : SharedCreamPieSystem var appearance = ent.Comp3; // If there is no sprite to use, remove the layer. Otherwise ensure that it exists and set the visuals accordingly. - int index; if (creamPied.Sprite == null) { _sprite.RemoveLayer((ent.Owner, sprite), CreamPiedVisualLayer.Key); @@ -62,7 +61,7 @@ public sealed partial class CreamPieSystem : SharedCreamPieSystem return; } - index = _sprite.LayerMapReserve((ent.Owner, sprite), CreamPiedVisualLayer.Key); + int index = _sprite.LayerMapReserve((ent.Owner, sprite), CreamPiedVisualLayer.Key); _appearance.TryGetData(ent.Owner, CreamPiedVisuals.Creamed, out var isCreamPied, appearance); _sprite.LayerSetSprite((ent.Owner, sprite), index, creamPied.Sprite); @@ -72,5 +71,9 @@ public sealed partial class CreamPieSystem : SharedCreamPieSystem { _displacement.TryAddDisplacement(displacementProto.Displacement, (ent.Owner, sprite), index, CreamPiedVisualLayer.Key, out _); } + else + { + _displacement.EnsureDisplacementIsNotOnSprite((ent.Owner, sprite), CreamPiedVisualLayer.Key); + } } } diff --git a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs index 82af75fddc..0494a3ba73 100644 --- a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs +++ b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs @@ -494,5 +494,26 @@ namespace Content.Server.Atmos.EntitySystems } } } + + public void CopyComponent(Entity entity, EntityUid clone) + { + if (!Resolve(entity, ref entity.Comp, false)) + return; + + // Don't clone being on fire here. + var cloneComp = EnsureComp(clone); + cloneComp.Displacement = entity.Comp.Displacement; + cloneComp.AlwaysCombustible = entity.Comp.AlwaysCombustible; + cloneComp.CanExtinguish = entity.Comp.CanExtinguish; + cloneComp.Damage = entity.Comp.Damage.Clone(); + cloneComp.FirestackFade = entity.Comp.FirestackFade; + cloneComp.FirestacksOnIgnite = entity.Comp.FirestacksOnIgnite; + cloneComp.MaximumFireStacks = entity.Comp.MaximumFireStacks; + cloneComp.MinimumFireStacks = entity.Comp.MinimumFireStacks; + cloneComp.ResistTime = entity.Comp.ResistTime; + Dirty(clone, cloneComp); + + UpdateAppearance(clone, cloneComp); + } } } diff --git a/Content.Server/Cloning/CloningSystem.Subscriptions.cs b/Content.Server/Cloning/CloningSystem.Subscriptions.cs index 5f73649759..cd874e6450 100644 --- a/Content.Server/Cloning/CloningSystem.Subscriptions.cs +++ b/Content.Server/Cloning/CloningSystem.Subscriptions.cs @@ -1,9 +1,12 @@ using Content.Shared.Body.Components; +using Content.Server.Atmos.EntitySystems; +using Content.Shared.Atmos.Components; using Content.Shared.Body.Systems; -using Content.Server.Speech.EntitySystems; using Content.Shared.Cloning.Events; using Content.Shared.Clothing.Components; using Content.Shared.Clothing.EntitySystems; +using Content.Shared.Damage.Components; +using Content.Shared.Damage.Systems; using Content.Shared.FixedPoint; using Content.Shared.Forensics.Components; using Content.Shared.Forensics.Systems; @@ -14,6 +17,8 @@ using Content.Shared.Movement.Components; using Content.Shared.Movement.Pulling.Components; using Content.Shared.Movement.Pulling.Systems; using Content.Shared.Movement.Systems; +using Content.Shared.Nutrition.Components; +using Content.Shared.Nutrition.EntitySystems; using Content.Shared.Paper; using Content.Shared.Speech.Components; using Content.Shared.Speech.EntitySystems; @@ -42,7 +47,10 @@ public sealed partial class CloningSystem [Dependency] private SharedChameleonClothingSystem _chameleonClothing = default!; [Dependency] private PullingSystem _pulling = default!; [Dependency] private BloodstreamSystem _bloodstream = default!; + [Dependency] private SharedCreamPieSystem _creampie = default!; [Dependency] private ForensicsSystem _forensics = default!; + [Dependency] private FlammableSystem _flammable = default!; + [Dependency] private DamageableSystem _damageable = default!; public override void Initialize() { @@ -68,6 +76,9 @@ public sealed partial class CloningSystem SubscribeLocalEvent(OnCloneMovementSpeedModifier); SubscribeLocalEvent(OnClonePuller); SubscribeLocalEvent(OnCloneBloodstream); + SubscribeLocalEvent(OnCloneCreamPied); + SubscribeLocalEvent(OnCloneFlammable); + SubscribeLocalEvent(OnCloneDamageable); } private void OnCloneItemStack(Entity ent, ref CloningItemEvent args) @@ -163,4 +174,28 @@ public sealed partial class CloningSystem _bloodstream.CopyComponent(ent.AsNullable(), args.CloneUid); } + + private void OnCloneCreamPied(Entity ent, ref CloningEvent args) + { + if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name)) + return; + + _creampie.CopyComponent(ent.AsNullable(), args.CloneUid); + } + + private void OnCloneFlammable(Entity ent, ref CloningEvent args) + { + if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name)) + return; + + _flammable.CopyComponent(ent.AsNullable(), args.CloneUid); + } + + private void OnCloneDamageable(Entity ent, ref CloningEvent args) + { + if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name)) + return; + + _damageable.CopyComponent(ent.AsNullable(), args.CloneUid); + } } diff --git a/Content.Shared/Anomaly/Components/InnerBodyAnomalyVisualsComponent.cs b/Content.Shared/Anomaly/Components/InnerBodyAnomalyVisualsComponent.cs index 5298bce4f7..425324b46a 100644 --- a/Content.Shared/Anomaly/Components/InnerBodyAnomalyVisualsComponent.cs +++ b/Content.Shared/Anomaly/Components/InnerBodyAnomalyVisualsComponent.cs @@ -7,7 +7,7 @@ namespace Content.Shared.Anomaly.Components; /// /// Complementary visuals component to . /// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)] public sealed partial class InnerBodyAnomalyVisualsComponent : Component { /// diff --git a/Content.Shared/Atmos/Components/FlammableComponent.cs b/Content.Shared/Atmos/Components/FlammableComponent.cs index 7bf9b4363a..d8dda784fb 100644 --- a/Content.Shared/Atmos/Components/FlammableComponent.cs +++ b/Content.Shared/Atmos/Components/FlammableComponent.cs @@ -8,7 +8,7 @@ using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.Atmos.Components { - [RegisterComponent, NetworkedComponent, AutoGenerateComponentPause] // TODO: Access restriction so that other systems have to use the API to modify fire stacks + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause] // TODO: Access restriction so that other systems have to use the API to modify fire stacks public sealed partial class FlammableComponent : Component { /// @@ -36,43 +36,34 @@ namespace Content.Shared.Atmos.Components /// The time resisting being on fire will take. /// The mob will be paralyzed for this duration. /// - [DataField] + [DataField, AutoNetworkedField] public TimeSpan ResistTime = TimeSpan.FromSeconds(2); - [ViewVariables(VVAccess.ReadWrite)] [DataField] public bool OnFire; - [ViewVariables(VVAccess.ReadWrite)] [DataField] public float FireStacks; - [ViewVariables(VVAccess.ReadWrite)] - [DataField] + [DataField, AutoNetworkedField] public float MaximumFireStacks = 10f; - [ViewVariables(VVAccess.ReadWrite)] - [DataField] + [DataField, AutoNetworkedField] public float MinimumFireStacks = -10f; - [ViewVariables(VVAccess.ReadWrite)] [DataField] public string FlammableFixtureID = "flammable"; - [ViewVariables(VVAccess.ReadWrite)] - [DataField] + [DataField, AutoNetworkedField] public float MinIgnitionTemperature = 373.15f; - [ViewVariables(VVAccess.ReadWrite)] [DataField] public bool FireSpread { get; private set; } = false; - [ViewVariables(VVAccess.ReadWrite)] [DataField] public bool CanResistFire { get; private set; } = false; - [DataField(required: true)] - [ViewVariables(VVAccess.ReadWrite)] + [DataField(required: true), AutoNetworkedField] public DamageSpecifier Damage = new(); // Empty by default, we don't want any funny NREs. /// @@ -84,28 +75,25 @@ namespace Content.Shared.Atmos.Components /// /// Should the component be set on fire by interactions with isHot entities /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField] + [DataField, AutoNetworkedField] public bool AlwaysCombustible = false; /// /// Can the component anyhow lose its FireStacks? /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField] + [DataField, AutoNetworkedField] public bool CanExtinguish = true; /// /// How many firestacks should be applied to component when being set on fire? /// - [ViewVariables(VVAccess.ReadWrite)] - [DataField] + [DataField, AutoNetworkedField] public float FirestacksOnIgnite = 2.0f; /// /// Determines how quickly the object will fade out. With positive values, the object will flare up instead of going out. /// - [DataField, ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField] public float FirestackFade = -0.1f; [DataField] @@ -114,7 +102,7 @@ namespace Content.Shared.Atmos.Components /// /// If set, applies the displacement map associated with the . /// - [DataField] + [DataField, AutoNetworkedField] public ProtoId? Displacement; } } diff --git a/Content.Shared/Body/SharedVisualBodySystem.cs b/Content.Shared/Body/SharedVisualBodySystem.cs index 17b55522c9..41f2d39ec7 100644 --- a/Content.Shared/Body/SharedVisualBodySystem.cs +++ b/Content.Shared/Body/SharedVisualBodySystem.cs @@ -1,4 +1,5 @@ using System.Linq; +using Content.Shared.DisplacementMap; using Content.Shared.Humanoid.Markings; using Content.Shared.Humanoid; using Robust.Shared.Containers; @@ -74,15 +75,17 @@ public abstract partial class SharedVisualBodySystem : EntitySystem Dirty(ent); } - protected virtual void SetOrganAppearance(Entity ent, PrototypeLayerData data) + protected virtual void SetOrganAppearance(Entity ent, PrototypeLayerData data, ProtoId? displacement) { ent.Comp.Data = data; + ent.Comp.Displacement = displacement; Dirty(ent); } - protected virtual void SetOrganMarkings(Entity ent, Dictionary> markings) + protected virtual void SetOrganMarkings(Entity ent, Dictionary> markings, Dictionary displacement) { ent.Comp.Markings = markings; + ent.Comp.MarkingsDisplacement = displacement.ShallowClone(); Dirty(ent); } @@ -94,7 +97,7 @@ public abstract partial class SharedVisualBodySystem : EntitySystem if (!other.Layer.Equals(ent.Comp.Layer)) return; - SetOrganAppearance(ent, other.Data); + SetOrganAppearance(ent, other.Data, other.Displacement); } private void OnMarkingsOrganCopyAppearance(Entity ent, ref BodyRelayedEvent args) @@ -105,7 +108,7 @@ public abstract partial class SharedVisualBodySystem : EntitySystem if (!other.MarkingData.Layers.SetEquals(ent.Comp.MarkingData.Layers)) return; - SetOrganMarkings(ent, other.Markings); + SetOrganMarkings(ent, other.Markings, other.MarkingsDisplacement); } private void OnVisualOrganApplyProfile(Entity ent, ref BodyRelayedEvent args) @@ -130,7 +133,7 @@ public abstract partial class SharedVisualBodySystem : EntitySystem if (ent.Comp.SexStateOverrides is { } overrides && overrides.TryGetValue(data.Sex, out var state)) { ent.Comp.Data.State = state; - SetOrganAppearance(ent, ent.Comp.Data); + SetOrganAppearance(ent, ent.Comp.Data, ent.Comp.Displacement); } } @@ -168,7 +171,7 @@ public abstract partial class SharedVisualBodySystem : EntitySystem kvp => kvp.Key, kvp => ResolveMarkings(kvp.Value, profile.SkinColor, profile.EyeColor, groupProto.Appearances)); - SetOrganMarkings(ent, resolved); + SetOrganMarkings(ent, resolved, ent.Comp.MarkingsDisplacement); } } diff --git a/Content.Shared/Damage/Components/DamageableComponent.cs b/Content.Shared/Damage/Components/DamageableComponent.cs index aa395a4460..caf27ab4f2 100644 --- a/Content.Shared/Damage/Components/DamageableComponent.cs +++ b/Content.Shared/Damage/Components/DamageableComponent.cs @@ -76,9 +76,11 @@ public sealed partial class DamageableComponent : Component [Serializable, NetSerializable] public sealed class DamageableComponentState( DamageSpecifier damage, - ProtoId? modifierSetId) + ProtoId? modifierSetId, + ProtoId? displacement) : ComponentState { public readonly DamageSpecifier Damage = damage; public readonly ProtoId? ModifierSetId = modifierSetId; + public readonly ProtoId? Displacement = displacement; } diff --git a/Content.Shared/Damage/Systems/DamageableSystem.Events.cs b/Content.Shared/Damage/Systems/DamageableSystem.Events.cs index d7650711ec..929134deb7 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.Events.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.Events.cs @@ -189,7 +189,8 @@ public sealed partial class DamageableSystem { args.State = new DamageableComponentState( _netMan.IsServer ? ent.Comp.Damage : ent.Comp.Damage.Clone(), - ent.Comp.DamageModifierSetId + ent.Comp.DamageModifierSetId, + ent.Comp.Displacement ); } @@ -199,6 +200,7 @@ public sealed partial class DamageableSystem return; ent.Comp.DamageModifierSetId = state.ModifierSetId; + ent.Comp.Displacement = state.Displacement; // Has the damage actually changed? var newDamage = state.Damage.Clone(); diff --git a/Content.Shared/Damage/Systems/DamageableSystem.cs b/Content.Shared/Damage/Systems/DamageableSystem.cs index 5c7a8a73cb..134382b829 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.cs @@ -108,4 +108,17 @@ public sealed partial class DamageableSystem : EntitySystem } return damageTypes; } + + public void CopyComponent(Entity entity, EntityUid clone) + { + if (!Resolve(entity, ref entity.Comp, false)) + return; + + // Don't clone current damage values. + var cloneComp = EnsureComp(clone); + cloneComp.Displacement = entity.Comp.Displacement; + cloneComp.DamageModifierSetId = entity.Comp.DamageModifierSetId; + cloneComp.RadiationDamageTypeIDs = new (entity.Comp.RadiationDamageTypeIDs); + Dirty(clone, cloneComp); + } } diff --git a/Content.Shared/Nutrition/EntitySystems/SharedCreamPieSystem.cs b/Content.Shared/Nutrition/EntitySystems/SharedCreamPieSystem.cs index d87cd5959b..46a436eb7b 100644 --- a/Content.Shared/Nutrition/EntitySystems/SharedCreamPieSystem.cs +++ b/Content.Shared/Nutrition/EntitySystems/SharedCreamPieSystem.cs @@ -160,4 +160,16 @@ public abstract partial class SharedCreamPieSystem : EntitySystem { ActivatePayload(ent); } + + public void CopyComponent(Entity entity, EntityUid clone) + { + if (!Resolve(entity, ref entity.Comp, false)) + return; + + // We don't clone whether you are actively creampied on purpose. + var cloneComp = EnsureComp(clone); + cloneComp.Displacement = entity.Comp.Displacement; + cloneComp.Sprite = entity.Comp.Sprite; + Dirty(clone, cloneComp); + } } diff --git a/Resources/Prototypes/Entities/Mobs/Player/clone.yml b/Resources/Prototypes/Entities/Mobs/Player/clone.yml index 11ba6c28cd..1aad74a123 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/clone.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/clone.yml @@ -33,12 +33,12 @@ id: Body components: # general - - CreamPied - DetailExaminable - Dna - Fingerprint - Grammar # Pronouns - HumanoidProfile # Age, Sex, Gender + - InnerBodyAnomalyVisuals # How you look with anomalies - MeleeWeapon # Attack animation, damage and sound - NpcFactionMember - RandomPrice @@ -73,6 +73,9 @@ - SpanishAccent - StutteringAccent eventComponents: + - Damageable # Sprites and damage modifier + - Flammable # Displacements + - CreamPied # Displacements - Hands # displacements - Puller - Vocal # voice sounds