Documents all the public APIs for Nubody & markings code (#42857)
This commit is contained in:
parent
0d92860b32
commit
ee17a544d2
|
|
@ -7,6 +7,9 @@ using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Client.Humanoid;
|
namespace Content.Client.Humanoid;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// View model for UIs manipulating a set of markings, responsible for applying markings logic and keeping state synchronized.
|
||||||
|
/// </summary>
|
||||||
public sealed class MarkingsViewModel
|
public sealed class MarkingsViewModel
|
||||||
{
|
{
|
||||||
[Dependency] private readonly MarkingManager _marking = default!;
|
[Dependency] private readonly MarkingManager _marking = default!;
|
||||||
|
|
@ -14,6 +17,10 @@ public sealed class MarkingsViewModel
|
||||||
|
|
||||||
private bool _enforceLimits = true;
|
private bool _enforceLimits = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the markings view model will enforce limitations on how many markings an organ can have
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="EnforcementsChanged" />
|
||||||
public bool EnforceLimits
|
public bool EnforceLimits
|
||||||
{
|
{
|
||||||
get => _enforceLimits;
|
get => _enforceLimits;
|
||||||
|
|
@ -29,6 +36,10 @@ public sealed class MarkingsViewModel
|
||||||
|
|
||||||
private bool _enforceGroupAndSexRestrictions = true;
|
private bool _enforceGroupAndSexRestrictions = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the markings view model will enforce restrictions on the group and sex of markings for an organ
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="EnforcementsChanged" />
|
||||||
public bool EnforceGroupAndSexRestrictions
|
public bool EnforceGroupAndSexRestrictions
|
||||||
{
|
{
|
||||||
get => _enforceGroupAndSexRestrictions;
|
get => _enforceGroupAndSexRestrictions;
|
||||||
|
|
@ -44,10 +55,18 @@ public sealed class MarkingsViewModel
|
||||||
|
|
||||||
private bool AnyEnforcementsLifted => !_enforceLimits || !_enforceGroupAndSexRestrictions;
|
private bool AnyEnforcementsLifted => !_enforceLimits || !_enforceGroupAndSexRestrictions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised whenever the view model is enforcing a different set of constraints on possible markings than before
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="EnforceLimits" />
|
||||||
|
/// <seealso cref="EnforceGroupAndSexRestrictions" />
|
||||||
public event Action? EnforcementsChanged;
|
public event Action? EnforcementsChanged;
|
||||||
|
|
||||||
private Dictionary<ProtoId<OrganCategoryPrototype>, OrganProfileData> _organProfileData = new();
|
private Dictionary<ProtoId<OrganCategoryPrototype>, OrganProfileData> _organProfileData = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The organ profile data this view model is concerned with.
|
||||||
|
/// </summary>
|
||||||
public Dictionary<ProtoId<OrganCategoryPrototype>, OrganProfileData> OrganProfileData
|
public Dictionary<ProtoId<OrganCategoryPrototype>, OrganProfileData> OrganProfileData
|
||||||
{
|
{
|
||||||
get => _organProfileData;
|
get => _organProfileData;
|
||||||
|
|
@ -58,6 +77,10 @@ public sealed class MarkingsViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the sex of all organ profiles in the view model.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sex">The new sex</param>
|
||||||
public void SetOrganSexes(Sex sex)
|
public void SetOrganSexes(Sex sex)
|
||||||
{
|
{
|
||||||
foreach (var (organ, data) in _organProfileData)
|
foreach (var (organ, data) in _organProfileData)
|
||||||
|
|
@ -67,6 +90,10 @@ public sealed class MarkingsViewModel
|
||||||
OrganProfileDataChanged?.Invoke(true);
|
OrganProfileDataChanged?.Invoke(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the skin color of all organ profiles in the view model.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="skinColor">The new skin color</param>
|
||||||
public void SetOrganSkinColor(Color skinColor)
|
public void SetOrganSkinColor(Color skinColor)
|
||||||
{
|
{
|
||||||
foreach (var (organ, data) in _organProfileData)
|
foreach (var (organ, data) in _organProfileData)
|
||||||
|
|
@ -76,6 +103,10 @@ public sealed class MarkingsViewModel
|
||||||
OrganProfileDataChanged?.Invoke(false);
|
OrganProfileDataChanged?.Invoke(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the eye color of all organ profiles in the view model.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eyeColor">The new eye color</param>
|
||||||
public void SetOrganEyeColor(Color eyeColor)
|
public void SetOrganEyeColor(Color eyeColor)
|
||||||
{
|
{
|
||||||
foreach (var (organ, data) in _organProfileData)
|
foreach (var (organ, data) in _organProfileData)
|
||||||
|
|
@ -85,10 +116,21 @@ public sealed class MarkingsViewModel
|
||||||
OrganProfileDataChanged?.Invoke(false);
|
OrganProfileDataChanged?.Invoke(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised whenever the organ profile data changes.
|
||||||
|
/// The boolean value represents whether the set of possible markings may have changed.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="OrganProfileData" />
|
||||||
|
/// <seealso cref="SetOrganSexes" />
|
||||||
|
/// <seealso cref="SetOrganSkinColor" />
|
||||||
|
/// <seealso cref="SetOrganEyeColor" />
|
||||||
public event Action<bool>? OrganProfileDataChanged;
|
public event Action<bool>? OrganProfileDataChanged;
|
||||||
|
|
||||||
private Dictionary<ProtoId<OrganCategoryPrototype>, Dictionary<HumanoidVisualLayers, List<Marking>>> _markings = new();
|
private Dictionary<ProtoId<OrganCategoryPrototype>, Dictionary<HumanoidVisualLayers, List<Marking>>> _markings = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The currently applied set of markings
|
||||||
|
/// </summary>
|
||||||
public Dictionary<ProtoId<OrganCategoryPrototype>, Dictionary<HumanoidVisualLayers, List<Marking>>> Markings
|
public Dictionary<ProtoId<OrganCategoryPrototype>, Dictionary<HumanoidVisualLayers, List<Marking>>> Markings
|
||||||
{
|
{
|
||||||
get => _markings;
|
get => _markings;
|
||||||
|
|
@ -104,12 +146,21 @@ public sealed class MarkingsViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised whenever the set of markings has fully changed and requires a UI reload
|
||||||
|
/// </summary>
|
||||||
public event Action? MarkingsReset;
|
public event Action? MarkingsReset;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised whenever a specific layer's markings have changed
|
||||||
|
/// </summary>
|
||||||
public event Action<ProtoId<OrganCategoryPrototype>, HumanoidVisualLayers>? MarkingsChanged;
|
public event Action<ProtoId<OrganCategoryPrototype>, HumanoidVisualLayers>? MarkingsChanged;
|
||||||
|
|
||||||
private Dictionary<ProtoId<OrganCategoryPrototype>, OrganMarkingData> _organData = new();
|
private Dictionary<ProtoId<OrganCategoryPrototype>, OrganMarkingData> _organData = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The organ marking data the view model is concerned with.
|
||||||
|
/// </summary>
|
||||||
public Dictionary<ProtoId<OrganCategoryPrototype>, OrganMarkingData>
|
public Dictionary<ProtoId<OrganCategoryPrototype>, OrganMarkingData>
|
||||||
OrganData
|
OrganData
|
||||||
{
|
{
|
||||||
|
|
@ -125,15 +176,25 @@ public sealed class MarkingsViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raised whenever the organ data within the view model is changed.
|
||||||
|
/// </summary>
|
||||||
public event Action? OrganDataChanged;
|
public event Action? OrganDataChanged;
|
||||||
|
|
||||||
private Dictionary<ProtoId<MarkingPrototype>, List<Color>> _previousColors = new();
|
private readonly Dictionary<ProtoId<MarkingPrototype>, List<Color>> _previousColors = new();
|
||||||
|
|
||||||
public MarkingsViewModel()
|
public MarkingsViewModel()
|
||||||
{
|
{
|
||||||
IoCManager.InjectDependencies(this);
|
IoCManager.InjectDependencies(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether the given marking is currently selected in the model
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="organ">The organ to check for the marking within</param>
|
||||||
|
/// <param name="layer">The layer within the organ to check for the marking within</param>
|
||||||
|
/// <param name="markingId">The marking ID to check for</param>
|
||||||
|
/// <returns>Whether the marking is currently present within the set of selected markings</returns>
|
||||||
public bool IsMarkingSelected(ProtoId<OrganCategoryPrototype> organ,
|
public bool IsMarkingSelected(ProtoId<OrganCategoryPrototype> organ,
|
||||||
HumanoidVisualLayers layer,
|
HumanoidVisualLayers layer,
|
||||||
ProtoId<MarkingPrototype> markingId)
|
ProtoId<MarkingPrototype> markingId)
|
||||||
|
|
@ -141,6 +202,11 @@ public sealed class MarkingsViewModel
|
||||||
return GetMarking(organ, layer, markingId) is not null;
|
return GetMarking(organ, layer, markingId) is not null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns whether the marking at the given location can have its color customized by the user
|
||||||
|
/// </summary>
|
||||||
|
/// <inheritdoc cref="IsMarkingSelected" path="param" />
|
||||||
|
/// <returns>Whether the marking is capable of having its color customized by the user</returns>
|
||||||
public bool IsMarkingColorCustomizable(ProtoId<OrganCategoryPrototype> organ,
|
public bool IsMarkingColorCustomizable(ProtoId<OrganCategoryPrototype> organ,
|
||||||
HumanoidVisualLayers layer,
|
HumanoidVisualLayers layer,
|
||||||
ProtoId<MarkingPrototype> markingId)
|
ProtoId<MarkingPrototype> markingId)
|
||||||
|
|
@ -163,6 +229,11 @@ public sealed class MarkingsViewModel
|
||||||
return !appearance.MatchSkin;
|
return !appearance.MatchSkin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the currently applied marking by its ID, if it exists
|
||||||
|
/// </summary>
|
||||||
|
/// <inheritdoc cref="IsMarkingSelected" path="param" />
|
||||||
|
/// <returns>The marking currently applied if it exists, otherwise null</returns>
|
||||||
public Marking? GetMarking(ProtoId<OrganCategoryPrototype> organ,
|
public Marking? GetMarking(ProtoId<OrganCategoryPrototype> organ,
|
||||||
HumanoidVisualLayers layer,
|
HumanoidVisualLayers layer,
|
||||||
ProtoId<MarkingPrototype> markingId)
|
ProtoId<MarkingPrototype> markingId)
|
||||||
|
|
@ -176,6 +247,11 @@ public sealed class MarkingsViewModel
|
||||||
return markings.FirstOrNull(it => it.MarkingId == markingId);
|
return markings.FirstOrNull(it => it.MarkingId == markingId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to add a marking to the current set of markings
|
||||||
|
/// </summary>
|
||||||
|
/// <inheritdoc cref="IsMarkingSelected" path="param" />
|
||||||
|
/// <returns>Whether the marking was successfully added to the set of markings</returns>
|
||||||
public bool TrySelectMarking(ProtoId<OrganCategoryPrototype> organ,
|
public bool TrySelectMarking(ProtoId<OrganCategoryPrototype> organ,
|
||||||
HumanoidVisualLayers layer,
|
HumanoidVisualLayers layer,
|
||||||
ProtoId<MarkingPrototype> markingId)
|
ProtoId<MarkingPrototype> markingId)
|
||||||
|
|
@ -230,6 +306,12 @@ public sealed class MarkingsViewModel
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the list of currently selected markings for the layer on the given organ
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="organ">The organ to look up the layer within</param>
|
||||||
|
/// <param name="layer">The layer within the organ to look up</param>
|
||||||
|
/// <returns>The set of markings for the provided organ if it has any, or null</returns>
|
||||||
public List<Marking>? SelectedMarkings(ProtoId<OrganCategoryPrototype> organ,
|
public List<Marking>? SelectedMarkings(ProtoId<OrganCategoryPrototype> organ,
|
||||||
HumanoidVisualLayers layer)
|
HumanoidVisualLayers layer)
|
||||||
{
|
{
|
||||||
|
|
@ -238,6 +320,11 @@ public sealed class MarkingsViewModel
|
||||||
: organMarkings.GetValueOrDefault(layer);
|
: organMarkings.GetValueOrDefault(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to remove a marking from the current set of markings
|
||||||
|
/// </summary>
|
||||||
|
/// <inheritdoc cref="IsMarkingSelected" path="param" />
|
||||||
|
/// <returns>Whether the marking was successfully removed from the set of markings</returns>
|
||||||
public bool TryDeselectMarking(ProtoId<OrganCategoryPrototype> organ,
|
public bool TryDeselectMarking(ProtoId<OrganCategoryPrototype> organ,
|
||||||
HumanoidVisualLayers layer,
|
HumanoidVisualLayers layer,
|
||||||
ProtoId<MarkingPrototype> markingId)
|
ProtoId<MarkingPrototype> markingId)
|
||||||
|
|
@ -275,6 +362,12 @@ public sealed class MarkingsViewModel
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to set the color of the specified marking at the given index
|
||||||
|
/// </summary>
|
||||||
|
/// <inheritdoc cref="IsMarkingSelected" path="param" />
|
||||||
|
/// <param name="colorIndex">The index within the marking's color array to set</param>
|
||||||
|
/// <param name="color">The new color to set</param>
|
||||||
public void TrySetMarkingColor(ProtoId<OrganCategoryPrototype> organ,
|
public void TrySetMarkingColor(ProtoId<OrganCategoryPrototype> organ,
|
||||||
HumanoidVisualLayers layer,
|
HumanoidVisualLayers layer,
|
||||||
ProtoId<MarkingPrototype> markingId,
|
ProtoId<MarkingPrototype> markingId,
|
||||||
|
|
@ -295,6 +388,9 @@ public sealed class MarkingsViewModel
|
||||||
MarkingsChanged?.Invoke(organ, layer);
|
MarkingsChanged?.Invoke(organ, layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ensures the markings within the model are valid.
|
||||||
|
/// </summary>
|
||||||
public void ValidateMarkings()
|
public void ValidateMarkings()
|
||||||
{
|
{
|
||||||
foreach (var (organ, organData) in _organData)
|
foreach (var (organ, organData) in _organData)
|
||||||
|
|
@ -318,6 +414,14 @@ public sealed class MarkingsViewModel
|
||||||
MarkingsReset?.Invoke();
|
MarkingsReset?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the count data for an organ layer.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="organ">The organ to look up count data for</param>
|
||||||
|
/// <param name="layer">The layer within the organ to look up count data for</param>
|
||||||
|
/// <param name="isRequired">Whether this layer requires at least one marking to be selected</param>
|
||||||
|
/// <param name="count">The maximum amount of markings that can be selected for this layer</param>
|
||||||
|
/// <param name="selected">The currently selected amount of markings</param>
|
||||||
public void GetMarkingCounts(ProtoId<OrganCategoryPrototype> organ, HumanoidVisualLayers layer, out bool isRequired, out int count, out int selected)
|
public void GetMarkingCounts(ProtoId<OrganCategoryPrototype> organ, HumanoidVisualLayers layer, out bool isRequired, out int count, out int selected)
|
||||||
{
|
{
|
||||||
isRequired = false;
|
isRequired = false;
|
||||||
|
|
@ -348,6 +452,14 @@ public sealed class MarkingsViewModel
|
||||||
selected = layerMarkings.Count;
|
selected = layerMarkings.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reorders the specified marking ID to the index and position relative to its index
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="organ">The organ to reorder the markings of</param>
|
||||||
|
/// <param name="layer">The layer to reorder the markings of</param>
|
||||||
|
/// <param name="markingId">The marking to reorder</param>
|
||||||
|
/// <param name="position">Whether the marking should be moved to before or after the given index</param>
|
||||||
|
/// <param name="positionIndex">The new position index of the marking</param>
|
||||||
public void ChangeMarkingOrder(ProtoId<OrganCategoryPrototype> organ,
|
public void ChangeMarkingOrder(ProtoId<OrganCategoryPrototype> organ,
|
||||||
HumanoidVisualLayers layer,
|
HumanoidVisualLayers layer,
|
||||||
ProtoId<MarkingPrototype> markingId,
|
ProtoId<MarkingPrototype> markingId,
|
||||||
|
|
@ -381,6 +493,9 @@ public sealed class MarkingsViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies whether an item in a list will be moved to before or after a corresponding index
|
||||||
|
/// </summary>
|
||||||
public enum CandidatePosition
|
public enum CandidatePosition
|
||||||
{
|
{
|
||||||
Before,
|
Before,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,11 @@ using Robust.Shared.GameStates;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Component on the entity that "has" a body, and that oversees entities with the <see cref="OrganComponent"/> inside it.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="BodySystem" />
|
||||||
|
/// <seealso cref="SharedVisualBodySystem" />
|
||||||
[RegisterComponent, NetworkedComponent]
|
[RegisterComponent, NetworkedComponent]
|
||||||
[Access(typeof(BodySystem))]
|
[Access(typeof(BodySystem))]
|
||||||
public sealed partial class BodyComponent : Component
|
public sealed partial class BodyComponent : Component
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,19 @@
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
public sealed partial class BodySystem
|
public sealed partial class BodySystem
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a list of organs with a given component in the body.
|
||||||
|
/// This is only provided to ease migration from the older BodySystem and should not be used in new code.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ent">The body to query.</param>
|
||||||
|
/// <param name="organs">The set of organs with the given component.</param>
|
||||||
|
/// <typeparam name="TComp">The component to test for.</typeparam>
|
||||||
|
/// <returns>Whether any organs were returned.</returns>
|
||||||
[Obsolete("Use an event-relay based approach instead")]
|
[Obsolete("Use an event-relay based approach instead")]
|
||||||
|
[PublicAPI]
|
||||||
public bool TryGetOrgansWithComponent<TComp>(Entity<BodyComponent?> ent, out List<Entity<TComp>> organs) where TComp : Component
|
public bool TryGetOrgansWithComponent<TComp>(Entity<BodyComponent?> ent, out List<Entity<TComp>> organs) where TComp : Component
|
||||||
{
|
{
|
||||||
organs = new();
|
organs = new();
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,13 @@ using Content.Shared.Body.Events;
|
||||||
using Content.Shared.Gibbing;
|
using Content.Shared.Gibbing;
|
||||||
using Content.Shared.Humanoid;
|
using Content.Shared.Humanoid;
|
||||||
using Content.Shared.Medical;
|
using Content.Shared.Medical;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
public sealed partial class BodySystem
|
public sealed partial class BodySystem
|
||||||
{
|
{
|
||||||
|
// Refrain from adding an infinite block of relays here - consuming systems can use RelayEvent
|
||||||
private void InitializeRelay()
|
private void InitializeRelay()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<BodyComponent, ApplyMetabolicMultiplierEvent>(RefRelayBodyEvent);
|
SubscribeLocalEvent<BodyComponent, ApplyMetabolicMultiplierEvent>(RefRelayBodyEvent);
|
||||||
|
|
@ -28,6 +30,13 @@ public sealed partial class BodySystem
|
||||||
RelayEvent((uid, component), args);
|
RelayEvent((uid, component), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relays the given event to organs within a body.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ent">The body to relay the event within</param>
|
||||||
|
/// <param name="args">The event to relay</param>
|
||||||
|
/// <typeparam name="T">The type of the event</typeparam>
|
||||||
|
[PublicAPI]
|
||||||
public void RelayEvent<T>(Entity<BodyComponent> ent, ref T args) where T : struct
|
public void RelayEvent<T>(Entity<BodyComponent> ent, ref T args) where T : struct
|
||||||
{
|
{
|
||||||
var ev = new BodyRelayedEvent<T>(ent, args);
|
var ev = new BodyRelayedEvent<T>(ent, args);
|
||||||
|
|
@ -38,6 +47,13 @@ public sealed partial class BodySystem
|
||||||
args = ev.Args;
|
args = ev.Args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relays the given event to organs within a body.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ent">The body to relay the event within</param>
|
||||||
|
/// <param name="args">The event to relay</param>
|
||||||
|
/// <typeparam name="T">The type of the event</typeparam>
|
||||||
|
[PublicAPI]
|
||||||
public void RelayEvent<T>(Entity<BodyComponent> ent, T args) where T : class
|
public void RelayEvent<T>(Entity<BodyComponent> ent, T args) where T : class
|
||||||
{
|
{
|
||||||
var ev = new BodyRelayedEvent<T>(ent, args);
|
var ev = new BodyRelayedEvent<T>(ent, args);
|
||||||
|
|
@ -49,7 +65,7 @@ public sealed partial class BodySystem
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event wrapper for relayed events.
|
/// Event wrapper for events being relayed to organs within a body.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ByRefEvent]
|
[ByRefEvent]
|
||||||
public record struct BodyRelayedEvent<TEvent>(Entity<BodyComponent> Body, TEvent Args);
|
public record struct BodyRelayedEvent<TEvent>(Entity<BodyComponent> Body, TEvent Args);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,17 @@ using Robust.Shared.Containers;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// System responsible for coordinating entities with <see cref="BodyComponent" /> and their entities with <see cref="OrganComponent" />.
|
||||||
|
/// This system is primarily responsible for event relaying and the relationships between a body and its organs.
|
||||||
|
/// It is not responsible for player-facing body features, e.g. "blood" or "breathing."
|
||||||
|
/// Such features should be implemented in systems relying on the various events raised by this class.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="OrganGotInsertedEvent" />
|
||||||
|
/// <seealso cref="OrganGotRemovedEvent" />
|
||||||
|
/// <seealso cref="OrganInsertedIntoEvent" />
|
||||||
|
/// <seealso cref="OrganRemovedFromEvent" />
|
||||||
|
/// <seealso cref="BodyRelayedEvent{TEvent}" />
|
||||||
public sealed partial class BodySystem : EntitySystem
|
public sealed partial class BodySystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly SharedContainerSystem _container = default!;
|
[Dependency] private readonly SharedContainerSystem _container = default!;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
|
using Content.Shared.Gibbing;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Component that causes this entity to become gibs when the body it's in is gibbed
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="GibbingSystem" />
|
||||||
[RegisterComponent, NetworkedComponent]
|
[RegisterComponent, NetworkedComponent]
|
||||||
[Access(typeof(GibbableOrganSystem))]
|
[Access(typeof(GibbableOrganSystem))]
|
||||||
public sealed partial class GibbableOrganComponent : Component;
|
public sealed partial class GibbableOrganComponent : Component;
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,22 @@ using Robust.Shared.GameStates;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Organs with this component provide a hand with the given ID and data to the body when inserted.
|
||||||
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent]
|
[RegisterComponent, NetworkedComponent]
|
||||||
[Access(typeof(HandOrganSystem))]
|
[Access(typeof(HandOrganSystem))]
|
||||||
public sealed partial class HandOrganComponent : Component
|
public sealed partial class HandOrganComponent : Component
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The hand ID used by <seealso cref="HandsComponent" /> on the body
|
||||||
|
/// </summary>
|
||||||
[DataField(required: true)]
|
[DataField(required: true)]
|
||||||
public string HandID;
|
public string HandID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The data used to create the hand
|
||||||
|
/// </summary>
|
||||||
[DataField(required: true)]
|
[DataField(required: true)]
|
||||||
public Hand Data;
|
public Hand Data;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,15 @@ namespace Content.Shared.Body;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// On map initialization, spawns the given organs into the body.
|
/// On map initialization, spawns the given organs into the body.
|
||||||
|
/// Liable to change as the body becomes more complex.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[Access(typeof(InitialBodySystem))]
|
[Access(typeof(InitialBodySystem))]
|
||||||
public sealed partial class InitialBodyComponent : Component
|
public sealed partial class InitialBodyComponent : Component
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The organs to spawn based on their category.
|
||||||
|
/// </summary>
|
||||||
[DataField(required: true)]
|
[DataField(required: true)]
|
||||||
public Dictionary<ProtoId<OrganCategoryPrototype>, EntProtoId<OrganComponent>> Organs;
|
public Dictionary<ProtoId<OrganCategoryPrototype>, EntProtoId<OrganComponent>> Organs;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@ using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Marks an entity as being able to be inserted into an entity with <seealso cref="BodyComponent" />.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="BodySystem" />
|
||||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
[Access(typeof(BodySystem))]
|
[Access(typeof(BodySystem))]
|
||||||
public sealed partial class OrganComponent : Component
|
public sealed partial class OrganComponent : Component
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using Content.Shared.Humanoid;
|
||||||
using Content.Shared.Humanoid.Markings;
|
using Content.Shared.Humanoid.Markings;
|
||||||
using Content.Shared.Preferences;
|
using Content.Shared.Preferences;
|
||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
|
|
@ -47,6 +48,26 @@ public abstract partial class SharedVisualBodySystem
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the appearance of organs from one body to another
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">The body whose organs to copy the appearance from</param>
|
||||||
|
/// <param name="target">The body whose organs to copy the appearance to</param>
|
||||||
|
[PublicAPI]
|
||||||
|
public void CopyAppearanceFrom(Entity<BodyComponent?> source, Entity<BodyComponent?> target)
|
||||||
|
{
|
||||||
|
if (!Resolve(source, ref source.Comp) || !Resolve(target, ref target.Comp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var sourceOrgans = _container.EnsureContainer<Container>(source, BodyComponent.ContainerID);
|
||||||
|
|
||||||
|
foreach (var sourceOrgan in sourceOrgans.ContainedEntities)
|
||||||
|
{
|
||||||
|
var evt = new OrganCopyAppearanceEvent(sourceOrgan);
|
||||||
|
RaiseLocalEvent(target, ref evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gathers all the markings-relevant data from this entity
|
/// Gathers all the markings-relevant data from this entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -111,6 +132,12 @@ public abstract partial class SharedVisualBodySystem
|
||||||
RaiseLocalEvent(ent, ref markingsEvt);
|
RaiseLocalEvent(ent, ref markingsEvt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies the given set of markings to the body.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ent">The body whose organs to apply markings to.</param>
|
||||||
|
/// <param name="markings">A dictionary of organ categories to markings information. Organs not included in this dictionary will remain unaffected.</param>
|
||||||
|
[PublicAPI]
|
||||||
public void ApplyMarkings(EntityUid ent, Dictionary<ProtoId<OrganCategoryPrototype>, Dictionary<HumanoidVisualLayers, List<Marking>>> markings)
|
public void ApplyMarkings(EntityUid ent, Dictionary<ProtoId<OrganCategoryPrototype>, Dictionary<HumanoidVisualLayers, List<Marking>>> markings)
|
||||||
{
|
{
|
||||||
var markingsEvt = new ApplyOrganMarkingsEvent(markings);
|
var markingsEvt = new ApplyOrganMarkingsEvent(markings);
|
||||||
|
|
@ -134,17 +161,37 @@ public abstract partial class SharedVisualBodySystem
|
||||||
RaiseLocalEvent(ent, ref markingsEvt);
|
RaiseLocalEvent(ent, ref markingsEvt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies the information contained with a <see cref="HumanoidCharacterProfile"/> to a visual body's appearance.
|
||||||
|
/// This sets the profile data and markings of all organs contained within the profile.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ent">The body to apply the profile to</param>
|
||||||
|
/// <param name="profile">The profile to apply</param>
|
||||||
|
[PublicAPI]
|
||||||
public void ApplyProfileTo(Entity<VisualBodyComponent?> ent, HumanoidCharacterProfile profile)
|
public void ApplyProfileTo(Entity<VisualBodyComponent?> ent, HumanoidCharacterProfile profile)
|
||||||
{
|
{
|
||||||
ApplyAppearanceTo(ent, profile.Appearance, profile.Sex);
|
ApplyAppearanceTo(ent, profile.Appearance, profile.Sex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies profile data to all visual organs within the body.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ent">The body to apply the organ profile to</param>
|
||||||
|
/// <param name="profile">The profile to apply</param>
|
||||||
|
[PublicAPI]
|
||||||
public void ApplyProfile(EntityUid ent, OrganProfileData profile)
|
public void ApplyProfile(EntityUid ent, OrganProfileData profile)
|
||||||
{
|
{
|
||||||
var profileEvt = new ApplyOrganProfileDataEvent(profile, null);
|
var profileEvt = new ApplyOrganProfileDataEvent(profile, null);
|
||||||
RaiseLocalEvent(ent, ref profileEvt);
|
RaiseLocalEvent(ent, ref profileEvt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies profile data to the specified visual organs within the body.
|
||||||
|
/// Organs not specified are left unchanged.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ent">The body to apply the organ profiles to.</param>
|
||||||
|
/// <param name="profiles">The profiles to apply.</param>
|
||||||
|
[PublicAPI]
|
||||||
public void ApplyProfiles(EntityUid ent, Dictionary<ProtoId<OrganCategoryPrototype>, OrganProfileData> profiles)
|
public void ApplyProfiles(EntityUid ent, Dictionary<ProtoId<OrganCategoryPrototype>, OrganProfileData> profiles)
|
||||||
{
|
{
|
||||||
var profileEvt = new ApplyOrganProfileDataEvent(null, profiles);
|
var profileEvt = new ApplyOrganProfileDataEvent(null, profiles);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Class responsible for managing the appearance of an entity with <see cref="VisualBodyComponent" /> via its organs with <see cref="VisualOrganComponent" />
|
||||||
|
/// </summary>
|
||||||
public abstract partial class SharedVisualBodySystem : EntitySystem
|
public abstract partial class SharedVisualBodySystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||||
|
|
@ -84,20 +87,6 @@ public abstract partial class SharedVisualBodySystem : EntitySystem
|
||||||
Dirty(ent);
|
Dirty(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyAppearanceFrom(Entity<BodyComponent?> source, Entity<BodyComponent?> target)
|
|
||||||
{
|
|
||||||
if (!Resolve(source, ref source.Comp) || !Resolve(target, ref target.Comp))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var sourceOrgans = _container.EnsureContainer<Container>(source, BodyComponent.ContainerID);
|
|
||||||
|
|
||||||
foreach (var sourceOrgan in sourceOrgans.ContainedEntities)
|
|
||||||
{
|
|
||||||
var evt = new OrganCopyAppearanceEvent(sourceOrgan);
|
|
||||||
RaiseLocalEvent(target, ref evt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnVisualOrganCopyAppearance(Entity<VisualOrganComponent> ent, ref BodyRelayedEvent<OrganCopyAppearanceEvent> args)
|
private void OnVisualOrganCopyAppearance(Entity<VisualOrganComponent> ent, ref BodyRelayedEvent<OrganCopyAppearanceEvent> args)
|
||||||
{
|
{
|
||||||
if (!TryComp<VisualOrganComponent>(args.Args.Organ, out var other))
|
if (!TryComp<VisualOrganComponent>(args.Args.Organ, out var other))
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,9 @@ using Robust.Shared.GameStates;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Component on an entity with <see cref="BodyComponent" /> that modifies its appearance based on contained organs with <see cref="VisualOrganComponent" />
|
||||||
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent]
|
[RegisterComponent, NetworkedComponent]
|
||||||
[Access(typeof(SharedVisualBodySystem))]
|
[Access(typeof(SharedVisualBodySystem))]
|
||||||
public sealed partial class VisualBodyComponent : Component;
|
public sealed partial class VisualBodyComponent : Component;
|
||||||
|
|
|
||||||
|
|
@ -4,28 +4,35 @@ using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines an organ that applies a sprite to the specified <see cref="Layer" /> within the body
|
||||||
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
|
||||||
[Access(typeof(SharedVisualBodySystem))]
|
[Access(typeof(SharedVisualBodySystem))]
|
||||||
public sealed partial class VisualOrganComponent : Component
|
public sealed partial class VisualOrganComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The layer on the entity that this contributes to
|
/// The sprite layer on the entity that this contributes to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField(required: true)]
|
[DataField(required: true)]
|
||||||
public Enum Layer;
|
public Enum Layer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The data for the layer
|
/// The sprite data for the layer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField(required: true), AutoNetworkedField, AlwaysPushInheritance]
|
[DataField(required: true), AutoNetworkedField, AlwaysPushInheritance]
|
||||||
public PrototypeLayerData Data;
|
public PrototypeLayerData Data;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// When applying a profile, if the sex is present in this dictionary, overrides the state of the data.
|
/// When applying a profile, if the sex is present in this dictionary, overrides the state of the sprite data.
|
||||||
|
/// Used for e.g. male vs female torsoes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField]
|
[DataField]
|
||||||
public Dictionary<Sex, string>? SexStateOverrides;
|
public Dictionary<Sex, string>? SexStateOverrides;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current profile data of this organ, used for alternate sprite selection and colouration.
|
||||||
|
/// </summary>
|
||||||
[DataField, AutoNetworkedField]
|
[DataField, AutoNetworkedField]
|
||||||
public OrganProfileData Profile = new();
|
public OrganProfileData Profile = new();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,21 @@ using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Body;
|
namespace Content.Shared.Body;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines an organ that applies markings on top of the layer specified in <see cref="VisualOrganComponent" />
|
||||||
|
/// </summary>
|
||||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(raiseAfterAutoHandleState: true, fieldDeltas: true)]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(raiseAfterAutoHandleState: true, fieldDeltas: true)]
|
||||||
[Access(typeof(SharedVisualBodySystem))]
|
[Access(typeof(SharedVisualBodySystem))]
|
||||||
public sealed partial class VisualOrganMarkingsComponent : Component
|
public sealed partial class VisualOrganMarkingsComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// What markings this organ can take
|
/// Defines the type of markings this organ can take
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField(required: true), AlwaysPushInheritance]
|
[DataField(required: true), AlwaysPushInheritance]
|
||||||
public OrganMarkingData MarkingData = default!;
|
public OrganMarkingData MarkingData = default!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of markings to apply to the entity
|
/// The list of markings this organ is currently providing to the entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField, AutoNetworkedField]
|
[DataField, AutoNetworkedField]
|
||||||
public Dictionary<HumanoidVisualLayers, List<Marking>> Markings = new();
|
public Dictionary<HumanoidVisualLayers, List<Marking>> Markings = new();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@ using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Shared.Humanoid.Markings;
|
namespace Content.Shared.Humanoid.Markings;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manager responsible for sharing the logic of markings between in-simulation bodies and out-of-simulation profile editing
|
||||||
|
/// </summary>
|
||||||
public sealed class MarkingManager
|
public sealed class MarkingManager
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IComponentFactory _component = default!;
|
[Dependency] private readonly IComponentFactory _component = default!;
|
||||||
|
|
@ -81,6 +84,12 @@ public sealed class MarkingManager
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the marking prototype associated with the marking.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="marking">The marking to look up</param>
|
||||||
|
/// <param name="markingResult">When this method returns; will contain the marking prototype corresponding to the one specified by the marking if it exists.</param>
|
||||||
|
/// <returns>Whether a marking prototype exists for the given marking</returns>
|
||||||
public bool TryGetMarking(Marking marking, [NotNullWhen(true)] out MarkingPrototype? markingResult)
|
public bool TryGetMarking(Marking marking, [NotNullWhen(true)] out MarkingPrototype? markingResult)
|
||||||
{
|
{
|
||||||
return _markings.TryGetValue(marking.MarkingId, out markingResult);
|
return _markings.TryGetValue(marking.MarkingId, out markingResult);
|
||||||
|
|
@ -92,7 +101,13 @@ public sealed class MarkingManager
|
||||||
CachePrototypes();
|
CachePrototypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if a marking prototype can be applied to something with the given markings group and sex.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="group">The markings group to test</param>
|
||||||
|
/// <param name="sex">The sex to test</param>
|
||||||
|
/// <param name="prototype">The prototype to reference against</param>
|
||||||
|
/// <returns>True if a marking with the prototype could be applied</returns>
|
||||||
public bool CanBeApplied(ProtoId<MarkingsGroupPrototype> group, Sex sex, MarkingPrototype prototype)
|
public bool CanBeApplied(ProtoId<MarkingsGroupPrototype> group, Sex sex, MarkingPrototype prototype)
|
||||||
{
|
{
|
||||||
var groupProto = _prototype.Index(group);
|
var groupProto = _prototype.Index(group);
|
||||||
|
|
@ -223,6 +238,11 @@ public sealed class MarkingManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the expected set of organs for a species to have.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="species">The species to look up.</param>
|
||||||
|
/// <returns>A dictionary of organ categories to their usual organs within a species.</returns>
|
||||||
public Dictionary<ProtoId<OrganCategoryPrototype>, EntProtoId<OrganComponent>> GetOrgans(ProtoId<SpeciesPrototype> species)
|
public Dictionary<ProtoId<OrganCategoryPrototype>, EntProtoId<OrganComponent>> GetOrgans(ProtoId<SpeciesPrototype> species)
|
||||||
{
|
{
|
||||||
var speciesPrototype = _prototype.Index(species);
|
var speciesPrototype = _prototype.Index(species);
|
||||||
|
|
@ -234,6 +254,11 @@ public sealed class MarkingManager
|
||||||
return initialBody.Organs;
|
return initialBody.Organs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up the expected set of <see cref="OrganMarkingData" /> for the species to have
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="species">The species to look up the usual organs of.</param>
|
||||||
|
/// <returns>A dictionary of organ categories to their usual organ marking data within a species.</returns>
|
||||||
public Dictionary<ProtoId<OrganCategoryPrototype>, OrganMarkingData> GetMarkingData(ProtoId<SpeciesPrototype> species)
|
public Dictionary<ProtoId<OrganCategoryPrototype>, OrganMarkingData> GetMarkingData(ProtoId<SpeciesPrototype> species)
|
||||||
{
|
{
|
||||||
var ret = new Dictionary<ProtoId<OrganCategoryPrototype>, OrganMarkingData>();
|
var ret = new Dictionary<ProtoId<OrganCategoryPrototype>, OrganMarkingData>();
|
||||||
|
|
@ -249,6 +274,15 @@ public sealed class MarkingManager
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Expands the provided profile data into all the categories for a species.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="species">The species the returned dictionary should be comprehensive for.</param>
|
||||||
|
/// <param name="sex">The sex to apply to all organs</param>
|
||||||
|
/// <param name="skinColor">The skin color to apply to all organs</param>
|
||||||
|
/// <param name="eyeColor">The eye color to apply to all organs</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
/// <seealso cref="OrganProfileData" />
|
||||||
public Dictionary<ProtoId<OrganCategoryPrototype>, OrganProfileData> GetProfileData(ProtoId<SpeciesPrototype> species,
|
public Dictionary<ProtoId<OrganCategoryPrototype>, OrganProfileData> GetProfileData(ProtoId<SpeciesPrototype> species,
|
||||||
Sex sex,
|
Sex sex,
|
||||||
Color skinColor,
|
Color skinColor,
|
||||||
|
|
@ -269,6 +303,12 @@ public sealed class MarkingManager
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="OrganMarkingData" /> for the entity prototype corresponding to an organ
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="organ">The ID of the organ entity prototype to look up</param>
|
||||||
|
/// <param name="organData">The marking data for the organ if it exists</param>
|
||||||
|
/// <returns>Whether the provided entity prototype ID corresponded to organ marking data that could be returned</returns>
|
||||||
public bool TryGetMarkingData(EntProtoId organ, [NotNullWhen(true)] out OrganMarkingData? organData)
|
public bool TryGetMarkingData(EntProtoId organ, [NotNullWhen(true)] out OrganMarkingData? organData)
|
||||||
{
|
{
|
||||||
organData = null;
|
organData = null;
|
||||||
|
|
@ -284,6 +324,12 @@ public sealed class MarkingManager
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a legacy flat list of markings to a structured markings dictionary for a given species
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="markings">A flat list of markings</param>
|
||||||
|
/// <param name="species">The species to convert the markings for</param>
|
||||||
|
/// <returns>A dictionary with the provided markings categorized appropriately for the species</returns>
|
||||||
public Dictionary<ProtoId<OrganCategoryPrototype>, Dictionary<HumanoidVisualLayers, List<Marking>>> ConvertMarkings(List<Marking> markings,
|
public Dictionary<ProtoId<OrganCategoryPrototype>, Dictionary<HumanoidVisualLayers, List<Marking>>> ConvertMarkings(List<Marking> markings,
|
||||||
ProtoId<SpeciesPrototype> species)
|
ProtoId<SpeciesPrototype> species)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue