using Content.Shared.Changeling.Systems; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; using Content.Shared.FixedPoint; using Content.Shared.Whitelist; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.Changeling.Components; /// /// Component responsible for Changelings Devour attack. Including the amount of damage /// and how long it takes to devour someone /// [RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause] [Access(typeof(ChangelingDevourSystem))] public sealed partial class ChangelingDevourComponent : Component { /// /// The Action for devouring /// [DataField] public EntProtoId? ChangelingDevourAction = "ActionChangelingDevour"; /// /// The action entity associated with devouring /// [DataField, AutoNetworkedField] public EntityUid? ChangelingDevourActionEntity; /// /// The whitelist of targets for devouring /// [DataField, AutoNetworkedField] public EntityWhitelist? Whitelist = new() { Components = [ "MobState", "HumanoidAppearance", ], }; /// /// The Sound to use during consumption of a victim /// /// /// 6 distance due to the default 15 being hearable all the way across PVS. Changeling is meant to be stealthy. /// 6 still allows the sound to be hearable, but not across an entire department. /// [DataField, AutoNetworkedField] public SoundSpecifier? ConsumeNoise = new SoundCollectionSpecifier("ChangelingDevourConsume", AudioParams.Default.WithMaxDistance(6)); /// /// The Sound to use during the windup before consuming a victim /// /// /// 6 distance due to the default 15 being hearable all the way across PVS. Changeling is meant to be stealthy. /// 6 still allows the sound to be hearable, but not across an entire department. /// [DataField, AutoNetworkedField] public SoundSpecifier? DevourWindupNoise = new SoundCollectionSpecifier("ChangelingDevourWindup", AudioParams.Default.WithMaxDistance(6)); /// /// The time between damage ticks /// [DataField, AutoNetworkedField] public TimeSpan DamageTimeBetweenTicks = TimeSpan.FromSeconds(1); /// /// The windup time before the changeling begins to engage in devouring the identity of a target /// [DataField, AutoNetworkedField] public TimeSpan DevourWindupTime = TimeSpan.FromSeconds(2); /// /// The time it takes to FULLY consume someones identity. /// [DataField, AutoNetworkedField] public TimeSpan DevourConsumeTime = TimeSpan.FromSeconds(10); /// /// Damage cap that a target is allowed to be caused due to IdentityConsumption /// [DataField, AutoNetworkedField] public float DevourConsumeDamageCap = 350f; /// /// The Currently active devour sound in the world /// [DataField] public EntityUid? CurrentDevourSound; /// /// The damage profile for a single tick of devour damage /// [DataField, AutoNetworkedField] public DamageSpecifier DamagePerTick = new() { DamageDict = new Dictionary { { "Slash", 10}, { "Piercing", 10 }, { "Blunt", 5 }, }, }; /// /// The list of protective damage types capable of preventing a devour if over the threshold /// [DataField, AutoNetworkedField] public List> ProtectiveDamageTypes = new() { "Slash", "Piercing", "Blunt", }; /// /// The next Tick to deal damage on (utilized during the consumption "do-during" (a do after with an attempt event)) /// [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField, AutoPausedField] public TimeSpan NextTick = TimeSpan.Zero; /// /// The percentage of ANY brute damage resistance that will prevent devouring /// [DataField, AutoNetworkedField] public float DevourPreventionPercentageThreshold = 0.1f; public override bool SendOnlyToOwner => true; }