ОБНОВЛЕНИЕ ДИСПЛЕЙСМЕНТОВ (#2578)

Co-authored-by: rhailrake <splatt.pr@gmail.com>
Co-authored-by: Odleer <131581952+Odleer@users.noreply.github.com>
This commit is contained in:
SplikZerys 2025-07-19 01:47:12 -04:00 committed by GitHub
parent 0a267bb53c
commit 12cf4f4406
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 373 additions and 8 deletions

View file

@ -4,9 +4,11 @@ using Content.Client.DisplacementMap;
using Content.Client.Examine;
using Content.Client.Strip;
using Content.Client.Verbs.UI;
using Content.Shared.DisplacementMap;
using Content.Shared.Hands;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Humanoid;
using Content.Shared.Inventory.VirtualItem;
using Content.Shared.Item;
using JetBrains.Annotations;
@ -16,6 +18,7 @@ using Robust.Client.UserInterface;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@ -26,6 +29,7 @@ namespace Content.Client.Hands.Systems
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IUserInterfaceManager _ui = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly StrippableSystem _stripSys = default!;
@ -350,13 +354,8 @@ namespace Content.Client.Hands.Systems
_sprite.LayerSetData((uid, sprite), index, layerData);
// Add displacement maps
var displacement = hand.Location switch
{
HandLocation.Left => handComp.LeftHandDisplacement,
HandLocation.Right => handComp.RightHandDisplacement,
_ => handComp.HandDisplacement
};
// Select displacement maps with body type support
var displacement = GetHandDisplacement(uid, hand.Location, handComp);
if (displacement is not null && _displacement.TryAddDisplacement(displacement, (uid, sprite), index, key, out var displacementKey))
revealedLayers.Add(displacementKey);
@ -365,6 +364,46 @@ namespace Content.Client.Hands.Systems
RaiseLocalEvent(held, new HeldVisualsUpdatedEvent(uid, revealedLayers), true);
}
/// <summary>
/// Get the appropriate displacement map for a hand, considering body type and hand location.
/// </summary>
private DisplacementData? GetHandDisplacement(EntityUid uid, HandLocation handLocation, HandsComponent handComp)
{
string? bodyTypeName = null;
if (TryComp(uid, out HumanoidAppearanceComponent? humanoid))
{
bodyTypeName = _prototype.Index(humanoid.BodyType).Name;
}
// First try to get body type specific displacement maps
if (bodyTypeName != null)
{
switch (handLocation)
{
case HandLocation.Left:
if (handComp.LeftHandBodyTypeDisplacements.TryGetValue(bodyTypeName, out var leftBodyTypeDisplacement))
return leftBodyTypeDisplacement;
break;
case HandLocation.Right:
if (handComp.RightHandBodyTypeDisplacements.TryGetValue(bodyTypeName, out var rightBodyTypeDisplacement))
return rightBodyTypeDisplacement;
break;
}
// Try generic body type displacement
if (handComp.BodyTypeDisplacements.TryGetValue(bodyTypeName, out var bodyTypeDisplacement))
return bodyTypeDisplacement;
}
// Fall back to the original logic
return handLocation switch
{
HandLocation.Left => handComp.LeftHandDisplacement,
HandLocation.Right => handComp.RightHandDisplacement,
_ => handComp.HandDisplacement
};
}
private void OnVisualsChanged(EntityUid uid, HandsComponent component, VisualsChangedEvent args)
{
// update hands visuals if this item is in a hand (rather then inventory or other container).

View file

@ -3,6 +3,7 @@ using Content.Shared.CCVar;
using Content.Shared.Humanoid;
using Content.Shared.CCVar;
using Content.Shared._Sunrise;
using Content.Shared.DisplacementMap;
using Content.Shared.Humanoid.Markings;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Inventory;
@ -393,13 +394,52 @@ public sealed class HumanoidAppearanceSystem : SharedHumanoidAppearanceSystem
_sprite.LayerSetColor((entity.Owner, sprite), layerId, Color.White);
}
if (humanoid.MarkingsDisplacement.TryGetValue(markingPrototype.BodyPart, out var displacementData) && markingPrototype.CanBeDisplaced)
var displacementData = GetMarkingDisplacement(entity.Owner, markingPrototype.BodyPart, humanoid);
if (displacementData != null && markingPrototype.CanBeDisplaced)
{
_displacement.TryAddDisplacement(displacementData, (entity.Owner, sprite), targetLayer + j + 1, layerId, out _);
}
}
}
private DisplacementData? GetMarkingDisplacement(EntityUid uid, HumanoidVisualLayers layer, HumanoidAppearanceComponent humanoid)
{
string? bodyTypeName = null;
if (TryComp(uid, out HumanoidAppearanceComponent? humanoidComp))
{
bodyTypeName = _prototypeManager.Index(humanoidComp.BodyType).Name;
}
var sex = humanoid.Sex;
// First try to get body type and sex specific displacement maps
if (bodyTypeName != null && humanoid.BodyTypeSexMarkingsDisplacement.TryGetValue(bodyTypeName, out var bodyTypeSexDisplacements))
{
if (bodyTypeSexDisplacements.TryGetValue(sex, out var sexDisplacements))
{
if (sexDisplacements.TryGetValue(layer, out var bodyTypeSexDisplacement))
return bodyTypeSexDisplacement;
}
}
// Then try body type specific displacement maps
if (bodyTypeName != null && humanoid.BodyTypeMarkingsDisplacement.TryGetValue(bodyTypeName, out var bodyTypeDisplacements))
{
if (bodyTypeDisplacements.TryGetValue(layer, out var bodyTypeDisplacement))
return bodyTypeDisplacement;
}
// Try sex specific displacement maps
if (humanoid.SexMarkingsDisplacement.TryGetValue(sex, out var sexSpecificDisplacements))
{
if (sexSpecificDisplacements.TryGetValue(layer, out var sexDisplacement))
return sexDisplacement;
}
// Fall back to the original logic
return humanoid.MarkingsDisplacement.TryGetValue(layer, out var displacement) ? displacement : null;
}
public override void SetSkinColor(EntityUid uid, Color skinColor, bool sync = true, bool verify = true, HumanoidAppearanceComponent? humanoid = null)
{
if (!Resolve(uid, ref humanoid) || humanoid.SkinColor == skinColor)

View file

@ -96,6 +96,25 @@ public sealed partial class HandsComponent : Component
[DataField]
public DisplacementData? RightHandDisplacement;
// Body type specific displacement maps
/// <summary>
/// Body type specific displacement maps for hands. Format: "bodytype" -> DisplacementData
/// </summary>
[DataField]
public Dictionary<string, DisplacementData> BodyTypeDisplacements = new();
/// <summary>
/// Body type specific displacement maps for left hands. Format: "bodytype" -> DisplacementData
/// </summary>
[DataField]
public Dictionary<string, DisplacementData> LeftHandBodyTypeDisplacements = new();
/// <summary>
/// Body type specific displacement maps for right hands. Format: "bodytype" -> DisplacementData
/// </summary>
[DataField]
public Dictionary<string, DisplacementData> RightHandBodyTypeDisplacements = new();
/// <summary>
/// If false, hands cannot be stripped, and they do not show up in the stripping menu.
/// </summary>

View file

@ -107,6 +107,24 @@ public sealed partial class HumanoidAppearanceComponent : Component
/// </summary>
[DataField]
public Dictionary<HumanoidVisualLayers, DisplacementData> MarkingsDisplacement = new();
/// <summary>
/// Body type specific displacement maps for markings. Format: "bodytype" -> layer -> DisplacementData
/// </summary>
[DataField]
public Dictionary<string, Dictionary<HumanoidVisualLayers, DisplacementData>> BodyTypeMarkingsDisplacement = new();
/// <summary>
/// Sex specific displacement maps for markings. Format: sex -> layer -> DisplacementData
/// </summary>
[DataField]
public Dictionary<Sex, Dictionary<HumanoidVisualLayers, DisplacementData>> SexMarkingsDisplacement = new();
/// <summary>
/// Body type and sex specific displacement maps for markings. Format: "bodytype" -> sex -> layer -> DisplacementData
/// </summary>
[DataField]
public Dictionary<string, Dictionary<Sex, Dictionary<HumanoidVisualLayers, DisplacementData>>> BodyTypeSexMarkingsDisplacement = new();
}
[DataDefinition]

