Remove IBody, IBodyPart, IMechanism and IMechanismBehavior (#4187)
* Remove IBody, IBodyPart, IMechanism and IMechanismBehavior interfaces * Summary cleanup
This commit is contained in:
@@ -1,142 +0,0 @@
|
||||
#nullable enable
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Mechanism;
|
||||
using Content.Shared.Body.Part;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Shared.Body.Behavior
|
||||
{
|
||||
/// <summary>
|
||||
/// Gives functionality to a <see cref="IMechanism"/> when added to it.
|
||||
/// </summary>
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
public interface IMechanismBehavior
|
||||
{
|
||||
/// <summary>
|
||||
/// The body that owns the <see cref="IBodyPart"/> in which the
|
||||
/// <see cref="IMechanism"/> that owns this
|
||||
/// <see cref="IMechanismBehavior"/> is in.
|
||||
/// </summary>
|
||||
IBody? Body { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The part in which the <see cref="IMechanism"/> that owns this
|
||||
/// <see cref="IMechanismBehavior"/> is in.
|
||||
/// </summary>
|
||||
IBodyPart? Part { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Upward reference to the parent <see cref="IMechanism"/> that this
|
||||
/// behavior is attached to.
|
||||
/// </summary>
|
||||
IMechanism Parent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The entity that owns <see cref="Parent"/>.
|
||||
/// For the entity owning the body that this mechanism may be in,
|
||||
/// see <see cref="Body"/>'s <see cref="IBody.Owner"/>.
|
||||
/// </summary>
|
||||
IEntity Owner { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when this <see cref="IMechanismBehavior"/> is added to a
|
||||
/// <see cref="IMechanism"/>, during <see cref="IComponent.Initialize"/>.
|
||||
/// If it is added after component initialization,
|
||||
/// it is called immediately.
|
||||
/// </summary>
|
||||
/// <param name="parent">
|
||||
/// The mechanism that owns this <see cref="IMechanismBehavior"/>.
|
||||
/// </param>
|
||||
void Initialize(IMechanism parent);
|
||||
|
||||
/// <summary>
|
||||
/// Called when this <see cref="IMechanismBehavior"/> is added to a
|
||||
/// <see cref="IMechanism"/>, during <see cref="IComponent.Startup"/>.
|
||||
/// If it is added after component startup, it is called immediately.
|
||||
/// </summary>
|
||||
void Startup();
|
||||
|
||||
/// <summary>
|
||||
/// Runs an update cycle on this <see cref="IMechanismBehavior"/>.
|
||||
/// </summary>
|
||||
/// <param name="frameTime">
|
||||
/// The amount of seconds that passed since the last update.
|
||||
/// </param>
|
||||
void Update(float frameTime);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the containing <see cref="IBodyPart"/> is attached to a
|
||||
/// <see cref="IBody"/>.
|
||||
/// For instance, attaching a head with a brain inside to a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="body">
|
||||
/// The body that the containing <see cref="IMechanism"/> was added to.
|
||||
/// </param>
|
||||
void AddedToBody(IBody body);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent <see cref="IMechanism"/> is
|
||||
/// added into a <see cref="IBodyPart"/> that is not attached to a
|
||||
/// <see cref="IBody"/>.
|
||||
/// For instance, adding a brain to a dismembered head.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="part">
|
||||
/// The part that the containing <see cref="IMechanism"/> was added to.
|
||||
/// </param>
|
||||
void AddedToPart(IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent <see cref="IMechanism"/> is added to a
|
||||
/// <see cref="IBodyPart"/> that is attached to a <see cref="IBody"/>.
|
||||
/// For instance, adding a brain to a head that is attached to a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="body">
|
||||
/// The body that the containing <see cref="IMechanism"/> was added to.
|
||||
/// </param>
|
||||
/// <param name="part">
|
||||
/// The part that the containing <see cref="IMechanism"/> was added to.
|
||||
/// </param>
|
||||
void AddedToPartInBody(IBody body, IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent <see cref="IBodyPart"/> is removed from a
|
||||
/// <see cref="IBody"/>.
|
||||
/// For instance, removing a head with a brain inside from a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="old">
|
||||
/// The body that the containing <see cref="IMechanism"/> was removed from.
|
||||
/// </param>
|
||||
void RemovedFromBody(IBody old);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent <see cref="IMechanism"/> is
|
||||
/// removed from a <see cref="IBodyPart"/> that is not attached to a
|
||||
/// <see cref="IBody"/>.
|
||||
/// For instance, removing a brain from a dismembered head.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="old">
|
||||
/// The part that the containing <see cref="IMechanism"/> was removed from.
|
||||
/// </param>
|
||||
void RemovedFromPart(IBodyPart old);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent <see cref="IMechanism"/> is removed from a
|
||||
/// <see cref="IBodyPart"/> that is attached to a <see cref="IBody"/>.
|
||||
/// For instance, removing a brain from a head that is attached to a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="oldBody">
|
||||
/// The body that the containing <see cref="IMechanism"/> was removed from.
|
||||
/// </param>
|
||||
/// <param name="oldPart">
|
||||
/// The part that the containing <see cref="IMechanism"/> was removed from.
|
||||
/// </param>
|
||||
void RemovedFromPartInBody(IBody oldBody, IBodyPart oldPart);
|
||||
}
|
||||
}
|
||||
119
Content.Shared/Body/Behavior/SharedMechanismBehavior.cs
Normal file
119
Content.Shared/Body/Behavior/SharedMechanismBehavior.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
#nullable enable
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Mechanism;
|
||||
using Content.Shared.Body.Part;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Shared.Body.Behavior
|
||||
{
|
||||
/// <summary>
|
||||
/// Gives functionality to a mechanism when added to it.
|
||||
/// </summary>
|
||||
[ImplicitDataDefinitionForInheritors]
|
||||
public abstract class SharedMechanismBehavior
|
||||
{
|
||||
public abstract SharedBodyComponent? Body { get; }
|
||||
|
||||
public abstract SharedBodyPartComponent? Part { get; }
|
||||
|
||||
public abstract SharedMechanismComponent Parent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The entity that owns <see cref="Parent"/>.
|
||||
/// For the entity owning the body that this mechanism may be in,
|
||||
/// see <see cref="Body"/>'s <see cref="SharedBodyComponent.Owner"/>.
|
||||
/// </summary>
|
||||
public abstract IEntity Owner { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when this behavior is added to a mechanism, during <see cref="IComponent.Initialize"/>.
|
||||
/// If it is added after component initialization,
|
||||
/// it is called immediately.
|
||||
/// </summary>
|
||||
/// <param name="parent">
|
||||
/// The mechanism that owns this behavior.
|
||||
/// </param>
|
||||
public abstract void Initialize(SharedMechanismComponent parent);
|
||||
|
||||
/// <summary>
|
||||
/// Called when this behavior is added to a mechanism, during <see cref="Component.Startup"/>.
|
||||
/// If it is added after component startup, it is called immediately.
|
||||
/// </summary>
|
||||
public abstract void Startup();
|
||||
|
||||
/// <summary>
|
||||
/// Runs an update cycle on this behavior.
|
||||
/// </summary>
|
||||
/// <param name="frameTime">
|
||||
/// The amount of seconds that passed since the last update.
|
||||
/// </param>
|
||||
public abstract void Update(float frameTime);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the containing part is attached to a body.
|
||||
/// For instance, attaching a head with a brain inside to a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="body">
|
||||
/// The body that the containing mechanism was added to.
|
||||
/// </param>
|
||||
public abstract void AddedToBody(SharedBodyComponent body);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent mechanism is added into a part that is not attached to a body.
|
||||
/// For instance, adding a brain to a dismembered head.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="part">
|
||||
/// The part that the containing mechanism was added to.
|
||||
/// </param>
|
||||
public abstract void AddedToPart(SharedBodyPartComponent part);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent mechanism is added to a part that is attached to a body.
|
||||
/// For instance, adding a brain to a head that is attached to a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="body">
|
||||
/// The body that the containing mechanism was added to.
|
||||
/// </param>
|
||||
/// <param name="part">
|
||||
/// The part that the containing mechanism was added to.
|
||||
/// </param>
|
||||
public abstract void AddedToPartInBody(SharedBodyComponent body, SharedBodyPartComponent part);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent part is removed from a body.
|
||||
/// For instance, removing a head with a brain inside from a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="old">
|
||||
/// The body that the containing mechanism was removed from.
|
||||
/// </param>
|
||||
public abstract void RemovedFromBody(SharedBodyComponent old);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent mechanism is removed from a part that is not attached to a body.
|
||||
/// For instance, removing a brain from a dismembered head.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="old">
|
||||
/// The part that the containing mechanism was removed from.
|
||||
/// </param>
|
||||
public abstract void RemovedFromPart(SharedBodyPartComponent old);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent mechanism is removed from a part that is attached to a body.
|
||||
/// For instance, removing a brain from a head that is attached to a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="oldBody">
|
||||
/// The body that the containing mechanism was removed from.
|
||||
/// </param>
|
||||
/// <param name="oldPart">
|
||||
/// The part that the containing mechanism was removed from.
|
||||
/// </param>
|
||||
public abstract void RemovedFromPartInBody(SharedBodyComponent oldBody, SharedBodyPartComponent oldPart);
|
||||
}
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Body.Part;
|
||||
using Content.Shared.Body.Part.Property;
|
||||
using Content.Shared.Body.Preset;
|
||||
using Content.Shared.Body.Slot;
|
||||
using Content.Shared.Body.Template;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Shared.Body.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Component representing a collection of <see cref="IBodyPart"/>s
|
||||
/// attached to each other.
|
||||
/// </summary>
|
||||
public interface IBody : IComponent, IBodyPartContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="BodyTemplatePrototype"/> used to create this
|
||||
/// <see cref="IBody"/>.
|
||||
/// </summary>
|
||||
public BodyTemplatePrototype? Template { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="BodyPresetPrototype"/> used to create this
|
||||
/// <see cref="IBody"/>.
|
||||
/// </summary>
|
||||
public BodyPresetPrototype? Preset { get; }
|
||||
|
||||
/// <summary>
|
||||
/// An enumeration of the slots that make up this body, regardless
|
||||
/// of if they contain a part or not.
|
||||
/// </summary>
|
||||
IEnumerable<BodyPartSlot> Slots { get; }
|
||||
|
||||
/// <summary>
|
||||
/// An enumeration of the parts on this body paired with the slots
|
||||
/// that they are in.
|
||||
/// </summary>
|
||||
IEnumerable<KeyValuePair<IBodyPart, BodyPartSlot>> Parts { get; }
|
||||
|
||||
/// <summary>
|
||||
/// An enumeration of the slots on this body without a part in them.
|
||||
/// </summary>
|
||||
IEnumerable<BodyPartSlot> EmptySlots { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Finds the central <see cref="BodyPartSlot"/>, if any,
|
||||
/// of this body.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The central <see cref="BodyPartSlot"/> if one exists,
|
||||
/// null otherwise.
|
||||
/// </returns>
|
||||
BodyPartSlot? CenterSlot { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Finds the central <see cref="IBodyPart"/>, if any,
|
||||
/// of this body.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The central <see cref="IBodyPart"/> if one exists,
|
||||
/// null otherwise.
|
||||
/// </returns>
|
||||
IBodyPart? CenterPart { get; }
|
||||
|
||||
// TODO BODY Sensible templates
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to add a part to the given slot.
|
||||
/// </summary>
|
||||
/// <param name="slotId">The slot to add this part to.</param>
|
||||
/// <param name="part">The part to add.</param>
|
||||
/// <param name="checkSlotExists">
|
||||
/// Whether to check if the slot exists, or create one otherwise.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// true if the part was added, false otherwise even if it was
|
||||
/// already added.
|
||||
/// </returns>
|
||||
bool TryAddPart(string slotId, IBodyPart part);
|
||||
|
||||
void SetPart(string slotId, IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if there is a <see cref="IBodyPart"/> in the given slot.
|
||||
/// </summary>
|
||||
/// <param name="slotId">The slot to look in.</param>
|
||||
/// <returns>
|
||||
/// true if there is a part in the given <see cref="slotId"/>,
|
||||
/// false otherwise.
|
||||
/// </returns>
|
||||
bool HasPart(string slotId);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this <see cref="IBody"/> contains the given <see cref="part"/>.
|
||||
/// </summary>
|
||||
/// <param name="part">The part to look for.</param>
|
||||
/// <returns>
|
||||
/// true if the given <see cref="part"/> is attached to the body,
|
||||
/// false otherwise.
|
||||
/// </returns>
|
||||
bool HasPart(IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the given <see cref="IBodyPart"/> from this body,
|
||||
/// dropping other <see cref="IBodyPart"/> if they were hanging
|
||||
/// off of it.
|
||||
/// <param name="part">The part to remove.</param>
|
||||
/// <returns>
|
||||
/// true if the part was removed, false otherwise
|
||||
/// even if the part was already removed previously.
|
||||
/// </returns>
|
||||
/// </summary>
|
||||
bool RemovePart(IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the body part in slot <see cref="slotId"/> from this body,
|
||||
/// if one exists.
|
||||
/// </summary>
|
||||
/// <param name="slotId">The slot to remove it from.</param>
|
||||
/// <returns>true if the part was removed, false otherwise.</returns>
|
||||
bool RemovePart(string slotId);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the body part from this body, if one exists.
|
||||
/// </summary>
|
||||
/// <param name="part">The part to remove from this body.</param>
|
||||
/// <param name="slotId">The slot that the part was in, if any.</param>
|
||||
/// <returns>
|
||||
/// true if <see cref="part"/> was removed, false otherwise.
|
||||
/// </returns>
|
||||
bool RemovePart(IBodyPart part, [NotNullWhen(true)] out BodyPartSlot? slotId);
|
||||
|
||||
/// <summary>
|
||||
/// Disconnects the given <see cref="IBodyPart"/> reference, potentially
|
||||
/// dropping other <see cref="IBodyPart">BodyParts</see> if they
|
||||
/// were hanging off of it.
|
||||
/// </summary>
|
||||
/// <param name="slot">The part to drop.</param>
|
||||
/// <param name="dropped">
|
||||
/// All of the parts that were dropped, including the one in
|
||||
/// <see cref="slot"/>.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// true if the part was dropped, false otherwise.
|
||||
/// </returns>
|
||||
bool TryDropPart(BodyPartSlot slot, [NotNullWhen(true)] out Dictionary<BodyPartSlot, IBodyPart>? dropped);
|
||||
|
||||
/// <summary>
|
||||
/// Recursively searches for if <see cref="part"/> is connected to
|
||||
/// the center.
|
||||
/// </summary>
|
||||
/// <param name="part">The body part to find the center for.</param>
|
||||
/// <returns>
|
||||
/// true if it is connected to the center, false otherwise.
|
||||
/// </returns>
|
||||
bool ConnectedToCenter(IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the given part slot exists in this body.
|
||||
/// </summary>
|
||||
/// <param name="slot">The slot to check for.</param>
|
||||
/// <returns>true if the slot exists in this body, false otherwise.</returns>
|
||||
bool HasSlot(string slot);
|
||||
|
||||
BodyPartSlot? GetSlot(IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Finds the slot that the given <see cref="IBodyPart"/> resides in.
|
||||
/// </summary>
|
||||
/// <param name="part">
|
||||
/// The <see cref="IBodyPart"/> to find the slot for.
|
||||
/// </param>
|
||||
/// <param name="slot">The slot found, if any.</param>
|
||||
/// <returns>true if a slot was found, false otherwise</returns>
|
||||
bool TryGetSlot(IBodyPart part, [NotNullWhen(true)] out BodyPartSlot? slot);
|
||||
|
||||
/// <summary>
|
||||
/// Finds the <see cref="IBodyPart"/> in the given
|
||||
/// <see cref="slotId"/> if one exists.
|
||||
/// </summary>
|
||||
/// <param name="slotId">The part slot to search in.</param>
|
||||
/// <param name="result">The body part in that slot, if any.</param>
|
||||
/// <returns>true if found, false otherwise.</returns>
|
||||
bool TryGetPart(string slotId, [NotNullWhen(true)] out IBodyPart? result);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a slot of the specified type exists on this body.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to check for.</param>
|
||||
/// <returns>true if present, false otherwise.</returns>
|
||||
bool HasSlotOfType(BodyPartType type);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all slots of the specified type on this body.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to check for.</param>
|
||||
/// <returns>An enumerable of the found slots.</returns>
|
||||
IEnumerable<BodyPartSlot> GetSlotsOfType(BodyPartType type);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a part of the specified type exists on this body.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to check for.</param>
|
||||
/// <returns>true if present, false otherwise.</returns>
|
||||
bool HasPartOfType(BodyPartType type);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all slots of the specified type on this body.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to check for.</param>
|
||||
/// <returns>An enumerable of the found slots.</returns>
|
||||
IEnumerable<IBodyPart> GetPartsOfType(BodyPartType type);
|
||||
|
||||
/// <summary>
|
||||
/// Finds all <see cref="IBodyPart"/>s with the given property in
|
||||
/// this body.
|
||||
/// </summary>
|
||||
/// <type name="type">The property type to look for.</type>
|
||||
/// <returns>A list of parts with that property.</returns>
|
||||
IEnumerable<(IBodyPart part, IBodyPartProperty property)> GetPartsWithProperty(Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Finds all <see cref="IBodyPart"/>s with the given property in this body.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The property type to look for.</typeparam>
|
||||
/// <returns>A list of parts with that property.</returns>
|
||||
IEnumerable<(IBodyPart part, T property)> GetPartsWithProperty<T>() where T : class, IBodyPartProperty;
|
||||
|
||||
// TODO BODY Make a slot object that makes sense to the human mind, and make it serializable. Imagine the possibilities!
|
||||
/// <summary>
|
||||
/// Retrieves the slot at the given index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index to look in.</param>
|
||||
/// <returns>A pair of the slot name and part type occupying it.</returns>
|
||||
BodyPartSlot SlotAt(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the part at the given index.
|
||||
/// </summary>
|
||||
/// <param name="index">The index to look in.</param>
|
||||
/// <returns>A pair of the part name and body part occupying it.</returns>
|
||||
KeyValuePair<IBodyPart, BodyPartSlot> PartAt(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Gibs this body.
|
||||
/// </summary>
|
||||
/// <param name="gibParts">
|
||||
/// Whether or not to also gib this body's parts.
|
||||
/// </param>
|
||||
void Gib(bool gibParts = false);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared.Body.Behavior;
|
||||
using Content.Shared.Body.Part;
|
||||
using Content.Shared.Body.Part.Property;
|
||||
using Content.Shared.Body.Preset;
|
||||
@@ -25,7 +26,7 @@ using Robust.Shared.ViewVariables;
|
||||
namespace Content.Shared.Body.Components
|
||||
{
|
||||
// TODO BODY Damage methods for collections of IDamageableComponents
|
||||
public abstract class SharedBodyComponent : Component, IBody, ISerializationHooks
|
||||
public abstract class SharedBodyComponent : Component, IBodyPartContainer, ISerializationHooks
|
||||
{
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
|
||||
@@ -55,13 +56,13 @@ namespace Content.Shared.Body.Components
|
||||
private Dictionary<string, BodyPartSlot> SlotIds { get; } = new();
|
||||
|
||||
[ViewVariables]
|
||||
private Dictionary<IBodyPart, BodyPartSlot> SlotParts { get; } = new();
|
||||
private Dictionary<SharedBodyPartComponent, BodyPartSlot> SlotParts { get; } = new();
|
||||
|
||||
[ViewVariables]
|
||||
public IEnumerable<BodyPartSlot> Slots => SlotIds.Values;
|
||||
|
||||
[ViewVariables]
|
||||
public IEnumerable<KeyValuePair<IBodyPart, BodyPartSlot>> Parts => SlotParts;
|
||||
public IEnumerable<KeyValuePair<SharedBodyPartComponent, BodyPartSlot>> Parts => SlotParts;
|
||||
|
||||
[ViewVariables]
|
||||
public IEnumerable<BodyPartSlot> EmptySlots => Slots.Where(slot => slot.Part == null);
|
||||
@@ -71,7 +72,7 @@ namespace Content.Shared.Body.Components
|
||||
? SlotIds.GetValueOrDefault(centerSlot)
|
||||
: null;
|
||||
|
||||
public IBodyPart? CenterPart => CenterSlot?.Part;
|
||||
public SharedBodyPartComponent? CenterPart => CenterSlot?.Part;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -119,9 +120,9 @@ namespace Content.Shared.Body.Components
|
||||
return slot;
|
||||
}
|
||||
|
||||
private Dictionary<BodyPartSlot, IBodyPart> GetHangingParts(BodyPartSlot from)
|
||||
private Dictionary<BodyPartSlot, SharedBodyPartComponent> GetHangingParts(BodyPartSlot from)
|
||||
{
|
||||
var hanging = new Dictionary<BodyPartSlot, IBodyPart>();
|
||||
var hanging = new Dictionary<BodyPartSlot, SharedBodyPartComponent>();
|
||||
|
||||
foreach (var connection in from.Connections)
|
||||
{
|
||||
@@ -135,7 +136,7 @@ namespace Content.Shared.Body.Components
|
||||
return hanging;
|
||||
}
|
||||
|
||||
protected virtual bool CanAddPart(string slotId, IBodyPart part)
|
||||
protected virtual bool CanAddPart(string slotId, SharedBodyPartComponent part)
|
||||
{
|
||||
if (!SlotIds.TryGetValue(slotId, out var slot) ||
|
||||
slot.CanAddPart(part))
|
||||
@@ -146,7 +147,7 @@ namespace Content.Shared.Body.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual void OnAddPart(BodyPartSlot slot, IBodyPart part)
|
||||
protected virtual void OnAddPart(BodyPartSlot slot, SharedBodyPartComponent part)
|
||||
{
|
||||
SlotParts[part] = slot;
|
||||
part.Body = this;
|
||||
@@ -162,7 +163,7 @@ namespace Content.Shared.Body.Components
|
||||
OnBodyChanged();
|
||||
}
|
||||
|
||||
protected virtual void OnRemovePart(BodyPartSlot slot, IBodyPart part)
|
||||
protected virtual void OnRemovePart(BodyPartSlot slot, SharedBodyPartComponent part)
|
||||
{
|
||||
SlotParts.Remove(part);
|
||||
|
||||
@@ -203,7 +204,8 @@ namespace Content.Shared.Body.Components
|
||||
OnBodyChanged();
|
||||
}
|
||||
|
||||
public bool TryAddPart(string slotId, IBodyPart part)
|
||||
// TODO BODY Sensible templates
|
||||
public bool TryAddPart(string slotId, SharedBodyPartComponent part)
|
||||
{
|
||||
DebugTools.AssertNotNull(part);
|
||||
DebugTools.AssertNotNull(slotId);
|
||||
@@ -217,7 +219,7 @@ namespace Content.Shared.Body.Components
|
||||
slot.TryAddPart(part);
|
||||
}
|
||||
|
||||
public void SetPart(string slotId, IBodyPart part)
|
||||
public void SetPart(string slotId, SharedBodyPartComponent part)
|
||||
{
|
||||
if (!SlotIds.TryGetValue(slotId, out var slot))
|
||||
{
|
||||
@@ -236,14 +238,14 @@ namespace Content.Shared.Body.Components
|
||||
slot.Part != null;
|
||||
}
|
||||
|
||||
public bool HasPart(IBodyPart part)
|
||||
public bool HasPart(SharedBodyPartComponent part)
|
||||
{
|
||||
DebugTools.AssertNotNull(part);
|
||||
|
||||
return SlotParts.ContainsKey(part);
|
||||
}
|
||||
|
||||
public bool RemovePart(IBodyPart part)
|
||||
public bool RemovePart(SharedBodyPartComponent part)
|
||||
{
|
||||
DebugTools.AssertNotNull(part);
|
||||
|
||||
@@ -259,7 +261,7 @@ namespace Content.Shared.Body.Components
|
||||
slot.RemovePart();
|
||||
}
|
||||
|
||||
public bool RemovePart(IBodyPart part, [NotNullWhen(true)] out BodyPartSlot? slotId)
|
||||
public bool RemovePart(SharedBodyPartComponent part, [NotNullWhen(true)] out BodyPartSlot? slotId)
|
||||
{
|
||||
DebugTools.AssertNotNull(part);
|
||||
|
||||
@@ -279,7 +281,7 @@ namespace Content.Shared.Body.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryDropPart(BodyPartSlot slot, [NotNullWhen(true)] out Dictionary<BodyPartSlot, IBodyPart>? dropped)
|
||||
public bool TryDropPart(BodyPartSlot slot, [NotNullWhen(true)] out Dictionary<BodyPartSlot, SharedBodyPartComponent>? dropped)
|
||||
{
|
||||
DebugTools.AssertNotNull(slot);
|
||||
|
||||
@@ -304,7 +306,7 @@ namespace Content.Shared.Body.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ConnectedToCenter(IBodyPart part)
|
||||
public bool ConnectedToCenter(SharedBodyPartComponent part)
|
||||
{
|
||||
return TryGetSlot(part, out var result) &&
|
||||
ConnectedToCenterPartRecursion(result);
|
||||
@@ -343,7 +345,7 @@ namespace Content.Shared.Body.Components
|
||||
return SlotIds.ContainsKey(slot);
|
||||
}
|
||||
|
||||
public IEnumerable<IBodyPart> GetParts()
|
||||
public IEnumerable<SharedBodyPartComponent> GetParts()
|
||||
{
|
||||
foreach (var slot in SlotIds.Values)
|
||||
{
|
||||
@@ -354,7 +356,7 @@ namespace Content.Shared.Body.Components
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetPart(string slotId, [NotNullWhen(true)] out IBodyPart? result)
|
||||
public bool TryGetPart(string slotId, [NotNullWhen(true)] out SharedBodyPartComponent? result)
|
||||
{
|
||||
result = null;
|
||||
|
||||
@@ -367,7 +369,7 @@ namespace Content.Shared.Body.Components
|
||||
return SlotIds.GetValueOrDefault(id);
|
||||
}
|
||||
|
||||
public BodyPartSlot? GetSlot(IBodyPart part)
|
||||
public BodyPartSlot? GetSlot(SharedBodyPartComponent part)
|
||||
{
|
||||
return SlotParts.GetValueOrDefault(part);
|
||||
}
|
||||
@@ -377,12 +379,12 @@ namespace Content.Shared.Body.Components
|
||||
return (slot = GetSlot(slotId)) != null;
|
||||
}
|
||||
|
||||
public bool TryGetSlot(IBodyPart part, [NotNullWhen(true)] out BodyPartSlot? slot)
|
||||
public bool TryGetSlot(SharedBodyPartComponent part, [NotNullWhen(true)] out BodyPartSlot? slot)
|
||||
{
|
||||
return (slot = GetSlot(part)) != null;
|
||||
}
|
||||
|
||||
public bool TryGetPartConnections(string slotId, [NotNullWhen(true)] out List<IBodyPart>? connections)
|
||||
public bool TryGetPartConnections(string slotId, [NotNullWhen(true)] out List<SharedBodyPartComponent>? connections)
|
||||
{
|
||||
if (!SlotIds.TryGetValue(slotId, out var slot))
|
||||
{
|
||||
@@ -390,7 +392,7 @@ namespace Content.Shared.Body.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
connections = new List<IBodyPart>();
|
||||
connections = new List<SharedBodyPartComponent>();
|
||||
foreach (var connection in slot.Connections)
|
||||
{
|
||||
if (connection.Part != null)
|
||||
@@ -439,7 +441,7 @@ namespace Content.Shared.Body.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerable<IBodyPart> GetPartsOfType(BodyPartType type)
|
||||
public IEnumerable<SharedBodyPartComponent> GetPartsOfType(BodyPartType type)
|
||||
{
|
||||
foreach (var slot in GetSlotsOfType(type))
|
||||
{
|
||||
@@ -450,7 +452,8 @@ namespace Content.Shared.Body.Components
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<(IBodyPart part, IBodyPartProperty property)> GetPartsWithProperty(Type type)
|
||||
/// <returns>A list of parts with that property.</returns>
|
||||
public IEnumerable<(SharedBodyPartComponent part, IBodyPartProperty property)> GetPartsWithProperty(Type type)
|
||||
{
|
||||
foreach (var slot in SlotIds.Values)
|
||||
{
|
||||
@@ -461,7 +464,7 @@ namespace Content.Shared.Body.Components
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<(IBodyPart part, T property)> GetPartsWithProperty<T>() where T : class, IBodyPartProperty
|
||||
public IEnumerable<(SharedBodyPartComponent part, T property)> GetPartsWithProperty<T>() where T : class, IBodyPartProperty
|
||||
{
|
||||
foreach (var part in SlotParts.Keys)
|
||||
{
|
||||
@@ -509,9 +512,6 @@ namespace Content.Shared.Body.Components
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the layout of this body changes.
|
||||
/// </summary>
|
||||
private void OnBodyChanged()
|
||||
{
|
||||
// Calculate move speed based on this body.
|
||||
@@ -523,19 +523,7 @@ namespace Content.Shared.Body.Components
|
||||
Dirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the combined length of the distance to the nearest
|
||||
/// <see cref="IBodyPart"/> that is a foot.
|
||||
/// If you consider a <see cref="IBody"/> a node map, then it will
|
||||
/// look for a foot node from the given node. It can only search
|
||||
/// through <see cref="IBodyPart"/>s with an
|
||||
/// <see cref="ExtensionComponent"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The distance to the foot if found, <see cref="float.MinValue"/>
|
||||
/// otherwise.
|
||||
/// </returns>
|
||||
public float DistanceToNearestFoot(IBodyPart source)
|
||||
public float DistanceToNearestFoot(SharedBodyPartComponent source)
|
||||
{
|
||||
if (source.PartType == BodyPartType.Foot &&
|
||||
source.TryGetProperty<ExtensionComponent>(out var extension))
|
||||
@@ -546,7 +534,7 @@ namespace Content.Shared.Body.Components
|
||||
return LookForFootRecursion(source);
|
||||
}
|
||||
|
||||
private float LookForFootRecursion(IBodyPart current, HashSet<BodyPartSlot>? searched = null)
|
||||
private float LookForFootRecursion(SharedBodyPartComponent current, HashSet<BodyPartSlot>? searched = null)
|
||||
{
|
||||
searched ??= new HashSet<BodyPartSlot>();
|
||||
|
||||
@@ -555,13 +543,11 @@ namespace Content.Shared.Body.Components
|
||||
return float.MinValue;
|
||||
}
|
||||
|
||||
// Get all connected parts if the current part has an extension property
|
||||
if (!TryGetSlot(current, out var slot))
|
||||
{
|
||||
return float.MinValue;
|
||||
}
|
||||
|
||||
// If a connected BodyPart is a foot, return this BodyPart's length.
|
||||
foreach (var connection in slot.Connections)
|
||||
{
|
||||
if (connection.PartType == BodyPartType.Foot &&
|
||||
@@ -571,8 +557,6 @@ namespace Content.Shared.Body.Components
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, get the recursion values of all connected BodyParts and
|
||||
// store them in a list.
|
||||
var distances = new List<float>();
|
||||
foreach (var connection in slot.Connections)
|
||||
{
|
||||
@@ -589,8 +573,6 @@ namespace Content.Shared.Body.Components
|
||||
}
|
||||
}
|
||||
|
||||
// If one or more of the searches found a foot, return the smallest one
|
||||
// and add this ones length.
|
||||
if (distances.Count > 0)
|
||||
{
|
||||
return distances.Min<float>() + extProperty.Distance;
|
||||
@@ -605,7 +587,7 @@ namespace Content.Shared.Body.Components
|
||||
return SlotIds.Values.ElementAt(index);
|
||||
}
|
||||
|
||||
public KeyValuePair<IBodyPart, BodyPartSlot> PartAt(int index)
|
||||
public KeyValuePair<SharedBodyPartComponent, BodyPartSlot> PartAt(int index)
|
||||
{
|
||||
return SlotParts.ElementAt(index);
|
||||
}
|
||||
@@ -664,12 +646,68 @@ namespace Content.Shared.Body.Components
|
||||
part.Gib();
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetMechanismBehaviors([NotNullWhen(true)] out List<SharedMechanismBehavior>? behaviors)
|
||||
{
|
||||
behaviors = GetMechanismBehaviors().ToList();
|
||||
|
||||
if (behaviors.Count == 0)
|
||||
{
|
||||
behaviors = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool HasMechanismBehavior<T>() where T : SharedMechanismBehavior
|
||||
{
|
||||
return Parts.Any(p => p.Key.HasMechanismBehavior<T>());
|
||||
}
|
||||
|
||||
// TODO cache these 2 methods jesus
|
||||
public IEnumerable<SharedMechanismBehavior> GetMechanismBehaviors()
|
||||
{
|
||||
foreach (var (part, _) in Parts)
|
||||
foreach (var mechanism in part.Mechanisms)
|
||||
foreach (var behavior in mechanism.Behaviors.Values)
|
||||
{
|
||||
yield return behavior;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetMechanismBehaviors<T>() where T : SharedMechanismBehavior
|
||||
{
|
||||
foreach (var (part, _) in Parts)
|
||||
foreach (var mechanism in part.Mechanisms)
|
||||
foreach (var behavior in mechanism.Behaviors.Values)
|
||||
{
|
||||
if (behavior is T tBehavior)
|
||||
{
|
||||
yield return tBehavior;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetMechanismBehaviors<T>([NotNullWhen(true)] out List<T>? behaviors)
|
||||
where T : SharedMechanismBehavior
|
||||
{
|
||||
behaviors = GetMechanismBehaviors<T>().ToList();
|
||||
|
||||
if (behaviors.Count == 0)
|
||||
{
|
||||
behaviors = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class BodyComponentState : ComponentState
|
||||
{
|
||||
private Dictionary<string, IBodyPart>? _parts;
|
||||
private Dictionary<string, SharedBodyPartComponent>? _parts;
|
||||
|
||||
public readonly (string slot, EntityUid partId)[] PartIds;
|
||||
|
||||
@@ -678,7 +716,7 @@ namespace Content.Shared.Body.Components
|
||||
PartIds = partIds;
|
||||
}
|
||||
|
||||
public Dictionary<string, IBodyPart> Parts(IEntityManager? entityManager = null)
|
||||
public Dictionary<string, SharedBodyPartComponent> Parts(IEntityManager? entityManager = null)
|
||||
{
|
||||
if (_parts != null)
|
||||
{
|
||||
@@ -687,7 +725,7 @@ namespace Content.Shared.Body.Components
|
||||
|
||||
entityManager ??= IoCManager.Resolve<IEntityManager>();
|
||||
|
||||
var parts = new Dictionary<string, IBodyPart>(PartIds.Length);
|
||||
var parts = new Dictionary<string, SharedBodyPartComponent>(PartIds.Length);
|
||||
|
||||
foreach (var (slot, partId) in PartIds)
|
||||
{
|
||||
@@ -696,7 +734,7 @@ namespace Content.Shared.Body.Components
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entity.TryGetComponent(out IBodyPart? part))
|
||||
if (!entity.TryGetComponent(out SharedBodyPartComponent? part))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.Body.Behavior;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Part;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Shared.Body.Mechanism
|
||||
{
|
||||
public interface IMechanism : IComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The body that owns the <see cref="IBodyPart"/> in which this
|
||||
/// <see cref="IMechanism"/> is in.
|
||||
/// </summary>
|
||||
IBody? Body { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The part in which this <see cref="IMechanism"/> is in.
|
||||
/// </summary>
|
||||
IBodyPart? Part { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The behaviors attached to this <see cref="IMechanism"/>
|
||||
/// mapped by their type.
|
||||
/// </summary>
|
||||
IReadOnlyDictionary<Type, IMechanismBehavior> Behaviors { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Max HP of this <see cref="IMechanism"/>.
|
||||
/// </summary>
|
||||
int MaxDurability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current HP of this <see cref="IMechanism"/>.
|
||||
/// </summary>
|
||||
int CurrentDurability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// At what HP this <see cref="IMechanism"/> is completely destroyed.
|
||||
/// </summary>
|
||||
int DestroyThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Armor of this <see cref="IMechanism"/> against attacks.
|
||||
/// </summary>
|
||||
int Resistance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines a handful of things - mostly whether this
|
||||
/// <see cref="IMechanism"/> can fit into a <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
// TODO BODY OnSizeChanged
|
||||
int Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// What kind of <see cref="IBodyPart"/> this
|
||||
/// <see cref="IMechanism"/> can be easily installed into.
|
||||
/// </summary>
|
||||
BodyPartCompatibility Compatibility { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="IMechanismBehavior"/> if this
|
||||
/// <see cref="IMechanism"/> does not have it already.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The behavior type to add.</typeparam>
|
||||
/// <returns>
|
||||
/// True if the behavior already existed, false if it had to be created.
|
||||
/// </returns>
|
||||
bool EnsureBehavior<T>(out T behavior) where T : IMechanismBehavior, new();
|
||||
|
||||
/// <summary>
|
||||
/// Checks if this <see cref="IMechanism"/> has the specified
|
||||
/// <see cref="IMechanismBehavior"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The type of <see cref="IMechanismBehavior"/> to check for.
|
||||
/// </typeparam>
|
||||
/// <returns>
|
||||
/// true if it has the <see cref="IMechanismBehavior"/>, false otherwise.
|
||||
/// </returns>
|
||||
bool HasBehavior<T>() where T : IMechanismBehavior;
|
||||
|
||||
/// <summary>
|
||||
/// Removes the specified <see cref="IMechanismBehavior"/> from this
|
||||
/// <see cref="IMechanism"/> if it has it.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The type of <see cref="IMechanismBehavior"/> to remove.
|
||||
/// </typeparam>
|
||||
/// <returns>true if it was removed, false otherwise.</returns>
|
||||
bool TryRemoveBehavior<T>() where T : IMechanismBehavior;
|
||||
|
||||
/// <summary>
|
||||
/// Runs an update cycle for this <see cref="IMechanism"/>.
|
||||
/// </summary>
|
||||
/// <param name="frameTime">
|
||||
/// The amount of seconds that passed since the last update.
|
||||
/// </param>
|
||||
void Update(float frameTime);
|
||||
|
||||
// TODO BODY Turn these into event listeners so they dont need to be exposed
|
||||
/// <summary>
|
||||
/// Called when the containing <see cref="IBodyPart"/> is attached to a
|
||||
/// <see cref="IBody"/>.
|
||||
/// For instance, attaching a head with a brain inside to a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="body">
|
||||
/// The body that this <see cref="IMechanism"/> was added to.
|
||||
/// </param>
|
||||
void AddedToBody(IBody body);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent <see cref="IMechanism"/> is
|
||||
/// added into a <see cref="IBodyPart"/> that is not attached to a
|
||||
/// <see cref="IBody"/>.
|
||||
/// For instance, adding a brain to a dismembered head.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="part">
|
||||
/// The part that this <see cref="IMechanism"/> was added to.
|
||||
/// </param>
|
||||
void AddedToPart(IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent <see cref="IMechanism"/> is added to a
|
||||
/// <see cref="IBodyPart"/> that is attached to a <see cref="IBody"/>.
|
||||
/// For instance, adding a brain to a head that is attached to a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="body">
|
||||
/// The body that this <see cref="IMechanism"/> was added to.
|
||||
/// </param>
|
||||
/// <param name="part">
|
||||
/// The part that this <see cref="IMechanism"/> was added to.
|
||||
/// </param>
|
||||
void AddedToPartInBody(IBody body, IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent <see cref="IBodyPart"/> is removed from a
|
||||
/// <see cref="IBody"/>.
|
||||
/// For instance, removing a head with a brain inside from a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="old">
|
||||
/// The body that this <see cref="IMechanism"/> was removed from.
|
||||
/// </param>
|
||||
void RemovedFromBody(IBody old);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent <see cref="IMechanism"/> is
|
||||
/// removed from a <see cref="IBodyPart"/> that is not attached to a
|
||||
/// <see cref="IBody"/>.
|
||||
/// For instance, removing a brain from a dismembered head.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="old">
|
||||
/// The part that this <see cref="IMechanism"/> was removed from.
|
||||
/// </param>
|
||||
void RemovedFromPart(IBodyPart old);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the parent <see cref="IMechanism"/> is removed from a
|
||||
/// <see cref="IBodyPart"/> that is attached to a <see cref="IBody"/>.
|
||||
/// For instance, removing a brain from a head that is attached to a body.
|
||||
/// DO NOT CALL THIS DIRECTLY FROM OUTSIDE BODY SYSTEM CODE!
|
||||
/// </summary>
|
||||
/// <param name="oldBody">
|
||||
/// The body that this <see cref="IMechanism"/> was removed from.
|
||||
/// </param>
|
||||
/// <param name="oldPart">
|
||||
/// The part that this <see cref="IMechanism"/> was removed from.
|
||||
/// </param>
|
||||
void RemovedFromPartInBody(IBody oldBody, IBodyPart oldPart);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Content.Shared.Body.Mechanism
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
foreach (var mechanism in ComponentManager.EntityQuery<IMechanism>(true))
|
||||
foreach (var mechanism in ComponentManager.EntityQuery<SharedMechanismComponent>(true))
|
||||
{
|
||||
mechanism.Update(frameTime);
|
||||
}
|
||||
|
||||
@@ -14,23 +14,23 @@ using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Body.Mechanism
|
||||
{
|
||||
public abstract class SharedMechanismComponent : Component, IMechanism, ISerializationHooks
|
||||
public abstract class SharedMechanismComponent : Component, ISerializationHooks
|
||||
{
|
||||
public override string Name => "Mechanism";
|
||||
|
||||
protected readonly Dictionary<int, object> OptionsCache = new();
|
||||
protected IBody? BodyCache;
|
||||
protected SharedBodyComponent? BodyCache;
|
||||
protected int IdHash;
|
||||
protected IEntity? PerformerCache;
|
||||
private IBodyPart? _part;
|
||||
private SharedBodyPartComponent? _part;
|
||||
|
||||
[DataField("behaviors", serverOnly: true)] private HashSet<IMechanismBehavior> _behaviorTypes = new();
|
||||
[DataField("behaviors", serverOnly: true)] private HashSet<SharedMechanismBehavior> _behaviorTypes = new();
|
||||
|
||||
private readonly Dictionary<Type, IMechanismBehavior> _behaviors = new();
|
||||
private readonly Dictionary<Type, SharedMechanismBehavior> _behaviors = new();
|
||||
|
||||
public IBody? Body => Part?.Body;
|
||||
public SharedBodyComponent? Body => Part?.Body;
|
||||
|
||||
public IBodyPart? Part
|
||||
public SharedBodyPartComponent? Part
|
||||
{
|
||||
get => _part;
|
||||
set
|
||||
@@ -69,7 +69,7 @@ namespace Content.Shared.Body.Mechanism
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<Type, IMechanismBehavior> Behaviors => _behaviors;
|
||||
public IReadOnlyDictionary<Type, SharedMechanismBehavior> Behaviors => _behaviors;
|
||||
|
||||
[DataField("maxDurability")] public int MaxDurability { get; set; } = 10;
|
||||
|
||||
@@ -82,8 +82,16 @@ namespace Content.Shared.Body.Mechanism
|
||||
[DataField("resistance")] public int Resistance { get; set; } = 0;
|
||||
|
||||
// TODO BODY OnSizeChanged
|
||||
/// <summary>
|
||||
/// Determines whether this
|
||||
/// <see cref="SharedMechanismComponent"/> can fit into a <see cref="SharedBodyPartComponent"/>.
|
||||
/// </summary>
|
||||
[DataField("size")] public int Size { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// What kind of <see cref="SharedBodyPartComponent"/> this
|
||||
/// <see cref="SharedMechanismComponent"/> can be easily installed into.
|
||||
/// </summary>
|
||||
[DataField("compatibility")]
|
||||
public BodyPartCompatibility Compatibility { get; set; } = BodyPartCompatibility.Universal;
|
||||
|
||||
@@ -128,7 +136,7 @@ namespace Content.Shared.Body.Mechanism
|
||||
}
|
||||
}
|
||||
|
||||
public bool EnsureBehavior<T>(out T behavior) where T : IMechanismBehavior, new()
|
||||
public bool EnsureBehavior<T>(out T behavior) where T : SharedMechanismBehavior, new()
|
||||
{
|
||||
if (_behaviors.TryGetValue(typeof(T), out var rawBehavior))
|
||||
{
|
||||
@@ -144,12 +152,12 @@ namespace Content.Shared.Body.Mechanism
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool HasBehavior<T>() where T : IMechanismBehavior
|
||||
public bool HasBehavior<T>() where T : SharedMechanismBehavior
|
||||
{
|
||||
return _behaviors.ContainsKey(typeof(T));
|
||||
}
|
||||
|
||||
public bool TryRemoveBehavior<T>() where T : IMechanismBehavior
|
||||
public bool TryRemoveBehavior<T>() where T : SharedMechanismBehavior
|
||||
{
|
||||
return _behaviors.Remove(typeof(T));
|
||||
}
|
||||
@@ -162,7 +170,8 @@ namespace Content.Shared.Body.Mechanism
|
||||
}
|
||||
}
|
||||
|
||||
public void AddedToBody(IBody body)
|
||||
// TODO BODY Turn these into event listeners so they dont need to be exposed
|
||||
public void AddedToBody(SharedBodyComponent body)
|
||||
{
|
||||
DebugTools.AssertNotNull(Body);
|
||||
DebugTools.AssertNotNull(body);
|
||||
@@ -173,7 +182,7 @@ namespace Content.Shared.Body.Mechanism
|
||||
}
|
||||
}
|
||||
|
||||
public void AddedToPart(IBodyPart part)
|
||||
public void AddedToPart(SharedBodyPartComponent part)
|
||||
{
|
||||
DebugTools.AssertNotNull(Part);
|
||||
DebugTools.AssertNotNull(part);
|
||||
@@ -186,7 +195,7 @@ namespace Content.Shared.Body.Mechanism
|
||||
}
|
||||
}
|
||||
|
||||
public void AddedToPartInBody(IBody body, IBodyPart part)
|
||||
public void AddedToPartInBody(SharedBodyComponent body, SharedBodyPartComponent part)
|
||||
{
|
||||
DebugTools.AssertNotNull(Body);
|
||||
DebugTools.AssertNotNull(body);
|
||||
@@ -201,7 +210,7 @@ namespace Content.Shared.Body.Mechanism
|
||||
}
|
||||
}
|
||||
|
||||
public void RemovedFromBody(IBody old)
|
||||
public void RemovedFromBody(SharedBodyComponent old)
|
||||
{
|
||||
DebugTools.AssertNull(Body);
|
||||
DebugTools.AssertNotNull(old);
|
||||
@@ -212,7 +221,7 @@ namespace Content.Shared.Body.Mechanism
|
||||
}
|
||||
}
|
||||
|
||||
public void RemovedFromPart(IBodyPart old)
|
||||
public void RemovedFromPart(SharedBodyPartComponent old)
|
||||
{
|
||||
DebugTools.AssertNull(Part);
|
||||
DebugTools.AssertNotNull(old);
|
||||
@@ -225,7 +234,7 @@ namespace Content.Shared.Body.Mechanism
|
||||
}
|
||||
}
|
||||
|
||||
public void RemovedFromPartInBody(IBody oldBody, IBodyPart oldPart)
|
||||
public void RemovedFromPartInBody(SharedBodyComponent oldBody, SharedBodyPartComponent oldPart)
|
||||
{
|
||||
DebugTools.AssertNull(Body);
|
||||
DebugTools.AssertNotNull(oldBody);
|
||||
|
||||
@@ -5,7 +5,7 @@ using Robust.Shared.Serialization;
|
||||
namespace Content.Shared.Body.Part
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether two <see cref="IBodyPart"/>s can connect.
|
||||
/// Determines whether two <see cref="SharedBodyPartComponent"/>s can connect.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public enum BodyPartCompatibility
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Content.Shared.Body.Part.Property;
|
||||
|
||||
namespace Content.Shared.Body.Part
|
||||
{
|
||||
public static class BodyPartExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if the given <see cref="IBodyPart"/> has the specified property.
|
||||
/// </summary>
|
||||
/// <param name="part">The <see cref="IBodyPart"/> to check in.</param>
|
||||
/// <param name="type">
|
||||
/// The type of <see cref="IBodyPartProperty"/> to check for.
|
||||
/// </param>
|
||||
/// <returns>true if found, false otherwise.</returns>
|
||||
public static bool HasProperty(this IBodyPart part, Type type)
|
||||
{
|
||||
return part.Owner.HasComponent(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the given <see cref="IBodyPart"/> has the specified property.
|
||||
/// </summary>
|
||||
/// <param name="part">The <see cref="IBodyPart"/> to check in.</param>
|
||||
/// <typeparam name="T">
|
||||
/// The type of <see cref="IBodyPartProperty"/> to check for.
|
||||
/// </typeparam>
|
||||
/// <returns>true if found, false otherwise.</returns>
|
||||
public static bool HasProperty<T>(this IBodyPart part) where T : class, IBodyPartProperty
|
||||
{
|
||||
return part.HasProperty(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to retrieve the <see cref="IBodyPartProperty"/> with the
|
||||
/// specified type.
|
||||
/// </summary>
|
||||
/// <param name="part">The <see cref="IBodyPart"/> to search in.</param>
|
||||
/// <param name="type">
|
||||
/// The type of <see cref="IBodyPartProperty"/> to search for.
|
||||
/// </param>
|
||||
/// <param name="property">
|
||||
/// The property, if it was found. Null otherwise.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// true if a component with the specified type was found, false otherwise.
|
||||
/// </returns>
|
||||
public static bool TryGetProperty(this IBodyPart part, Type type,
|
||||
[NotNullWhen(true)] out IBodyPartProperty? property)
|
||||
{
|
||||
if (!part.Owner.TryGetComponent(type, out var component))
|
||||
{
|
||||
property = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return (property = component as IBodyPartProperty) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to retrieve the <see cref="IBodyPartProperty"/> with the
|
||||
/// specified type.
|
||||
/// </summary>
|
||||
/// <param name="part">The <see cref="IBodyPart"/> to search in.</param>
|
||||
/// <typeparam name="T">
|
||||
/// The type of <see cref="IBodyPartProperty"/> to search for.
|
||||
/// </typeparam>
|
||||
/// <param name="property">
|
||||
/// The property, if it was found. Null otherwise.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// true if a component with the specified type was found, false otherwise.
|
||||
/// </returns>
|
||||
public static bool TryGetProperty<T>(this IBodyPart part, [NotNullWhen(true)] out T? property) where T : class, IBodyPartProperty
|
||||
{
|
||||
return part.Owner.TryGetComponent(out property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Robust.Shared.Serialization;
|
||||
namespace Content.Shared.Body.Part
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the symmetry of a <see cref="IBodyPart"/>.
|
||||
/// Defines the symmetry of a <see cref="SharedBodyPartComponent"/>.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public enum BodyPartSymmetry
|
||||
|
||||
@@ -5,7 +5,7 @@ using Robust.Shared.Serialization;
|
||||
namespace Content.Shared.Body.Part
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the type of a <see cref="IBodyPart"/>.
|
||||
/// Defines the type of a <see cref="SharedBodyPartComponent"/>.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public enum BodyPartType
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Mechanism;
|
||||
using Content.Shared.Body.Surgery;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Shared.Body.Part
|
||||
{
|
||||
public interface IBodyPart : IComponent, IBodyPartContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IBody"/> to which this <see cref="IBodyPart"/> is
|
||||
/// attached to.
|
||||
/// </summary>
|
||||
IBody? Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The string to show when displaying this part's name to players.
|
||||
/// </summary>
|
||||
string DisplayName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="BodyPartType"/> that this <see cref="IBodyPart"/> is considered
|
||||
/// to be.
|
||||
/// For example, <see cref="BodyPartType.Arm"/>.
|
||||
/// </summary>
|
||||
BodyPartType PartType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines how many mechanisms can be fit inside this
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
int Size { get; }
|
||||
|
||||
// TODO BODY Mechanisms occupying different parts at the body level
|
||||
/// <summary>
|
||||
/// Collection of all <see cref="IMechanism"/>s currently inside this
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// To add and remove from this list see <see cref="TryAddMechanism"/> and
|
||||
/// <see cref="RemoveMechanism"/>
|
||||
/// </summary>
|
||||
IReadOnlyCollection<IMechanism> Mechanisms { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the owning <see cref="Body"/> will die if all
|
||||
/// <see cref="IBodyPart"/>s of this type are removed from it.
|
||||
/// </summary>
|
||||
public bool IsVital { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The symmetry of this <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
public BodyPartSymmetry Symmetry { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the given <see cref="SurgeryType"/> can be used on
|
||||
/// the current state of this <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
/// <returns>True if it can be used, false otherwise.</returns>
|
||||
bool SurgeryCheck(SurgeryType surgery);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to perform surgery on this <see cref="IBodyPart"/> with the given
|
||||
/// tool.
|
||||
/// </summary>
|
||||
/// <returns>True if successful, false if there was an error.</returns>
|
||||
public bool AttemptSurgery(SurgeryType toolType, IBodyPartContainer target, ISurgeon surgeon,
|
||||
IEntity performer);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if another <see cref="IBodyPart"/> can be connected to this one.
|
||||
/// </summary>
|
||||
/// <param name="part">The part to connect.</param>
|
||||
/// <returns>True if it can be connected, false otherwise.</returns>
|
||||
bool CanAttachPart(IBodyPart part);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a <see cref="IMechanism"/> can be added on this
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
/// <returns>True if it can be added, false otherwise.</returns>
|
||||
bool CanAddMechanism(IMechanism mechanism);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add a <see cref="IMechanism"/> to this body.
|
||||
/// </summary>
|
||||
/// <param name="mechanism">The mechanism to add.</param>
|
||||
/// <param name="force">
|
||||
/// Whether or not to check if the mechanism is compatible.
|
||||
/// Passing true does not guarantee it to be added, for example if
|
||||
/// it was already added before.
|
||||
/// </param>
|
||||
/// <returns>true if added, false otherwise even if it was already added.</returns>
|
||||
bool TryAddMechanism(IMechanism mechanism, bool force = false);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove the given <see cref="mechanism"/> from this
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
/// <param name="mechanism">The mechanism to remove.</param>
|
||||
/// <returns>True if it was removed, false otherwise.</returns>
|
||||
bool RemoveMechanism(IMechanism mechanism);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove the given <see cref="mechanism"/> from this
|
||||
/// <see cref="IBodyPart"/> and drops it at the specified coordinates.
|
||||
/// </summary>
|
||||
/// <param name="mechanism">The mechanism to remove.</param>
|
||||
/// <param name="dropAt">The coordinates to drop it at.</param>
|
||||
/// <returns>True if it was removed, false otherwise.</returns>
|
||||
bool RemoveMechanism(IMechanism mechanism, EntityCoordinates dropAt);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to destroy the given <see cref="IMechanism"/> from
|
||||
/// this <see cref="IBodyPart"/>.
|
||||
/// The mechanism won't be deleted if it is not in this body part.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// True if the mechanism was in this body part and destroyed,
|
||||
/// false otherwise.
|
||||
/// </returns>
|
||||
bool DeleteMechanism(IMechanism mechanism);
|
||||
|
||||
/// <summary>
|
||||
/// Gibs the body part.
|
||||
/// </summary>
|
||||
void Gib();
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Content.Shared.Body.Part
|
||||
public interface IBodyPartAdded : IComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when a <see cref="IBodyPart"/> is added to the
|
||||
/// Called when a <see cref="SharedBodyPartComponent"/> is added to the
|
||||
/// entity owning this component.
|
||||
/// </summary>
|
||||
/// <param name="args">Information about the part that was added.</param>
|
||||
@@ -20,7 +20,7 @@ namespace Content.Shared.Body.Part
|
||||
|
||||
public class BodyPartAddedEventArgs : EventArgs
|
||||
{
|
||||
public BodyPartAddedEventArgs(string slot, IBodyPart part)
|
||||
public BodyPartAddedEventArgs(string slot, SharedBodyPartComponent part)
|
||||
{
|
||||
Slot = slot;
|
||||
Part = part;
|
||||
@@ -34,6 +34,6 @@ namespace Content.Shared.Body.Part
|
||||
/// <summary>
|
||||
/// The part that was added.
|
||||
/// </summary>
|
||||
public IBodyPart Part { get; }
|
||||
public SharedBodyPartComponent Part { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Content.Shared.Body.Part
|
||||
public interface IBodyPartRemoved
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when a <see cref="IBodyPart"/> is removed from the
|
||||
/// Called when a <see cref="SharedBodyPartComponent"/> is removed from the
|
||||
/// entity owning this component.
|
||||
/// </summary>
|
||||
/// <param name="args">Information about the part that was removed.</param>
|
||||
@@ -19,7 +19,7 @@ namespace Content.Shared.Body.Part
|
||||
|
||||
public class BodyPartRemovedEventArgs : EventArgs
|
||||
{
|
||||
public BodyPartRemovedEventArgs(string slot, IBodyPart part)
|
||||
public BodyPartRemovedEventArgs(string slot, SharedBodyPartComponent part)
|
||||
{
|
||||
Slot = slot;
|
||||
Part = part;
|
||||
@@ -33,6 +33,6 @@ namespace Content.Shared.Body.Part
|
||||
/// <summary>
|
||||
/// The part that was removed.
|
||||
/// </summary>
|
||||
public IBodyPart Part { get; }
|
||||
public SharedBodyPartComponent Part { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ using Robust.Shared.Serialization.Manager.Attributes;
|
||||
namespace Content.Shared.Body.Part.Property
|
||||
{
|
||||
/// <summary>
|
||||
/// Property attachable to a <see cref="IBodyPart"/>.
|
||||
/// Property attachable to a <see cref="SharedBodyPartComponent"/>.
|
||||
/// For example, this is used to define the speed capabilities of a leg.
|
||||
/// The movement system will look for a <see cref="LegComponent"/> on all
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// <see cref="SharedBodyPartComponent"/>.
|
||||
/// </summary>
|
||||
public abstract class BodyPartPropertyComponent : Component, IBodyPartProperty
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using Robust.Shared.Serialization.Manager.Attributes;
|
||||
namespace Content.Shared.Body.Part.Property
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the length of a <see cref="IBodyPart"/>.
|
||||
/// Defines the length of a <see cref="SharedBodyPartComponent"/>.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public class ExtensionComponent : BodyPartPropertyComponent
|
||||
|
||||
@@ -4,7 +4,7 @@ using Robust.Shared.GameObjects;
|
||||
namespace Content.Shared.Body.Part.Property
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a <see cref="IBodyPart"/> as being able to grasp around an entity,
|
||||
/// Defines a <see cref="SharedBodyPartComponent"/> as being able to grasp around an entity,
|
||||
/// for example picking up an item.
|
||||
/// </summary>
|
||||
// TODO BODY Implement
|
||||
|
||||
@@ -4,7 +4,7 @@ using Robust.Shared.GameObjects;
|
||||
namespace Content.Shared.Body.Part.Property
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a property for a <see cref="IBodyPart"/>.
|
||||
/// Defines a property for a <see cref="SharedBodyPartComponent"/>.
|
||||
/// </summary>
|
||||
public interface IBodyPartProperty : IComponent
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using Robust.Shared.Serialization.Manager.Attributes;
|
||||
namespace Content.Shared.Body.Part.Property
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the speed at which a <see cref="IBodyPart"/> can move.
|
||||
/// Defines the speed at which a <see cref="SharedBodyPartComponent"/> can move.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public class LegComponent : BodyPartPropertyComponent
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared.Body.Behavior;
|
||||
using Content.Shared.Body.Components;
|
||||
using Content.Shared.Body.Mechanism;
|
||||
using Content.Shared.Body.Part.Property;
|
||||
using Content.Shared.Body.Surgery;
|
||||
using Content.Shared.NetIDs;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -17,24 +20,24 @@ using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Shared.Body.Part
|
||||
{
|
||||
public abstract class SharedBodyPartComponent : Component, IBodyPart
|
||||
public abstract class SharedBodyPartComponent : Component, IBodyPartContainer
|
||||
{
|
||||
public override string Name => "BodyPart";
|
||||
|
||||
public override uint? NetID => ContentNetIDs.BODY_PART;
|
||||
|
||||
private IBody? _body;
|
||||
private SharedBodyComponent? _body;
|
||||
|
||||
// TODO BODY Remove
|
||||
[DataField("mechanisms")]
|
||||
private List<string> _mechanismIds = new();
|
||||
private readonly List<string> _mechanismIds = new();
|
||||
public IReadOnlyList<string> MechanismIds => _mechanismIds;
|
||||
|
||||
[ViewVariables]
|
||||
private readonly HashSet<IMechanism> _mechanisms = new();
|
||||
private readonly HashSet<SharedMechanismComponent> _mechanisms = new();
|
||||
|
||||
[ViewVariables]
|
||||
public IBody? Body
|
||||
public SharedBodyComponent? Body
|
||||
{
|
||||
get => _body;
|
||||
set
|
||||
@@ -59,13 +62,25 @@ namespace Content.Shared.Body.Part
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The string to show when displaying this part's name to players.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public string DisplayName => Name;
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="BodyPartType"/> that this <see cref="IBodyPart"/> is considered
|
||||
/// to be.
|
||||
/// For example, <see cref="BodyPartType.Arm"/>.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
[DataField("partType")]
|
||||
public BodyPartType PartType { get; private set; } = BodyPartType.Other;
|
||||
|
||||
/// <summary>
|
||||
/// Determines how many mechanisms can be fit inside this
|
||||
/// <see cref="SharedBodyPartComponent"/>.
|
||||
/// </summary>
|
||||
[ViewVariables] [DataField("size")] public int Size { get; private set; } = 1;
|
||||
|
||||
[ViewVariables] public int SizeUsed { get; private set; }
|
||||
@@ -74,7 +89,7 @@ namespace Content.Shared.Body.Part
|
||||
// TODO BODY surgerydata
|
||||
|
||||
/// <summary>
|
||||
/// What types of BodyParts this <see cref="IBodyPart"/> can easily attach to.
|
||||
/// What types of BodyParts this <see cref="SharedBodyPartComponent"/> can easily attach to.
|
||||
/// For the most part, most limbs aren't universal and require extra work to
|
||||
/// attach between types.
|
||||
/// </summary>
|
||||
@@ -82,17 +97,14 @@ namespace Content.Shared.Body.Part
|
||||
[DataField("compatibility")]
|
||||
public BodyPartCompatibility Compatibility { get; private set; } = BodyPartCompatibility.Universal;
|
||||
|
||||
/// <summary>
|
||||
/// Set of all <see cref="IMechanism"/> currently inside this
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// </summary>
|
||||
// TODO BODY Mechanisms occupying different parts at the body level
|
||||
[ViewVariables]
|
||||
public IReadOnlyCollection<IMechanism> Mechanisms => _mechanisms;
|
||||
public IReadOnlyCollection<SharedMechanismComponent> Mechanisms => _mechanisms;
|
||||
|
||||
// TODO BODY Replace with a simulation of organs
|
||||
/// <summary>
|
||||
/// Represents if body part is vital for creature.
|
||||
/// If the last vital body part is removed creature dies
|
||||
/// Whether or not the owning <see cref="Body"/> will die if all
|
||||
/// <see cref="SharedBodyPartComponent"/>s of this type are removed from it.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
[DataField("vital")]
|
||||
@@ -105,7 +117,7 @@ namespace Content.Shared.Body.Part
|
||||
[ViewVariables]
|
||||
public ISurgeryData? SurgeryDataComponent => Owner.GetComponentOrNull<ISurgeryData>();
|
||||
|
||||
protected virtual void OnAddMechanism(IMechanism mechanism)
|
||||
protected virtual void OnAddMechanism(SharedMechanismComponent mechanism)
|
||||
{
|
||||
var prototypeId = mechanism.Owner.Prototype!.ID;
|
||||
|
||||
@@ -120,7 +132,7 @@ namespace Content.Shared.Body.Part
|
||||
Dirty();
|
||||
}
|
||||
|
||||
protected virtual void OnRemoveMechanism(IMechanism mechanism)
|
||||
protected virtual void OnRemoveMechanism(SharedMechanismComponent mechanism)
|
||||
{
|
||||
_mechanismIds.Remove(mechanism.Owner.Prototype!.ID);
|
||||
mechanism.Part = null;
|
||||
@@ -176,11 +188,6 @@ namespace Content.Shared.Body.Part
|
||||
return SurgeryDataComponent?.CheckSurgery(surgery) ?? false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to perform surgery on this <see cref="IBodyPart"/> with the given
|
||||
/// tool.
|
||||
/// </summary>
|
||||
/// <returns>True if successful, false if there was an error.</returns>
|
||||
public bool AttemptSurgery(SurgeryType toolType, IBodyPartContainer target, ISurgeon surgeon, IEntity performer)
|
||||
{
|
||||
DebugTools.AssertNotNull(toolType);
|
||||
@@ -191,14 +198,14 @@ namespace Content.Shared.Body.Part
|
||||
return SurgeryDataComponent?.PerformSurgery(toolType, target, surgeon, performer) ?? false;
|
||||
}
|
||||
|
||||
public bool CanAttachPart(IBodyPart part)
|
||||
public bool CanAttachPart(SharedBodyPartComponent part)
|
||||
{
|
||||
DebugTools.AssertNotNull(part);
|
||||
|
||||
return SurgeryDataComponent?.CanAttachBodyPart(part) ?? false;
|
||||
}
|
||||
|
||||
public virtual bool CanAddMechanism(IMechanism mechanism)
|
||||
public virtual bool CanAddMechanism(SharedMechanismComponent mechanism)
|
||||
{
|
||||
DebugTools.AssertNotNull(mechanism);
|
||||
|
||||
@@ -208,19 +215,16 @@ namespace Content.Shared.Body.Part
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add a mechanism onto this body part.
|
||||
/// Tries to add a <see cref="SharedMechanismComponent"/> to this part.
|
||||
/// </summary>
|
||||
/// <param name="mechanism">The mechanism to try to add.</param>
|
||||
/// <param name="mechanism">The mechanism to add.</param>
|
||||
/// <param name="force">
|
||||
/// Whether or not to check if the mechanism can be added.
|
||||
/// Whether or not to check if the mechanism is compatible.
|
||||
/// Passing true does not guarantee it to be added, for example if
|
||||
/// it was already added before.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// True if successful, false if there was an error
|
||||
/// (e.g. not enough room in <see cref="IBodyPart"/>).
|
||||
/// Will return false even when forced if the mechanism is already
|
||||
/// added in this <see cref="IBodyPart"/>.
|
||||
/// </returns>
|
||||
public bool TryAddMechanism(IMechanism mechanism, bool force = false)
|
||||
/// <returns>true if added, false otherwise even if it was already added.</returns>
|
||||
public bool TryAddMechanism(SharedMechanismComponent mechanism, bool force = false)
|
||||
{
|
||||
DebugTools.AssertNotNull(mechanism);
|
||||
|
||||
@@ -239,7 +243,12 @@ namespace Content.Shared.Body.Part
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveMechanism(IMechanism mechanism)
|
||||
/// <summary>
|
||||
/// Tries to remove the given <see cref="mechanism"/> from this part.
|
||||
/// </summary>
|
||||
/// <param name="mechanism">The mechanism to remove.</param>
|
||||
/// <returns>True if it was removed, false otherwise.</returns>
|
||||
public bool RemoveMechanism(SharedMechanismComponent mechanism)
|
||||
{
|
||||
DebugTools.AssertNotNull(mechanism);
|
||||
|
||||
@@ -253,7 +262,14 @@ namespace Content.Shared.Body.Part
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveMechanism(IMechanism mechanism, EntityCoordinates coordinates)
|
||||
/// <summary>
|
||||
/// Tries to remove the given <see cref="mechanism"/> from this
|
||||
/// part and drops it at the specified coordinates.
|
||||
/// </summary>
|
||||
/// <param name="mechanism">The mechanism to remove.</param>
|
||||
/// <param name="coordinates">The coordinates to drop it at.</param>
|
||||
/// <returns>True if it was removed, false otherwise.</returns>
|
||||
public bool RemoveMechanism(SharedMechanismComponent mechanism, EntityCoordinates coordinates)
|
||||
{
|
||||
if (RemoveMechanism(mechanism))
|
||||
{
|
||||
@@ -264,7 +280,16 @@ namespace Content.Shared.Body.Part
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DeleteMechanism(IMechanism mechanism)
|
||||
/// <summary>
|
||||
/// Tries to destroy the given <see cref="SharedMechanismComponent"/> from
|
||||
/// this part.
|
||||
/// The mechanism won't be deleted if it is not in this body part.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// True if the mechanism was in this body part and destroyed,
|
||||
/// false otherwise.
|
||||
/// </returns>
|
||||
public bool DeleteMechanism(SharedMechanismComponent mechanism)
|
||||
{
|
||||
DebugTools.AssertNotNull(mechanism);
|
||||
|
||||
@@ -277,7 +302,7 @@ namespace Content.Shared.Body.Part
|
||||
return true;
|
||||
}
|
||||
|
||||
private void AddedToBody(IBody body)
|
||||
private void AddedToBody(SharedBodyComponent body)
|
||||
{
|
||||
Owner.Transform.LocalRotation = 0;
|
||||
Owner.Transform.AttachParent(body.Owner);
|
||||
@@ -289,7 +314,7 @@ namespace Content.Shared.Body.Part
|
||||
}
|
||||
}
|
||||
|
||||
private void RemovedFromBody(IBody old)
|
||||
private void RemovedFromBody(SharedBodyComponent old)
|
||||
{
|
||||
if (!Owner.Transform.Deleted)
|
||||
{
|
||||
@@ -304,10 +329,13 @@ namespace Content.Shared.Body.Part
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnAddedToBody(IBody body) { }
|
||||
protected virtual void OnAddedToBody(SharedBodyComponent body) { }
|
||||
|
||||
protected virtual void OnRemovedFromBody(IBody old) { }
|
||||
protected virtual void OnRemovedFromBody(SharedBodyComponent old) { }
|
||||
|
||||
/// <summary>
|
||||
/// Gibs the body part.
|
||||
/// </summary>
|
||||
public virtual void Gib()
|
||||
{
|
||||
foreach (var mechanism in _mechanisms)
|
||||
@@ -315,12 +343,44 @@ namespace Content.Shared.Body.Part
|
||||
RemoveMechanism(mechanism);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasProperty(Type type)
|
||||
{
|
||||
return Owner.HasComponent(type);
|
||||
}
|
||||
|
||||
public bool HasProperty<T>() where T : class, IBodyPartProperty
|
||||
{
|
||||
return HasProperty(typeof(T));
|
||||
}
|
||||
|
||||
public bool TryGetProperty(Type type,
|
||||
[NotNullWhen(true)] out IBodyPartProperty? property)
|
||||
{
|
||||
if (!Owner.TryGetComponent(type, out var component))
|
||||
{
|
||||
property = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return (property = component as IBodyPartProperty) != null;
|
||||
}
|
||||
|
||||
public bool TryGetProperty<T>([NotNullWhen(true)] out T? property) where T : class, IBodyPartProperty
|
||||
{
|
||||
return Owner.TryGetComponent(out property);
|
||||
}
|
||||
|
||||
public bool HasMechanismBehavior<T>() where T : SharedMechanismBehavior
|
||||
{
|
||||
return Mechanisms.Any(m => m.HasBehavior<T>());
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class BodyPartComponentState : ComponentState
|
||||
{
|
||||
[NonSerialized] private List<IMechanism>? _mechanisms;
|
||||
[NonSerialized] private List<SharedMechanismComponent>? _mechanisms;
|
||||
|
||||
public readonly EntityUid[] MechanismIds;
|
||||
|
||||
@@ -329,7 +389,7 @@ namespace Content.Shared.Body.Part
|
||||
MechanismIds = mechanismIds;
|
||||
}
|
||||
|
||||
public List<IMechanism> Mechanisms(IEntityManager? entityManager = null)
|
||||
public List<SharedMechanismComponent> Mechanisms(IEntityManager? entityManager = null)
|
||||
{
|
||||
if (_mechanisms != null)
|
||||
{
|
||||
@@ -338,7 +398,7 @@ namespace Content.Shared.Body.Part
|
||||
|
||||
entityManager ??= IoCManager.Resolve<IEntityManager>();
|
||||
|
||||
var mechanisms = new List<IMechanism>(MechanismIds.Length);
|
||||
var mechanisms = new List<SharedMechanismComponent>(MechanismIds.Length);
|
||||
|
||||
foreach (var id in MechanismIds)
|
||||
{
|
||||
@@ -347,7 +407,7 @@ namespace Content.Shared.Body.Part
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entity.TryGetComponent(out IMechanism? mechanism))
|
||||
if (!entity.TryGetComponent(out SharedMechanismComponent? mechanism))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ using Robust.Shared.ViewVariables;
|
||||
namespace Content.Shared.Body.Preset
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the <see cref="IBodyPart"/>s used in a <see cref="IBody"/>.
|
||||
/// Defines the parts used in a body.
|
||||
/// </summary>
|
||||
[Prototype("bodyPreset")]
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Content.Shared.Body.Slot
|
||||
/// The part currently in this slot, if any.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public IBodyPart? Part { get; private set; }
|
||||
public SharedBodyPartComponent? Part { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// List of slots that this slot connects to.
|
||||
@@ -45,21 +45,21 @@ namespace Content.Shared.Body.Slot
|
||||
[ViewVariables]
|
||||
public HashSet<BodyPartSlot> Connections { get; private set; }
|
||||
|
||||
public event Action<IBodyPart>? PartAdded;
|
||||
public event Action<SharedBodyPartComponent>? PartAdded;
|
||||
|
||||
public event Action<IBodyPart>? PartRemoved;
|
||||
public event Action<SharedBodyPartComponent>? PartRemoved;
|
||||
|
||||
internal void SetConnectionsInternal(IEnumerable<BodyPartSlot> connections)
|
||||
{
|
||||
Connections = new HashSet<BodyPartSlot>(connections);
|
||||
}
|
||||
|
||||
public bool CanAddPart(IBodyPart part)
|
||||
public bool CanAddPart(SharedBodyPartComponent part)
|
||||
{
|
||||
return Part == null && part.PartType == PartType;
|
||||
}
|
||||
|
||||
public bool TryAddPart(IBodyPart part)
|
||||
public bool TryAddPart(SharedBodyPartComponent part)
|
||||
{
|
||||
if (!CanAddPart(part))
|
||||
{
|
||||
@@ -70,7 +70,7 @@ namespace Content.Shared.Body.Slot
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetPart(IBodyPart part)
|
||||
public void SetPart(SharedBodyPartComponent part)
|
||||
{
|
||||
if (Part != null)
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Content.Shared.Body.Surgery
|
||||
public interface ISurgeon
|
||||
{
|
||||
public delegate void MechanismRequestCallback(
|
||||
IMechanism target,
|
||||
SharedMechanismComponent target,
|
||||
IBodyPartContainer container,
|
||||
ISurgeon surgeon,
|
||||
IEntity performer);
|
||||
@@ -25,10 +25,10 @@ namespace Content.Shared.Body.Surgery
|
||||
/// <summary>
|
||||
/// When performing a surgery, the <see cref="SurgeryDataComponent"/>
|
||||
/// may sometimes require selecting from a set of
|
||||
/// <see cref="IMechanism"/>s to operate on.
|
||||
/// <see cref="SharedMechanismComponent"/>s to operate on.
|
||||
/// This function is called in that scenario, and it is expected that you call
|
||||
/// the callback with one <see cref="IMechanism"/> from the provided list.
|
||||
/// the callback with one <see cref="SharedMechanismComponent"/> from the provided list.
|
||||
/// </summary>
|
||||
public void RequestMechanism(IEnumerable<IMechanism> options, MechanismRequestCallback callback);
|
||||
public void RequestMechanism(IEnumerable<SharedMechanismComponent> options, MechanismRequestCallback callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,21 +6,21 @@ using Robust.Shared.GameObjects;
|
||||
namespace Content.Shared.Body.Surgery
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the current surgery state of a <see cref="IBodyPart"/>.
|
||||
/// Represents the current surgery state of a <see cref="SharedBodyPartComponent"/>.
|
||||
/// </summary>
|
||||
public interface ISurgeryData : IComponent
|
||||
{
|
||||
public delegate void SurgeryAction(IBodyPartContainer container, ISurgeon surgeon, IEntity performer);
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IBodyPart"/> this
|
||||
/// The <see cref="SharedBodyPartComponent"/> this
|
||||
/// <see cref="ISurgeryData"/> is attached to.
|
||||
/// </summary>
|
||||
public IBodyPart? Parent { get; }
|
||||
public SharedBodyPartComponent? Parent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="BodyPartType"/> of the parent
|
||||
/// <see cref="IBodyPart"/>.
|
||||
/// <see cref="SharedBodyPartComponent"/>.
|
||||
/// </summary>
|
||||
public BodyPartType? ParentType { get; }
|
||||
|
||||
@@ -31,18 +31,18 @@ namespace Content.Shared.Body.Surgery
|
||||
public string GetDescription();
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a <see cref="IMechanism"/> can be added into the
|
||||
/// <see cref="IBodyPart"/> this <see cref="ISurgeryData"/>
|
||||
/// Returns whether a <see cref="SharedMechanismComponent"/> can be added into the
|
||||
/// <see cref="SharedBodyPartComponent"/> this <see cref="ISurgeryData"/>
|
||||
/// represents.
|
||||
/// </summary>
|
||||
public bool CanAddMechanism(IMechanism mechanism);
|
||||
public bool CanAddMechanism(SharedMechanismComponent mechanism);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the given <see cref="IBodyPart"/> can be connected
|
||||
/// to the <see cref="IBodyPart"/> this <see cref="ISurgeryData"/>
|
||||
/// Returns whether the given <see cref="SharedBodyPartComponent"/> can be connected
|
||||
/// to the <see cref="SharedBodyPartComponent"/> this <see cref="ISurgeryData"/>
|
||||
/// represents.
|
||||
/// </summary>
|
||||
public bool CanAttachBodyPart(IBodyPart part);
|
||||
public bool CanAttachBodyPart(SharedBodyPartComponent part);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the delegate corresponding to the surgery step using the given
|
||||
@@ -56,7 +56,7 @@ namespace Content.Shared.Body.Surgery
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether the given <see cref="SurgeryType"/> can be used to
|
||||
/// perform a surgery on the <see cref="IBodyPart"/> this
|
||||
/// perform a surgery on the <see cref="SharedBodyPartComponent"/> this
|
||||
/// <see cref="ISurgeryData"/> represents.
|
||||
/// </summary>
|
||||
public bool CheckSurgery(SurgeryType toolType)
|
||||
|
||||
@@ -11,7 +11,7 @@ using Robust.Shared.ViewVariables;
|
||||
namespace Content.Shared.Body.Template
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the layout of a <see cref="IBody"/>.
|
||||
/// Defines the layout of a body.
|
||||
/// </summary>
|
||||
[Prototype("bodyTemplate")]
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
Reference in New Issue
Block a user