]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Anomaly Locator (#15677)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Sun, 23 Apr 2023 05:39:33 +0000 (01:39 -0400)
committerGitHub <noreply@github.com>
Sun, 23 Apr 2023 05:39:33 +0000 (15:39 +1000)
14 files changed:
Content.Server/Pinpointer/ProximityBeeperComponent.cs [new file with mode: 0644]
Content.Server/Pinpointer/ProximityBeeperSystem.cs [new file with mode: 0644]
Content.Shared/Pinpointer/SharedProximityBeeper.cs [new file with mode: 0644]
Resources/Audio/Items/attributions.yml
Resources/Audio/Items/locator_beep.ogg [new file with mode: 0644]
Resources/Prototypes/Catalog/Research/technologies.yml
Resources/Prototypes/Entities/Objects/Specific/Research/anomaly.yml
Resources/Prototypes/Entities/Structures/Machines/lathe.yml
Resources/Prototypes/Recipes/Lathes/devices.yml
Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/icon.png [new file with mode: 0644]
Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/inhand-left.png [new file with mode: 0644]
Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/inhand-right.png [new file with mode: 0644]
Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/meta.json [new file with mode: 0644]
Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/screen.png [new file with mode: 0644]

diff --git a/Content.Server/Pinpointer/ProximityBeeperComponent.cs b/Content.Server/Pinpointer/ProximityBeeperComponent.cs
new file mode 100644 (file)
index 0000000..8abc7b6
--- /dev/null
@@ -0,0 +1,54 @@
+using Robust.Shared.Audio;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+
+namespace Content.Server.Pinpointer;
+
+/// <summary>
+/// This is used for an item that beeps based on
+/// proximity to a specified component.
+/// </summary>
+[RegisterComponent, Access(typeof(ProximityBeeperSystem))]
+public sealed class ProximityBeeperComponent : Component
+{
+    /// <summary>
+    /// Whether or not it's on.
+    /// </summary>
+    [DataField("enabled")]
+    public bool Enabled;
+
+    /// <summary>
+    /// The target component that is being searched for
+    /// </summary>
+    [DataField("component", required: true), ViewVariables(VVAccess.ReadWrite)]
+    public string Component = default!;
+
+    /// <summary>
+    /// The farthest distance a target can be for the beep to occur
+    /// </summary>
+    [DataField("maximumDistance"), ViewVariables(VVAccess.ReadWrite)]
+    public float MaximumDistance = 10f;
+
+    /// <summary>
+    /// The maximum interval between beeps.
+    /// </summary>
+    [DataField("maxBeepInterval"), ViewVariables(VVAccess.ReadWrite)]
+    public TimeSpan MaxBeepInterval = TimeSpan.FromSeconds(1.5f);
+
+    /// <summary>
+    /// The minimum interval between beeps.
+    /// </summary>
+    [DataField("minBeepInterval"), ViewVariables(VVAccess.ReadWrite)]
+    public TimeSpan MinBeepInterval = TimeSpan.FromSeconds(0.25f);
+
+    /// <summary>
+    /// When the next beep will occur
+    /// </summary>
+    [DataField("nextBeepTime", customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite)]
+    public TimeSpan NextBeepTime;
+
+    /// <summary>
+    /// The sound played when the locator beeps.
+    /// </summary>
+    [DataField("beepSound")]
+    public SoundSpecifier? BeepSound;
+}
diff --git a/Content.Server/Pinpointer/ProximityBeeperSystem.cs b/Content.Server/Pinpointer/ProximityBeeperSystem.cs
new file mode 100644 (file)
index 0000000..472a50f
--- /dev/null
@@ -0,0 +1,167 @@
+using Content.Server.PowerCell;
+using Content.Shared.Interaction.Events;
+using Content.Shared.Pinpointer;
+using Robust.Server.GameObjects;
+using Robust.Shared.Timing;
+
+namespace Content.Server.Pinpointer;
+
+/// <summary>
+/// This handles logic and interaction relating to <see cref="ProximityBeeperComponent"/>
+/// </summary>
+public sealed class ProximityBeeperSystem : EntitySystem
+{
+    [Dependency] private readonly IGameTiming _timing = default!;
+    [Dependency] private readonly AppearanceSystem _appearance = default!;
+    [Dependency] private readonly AudioSystem _audio = default!;
+    [Dependency] private readonly EntityLookupSystem _entityLookup = default!;
+    [Dependency] private readonly PowerCellSystem _powerCell = default!;
+    [Dependency] private readonly TransformSystem _transform = default!;
+
+    /// <inheritdoc/>
+    public override void Initialize()
+    {
+        SubscribeLocalEvent<ProximityBeeperComponent, UseInHandEvent>(OnUseInHand);
+        SubscribeLocalEvent<ProximityBeeperComponent, ComponentInit>(OnInit);
+        SubscribeLocalEvent<ProximityBeeperComponent, EntityUnpausedEvent>(OnUnpaused);
+        SubscribeLocalEvent<ProximityBeeperComponent, PowerCellSlotEmptyEvent>(OnPowerCellSlotEmpty);
+    }
+    private void OnUseInHand(EntityUid uid, ProximityBeeperComponent component, UseInHandEvent args)
+    {
+        if (args.Handled)
+            return;
+
+        args.Handled = TryToggle(uid, component, args.User);
+    }
+
+    private void OnInit(EntityUid uid, ProximityBeeperComponent component, ComponentInit args)
+    {
+        if (component.NextBeepTime < _timing.CurTime)
+            component.NextBeepTime = _timing.CurTime;
+    }
+
+    private void OnUnpaused(EntityUid uid, ProximityBeeperComponent component, ref EntityUnpausedEvent args)
+    {
+        component.NextBeepTime += args.PausedTime;
+    }
+
+    private void OnPowerCellSlotEmpty(EntityUid uid, ProximityBeeperComponent component, ref PowerCellSlotEmptyEvent args)
+    {
+        if (component.Enabled)
+            TryDisable(uid, component);
+    }
+
+    /// <summary>
+    /// Beeps the proximitybeeper as well as sets the time for the next beep
+    /// based on proximity to entities with the target component.
+    /// </summary>
+    public void UpdateBeep(EntityUid uid, ProximityBeeperComponent? component = null, bool playBeep = true)
+    {
+        if (!Resolve(uid, ref component))
+            return;
+
+        if (!component.Enabled)
+        {
+            component.NextBeepTime += component.MinBeepInterval;
+            return;
+        }
+
+        var xformQuery = GetEntityQuery<TransformComponent>();
+        var xform = xformQuery.GetComponent(uid);
+        var comp = EntityManager.ComponentFactory.GetRegistration(component.Component).Type;
+        float? closestDistance = null;
+        foreach (var targetXform in _entityLookup.GetComponentsInRange<TransformComponent>(xform.MapPosition, component.MaximumDistance))
+        {
+            // forgive me father, for i have sinned.
+            var ent = targetXform.Owner;
+
+            if (!HasComp(ent, comp))
+                continue;
+
+            var dist = (_transform.GetWorldPosition(xform, xformQuery) - _transform.GetWorldPosition(targetXform, xformQuery)).Length;
+            if (dist >= (closestDistance ?? float.MaxValue))
+                continue;
+            closestDistance = dist;
+        }
+
+        if (closestDistance is not { } distance)
+            return;
+
+        if (playBeep)
+            _audio.PlayPvs(component.BeepSound, uid);
+
+        var scalingFactor = distance / component.MaximumDistance;
+        var interval = (component.MaxBeepInterval - component.MinBeepInterval) * scalingFactor + component.MinBeepInterval;
+        component.NextBeepTime += interval;
+    }
+
+    /// <summary>
+    /// Enables the proximity beeper
+    /// </summary>
+    public bool TryEnable(EntityUid uid, ProximityBeeperComponent? component = null, EntityUid? user = null)
+    {
+        if (!Resolve(uid, ref component))
+            return false;
+
+        TryComp<PowerCellDrawComponent>(uid, out var draw);
+
+        if (!_powerCell.HasActivatableCharge(uid, battery: draw, user: user))
+            return false;
+
+        component.Enabled = true;
+        _appearance.SetData(uid, ProximityBeeperVisuals.Enabled, true);
+        component.NextBeepTime = _timing.CurTime;
+        UpdateBeep(uid, component, false);
+        if (draw != null)
+            draw.Enabled = true;
+        return true;
+    }
+
+    /// <summary>
+    /// Disables the proximity beeper
+    /// </summary>
+    public bool TryDisable(EntityUid uid, ProximityBeeperComponent? component = null)
+    {
+        if (!Resolve(uid, ref component))
+            return false;
+
+        if (!component.Enabled)
+            return false;
+
+        component.Enabled = false;
+        _appearance.SetData(uid, ProximityBeeperVisuals.Enabled, false);
+        if (TryComp<PowerCellDrawComponent>(uid, out var draw))
+            draw.Enabled = true;
+        UpdateBeep(uid, component);
+        return true;
+    }
+
+    /// <summary>
+    /// toggles the proximity beeper
+    /// </summary>
+    public bool TryToggle(EntityUid uid, ProximityBeeperComponent? component = null, EntityUid? user = null)
+    {
+        if (!Resolve(uid, ref component))
+            return false;
+
+        return component.Enabled
+            ? TryDisable(uid, component)
+            : TryEnable(uid, component, user);
+    }
+
+    public override void Update(float frameTime)
+    {
+        base.Update(frameTime);
+
+        var query = EntityQueryEnumerator<ProximityBeeperComponent>();
+        while (query.MoveNext(out var uid, out var beeper))
+        {
+            if (!beeper.Enabled)
+                continue;
+
+            if (_timing.CurTime < beeper.NextBeepTime)
+                continue;
+            UpdateBeep(uid, beeper);
+        }
+    }
+}
diff --git a/Content.Shared/Pinpointer/SharedProximityBeeper.cs b/Content.Shared/Pinpointer/SharedProximityBeeper.cs
new file mode 100644 (file)
index 0000000..5163112
--- /dev/null
@@ -0,0 +1,9 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Pinpointer;
+
+[Serializable, NetSerializable]
+public enum ProximityBeeperVisuals : byte
+{
+    Enabled
+}
index 19f084fed6ef95371ad40e899dc3ab417330b8a1..1ebbf8311fe6208a702d069fcfcf7171443dc384 100644 (file)
@@ -3,6 +3,11 @@
   copyright: "Created by Pól, converted to OGG and Mono by EmoGarbage"
   source: "https://freesound.org/people/P%C3%B3l/sounds/385927/"
 
+- files: ["locator_beep.ogg"]
+  license: "CC0-1.0"
+  copyright: "Created by MATRIXXX_, converted to OGG, shortened, sped up, and pitched up by EmoGarbage404 (github)"
+  source: "https://freesound.org/people/MATRIXXX_/sounds/657947/"
+
 - files: ["trayhit1.ogg"]
   license: "CC-BY-SA-3.0"
   copyright: "Time immemorial"
diff --git a/Resources/Audio/Items/locator_beep.ogg b/Resources/Audio/Items/locator_beep.ogg
new file mode 100644 (file)
index 0000000..ae37c1e
Binary files /dev/null and b/Resources/Audio/Items/locator_beep.ogg differ
index 1ad09c82ba995e9a6cfd593cec3bf9bcf2f6e0da..9db86f498a65641c8b0386aa118bb2d3c89c0fe4 100644 (file)
   - ScanningModuleStockPart
   - NodeScanner
   - AnomalyScanner
+  - AnomalyLocator
 
 - type: technology
   name: technologies-anomaly-technology
index ff3c7606ad4fce6c8b60a86243fa75ddea7a93ae..a91be8c5881a5adae2a67b1e1175ffb3abef9855 100644 (file)
   - type: GuideHelp
     guides:
     - ScannersAndVessels
+
+- type: entity
+  id: AnomalyLocator
+  parent: [ BaseItem, PowerCellSlotSmallItem ]
+  name: anomaly locator
+  description: A device designed to aid in the locating of anomalies. Did you check the gas miners?
+  components:
+  - type: Sprite
+    sprite: Objects/Specific/Research/anomalylocator.rsi
+    netsync: false
+    layers:
+    - state: icon
+    - state: screen
+      shader: unshaded
+      visible: false
+      map: ["enum.PowerDeviceVisualLayers.Powered"]
+  - type: Appearance
+  - type: GenericVisualizer
+    visuals:
+      enum.ProximityBeeperVisuals.Enabled:
+        enum.PowerDeviceVisualLayers.Powered:
+          True: { visible: true }
+          False: { visible: false }
+  - type: PowerCellDraw
+    drawRate: 10
+    useRate: 0
+  - type: ProximityBeeper
+    component: Anomaly
+    beepSound:
+      path: "/Audio/Items/locator_beep.ogg"
+      params:
+        maxdistance: 1
+        volume: -8
+
+- type: entity
+  id: AnomalyLocatorNoBattery
+  parent: AnomalyLocator
+  suffix: No Battery
+  components:
+  - type: ItemSlots
+    slots:
+      cell_slot:
+        name: power-cell-slot-component-slot-name-default
\ No newline at end of file
index 18bae4399763ac1e7dd7a75f5b4b8cfaa543befb..05ed6926d3be704542a50529e9c41573f44a9b53 100644 (file)
       - ConveyorBeltAssembly
       - AppraisalTool
       - AnomalyScanner
+      - AnomalyLocator
       - RCD
       - RCDAmmo
       - HydroponicsToolScythe
index 135d1005ae524a74acd27d5ec366c49f7d2bfc8c..36b66a7cc427e8b24613d3c5138d3fcdc866785f 100644 (file)
     Plastic: 200
     Glass: 100
 
+- type: latheRecipe
+  id: AnomalyLocator
+  result: AnomalyLocatorNoBattery
+  completetime: 3
+  materials:
+    Steel: 400
+    Glass: 100
+
 - type: latheRecipe
   id: AnomalyScanner
   result: AnomalyScanner
diff --git a/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/icon.png b/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/icon.png
new file mode 100644 (file)
index 0000000..1ded159
Binary files /dev/null and b/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/icon.png differ
diff --git a/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/inhand-left.png b/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/inhand-left.png
new file mode 100644 (file)
index 0000000..84f9ca5
Binary files /dev/null and b/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/inhand-left.png differ
diff --git a/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/inhand-right.png b/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/inhand-right.png
new file mode 100644 (file)
index 0000000..8c4743d
Binary files /dev/null and b/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/inhand-right.png differ
diff --git a/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/meta.json b/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/meta.json
new file mode 100644 (file)
index 0000000..c10f31b
--- /dev/null
@@ -0,0 +1,33 @@
+{
+  "version": 1,
+  "license": "CC0-1.0",
+  "copyright": "Created by EmoGarbage404 (github) for Space Station 14.",
+  "size": {
+    "x": 32,
+    "y": 32
+  },
+  "states": [
+    {
+      "name": "icon"
+    },
+    {
+      "name": "inhand-left",
+      "directions": 4
+    },
+    {
+      "name": "inhand-right",
+      "directions": 4
+    },
+    {
+      "name": "screen",
+      "delays": [
+        [
+          0.2,
+          0.2,
+          0.2,
+          0.2
+        ]
+      ]
+    }
+  ]
+}
diff --git a/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/screen.png b/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/screen.png
new file mode 100644 (file)
index 0000000..7506f35
Binary files /dev/null and b/Resources/Textures/Objects/Specific/Research/anomalylocator.rsi/screen.png differ