View file

@ -25,6 +25,106 @@
hideLayersOnEquip:
- Hair
- Snout
# MARKINGS START
bodyTypeMarkingsDisplacement:
body-fat-m:
Hair:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: marking
body-fat-f:
Hair:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: marking
# MARKINGS END
# HANDS DISPLACEMENT
- type: Hands
leftHandBodyTypeDisplacements:
body-giga-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Giga/displacement.rsi
state: hand_l
body-giga-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Giga/displacement.rsi
state: hand_l
body-slim-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Slim/displacement.rsi
state: hand_l
body-slim-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Slim/displacement.rsi
state: hand_l
body-distrofik-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Distrofik/displacement.rsi
state: hand_l
body-distrofik-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Distrofik/displacement.rsi
state: hand_l
body-fat-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: hand_l
body-fat-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: hand_l
rightHandBodyTypeDisplacements:
body-giga-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Giga/displacement.rsi
state: hand_r
body-giga-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Giga/displacement.rsi
state: hand_r
body-slim-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Slim/displacement.rsi
state: hand_r
body-slim-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Slim/displacement.rsi
state: hand_r
body-distrofik-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Distrofik/displacement.rsi
state: hand_r
body-distrofik-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Distrofik/displacement.rsi
state: hand_r
body-fat-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: hand_r
body-fat-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: hand_r
# HANDS DISPLACEMENT
- type: Inventory
### Female
## BASE
@ -407,6 +507,107 @@
id: MobHumanDummy
categories: [ HideSpawnMenu ]
components:
- type: HumanoidAppearance
# MARKINGS START
bodyTypeMarkingsDisplacement:
body-fat-m:
Hair:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: marking
body-fat-f:
Hair:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: marking
# MARKINGS END
# HANDS DISPLACEMENT
- type: Hands
leftHandBodyTypeDisplacements:
body-giga-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Giga/displacement.rsi
state: hand_l
body-giga-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Giga/displacement.rsi
state: hand_l
body-slim-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Slim/displacement.rsi
state: hand_l
body-slim-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Slim/displacement.rsi
state: hand_l
body-distrofik-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Distrofik/displacement.rsi
state: hand_l
body-distrofik-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Distrofik/displacement.rsi
state: hand_l
body-fat-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: hand_l
body-fat-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: hand_l
rightHandBodyTypeDisplacements:
body-giga-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Giga/displacement.rsi
state: hand_r
body-giga-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Giga/displacement.rsi
state: hand_r
body-slim-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Slim/displacement.rsi
state: hand_r
body-slim-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Slim/displacement.rsi
state: hand_r
body-distrofik-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Distrofik/displacement.rsi
state: hand_r
body-distrofik-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Distrofik/displacement.rsi
state: hand_r
body-fat-m:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: hand_r
body-fat-f:
sizeMaps:
32:
sprite: _Sunrise/Mobs/Species/Human/Fat/displacement.rsi
state: hand_r
# HANDS DISPLACEMENT
- type: Inventory
### Female
# Base

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

