Merge 472a573b01 into c3c6a6abd9
This commit is contained in:
commit
1801c3b9bd
|
|
@ -0,0 +1,158 @@
|
|||
using System.Linq;
|
||||
using Content.Server.DeviceLinking.Systems;
|
||||
using Content.Server.Power.Components;
|
||||
using Content.Shared._DV.MetalDetector;
|
||||
using Content.Shared.Access.Components;
|
||||
using Content.Shared.Access.Systems;
|
||||
using Content.Shared.Contraband;
|
||||
using Content.Shared.Emag.Components;
|
||||
using Content.Shared.Emag.Systems;
|
||||
using Content.Shared.Implants.Components;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Item.ItemToggle.Components;
|
||||
using Content.Shared.StepTrigger.Systems;
|
||||
using Content.Shared.Storage;
|
||||
using Content.Shared.Toggleable;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Server._DV.MetalDetector;
|
||||
|
||||
/// <summary>
|
||||
/// Systems related to the Metal Detector and how it functions.
|
||||
/// </summary>
|
||||
public sealed class MetalDetectorSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly InventorySystem _inventorySystem = default!;
|
||||
[Dependency] private readonly SharedIdCardSystem _idSystem = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
|
||||
[Dependency] private readonly EmagSystem _emag = default!;
|
||||
[Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<MetalDetectorComponent, StepTriggeredOnEvent>(HandleStepOnTriggered);
|
||||
SubscribeLocalEvent<MetalDetectorComponent, StepTriggeredOffEvent>(HandleStepOffTriggered);
|
||||
SubscribeLocalEvent<MetalDetectorComponent, StepTriggerAttemptEvent>(HandleStepTriggerAttempt);
|
||||
SubscribeLocalEvent<MetalDetectorComponent, GotEmaggedEvent>(OnEmagged);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
using var query = EntityQueryEnumerator<MetalDetectorComponent>();
|
||||
while (query.MoveNext(out var ent, out var comp))
|
||||
{
|
||||
if (!comp.IsSirenRunning || !TryComp<ItemToggleComponent>(ent, out var toggle) || !toggle.Activated)
|
||||
continue;
|
||||
|
||||
var powered = TryComp<ApcPowerReceiverComponent>(ent, out var receiver) && receiver.Powered;
|
||||
|
||||
TryComp<AppearanceComponent>(ent, out var appComp);
|
||||
|
||||
if (comp.EndOfSirenSound <= _timing.CurTime || !powered)
|
||||
{
|
||||
comp.IsSirenRunning = false;
|
||||
var toggledEvent = new ItemToggledEvent(false, false, ent);
|
||||
toggle.Activated = false;
|
||||
_appearanceSystem.SetData(ent, MetalDetectorVisuals.MetalDetectorActivated, false);
|
||||
_appearanceSystem.SetData(ent, ToggleableVisuals.Enabled, false, appComp);
|
||||
RaiseLocalEvent(ent, ref toggledEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleStepOnTriggered(Entity<MetalDetectorComponent> ent, ref StepTriggeredOnEvent args)
|
||||
{
|
||||
if (ent.Comp.IsSirenRunning)
|
||||
{
|
||||
ent.Comp.EndOfSirenSound = _timing.CurTime + ent.Comp.SirenRunTime;
|
||||
return;
|
||||
}
|
||||
|
||||
var random = new Random();
|
||||
if (TryComp<ItemToggleComponent>(ent, out var toggleComponent) && (CheckForContraband(args.Tripper)
|
||||
|| random.NextFloat(0.0f, 100.0f) < ent.Comp.FalsePositiveChance
|
||||
|| HasComp<EmaggedComponent>(ent)))
|
||||
{
|
||||
toggleComponent.Activated = true;
|
||||
TryComp<AppearanceComponent>(ent, out var appComp);
|
||||
_appearanceSystem.SetData(ent, MetalDetectorVisuals.MetalDetectorActivated, true);
|
||||
_appearanceSystem.SetData(ent, ToggleableVisuals.Enabled, true, appComp);
|
||||
var toggledEvent = new ItemToggledEvent(false, true, ent);
|
||||
ent.Comp.EndOfSirenSound = _timing.CurTime + ent.Comp.SirenRunTime;
|
||||
RaiseLocalEvent(ent, ref toggledEvent);
|
||||
|
||||
_deviceLink.InvokePort(ent, ent.Comp.TriggerPort);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleStepOffTriggered(Entity<MetalDetectorComponent> ent, ref StepTriggeredOffEvent args)
|
||||
{
|
||||
// Start timer to deactivate the siren
|
||||
ent.Comp.IsSirenRunning = TryComp<ItemToggleComponent>(ent, out var toggleComponent) && toggleComponent.Activated;
|
||||
}
|
||||
|
||||
private void HandleStepTriggerAttempt(Entity<MetalDetectorComponent> ent, ref StepTriggerAttemptEvent args)
|
||||
{
|
||||
args.Continue = TryComp<ApcPowerReceiverComponent>(ent, out var receiver) && receiver.Powered;
|
||||
}
|
||||
|
||||
private void OnEmagged(Entity<MetalDetectorComponent> metalDetectorComponent, ref GotEmaggedEvent args)
|
||||
{
|
||||
if (!_emag.CompareFlag(args.Type, EmagType.Interaction))
|
||||
return;
|
||||
|
||||
if (_emag.CheckFlag(metalDetectorComponent.Owner, EmagType.Interaction))
|
||||
return;
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private bool CheckForContraband(EntityUid characterUid)
|
||||
{
|
||||
// In it's just a contraband item
|
||||
if (HasComp<ContrabandComponent>(characterUid))
|
||||
return true;
|
||||
|
||||
if (_containerSystem.TryGetContainer(characterUid, ImplanterComponent.ImplantSlotId, out var implants))
|
||||
{
|
||||
var storageImplanter = implants.ContainedEntities.ToList().Find(HasComp<StorageComponent>);
|
||||
|
||||
if (TryComp<StorageComponent>(storageImplanter, out var storage))
|
||||
{
|
||||
foreach (var stored in storage.Container.ContainedEntities)
|
||||
{
|
||||
if (IsEntityContraband(characterUid, stored))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in _inventorySystem.GetHandOrInventoryEntities(characterUid))
|
||||
{
|
||||
if (IsEntityContraband(characterUid, item))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsEntityContraband(EntityUid characterUid, EntityUid item)
|
||||
{
|
||||
if (!TryComp<ContrabandComponent>(item, out var contrabandComp))
|
||||
return false;
|
||||
|
||||
if (!_idSystem.TryFindIdCard(characterUid, out var idCard))
|
||||
return true;
|
||||
|
||||
return !idCard.Comp.JobDepartments.Intersect(contrabandComp.AllowedDepartments).Any();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
using Content.Shared.DeviceLinking;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
|
||||
namespace Content.Shared._DV.MetalDetector;
|
||||
|
||||
/// <summary>
|
||||
/// Responsible for holding some data of whom has passed by and which item is the most dangerous.
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public sealed partial class MetalDetectorComponent : Component
|
||||
{
|
||||
[DataField]
|
||||
public TimeSpan SirenRunTime = TimeSpan.FromSeconds(10);
|
||||
|
||||
/// <summary>
|
||||
/// Value to determine the chance that the Metal Detector simply fires and gives a false positive. from 0 to 100.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float FalsePositiveChance = 5.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Timespan which is set runtime to determine when the Siren should stop running
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan EndOfSirenSound = TimeSpan.FromSeconds(0);
|
||||
|
||||
public bool IsSirenRunning = false;
|
||||
|
||||
/// <summary>
|
||||
/// Siren Sound which is played when the Metal Detector fires.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier? SirenSound;
|
||||
|
||||
/// <summary>
|
||||
/// The port that gets signaled when the the metal detector fires
|
||||
/// </summary>
|
||||
[DataField(customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
|
||||
public string TriggerPort = "Trigger";
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum MetalDetectorVisuals : byte
|
||||
{
|
||||
MetalDetectorActivated,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum MetalDetectorVisualLayers : byte
|
||||
{
|
||||
MetalDetectorLayer,
|
||||
}
|
||||
|
|
@ -450,6 +450,7 @@
|
|||
- SecurityAmmoStatic
|
||||
- SecurityWeaponsStatic
|
||||
# Being DeltaV Additions
|
||||
- SecurityMachines
|
||||
- ReportingStatic
|
||||
- SecurityRubberAmmoStatic
|
||||
- SecurityShotgunDrumsStatic
|
||||
|
|
@ -519,7 +520,7 @@
|
|||
unlitRunningState: unlit-building # DeltaV - added animation sprite layers
|
||||
staticPacks:
|
||||
- SecurityAmmoStatic
|
||||
# Start DeltaV Additions
|
||||
# Start DeltaV Additions
|
||||
- SecurityShotgunDrumsStatic
|
||||
- AmmoFabPracticeStatic # Removes practice guns
|
||||
- SecurityRubberAmmoStatic
|
||||
|
|
|
|||
|
|
@ -101,3 +101,19 @@
|
|||
stackRequirements:
|
||||
Manipulator: 4
|
||||
Cable: 5
|
||||
|
||||
# Metal Detector
|
||||
- type: entity
|
||||
id: MetalDetectorMachineCircuitBoard
|
||||
parent: BaseMachineCircuitboard
|
||||
name: metal detector machine board
|
||||
description: Makes beeps and boops when evil passes by
|
||||
components:
|
||||
- type: Sprite
|
||||
state: security
|
||||
- type: MachineBoard
|
||||
prototype: MetalDetector
|
||||
stackRequirements:
|
||||
Manipulator: 4
|
||||
Glass: 5
|
||||
Cable: 5
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
- type: entity
|
||||
parent: ConstructibleMachine
|
||||
id: MetalDetector
|
||||
name: Metal Detector
|
||||
description: Beeps when metal and contraband is detected by a passing person.
|
||||
placement:
|
||||
mode: SnapgridCenter
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: _DV/Structures/Machines/metal_detector.rsi
|
||||
layers:
|
||||
- state: metal_detector_off
|
||||
map: [ "enum.MetalDetectorVisualLayers.MetalDetectorLayer" ]
|
||||
- type: GenericVisualizer
|
||||
visuals:
|
||||
enum.MetalDetectorVisuals.MetalDetectorActivated:
|
||||
enum.MetalDetectorVisualLayers.MetalDetectorLayer:
|
||||
True: { state: metal_detector_on }
|
||||
False: { state: metal_detector_off }
|
||||
- type: ApcPowerReceiver
|
||||
powerLoad: 1000
|
||||
- type: Clickable
|
||||
- type: InteractionOutline
|
||||
- type: Pullable
|
||||
- type: Machine
|
||||
board: MetalDetectorMachineCircuitBoard
|
||||
- type: Transform
|
||||
anchored: true
|
||||
noRot: true
|
||||
- type: ExtensionCableReceiver
|
||||
- type: LightningTarget
|
||||
priority: 1
|
||||
- type: DeviceNetwork
|
||||
deviceNetId: Wireless
|
||||
- type: WirelessNetworkConnection
|
||||
range: 200
|
||||
- type: DeviceLinkSource
|
||||
ports:
|
||||
- Trigger
|
||||
- type: WiresPanel
|
||||
- type: Wires
|
||||
alwaysRandomize: true
|
||||
boardName: wires-board-name-apc
|
||||
layoutId: APC
|
||||
- type: WiresVisuals
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 200
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: [ "Destruction" ]
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 100
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: ["Destruction"]
|
||||
- !type:PlaySoundBehavior
|
||||
sound:
|
||||
collection: MetalBreak
|
||||
- type: LockedWiresPanel
|
||||
- type: LockedAnchorable
|
||||
- type: Damageable
|
||||
damageContainer: Inorganic
|
||||
damageModifierSet: Metallic
|
||||
- type: Anchorable
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
- type: ToggleableVisuals
|
||||
spriteLayer: null
|
||||
- type: ItemToggle
|
||||
predictable: false # issues between ToggleCellDraw and ItemToggleActiveSound
|
||||
onActivate: false
|
||||
- type: ItemTogglePointLight
|
||||
- type: PointLight
|
||||
enabled: false
|
||||
radius: 2.5
|
||||
energy: 3
|
||||
color: red
|
||||
netsync: false
|
||||
mask: /Textures/Effects/LightMasks/double_cone.png
|
||||
- type: RotatingLight
|
||||
speed: 360
|
||||
- type: ItemToggleActiveSound
|
||||
activeSound:
|
||||
path: /Audio/Effects/Vehicle/policesiren.ogg
|
||||
params:
|
||||
volume: -3
|
||||
- type: Appearance
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
shape:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.5,-0.5,0.5,0.5"
|
||||
mask:
|
||||
- TabletopMachineMask
|
||||
layer:
|
||||
- TabletopMachineLayer
|
||||
overlap:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.5,-0.5,0.5,0.5"
|
||||
hard: false
|
||||
layer:
|
||||
- Impassable
|
||||
- type: MetalDetector
|
||||
- type: StepTrigger
|
||||
requiredTriggeredSpeed: 0
|
||||
stepOn: true
|
||||
|
|
@ -64,6 +64,11 @@
|
|||
recipes:
|
||||
- Truncheon
|
||||
|
||||
- type: latheRecipePack
|
||||
id: SecurityMachines
|
||||
recipes:
|
||||
- MetalDetectorMachineCircuitBoard
|
||||
|
||||
## Dynamic
|
||||
|
||||
- type: latheRecipePack
|
||||
|
|
|
|||
|
|
@ -3,3 +3,9 @@
|
|||
parent: [ BaseCircuitboardRecipe, BaseEngineeringMachineRecipeCategory ]
|
||||
id: KitchenFreezerMachineCircuitBoard
|
||||
result: KitchenFreezerMachineCircuitBoard
|
||||
|
||||
# Security
|
||||
- type: latheRecipe
|
||||
parent: [ BaseCircuitboardRecipe, BaseSecurityMachineRecipeCategory ]
|
||||
id: MetalDetectorMachineCircuitBoard
|
||||
result: MetalDetectorMachineCircuitBoard
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-4.0",
|
||||
"copyright": "From coryduck on the Delta-V Server Discord",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "metal_detector_off"
|
||||
},
|
||||
{
|
||||
"name": "metal_detector_on",
|
||||
"delays": [
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 395 B |
Binary file not shown.
|
After Width: | Height: | Size: 756 B |
Loading…
Reference in New Issue