mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 10:21:18 +03:00
Fix Dwarf Displacement Cloning (#45256)
* half working * leave this here * works! * damageable * fix * fix * no index * comment * move reserve down
This commit is contained in:
parent
3e05e1adbd
commit
b7182f5643
14 changed files with 193 additions and 60 deletions
|
|
@ -12,51 +12,63 @@ public sealed partial class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomal
|
|||
[Dependency] private DisplacementMapSystem _displacement = default!;
|
||||
|
||||
[Dependency] private EntityQuery<InnerBodyAnomalyVisualsComponent> _visualsQuery = default!;
|
||||
[Dependency] private EntityQuery<InnerBodyAnomalyComponent> _anomalyQuery = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<InnerBodyAnomalyComponent, AfterAutoHandleStateEvent>(OnAfterHandleState);
|
||||
SubscribeLocalEvent<InnerBodyAnomalyVisualsComponent, AfterAutoHandleStateEvent>(OnVisualsAfterHandleState);
|
||||
SubscribeLocalEvent<InnerBodyAnomalyComponent, ComponentShutdown>(OnCompShutdown);
|
||||
SubscribeLocalEvent<InnerBodyAnomalyVisualsComponent, ComponentShutdown>(OnVisualsShutdown);
|
||||
}
|
||||
|
||||
private void OnAfterHandleState(Entity<InnerBodyAnomalyComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
private void UpdateVisuals(Entity<InnerBodyAnomalyComponent, InnerBodyAnomalyVisualsComponent?> ent)
|
||||
{
|
||||
if (!TryComp<SpriteComponent>(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<HumanoidProfileComponent>(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<InnerBodyAnomalyComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
_visualsQuery.TryGetComponent(ent.Owner, out var visuals);
|
||||
UpdateVisuals((ent, ent.Comp, visuals));
|
||||
}
|
||||
|
||||
private void OnVisualsAfterHandleState(Entity<InnerBodyAnomalyVisualsComponent> ent, ref AfterAutoHandleStateEvent args)
|
||||
{
|
||||
if (_anomalyQuery.TryGetComponent(ent.Owner, out var anomaly))
|
||||
UpdateVisuals((ent.Owner, anomaly, ent.Comp));
|
||||
}
|
||||
|
||||
private void OnCompShutdown(Entity<InnerBodyAnomalyComponent> 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<InnerBodyAnomalyVisualsComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
if (!TryComp<SpriteComponent>(ent, out var sprite))
|
||||
return;
|
||||
|
||||
if (!TryComp<InnerBodyAnomalyComponent>(ent, out var anomaly))
|
||||
return;
|
||||
|
||||
var index = _sprite.LayerMapGet((ent.Owner, sprite), anomaly.LayerMap);
|
||||
|
||||
_displacement.EnsureDisplacementIsNotOnSprite((ent.Owner, sprite), anomaly.LayerMap);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<OrganComponent>(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<SpriteComponent>(target)), ent.Comp.Layer);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveVisual(Entity<VisualOrganComponent> ent, EntityUid target)
|
||||
|
|
@ -124,9 +132,9 @@ public sealed partial class VisualBodySystem : SharedVisualBodySystem
|
|||
ApplyVisual(ent, body);
|
||||
}
|
||||
|
||||
protected override void SetOrganMarkings(Entity<VisualOrganMarkingsComponent> ent, Dictionary<HumanoidVisualLayers, List<Marking>> markings)
|
||||
protected override void SetOrganMarkings(Entity<VisualOrganMarkingsComponent> ent, Dictionary<HumanoidVisualLayers, List<Marking>> markings, Dictionary<HumanoidVisualLayers, DisplacementData> displacement)
|
||||
{
|
||||
base.SetOrganMarkings(ent, markings);
|
||||
base.SetOrganMarkings(ent, markings, displacement);
|
||||
|
||||
if (Comp<OrganComponent>(ent).Body is not { } body)
|
||||
return;
|
||||
|
|
@ -135,9 +143,9 @@ public sealed partial class VisualBodySystem : SharedVisualBodySystem
|
|||
ApplyMarkings(ent, body);
|
||||
}
|
||||
|
||||
protected override void SetOrganAppearance(Entity<VisualOrganComponent> ent, PrototypeLayerData data)
|
||||
protected override void SetOrganAppearance(Entity<VisualOrganComponent> ent, PrototypeLayerData data, ProtoId<DisplacementDataPrototype>? displacement)
|
||||
{
|
||||
base.SetOrganAppearance(ent, data);
|
||||
base.SetOrganAppearance(ent, data, displacement);
|
||||
|
||||
if (Comp<OrganComponent>(ent).Body is not { } body)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ public sealed partial class DisplacementMapSystem : EntitySystem
|
|||
|
||||
//needs to be replaced later: see comment on line 48
|
||||
private static readonly ProtoId<ShaderPrototype> UnshadedID = "unshaded";
|
||||
public static readonly ProtoId<ShaderPrototype> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ public sealed partial class CreamPieSystem : SharedCreamPieSystem
|
|||
|
||||
private void OnComponentShutdown(Entity<CreamPiedComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
_sprite.RemoveLayer(ent.Owner, CreamPiedVisualLayer.Key);
|
||||
_displacement.EnsureDisplacementIsNotOnSprite((ent, Comp<SpriteComponent>(ent)), CreamPiedVisualLayer.Key);
|
||||
_sprite.RemoveLayer(ent.Owner, CreamPiedVisualLayer.Key);
|
||||
}
|
||||
|
||||
private void OnAppearanceChange(Entity<CreamPiedComponent> 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<bool>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -494,5 +494,26 @@ namespace Content.Server.Atmos.EntitySystems
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyComponent(Entity<FlammableComponent?> entity, EntityUid clone)
|
||||
{
|
||||
if (!Resolve(entity, ref entity.Comp, false))
|
||||
return;
|
||||
|
||||
// Don't clone being on fire here.
|
||||
var cloneComp = EnsureComp<FlammableComponent>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<MovementSpeedModifierComponent, CloningEvent>(OnCloneMovementSpeedModifier);
|
||||
SubscribeLocalEvent<PullerComponent, CloningEvent>(OnClonePuller);
|
||||
SubscribeLocalEvent<BloodstreamComponent, CloningEvent>(OnCloneBloodstream);
|
||||
SubscribeLocalEvent<CreamPiedComponent, CloningEvent>(OnCloneCreamPied);
|
||||
SubscribeLocalEvent<FlammableComponent, CloningEvent>(OnCloneFlammable);
|
||||
SubscribeLocalEvent<DamageableComponent, CloningEvent>(OnCloneDamageable);
|
||||
}
|
||||
|
||||
private void OnCloneItemStack(Entity<StackComponent> ent, ref CloningItemEvent args)
|
||||
|
|
@ -163,4 +174,28 @@ public sealed partial class CloningSystem
|
|||
|
||||
_bloodstream.CopyComponent(ent.AsNullable(), args.CloneUid);
|
||||
}
|
||||
|
||||
private void OnCloneCreamPied(Entity<CreamPiedComponent> 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<FlammableComponent> 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<DamageableComponent> ent, ref CloningEvent args)
|
||||
{
|
||||
if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name))
|
||||
return;
|
||||
|
||||
_damageable.CopyComponent(ent.AsNullable(), args.CloneUid);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ namespace Content.Shared.Anomaly.Components;
|
|||
/// <summary>
|
||||
/// Complementary visuals component to <see cref="InnerBodyAnomalyComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
|
||||
public sealed partial class InnerBodyAnomalyVisualsComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -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.
|
||||
/// </summary>
|
||||
[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.
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -84,28 +75,25 @@ namespace Content.Shared.Atmos.Components
|
|||
/// <summary>
|
||||
/// Should the component be set on fire by interactions with isHot entities
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool AlwaysCombustible = false;
|
||||
|
||||
/// <summary>
|
||||
/// Can the component anyhow lose its FireStacks?
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool CanExtinguish = true;
|
||||
|
||||
/// <summary>
|
||||
/// How many firestacks should be applied to component when being set on fire?
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
[DataField, AutoNetworkedField]
|
||||
public float FirestacksOnIgnite = 2.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Determines how quickly the object will fade out. With positive values, the object will flare up instead of going out.
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField, AutoNetworkedField]
|
||||
public float FirestackFade = -0.1f;
|
||||
|
||||
[DataField]
|
||||
|
|
@ -114,7 +102,7 @@ namespace Content.Shared.Atmos.Components
|
|||
/// <summary>
|
||||
/// If set, applies the displacement map associated with the <see cref="DisplacementDataPrototype"/>.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[DataField, AutoNetworkedField]
|
||||
public ProtoId<DisplacementDataPrototype>? Displacement;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<VisualOrganComponent> ent, PrototypeLayerData data)
|
||||
protected virtual void SetOrganAppearance(Entity<VisualOrganComponent> ent, PrototypeLayerData data, ProtoId<DisplacementDataPrototype>? displacement)
|
||||
{
|
||||
ent.Comp.Data = data;
|
||||
ent.Comp.Displacement = displacement;
|
||||
Dirty(ent);
|
||||
}
|
||||
|
||||
protected virtual void SetOrganMarkings(Entity<VisualOrganMarkingsComponent> ent, Dictionary<HumanoidVisualLayers, List<Marking>> markings)
|
||||
protected virtual void SetOrganMarkings(Entity<VisualOrganMarkingsComponent> ent, Dictionary<HumanoidVisualLayers, List<Marking>> markings, Dictionary<HumanoidVisualLayers, DisplacementData> 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<VisualOrganMarkingsComponent> ent, ref BodyRelayedEvent<OrganCopyAppearanceEvent> 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<VisualOrganComponent> ent, ref BodyRelayedEvent<ApplyOrganProfileDataEvent> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,9 +76,11 @@ public sealed partial class DamageableComponent : Component
|
|||
[Serializable, NetSerializable]
|
||||
public sealed class DamageableComponentState(
|
||||
DamageSpecifier damage,
|
||||
ProtoId<DamageModifierSetPrototype>? modifierSetId)
|
||||
ProtoId<DamageModifierSetPrototype>? modifierSetId,
|
||||
ProtoId<DisplacementDataPrototype>? displacement)
|
||||
: ComponentState
|
||||
{
|
||||
public readonly DamageSpecifier Damage = damage;
|
||||
public readonly ProtoId<DamageModifierSetPrototype>? ModifierSetId = modifierSetId;
|
||||
public readonly ProtoId<DisplacementDataPrototype>? Displacement = displacement;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -108,4 +108,17 @@ public sealed partial class DamageableSystem : EntitySystem
|
|||
}
|
||||
return damageTypes;
|
||||
}
|
||||
|
||||
public void CopyComponent(Entity<DamageableComponent?> entity, EntityUid clone)
|
||||
{
|
||||
if (!Resolve(entity, ref entity.Comp, false))
|
||||
return;
|
||||
|
||||
// Don't clone current damage values.
|
||||
var cloneComp = EnsureComp<DamageableComponent>(clone);
|
||||
cloneComp.Displacement = entity.Comp.Displacement;
|
||||
cloneComp.DamageModifierSetId = entity.Comp.DamageModifierSetId;
|
||||
cloneComp.RadiationDamageTypeIDs = new (entity.Comp.RadiationDamageTypeIDs);
|
||||
Dirty(clone, cloneComp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,4 +160,16 @@ public abstract partial class SharedCreamPieSystem : EntitySystem
|
|||
{
|
||||
ActivatePayload(ent);
|
||||
}
|
||||
|
||||
public void CopyComponent(Entity<CreamPiedComponent?> 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<CreamPiedComponent>(clone);
|
||||
cloneComp.Displacement = entity.Comp.Displacement;
|
||||
cloneComp.Sprite = entity.Comp.Sprite;
|
||||
Dirty(clone, cloneComp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue