Files
wwdpublic/Content.Client/Body/Systems/BodySystem.cs
VMSolidus 9117ff238c Marking Shaders (#2432)
# Description

This PR adds shader support to markings, which can define specific
layers that have a shader, and which shader is desired. I wanted to have
glowing eyes like my character in Aurora does, but was frustrated that I
couldn't. So here's that tiny feature now.

<details><summary><h1>Media</h1></summary>
<p>


![image](https://github.com/user-attachments/assets/f8241813-3f3d-4c5a-84f1-3ea8e291e258)

</p>
</details>

# Changelog

🆑
- add: Markings can now use shaders. Including things like glowing light
effects. You can now also have glowing cybernetic eyes. IPC head screens
now glow.
2025-07-12 01:12:42 +10:00

81 lines
2.7 KiB
C#

using Content.Shared.Body.Systems;
// Shitmed Change Start
using Content.Shared._Shitmed.Body.Part;
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings;
using Robust.Client.GameObjects;
using Robust.Shared.Utility;
using Content.Shared.Body.Components;
// Shitmed Change End
namespace Content.Client.Body.Systems;
public sealed class BodySystem : SharedBodySystem
{
// Shitmed Change Start
[Dependency] private readonly MarkingManager _markingManager = default!;
private void ApplyMarkingToPart(MarkingPrototype markingPrototype,
IReadOnlyList<Color>? colors,
bool visible,
SpriteComponent sprite)
{
for (var j = 0; j < markingPrototype.Sprites.Count; j++)
{
var markingSprite = markingPrototype.Sprites[j];
if (markingSprite is not SpriteSpecifier.Rsi rsi)
continue;
var layerId = $"{markingPrototype.ID}-{rsi.RsiState}";
if (!sprite.LayerMapTryGet(layerId, out _))
{
var layer = sprite.AddLayer(markingSprite, j + 1);
sprite.LayerMapSet(layerId, layer);
sprite.LayerSetSprite(layerId, rsi);
}
sprite.LayerSetVisible(layerId, visible);
if (!visible)
continue;
// 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(layerId, colors[j]);
else
sprite.LayerSetColor(layerId, Color.White);
var shaders = markingPrototype.Shaders;
if (shaders is not null && shaders.ContainsKey(rsi.RsiState))
sprite.LayerSetShader(layerId, shaders[rsi.RsiState]);
}
}
protected override void ApplyPartMarkings(EntityUid target, BodyPartAppearanceComponent component)
{
if (!TryComp(target, out SpriteComponent? sprite))
return;
if (component.Color != null)
sprite.Color = component.Color.Value;
foreach (var (visualLayer, markingList) in component.Markings)
foreach (var marking in markingList)
{
if (!_markingManager.TryGetMarking(marking, out var markingPrototype))
continue;
ApplyMarkingToPart(markingPrototype, marking.MarkingColors, marking.Visible, sprite);
}
}
protected override void RemoveBodyMarkings(EntityUid target, BodyPartAppearanceComponent partAppearance, HumanoidAppearanceComponent bodyAppearance)
{
return;
}
// Shitmed Change End
}