#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) { } } }