From a3849c8aa91d7b672ac6b035d59cef875440807c Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Sun, 16 Feb 2025 00:39:36 +0300 Subject: [PATCH] pressure plate (#902) --- .../DeviceLinking/CP14PressurePlateSystem.cs | 99 ++++++++++++++++++ .../Components/CP14PressurePlateComponent.cs | 39 +++++++ .../CP14SharedPressurePlateSignal.cs | 9 ++ .../machineLinking/transmitter_ports.ftl | 5 + .../machineLinking/transmitter_ports.ftl | 5 + .../_CP14/DeviceLinking/source_ports.yml | 11 ++ .../Objects/Specific/Thaumaturgy/tools.yml | 14 ++- .../Specific/Device/pressure_plate.yml | 71 +++++++++++++ .../Specific/Device/wallmount_buttons.yml | 22 ++-- .../Device/pressure_plate.rsi/meta.json | 17 +++ .../Device/pressure_plate.rsi/wooden.png | Bin 0 -> 464 bytes .../pressure_plate.rsi/wooden_pressed.png | Bin 0 -> 435 bytes .../Device/wallmount_buttons.rsi}/meta.json | 4 + .../Device/wallmount_buttons.rsi/stone.png | Bin 0 -> 396 bytes .../Device/wallmount_buttons.rsi}/wooden.png | Bin 15 files changed, 287 insertions(+), 9 deletions(-) create mode 100644 Content.Server/_CP14/DeviceLinking/CP14PressurePlateSystem.cs create mode 100644 Content.Server/_CP14/DeviceLinking/Components/CP14PressurePlateComponent.cs create mode 100644 Content.Shared/_CP14/DeviceLinking/CP14SharedPressurePlateSignal.cs create mode 100644 Resources/Locale/en-US/_CP14/machineLinking/transmitter_ports.ftl create mode 100644 Resources/Locale/ru-RU/_CP14/machineLinking/transmitter_ports.ftl create mode 100644 Resources/Prototypes/_CP14/DeviceLinking/source_ports.yml create mode 100644 Resources/Prototypes/_CP14/Entities/Structures/Specific/Device/pressure_plate.yml create mode 100644 Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/meta.json create mode 100644 Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/wooden.png create mode 100644 Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/wooden_pressed.png rename Resources/Textures/_CP14/Structures/{Wallmount/buttons.rsi => Specific/Device/wallmount_buttons.rsi}/meta.json (77%) create mode 100644 Resources/Textures/_CP14/Structures/Specific/Device/wallmount_buttons.rsi/stone.png rename Resources/Textures/_CP14/Structures/{Wallmount/buttons.rsi => Specific/Device/wallmount_buttons.rsi}/wooden.png (100%) diff --git a/Content.Server/_CP14/DeviceLinking/CP14PressurePlateSystem.cs b/Content.Server/_CP14/DeviceLinking/CP14PressurePlateSystem.cs new file mode 100644 index 0000000000..b6d082f836 --- /dev/null +++ b/Content.Server/_CP14/DeviceLinking/CP14PressurePlateSystem.cs @@ -0,0 +1,99 @@ +using Content.Server.DeviceLinking.Systems; +using Content.Server.Storage.Components; +using Content.Shared._CP14.DeviceLinking; +using Content.Shared.Placeable; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; +using Robust.Shared.Physics.Components; + +namespace Content.Server._CP14.DeviceLinking; + +public sealed class CP14PressurePlateSystem : EntitySystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly DeviceLinkSystem _signal = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnItemPlaced); + SubscribeLocalEvent(OnItemRemoved); + } + + private void OnInit(Entity plate, ref ComponentInit args) + { + _signal.EnsureSourcePorts(plate, plate.Comp.PressedPort, plate.Comp.ReleasedPort); + _appearance.SetData(plate, PressurePlateVisuals.Pressed, false); + } + + private void OnItemRemoved(Entity plate, ref ItemRemovedEvent args) + { + UpdateState(plate); + } + + private void OnItemPlaced(Entity plate, ref ItemPlacedEvent args) + { + UpdateState(plate); + } + + private void UpdateState(Entity plate) + { + if (!TryComp(plate, out var itemPlacer)) + return; + var totalMass = 0f; + + foreach (var ent in itemPlacer.PlacedEntities) + { + totalMass += GetEntWeightRecursive(ent); + } + var pressed = totalMass >= plate.Comp.WeightRequired; + if (pressed == plate.Comp.IsPressed) + return; + + plate.Comp.IsPressed = pressed; + _signal.SendSignal(plate, plate.Comp.StatusPort, pressed); + _signal.InvokePort(plate, pressed ? plate.Comp.PressedPort : plate.Comp.ReleasedPort); + + _appearance.SetData(plate, PressurePlateVisuals.Pressed, pressed); + _audio.PlayPvs(pressed ? plate.Comp.PressedSound : plate.Comp.ReleasedSound, plate); + } + + /// + /// Recursively calculates the weight of the object, and all its contents, and the contents and its contents... + /// + public float GetEntWeightRecursive(EntityUid uid) + { + var totalMass = 0f; + if (Deleted(uid)) return 0f; + + if (TryComp(uid, out var physics)) + { + totalMass += physics.Mass; + } + + //Containers + if (TryComp(uid, out var entityStorage)) + { + var storage = entityStorage.Contents; + foreach (var ent in storage.ContainedEntities) + { + totalMass += GetEntWeightRecursive(ent); + } + } + //Inventory + if (TryComp(uid, out var containerManager)) + { + foreach (var container in containerManager.Containers) + { + var storage = container.Value.ContainedEntities; + foreach (var ent in storage) + { + totalMass += GetEntWeightRecursive(ent); + } + } + } + return totalMass; + } +} diff --git a/Content.Server/_CP14/DeviceLinking/Components/CP14PressurePlateComponent.cs b/Content.Server/_CP14/DeviceLinking/Components/CP14PressurePlateComponent.cs new file mode 100644 index 0000000000..2cf48fd223 --- /dev/null +++ b/Content.Server/_CP14/DeviceLinking/Components/CP14PressurePlateComponent.cs @@ -0,0 +1,39 @@ +using Content.Shared.DeviceLinking; +using Robust.Shared.Audio; +using Robust.Shared.Prototypes; + +namespace Content.Server._CP14.DeviceLinking.Components; + +/// +/// This component allows the facility to register the weight of objects above it and provide signals to devices +/// +[RegisterComponent, Access(typeof(CP14PressurePlateSystem))] +public sealed partial class CP14PressurePlateComponent : Component +{ + [DataField] + public bool IsPressed; + + /// + /// The required weight of an object that happens to be above the slab to activate. + /// + [DataField] + public float WeightRequired = 100f; + + [DataField] + public float CurrentWeight; + + [DataField] + public ProtoId PressedPort = "CP14Pressed"; + + [DataField] + public ProtoId StatusPort = "Status"; + + [DataField] + public ProtoId ReleasedPort = "CP14Released"; + + [DataField] + public SoundSpecifier PressedSound = new SoundPathSpecifier("/Audio/Machines/button.ogg"); + + [DataField] + public SoundSpecifier ReleasedSound = new SoundPathSpecifier("/Audio/Machines/button.ogg"); +} diff --git a/Content.Shared/_CP14/DeviceLinking/CP14SharedPressurePlateSignal.cs b/Content.Shared/_CP14/DeviceLinking/CP14SharedPressurePlateSignal.cs new file mode 100644 index 0000000000..370a200851 --- /dev/null +++ b/Content.Shared/_CP14/DeviceLinking/CP14SharedPressurePlateSignal.cs @@ -0,0 +1,9 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared._CP14.DeviceLinking; + +[Serializable, NetSerializable] +public enum PressurePlateVisuals : byte +{ + Pressed, +} diff --git a/Resources/Locale/en-US/_CP14/machineLinking/transmitter_ports.ftl b/Resources/Locale/en-US/_CP14/machineLinking/transmitter_ports.ftl new file mode 100644 index 0000000000..428c3e64b7 --- /dev/null +++ b/Resources/Locale/en-US/_CP14/machineLinking/transmitter_ports.ftl @@ -0,0 +1,5 @@ +cp14-signal-port-name-pressed = Pressed +cp14-signal-port-description-pressed = This node is activated when the device is pressed. + +cp14-signal-port-name-released = Released +cp14-signal-port-description-released = This node is activated when the device is released. \ No newline at end of file diff --git a/Resources/Locale/ru-RU/_CP14/machineLinking/transmitter_ports.ftl b/Resources/Locale/ru-RU/_CP14/machineLinking/transmitter_ports.ftl new file mode 100644 index 0000000000..538848eda4 --- /dev/null +++ b/Resources/Locale/ru-RU/_CP14/machineLinking/transmitter_ports.ftl @@ -0,0 +1,5 @@ +cp14-signal-port-name-pressed = Нажато +cp14-signal-port-description-pressed = Этот узел активируется, когда на устройство нажимают. + +cp14-signal-port-name-released = Отпущено +cp14-signal-port-description-released = Этот узел активируется, когда устройство отпускают. \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/DeviceLinking/source_ports.yml b/Resources/Prototypes/_CP14/DeviceLinking/source_ports.yml new file mode 100644 index 0000000000..26a5879c31 --- /dev/null +++ b/Resources/Prototypes/_CP14/DeviceLinking/source_ports.yml @@ -0,0 +1,11 @@ +- type: sourcePort + id: CP14Pressed + name: cp14-signal-port-name-pressed + description: cp14-signal-port-description-pressed + defaultLinks: [ Toggle, Trigger, Timer ] + +- type: sourcePort + id: CP14Released + name: cp14-signal-port-name-released + description: cp14-signal-port-description-released + defaultLinks: [ Toggle, Trigger, Timer ] \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Objects/Specific/Thaumaturgy/tools.yml b/Resources/Prototypes/_CP14/Entities/Objects/Specific/Thaumaturgy/tools.yml index 97da442acc..d12be98ac7 100644 --- a/Resources/Prototypes/_CP14/Entities/Objects/Specific/Thaumaturgy/tools.yml +++ b/Resources/Prototypes/_CP14/Entities/Objects/Specific/Thaumaturgy/tools.yml @@ -54,4 +54,16 @@ soundHit: collection: MetalThud cPAnimationLength: 0.25 - cPAnimationOffset: -1.3 \ No newline at end of file + cPAnimationOffset: -1.3 + - type: NetworkConfigurator + - type: ActivatableUI + key: enum.NetworkConfiguratorUiKey.List + inHandsOnly: true + - type: UserInterface + interfaces: + enum.NetworkConfiguratorUiKey.List: + type: NetworkConfiguratorBoundUserInterface + enum.NetworkConfiguratorUiKey.Configure: + type: NetworkConfiguratorBoundUserInterface + enum.NetworkConfiguratorUiKey.Link: + type: NetworkConfiguratorBoundUserInterface \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Specific/Device/pressure_plate.yml b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Device/pressure_plate.yml new file mode 100644 index 0000000000..0c32247658 --- /dev/null +++ b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Device/pressure_plate.yml @@ -0,0 +1,71 @@ +- type: entity + id: CP14PressurePlateBase + abstract: true + parent: BaseStructure + placement: + mode: SnapgridCenter + categories: [ ForkFiltered ] + name: pressure plate + description: This button can activate something! + components: + - type: Fixtures + fixtures: + slipFixture: + shape: + !type:PhysShapeAabb + bounds: "-0.4,-0.4,0.4,0.4" + mask: + - SmallMobMask + layer: + - SmallMobLayer + hard: false + - type: Physics + bodyType: Static + - type: Sprite + snapCardinals: true + drawdepth: FloorObjects + sprite: _CP14/Structures/Specific/Device/pressure_plate.rsi + - type: ItemPlacer + maxEntities: 5 + - type: Appearance + - type: CollisionWake + enabled: false + - type: CP14PressurePlate + pressedSound: + path: /Audio/Machines/button.ogg + params: + pitchscale: 0.75 + releasedSound: + path: /Audio/Machines/button.ogg + - type: DeviceNetwork + deviceNetId: Wireless + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - type: WirelessNetworkConnection + range: 10 + - type: DeviceLinkSource + ports: + - CP14Pressed + - Status + - CP14Released + +- type: entity + parent: CP14PressurePlateBase + id: CP14PressurePlateWooden + components: + - type: Sprite + layers: + - state: wooden + map: ["enabled"] + - type: GenericVisualizer + visuals: + enum.PressurePlateVisuals.Pressed: + enabled: + True: { state: wooden_pressed } + False: { state: wooden } \ No newline at end of file diff --git a/Resources/Prototypes/_CP14/Entities/Structures/Specific/Device/wallmount_buttons.yml b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Device/wallmount_buttons.yml index 1a24c3cf0b..d7074f7b7e 100644 --- a/Resources/Prototypes/_CP14/Entities/Structures/Specific/Device/wallmount_buttons.yml +++ b/Resources/Prototypes/_CP14/Entities/Structures/Specific/Device/wallmount_buttons.yml @@ -8,7 +8,7 @@ description: This button can activate something! components: - type: Sprite - sprite: _CP14/Structures/Wallmount/buttons.rsi + sprite: _CP14/Structures/Specific/Device/wallmount_buttons.rsi - type: Clickable - type: InteractionOutline - type: Physics @@ -16,22 +16,28 @@ - type: UseDelay delay: 0.5 # prevent light-toggling auto-clickers. - type: SignalSwitch - onPort: Pressed - offPort: Pressed - statusPort: Pressed + onPort: CP14Pressed + offPort: CP14Pressed + statusPort: CP14Pressed - type: Fixtures - type: DeviceNetwork deviceNetId: Wireless - type: WirelessNetworkConnection - range: 100 + range: 10 - type: DeviceLinkSource ports: - - Pressed + - CP14Pressed - type: entity id: CP14WallmouontButtonWooden parent: CP14WallmountButtonBase - name: wooden wall button components: - type: Sprite - state: wooden \ No newline at end of file + state: wooden + +- type: entity + id: CP14WallmouontButtonStone + parent: CP14WallmountButtonBase + components: + - type: Sprite + state: stone \ No newline at end of file diff --git a/Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/meta.json b/Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/meta.json new file mode 100644 index 0000000000..67fa076099 --- /dev/null +++ b/Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/meta.json @@ -0,0 +1,17 @@ +{ + "version": 1, + "license": "CC-BY-SA-4.0", + "copyright": "Created by TheShuEd", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "wooden" + }, + { + "name": "wooden_pressed" + } + ] +} diff --git a/Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/wooden.png b/Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/wooden.png new file mode 100644 index 0000000000000000000000000000000000000000..573d63d64b10ad774d9e0671881df5cab923fdae GIT binary patch literal 464 zcmV;>0WbcEP)Px$ib+I4R9J=WmO*QSKoEtWZ7`|0Az2DNl(rOd=_$1TqQAJeUVAAGIi-h|U?lV+ zMzn<0rr3i~baiz#geKs3QD>a>vGbS}XleOpl=Q>n!(9jfL{;DgA&8nu!wW*hc|IQ3 z$nf+wOBU$xNunyC{Vr%hAq8Mq47A_P#nV?2w(I9ap2#TPCz%~^);}Ps3Q9Bp0Nb!6 z*X#5EL_46JHPdao(KmzwfT*97xn0obb#gy5*L+z*U4IBYz*E&j6PA*r~0=ytB?Qs>)(?zZK3q2s}<795*=DgQT8KOCG93Bw&(FP?N z*oGx@Ats&~d^}U_`qcuwAS~_UWNvToL_VqKAL%(z7sFyXzZ{PTc9{eGI%!WxdtjG2 zkS1EEd@U&t7#73*t;}gq&f%X0<7<-q3#6e$E1&U_jP+B{FAp#80s+&7htb6bzWPx$ZAnByR9J=WmcdJeKorJ5YjI5+X@_n>5p?Oa)PK=m+^uW3WKY{65I2?%i7Og1 zYYTQTMMp@1OSMtAdC|bwG>7eC&=Rbe6~i0 zr`KhkV8RE9s(_kP(3*u5fa5Yyb6S}%K1F!Jwj%OGM)5u=oq!+xfT$`c(E$K#$MTpq z(Ey|;pr7^A?FH!`LIFTpPs{dd>Kx_cIc7Cyh03<9V^_^nI-dM0K=m57!r3KV?Y!z;Sp$Tt^R-=wLgR z_l1nCXYli-)xox1Ko}>Db+l~nZzS?bH~&cYfvz|%tN7)3JTRmW@Og@!koLfkK2Rjh z)0|7n1CGmZegAGV-xtR*07>k44ofy`glX(ebyLq}ehE&XX zdv~K3v!ejRh0YdMY3b7m6E!3@Zv0@cv*vFsx8N2*L7$+OlIhQMn64jjV(QF1BUBvo zDbCX1_#3%s-ZL&hGZ|!NTwBH|{yhBi>)E$GG}j(ky{c>b_2)li_T>LLYbAR%*5U3g zOHa+E7OzXfk{+K-(Pn)cb&XZzsL85TQJqttUJv8CW$Le>zEY#h{^%@)*Gy?oO^!V+ zxxE!+G{XV=>=0$+N6Rg%Yl@`y#+9qu$@C?K`I+aPOZ&?D>e~DGbzjwjy*_^W5)teQ z)__JFShwZfJNajVKZ7G@Kl>hXYw?tzB~z{)yYg;x+BU1>RO`mrjeZu|RJKf QcY}mIUHx3vIVCg!0LBrWC;$Ke literal 0 HcmV?d00001 diff --git a/Resources/Textures/_CP14/Structures/Wallmount/buttons.rsi/wooden.png b/Resources/Textures/_CP14/Structures/Specific/Device/wallmount_buttons.rsi/wooden.png similarity index 100% rename from Resources/Textures/_CP14/Structures/Wallmount/buttons.rsi/wooden.png rename to Resources/Textures/_CP14/Structures/Specific/Device/wallmount_buttons.rsi/wooden.png