]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
artifact crusher (#22301)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Mon, 11 Dec 2023 23:15:47 +0000 (18:15 -0500)
committerGitHub <noreply@github.com>
Mon, 11 Dec 2023 23:15:47 +0000 (10:15 +1100)
23 files changed:
Content.Client/Storage/Visualizers/EntityStorageVisualizerSystem.cs
Content.Client/Storage/Visualizers/EntityStorageVisualsComponent.cs
Content.Client/Xenoarchaeology/Equipment/ArtifactCrusherSystem.cs [new file with mode: 0644]
Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs [new file with mode: 0644]
Content.Shared/Xenoarchaeology/Equipment/ArtifactCrusherComponent.cs [new file with mode: 0644]
Content.Shared/Xenoarchaeology/Equipment/SharedArtifactCrusherSystem.cs [new file with mode: 0644]
Resources/Audio/Effects/attributions.yml
Resources/Audio/Effects/hydraulic_press.ogg [new file with mode: 0644]
Resources/Audio/Effects/metal_crunch.ogg [new file with mode: 0644]
Resources/Locale/en-US/wires/wire-names.ftl
Resources/Locale/en-US/xenoarchaeology/artifact-crusher.ftl [new file with mode: 0644]
Resources/Prototypes/Entities/Objects/Devices/Circuitboards/Machine/production.yml
Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml
Resources/Prototypes/Entities/Structures/Machines/lathe.yml
Resources/Prototypes/Recipes/Lathes/electronics.yml
Resources/Prototypes/Research/experimental.yml
Resources/Textures/Structures/Machines/artifact_crusher.rsi/base.png [new file with mode: 0644]
Resources/Textures/Structures/Machines/artifact_crusher.rsi/door-closed.png [new file with mode: 0644]
Resources/Textures/Structures/Machines/artifact_crusher.rsi/glass.png [new file with mode: 0644]
Resources/Textures/Structures/Machines/artifact_crusher.rsi/lights.png [new file with mode: 0644]
Resources/Textures/Structures/Machines/artifact_crusher.rsi/meta.json [new file with mode: 0644]
Resources/Textures/Structures/Machines/artifact_crusher.rsi/piston-push.png [new file with mode: 0644]
Resources/Textures/Structures/Machines/artifact_crusher.rsi/piston.png [new file with mode: 0644]

index 39a8f3d932cb6d0d2337fb18f9cb4ceefa263f07..772f516a6920114a53920263d175ae89d1a50283 100644 (file)
@@ -37,15 +37,27 @@ public sealed class EntityStorageVisualizerSystem : VisualizerSystem<EntityStora
         {
             if (open)
             {
-                args.Sprite.LayerSetVisible(StorageVisualLayers.Door, true);
+                if (comp.OpenDrawDepth != null)
+                    args.Sprite.DrawDepth = comp.OpenDrawDepth.Value;
+
                 if (comp.StateDoorOpen != null)
+                {
                     args.Sprite.LayerSetState(StorageVisualLayers.Door, comp.StateDoorOpen);
+                    args.Sprite.LayerSetVisible(StorageVisualLayers.Door, true);
+                }
+                else
+                {
+                    args.Sprite.LayerSetVisible(StorageVisualLayers.Door, false);
+                }
 
                 if (comp.StateBaseOpen != null)
                     args.Sprite.LayerSetState(StorageVisualLayers.Base, comp.StateBaseOpen);
             }
             else
             {
+                if (comp.ClosedDrawDepth != null)
+                    args.Sprite.DrawDepth = comp.ClosedDrawDepth.Value;
+
                 if (comp.StateDoorClosed != null)
                 {
                     args.Sprite.LayerSetState(StorageVisualLayers.Door, comp.StateDoorClosed);
index 2635608421c0f35bd842123b531167b14cede641..dc171d6c54e0dc7a5cc0d1d9683f96e6dc347c57 100644 (file)
@@ -45,4 +45,16 @@ public sealed partial class EntityStorageVisualsComponent : Component
     [DataField("stateUnlocked")]
     [ViewVariables(VVAccess.ReadWrite)]
     public string? StateUnlocked = "unlocked";
+
+    /// <summary>
+    /// The drawdepth the object has when it's open
+    /// </summary>
+    [DataField, ViewVariables(VVAccess.ReadWrite)]
+    public int? OpenDrawDepth;
+
+    /// <summary>
+    /// The drawdepth the object has when it's closed
+    /// </summary>
+    [DataField, ViewVariables(VVAccess.ReadWrite)]
+    public int? ClosedDrawDepth;
 }
diff --git a/Content.Client/Xenoarchaeology/Equipment/ArtifactCrusherSystem.cs b/Content.Client/Xenoarchaeology/Equipment/ArtifactCrusherSystem.cs
new file mode 100644 (file)
index 0000000..a57ef55
--- /dev/null
@@ -0,0 +1,9 @@
+using Content.Shared.Xenoarchaeology.Equipment;
+
+namespace Content.Client.Xenoarchaeology.Equipment;
+
+/// <inheritdoc/>
+public sealed class ArtifactCrusherSystem : SharedArtifactCrusherSystem
+{
+
+}
diff --git a/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs b/Content.Server/Xenoarchaeology/Equipment/Systems/ArtifactCrusherSystem.cs
new file mode 100644 (file)
index 0000000..de417d0
--- /dev/null
@@ -0,0 +1,138 @@
+using Content.Server.Body.Systems;
+using Content.Server.Power.Components;
+using Content.Server.Power.EntitySystems;
+using Content.Server.Stack;
+using Content.Server.Storage.Components;
+using Content.Server.Xenoarchaeology.XenoArtifacts;
+using Content.Shared.Body.Components;
+using Content.Shared.Damage;
+using Content.Shared.Verbs;
+using Content.Shared.Xenoarchaeology.Equipment;
+using Robust.Shared.Collections;
+using Robust.Shared.Random;
+using Robust.Shared.Timing;
+
+namespace Content.Server.Xenoarchaeology.Equipment.Systems;
+
+/// <inheritdoc/>
+public sealed class ArtifactCrusherSystem : SharedArtifactCrusherSystem
+{
+    [Dependency] private readonly IGameTiming _timing = default!;
+    [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly ArtifactSystem _artifact = default!;
+    [Dependency] private readonly BodySystem _body = default!;
+    [Dependency] private readonly DamageableSystem _damageable = default!;
+    [Dependency] private readonly StackSystem _stack = default!;
+
+    /// <inheritdoc/>
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<ArtifactCrusherComponent, GetVerbsEvent<AlternativeVerb>>(OnGetVerbs);
+        SubscribeLocalEvent<ArtifactCrusherComponent, PowerChangedEvent>(OnPowerChanged);
+    }
+
+    private void OnGetVerbs(Entity<ArtifactCrusherComponent> ent, ref GetVerbsEvent<AlternativeVerb> args)
+    {
+        if (!args.CanAccess || !args.CanInteract || args.Hands == null || ent.Comp.Crushing)
+            return;
+
+        if (!TryComp<EntityStorageComponent>(ent, out var entityStorageComp) || entityStorageComp.Contents.ContainedEntities.Count == 0)
+            return;
+
+        if (entityStorageComp.Contents.Contains(args.User) || !this.IsPowered(ent, EntityManager))
+            return;
+
+        var verb = new AlternativeVerb
+        {
+            Text = Loc.GetString("artifact-crusher-verb-start-crushing"),
+            Priority = 2,
+            Act = () => StartCrushing((ent, ent.Comp, entityStorageComp))
+        };
+        args.Verbs.Add(verb);
+    }
+
+    private void OnPowerChanged(Entity<ArtifactCrusherComponent> ent, ref PowerChangedEvent args)
+    {
+        if (!args.Powered)
+            StopCrushing(ent);
+    }
+
+    public void StartCrushing(Entity<ArtifactCrusherComponent, EntityStorageComponent> ent)
+    {
+        var (_, crusher, _) = ent;
+
+        if (crusher.Crushing)
+            return;
+
+        crusher.Crushing = true;
+        crusher.NextSecond = _timing.CurTime + TimeSpan.FromSeconds(1);
+        crusher.CrushEndTime = _timing.CurTime + crusher.CrushDuration;
+        crusher.CrushingSoundEntity = AudioSystem.PlayPvs(crusher.CrushingSound, ent);
+        Appearance.SetData(ent, ArtifactCrusherVisuals.Crushing, true);
+        Dirty(ent, ent.Comp1);
+    }
+
+    public void FinishCrushing(Entity<ArtifactCrusherComponent, EntityStorageComponent> ent)
+    {
+        var (_, crusher, storage) = ent;
+        StopCrushing((ent, ent.Comp1), false);
+        AudioSystem.PlayPvs(crusher.CrushingCompleteSound, ent);
+        crusher.CrushingSoundEntity = null;
+        Dirty(ent, ent.Comp1);
+
+        var contents = new ValueList<EntityUid>(storage.Contents.ContainedEntities);
+        var coords = Transform(ent).Coordinates;
+        foreach (var contained in contents)
+        {
+            if (crusher.CrushingWhitelist.IsValid(contained, EntityManager))
+            {
+                var amount = _random.Next(crusher.MinFragments, crusher.MaxFragments);
+                var stacks = _stack.SpawnMultiple(crusher.FragmentStackProtoId, amount, coords);
+                foreach (var stack in stacks)
+                {
+                    ContainerSystem.Insert((stack, null, null, null), crusher.OutputContainer);
+                }
+                _artifact.ForceActivateArtifact(contained);
+            }
+
+            if (!TryComp<BodyComponent>(contained, out var body))
+                Del(contained);
+
+            var gibs = _body.GibBody(contained, body: body, gibOrgans: true, deleteBrain: true);
+            foreach (var gib in gibs)
+            {
+                ContainerSystem.Insert((gib, null, null, null), crusher.OutputContainer);
+            }
+        }
+    }
+
+    public override void Update(float frameTime)
+    {
+        base.Update(frameTime);
+
+        var query = EntityQueryEnumerator<ArtifactCrusherComponent, EntityStorageComponent>();
+        while (query.MoveNext(out var uid, out var crusher, out var storage))
+        {
+            if (!crusher.Crushing)
+                continue;
+
+            if (crusher.NextSecond < _timing.CurTime)
+            {
+                var contents = new ValueList<EntityUid>(storage.Contents.ContainedEntities);
+                foreach (var contained in contents)
+                {
+                    _damageable.TryChangeDamage(contained, crusher.CrushingDamage);
+                }
+                crusher.NextSecond += TimeSpan.FromSeconds(1);
+                Dirty(uid, crusher);
+            }
+
+            if (crusher.CrushEndTime < _timing.CurTime)
+            {
+                FinishCrushing((uid, crusher, storage));
+            }
+        }
+    }
+}
diff --git a/Content.Shared/Xenoarchaeology/Equipment/ArtifactCrusherComponent.cs b/Content.Shared/Xenoarchaeology/Equipment/ArtifactCrusherComponent.cs
new file mode 100644 (file)
index 0000000..6bfbe5d
--- /dev/null
@@ -0,0 +1,110 @@
+using Content.Shared.Damage;
+using Content.Shared.Stacks;
+using Content.Shared.Whitelist;
+using Robust.Shared.Audio;
+using Robust.Shared.Audio.Components;
+using Robust.Shared.Containers;
+using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
+
+namespace Content.Shared.Xenoarchaeology.Equipment;
+
+/// <summary>
+/// This is an entity storage that, when activated, crushes the artifact inside of it and gives artifact fragments.
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(SharedArtifactCrusherSystem))]
+public sealed partial class ArtifactCrusherComponent : Component
+{
+    /// <summary>
+    /// Whether or not the crusher is currently in the process of crushing something.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public bool Crushing;
+
+    /// <summary>
+    /// When the current crushing will end.
+    /// </summary>
+    [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+    public TimeSpan CrushEndTime;
+
+    /// <summary>
+    /// The next second. Used to apply damage over time.
+    /// </summary>
+    [DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+    public TimeSpan NextSecond;
+
+    /// <summary>
+    /// The total duration of the crushing.
+    /// </summary>
+    [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+    public TimeSpan CrushDuration = TimeSpan.FromSeconds(10);
+
+    /// <summary>
+    /// A whitelist specifying what items, when crushed, will give fragments.
+    /// </summary>
+    [DataField]
+    public EntityWhitelist CrushingWhitelist = new();
+
+    /// <summary>
+    /// The minimum amount of fragments spawned.
+    /// </summary>
+    [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+    public int MinFragments = 2;
+
+    /// <summary>
+    /// The maximum amount of fragments spawned, non-inclusive.
+    /// </summary>
+    [DataField, ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
+    public int MaxFragments = 5;
+
+    /// <summary>
+    /// The material for the fragments.
+    /// </summary>
+    [DataField, ViewVariables(VVAccess.ReadWrite)]
+    public ProtoId<StackPrototype> FragmentStackProtoId = "ArtifactFragment";
+
+    /// <summary>
+    /// A container used to hold fragments and gibs from crushing.
+    /// </summary>
+    [ViewVariables]
+    public Container OutputContainer;
+
+    /// <summary>
+    /// The ID for <see cref="OutputContainer"/>
+    /// </summary>
+    [DataField]
+    public string OutputContainerName = "output_container";
+
+    /// <summary>
+    /// Damage dealt each second to entities inside while crushing.
+    /// </summary>
+    [DataField]
+    public DamageSpecifier CrushingDamage = new();
+
+    /// <summary>
+    /// Sound played at the end of a successful crush.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public SoundSpecifier? CrushingCompleteSound = new SoundPathSpecifier("/Audio/Effects/metal_crunch.ogg");
+
+    /// <summary>
+    /// Sound played throughout the entire crushing. Cut off if ended early.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public SoundSpecifier? CrushingSound = new SoundPathSpecifier("/Audio/Effects/hydraulic_press.ogg");
+
+    /// <summary>
+    /// Stores entity of <see cref="CrushingSound"/> to allow ending it early.
+    /// </summary>
+    [DataField]
+    public (EntityUid, AudioComponent)? CrushingSoundEntity;
+}
+
+[Serializable, NetSerializable]
+public enum ArtifactCrusherVisuals : byte
+{
+    Crushing
+}
diff --git a/Content.Shared/Xenoarchaeology/Equipment/SharedArtifactCrusherSystem.cs b/Content.Shared/Xenoarchaeology/Equipment/SharedArtifactCrusherSystem.cs
new file mode 100644 (file)
index 0000000..44e1b91
--- /dev/null
@@ -0,0 +1,54 @@
+using Content.Shared.Storage.Components;
+using Robust.Shared.Audio.Systems;
+using Robust.Shared.Containers;
+
+namespace Content.Shared.Xenoarchaeology.Equipment;
+
+/// <summary>
+/// This handles logic relating to <see cref="ArtifactCrusherComponent"/>
+/// </summary>
+public abstract class SharedArtifactCrusherSystem : EntitySystem
+{
+    [Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
+    [Dependency] protected readonly SharedAudioSystem AudioSystem = default!;
+    [Dependency] protected readonly SharedContainerSystem ContainerSystem = default!;
+
+    /// <inheritdoc/>
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<ArtifactCrusherComponent, ComponentInit>(OnInit);
+        SubscribeLocalEvent<ArtifactCrusherComponent, StorageAfterOpenEvent>(OnStorageAfterOpen);
+    }
+
+    private void OnInit(Entity<ArtifactCrusherComponent> ent, ref ComponentInit args)
+    {
+        ent.Comp.OutputContainer = ContainerSystem.EnsureContainer<Container>(ent, ent.Comp.OutputContainerName);
+    }
+
+    private void OnStorageAfterOpen(Entity<ArtifactCrusherComponent> ent, ref StorageAfterOpenEvent args)
+    {
+        StopCrushing(ent);
+        ContainerSystem.EmptyContainer(ent.Comp.OutputContainer);
+    }
+
+    public void StopCrushing(Entity<ArtifactCrusherComponent> ent, bool early = true)
+    {
+        var (_, crusher) = ent;
+
+        if (!crusher.Crushing)
+            return;
+
+        crusher.Crushing = false;
+        Appearance.SetData(ent, ArtifactCrusherVisuals.Crushing, false);
+
+        if (early)
+        {
+            AudioSystem.Stop(crusher.CrushingSoundEntity?.Item1, crusher.CrushingSoundEntity?.Item2);
+            crusher.CrushingSoundEntity = null;
+        }
+
+        Dirty(ent, ent.Comp);
+    }
+}
index 252bc9ee14caf472893cfc9e882b2a878128d3de..2e14f74815339deb810cc3ef94f68d7149ffdff3 100644 (file)
   license: "CC-BY-4.0"
   source: "https://freesound.org/people/thomas_evdokimoff/sounds/202193/"
 
+- files: ["hydraulic_press.ogg"]
+  copyright: 'Created by chainsaw_dinner_party on Freesound.org. Extended and converted to MONO and .ogg by EmoGarbage404 (github)'
+  license: "CC0-1.0"
+  source: "https://freesound.org/people/chainsaw_dinner_party/sounds/403075/"
+
+- files: ["metal_crunch.ogg"]
+  copyright: 'Created by PNMCarrieRailfan on Freesound.org. Edited and exported to .ogg by EmoGarbage404 (github)'
+  license: "CC-BY-NC-4.0"
+  source: "https://freesound.org/people/PNMCarrieRailfan/sounds/682439/"
+
 - files: ["voteding.ogg"]
   copyright: '"Bike, Bell Ding, Single, 01-01.wav" byInspectorJ (www.jshaw.co.uk) of Freesound.org; The volume has been reduced.'
   license: "CC-BY-4.0"
diff --git a/Resources/Audio/Effects/hydraulic_press.ogg b/Resources/Audio/Effects/hydraulic_press.ogg
new file mode 100644 (file)
index 0000000..0158384
Binary files /dev/null and b/Resources/Audio/Effects/hydraulic_press.ogg differ
diff --git a/Resources/Audio/Effects/metal_crunch.ogg b/Resources/Audio/Effects/metal_crunch.ogg
new file mode 100644 (file)
index 0000000..a0973b7
Binary files /dev/null and b/Resources/Audio/Effects/metal_crunch.ogg differ
index 04bbca104e3983b139e480536af5af71d10ff2f2..aae87f9c53508c7bf5234be965e0c9df2c1e365e 100644 (file)
@@ -6,6 +6,7 @@ wires-board-name-thermomachine = Thermomachine
 wires-board-name-pa = Mk2 Particle Accelerator
 wires-board-name-highsec = HighSec Control
 wires-board-name-vessel = Vessel
+wires-board-name-crusher = Crusher
 wires-board-name-smes = SMES
 wires-board-name-substation = Substation
 wires-board-name-apc = APC
diff --git a/Resources/Locale/en-US/xenoarchaeology/artifact-crusher.ftl b/Resources/Locale/en-US/xenoarchaeology/artifact-crusher.ftl
new file mode 100644 (file)
index 0000000..d16918b
--- /dev/null
@@ -0,0 +1 @@
+artifact-crusher-verb-start-crushing = Start crushing
index b47e286bda03e22698a767b3f13149ea4a37db59..af4f8cba783363b2824e27a63e215a8ab97da98f 100644 (file)
         Steel: 5
         Cable: 1
 
+- type: entity
+  id: ArtifactCrusherMachineCircuitboard
+  parent: BaseMachineCircuitboard
+  name: artifact crusher machine board
+  description: A machine printed circuit board for an artifact crusher.
+  components:
+  - type: Sprite
+    state: science
+  - type: MachineBoard
+    prototype: MachineArtifactCrusher
+    requirements:
+      Manipulator: 2
+    materialRequirements:
+      Glass: 1
+      Steel: 5
+
 - type: entity
   parent: BaseMachineCircuitboard
   id: AnomalyVesselCircuitboard
index d1cc01ea40b5945729a669218ceb9499ebb59cda..4dd8ccdbbbd5a44e53d4897edcc15db51ed13759 100644 (file)
         enum.PowerDeviceVisualLayers.Powered:
           True: { visible: true }
           False: { visible: false }
+
+- type: entity
+  id: MachineArtifactCrusher
+  parent: [ ConstructibleMachine, BaseMachinePowered ]
+  name: artifact crusher
+  description: Best not to let your fingers get stuck...
+  components:
+  - type: ArtifactCrusher
+    crushingWhitelist:
+      components:
+      - Artifact
+    crushingDamage:
+      types:
+        Blunt: 10
+  - type: Machine
+    board: ArtifactCrusherMachineCircuitboard
+  - type: Wires
+    boardName: wires-board-name-crusher
+    layoutId: Crusher
+  - type: WiresPanel
+  - type: Sprite
+    sprite: Structures/Machines/artifact_crusher.rsi
+    offset: 0,0.5
+    noRot: true
+    layers:
+    - state: base
+      map: ["enum.StorageVisualLayers.Base"]
+    - state: door-closed
+      map: ["enum.StorageVisualLayers.Door"]
+    - state: piston
+      map: ["pistonlayer"]
+    - state: glass
+    - state: lights
+      map: ["enum.PowerDeviceVisualLayers.Powered"]
+      shader: unshaded
+  - type: Fixtures
+    fixtures:
+      fix1:
+        shape:
+          !type:PhysShapeCircle
+          radius: 0.45
+        density: 50
+        mask:
+        - HighImpassable
+        layer:
+        - HighImpassable
+  - type: EntityStorage
+    capacity: 1
+    whitelist:
+      components:
+      - Artifact
+  - type: Appearance
+  - type: GenericVisualizer
+    visuals:
+      enum.ArtifactCrusherVisuals.Crushing:
+        pistonlayer:
+          True: {state: piston-push}
+          False: {state: piston}
+      enum.PowerDeviceVisuals.Powered:
+        enum.PowerDeviceVisualLayers.Powered:
+          True: { visible: true }
+          False: { visible: false }
+  - type: EntityStorageVisuals
+    stateDoorClosed: door-closed
+    openDrawDepth: 0
+    closedDrawDepth: 4
+  - type: Construction
+    containers:
+    - machine_board
+    - machine_parts
+    - entity_storage
+    - output_container
+  - type: ContainerContainer
+    containers:
+      machine_board: !type:Container
+      machine_parts: !type:Container
+      entity_storage: !type:Container
+      output_container: !type:Container
index ec83d4005ffed03619125d2f3d1a0c7941d14673..5972a6c97631b32b12494573390037655fb45c8e 100644 (file)
       - APECircuitboard
       - ArtifactAnalyzerMachineCircuitboard
       - TraversalDistorterMachineCircuitboard
+      - ArtifactCrusherMachineCircuitboard
       - BoozeDispenserMachineCircuitboard
       - SodaDispenserMachineCircuitboard
       - TelecomServerCircuitboard
index df031864cf16f52cf1a0fd6d7ad96e93e3d1ceb1..8477e6c9be56d54b862bd662f5aadb8ce9d29a5d 100644 (file)
      Glass: 900
      Gold: 100
 
+- type: latheRecipe
+  id: ArtifactCrusherMachineCircuitboard
+  result: ArtifactCrusherMachineCircuitboard
+  completetime: 4
+  materials:
+    Steel: 100
+    Glass: 900
+    Gold: 100
+
 - type: latheRecipe
   id: AnomalyVesselCircuitboard
   result: AnomalyVesselCircuitboard
index 9eed5e59942b7898b160b3e0f22b42b992df56bc..a58baf1b78803ad3bff66cfa568d1d9b209ecb25 100644 (file)
@@ -97,6 +97,7 @@
   cost: 5000
   recipeUnlocks:
   - TraversalDistorterMachineCircuitboard
+  - ArtifactCrusherMachineCircuitboard
 
 - type: technology
   id: AdvancedAnomalyResearch
diff --git a/Resources/Textures/Structures/Machines/artifact_crusher.rsi/base.png b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/base.png
new file mode 100644 (file)
index 0000000..cf281d8
Binary files /dev/null and b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/base.png differ
diff --git a/Resources/Textures/Structures/Machines/artifact_crusher.rsi/door-closed.png b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/door-closed.png
new file mode 100644 (file)
index 0000000..3a86381
Binary files /dev/null and b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/door-closed.png differ
diff --git a/Resources/Textures/Structures/Machines/artifact_crusher.rsi/glass.png b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/glass.png
new file mode 100644 (file)
index 0000000..04bb703
Binary files /dev/null and b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/glass.png differ
diff --git a/Resources/Textures/Structures/Machines/artifact_crusher.rsi/lights.png b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/lights.png
new file mode 100644 (file)
index 0000000..181e9cb
Binary files /dev/null and b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/lights.png differ
diff --git a/Resources/Textures/Structures/Machines/artifact_crusher.rsi/meta.json b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/meta.json
new file mode 100644 (file)
index 0000000..dc0d23c
--- /dev/null
@@ -0,0 +1,48 @@
+{
+  "version": 1,
+  "license": "CC-BY-SA-3.0",
+  "copyright": "Made by brainfood1183 (github) for ss14",
+  "size": {
+    "x": 32,
+    "y": 64
+  },
+  "states": [
+    {
+      "name": "glass"
+    },
+    {
+      "name": "door-closed"
+    },
+    {
+      "name": "piston"
+    },
+    {
+      "name": "base"
+    },
+    {
+      "name": "lights"
+    },
+    {
+      "name": "piston-push",
+      "delays": [
+        [
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          0.66,
+          1
+        ]
+      ]
+    }
+  ]
+}
diff --git a/Resources/Textures/Structures/Machines/artifact_crusher.rsi/piston-push.png b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/piston-push.png
new file mode 100644 (file)
index 0000000..e9fa5f8
Binary files /dev/null and b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/piston-push.png differ
diff --git a/Resources/Textures/Structures/Machines/artifact_crusher.rsi/piston.png b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/piston.png
new file mode 100644 (file)
index 0000000..9b1fe54
Binary files /dev/null and b/Resources/Textures/Structures/Machines/artifact_crusher.rsi/piston.png differ