using Content.Shared.Atmos.EntitySystems; using Content.Shared.Damage; using Content.Shared.FixedPoint; using Content.Shared.Guidebook; using Robust.Shared.GameStates; namespace Content.Shared.Atmos.Components; /// /// Entities that have this component will have damage done to them depending on the local pressure /// environment that they reside in. /// /// Atmospherics.DeltaPressure batch-processes entities with this component in a list on /// the grid's GridAtmosphereComponent. /// The entities are automatically added and removed from this list, and automatically /// added on initialization. /// /// Note that the entity should have an AirtightComponent and be a grid structure. [RegisterComponent] [NetworkedComponent, AutoGenerateComponentState] [Access(typeof(SharedAtmosphereSystem), typeof(SharedDeltaPressureSystem))] public sealed partial class DeltaPressureComponent : Component { /// /// Whether the entity is currently in the processing list of the grid's GridAtmosphereComponent. /// [DataField(readOnly: true)] [ViewVariables(VVAccess.ReadOnly)] public bool InProcessingList; /// /// Whether this entity is currently taking damage from pressure. /// [DataField, AutoNetworkedField] public bool IsTakingDamage; /// /// The grid this entity is currently joined to for processing. /// Required for proper deletion, as we cannot reference the grid /// for removal while the entity is being deleted. /// /// Note that while AirtightComponent already stores the grid, /// we cannot trust it to be available on init or when the entity is being deleted. Tragic. /// Double note: this is set during ComponentInit and thus does not need to be a datafield /// or else it will spam serialization. /// TODO ATMOS: Simply use AirtightComponent's GridUID caching and handle entity removal from the processing list on an invalidation system similar to InvalidTiles. [ViewVariables(VVAccess.ReadOnly)] public EntityUid? GridUid; /// /// The percent chance that the entity will take damage each atmos tick, /// when the entity is above the damage threshold. /// Makes it so that windows don't all break in one go. /// Float is from 0 to 1, where 1 means 100% chance. /// If this is set to 0, the entity will never take damage. /// [DataField] public float RandomDamageChance = 1f; /// /// The base damage applied to the entity per atmos tick when it is above the damage threshold. /// This damage will be scaled as defined by the enum /// depending on the current effective pressure this entity is experiencing. /// Note that this damage will scale depending on the pressure above the minimum pressure, /// not at the current pressure. /// [DataField] public DamageSpecifier BaseDamage = new() { DamageDict = new Dictionary { { "Structural", 10 }, }, }; /// /// The minimum pressure in kPa at which the entity will start taking damage. /// This doesn't depend on the difference in pressure. /// The entity will start to take damage if it is exposed to this pressure. /// This is needed because we don't correctly handle 2-layer windows yet. /// [DataField] public float MinPressure = 10000; /// /// The minimum difference in pressure between any side required for the entity to start taking damage. /// [DataField] [GuidebookData] public float MinPressureDelta = 7500; /// /// The maximum pressure at which damage will no longer scale. /// If the effective pressure goes beyond this, the damage will be considered at this pressure. /// [DataField] public float MaxEffectivePressure = 10000; /// /// Simple constant to affect the scaling behavior. /// See comments in the types to see how this affects scaling. /// [DataField] public float ScalingPower = 1; /// /// Defines the scaling behavior for the damage. /// [DataField] public DeltaPressureDamageScalingType ScalingType = DeltaPressureDamageScalingType.Threshold; } /// /// An enum that defines how the damage dealt by the scales /// depending on the pressure experienced by the entity. /// The scaling is done on the effective pressure, which is the pressure above the minimum pressure. /// See https://www.desmos.com/calculator/9ctlq3zpnt for a visual representation of the scaling types. /// [Serializable] public enum DeltaPressureDamageScalingType : byte { /// /// Damage dealt will be constant as long as the minimum values are met. /// Scaling power is ignored. /// Threshold, /// /// Damage dealt will be a linear function. /// Scaling power determines the slope of the function. /// Linear, /// /// Damage dealt will be a logarithmic function. /// Scaling power determines the base of the log. /// Log, }