pressure plate (#902)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.DeviceLinking;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum PressurePlateVisuals : byte
|
||||
{
|
||||
Pressed,
|
||||
}
|
||||
@@ -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.
|
||||
@@ -0,0 +1,5 @@
|
||||
cp14-signal-port-name-pressed = Нажато
|
||||
cp14-signal-port-description-pressed = Этот узел активируется, когда на устройство нажимают.
|
||||
|
||||
cp14-signal-port-name-released = Отпущено
|
||||
cp14-signal-port-description-released = Этот узел активируется, когда устройство отпускают.
|
||||
11
Resources/Prototypes/_CP14/DeviceLinking/source_ports.yml
Normal file
11
Resources/Prototypes/_CP14/DeviceLinking/source_ports.yml
Normal 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 ]
|
||||
@@ -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
|
||||
@@ -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 }
|
||||
@@ -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
|
||||
@@ -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 |
@@ -10,6 +10,10 @@
|
||||
{
|
||||
"name": "wooden",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "stone",
|
||||
"directions": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 396 B |
|
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 395 B |
Reference in New Issue
Block a user