#nullable enable
using System;
using Content.Server.GameObjects.Components.Body;
using Content.Server.GameObjects.Components.Metabolism;
namespace Content.Server.Body.Mechanisms.Behaviors
{
///
/// The behaviors a mechanism performs.
///
public abstract class MechanismBehavior
{
private bool Initialized { get; set; }
private bool Removed { get; set; }
///
/// The network, if any, that this behavior forms when its mechanism is
/// added and destroys when its mechanism is removed.
///
protected virtual Type? Network { get; } = null;
///
/// Upward reference to the parent that this
/// behavior is attached to.
///
protected Mechanism Mechanism { get; private set; } = null!;
///
/// Called by a to initialize this behavior.
///
/// The mechanism that owns this behavior.
///
/// If the mechanism has already been initialized.
///
public void Initialize(Mechanism mechanism)
{
if (Initialized)
{
throw new InvalidOperationException("This mechanism has already been initialized.");
}
Mechanism = mechanism;
Initialize();
if (Mechanism.Body != null)
{
OnInstalledIntoBody();
}
if (Mechanism.Part != null)
{
OnInstalledIntoPart();
}
Initialized = true;
}
///
/// Called when a behavior is removed from a .
///
public void Remove()
{
OnRemove();
TryRemoveNetwork(Mechanism.Body);
Mechanism = null!;
Removed = true;
}
///
/// Called when the containing is attached to a
/// .
/// For instance, attaching a head to a body will call this on the brain inside.
///
public void InstalledIntoBody()
{
TryAddNetwork();
OnInstalledIntoBody();
}
///
/// Called when the parent is
/// installed into a .
/// For instance, putting a brain into an empty head.
///
public void InstalledIntoPart()
{
TryAddNetwork();
OnInstalledIntoPart();
}
///
/// Called when the containing is removed from a
/// .
/// For instance, cutting off ones head will call this on the brain inside.
///
public void RemovedFromBody(IBodyManagerComponent old)
{
OnRemovedFromBody(old);
TryRemoveNetwork(old);
}
///
/// Called when the parent is
/// removed from a .
/// For instance, taking a brain out of ones head.
///
public void RemovedFromPart(IBodyPart old)
{
OnRemovedFromPart(old);
TryRemoveNetwork(old.Body);
}
private void TryAddNetwork()
{
if (Network != null)
{
Mechanism.Body?.EnsureNetwork(Network);
}
}
private void TryRemoveNetwork(IBodyManagerComponent? body)
{
if (Network != null)
{
body?.RemoveNetwork(Network);
}
}
///
/// Called by when this behavior is first initialized.
///
protected virtual void Initialize() { }
protected virtual void OnRemove() { }
///
/// Called when the containing is attached to a
/// .
/// For instance, attaching a head to a body will call this on the brain inside.
///
protected virtual void OnInstalledIntoBody() { }
///
/// Called when the parent is
/// installed into a .
/// For instance, putting a brain into an empty head.
///
protected virtual void OnInstalledIntoPart() { }
///
/// Called when the containing is removed from a
/// .
/// For instance, cutting off ones head will call this on the brain inside.
///
protected virtual void OnRemovedFromBody(IBodyManagerComponent old) { }
///
/// Called when the parent is
/// removed from a .
/// For instance, taking a brain out of ones head.
///
protected virtual void OnRemovedFromPart(IBodyPart old) { }
///
/// Called every update when this behavior is connected to a
/// , but not while in a
/// or
/// ,
/// before is called.
///
public virtual void PreMetabolism(float frameTime) { }
///
/// Called every update when this behavior is connected to a
/// , but not while in a
/// or
/// ,
/// after is called.
///
public virtual void PostMetabolism(float frameTime) { }
}
}