Add IMechanism interface to body system (#1997)

This commit is contained in:
DrSmugleaf
2020-09-02 01:16:13 +02:00
committed by GitHub
parent 072f374bcc
commit 682b6b9568
9 changed files with 162 additions and 117 deletions

View File

@@ -36,7 +36,7 @@ namespace Content.Server.Body
{
private IBodyManagerComponent? _body;
private readonly HashSet<Mechanism> _mechanisms = new HashSet<Mechanism>();
private readonly HashSet<IMechanism> _mechanisms = new HashSet<IMechanism>();
public BodyPart(BodyPartPrototype data)
{
@@ -146,11 +146,11 @@ namespace Content.Server.Body
public BodyPartCompatibility Compatibility { get; private set; }
/// <summary>
/// Set of all <see cref="Mechanism"/> currently inside this
/// Set of all <see cref="IMechanism"/> currently inside this
/// <see cref="IBodyPart"/>.
/// </summary>
[ViewVariables]
public IReadOnlyCollection<Mechanism> Mechanisms => _mechanisms;
public IReadOnlyCollection<IMechanism> Mechanisms => _mechanisms;
/// <summary>
/// This method is called by
@@ -258,7 +258,7 @@ namespace Content.Server.Body
return SurgeryData.CanAttachBodyPart(part);
}
public bool CanInstallMechanism(Mechanism mechanism)
public bool CanInstallMechanism(IMechanism mechanism)
{
return SizeUsed + mechanism.Size <= Size &&
SurgeryData.CanInstallMechanism(mechanism);
@@ -275,7 +275,7 @@ namespace Content.Server.Body
/// True if successful, false if there was an error
/// (e.g. not enough room in <see cref="IBodyPart"/>).
/// </returns>
private bool TryInstallMechanism(Mechanism mechanism)
private bool TryInstallMechanism(IMechanism mechanism)
{
if (!CanInstallMechanism(mechanism))
{
@@ -308,7 +308,7 @@ namespace Content.Server.Body
return true;
}
public bool TryDropMechanism(IEntity dropLocation, Mechanism mechanismTarget,
public bool TryDropMechanism(IEntity dropLocation, IMechanism mechanismTarget,
[NotNullWhen(true)] out DroppedMechanismComponent dropped)
{
dropped = null!;
@@ -331,16 +331,16 @@ namespace Content.Server.Body
}
/// <summary>
/// Tries to destroy the given <see cref="Mechanism"/> in this
/// Tries to destroy the given <see cref="IMechanism"/> in this
/// <see cref="IBodyPart"/>. Does NOT spawn a dropped entity.
/// </summary>
/// <summary>
/// Tries to destroy the given <see cref="Mechanism"/> in this
/// Tries to destroy the given <see cref="IMechanism"/> in this
/// <see cref="IBodyPart"/>.
/// </summary>
/// <param name="mechanismTarget">The mechanism to destroy.</param>
/// <returns>True if successful, false otherwise.</returns>
public bool DestroyMechanism(Mechanism mechanismTarget)
public bool DestroyMechanism(IMechanism mechanismTarget)
{
if (!RemoveMechanism(mechanismTarget))
{
@@ -365,7 +365,7 @@ namespace Content.Server.Body
return SurgeryData.PerformSurgery(toolType, target, surgeon, performer);
}
private void AddMechanism(Mechanism mechanism)
private void AddMechanism(IMechanism mechanism)
{
DebugTools.AssertNotNull(mechanism);
@@ -402,7 +402,7 @@ namespace Content.Server.Body
/// </summary>
/// <param name="mechanism">The mechanism to remove.</param>
/// <returns>True if it was removed, false otherwise.</returns>
private bool RemoveMechanism(Mechanism mechanism)
private bool RemoveMechanism(IMechanism mechanism)
{
DebugTools.AssertNotNull(mechanism);

View File

@@ -54,12 +54,12 @@ namespace Content.Server.Body
int CurrentDurability { get; }
/// <summary>
/// Collection of all <see cref="Mechanism"/>s currently inside this
/// Collection of all <see cref="IMechanism"/>s currently inside this
/// <see cref="IBodyPart"/>.
/// To add and remove from this list see <see cref="AddMechanism"/> and
/// <see cref="RemoveMechanism"/>
/// </summary>
IReadOnlyCollection<Mechanism> Mechanisms { get; }
IReadOnlyCollection<IMechanism> Mechanisms { get; }
/// <summary>
/// Path to the RSI that represents this <see cref="IBodyPart"/>.
@@ -109,23 +109,23 @@ namespace Content.Server.Body
bool CanAttachPart(IBodyPart part);
/// <summary>
/// Checks if a <see cref="Mechanism"/> can be installed on this
/// Checks if a <see cref="IMechanism"/> can be installed on this
/// <see cref="IBodyPart"/>.
/// </summary>
/// <returns>True if it can be installed, false otherwise.</returns>
bool CanInstallMechanism(Mechanism mechanism);
bool CanInstallMechanism(IMechanism mechanism);
/// <summary>
/// Tries to remove the given <see cref="Mechanism"/> reference from
/// Tries to remove the given <see cref="IMechanism"/> reference from
/// this <see cref="IBodyPart"/>.
/// </summary>
/// <returns>
/// The newly spawned <see cref="DroppedMechanismComponent"/>, or null
/// if there was an error in spawning the entity or removing the mechanism.
/// </returns>
bool TryDropMechanism(IEntity dropLocation, Mechanism mechanismTarget,
bool TryDropMechanism(IEntity dropLocation, IMechanism mechanismTarget,
[NotNullWhen(true)] out DroppedMechanismComponent dropped);
bool DestroyMechanism(Mechanism mechanism);
bool DestroyMechanism(IMechanism mechanism);
}
}

View File

@@ -0,0 +1,103 @@
#nullable enable
using System.Collections.Generic;
using Content.Server.Body.Mechanisms.Behaviors;
using Content.Server.GameObjects.Components.Body;
using Content.Shared.GameObjects.Components.Body;
namespace Content.Server.Body.Mechanisms
{
public interface IMechanism
{
string Id { get; }
string Name { get; set; }
/// <summary>
/// Professional description of the <see cref="IMechanism"/>.
/// </summary>
string Description { get; set; }
/// <summary>
/// The message to display upon examining a mob with this Mechanism installed.
/// If the string is empty (""), no message will be displayed.
/// </summary>
string ExamineMessage { get; set; }
// TODO: Make RSI properties sane
/// <summary>
/// Path to the RSI that represents this <see cref="IMechanism"/>.
/// </summary>
string RSIPath { get; set; }
/// <summary>
/// RSI state that represents this <see cref="IMechanism"/>.
/// </summary>
string RSIState { get; set; }
/// <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: 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; }
IReadOnlyList<MechanismBehavior> Behaviors { get; }
IBodyManagerComponent? Body { get; }
IBodyPart? Part { get; set; }
void EnsureInitialize();
void InstalledIntoBody();
void RemovedFromBody(IBodyManagerComponent old);
/// <summary>
/// This method is called by <see cref="IBodyPart.PreMetabolism"/> before
/// <see cref="MetabolismComponent.Update"/> is called.
/// </summary>
void PreMetabolism(float frameTime);
/// <summary>
/// This method is called by <see cref="IBodyPart.PostMetabolism"/> after
/// <see cref="MetabolismComponent.Update"/> is called.
/// </summary>
void PostMetabolism(float frameTime);
void AddBehavior(MechanismBehavior behavior);
/// <summary>
/// Removes a behavior from this mechanism.
/// </summary>
/// <param name="behavior">The behavior to remove.</param>
/// <returns>True if it was removed, false otherwise.</returns>
bool RemoveBehavior(MechanismBehavior behavior);
}
}

View File

@@ -16,7 +16,7 @@ namespace Content.Server.Body.Mechanisms
/// This includes livers, eyes, cameras, brains, explosive implants,
/// binary communicators, and other things.
/// </summary>
public class Mechanism
public class Mechanism : IMechanism
{
private IBodyPart? _part;
@@ -29,7 +29,7 @@ namespace Content.Server.Body.Mechanisms
ExamineMessage = null!;
RSIPath = null!;
RSIState = null!;
Behaviors = new List<MechanismBehavior>();
_behaviors = new List<MechanismBehavior>();
}
[ViewVariables] private bool Initialized { get; set; }
@@ -40,74 +40,29 @@ namespace Content.Server.Body.Mechanisms
[ViewVariables] public string Name { get; set; }
/// <summary>
/// Professional description of the <see cref="Mechanism"/>.
/// </summary>
[ViewVariables]
public string Description { get; set; }
[ViewVariables] public string Description { get; set; }
/// <summary>
/// The message to display upon examining a mob with this Mechanism installed.
/// If the string is empty (""), no message will be displayed.
/// </summary>
[ViewVariables]
public string ExamineMessage { get; set; }
[ViewVariables] public string ExamineMessage { get; set; }
/// <summary>
/// Path to the RSI that represents this <see cref="Mechanism"/>.
/// </summary>
[ViewVariables]
public string RSIPath { get; set; }
[ViewVariables] public string RSIPath { get; set; }
/// <summary>
/// RSI state that represents this <see cref="Mechanism"/>.
/// </summary>
[ViewVariables]
public string RSIState { get; set; }
[ViewVariables] public string RSIState { get; set; }
/// <summary>
/// Max HP of this <see cref="Mechanism"/>.
/// </summary>
[ViewVariables]
public int MaxDurability { get; set; }
[ViewVariables] public int MaxDurability { get; set; }
/// <summary>
/// Current HP of this <see cref="Mechanism"/>.
/// </summary>
[ViewVariables]
public int CurrentDurability { get; set; }
[ViewVariables] public int CurrentDurability { get; set; }
/// <summary>
/// At what HP this <see cref="Mechanism"/> is completely destroyed.
/// </summary>
[ViewVariables]
public int DestroyThreshold { get; set; }
[ViewVariables] public int DestroyThreshold { get; set; }
/// <summary>
/// Armor of this <see cref="Mechanism"/> against attacks.
/// </summary>
[ViewVariables]
public int Resistance { get; set; }
[ViewVariables] public int Resistance { get; set; }
/// <summary>
/// Determines a handful of things - mostly whether this
/// <see cref="Mechanism"/> can fit into a <see cref="IBodyPart"/>.
/// </summary>
[ViewVariables]
public int Size { get; set; }
[ViewVariables] public int Size { get; set; }
/// <summary>
/// What kind of <see cref="IBodyPart"/> this <see cref="Mechanism"/> can be
/// easily installed into.
/// </summary>
[ViewVariables]
public BodyPartCompatibility Compatibility { get; set; }
[ViewVariables] public BodyPartCompatibility Compatibility { get; set; }
/// <summary>
/// The behaviors that this <see cref="Mechanism"/> performs.
/// </summary>
[ViewVariables]
private List<MechanismBehavior> Behaviors { get; }
private readonly List<MechanismBehavior> _behaviors;
[ViewVariables] public IReadOnlyList<MechanismBehavior> Behaviors => _behaviors;
public IBodyManagerComponent? Body => Part?.Body;
@@ -167,7 +122,7 @@ namespace Content.Server.Body.Mechanisms
Size = data.Size;
Compatibility = data.Compatibility;
foreach (var behavior in Behaviors.ToArray())
foreach (var behavior in _behaviors.ToArray())
{
RemoveBehavior(behavior);
}
@@ -210,10 +165,6 @@ namespace Content.Server.Body.Mechanisms
}
}
/// <summary>
/// This method is called by <see cref="IBodyPart.PreMetabolism"/> before
/// <see cref="MetabolismComponent.Update"/> is called.
/// </summary>
public void PreMetabolism(float frameTime)
{
foreach (var behavior in Behaviors)
@@ -222,10 +173,6 @@ namespace Content.Server.Body.Mechanisms
}
}
/// <summary>
/// This method is called by <see cref="IBodyPart.PostMetabolism"/> after
/// <see cref="MetabolismComponent.Update"/> is called.
/// </summary>
public void PostMetabolism(float frameTime)
{
foreach (var behavior in Behaviors)
@@ -234,16 +181,21 @@ namespace Content.Server.Body.Mechanisms
}
}
private void AddBehavior(MechanismBehavior behavior)
public void AddBehavior(MechanismBehavior behavior)
{
Behaviors.Add(behavior);
_behaviors.Add(behavior);
behavior.Initialize(this);
}
private bool RemoveBehavior(MechanismBehavior behavior)
public bool RemoveBehavior(MechanismBehavior behavior)
{
if (_behaviors.Remove(behavior))
{
behavior.Remove();
return Behaviors.Remove(behavior);
return true;
}
return false;
}
}
}

View File

@@ -17,7 +17,7 @@ namespace Content.Server.Body.Surgery
[UsedImplicitly]
public class BiologicalSurgeryData : SurgeryData
{
private readonly List<Mechanism> _disconnectedOrgans = new List<Mechanism>();
private readonly List<IMechanism> _disconnectedOrgans = new List<IMechanism>();
private bool _skinOpened;
private bool _skinRetracted;
@@ -118,7 +118,7 @@ namespace Content.Server.Body.Surgery
return toReturn;
}
public override bool CanInstallMechanism(Mechanism mechanism)
public override bool CanInstallMechanism(IMechanism mechanism)
{
return _skinOpened && _vesselsClamped && _skinRetracted;
}
@@ -170,7 +170,7 @@ namespace Content.Server.Body.Surgery
return;
}
var toSend = new List<Mechanism>();
var toSend = new List<IMechanism>();
foreach (var mechanism in Parent.Mechanisms)
{
if (!_disconnectedOrgans.Contains(mechanism))
@@ -185,7 +185,7 @@ namespace Content.Server.Body.Surgery
}
}
private void LoosenOrganSurgeryCallback(Mechanism target, IBodyPartContainer container, ISurgeon surgeon,
private void LoosenOrganSurgeryCallback(IMechanism target, IBodyPartContainer container, ISurgeon surgeon,
IEntity performer)
{
if (target == null || !Parent.Mechanisms.Contains(target))
@@ -216,7 +216,7 @@ namespace Content.Server.Body.Surgery
}
}
private void RemoveOrganSurgeryCallback(Mechanism target, IBodyPartContainer container, ISurgeon surgeon,
private void RemoveOrganSurgeryCallback(IMechanism target, IBodyPartContainer container, ISurgeon surgeon,
IEntity performer)
{
if (target == null || !Parent.Mechanisms.Contains(target))

View File

@@ -13,7 +13,7 @@ namespace Content.Server.Body.Surgery
public interface ISurgeon
{
public delegate void MechanismRequestCallback(
Mechanism target,
IMechanism target,
IBodyPartContainer container,
ISurgeon surgeon,
IEntity performer);
@@ -29,6 +29,6 @@ namespace Content.Server.Body.Surgery
/// This function is called in that scenario, and it is expected that you call the callback with one mechanism from the
/// provided list.
/// </summary>
public void RequestMechanism(IEnumerable<Mechanism> options, MechanismRequestCallback callback);
public void RequestMechanism(IEnumerable<IMechanism> options, MechanismRequestCallback callback);
}
}

View File

@@ -38,10 +38,10 @@ namespace Content.Server.Body.Surgery
public abstract string GetDescription(IEntity target);
/// <summary>
/// Returns whether a <see cref="Mechanism"/> can be installed into the
/// Returns whether a <see cref="IMechanism"/> can be installed into the
/// <see cref="IBodyPart"/> this <see cref="SurgeryData"/> represents.
/// </summary>
public abstract bool CanInstallMechanism(Mechanism mechanism);
public abstract bool CanInstallMechanism(IMechanism mechanism);
/// <summary>
/// Returns whether the given <see cref="IBodyPart"/> can be connected to the

View File

@@ -40,7 +40,7 @@ namespace Content.Server.GameObjects.Components.Body
private IEntity? _performerCache;
[ViewVariables] public Mechanism ContainedMechanism { get; private set; } = default!;
[ViewVariables] public IMechanism ContainedMechanism { get; private set; } = default!;
[ViewVariables] private BoundUserInterface? UserInterface => Owner.GetUIOrNull(GenericSurgeryUiKey.Key);
@@ -81,7 +81,7 @@ namespace Content.Server.GameObjects.Components.Body
}
}
public void InitializeDroppedMechanism(Mechanism data)
public void InitializeDroppedMechanism(IMechanism data)
{
ContainedMechanism = data;
Owner.Name = Loc.GetString(ContainedMechanism.Name);

View File

@@ -128,7 +128,7 @@ namespace Content.Server.GameObjects.Components.Body
public float BaseOperationTime { get => _baseOperateTime; set => _baseOperateTime = value; }
public void RequestMechanism(IEnumerable<Mechanism> options, ISurgeon.MechanismRequestCallback callback)
public void RequestMechanism(IEnumerable<IMechanism> options, ISurgeon.MechanismRequestCallback callback)
{
var toSend = new Dictionary<string, int>();
foreach (var mechanism in options)
@@ -230,7 +230,7 @@ namespace Content.Server.GameObjects.Components.Body
/// <summary>
/// Called after the client chooses from a list of possible
/// <see cref="Mechanism"/> to choose from.
/// <see cref="IMechanism"/> to choose from.
/// </summary>
private void HandleReceiveMechanism(int key)
{
@@ -251,23 +251,13 @@ namespace Content.Server.GameObjects.Components.Body
private void SendNoUsefulWayToUsePopup()
{
if (_bodyManagerComponentCache == null)
{
return;
}
_bodyManagerComponentCache.Owner.PopupMessage(_performerCache,
_bodyManagerComponentCache?.Owner.PopupMessage(_performerCache,
Loc.GetString("You see no useful way to use {0:theName}.", Owner));
}
private void SendNoUsefulWayToUseAnymorePopup()
{
if (_bodyManagerComponentCache == null)
{
return;
}
_bodyManagerComponentCache.Owner.PopupMessage(_performerCache,
_bodyManagerComponentCache?.Owner.PopupMessage(_performerCache,
Loc.GetString("You see no useful way to use {0:theName} anymore.", Owner));
}