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 0000000000..573d63d64b Binary files /dev/null and b/Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/wooden.png differ diff --git a/Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/wooden_pressed.png b/Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/wooden_pressed.png new file mode 100644 index 0000000000..7cf11f96ff Binary files /dev/null and b/Resources/Textures/_CP14/Structures/Specific/Device/pressure_plate.rsi/wooden_pressed.png differ diff --git a/Resources/Textures/_CP14/Structures/Wallmount/buttons.rsi/meta.json b/Resources/Textures/_CP14/Structures/Specific/Device/wallmount_buttons.rsi/meta.json similarity index 77% rename from Resources/Textures/_CP14/Structures/Wallmount/buttons.rsi/meta.json rename to Resources/Textures/_CP14/Structures/Specific/Device/wallmount_buttons.rsi/meta.json index 73a45f2a63..8c6833b0b2 100644 --- a/Resources/Textures/_CP14/Structures/Wallmount/buttons.rsi/meta.json +++ b/Resources/Textures/_CP14/Structures/Specific/Device/wallmount_buttons.rsi/meta.json @@ -10,6 +10,10 @@ { "name": "wooden", "directions": 4 + }, + { + "name": "stone", + "directions": 4 } ] } diff --git a/Resources/Textures/_CP14/Structures/Specific/Device/wallmount_buttons.rsi/stone.png b/Resources/Textures/_CP14/Structures/Specific/Device/wallmount_buttons.rsi/stone.png new file mode 100644 index 0000000000..2b2d0dd6d1 Binary files /dev/null and b/Resources/Textures/_CP14/Structures/Specific/Device/wallmount_buttons.rsi/stone.png differ 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