forked from space-syndicate/space-station-14
-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ExeCute * fix? * nope * fix: formatting - remove useless comments - if statement in OnSignalRecieved() should be handled in switch-case - Logger class shouldn't be used in logging, there is sawmills for this - Remove unnecessary methods * some more shit * wrong author --------- Co-authored-by: JerryImMouse <[email protected]>
- Loading branch information
1 parent
e3f7bce
commit 7b4b3c3
Showing
7 changed files
with
290 additions
and
0 deletions.
There are no files selected for viewing
85 changes: 85 additions & 0 deletions
85
Content.Server/_CorvaxNext/ExecutionChair/ExecutionChairComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
using Content.Shared.DeviceLinking; | ||
using Robust.Shared.Audio; | ||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; | ||
using Content.Server._CorvaxNext.ExecutionChair; | ||
|
||
namespace Content.Server._CorvaxNext.ExecutionChair; | ||
|
||
/// <summary> | ||
/// This component represents the state and configuration of an Execution Chair entity. | ||
/// It holds data fields that determine how the chair behaves when it delivers electric shocks | ||
/// to entities buckled into it. It also provides fields for connecting to and receiving signals | ||
/// from the device linking system. | ||
/// </summary> | ||
[RegisterComponent, Access(typeof(ExecutionChairSystem))] | ||
public sealed partial class ExecutionChairComponent : Component | ||
{ | ||
/// <summary> | ||
/// The next scheduled time at which this chair can deliver damage to strapped entities. | ||
/// This is used to control the rate of repeated electrocution ticks. | ||
/// </summary> | ||
[ViewVariables] | ||
public TimeSpan NextDamageTick = TimeSpan.Zero; | ||
|
||
/// <summary> | ||
/// Indicates whether the chair is currently enabled. If true, and all conditions (powered, anchored, etc.) | ||
/// are met, the chair will deliver electrical damage to any buckled entities at regular intervals. | ||
/// </summary> | ||
[DataField, AutoNetworkedField] | ||
public bool Enabled = false; | ||
|
||
/// <summary> | ||
/// Determines whether the chair should play a sound when entities are shocked. If set to true, | ||
/// a sound from <see cref="ShockNoises"/> will be played each time damage is dealt. | ||
/// </summary> | ||
[DataField] | ||
public bool PlaySoundOnShock = true; | ||
|
||
/// <summary> | ||
/// Specifies which sound collection is played when entities are shocked. By default, uses a collection of | ||
/// "sparks" sounds. This allows multiple random sparks audio clips to be played. | ||
/// </summary> | ||
[DataField] | ||
public SoundSpecifier ShockNoises = new SoundCollectionSpecifier("sparks"); | ||
|
||
/// <summary> | ||
/// Controls how loud the shock sound is. This value is applied to the base volume of the chosen sound | ||
/// when played. | ||
/// </summary> | ||
[DataField] | ||
public float ShockVolume = 20; | ||
|
||
/// <summary> | ||
/// The amount of damage delivered to a buckled entity each damage tick while the chair is active. | ||
/// </summary> | ||
[DataField] | ||
public int DamagePerTick = 25; | ||
|
||
/// <summary> | ||
/// The duration in seconds for which the electrocution effect is applied each time damage is dealt. | ||
/// For example, if set to 4, it electrocutes an entity for 4 seconds. | ||
/// </summary> | ||
[DataField] | ||
public int DamageTime = 4; | ||
|
||
/// <summary> | ||
/// The name of the device link port used to toggle the chair's state. Receiving a signal on this port | ||
/// switches the enabled state from on to off or from off to on. | ||
/// </summary> | ||
[DataField] | ||
public string TogglePort = "Toggle"; | ||
|
||
/// <summary> | ||
/// The name of the device link port used to force the chair's state to enabled (on). | ||
/// Receiving a signal here ensures the chair is active. | ||
/// </summary> | ||
[DataField] | ||
public string OnPort = "On"; | ||
|
||
/// <summary> | ||
/// The name of the device link port used to force the chair's state to disabled (off). | ||
/// Receiving a signal here ensures the chair is inactive. | ||
/// </summary> | ||
[DataField] | ||
public string OffPort = "Off"; | ||
} |
138 changes: 138 additions & 0 deletions
138
Content.Server/_CorvaxNext/ExecutionChair/ExecutionChairSystem.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
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 Content.Shared.Popups; | ||
using Robust.Shared.Audio; | ||
using Robust.Shared.Audio.Systems; | ||
using Robust.Shared.Random; | ||
using Robust.Shared.Timing; | ||
|
||
namespace Content.Server._CorvaxNext.ExecutionChair | ||
{ | ||
public sealed partial class ExecutionChairSystem : EntitySystem | ||
{ | ||
[Dependency] private readonly IGameTiming _gameTimer = default!; | ||
[Dependency] private readonly IRobustRandom _randomGen = default!; | ||
[Dependency] private readonly DeviceLinkSystem _deviceSystem = default!; | ||
[Dependency] private readonly ElectrocutionSystem _shockSystem = default!; | ||
[Dependency] private readonly SharedAudioSystem _soundSystem = default!; | ||
[Dependency] private readonly SharedPopupSystem _popup = default!; | ||
|
||
private ISawmill _sawmill = default!; | ||
|
||
private const float VolumeVariationMin = 0.8f; | ||
private const float VolumeVariationMax = 1.2f; | ||
|
||
public override void Initialize() | ||
{ | ||
base.Initialize(); | ||
SubscribeLocalEvent<ExecutionChairComponent, MapInitEvent>(OnChairSpawned); | ||
SubscribeLocalEvent<ExecutionChairComponent, SignalReceivedEvent>(OnSignalReceived); | ||
|
||
_sawmill = Logger.GetSawmill("execution_chair"); | ||
} | ||
|
||
private void OnChairSpawned(EntityUid uid, ExecutionChairComponent component, ref MapInitEvent args) | ||
{ | ||
_deviceSystem.EnsureSinkPorts(uid, component.TogglePort, component.OnPort, component.OffPort); | ||
} | ||
|
||
private void OnSignalReceived(EntityUid uid, ExecutionChairComponent component, ref SignalReceivedEvent args) | ||
{ | ||
// default case for switch below | ||
bool DefaultCase(EntityUid uid, string port, ExecutionChairComponent component) | ||
{ | ||
_sawmill.Debug($"Receieved unexpected port signal: {port} on chair {ToPrettyString(uid)}"); | ||
return component.Enabled; | ||
} | ||
|
||
var newState = args.Port switch | ||
{ | ||
var p when p == component.TogglePort => !component.Enabled, | ||
var p when p == component.OnPort => true, | ||
var p when p == component.OffPort => false, | ||
_ => DefaultCase(uid, args.Port, component) | ||
}; | ||
|
||
UpdateChairState(uid, newState, component); | ||
} | ||
|
||
private void UpdateChairState(EntityUid uid, bool activated, ExecutionChairComponent? component = null) | ||
{ | ||
if (!Resolve(uid, ref component)) | ||
return; | ||
|
||
component.Enabled = activated; | ||
Dirty(uid, component); | ||
var message = activated | ||
? Loc.GetString("execution-chair-turn-on") | ||
: Loc.GetString("execution-chair-chair-turn-off"); | ||
|
||
_popup.PopupEntity(message, uid, PopupType.Medium); | ||
} | ||
|
||
public override void Update(float frameTime) | ||
{ | ||
base.Update(frameTime); | ||
|
||
var query = EntityQueryEnumerator<ExecutionChairComponent>(); | ||
|
||
while (query.MoveNext(out var uid, out var chair)) | ||
{ | ||
if (!ValidateChairOperation(uid, chair)) | ||
continue; | ||
|
||
if (!TryComp<StrapComponent>(uid, out var restraint) || restraint.BuckledEntities.Count == 0) | ||
continue; | ||
|
||
ApplyShockEffect(uid, chair, restraint); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Ensures that the chair is in a valid state to operate: | ||
/// - The chair is anchored in the world (not picked up or moved). | ||
/// - The chair is powered. | ||
/// - The chair is currently enabled/turned on. | ||
/// - The current game time has passed beyond the next scheduled damage tick. | ||
/// </summary> | ||
private bool ValidateChairOperation(EntityUid uid, ExecutionChairComponent chair) | ||
{ | ||
var transformComponent = Transform(uid); | ||
return transformComponent.Anchored && | ||
this.IsPowered(uid, EntityManager) && | ||
chair.Enabled && | ||
_gameTimer.CurTime >= chair.NextDamageTick; | ||
} | ||
|
||
private void ApplyShockEffect(EntityUid uid, ExecutionChairComponent chair, StrapComponent restraint) | ||
{ | ||
var shockDuration = TimeSpan.FromSeconds(chair.DamageTime); | ||
|
||
foreach (var target in restraint.BuckledEntities) | ||
{ | ||
var volumeModifier = _randomGen.NextFloat(VolumeVariationMin, VolumeVariationMax); | ||
|
||
var shockSuccess = _shockSystem.TryDoElectrocution( | ||
target, | ||
uid, | ||
chair.DamagePerTick, | ||
shockDuration, | ||
true, | ||
volumeModifier, | ||
ignoreInsulation: true | ||
); | ||
|
||
if (shockSuccess && chair.PlaySoundOnShock && chair.ShockNoises != null) | ||
{ | ||
var audioParams = AudioParams.Default.WithVolume(chair.ShockVolume); | ||
_soundSystem.PlayPvs(chair.ShockNoises, target, audioParams); | ||
} | ||
} | ||
|
||
chair.NextDamageTick = _gameTimer.CurTime + TimeSpan.FromSeconds(1); | ||
} | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
Resources/Locale/ru-RU/_CorvaxNext/executionchair/executionchair.ftl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
execution-chair-turn-on = Воздух словно искрится... | ||
execution-chair-chair-turn-off = Атмосфера разряжается. |
2 changes: 2 additions & 0 deletions
2
...ale/ru-RU/ss14-ru/prototypes/_corvaxnext/entities/structures/machines/execution_chair.ftl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
ent-ExecutionChair = электрический стул | ||
.desc = Выглядит комфортно. |
48 changes: 48 additions & 0 deletions
48
Resources/Prototypes/_CorvaxNext/Entities/Structures/Machines/execution_chair.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
- type: entity | ||
id: ExecutionChair | ||
parent: BaseStructureDynamic | ||
name: execution chair | ||
description: Looks comfy. | ||
components: | ||
- type: Sprite | ||
sprite: _CorvaxNext/Structures/Furniture/execution_chair.rsi | ||
state: execution-chair | ||
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: ExecutionChair | ||
- type: ApcPowerReceiver | ||
powerLoad: 1500 | ||
- type: ExtensionCableReceiver | ||
- type: Transform | ||
anchored: true | ||
- type: Damageable | ||
damageModifierSet: Metallic | ||
- type: Destructible | ||
thresholds: | ||
- trigger: | ||
!type:DamageTrigger | ||
damage: 100 | ||
behaviors: | ||
- !type:DoActsBehavior | ||
acts: ["Destruction"] | ||
- !type:PlaySoundBehavior | ||
sound: | ||
collection: MetalBreak | ||
- !type:SpawnEntitiesBehavior | ||
spawn: | ||
SheetSteel: | ||
min: 5 | ||
max: 5 |
Binary file added
BIN
+2.91 KB
...xtures/_CorvaxNext/Structures/Furniture/execution_chair.rsi/execution-chair.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions
15
Resources/Textures/_CorvaxNext/Structures/Furniture/execution_chair.rsi/meta.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"version": 1, | ||
"license": "CC-BY-SA-4.0", | ||
"copyright": "Made by ko4erga(discord 266899933632659456) for Corvax", | ||
"size": { | ||
"x": 32, | ||
"y": 32 | ||
}, | ||
"states": [ | ||
{ | ||
"name": "execution-chair", | ||
"directions": 4 | ||
} | ||
] | ||
} |