using Content.Shared.Chemistry;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent;
+using Content.Shared.Clothing;
+using Content.Shared.Clothing.Components;
using Content.Shared.Hands;
using Content.Shared.Item;
using Content.Shared.Rounding;
base.Initialize();
SubscribeLocalEvent<SolutionContainerVisualsComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<SolutionContainerVisualsComponent, GetInhandVisualsEvent>(OnGetHeldVisuals);
+ SubscribeLocalEvent<SolutionContainerVisualsComponent, GetEquipmentVisualsEvent>(OnGetClothingVisuals);
}
private void OnMapInit(EntityUid uid, SolutionContainerVisualsComponent component, MapInitEvent args)
args.Layers.Add((key, layer));
}
}
+
+ private void OnGetClothingVisuals(Entity<SolutionContainerVisualsComponent> ent, ref GetEquipmentVisualsEvent args)
+ {
+ if (ent.Comp.EquippedFillBaseName == null)
+ return;
+
+ if (!TryComp<AppearanceComponent>(ent, out var appearance))
+ return;
+
+ if (!TryComp<ClothingComponent>(ent, out var clothing))
+ return;
+
+ if (!AppearanceSystem.TryGetData<float>(ent, SolutionContainerVisuals.FillFraction, out var fraction, appearance))
+ return;
+
+ var closestFillSprite = ContentHelpers.RoundToLevels(fraction, 1, ent.Comp.EquippedMaxFillLevels + 1);
+
+ if (closestFillSprite > 0)
+ {
+ var layer = new PrototypeLayerData();
+
+ var equippedPrefix = clothing.EquippedPrefix == null ? $"equipped-{args.Slot}" : $" {clothing.EquippedPrefix}-equipped-{args.Slot}";
+ var key = equippedPrefix + ent.Comp.EquippedFillBaseName + closestFillSprite;
+
+ // Make sure the sprite state is valid so we don't show a big red error message
+ // This saves us from having to make fill level sprites for every possible slot the item could be in (including pockets).
+ if (!TryComp<SpriteComponent>(ent, out var sprite) || sprite.BaseRSI == null || !sprite.BaseRSI.TryGetState(key, out _))
+ return;
+
+ layer.State = key;
+
+ if (ent.Comp.ChangeColor && AppearanceSystem.TryGetData<Color>(ent, SolutionContainerVisuals.Color, out var color, appearance))
+ layer.Color = color;
+
+ args.Layers.Add((key, layer));
+ }
+ }
}
/// </summary>
[DataField]
public int InHandsMaxFillLevels = 0;
+
+ /// <summary>
+ /// Optional equipped visuals to show someone is wearing a something with a filled container.
+ /// </summary>
+ [DataField]
+ public string? EquippedFillBaseName = null;
+
+ /// <summary>
+ /// A separate max fill levels for equipped items (to reduce number of sprites needed)
+ /// </summary>
+ [DataField]
+ public int EquippedMaxFillLevels = 0;
}
}
- type: SolutionContainerVisuals
maxFillLevels: 1
fillBaseName: spear
+ inHandsFillBaseName: -fill-
+ inHandsMaxFillLevels: 1
+ equippedFillBaseName: -fill-
+ equippedMaxFillLevels: 1
+
- type: entity
name: reinforced spear
},
"states": [
{
- "name": "spear"
+ "name": "spear"
},
{
- "name": "spear1"
+ "name": "spear1"
},
{
- "name": "inhand-left",
- "directions": 4
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-left-fill-1",
+ "directions": 4
},
{
- "name": "inhand-right",
- "directions": 4
+ "name": "inhand-right",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right-fill-1",
+ "directions": 4
},
{
"name": "wielded-inhand-left",
"directions": 4
},
+ {
+ "name": "wielded-inhand-left-fill-1",
+ "directions": 4
+ },
{
"name": "wielded-inhand-right",
"directions": 4
},
{
- "name": "equipped-BACKPACK",
- "directions": 4
+ "name": "wielded-inhand-right-fill-1",
+ "directions": 4
+ },
+ {
+ "name": "equipped-BACKPACK",
+ "directions": 4
+ },
+ {
+ "name": "equipped-back-fill-1",
+ "directions": 4
},
{
"name": "equipped-SUITSTORAGE",
"directions": 4
+ },
+ {
+ "name": "equipped-suitstorage-fill-1",
+ "directions": 4
}
]
}
},
"states": [
{
- "name": "spear"
+ "name": "spear"
},
{
- "name": "spear1"
+ "name": "spear1"
},
{
- "name": "inhand-left",
- "directions": 4
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-left-fill-1",
+ "directions": 4
},
{
- "name": "inhand-right",
- "directions": 4
+ "name": "inhand-right",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right-fill-1",
+ "directions": 4
},
{
"name": "wielded-inhand-left",
"directions": 4
},
+ {
+ "name": "wielded-inhand-left-fill-1",
+ "directions": 4
+ },
{
"name": "wielded-inhand-right",
"directions": 4
},
{
- "name": "equipped-BACKPACK",
- "directions": 4
+ "name": "wielded-inhand-right-fill-1",
+ "directions": 4
+ },
+ {
+ "name": "equipped-BACKPACK",
+ "directions": 4
+ },
+ {
+ "name": "equipped-back-fill-1",
+ "directions": 4
},
{
"name": "equipped-SUITSTORAGE",
"directions": 4
+ },
+ {
+ "name": "equipped-suitstorage-fill-1",
+ "directions": 4
}
]
}
},
"states": [
{
- "name": "spear"
+ "name": "spear"
},
{
- "name": "spear1"
+ "name": "spear1"
},
{
- "name": "inhand-left",
- "directions": 4
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-left-fill-1",
+ "directions": 4
},
{
- "name": "inhand-right",
- "directions": 4
+ "name": "inhand-right",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right-fill-1",
+ "directions": 4
},
{
"name": "wielded-inhand-left",
"directions": 4
},
+ {
+ "name": "wielded-inhand-left-fill-1",
+ "directions": 4
+ },
{
"name": "wielded-inhand-right",
"directions": 4
},
{
- "name": "equipped-BACKPACK",
- "directions": 4
+ "name": "wielded-inhand-right-fill-1",
+ "directions": 4
+ },
+ {
+ "name": "equipped-BACKPACK",
+ "directions": 4
+ },
+ {
+ "name": "equipped-back-fill-1",
+ "directions": 4
},
{
"name": "equipped-SUITSTORAGE",
"directions": 4
+ },
+ {
+ "name": "equipped-suitstorage-fill-1",
+ "directions": 4
}
]
}
},
"states": [
{
- "name": "spear"
+ "name": "spear"
},
{
- "name": "spear1"
+ "name": "spear1"
},
{
- "name": "inhand-left",
- "directions": 4
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-left-fill-1",
+ "directions": 4
},
{
- "name": "inhand-right",
- "directions": 4
+ "name": "inhand-right",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right-fill-1",
+ "directions": 4
},
{
"name": "wielded-inhand-left",
"directions": 4
},
+ {
+ "name": "wielded-inhand-left-fill-1",
+ "directions": 4
+ },
{
"name": "wielded-inhand-right",
"directions": 4
},
{
- "name": "equipped-BACKPACK",
- "directions": 4
+ "name": "wielded-inhand-right-fill-1",
+ "directions": 4
+ },
+ {
+ "name": "equipped-BACKPACK",
+ "directions": 4
+ },
+ {
+ "name": "equipped-back-fill-1",
+ "directions": 4
},
{
"name": "equipped-SUITSTORAGE",
"directions": 4
+ },
+ {
+ "name": "equipped-suitstorage-fill-1",
+ "directions": 4
}
]
}
},
"states": [
{
- "name": "spear"
+ "name": "spear"
},
{
- "name": "spear1"
+ "name": "spear1"
},
{
- "name": "inhand-left",
- "directions": 4
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-left-fill-1",
+ "directions": 4
},
{
- "name": "inhand-right",
- "directions": 4
+ "name": "inhand-right",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right-fill-1",
+ "directions": 4
},
{
"name": "wielded-inhand-left",
"directions": 4
},
+ {
+ "name": "wielded-inhand-left-fill-1",
+ "directions": 4
+ },
{
"name": "wielded-inhand-right",
"directions": 4
},
{
- "name": "equipped-BACKPACK",
- "directions": 4
+ "name": "wielded-inhand-right-fill-1",
+ "directions": 4
+ },
+ {
+ "name": "equipped-BACKPACK",
+ "directions": 4
+ },
+ {
+ "name": "equipped-back-fill-1",
+ "directions": 4
},
{
"name": "equipped-SUITSTORAGE",
"directions": 4
+ },
+ {
+ "name": "equipped-suitstorage-fill-1",
+ "directions": 4
}
]
}