pressure plate (#902)

This commit is contained in:
Ed
2025-02-16 00:39:36 +03:00
committed by GitHub
parent 37fd4d887f
commit a3849c8aa9
15 changed files with 287 additions and 9 deletions

View File

@@ -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<Components.CP14PressurePlateComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<Components.CP14PressurePlateComponent, ItemPlacedEvent>(OnItemPlaced);
SubscribeLocalEvent<Components.CP14PressurePlateComponent, ItemRemovedEvent>(OnItemRemoved);
}
private void OnInit(Entity<Components.CP14PressurePlateComponent> plate, ref ComponentInit args)
{
_signal.EnsureSourcePorts(plate, plate.Comp.PressedPort, plate.Comp.ReleasedPort);
_appearance.SetData(plate, PressurePlateVisuals.Pressed, false);
}
private void OnItemRemoved(Entity<Components.CP14PressurePlateComponent> plate, ref ItemRemovedEvent args)
{
UpdateState(plate);
}
private void OnItemPlaced(Entity<Components.CP14PressurePlateComponent> plate, ref ItemPlacedEvent args)
{
UpdateState(plate);
}
private void UpdateState(Entity<Components.CP14PressurePlateComponent> plate)
{
if (!TryComp<ItemPlacerComponent>(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);
}
/// <summary>
/// Recursively calculates the weight of the object, and all its contents, and the contents and its contents...
/// </summary>
public float GetEntWeightRecursive(EntityUid uid)
{
var totalMass = 0f;
if (Deleted(uid)) return 0f;
if (TryComp<PhysicsComponent>(uid, out var physics))
{
totalMass += physics.Mass;
}
//Containers
if (TryComp<EntityStorageComponent>(uid, out var entityStorage))
{
var storage = entityStorage.Contents;
foreach (var ent in storage.ContainedEntities)
{
totalMass += GetEntWeightRecursive(ent);
}
}
//Inventory
if (TryComp<ContainerManagerComponent>(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;
}
}

View File

@@ -0,0 +1,39 @@
using Content.Shared.DeviceLinking;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
namespace Content.Server._CP14.DeviceLinking.Components;
/// <summary>
/// This component allows the facility to register the weight of objects above it and provide signals to devices
/// </summary>
[RegisterComponent, Access(typeof(CP14PressurePlateSystem))]
public sealed partial class CP14PressurePlateComponent : Component
{
[DataField]
public bool IsPressed;
/// <summary>
/// The required weight of an object that happens to be above the slab to activate.
/// </summary>
[DataField]
public float WeightRequired = 100f;
[DataField]
public float CurrentWeight;
[DataField]
public ProtoId<SourcePortPrototype> PressedPort = "CP14Pressed";
[DataField]
public ProtoId<SourcePortPrototype> StatusPort = "Status";
[DataField]
public ProtoId<SourcePortPrototype> ReleasedPort = "CP14Released";
[DataField]
public SoundSpecifier PressedSound = new SoundPathSpecifier("/Audio/Machines/button.ogg");
[DataField]
public SoundSpecifier ReleasedSound = new SoundPathSpecifier("/Audio/Machines/button.ogg");
}

View File

@@ -0,0 +1,9 @@
using Robust.Shared.Serialization;
namespace Content.Shared._CP14.DeviceLinking;
[Serializable, NetSerializable]
public enum PressurePlateVisuals : byte
{
Pressed,
}

View File

@@ -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.

View File

@@ -0,0 +1,5 @@
cp14-signal-port-name-pressed = Нажато
cp14-signal-port-description-pressed = Этот узел активируется, когда на устройство нажимают.
cp14-signal-port-name-released = Отпущено
cp14-signal-port-description-released = Этот узел активируется, когда устройство отпускают.

View File

@@ -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 ]

View File

@@ -54,4 +54,16 @@
soundHit:
collection: MetalThud
cPAnimationLength: 0.25
cPAnimationOffset: -1.3
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

View File

@@ -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 }

View File

@@ -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
state: wooden
- type: entity
id: CP14WallmouontButtonStone
parent: CP14WallmountButtonBase
components:
- type: Sprite
state: stone

View File

@@ -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"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 B

View File

@@ -10,6 +10,10 @@
{
"name": "wooden",
"directions": 4
},
{
"name": "stone",
"directions": 4
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B