diff --git a/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs b/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs index 6d48254c19..173aca24bf 100644 --- a/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs +++ b/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs @@ -1,3 +1,4 @@ +using Content.Client.DisplacementMap; using Content.Shared.Anomaly.Components; using Content.Shared.Anomaly.Effects; using Content.Shared.Humanoid; @@ -8,6 +9,9 @@ namespace Content.Client.Anomaly.Effects; public sealed partial class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem { [Dependency] private SpriteSystem _sprite = default!; + [Dependency] private DisplacementMapSystem _displacement = default!; + + [Dependency] private EntityQuery _visualsQuery = default!; public override void Initialize() { @@ -37,6 +41,22 @@ public sealed partial class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomal _sprite.LayerSetVisible((ent.Owner, sprite), index, true); sprite.LayerSetShader(index, "unshaded"); + + if (_visualsQuery.TryGetComponent(ent, out var visuals) && visuals.Displacement != null) + { + 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); + } + } } private void OnCompShutdown(Entity ent, ref ComponentShutdown args) @@ -46,5 +66,7 @@ public sealed partial class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomal var index = _sprite.LayerMapGet((ent.Owner, sprite), ent.Comp.LayerMap); _sprite.LayerSetVisible((ent.Owner, sprite), index, false); + + _displacement.EnsureDisplacementIsNotOnSprite((ent.Owner, sprite), ent.Comp.LayerMap); } } diff --git a/Content.Client/Atmos/Components/FireVisualsComponent.cs b/Content.Client/Atmos/Components/FireVisualsComponent.cs index 02278e9479..ac7a78edcf 100644 --- a/Content.Client/Atmos/Components/FireVisualsComponent.cs +++ b/Content.Client/Atmos/Components/FireVisualsComponent.cs @@ -1,3 +1,6 @@ +using Content.Shared.DisplacementMap; +using Robust.Shared.Prototypes; + namespace Content.Client.Atmos.Components; /// @@ -39,4 +42,10 @@ public sealed partial class FireVisualsComponent : Component /// the burning entity as entities don't support having multiple point-lights. /// public EntityUid? LightEntity; + + /// + /// Tracks the currently applied displacement, so that only new changes update the layer. + /// + [DataField] + public ProtoId? CurrentDisplacement; } diff --git a/Content.Client/Atmos/EntitySystems/FireVisualizerSystem.cs b/Content.Client/Atmos/EntitySystems/FireVisualizerSystem.cs index ec4500935c..f308e0da03 100644 --- a/Content.Client/Atmos/EntitySystems/FireVisualizerSystem.cs +++ b/Content.Client/Atmos/EntitySystems/FireVisualizerSystem.cs @@ -1,5 +1,7 @@ using Content.Client.Atmos.Components; +using Content.Client.DisplacementMap; using Content.Shared.Atmos; +using Content.Shared.DisplacementMap; using Robust.Client.GameObjects; using Robust.Shared.Map; using Robust.Shared.Utility; @@ -12,6 +14,7 @@ namespace Content.Client.Atmos.EntitySystems; public sealed partial class FireVisualizerSystem : VisualizerSystem { [Dependency] private PointLightSystem _lights = default!; + [Dependency] private DisplacementMapSystem _displacement = default!; public override void Initialize() { @@ -65,6 +68,7 @@ public sealed partial class FireVisualizerSystem : VisualizerSystem(uid, FireVisuals.OnFire, out var onFire, appearance); AppearanceSystem.TryGetData(uid, FireVisuals.FireStacks, out var fireStacks, appearance); + AppearanceSystem.TryGetData(uid, FireVisuals.FireDisplacement, out var fireDisplacement, appearance); SpriteSystem.LayerSetVisible((uid, sprite), index, onFire); if (!onFire) @@ -83,6 +87,16 @@ public sealed partial class FireVisualizerSystem : VisualizerSystem(fireDisplacement, out var displacementProto)) + _displacement.TryAddDisplacement(displacementProto.Displacement, (uid, sprite), index, FireVisualLayers.Fire, out _); + else + _displacement.EnsureDisplacementIsNotOnSprite((uid, sprite), FireVisualLayers.Fire); + + component.CurrentDisplacement = fireDisplacement; + } + component.LightEntity ??= Spawn(null, new EntityCoordinates(uid, default)); var light = EnsureComp(component.LightEntity.Value); diff --git a/Content.Client/Body/VisualBodySystem.cs b/Content.Client/Body/VisualBodySystem.cs index c29a60cc97..cf2cbd0c49 100644 --- a/Content.Client/Body/VisualBodySystem.cs +++ b/Content.Client/Body/VisualBodySystem.cs @@ -2,6 +2,7 @@ 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; @@ -73,6 +74,16 @@ public sealed partial class VisualBodySystem : SharedVisualBodySystem return; _sprite.LayerSetData(target, index, ent.Comp.Data); + + var displacement = ent.Comp.Displacement; + if (displacement != null && ProtoMan.Resolve(displacement, out var displacementProto)) + { + _displacement.TryAddDisplacement(displacementProto.Displacement, + (target, Comp(target)), + index, + ent.Comp.Layer, + out _); + } } private void RemoveVisual(Entity ent, EntityUid target) @@ -81,6 +92,8 @@ public sealed partial class VisualBodySystem : SharedVisualBodySystem return; _sprite.LayerSetRsiState(target, index, RSI.StateId.Invalid); + + _displacement.EnsureDisplacementIsNotOnSprite((target, Comp(target)), ent.Comp.Layer); } private void OnMarkingsGotInserted(Entity ent, ref OrganGotInsertedEvent args) diff --git a/Content.Client/Damage/DamageVisualsComponent.cs b/Content.Client/Damage/DamageVisualsComponent.cs index 26356496bb..a092e30337 100644 --- a/Content.Client/Damage/DamageVisualsComponent.cs +++ b/Content.Client/Damage/DamageVisualsComponent.cs @@ -1,4 +1,6 @@ +using Content.Shared.Damage.Components; using Content.Shared.Damage.Prototypes; +using Content.Shared.DisplacementMap; using Content.Shared.FixedPoint; using Robust.Shared.Prototypes; @@ -117,6 +119,13 @@ public sealed partial class DamageVisualsComponent : Component /// [DataField("damageOverlay")] public DamageVisualizerSprite? DamageOverlay; + /// + /// Applies a displacement map to the damage visuals. + /// Is set via . + /// + [DataField] + public DisplacementData? Displacement; + public readonly List TargetLayerMapKeys = new(); public bool Disabled = false; public bool Valid = true; diff --git a/Content.Client/Damage/DamageVisualsSystem.cs b/Content.Client/Damage/DamageVisualsSystem.cs index b374831059..13ff8a0137 100644 --- a/Content.Client/Damage/DamageVisualsSystem.cs +++ b/Content.Client/Damage/DamageVisualsSystem.cs @@ -1,8 +1,10 @@ using System.Linq; +using Content.Client.DisplacementMap; using Content.Shared.Damage; using Content.Shared.Damage.Components; using Content.Shared.Damage.Prototypes; using Content.Shared.Damage.Systems; +using Content.Shared.DisplacementMap; using Content.Shared.FixedPoint; using Robust.Client.GameObjects; using Robust.Shared.Prototypes; @@ -29,6 +31,7 @@ namespace Content.Client.Damage; public sealed partial class DamageVisualsSystem : VisualizerSystem { [Dependency] private DamageableSystem _damageable = default!; + [Dependency] private DisplacementMapSystem _displacement = default!; public override void Initialize() { @@ -326,10 +329,14 @@ public sealed partial class DamageVisualsSystem : VisualizerSystem private void AddDamageLayerToSprite(Entity spriteEnt, DamageVisualizerSprite sprite, string state, string mapKey, int? index = null) { + if (!Resolve(spriteEnt, ref spriteEnt.Comp)) + return; + var newLayer = SpriteSystem.AddLayer( spriteEnt, new SpriteSpecifier.Rsi( - new(sprite.Sprite), state + new(sprite.Sprite), + state ), index ); @@ -354,6 +361,12 @@ public sealed partial class DamageVisualsSystem : VisualizerSystem(uid, DamageVisualizerKeys.Displacement, out var displacement, args.Component) && + ProtoMan.Resolve(displacement, out var displacementProto)) + damageVisComp.Displacement = displacementProto.Displacement; + else + damageVisComp.Displacement = null; + HandleDamage(uid, args.Component, damageVisComp); } @@ -503,7 +516,7 @@ public sealed partial class DamageVisualsSystem : VisualizerSystem /// Updates an overlay that is tracking all damage. /// - private void UpdateOverlay(Entity spriteEnt, FixedPoint2 threshold) + private void UpdateOverlay(Entity spriteEnt, FixedPoint2 threshold, DisplacementData? displacement = null) { SpriteSystem.LayerMapTryGet(spriteEnt.AsNullable(), $"DamageOverlay", out var spriteLayer, false); UpdateDamageLayerState(spriteEnt, spriteLayer, $"DamageOverlay", - threshold); + threshold, + $"DamageOverlay", + displacement); } /// /// Updates an overlay based on damage group. /// - private void UpdateOverlay(Entity entity, string damageGroup, FixedPoint2 threshold) + private void UpdateOverlay(Entity entity, string damageGroup, FixedPoint2 threshold, DisplacementData? displacement = null) { var spriteComponent = entity.Comp1; var damageVisComp = entity.Comp2; @@ -695,7 +718,9 @@ public sealed partial class DamageVisualsSystem : VisualizerSystem - private void UpdateDamageLayerState(Entity spriteEnt, int spriteLayer, string statePrefix, FixedPoint2 threshold) + private void UpdateDamageLayerState(Entity spriteEnt, int spriteLayer, string statePrefix, FixedPoint2 threshold, string layerKey, DisplacementData? displacement) { if (threshold == 0) { @@ -719,6 +744,14 @@ public sealed partial class DamageVisualsSystem : VisualizerSystem /// The sprite to remove the displacement layer from. /// The key of the layer that is referenced by the displacement layer we want to remove. - /// Whether to report an error if the displacement map isn't on the sprite. - public void EnsureDisplacementIsNotOnSprite(Entity sprite, object key) + /// Returns true if the displacement existed and was removed. + public bool EnsureDisplacementIsNotOnSprite(Entity sprite, object key) { var displacementLayerKey = BuildDisplacementLayerKey(key); if (displacementLayerKey is null) - return; + return false; - _sprite.RemoveLayer(sprite.AsNullable(), displacementLayerKey, false); + return _sprite.RemoveLayer(sprite.AsNullable(), displacementLayerKey, false); } } diff --git a/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs b/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs index 5dd5192537..2d03abc843 100644 --- a/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs +++ b/Content.Client/Nutrition/EntitySystems/CreamPieSystem.cs @@ -1,6 +1,8 @@ +using Content.Client.DisplacementMap; using Content.Shared.Nutrition.Components; using Content.Shared.Nutrition.EntitySystems; using Robust.Client.GameObjects; +using Robust.Shared.Prototypes; namespace Content.Client.Nutrition.EntitySystems; @@ -8,6 +10,7 @@ public sealed partial class CreamPieSystem : SharedCreamPieSystem { [Dependency] private SpriteSystem _sprite = default!; [Dependency] private AppearanceSystem _appearance = default!; + [Dependency] private DisplacementMapSystem _displacement = default!; public override void Initialize() { @@ -27,6 +30,7 @@ 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); } private void OnAppearanceChange(Entity ent, ref AppearanceChangeEvent args) @@ -54,6 +58,7 @@ public sealed partial class CreamPieSystem : SharedCreamPieSystem if (creamPied.Sprite == null) { _sprite.RemoveLayer((ent.Owner, sprite), CreamPiedVisualLayer.Key); + _displacement.EnsureDisplacementIsNotOnSprite((ent.Owner, sprite), CreamPiedVisualLayer.Key); return; } @@ -62,5 +67,10 @@ public sealed partial class CreamPieSystem : SharedCreamPieSystem _appearance.TryGetData(ent.Owner, CreamPiedVisuals.Creamed, out var isCreamPied, appearance); _sprite.LayerSetSprite((ent.Owner, sprite), index, creamPied.Sprite); _sprite.LayerSetVisible((ent.Owner, sprite), index, isCreamPied); + + if (ProtoMan.Resolve(ent.Comp1.Displacement, out var displacementProto)) + { + _displacement.TryAddDisplacement(displacementProto.Displacement, (ent.Owner, sprite), index, CreamPiedVisualLayer.Key, out _); + } } } diff --git a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs index bb282bf25d..137da5f10d 100644 --- a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs +++ b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs @@ -269,6 +269,11 @@ namespace Content.Server.Atmos.EntitySystems _appearance.SetData(uid, FireVisuals.OnFire, flammable.OnFire, appearance); _appearance.SetData(uid, FireVisuals.FireStacks, flammable.FireStacks, appearance); + if (flammable.Displacement != null) + _appearance.SetData(uid, FireVisuals.FireDisplacement, flammable.Displacement.Value.Id, appearance); + else + _appearance.RemoveData(uid, FireVisuals.FireDisplacement); + // Also enable toggleable-light visuals // This is intended so that matches & candles can re-use code for un-shaded layers on in-hand sprites. // However, this could cause conflicts if something is ACTUALLY both a toggleable light and flammable. diff --git a/Content.Shared/Anomaly/Components/InnerBodyAnomalyVisualsComponent.cs b/Content.Shared/Anomaly/Components/InnerBodyAnomalyVisualsComponent.cs new file mode 100644 index 0000000000..5298bce4f7 --- /dev/null +++ b/Content.Shared/Anomaly/Components/InnerBodyAnomalyVisualsComponent.cs @@ -0,0 +1,18 @@ +using Content.Shared.DisplacementMap; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Anomaly.Components; + +/// +/// Complementary visuals component to . +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class InnerBodyAnomalyVisualsComponent : Component +{ + /// + /// If set, applies a displacement map to the anomaly sprites. + /// + [DataField, AutoNetworkedField] + public ProtoId? Displacement; +} diff --git a/Content.Shared/Atmos/Components/FlammableComponent.cs b/Content.Shared/Atmos/Components/FlammableComponent.cs index aa1d361fa0..7bf9b4363a 100644 --- a/Content.Shared/Atmos/Components/FlammableComponent.cs +++ b/Content.Shared/Atmos/Components/FlammableComponent.cs @@ -1,5 +1,6 @@ using Content.Shared.Alert; using Content.Shared.Damage; +using Content.Shared.DisplacementMap; using Robust.Shared.GameStates; using Robust.Shared.Physics.Collision.Shapes; using Robust.Shared.Prototypes; @@ -109,5 +110,11 @@ namespace Content.Shared.Atmos.Components [DataField] public ProtoId FireAlert = "Fire"; + + /// + /// If set, applies the displacement map associated with the . + /// + [DataField] + public ProtoId? Displacement; } } diff --git a/Content.Shared/Atmos/FireVisuals.cs b/Content.Shared/Atmos/FireVisuals.cs index aeab858a35..6758a95fd8 100644 --- a/Content.Shared/Atmos/FireVisuals.cs +++ b/Content.Shared/Atmos/FireVisuals.cs @@ -7,5 +7,6 @@ namespace Content.Shared.Atmos { OnFire, FireStacks, + FireDisplacement, } } diff --git a/Content.Shared/Body/VisualOrganComponent.cs b/Content.Shared/Body/VisualOrganComponent.cs index 6427c8f0e3..80525e35a6 100644 --- a/Content.Shared/Body/VisualOrganComponent.cs +++ b/Content.Shared/Body/VisualOrganComponent.cs @@ -1,5 +1,7 @@ +using Content.Shared.DisplacementMap; using Content.Shared.Humanoid; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; namespace Content.Shared.Body; @@ -35,6 +37,12 @@ public sealed partial class VisualOrganComponent : Component /// [DataField, AutoNetworkedField] public OrganProfileData Profile = new(); + + /// + /// Displacement data prototype applied to the organ's visualization. + /// + [DataField, AutoNetworkedField] + public ProtoId? Displacement; } /// diff --git a/Content.Shared/Damage/Components/DamageableComponent.cs b/Content.Shared/Damage/Components/DamageableComponent.cs index 7476199829..aa395a4460 100644 --- a/Content.Shared/Damage/Components/DamageableComponent.cs +++ b/Content.Shared/Damage/Components/DamageableComponent.cs @@ -1,5 +1,6 @@ using Content.Shared.Damage.Prototypes; using Content.Shared.Damage.Systems; +using Content.Shared.DisplacementMap; using Content.Shared.FixedPoint; using Content.Shared.Mobs; using Content.Shared.StatusIcon; @@ -63,6 +64,13 @@ public sealed partial class DamageableComponent : Component [DataField("radiationDamageTypes")] // ReSharper disable once UseCollectionExpression - Cannot refactor this as it's a potential sandbox violation. public List> RadiationDamageTypeIDs = new() { "Radiation" }; + + /// + /// Sets the displacement map used for any of the DamageVisuals sprites for this entity. + /// TODO: The entirety of DamageVisualsSystem needs to be rewritten. + /// + [DataField] + public ProtoId? Displacement; } [Serializable, NetSerializable] diff --git a/Content.Shared/Damage/DamageVisualizerKeys.cs b/Content.Shared/Damage/DamageVisualizerKeys.cs index 9719b96fe7..b142ec1c9e 100644 --- a/Content.Shared/Damage/DamageVisualizerKeys.cs +++ b/Content.Shared/Damage/DamageVisualizerKeys.cs @@ -10,7 +10,8 @@ namespace Content.Shared.Damage Disabled, DamageSpecifierDelta, DamageUpdateGroups, - ForceUpdate + ForceUpdate, + Displacement, } [Serializable, NetSerializable] diff --git a/Content.Shared/Damage/Systems/DamageableSystem.cs b/Content.Shared/Damage/Systems/DamageableSystem.cs index 2fba073b71..5c7a8a73cb 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.cs @@ -66,6 +66,20 @@ public sealed partial class DamageableSystem : EntitySystem new DamageVisualizerGroupData(ent.Comp.DamagePerGroup.Keys.ToList()), appearance ); + + if (ent.Comp.Displacement != null) + { + _appearance.SetData( + ent, + DamageVisualizerKeys.Displacement, + ent.Comp.Displacement.Value.Id, + appearance + ); + } + else + { + _appearance.RemoveData(ent, DamageVisualizerKeys.Displacement); + } } // TODO DAMAGE diff --git a/Content.Shared/DisplacementMap/DisplacementDataPrototype.cs b/Content.Shared/DisplacementMap/DisplacementDataPrototype.cs new file mode 100644 index 0000000000..46d1b10433 --- /dev/null +++ b/Content.Shared/DisplacementMap/DisplacementDataPrototype.cs @@ -0,0 +1,20 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.DisplacementMap; + +/// +/// Prototype wrapper for displacement maps, making it easier to network displacements from server to client. +/// +[Prototype] +public sealed partial class DisplacementDataPrototype : IPrototype +{ + /// + [IdDataField] + public string ID { get; private set; } = default!; + + /// + /// The displacement map this prototype is referencing. + /// + [DataField(required: true)] + public DisplacementData Displacement = default!; +} diff --git a/Content.Shared/Nutrition/Components/CreamPiedComponent.cs b/Content.Shared/Nutrition/Components/CreamPiedComponent.cs index 08c583ff7b..a050d0884f 100644 --- a/Content.Shared/Nutrition/Components/CreamPiedComponent.cs +++ b/Content.Shared/Nutrition/Components/CreamPiedComponent.cs @@ -1,5 +1,7 @@ +using Content.Shared.DisplacementMap; using Content.Shared.Nutrition.EntitySystems; using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Utility; @@ -26,6 +28,12 @@ public sealed partial class CreamPiedComponent : Component /// [DataField, AutoNetworkedField] public SpriteSpecifier? Sprite; + + /// + /// If set, applies a displacement map to the pie sprite. + /// + [DataField, AutoNetworkedField] + public ProtoId? Displacement; } /// diff --git a/Resources/Prototypes/Body/Species/dwarf.yml b/Resources/Prototypes/Body/Species/dwarf.yml index 1759ffd61f..0ad6857b60 100644 --- a/Resources/Prototypes/Body/Species/dwarf.yml +++ b/Resources/Prototypes/Body/Species/dwarf.yml @@ -5,26 +5,87 @@ name: dwarf appearance components: - type: Inventory - femaleDisplacements: + femaleDisplacements: { } # Necessary due to MobHuman inheritance for MobDwarf + displacements: jumpsuit: sizeMaps: 32: sprite: Mobs/Species/Human/displacement.rsi - state: jumpsuit-female + state: dwarfism + outerClothing: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + suitstorage: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + id: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + mask: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + belt: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + eyes: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + gloves: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + head: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + neck: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + back: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + ears: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + shoes: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism - type: InitialBody organs: - Torso: OrganHumanTorso - Head: OrganHumanHead - ArmLeft: OrganHumanArmLeft - ArmRight: OrganHumanArmRight - HandRight: OrganHumanHandRight - HandLeft: OrganHumanHandLeft - LegLeft: OrganHumanLegLeft - LegRight: OrganHumanLegRight - FootLeft: OrganHumanFootLeft - FootRight: OrganHumanFootRight + Torso: OrganDwarfTorso + Head: OrganDwarfHead + ArmLeft: OrganDwarfArmLeft + ArmRight: OrganDwarfArmRight + HandRight: OrganDwarfHandRight + HandLeft: OrganDwarfHandLeft + LegLeft: OrganDwarfLegLeft + LegRight: OrganDwarfLegRight + FootLeft: OrganDwarfFootLeft + FootRight: OrganDwarfFootRight Brain: OrganHumanBrain - Eyes: OrganHumanEyes + Eyes: OrganDwarfEyes Tongue: OrganHumanTongue Appendix: OrganHumanAppendix Ears: OrganHumanEars @@ -33,10 +94,27 @@ Stomach: OrganDwarfStomach Liver: OrganDwarfLiver Kidneys: OrganHumanKidneys + - type: Hands + leftHandDisplacement: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism_hand_left + rightHandDisplacement: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism_hand_right - type: HumanoidProfile species: Dwarf - - type: ScaleVisuals - scale: 1, 0.8 + +- type: displacementData + id: Dwarfism + displacement: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism - type: entity parent: @@ -64,6 +142,14 @@ accent: scottish - type: Speech speechSounds: Bass + - type: CreamPied + displacement: Dwarfism + - type: Damageable + displacement: Dwarfism + - type: Flammable + displacement: Dwarfism + - type: InnerBodyAnomalyVisuals + displacement: Dwarfism - type: entity parent: OrganBaseOrganic @@ -72,12 +158,220 @@ suffix: Dwarf - type: entity + parent: OrganDwarf + id: OrganDwarfAppearance + abstract: true + suffix: Dwarf + components: + - type: VisualOrgan + data: + sprite: Mobs/Species/Human/parts.rsi + displacement: Dwarfism + +- type: entity + parent: OrganDwarf id: OrganDwarfMetabolizer abstract: true components: - type: Metabolizer metabolizerTypes: [ Dwarf ] +- type: entity + parent: [ OrganHumanTorso, OrganDwarfAppearance ] + id: OrganDwarfTorso + components: + - type: VisualOrganMarkings + markingsDisplacement: + Chest: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + Tail: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + Overlay: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + TailOverlay: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + UndergarmentTop: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + UndergarmentBottom: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + Special: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + +- type: entity + parent: [ OrganHumanHead, OrganDwarfAppearance ] + id: OrganDwarfHead + components: + - type: VisualOrganMarkings + markingsDisplacement: + Head: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + Hair: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + FacialHair: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + Snout: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + SnoutCover: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + HeadSide: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + HeadTop: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + +- type: entity + parent: [ OrganHumanArmLeft, OrganDwarfAppearance ] + id: OrganDwarfArmLeft + components: + - type: VisualOrganMarkings + markingsDisplacement: + LArm: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + +- type: entity + parent: [ OrganHumanArmRight, OrganDwarfAppearance ] + id: OrganDwarfArmRight + components: + - type: VisualOrganMarkings + markingsDisplacement: + RArm: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + +- type: entity + parent: [ OrganHumanHandRight, OrganDwarfAppearance ] + id: OrganDwarfHandRight + components: + - type: VisualOrganMarkings + markingsDisplacement: + RHand: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + +- type: entity + parent: [ OrganHumanHandLeft, OrganDwarfAppearance ] + id: OrganDwarfHandLeft + components: + - type: VisualOrganMarkings + markingsDisplacement: + LHand: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + +- type: entity + parent: [ OrganHumanLegLeft, OrganDwarfAppearance ] + id: OrganDwarfLegLeft + components: + - type: VisualOrganMarkings + markingsDisplacement: + LLeg: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + +- type: entity + parent: [ OrganHumanLegRight, OrganDwarfAppearance ] + id: OrganDwarfLegRight + components: + - type: VisualOrganMarkings + markingsDisplacement: + RLeg: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + +- type: entity + parent: [ OrganHumanFootLeft, OrganDwarfAppearance ] + id: OrganDwarfFootLeft + components: + - type: VisualOrganMarkings + markingsDisplacement: + LFoot: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + +- type: entity + parent: [ OrganHumanFootRight, OrganDwarfAppearance ] + id: OrganDwarfFootRight + components: + - type: VisualOrganMarkings + markingsDisplacement: + RFoot: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + +- type: entity + parent: [ OrganHumanEyes, OrganDwarfAppearance ] + id: OrganDwarfEyes + components: + - type: VisualOrgan + data: + sprite: Mobs/Customization/eyes.rsi + displacement: Dwarfism + - type: VisualOrganMarkings + markingsDisplacement: + Eyes: + sizeMaps: + 32: + sprite: Mobs/Species/Human/displacement.rsi + state: dwarfism + - type: entity parent: [ OrganDwarfMetabolizer, OrganHumanStomach ] id: OrganDwarfStomach diff --git a/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism.png b/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism.png new file mode 100644 index 0000000000..86d57009d0 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism.png differ diff --git a/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism_hand_left.png b/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism_hand_left.png new file mode 100644 index 0000000000..e6f3832331 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism_hand_left.png differ diff --git a/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism_hand_right.png b/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism_hand_right.png new file mode 100644 index 0000000000..7f8da85c12 Binary files /dev/null and b/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism_hand_right.png differ diff --git a/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism_vertical.png b/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism_vertical.png new file mode 100644 index 0000000000..29076e52db Binary files /dev/null and b/Resources/Textures/Mobs/Species/Human/displacement.rsi/dwarfism_vertical.png differ diff --git a/Resources/Textures/Mobs/Species/Human/displacement.rsi/meta.json b/Resources/Textures/Mobs/Species/Human/displacement.rsi/meta.json index 7ac587cad7..d4d637bd08 100644 --- a/Resources/Textures/Mobs/Species/Human/displacement.rsi/meta.json +++ b/Resources/Textures/Mobs/Species/Human/displacement.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Made by TheShuEd", + "copyright": "jumpsuit-female made by TheShuEd, dwarfism sprites made by SlamBamActionman (Github)", "size": { "x": 32, "y": 32 @@ -13,6 +13,22 @@ { "name": "jumpsuit-female", "directions": 4 + }, + { + "name": "dwarfism", + "directions": 4 + }, + { + "name": "dwarfism_hand_left", + "directions": 4 + }, + { + "name": "dwarfism_hand_right", + "directions": 4 + }, + { + "name": "dwarfism_vertical", + "directions": 1 } ] }