From 9f39c112adc27516737ce112cc7f010b791bdad6 Mon Sep 17 00:00:00 2001 From: hivehum Date: Sun, 25 May 2025 20:57:56 -0400 Subject: [PATCH] PORT: Allows Markings to Set Custom Layers for Specific Sprites (#2516) * multilayer markings * vestigial reptilian tail sprites added * i fix :) --------- Co-authored-by: mq <113324899+mqole@users.noreply.github.com> --- .../Humanoid/HumanoidAppearanceSystem.cs | 126 +++++++++++++++--- Content.Client/Humanoid/MarkingPicker.xaml.cs | 27 +++- .../Tests/Sprite/ItemSpriteTest.cs | 6 +- .../Humanoid/HumanoidVisualLayers.cs | 43 ++++++ .../Humanoid/HumanoidVisualLayersExtension.cs | 3 + .../Humanoid/Markings/MarkingColoring.cs | 6 +- .../Humanoid/Markings/MarkingPrototype.cs | 104 ++++++++++++++- .../Mobs/Customization/Markings/reptilian.yml | 78 +++++++---- .../Entities/Mobs/Species/arachnid.yml | 2 + .../Prototypes/Entities/Mobs/Species/base.yml | 9 +- .../Prototypes/Entities/Mobs/Species/moth.yml | 2 + .../Prototypes/Entities/Mobs/Species/vox.yml | 2 + Resources/Prototypes/Species/arachnid.yml | 2 + Resources/Prototypes/Species/diona.yml | 2 + Resources/Prototypes/Species/gingerbread.yml | 2 + Resources/Prototypes/Species/human.yml | 2 + Resources/Prototypes/Species/moth.yml | 2 + Resources/Prototypes/Species/reptilian.yml | 3 + Resources/Prototypes/Species/slime.yml | 2 + Resources/Prototypes/Species/vox.yml | 2 + 20 files changed, 377 insertions(+), 48 deletions(-) diff --git a/Content.Client/Humanoid/HumanoidAppearanceSystem.cs b/Content.Client/Humanoid/HumanoidAppearanceSystem.cs index 54c2801e33..d74dcaf72a 100644 --- a/Content.Client/Humanoid/HumanoidAppearanceSystem.cs +++ b/Content.Client/Humanoid/HumanoidAppearanceSystem.cs @@ -146,7 +146,7 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem var customBaseLayers = new Dictionary(); - var speciesPrototype = _prototypeManager.Index(profile.Species); + var speciesPrototype = _prototypeManager.Index(profile.Species); // Floof var markings = new MarkingSet(speciesPrototype.MarkingPoints, _markingManager, _prototypeManager); // Add markings that doesn't need coloring. We store them until we add all other markings that doesn't need it. @@ -343,32 +343,116 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem bool visible, Entity entity) { - var humanoid = entity.Comp1; - var sprite = entity.Comp2; + // hi! mq here. + // if youre dealing with upstream merge conflicts, and you see a bunch of stuff up here, chances are its been moved in between some other shit. + // i love the documentation on this file but i can only look at layer maps for so long before i feel myself becoming ben affleck. + // sorry for any confusion. - if (!_sprite.LayerMapTryGet((entity.Owner, sprite), markingPrototype.BodyPart, out var targetLayer, false)) - return; - - visible &= !IsHidden(humanoid, markingPrototype.BodyPart); - visible &= humanoid.BaseLayers.TryGetValue(markingPrototype.BodyPart, out var setting) - && setting.AllowsMarkings; + // FLOOF ADD START + // make a handy dict of filename -> colors + // cus we might need to access it by filename to link + // one sprite's colors to another + var colorDict = new Dictionary(); + for (var i = 0; i < markingPrototype.Sprites.Count; i++) + { + var spriteName = markingPrototype.Sprites[i] switch + { + SpriteSpecifier.Rsi rsi => rsi.RsiState, + SpriteSpecifier.Texture texture => texture.TexturePath.Filename, + _ => null + }; + if (spriteName != null) + { + if (colors != null && i < colors.Count) + colorDict.Add(spriteName, colors[i]); + else + colorDict.Add(spriteName, Color.White); + } + } + // now, rearrange them, copying any parented colors to children set to + // inherit them + if (markingPrototype.ColorLinks != null) + { + foreach (var (child, parent) in markingPrototype.ColorLinks) + { + if (colorDict.TryGetValue(parent, out var color)) + { + colorDict[child] = color; + } + } + } + // and, since we can't rely on the iterator knowing where the heck to put + // each sprite when we have one marking setting multiple layers, + // lets just kinda sorta do that ourselves + var layerDict = new Dictionary(); + // FLOOF ADD END for (var j = 0; j < markingPrototype.Sprites.Count; j++) { var markingSprite = markingPrototype.Sprites[j]; - if (markingSprite is not SpriteSpecifier.Rsi rsi) - return; + { + continue; + } + + // FLOOF CHANGE START + var layerSlot = markingPrototype.BodyPart; + // first, try to see if there are any custom layers for this marking + if (markingPrototype.Layering != null) + { + var name = rsi.RsiState; + if (markingPrototype.Layering.TryGetValue(name, out var layerName)) + { + layerSlot = Enum.Parse(layerName); + } + } + // update the layerDict + // if it doesnt have this, add it at 0, otherwise increment it + if (layerDict.TryGetValue(layerSlot.ToString(), out var layerIndex)) + { + layerDict[layerSlot.ToString()] = layerIndex + 1; + } + else + { + layerDict.Add(layerSlot.ToString(), 0); + } + + // THIS IS THE UPSTREAM STUFF!!! RIGHT HERE!!! + var humanoid = entity.Comp1; + var sprite = entity.Comp2; + + if (!_sprite.LayerMapTryGet((entity.Owner, sprite), layerSlot, out var targetLayer, false)) + { + continue; + } + + visible &= !IsHidden(humanoid, markingPrototype.BodyPart); + visible &= humanoid.BaseLayers.TryGetValue(markingPrototype.BodyPart, out var setting) + && setting.AllowsMarkings; + // FLOOF CHANGE END var layerId = $"{markingPrototype.ID}-{rsi.RsiState}"; - if (!_sprite.LayerMapTryGet((entity.Owner, sprite), layerId, out _, false)) + if (!_sprite.LayerMapTryGet((entity.Owner, sprite), layerId, out layerIndex, false)) // imp layerindex { - var layer = _sprite.AddLayer((entity.Owner, sprite), markingSprite, targetLayer + j + 1); + // for layers that are supposed to be behind everything, + // adding 1 to the layer index makes it not be behind + // everything. fun! FLOOF ADD =3 + // var targLayerAdj = targetLayer == 0 ? 0 + j : targetLayer + j + 1; + var targLayerAdj = targetLayer + layerDict[layerSlot.ToString()] + 1; + var layer = _sprite.AddLayer((entity.Owner, sprite), markingSprite, targLayerAdj); _sprite.LayerMapSet((entity.Owner, sprite), layerId, layer); _sprite.LayerSetSprite((entity.Owner, sprite), layerId, rsi); } + // imp special via beck. check if there's a shader defined in the markingPrototype's shader datafield, and if there is... + if (markingPrototype.Shader != null) + { + // use spriteComponent's layersetshader function to set the layer's shader to that which is specified. + sprite.LayerSetShader(layerId, markingPrototype.Shader); + } + // end imp special + _sprite.LayerSetVisible((entity.Owner, sprite), layerId, visible); if (!visible || setting == null) // this is kinda implied @@ -377,10 +461,18 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem // Okay so if the marking prototype is modified but we load old marking data this may no longer be valid // and we need to check the index is correct. // So if that happens just default to white? - if (colors != null && j < colors.Count) - _sprite.LayerSetColor((entity.Owner, sprite), layerId, colors[j]); - else - _sprite.LayerSetColor((entity.Owner, sprite), layerId, Color.White); + // FLOOF ADD =3 + _sprite.LayerSetColor((entity.Owner, sprite), layerId, colorDict.TryGetValue(rsi.RsiState, out var color) ? color : Color.White); + + // FLOOF REMOVE + // if (colors != null && j < colors.Count) + // { + // _sprite.LayerSetColor((entity.Owner, sprite), layerId, colors[j]); + // } + // else + // { + // _sprite.LayerSetColor((entity.Owner, sprite), layerId, Color.White); + // } if (humanoid.MarkingsDisplacement.TryGetValue(markingPrototype.BodyPart, out var displacementData) && markingPrototype.CanBeDisplaced) _displacement.TryAddDisplacement(displacementData, (entity.Owner, sprite), targetLayer + j + 1, layerId, out _); diff --git a/Content.Client/Humanoid/MarkingPicker.xaml.cs b/Content.Client/Humanoid/MarkingPicker.xaml.cs index 992a72b930..82936a8450 100644 --- a/Content.Client/Humanoid/MarkingPicker.xaml.cs +++ b/Content.Client/Humanoid/MarkingPicker.xaml.cs @@ -408,12 +408,37 @@ public sealed partial class MarkingPicker : Control List colorSliders = new(); for (int i = 0; i < prototype.Sprites.Count; i++) { + // first, check if the coloration is parented to another marking + // and if so, just kinda sorta dont display it + var skipdraw = false; + if (prototype.ColorLinks?.Count > 0) + { + var name = prototype.Sprites[i] switch + { + SpriteSpecifier.Rsi rsi => rsi.RsiState, + SpriteSpecifier.Texture texture => texture.TexturePath.Filename, + _ => null + }; + + if (name != null && prototype.ColorLinks.ContainsKey(name)) + { + // dont show it, cus its parented to another marking + skipdraw = true; + } + } var colorContainer = new BoxContainer { Orientation = LayoutOrientation.Vertical, }; - CMarkingColors.AddChild(colorContainer); + // so. + // the color selector sliders decide which destination color to modify + // based on its index in the list of color selectors. + // this is a problem if we, say, want to *not* show a certain slider + // cus then it'll modify the wrong color, unless the color happened to + // be in index 0. + if(!skipdraw) + CMarkingColors.AddChild(colorContainer); ColorSelectorSliders colorSelector = new ColorSelectorSliders(); colorSelector.SelectorType = ColorSelectorSliders.ColorSelectorType.Hsv; // defaults color selector to HSV diff --git a/Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs b/Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs index da7e1e8e9b..3bd8cd900b 100644 --- a/Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs +++ b/Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs @@ -28,7 +28,11 @@ public sealed class PrototypeSaveTest { // The only prototypes that should get ignored are those that REQUIRE setup to get a sprite. At that point it is // the responsibility of the spawner to ensure that a valid sprite is set. - "VirtualItem" + "VirtualItem", + "MobGoblin", // imp edits - these four prototypes are species and do not receive their sprite data from ItemComponent, causing a false positive + "MobGoblinStowaway", + "MobGoblinKnight", + "MobGoblinCastaway", }; [Test] diff --git a/Content.Shared/Humanoid/HumanoidVisualLayers.cs b/Content.Shared/Humanoid/HumanoidVisualLayers.cs index 6b5f163000..a6a3b5612a 100644 --- a/Content.Shared/Humanoid/HumanoidVisualLayers.cs +++ b/Content.Shared/Humanoid/HumanoidVisualLayers.cs @@ -3,6 +3,10 @@ using Robust.Shared.Serialization; namespace Content.Shared.Humanoid { + /// + /// These are the layer defines for the humanoid sprite system. + /// If you want to add a new layer slot to species? Scroll down~ + /// [Serializable, NetSerializable] public enum HumanoidVisualLayers : byte { @@ -18,6 +22,9 @@ namespace Content.Shared.Humanoid SnoutCover, // things layered over snouts (i.e. noses) HeadSide, // side parts (i.e., frills) HeadTop, // top parts (i.e., ears) + TailBehind, // FLOOF - add tails that dont have to go through a brutal cookiecutter to work + TailBehindBackpack, // imp - to layer behind backpacks, treat this like an oversuit + TailOversuit, // FLOOF - add tails that dont have to go through a brutal cookiecutter to work Eyes, RArm, LArm, @@ -34,3 +41,39 @@ namespace Content.Shared.Humanoid } } + +/* * * * * * * * * * * * * * * * * * * * * * * * * + * HOW 2 ADD A NEW LAYER FOR MOB NON-EQUIPMENT APPEARANCE STUFF + * by Dank Elly + * Lets say you want to add something like socks to be selectable through markings + * Since people tend to have two feet, you'll actually need two new layers! one for each foot. + * First, add in the enum above a new layer slot, like so: + * LSock, + * RSock, + * Easy huh? Note that this enum does *not* define which layer in relation to other layers it will be layered! + * Next, since these'll be a whole new marking type, we'll need to add in a new marking category. + * in Content.Shared/Humanoid/Markings/MarkingCategories.cs, add in a new category for the socks + * lets assume we'll let the player pick two different socks, which means two different categories + * Its done the same way as this enum here + * Next, go to Content.Shared/Humanoid/HumanoidVisualLayersExtension.cs + * In here, find Sublayers() and add in the new layers to the switch statement + * case HumanoidVisualLayers.LFoot: + * yield return HumanoidVisualLayers.LSock; + * and so on. This will make it so if your leg/foot stops being visible, the sock will vanish as well! i think + * Next, we'll have to go through a lot of species files, to change a few things: + * speciesBaseSprites + * I'm not sure what this does, but you'll want to add in an entry under sprites for the new layer + * LSock: MobHumanoidAnyMarking <- I think this makes it selectable in the editor, and blank by default? + * RSock: MobHumanoidAnyMarking + * layers + * This is part of the species entity prototype, and this is where the sprite layering is defined. + * Note that this includes equipment layers, which means you can totally, say, have a tail sit between your suit and your backpack! + * - map: [ "enum.HumanoidVisualLayers.LFoot" ] + * - map: [ "enum.HumanoidVisualLayers.LSock" ] + * - map: [ "enum.HumanoidVisualLayers.RFoot" ] + * - map: [ "enum.HumanoidVisualLayers.RSock" ] + * This will make it so the socks are drawn on top of the feet, and not behind them. + * I'd list which files these are in, but there are a million different species files, all with the same name, in different folders + * So just search for "speciesBaseSprites" and "enum.HumanoidVisualLayers.Chest" and you'll find them all + * If you miss some, dont sweat it, someone'll point it out and then you can fix it! Hotties like you make the hottest hotfixes~ + */ diff --git a/Content.Shared/Humanoid/HumanoidVisualLayersExtension.cs b/Content.Shared/Humanoid/HumanoidVisualLayersExtension.cs index 1365c488d8..82441a3205 100644 --- a/Content.Shared/Humanoid/HumanoidVisualLayersExtension.cs +++ b/Content.Shared/Humanoid/HumanoidVisualLayersExtension.cs @@ -67,6 +67,9 @@ namespace Content.Shared.Humanoid case HumanoidVisualLayers.Chest: yield return HumanoidVisualLayers.Chest; yield return HumanoidVisualLayers.Tail; + yield return HumanoidVisualLayers.TailBehind; + yield return HumanoidVisualLayers.TailBehindBackpack; + yield return HumanoidVisualLayers.TailOversuit; break; default: yield break; diff --git a/Content.Shared/Humanoid/Markings/MarkingColoring.cs b/Content.Shared/Humanoid/Markings/MarkingColoring.cs index fa47475a23..f39becd15c 100644 --- a/Content.Shared/Humanoid/Markings/MarkingColoring.cs +++ b/Content.Shared/Humanoid/Markings/MarkingColoring.cs @@ -26,12 +26,12 @@ public static class MarkingColoring /// /// Returns list of colors for marking layers /// - public static List GetMarkingLayerColors - ( + public static List GetMarkingLayerColors( MarkingPrototype prototype, Color? skinColor, Color? eyeColor, - MarkingSet markingSet + MarkingSet markingSet, + List? ignores = null // Floof ) { var colors = new List(); diff --git a/Content.Shared/Humanoid/Markings/MarkingPrototype.cs b/Content.Shared/Humanoid/Markings/MarkingPrototype.cs index a6c578015a..f83414c9d0 100644 --- a/Content.Shared/Humanoid/Markings/MarkingPrototype.cs +++ b/Content.Shared/Humanoid/Markings/MarkingPrototype.cs @@ -3,7 +3,7 @@ using Robust.Shared.Utility; namespace Content.Shared.Humanoid.Markings { - [Prototype] + [Prototype("marking")] // Floof public sealed partial class MarkingPrototype : IPrototype { [IdDataField] @@ -42,9 +42,111 @@ namespace Content.Shared.Humanoid.Markings [DataField("sprites", required: true)] public List Sprites { get; private set; } = default!; + [DataField("shader")] + public string? Shader { get; private set; } = null; + + /// + /// Allows specific images to be put into any arbitrary layer on the mob. + /// Whole point of this is to have things like tails be able to be + /// behind the mob when facing south-east-west, but in front of the mob + /// when facing north. This requires two+ sprites, each in a different + /// layer. + /// Is a dictionary: sprite name -> layer name, + /// e.g. "tail-cute-vulp" -> "tail-back", "tail-cute-vulp-oversuit" -> "tail-oversuit" + /// also, FLOOF ADD =3 + /// + [DataField("layering")] + public Dictionary? Layering { get; private set; } + + /// + /// Allows you to link a specific sprite's coloring to another sprite's coloring. + /// This is useful for things like tails, which while they have two sets of sprites, + /// the two sets of sprites should be treated as one sprite for the purposes of + /// coloring. Just more intuitive that way~ + /// Format: spritename getting colored -> spritename which colors it + /// so if we have a Tail Behind with 'cooltail' as the sprite name, and a Tail Oversuit + /// with 'cooltail-oversuit' as the sprite name, and we want to have the Tail Behind + /// inherit the color of the Tail Oversuit, we would do: + /// cooltail -> cooltail-oversuit + /// cooltail will be hidden from the color picker, and just use whatevers set for + /// cooltail-oversuit. Easy huh? + /// also, FLOOF ADD =3 + /// + [DataField("colorLinks")] + public Dictionary? ColorLinks { get; private set; } + public Marking AsMarking() { return new Marking(ID, Sprites.Count); } } } + +/* * * * * * * * * * * * * * * * * * * * * * * * * + * HOW 2 MAKE MARKINGS WITH MULTIPLE LAYERS + * by Dank Elly + * + * So, since the dawn of SS14, markings have been a single layer. + * This is fine, since most markings are simple in terms of how they appear on a mob. + * Just a cool skin color, or a pattern, or something. + * + * Then, tails were added. + * Tails are different, if you think about it! + * They tend to hang from the body, and appear behind the mob from some angles, and + * in front of the mob from others. No real way around it, otherwise it'll look wierd! + * + * But, markings are still a single layer, which means that all the images sit in the + * stacked deck of cards that is our sprite layers. If a marking is set to be in the + * Underwear layer, that marking will only ever be in the Underwear layer, no matter + * which way you turn! Fine and all for most markings, but not for tails. + * + * The previous solution was to just cookie-cut out a human shape from some directions + * of the tail sprites, then layer then on top of the mob, over clothes and such. + * This worked! Sort of! It wouldnt support missing legs, it only worked if you were + * wearing skin-tight jumpsuits, and it made it so that you can't have any fancy leg + * shapes (digilegs my beloved~) + * + * However, SS13 had solved this years ago, which I am totally taking credit for cus + * I made roughly this system for Goonstation! The solution here was to just use + * two layers lmao! A layer for the tail from most angles, and a layer for the tail + * when youre facing away. This is known as the Behind and Oversuit layers, cus one + * goes behind the mob, the other goes over your suit (and ideally under the backpack). + * + * LOREDUMP OVER HOW TO MAKE IT DO THIS + * + * First, make your marking prototype as normal. + * Note, you'll need extra sprites for every layer you want to add. + * This includes things like colorable accessories, which will need to be + * added to the new layers as well. + * Next, add in a 'layering' entry to the marking prototype. + * Then, add in a new entry to the 'layering' dictionary, like so: + * layering: + * name_of_image: LayerToPutItIn + * name_of_another_image: LayerToPutItIn + * I'll have a complete example later, but this is the basic idea. + * The first part of the entry is what you put for the state of that sprite + * Its how the game knows which sprite to mess with! + * The second part is the layer you want to put it in. + * This points to an entry in the enum stored in this file: + * Content.Shared/Humanoid/HumanoidVisualLayers.cs + * Capitalization matters! + * todo: a way to link the colorations between layers + * + * Heres an example from Resources/Prototypes/Floof/Entities/Mobs/Customization/Markings/debug.yml + * +- type: marking + id: TailDebugPro + bodyPart: Tail + markingCategory: Tail + speciesRestriction: [Reptilian, SlimePerson, IPC, Rodentia, Vulpkanin, Felinid, Human, Oni] + layering: + tail_oversuit: TailOversuit <--------------\ + tail_behind: TailBehind <----------------+--------\ + sprites: | | + - sprite: _Floof/Mobs/Customization/debug.rsi | | + state: tail_oversuit >-------------------/ | + - sprite: _Floof/Mobs/Customization/debug.rsi | + state: tail_behind >------------------------------/ + * + * (dont include the arrows lol) + */ diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml index f9bae9ef1a..b000e1def6 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/reptilian.yml @@ -131,7 +131,16 @@ bodyPart: Tail markingCategory: Tail speciesRestriction: [Reptilian] + # imp edit below + layering: + tail_smooth_front: TailBehindBackpack + tail_smooth_primary: TailBehind + tail_smooth_secondary: TailBehind + colorLinks: + tail_smooth_primary: tail_smooth_front sprites: + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_smooth_front - sprite: Mobs/Customization/reptilian_parts.rsi state: tail_smooth_primary - sprite: Mobs/Customization/reptilian_parts.rsi @@ -142,36 +151,68 @@ bodyPart: Tail markingCategory: Tail speciesRestriction: [Reptilian] + # imp edit below + layering: + tail_large_front: TailBehindBackpack + tail_large_behind: TailBehind + colorLinks: + tail_large_behind: tail_large_front sprites: - sprite: Mobs/Customization/reptilian_parts.rsi - state: tail_large + state: tail_large_front + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_large_behind - type: marking id: LizardTailSpikes bodyPart: Tail markingCategory: Tail speciesRestriction: [Reptilian] + # imp edit below + layering: + tail_spikes_front: TailBehindBackpack + tail_spikes_behind: TailBehind + colorLinks: + tail_spikes_behind: tail_spikes_front sprites: - sprite: Mobs/Customization/reptilian_parts.rsi - state: tail_spikes + state: tail_spikes_behind + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_spikes_front - type: marking id: LizardTailLTiger bodyPart: Tail markingCategory: Tail speciesRestriction: [Reptilian] + # imp edit below + layering: + tail_ltiger_front: TailBehindBackpack + tail_ltiger_behind: TailBehind + colorLinks: + tail_ltiger_behind: tail_ltiger_front sprites: - sprite: Mobs/Customization/reptilian_parts.rsi - state: tail_ltiger + state: tail_ltiger_front + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_ltiger_behind - type: marking id: LizardTailDTiger bodyPart: Tail markingCategory: Tail speciesRestriction: [Reptilian] + # imp edit below + layering: + tail_dtiger_front: TailBehindBackpack + tail_dtiger_behind: TailBehind + colorLinks: + tail_dtiger_behind: tail_dtiger_front sprites: - sprite: Mobs/Customization/reptilian_parts.rsi - state: tail_dtiger + state: tail_dtiger_front + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_dtiger_behind - type: marking id: LizardTailAquatic @@ -382,10 +423,10 @@ markingCategory: Tail speciesRestriction: [] sprites: - - sprite: Mobs/Customization/reptilian_parts.rsi - state: tail_smooth_wagging_primary - - sprite: Mobs/Customization/reptilian_parts.rsi - state: tail_smooth_wagging_secondary + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_smooth_wagging_primary + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_smooth_wagging_secondary - type: marking id: LizardTailLargeAnimated @@ -402,8 +443,8 @@ markingCategory: Tail speciesRestriction: [] sprites: - - sprite: Mobs/Customization/reptilian_parts.rsi - state: tail_spikes_wagging + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_spikes_wagging - type: marking id: LizardTailLTigerAnimated @@ -411,8 +452,8 @@ markingCategory: Tail speciesRestriction: [] sprites: - - sprite: Mobs/Customization/reptilian_parts.rsi - state: tail_ltiger_wagging + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_ltiger_wagging - type: marking id: LizardTailDTigerAnimated @@ -420,14 +461,5 @@ markingCategory: Tail speciesRestriction: [] sprites: - - sprite: Mobs/Customization/reptilian_parts.rsi - state: tail_dtiger_wagging - -- type: marking - id: LizardTailAquaticAnimated - bodyPart: Tail - markingCategory: Tail - speciesRestriction: [] - sprites: - - sprite: Mobs/Customization/reptilian_parts.rsi - state: tail_aquatic_wagging + - sprite: Mobs/Customization/reptilian_parts.rsi + state: tail_dtiger_wagging diff --git a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml index 0624e9670a..82f44ed144 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/arachnid.yml @@ -72,6 +72,7 @@ proto: spider - type: Sprite # I'd prefer if these maps were better. Insert map pun here. layers: + - map: [ "enum.HumanoidVisualLayers.TailBehind" ] # Floof - map: [ "enum.HumanoidVisualLayers.Chest" ] - map: [ "enum.HumanoidVisualLayers.Head" ] - map: [ "enum.HumanoidVisualLayers.Snout" ] @@ -94,6 +95,7 @@ - map: [ "outerClothing" ] - map: [ "enum.HumanoidVisualLayers.Tail" ] # Mentioned in moth code: This needs renaming lol. - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.TailOversuit" ] # Floof - map: [ "neck" ] - map: [ "enum.HumanoidVisualLayers.SnoutCover" ] - map: [ "enum.HumanoidVisualLayers.FacialHair" ] diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index dd94880b2f..cc4ff14d14 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -14,6 +14,7 @@ components: - type: Sprite layers: + - map: [ "enum.HumanoidVisualLayers.TailBehind" ] # Floof - map: [ "enum.HumanoidVisualLayers.Chest" ] - map: [ "enum.HumanoidVisualLayers.Head" ] - map: [ "enum.HumanoidVisualLayers.Snout" ] @@ -36,7 +37,9 @@ - map: [ "belt" ] - map: [ "id" ] - map: [ "outerClothing" ] + - map: [ "enum.HumanoidVisualLayers.TailBehindBackpack" ] # imp - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.TailOversuit" ] # Floof - map: [ "neck" ] - map: [ "enum.HumanoidVisualLayers.SnoutCover" ] - map: [ "enum.HumanoidVisualLayers.FacialHair" ] @@ -276,8 +279,8 @@ - type: Butcherable butcheringType: Spike # TODO human. spawned: - - id: FoodMeat - amount: 5 + - id: FoodMeat + amount: 5 - type: Respirator damage: types: @@ -306,6 +309,7 @@ noRot: true # TODO BODY Turn these into individual body parts? layers: + - map: [ "enum.HumanoidVisualLayers.TailBehind" ] - map: [ "enum.HumanoidVisualLayers.Chest" ] - map: [ "enum.HumanoidVisualLayers.Head" ] - map: [ "enum.HumanoidVisualLayers.Snout" ] @@ -334,6 +338,7 @@ - map: [ "id" ] - map: [ "outerClothing" ] - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.TailOversuit" ] - map: [ "neck" ] - map: [ "enum.HumanoidVisualLayers.SnoutCover" ] - map: [ "enum.HumanoidVisualLayers.FacialHair" ] diff --git a/Resources/Prototypes/Entities/Mobs/Species/moth.yml b/Resources/Prototypes/Entities/Mobs/Species/moth.yml index 9503c2f56d..c024634ba7 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/moth.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/moth.yml @@ -75,6 +75,7 @@ noRot: true drawdepth: Mobs layers: + - map: [ "enum.HumanoidVisualLayers.TailBehind" ] # Floof - map: [ "enum.HumanoidVisualLayers.Chest" ] - map: [ "enum.HumanoidVisualLayers.Head" ] - map: [ "enum.HumanoidVisualLayers.Snout" ] @@ -104,6 +105,7 @@ - map: [ "outerClothing" ] - map: [ "enum.HumanoidVisualLayers.Tail" ] #in the utopian future we should probably have a wings enum inserted here so everyhting doesn't break - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.TailOversuit" ] # Floof - map: [ "neck" ] - map: [ "enum.HumanoidVisualLayers.SnoutCover" ] - map: [ "enum.HumanoidVisualLayers.FacialHair" ] diff --git a/Resources/Prototypes/Entities/Mobs/Species/vox.yml b/Resources/Prototypes/Entities/Mobs/Species/vox.yml index 68ae44da6f..f2e8b3fa1b 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/vox.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/vox.yml @@ -109,6 +109,7 @@ Slash: 5 # Reduce? - type: Sprite # Need to redefine the whole order to draw the tail over their gas tank layers: + - map: [ "enum.HumanoidVisualLayers.TailBehind" ] # Floof - map: [ "enum.HumanoidVisualLayers.Chest" ] - map: [ "enum.HumanoidVisualLayers.Head" ] - map: [ "enum.HumanoidVisualLayers.Snout" ] @@ -132,6 +133,7 @@ - map: [ "id" ] - map: [ "outerClothing" ] - map: [ "back" ] + - map: [ "enum.HumanoidVisualLayers.TailOversuit" ] # Floof - map: [ "neck" ] - map: [ "suitstorage" ] # This is not in the default order - map: [ "enum.HumanoidVisualLayers.SnoutCover" ] diff --git a/Resources/Prototypes/Species/arachnid.yml b/Resources/Prototypes/Species/arachnid.yml index 619612773a..0ec5cb4636 100644 --- a/Resources/Prototypes/Species/arachnid.yml +++ b/Resources/Prototypes/Species/arachnid.yml @@ -17,6 +17,8 @@ - type: speciesBaseSprites id: MobArachnidSprites sprites: + TailBehind: MobHumanoidAnyMarking # floof + TailOversuit: MobHumanoidAnyMarking # floof Head: MobArachnidHead Snout: MobHumanoidAnyMarking UndergarmentTop: MobHumanoidAnyMarking diff --git a/Resources/Prototypes/Species/diona.yml b/Resources/Prototypes/Species/diona.yml index cfb42a460f..53a9be2dce 100644 --- a/Resources/Prototypes/Species/diona.yml +++ b/Resources/Prototypes/Species/diona.yml @@ -16,6 +16,8 @@ - type: speciesBaseSprites id: MobDionaSprites sprites: + TailBehind: MobHumanoidAnyMarking # floof + TailOversuit: MobHumanoidAnyMarking # floof Head: MobDionaHead HeadTop: MobHumanoidAnyMarking HeadSide: MobHumanoidAnyMarking diff --git a/Resources/Prototypes/Species/gingerbread.yml b/Resources/Prototypes/Species/gingerbread.yml index bcce8d6ca9..48fadd6f37 100644 --- a/Resources/Prototypes/Species/gingerbread.yml +++ b/Resources/Prototypes/Species/gingerbread.yml @@ -12,6 +12,8 @@ - type: speciesBaseSprites id: MobGingerbreadSprites sprites: + TailBehind: MobHumanoidAnyMarking # floof. just in case i guess? + TailOversuit: MobHumanoidAnyMarking # floof Head: MobGingerbreadHead HeadTop: MobHumanoidAnyMarking HeadSide: MobHumanoidAnyMarking diff --git a/Resources/Prototypes/Species/human.yml b/Resources/Prototypes/Species/human.yml index aef1c95fee..7f66cdfcea 100644 --- a/Resources/Prototypes/Species/human.yml +++ b/Resources/Prototypes/Species/human.yml @@ -17,6 +17,8 @@ - type: speciesBaseSprites id: MobHumanSprites sprites: + TailBehind: MobHumanoidAnyMarking # floof + TailOversuit: MobHumanoidAnyMarking # floof Special: MobHumanoidAnyMarking Head: MobHumanHead Hair: MobHumanoidAnyMarking diff --git a/Resources/Prototypes/Species/moth.yml b/Resources/Prototypes/Species/moth.yml index 0101b4a1e6..4d360ec7a0 100644 --- a/Resources/Prototypes/Species/moth.yml +++ b/Resources/Prototypes/Species/moth.yml @@ -15,6 +15,8 @@ - type: speciesBaseSprites id: MobMothSprites sprites: + TailBehind: MobHumanoidAnyMarking # floof + TailOversuit: MobHumanoidAnyMarking # floof Head: MobMothHead Snout: MobHumanoidAnyMarking UndergarmentTop: MobHumanoidAnyMarking diff --git a/Resources/Prototypes/Species/reptilian.yml b/Resources/Prototypes/Species/reptilian.yml index 8949be2e72..984acd38a5 100644 --- a/Resources/Prototypes/Species/reptilian.yml +++ b/Resources/Prototypes/Species/reptilian.yml @@ -15,6 +15,9 @@ - type: speciesBaseSprites id: MobReptilianSprites sprites: + TailBehind: MobHumanoidAnyMarking # floof + TailOversuit: MobHumanoidAnyMarking # floof + TailBehindBackpack: MobHumanoidAnyMarking # imp Head: MobReptilianHead Snout: MobHumanoidAnyMarking UndergarmentTop: MobHumanoidAnyMarking diff --git a/Resources/Prototypes/Species/slime.yml b/Resources/Prototypes/Species/slime.yml index 4227efe4f2..9a1ccc66b8 100644 --- a/Resources/Prototypes/Species/slime.yml +++ b/Resources/Prototypes/Species/slime.yml @@ -12,6 +12,8 @@ - type: speciesBaseSprites id: MobSlimeSprites sprites: + TailBehind: MobHumanoidAnyMarking # floof + TailOversuit: MobHumanoidAnyMarking # floof Head: MobSlimeHead Hair: MobSlimeMarkingFollowSkin FacialHair: MobSlimeMarkingFollowSkin diff --git a/Resources/Prototypes/Species/vox.yml b/Resources/Prototypes/Species/vox.yml index ab94fa3d02..67e089b5f7 100644 --- a/Resources/Prototypes/Species/vox.yml +++ b/Resources/Prototypes/Species/vox.yml @@ -17,6 +17,8 @@ - type: speciesBaseSprites id: MobVoxSprites sprites: + TailBehind: MobHumanoidAnyMarking # floof + TailOversuit: MobHumanoidAnyMarking # floof Head: MobVoxHead Snout: MobHumanoidAnyMarking Hair: MobHumanoidAnyMarking