From 5243abff806d58f5a53dda5e34268fc3e5651f46 Mon Sep 17 00:00:00 2001 From: Kirus59 <145689588+Kirus59@users.noreply.github.com> Date: Wed, 23 Oct 2024 22:42:45 +0300 Subject: [PATCH] electrical chair --- .../ElectricalChairComponent.cs | 40 ++++++++ .../ElectricalChair/ElectricalChairSystem.cs | 94 +++++++++++++++++++ .../Structures/Machines/electrical_chair.yml | 52 ++++++++++ 3 files changed, 186 insertions(+) create mode 100644 Content.Server/SS220/ElectricalChair/ElectricalChairComponent.cs create mode 100644 Content.Server/SS220/ElectricalChair/ElectricalChairSystem.cs create mode 100644 Resources/Prototypes/SS220/Entities/Structures/Machines/electrical_chair.yml diff --git a/Content.Server/SS220/ElectricalChair/ElectricalChairComponent.cs b/Content.Server/SS220/ElectricalChair/ElectricalChairComponent.cs new file mode 100644 index 00000000000000..5abb33d9c920a6 --- /dev/null +++ b/Content.Server/SS220/ElectricalChair/ElectricalChairComponent.cs @@ -0,0 +1,40 @@ +// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt +using Content.Shared.DeviceLinking; +using Robust.Shared.Audio; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Server.SS220.ElectricalChair; + +[RegisterComponent, Access(typeof(ElectricalChairSystem))] +public sealed partial class ElectricalChairComponent : Component +{ + [ViewVariables] + public TimeSpan NextDamageSecond = TimeSpan.Zero; + + [DataField, AutoNetworkedField] + public bool Enabled = false; + + [DataField] + public int DamagePerSecond = 40; + + [DataField] + public int ElectrocuteTime = 4; + + [DataField] + public bool PlaySoundOnShock = true; + + [DataField] + public SoundSpecifier ShockNoises = new SoundCollectionSpecifier("sparks"); + + [DataField] + public float ShockVolume = 20; + + [DataField(customTypeSerializer: typeof(PrototypeIdSerializer))] + public string TogglePort = "Toggle"; + + [DataField(customTypeSerializer: typeof(PrototypeIdSerializer))] + public string OnPort = "On"; + + [DataField(customTypeSerializer: typeof(PrototypeIdSerializer))] + public string OffPort = "Off"; +} diff --git a/Content.Server/SS220/ElectricalChair/ElectricalChairSystem.cs b/Content.Server/SS220/ElectricalChair/ElectricalChairSystem.cs new file mode 100644 index 00000000000000..e22d0fa6faa917 --- /dev/null +++ b/Content.Server/SS220/ElectricalChair/ElectricalChairSystem.cs @@ -0,0 +1,94 @@ +// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt +using Content.Server.DeviceLinking.Events; +using Content.Server.DeviceLinking.Systems; +using Content.Server.Electrocution; +using Content.Server.Power.EntitySystems; +using Content.Shared.Buckle.Components; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Server.SS220.ElectricalChair; + +public sealed partial class ElectricalChairSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly DeviceLinkSystem _deviceLink = default!; + [Dependency] private readonly ElectrocutionSystem _electrocution = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnSignalReceived); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var component)) + { + if (!CanDoElectrocution(uid, component) || + _timing.CurTime < component.NextDamageSecond || + !TryComp(uid, out var strap) || + strap.BuckledEntities.Count <= 0) + continue; + + foreach (var target in strap.BuckledEntities) + { + if (_electrocution.TryDoElectrocution(target, + uid, + component.DamagePerSecond, + TimeSpan.FromSeconds(component.ElectrocuteTime), + true, + _random.NextFloat(0.8f, 1.2f), + ignoreInsulation: true) && + component.PlaySoundOnShock) + { + _audio.PlayPvs(component.ShockNoises, target, AudioParams.Default.WithVolume(component.ShockVolume)); + } + } + + component.NextDamageSecond = _timing.CurTime + TimeSpan.FromSeconds(1); + } + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + _deviceLink.EnsureSinkPorts(ent, ent.Comp.TogglePort, ent.Comp.OnPort, ent.Comp.OffPort); + } + + private void OnSignalReceived(Entity ent, ref SignalReceivedEvent args) + { + if (args.Port == ent.Comp.TogglePort) + SetState(ent, !ent.Comp.Enabled); + else if (args.Port == ent.Comp.OnPort) + SetState(ent, true); + else if (args.Port == ent.Comp.OffPort) + SetState(ent, false); + } + + private void SetState(EntityUid uid, bool value, ElectricalChairComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + component.Enabled = value; + Dirty(uid, component); + } + + private bool CanDoElectrocution(EntityUid uid, ElectricalChairComponent component) + { + var xform = Transform(uid); + if (!xform.Anchored || !this.IsPowered(uid, EntityManager)) + return false; + + return component.Enabled; + } +} diff --git a/Resources/Prototypes/SS220/Entities/Structures/Machines/electrical_chair.yml b/Resources/Prototypes/SS220/Entities/Structures/Machines/electrical_chair.yml new file mode 100644 index 00000000000000..a7db844451317c --- /dev/null +++ b/Resources/Prototypes/SS220/Entities/Structures/Machines/electrical_chair.yml @@ -0,0 +1,52 @@ +- type: entity + id: ElectricalChair + parent: BaseStructureDynamic + name: electrical chair + description: bzzzt. + components: + - type: Sprite + sprite: Structures/Furniture/chairs.rsi + state: wooden + noRot: true + - type: Rotatable + - type: InteractionOutline + - type: Strap + position: Stand + buckleOffset: "0,-0.05" + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeCircle + radius: 0.2 + density: 100 + mask: + - TableMask + - type: ElectricalChair + - type: ApcPowerReceiver + powerLoad: 1500 + - type: ExtensionCableReceiver + - type: Damageable + damageModifierSet: Wood + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 25 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: WoodDestroy + - !type:SpawnEntitiesBehavior + spawn: + MaterialWoodPlank: + min: 1 + max: 1 + - type: AddSleepAction #SS220-chair-sleep + - type: Tag + tags: + - Wooden + - type: StaticPrice + price: 75