using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Numerics;
+using Content.Client.DisplacementMap;
using Content.Client.Inventory;
using Content.Shared.Clothing;
using Content.Shared.Clothing.Components;
using Content.Shared.Clothing.EntitySystems;
+using Content.Shared.DisplacementMap;
using Content.Shared.Humanoid;
using Content.Shared.Inventory;
using Content.Shared.Inventory.Events;
[Dependency] private readonly IResourceCache _cache = default!;
[Dependency] private readonly ISerializationManager _serialization = default!;
[Dependency] private readonly InventorySystem _inventorySystem = default!;
+ [Dependency] private readonly DisplacementMapSystem _displacement = default!;
public override void Initialize()
{
private void OnAppearanceUpdate(EntityUid uid, InventoryComponent component, ref AppearanceChangeEvent args)
{
- // May need to update jumpsuit stencils if the sex changed. Also required to properly set the stencil on init
+ // May need to update displacement maps if the sex changed. Also required to properly set the stencil on init
if (args.Sprite == null)
return;
- if (_inventorySystem.TryGetSlotEntity(uid, Jumpsuit, out var suit, component)
- && TryComp(suit, out ClothingComponent? clothing))
+ var enumerator = _inventorySystem.GetSlotEnumerator((uid, component));
+ while (enumerator.NextItem(out var item, out var slot))
{
- SetGenderedMask(uid, args.Sprite, clothing);
- return;
+ RenderEquipment(uid, item, slot.Name, component);
}
// No clothing equipped -> make sure the layer is hidden, though this should already be handled by on-unequip.
private void OnDidUnequip(EntityUid uid, SpriteComponent component, DidUnequipEvent args)
{
- // Hide jumpsuit mask layer.
- if (args.Slot == Jumpsuit
- && TryComp(uid, out SpriteComponent? sprite)
- && sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var maskLayer))
- {
- sprite.LayerSetVisible(maskLayer, false);
- }
-
if (!TryComp(uid, out InventorySlotsComponent? inventorySlots))
return;
return;
}
- if (slot == Jumpsuit)
- SetGenderedMask(equipee, sprite, clothingComponent);
-
if (!_inventorySystem.TryGetSlot(equipee, slot, out var slotDef, inventory))
return;
// temporary, until layer draw depths get added. Basically: a layer with the key "slot" is being used as a
// bookmark to determine where in the list of layers we should insert the clothing layers.
bool slotLayerExists = sprite.LayerMapTryGet(slot, out var index);
- var displacementData = inventory.Displacements.GetValueOrDefault(slot);
+
+ // Select displacement maps
+ var displacementData = inventory.Displacements.GetValueOrDefault(slot); //Default unsexed map
+
+ var equipeeSex = CompOrNull<HumanoidAppearanceComponent>(equipee)?.Sex;
+ if (equipeeSex != null)
+ {
+ switch (equipeeSex)
+ {
+ case Sex.Male:
+ if (inventory.MaleDisplacements.Count > 0)
+ displacementData = inventory.MaleDisplacements.GetValueOrDefault(slot);
+ break;
+ case Sex.Female:
+ if (inventory.FemaleDisplacements.Count > 0)
+ displacementData = inventory.FemaleDisplacements.GetValueOrDefault(slot);
+ break;
+ }
+ }
// add the new layers
foreach (var (key, layerData) in ev.Layers)
index = sprite.LayerMapReserveBlank(key);
if (sprite[index] is not Layer layer)
- return;
+ continue;
// In case no RSI is given, use the item's base RSI as a default. This cuts down on a lot of unnecessary yaml entries.
if (layerData.RsiPath == null
layer.SetRsi(clothingSprite.BaseRSI);
}
- // Another "temporary" fix for clothing stencil masks.
- // Sprite layer redactor when
- // Sprite "redactor" just a week away.
- if (slot == Jumpsuit)
- layerData.Shader ??= "StencilDraw";
-
sprite.LayerSetData(index, layerData);
layer.Offset += slotDef.Offset;
- if (displacementData != null)
+ if (displacementData is not null)
{
- if (displacementData.ShaderOverride != null)
- sprite.LayerSetShader(index, displacementData.ShaderOverride);
-
- var displacementKey = $"{key}-displacement";
- if (!revealedLayers.Add(displacementKey))
- {
- Log.Warning($"Duplicate key for clothing visuals DISPLACEMENT: {displacementKey}.");
+ //Checking that the state is not tied to the current race. In this case we don't need to use the displacement maps.
+ if (layerData.State is not null && inventory.SpeciesId is not null && layerData.State.EndsWith(inventory.SpeciesId))
continue;
- }
-
- var displacementLayer = _serialization.CreateCopy(displacementData.Layer, notNullableOverride: true);
- displacementLayer.CopyToShaderParameters!.LayerKey = key;
- // Add before main layer for this item.
- sprite.AddLayer(displacementLayer, index);
- sprite.LayerMapSet(displacementKey, index);
-
- revealedLayers.Add(displacementKey);
+ _displacement.TryAddDisplacement(displacementData, sprite, index, key, revealedLayers);
}
}
RaiseLocalEvent(equipment, new EquipmentVisualsUpdatedEvent(equipee, slot, revealedLayers), true);
}
-
-
- /// <summary>
- /// Sets a sprite's gendered mask based on gender (obviously).
- /// </summary>
- /// <param name="sprite">Sprite to modify</param>
- /// <param name="humanoid">Humanoid, to get gender from</param>
- /// <param name="clothing">Clothing component, to get mask sprite type</param>
- private void SetGenderedMask(EntityUid uid, SpriteComponent sprite, ClothingComponent clothing)
- {
- if (!sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var layer))
- return;
-
- ClothingMask mask;
- string prefix;
-
- switch (CompOrNull<HumanoidAppearanceComponent>(uid)?.Sex)
- {
- case Sex.Male:
- mask = clothing.MaleMask;
- prefix = "male_";
- break;
- case Sex.Female:
- mask = clothing.FemaleMask;
- prefix = "female_";
- break;
- default:
- mask = clothing.UnisexMask;
- prefix = "unisex_";
- break;
- }
-
- sprite.LayerSetState(layer, mask switch
- {
- ClothingMask.NoMask => $"{prefix}none",
- ClothingMask.UniformTop => $"{prefix}top",
- _ => $"{prefix}full",
- });
- sprite.LayerSetVisible(layer, true);
- }
}
--- /dev/null
+using Content.Shared.DisplacementMap;
+using Robust.Client.GameObjects;
+using Robust.Client.Graphics;
+using Robust.Shared.Serialization.Manager;
+
+namespace Content.Client.DisplacementMap;
+
+public sealed class DisplacementMapSystem : EntitySystem
+{
+ [Dependency] private readonly ISerializationManager _serialization = default!;
+
+ public bool TryAddDisplacement(DisplacementData data, SpriteComponent sprite, int index, string key, HashSet<string> revealedLayers)
+ {
+ if (data.ShaderOverride != null)
+ sprite.LayerSetShader(index, data.ShaderOverride);
+
+ var displacementKey = $"{key}-displacement";
+ if (!revealedLayers.Add(displacementKey))
+ {
+ Log.Warning($"Duplicate key for DISPLACEMENT: {displacementKey}.");
+ return false;
+ }
+
+ //allows you not to write it every time in the YML
+ foreach (var pair in data.SizeMaps)
+ {
+ pair.Value.CopyToShaderParameters??= new()
+ {
+ LayerKey = "dummy",
+ ParameterTexture = "displacementMap",
+ ParameterUV = "displacementUV",
+ };
+ }
+
+ if (!data.SizeMaps.ContainsKey(32))
+ {
+ Log.Error($"DISPLACEMENT: {displacementKey} don't have 32x32 default displacement map");
+ return false;
+ }
+
+ // We choose a displacement map from the possible ones, matching the size with the original layer size.
+ // If there is no such a map, we use a standard 32 by 32 one
+ var displacementDataLayer = data.SizeMaps[EyeManager.PixelsPerMeter];
+ var actualRSI = sprite.LayerGetActualRSI(index);
+ if (actualRSI is not null)
+ {
+ if (actualRSI.Size.X != actualRSI.Size.Y)
+ Log.Warning($"DISPLACEMENT: {displacementKey} has a resolution that is not 1:1, things can look crooked");
+
+ var layerSize = actualRSI.Size.X;
+ if (data.SizeMaps.ContainsKey(layerSize))
+ displacementDataLayer = data.SizeMaps[layerSize];
+ }
+
+ var displacementLayer = _serialization.CreateCopy(displacementDataLayer, notNullableOverride: true);
+ displacementLayer.CopyToShaderParameters!.LayerKey = key;
+
+ sprite.AddLayer(displacementLayer, index);
+ sprite.LayerMapSet(displacementKey, index);
+
+ revealedLayers.Add(displacementKey);
+
+ return true;
+ }
+}
using System.Diagnostics.CodeAnalysis;
using System.Linq;
+using Content.Client.DisplacementMap;
using Content.Client.Examine;
using Content.Client.Strip;
using Content.Client.Verbs.UI;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly StrippableSystem _stripSys = default!;
[Dependency] private readonly ExamineSystem _examine = default!;
+ [Dependency] private readonly DisplacementMapSystem _displacement = default!;
public event Action<string, HandLocation>? OnPlayerAddHand;
public event Action<string>? OnPlayerRemoveHand;
}
sprite.LayerSetData(index, layerData);
+
+ //Add displacement maps
+ if (handComp.HandDisplacement is not null)
+ _displacement.TryAddDisplacement(handComp.HandDisplacement, sprite, index, key, revealedLayers);
}
RaiseLocalEvent(held, new HeldVisualsUpdatedEvent(uid, revealedLayers), true);
[DataField("sprite")]
public string? RsiPath;
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("maleMask")]
- public ClothingMask MaleMask = ClothingMask.UniformFull;
-
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("femaleMask")]
- public ClothingMask FemaleMask = ClothingMask.UniformFull;
-
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("unisexMask")]
- public ClothingMask UnisexMask = ClothingMask.UniformFull;
-
/// <summary>
/// Name of the inventory slot the clothing is in.
/// </summary>
clothing.ClothingVisuals = otherClothing.ClothingVisuals;
clothing.EquippedPrefix = otherClothing.EquippedPrefix;
clothing.RsiPath = otherClothing.RsiPath;
- clothing.FemaleMask = otherClothing.FemaleMask;
_itemSys.VisualsChanged(uid);
Dirty(uid, clothing);
--- /dev/null
+namespace Content.Shared.DisplacementMap;
+
+[DataDefinition]
+public sealed partial class DisplacementData
+{
+ /// <summary>
+ /// allows you to attach different maps for layers of different sizes.
+ /// </summary>
+ [DataField(required: true)]
+ public Dictionary<int, PrototypeLayerData> SizeMaps = new();
+
+ [DataField]
+ public string? ShaderOverride = "DisplacedStencilDraw";
+}
+using Content.Shared.DisplacementMap;
using Content.Shared.Hands.EntitySystems;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public TimeSpan ThrowCooldown = TimeSpan.FromSeconds(0.5f);
+
+ [DataField]
+ public DisplacementData? HandDisplacement;
}
[Serializable, NetSerializable]
-using Robust.Shared.Containers;
+using Content.Shared.DisplacementMap;
+using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
[DataField("speciesId")] public string? SpeciesId { get; set; }
- [DataField] public Dictionary<string, SlotDisplacementData> Displacements = [];
-
public SlotDefinition[] Slots = Array.Empty<SlotDefinition>();
public ContainerSlot[] Containers = Array.Empty<ContainerSlot>();
- [DataDefinition]
- public sealed partial class SlotDisplacementData
- {
- [DataField(required: true)]
- public PrototypeLayerData Layer = default!;
+ [DataField]
+ public Dictionary<string, DisplacementData> Displacements = new();
+
+ /// <summary>
+ /// Alternate displacement maps, which if available, will be selected for the player of the appropriate gender.
+ /// </summary>
+ [DataField]
+ public Dictionary<string, DisplacementData> FemaleDisplacements = new();
- [DataField]
- public string? ShaderOverride = "DisplacedStencilDraw";
- }
+ /// <summary>
+ /// Alternate displacement maps, which if available, will be selected for the player of the appropriate gender.
+ /// </summary>
+ [DataField]
+ public Dictionary<string, DisplacementData> MaleDisplacements = new();
}
sprite: Clothing/Uniforms/Jumpsuit/clown.rsi
- type: Clothing
sprite: Clothing/Uniforms/Jumpsuit/clown.rsi
- femaleMask: UniformTop
- type: Tag
tags:
- ClownSuit
sprite: Clothing/Uniforms/Jumpsuit/clown_banana.rsi
- type: Clothing
sprite: Clothing/Uniforms/Jumpsuit/clown_banana.rsi
- femaleMask: UniformTop
- type: Construction
graph: BananaClownJumpsuit
node: jumpsuit
- state: mask_null
map: [ "overlay" ]
- type: Clothing
- femaleMask: UniformTop
- maleMask: UniformTop
sprite: Clothing/Uniforms/procedural.rsi
clothingVisuals:
jumpsuit:
spawned:
- id: FoodMeatSpider
amount: 5
- - type: Inventory
- templateId: arachnid
- type: Reactive
reactions:
- reagents: [Water]
- map: [ "enum.HumanoidVisualLayers.LArm" ]
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
- - shader: StencilClear
- sprite: Mobs/Species/Human/parts.rsi #PJB on stencil clear being on the left leg: "...this is 'fine'" -https://github.com/space-wizards/space-station-14/pull/12217#issuecomment-1291677115
- # its fine, but its still very stupid that it has to be done like this instead of allowing sprites to just directly insert a stencil clear.
- # sprite refactor when
- state: l_leg
- - shader: StencilMask
- map: ["enum.HumanoidVisualLayers.StencilMask"]
- sprite: Mobs/Customization/masking_helpers.rsi
- state: unisex_full
- visible: false
- map: ["jumpsuit"]
- map: ["enum.HumanoidVisualLayers.LFoot"]
- map: ["enum.HumanoidVisualLayers.RFoot"]
sprite: "Effects/creampie.rsi"
state: "creampie_arachnid"
visible: false
+ - type: Inventory
+ templateId: arachnid
+
- type: entity
parent: BaseSpeciesDummy
- type: HumanoidAppearance
species: Arachnid
-#88w88
+
+#>88w88<
- map: [ "enum.HumanoidVisualLayers.LArm" ]
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
- - shader: StencilClear
- sprite: Mobs/Species/Human/parts.rsi #PJB on stencil clear being on the left leg: "...this is 'fine'" -https://github.com/space-wizards/space-station-14/pull/12217#issuecomment-1291677115
- # its fine, but its still very stupid that it has to be done like this instead of allowing sprites to just directly insert a stencil clear.
- # sprite refactor when
- state: l_leg
- - shader: StencilMask
- map: ["enum.HumanoidVisualLayers.StencilMask"]
- sprite: Mobs/Customization/masking_helpers.rsi
- state: unisex_full
- visible: false
- map: ["jumpsuit"]
- map: ["enum.HumanoidVisualLayers.LFoot"]
- map: ["enum.HumanoidVisualLayers.RFoot"]
- map: [ "enum.HumanoidVisualLayers.LArm" ]
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
- - shader: StencilClear
- sprite: Mobs/Species/Human/parts.rsi
- state: l_leg
- - shader: StencilMask
- map: ["enum.HumanoidVisualLayers.StencilMask"]
- sprite: Mobs/Customization/masking_helpers.rsi
- state: unisex_full
- visible: false
- map: ["jumpsuit"]
- map: ["enum.HumanoidVisualLayers.LFoot"]
- map: ["enum.HumanoidVisualLayers.RFoot"]
- type: UserInterface
interfaces:
enum.HumanoidMarkingModifierKey.Key: # sure, this can go here too
- type: HumanoidMarkingModifierBoundUserInterface
+ type: HumanoidMarkingModifierBoundUserInterface
\ No newline at end of file
- MobMask
layer:
- MobLayer
- - type: Inventory
- templateId: diona
- type: Speech
speechVerb: Plant
- type: Vocal
actionPrototype: DionaGibAction
allowedStates:
- Dead
+ - type: Inventory
+ templateId: diona
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
- type: entity
parent: BaseSpeciesDummy
id: MobDionaDummy
noSpawn: true
components:
- - type: Inventory
- templateId: diona
- type: HumanoidAppearance
species: Diona
+ - type: Inventory
+ templateId: diona
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
hideLayersOnEquip:
- Hair
- Snout
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
- type: entity
parent: BaseSpeciesDummy
components:
- type: Sprite
scale: 1, 0.8
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
- MobMask
layer:
- MobLayer
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
+
- type: entity
parent: BaseSpeciesDummy
components:
- type: HumanoidAppearance
species: Gingerbread
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
hideLayersOnEquip:
- Hair
- Snout
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
+
- type: entity
parent: BaseSpeciesDummy
id: MobHumanDummy
noSpawn: true
+ components:
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
+
- map: [ "enum.HumanoidVisualLayers.LArm" ]
- map: [ "enum.HumanoidVisualLayers.RLeg" ]
- map: [ "enum.HumanoidVisualLayers.LLeg" ]
- - shader: StencilClear
- sprite: Mobs/Species/Human/parts.rsi #PJB on stencil clear being on the left leg: "...this is 'fine'" -https://github.com/space-wizards/space-station-14/pull/12217#issuecomment-1291677115
- # its fine, but its still very stupid that it has to be done like this instead of allowing sprites to just directly insert a stencil clear.
- # sprite refactor when
- state: l_leg
- - shader: StencilMask
- map: [ "enum.HumanoidVisualLayers.StencilMask" ]
- sprite: Mobs/Customization/masking_helpers.rsi
- state: unisex_full
- visible: false
- map: [ "jumpsuit" ]
- map: [ "enum.HumanoidVisualLayers.LHand" ]
- map: [ "enum.HumanoidVisualLayers.RHand" ]
sprite: "Effects/creampie.rsi"
state: "creampie_moth"
visible: false
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
+
- type: entity
parent: BaseSpeciesDummy
components:
- type: HumanoidAppearance
species: Moth
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
+
spawned:
- id: FoodMeatLizard
amount: 5
- - type: Inventory
- speciesId: reptilian
- type: LizardAccent
- type: Speech
speechSounds: Lizard
types:
Heat : 1.5 #per second, scales with temperature & other constants
- type: Wagging
+ - type: Inventory
+ speciesId: reptilian
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
+
- type: entity
parent: BaseSpeciesDummy
- HeadSide
- type: Inventory
speciesId: reptilian
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
#Weh
- type: FireVisuals
alternateState: Standing
- type: FlashImmunity
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
- type: entity
parent: BaseSpeciesDummy
id: MobSkeletonPersonDummy
noSpawn: true
components:
- - type: HumanoidAppearance
- species: Skeleton
+ - type: HumanoidAppearance
+ species: Skeleton
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
types:
Asphyxiation: -1.0
maxSaturation: 15
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
- type: entity
parent: MobHumanDummy
id: MobSlimePersonDummy
noSpawn: true
components:
- - type: HumanoidAppearance
- species: SlimePerson
+ - type: HumanoidAppearance
+ species: SlimePerson
+ - type: Inventory
+ femaleDisplacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Human/displacement.rsi
+ state: jumpsuit-female
- type: HumanoidAppearance
species: Vox
#- type: VoxAccent # Not yet coded
- - type: Inventory
- speciesId: vox
- displacements:
- jumpsuit:
- layer:
- sprite: Mobs/Species/Vox/displacement.rsi
- state: jumpsuit
- copyToShaderParameters:
- # Value required, provide a dummy. Gets overridden when applied.
- layerKey: dummy
- parameterTexture: displacementMap
- parameterUV: displacementUV
- eyes:
- layer:
- sprite: Mobs/Species/Vox/displacement.rsi
- state: eyes
- copyToShaderParameters:
- layerKey: dummy
- parameterTexture: displacementMap
- parameterUV: displacementUV
- gloves:
- layer:
- sprite: Mobs/Species/Vox/displacement.rsi
- state: hand
- copyToShaderParameters:
- layerKey: dummy
- parameterTexture: displacementMap
- parameterUV: displacementUV
- back:
- layer:
- sprite: Mobs/Species/Vox/displacement.rsi
- state: back
- copyToShaderParameters:
- layerKey: dummy
- parameterTexture: displacementMap
- parameterUV: displacementUV
- type: Speech
speechVerb: Vox
speechSounds: Vox
sprite: "Effects/creampie.rsi"
state: "creampie_vox" # Not default
visible: false
+ - type: Inventory
+ speciesId: vox
+ displacements:
+ jumpsuit:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: jumpsuit
+ eyes:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: eyes
+ gloves:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: hand
+ back:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: back
+ ears:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: ears
+ shoes:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: shoes
- type: entity
parent: BaseSpeciesDummy
speciesId: vox
displacements:
jumpsuit:
- layer:
- sprite: Mobs/Species/Vox/displacement.rsi
- state: jumpsuit
- copyToShaderParameters:
- # Value required, provide a dummy. Gets overridden when applied.
- layerKey: dummy
- parameterTexture: displacementMap
- parameterUV: displacementUV
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: jumpsuit
eyes:
- layer:
- sprite: Mobs/Species/Vox/displacement.rsi
- state: eyes
- copyToShaderParameters:
- layerKey: dummy
- parameterTexture: displacementMap
- parameterUV: displacementUV
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: eyes
gloves:
- layer:
- sprite: Mobs/Species/Vox/displacement.rsi
- state: hand
- copyToShaderParameters:
- layerKey: dummy
- parameterTexture: displacementMap
- parameterUV: displacementUV
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: hand
back:
- layer:
- sprite: Mobs/Species/Vox/displacement.rsi
- state: back
- copyToShaderParameters:
- layerKey: dummy
- parameterTexture: displacementMap
- parameterUV: displacementUV
-
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: back
+ ears:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: ears
+ shoes:
+ sizeMaps:
+ 32:
+ sprite: Mobs/Species/Vox/displacement.rsi
+ state: shoes
--- /dev/null
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Made by TheShuEd",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "load": {
+ "srgb": false
+ },
+ "states": [
+ {
+ "name": "jumpsuit-female",
+ "directions": 4
+ }
+ ]
+}
{
"version": 1,
"license": "CC-BY-SA-3.0",
- "copyright": "jumpsuit state made by PJB3005. back, hand, and eyes states made by Flareguy",
+ "copyright": "jumpsuit state made by PJB3005. back, hand, and eyes states made by Flareguy, ears and shoes made by TheShuEd",
"size": {
"x": 32,
"y": 32
"name": "hand",
"directions": 4
},
+ {
+ "name": "ears",
+ "directions": 4
+ },
{
"name": "eyes",
"directions": 4
+ },
+ {
+ "name": "shoes",
+ "directions": 4
}
]
}