View file

@ -1,5 +1,7 @@
{
"version": 1,
"license": "CLA",
"copyright": "MADE FOR SUNRISE",
"size": {
"x": 32,
"y": 32
@ -47,6 +49,18 @@
{
"name": "hardsuit",
"directions" : 4
},
{
"name": "hand_l",
"directions" : 4
},
{
"name": "hand_r",
"directions" : 4
},
{
"name": "hand",
"directions" : 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 B

After

Width:  |  Height:  |  Size: 490 B

View file

@ -1,5 +1,7 @@
{
"version": 1,
"license": "CLA",
"copyright": "MADE FOR SUNRISE",
"size": {
"x": 32,
"y": 32
@ -59,6 +61,18 @@
{
"name": "marking",
"directions" : 4
},
{
"name": "hand_l",
"directions" : 4
},
{
"name": "hand_r",
"directions" : 4
},
{
"name": "hand",
"directions" : 4
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 512 B

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 B

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 409 B

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 B

After

Width:  |  Height:  |  Size: 412 B

View file

@ -1,5 +1,7 @@
{
"version": 1,
"license": "CLA",
"copyright": "MADE FOR SUNRISE",
"size": {
"x": 32,
"y": 32

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

View file

@ -1,5 +1,7 @@
{
"version": 1,
"license": "CLA",
"copyright": "MADE FOR SUNRISE",
"size": {
"x": 32,
"y": 32
@ -47,6 +49,22 @@
{
"name": "hardsuit",
"directions" : 4
},
{
"name": "hand_l",
"directions" : 4
},
{
"name": "hand_r",
"directions" : 4
},
{
"name": "hand",
"directions" : 4
},
{
"name": "marking",
"directions" : 4
}
]
}