artifact crusher (#22301)
This commit is contained in:
@@ -37,15 +37,27 @@ public sealed class EntityStorageVisualizerSystem : VisualizerSystem<EntityStora
|
|||||||
{
|
{
|
||||||
if (open)
|
if (open)
|
||||||
{
|
{
|
||||||
args.Sprite.LayerSetVisible(StorageVisualLayers.Door, true);
|
if (comp.OpenDrawDepth != null)
|
||||||
|
args.Sprite.DrawDepth = comp.OpenDrawDepth.Value;
|
||||||
|
|
||||||
if (comp.StateDoorOpen != null)
|
if (comp.StateDoorOpen != null)
|
||||||
|
{
|
||||||
args.Sprite.LayerSetState(StorageVisualLayers.Door, comp.StateDoorOpen);
|
args.Sprite.LayerSetState(StorageVisualLayers.Door, comp.StateDoorOpen);
|
||||||
|
args.Sprite.LayerSetVisible(StorageVisualLayers.Door, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args.Sprite.LayerSetVisible(StorageVisualLayers.Door, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (comp.StateBaseOpen != null)
|
if (comp.StateBaseOpen != null)
|
||||||
args.Sprite.LayerSetState(StorageVisualLayers.Base, comp.StateBaseOpen);
|
args.Sprite.LayerSetState(StorageVisualLayers.Base, comp.StateBaseOpen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (comp.ClosedDrawDepth != null)
|
||||||
|
args.Sprite.DrawDepth = comp.ClosedDrawDepth.Value;
|
||||||
|
|
||||||
if (comp.StateDoorClosed != null)
|
if (comp.StateDoorClosed != null)
|
||||||
{
|
{
|
||||||
args.Sprite.LayerSetState(StorageVisualLayers.Door, comp.StateDoorClosed);
|
args.Sprite.LayerSetState(StorageVisualLayers.Door, comp.StateDoorClosed);
|
||||||
|
|||||||
@@ -45,4 +45,16 @@ public sealed partial class EntityStorageVisualsComponent : Component
|
|||||||
[DataField("stateUnlocked")]
|
[DataField("stateUnlocked")]
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public string? StateUnlocked = "unlocked";
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using Content.Shared.Xenoarchaeology.Equipment;
|
||||||
|
|
||||||
|
namespace Content.Client.Xenoarchaeology.Equipment;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public sealed class ArtifactCrusherSystem : SharedArtifactCrusherSystem
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -107,6 +107,16 @@
|
|||||||
license: "CC-BY-4.0"
|
license: "CC-BY-4.0"
|
||||||
source: "https://freesound.org/people/thomas_evdokimoff/sounds/202193/"
|
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"]
|
- files: ["voteding.ogg"]
|
||||||
copyright: '"Bike, Bell Ding, Single, 01-01.wav" byInspectorJ (www.jshaw.co.uk) of Freesound.org; The volume has been reduced.'
|
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"
|
license: "CC-BY-4.0"
|
||||||
|
|||||||
BIN
Resources/Audio/Effects/hydraulic_press.ogg
Normal file
BIN
Resources/Audio/Effects/hydraulic_press.ogg
Normal file
Binary file not shown.
BIN
Resources/Audio/Effects/metal_crunch.ogg
Normal file
BIN
Resources/Audio/Effects/metal_crunch.ogg
Normal file
Binary file not shown.
@@ -6,6 +6,7 @@ wires-board-name-thermomachine = Thermomachine
|
|||||||
wires-board-name-pa = Mk2 Particle Accelerator
|
wires-board-name-pa = Mk2 Particle Accelerator
|
||||||
wires-board-name-highsec = HighSec Control
|
wires-board-name-highsec = HighSec Control
|
||||||
wires-board-name-vessel = Vessel
|
wires-board-name-vessel = Vessel
|
||||||
|
wires-board-name-crusher = Crusher
|
||||||
wires-board-name-smes = SMES
|
wires-board-name-smes = SMES
|
||||||
wires-board-name-substation = Substation
|
wires-board-name-substation = Substation
|
||||||
wires-board-name-apc = APC
|
wires-board-name-apc = APC
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
artifact-crusher-verb-start-crushing = Start crushing
|
||||||
@@ -217,6 +217,22 @@
|
|||||||
Steel: 5
|
Steel: 5
|
||||||
Cable: 1
|
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
|
- type: entity
|
||||||
parent: BaseMachineCircuitboard
|
parent: BaseMachineCircuitboard
|
||||||
id: AnomalyVesselCircuitboard
|
id: AnomalyVesselCircuitboard
|
||||||
|
|||||||
@@ -133,3 +133,81 @@
|
|||||||
enum.PowerDeviceVisualLayers.Powered:
|
enum.PowerDeviceVisualLayers.Powered:
|
||||||
True: { visible: true }
|
True: { visible: true }
|
||||||
False: { visible: false }
|
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
|
||||||
|
|||||||
@@ -374,6 +374,7 @@
|
|||||||
- APECircuitboard
|
- APECircuitboard
|
||||||
- ArtifactAnalyzerMachineCircuitboard
|
- ArtifactAnalyzerMachineCircuitboard
|
||||||
- TraversalDistorterMachineCircuitboard
|
- TraversalDistorterMachineCircuitboard
|
||||||
|
- ArtifactCrusherMachineCircuitboard
|
||||||
- BoozeDispenserMachineCircuitboard
|
- BoozeDispenserMachineCircuitboard
|
||||||
- SodaDispenserMachineCircuitboard
|
- SodaDispenserMachineCircuitboard
|
||||||
- TelecomServerCircuitboard
|
- TelecomServerCircuitboard
|
||||||
|
|||||||
@@ -240,6 +240,15 @@
|
|||||||
Glass: 900
|
Glass: 900
|
||||||
Gold: 100
|
Gold: 100
|
||||||
|
|
||||||
|
- type: latheRecipe
|
||||||
|
id: ArtifactCrusherMachineCircuitboard
|
||||||
|
result: ArtifactCrusherMachineCircuitboard
|
||||||
|
completetime: 4
|
||||||
|
materials:
|
||||||
|
Steel: 100
|
||||||
|
Glass: 900
|
||||||
|
Gold: 100
|
||||||
|
|
||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
id: AnomalyVesselCircuitboard
|
id: AnomalyVesselCircuitboard
|
||||||
result: AnomalyVesselCircuitboard
|
result: AnomalyVesselCircuitboard
|
||||||
|
|||||||
@@ -97,6 +97,7 @@
|
|||||||
cost: 5000
|
cost: 5000
|
||||||
recipeUnlocks:
|
recipeUnlocks:
|
||||||
- TraversalDistorterMachineCircuitboard
|
- TraversalDistorterMachineCircuitboard
|
||||||
|
- ArtifactCrusherMachineCircuitboard
|
||||||
|
|
||||||
- type: technology
|
- type: technology
|
||||||
id: AdvancedAnomalyResearch
|
id: AdvancedAnomalyResearch
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 368 B |
Binary file not shown.
|
After Width: | Height: | Size: 193 B |
Binary file not shown.
|
After Width: | Height: | Size: 152 B |
@@ -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
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 345 B |
Reference in New Issue
Block a user