mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 10:21:18 +03:00
Add industrial smelters (admin only) (#43651)
* Initial commit with shredder base functionality * Fix items being deleted and make items continue moving after a grid tile gets deleted * Make a bunch of previously unpullable/unrecyclable things work * temp commit * Fix the recycling hitbox to actually be good code * Fix material spawning via tiles * Finish up the prototype visuals for the shredder * SHRED EVERYTHING * Add reduced efficiency for recycling with shreder * Fix miss in conflict merge * Make more things pullable * Update shredder textures to look different to recyclers * Remove unused * "fix" repairability and sprites * Update sprites, set up TODO-s * Fix switches, description * Fix up some comments * Add "Do Not Map" to the smelter * Add to meta.json * Review fixes * Review changes * Review changes * Remove readonly in new system * Aaaand partial class * Fix the final test issues * Update and resolve merge conflicts * Update the impulse strength to match new mass values * Fix issues after merge conflict * Update size, fix physics resolve errors, prevent computers/circuitboards from being deleted * Review comments * Fix tiles giving steel * Add a todo about tilestacking
This commit is contained in:
parent
86e633be6e
commit
0cd76c7bac
31 changed files with 557 additions and 38 deletions
|
|
@ -37,6 +37,9 @@ public sealed class ReclaimerLoopTest : InteractionTest
|
|||
|
||||
var reclaimComp = Comp<MaterialReclaimerComponent>(Target);
|
||||
|
||||
// Put a floor tile down
|
||||
await InteractUsing(FloorTileId);
|
||||
|
||||
// Power the reclaimer
|
||||
await SpawnEntity(ApcId, SEntMan.GetCoordinates(TargetCoords));
|
||||
await RunTicks(1);
|
||||
|
|
@ -49,9 +52,6 @@ public sealed class ReclaimerLoopTest : InteractionTest
|
|||
// Check that reclaimer enabled
|
||||
Assume.That(reclaimComp.Enabled, "The reclaimer did not get or stay enabled");
|
||||
|
||||
// Put a floor tile down
|
||||
await InteractUsing(FloorTileId);
|
||||
|
||||
// Reclaimer can't reclaim materials? Job's done.
|
||||
if (!reclaimComp.ReclaimMaterials)
|
||||
Assert.Ignore("Cannot reclaim materials");
|
||||
|
|
|
|||
|
|
@ -210,19 +210,7 @@ public sealed partial class MaterialReclaimerSystem : SharedMaterialReclaimerSys
|
|||
_materialStorage.TryChangeMaterialAmount(reclaimer, material, outputAmount, storage);
|
||||
}
|
||||
|
||||
foreach (var (storedMaterial, storedAmount) in storage.Storage)
|
||||
{
|
||||
var stacks = _materialStorage.SpawnMultipleFromMaterial(storedAmount,
|
||||
storedMaterial,
|
||||
xform.Coordinates,
|
||||
out var materialOverflow);
|
||||
var amountConsumed = storedAmount - materialOverflow;
|
||||
_materialStorage.TryChangeMaterialAmount(reclaimer, storedMaterial, -amountConsumed, storage);
|
||||
foreach (var stack in stacks)
|
||||
{
|
||||
_stack.TryMergeToContacts(stack);
|
||||
}
|
||||
}
|
||||
_materialStorage.EjectAllMaterial(reclaimer, xform.Coordinates, storage, true);
|
||||
}
|
||||
|
||||
private void SpawnChemicalsFromComposition(EntityUid reclaimer,
|
||||
|
|
|
|||
|
|
@ -224,11 +224,13 @@ public sealed partial class MaterialStorageSystem : SharedMaterialStorageSystem
|
|||
/// <param name="entity">The entity with storage to eject from.</param>
|
||||
/// <param name="coordinates">The position where to spawn the created sheets. If not given, they're spawned next to the entity.</param>
|
||||
/// <param name="component">The storage component on <paramref name="entity"/>. Resolved automatically if not given.</param>
|
||||
/// <param name="mergeContacts">If true, spawned stacks will attempt to merge with existing stacks in the area.</param>
|
||||
/// <returns>The stack entities that were spawned.</returns>
|
||||
public List<EntityUid> EjectAllMaterial(
|
||||
EntityUid entity,
|
||||
EntityCoordinates? coordinates = null,
|
||||
MaterialStorageComponent? component = null)
|
||||
MaterialStorageComponent? component = null,
|
||||
bool mergeContacts = false)
|
||||
{
|
||||
if (!Resolve(entity, ref component))
|
||||
return new List<EntityUid>();
|
||||
|
|
@ -242,6 +244,14 @@ public sealed partial class MaterialStorageSystem : SharedMaterialStorageSystem
|
|||
allSpawned.AddRange(spawned);
|
||||
}
|
||||
|
||||
if (mergeContacts)
|
||||
{
|
||||
foreach (var stack in allSpawned)
|
||||
{
|
||||
_stackSystem.TryMergeToContacts(stack);
|
||||
}
|
||||
}
|
||||
|
||||
return allSpawned;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
26
Content.Server/Materials/ServerTileReclaimerSystem.cs
Normal file
26
Content.Server/Materials/ServerTileReclaimerSystem.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using Content.Shared.Materials;
|
||||
using Content.Shared.Maps;
|
||||
|
||||
namespace Content.Server.Materials;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public sealed partial class ServerTileReclaimerSystem : TileReclaimerSystem
|
||||
{
|
||||
[Dependency] private MaterialStorageSystem _materialStorage = default!;
|
||||
|
||||
protected override void SpawnMaterialsFromComposition(Entity<MaterialStorageComponent?, TransformComponent?> ent,
|
||||
ContentTileDefinition tileDefinition,
|
||||
float efficiency)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp1, ref ent.Comp2))
|
||||
return;
|
||||
|
||||
foreach (var (material, amount) in tileDefinition.MaterialComposition)
|
||||
{
|
||||
var outputAmount = (int) (amount * efficiency);
|
||||
_materialStorage.TryChangeMaterialAmount(ent, material, outputAmount, ent.Comp1);
|
||||
}
|
||||
|
||||
_materialStorage.EjectAllMaterial(ent, ent.Comp2.Coordinates, ent.Comp1, true);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Materials;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Shuttles.Systems;
|
||||
using Content.Shared.Tools;
|
||||
|
|
@ -132,6 +133,12 @@ public sealed partial class ContentTileDefinition : IPrototype, IInheritingProto
|
|||
/// </summary>
|
||||
[DataField] public bool EditorHidden { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// If this tile is reclaimed, what materials would come out of it?
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Dictionary<ProtoId<MaterialPrototype>, int> MaterialComposition = new();
|
||||
|
||||
public void AssignTileId(ushort id)
|
||||
{
|
||||
TileId = id;
|
||||
|
|
|
|||
77
Content.Shared/Materials/TileReclaimerComponent.cs
Normal file
77
Content.Shared/Materials/TileReclaimerComponent.cs
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
using Content.Shared.Maps;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared.Materials;
|
||||
|
||||
/// <summary>
|
||||
/// Makes an entity into a grid reclaimer, able to delete grids in front of it and produce materials.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(fieldDeltas: true), AutoGenerateComponentPause]
|
||||
[Access(typeof(TileReclaimerSystem))]
|
||||
public sealed partial class TileReclaimerComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// An "enable" toggle for things like interfacing with machine linking.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Enabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// A master control for whether or not the reclaimer is broken and can function.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Broken;
|
||||
|
||||
/// <summary>
|
||||
/// A whitelist for what grid entities can be affected by this reclaimer.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityWhitelist? Whitelist;
|
||||
|
||||
/// <summary>
|
||||
/// A whitelist for what grid entities can be affected by this reclaimer.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public EntityWhitelist? Blacklist;
|
||||
|
||||
/// <summary>
|
||||
/// The delay after a grid has been consumed that it can recycle again.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public TimeSpan RecycleDelay = TimeSpan.FromSeconds(0.3f);
|
||||
|
||||
/// <summary>
|
||||
/// The bounding box in local coordinates for where it will check for grids to reclaim.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public Box2 RecyclingBox = new(-0.5f, 0.5f, 0.5f, 1.5f);
|
||||
|
||||
/// <summary>
|
||||
/// Multiplier for the material being extracted from the tile, as defined in the tile's <see cref="ContentTileDefinition.MaterialComposition"/>
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public float Efficiency = 1f;
|
||||
|
||||
/// <summary>
|
||||
/// How strong impulse the reclaimer should apply to a grid after it has destroyed one of it tiles.
|
||||
/// This helps guide the grid further into the reclaimer.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public float SlurpStrength = 1600f;
|
||||
|
||||
/// <summary>
|
||||
/// Next time a recycling attempt can be made.
|
||||
/// </summary>
|
||||
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadOnly)]
|
||||
[AutoNetworkedField, AutoPausedField]
|
||||
public TimeSpan NextRecycle;
|
||||
|
||||
/// <summary>
|
||||
/// The sound played when something is being processed.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public SoundSpecifier? Sound;
|
||||
}
|
||||
141
Content.Shared/Materials/TileReclaimerSystem.cs
Normal file
141
Content.Shared/Materials/TileReclaimerSystem.cs
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
using Content.Shared.Conveyor;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Shared.Materials;
|
||||
|
||||
/// <summary>
|
||||
/// Handles interactions and logic related to <see cref="TileReclaimerComponent"/>.
|
||||
/// </summary>
|
||||
public abstract partial class TileReclaimerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private SharedAudioSystem _audio = default!;
|
||||
[Dependency] private SharedTransformSystem _transform = default!;
|
||||
[Dependency] private IGameTiming _timing = default!;
|
||||
[Dependency] private SharedMapSystem _mapSystem = default!;
|
||||
[Dependency] private SharedPhysicsSystem _physics = default!;
|
||||
[Dependency] private EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private TurfSystem _turf = default!;
|
||||
[Dependency] private EntityWhitelistSystem _whitelist = default!;
|
||||
|
||||
[Dependency] private EntityQuery<PhysicsComponent> _physicsComponentQuery = default!;
|
||||
|
||||
[SubscribeLocalEvent]
|
||||
private void OnMapInit(Entity<TileReclaimerComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
ent.Comp.NextRecycle = _timing.CurTime + ent.Comp.RecycleDelay;
|
||||
DirtyField(ent.Owner, ent.Comp, nameof(TileReclaimerComponent.NextRecycle));
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
var query = EntityQueryEnumerator<TileReclaimerComponent, TransformComponent>();
|
||||
while (query.MoveNext(out var uid, out var tileReclaimer, out var xform))
|
||||
{
|
||||
if (tileReclaimer.NextRecycle > _timing.CurTime)
|
||||
return;
|
||||
|
||||
Update((uid, tileReclaimer, xform));
|
||||
}
|
||||
}
|
||||
|
||||
private void Update(Entity<TileReclaimerComponent, TransformComponent> ent)
|
||||
{
|
||||
ent.Comp1.NextRecycle += ent.Comp1.RecycleDelay;
|
||||
DirtyField(ent.Owner, ent.Comp1, nameof(TileReclaimerComponent.NextRecycle));
|
||||
|
||||
//TODO: The recycler is hardcoded to rely on the conveyor component for its powered state, and this system is based on the same functionality. That should be fixed into a more general solution for both systems, but for the sake of consistency I'm not doing that now.
|
||||
if (!TryComp<ConveyorComponent>(ent, out var conveyor) || conveyor.State == ConveyorState.Off)
|
||||
return;
|
||||
|
||||
var reclaimerGrid = _transform.GetGrid((ent, ent));
|
||||
|
||||
if (reclaimerGrid == null)
|
||||
return;
|
||||
|
||||
var mapPos = _transform.GetMapCoordinates(ent);
|
||||
|
||||
var grids = new List<Entity<MapGridComponent>>();
|
||||
|
||||
var entMatrix = _transform.GetWorldMatrix(ent.Owner);
|
||||
var box = entMatrix.TransformBox(ent.Comp1.RecyclingBox);
|
||||
|
||||
_mapSystem.FindGridsIntersecting(mapPos.MapId, box, ref grids);
|
||||
|
||||
var shredded = false;
|
||||
|
||||
foreach (var grid in grids)
|
||||
{
|
||||
if (TerminatingOrDeleted(grid) || EntityManager.IsQueuedForDeletion(grid))
|
||||
continue;
|
||||
|
||||
if (grid == reclaimerGrid)
|
||||
continue;
|
||||
|
||||
if (!_whitelist.CheckBoth(grid, ent.Comp1.Blacklist, ent.Comp1.Whitelist))
|
||||
continue;
|
||||
|
||||
var intersectingEntities = new HashSet<EntityUid>();
|
||||
|
||||
foreach (var tile in _mapSystem.GetTilesIntersecting(grid.Owner, grid.Comp, box))
|
||||
{
|
||||
var tileDef = _turf.GetContentTileDefinition(tile);
|
||||
if (tileDef.Indestructible)
|
||||
continue;
|
||||
|
||||
intersectingEntities.Clear();
|
||||
_lookup.GetLocalEntitiesIntersecting(tile.GridUid, tile.GridIndices, intersectingEntities);
|
||||
|
||||
foreach (var entityOnTile in intersectingEntities)
|
||||
{
|
||||
if (!_physicsComponentQuery.TryComp(entityOnTile, out var physicsComp))
|
||||
{
|
||||
// Marker/Spawn entities and similar don't have physics, so we just plain remove them.
|
||||
QueueDel(entityOnTile);
|
||||
continue;
|
||||
}
|
||||
|
||||
_physics.SetCanCollide(entityOnTile, true, body: physicsComp);
|
||||
_physics.ApplyLinearImpulse(entityOnTile, _physics.GetLinearVelocity(grid.Owner, Transform(entityOnTile).LocalPosition), body: physicsComp);
|
||||
}
|
||||
|
||||
_mapSystem.SetTile(tile.GridUid, grid, tile.GridIndices, Tile.Empty);
|
||||
// TODO: Ideally this should be using tilestacking to get materials out of every tile in the stack, as opposed to the top one. Not doing it right now as it may be reworked however.
|
||||
SpawnMaterialsFromComposition((ent, null, ent.Comp2), tileDef, ent.Comp1.Efficiency);
|
||||
shredded = true;
|
||||
|
||||
// If it was the last tile, grid's probably gone
|
||||
if (TerminatingOrDeleted(grid))
|
||||
continue;
|
||||
|
||||
// We suck in the grid slurrrrp
|
||||
// TODO: This can probably be refined, as it applies a stacking speed which could theoretically get out of hand if a grid is very long.
|
||||
_physics.ApplyLinearImpulse(grid, ent.Comp1.SlurpStrength * _transform.GetWorldRotation(ent.Comp2).ToWorldVec(), tile.GridIndices);
|
||||
}
|
||||
}
|
||||
|
||||
if (!shredded)
|
||||
return;
|
||||
|
||||
_audio.PlayPvs(ent.Comp1.Sound, ent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spawns materials from the <see cref="ContentTileDefinition.MaterialComposition"/> of the given tile.
|
||||
/// </summary>
|
||||
/// <param name="ent">Entity performing the spawning action.</param>
|
||||
/// <param name="tileDefinition">Tile definition of the tile being reclaimed.</param>
|
||||
/// <param name="efficiency">Multiplier of the material amount.</param>
|
||||
protected virtual void SpawnMaterialsFromComposition(Entity<MaterialStorageComponent?, TransformComponent?> ent,
|
||||
ContentTileDefinition tileDefinition,
|
||||
float efficiency)
|
||||
{
|
||||
// Handled on the server because that's where MaterialStorageSystem is.
|
||||
}
|
||||
}
|
||||
|
|
@ -276,3 +276,8 @@
|
|||
copyright: "by petercornell (Freesound), sampled and sped up to 400% by whatston3 (GitHub)"
|
||||
license: "CC0-1.0"
|
||||
source: https://freesound.org/people/petercornell/sounds/837240/
|
||||
|
||||
- files: ["grind.ogg"]
|
||||
copyright: 'modified by SlamBamActionman (Github) from "01-1 Angle Grinder.wav" by domiscz of Freesound.org'
|
||||
license: "CC-BY-SA-3.0"
|
||||
source: https://freesound.org/people/domiscz/sounds/461728/
|
||||
|
|
|
|||
BIN
Resources/Audio/Effects/grind.ogg
Normal file
BIN
Resources/Audio/Effects/grind.ogg
Normal file
Binary file not shown.
|
|
@ -81,6 +81,9 @@
|
|||
interfaces:
|
||||
enum.DeimplantUiKey.Key:
|
||||
type: DeimplantBoundUserInterface
|
||||
- type: Tag
|
||||
tags:
|
||||
- SmeltingImmune
|
||||
|
||||
- type: entity
|
||||
id: Implanter
|
||||
|
|
@ -153,7 +156,8 @@
|
|||
True: {state: broken}
|
||||
False: {state: implanter1}
|
||||
- type: Tag
|
||||
tags: []
|
||||
tags:
|
||||
- SmeltingImmune
|
||||
|
||||
#Fun implanters
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
!type:PhysShapeAabb
|
||||
bounds: "-0.45,-0.45,0.45,0.45"
|
||||
density: 5
|
||||
mask:
|
||||
- LowImpassable
|
||||
layer:
|
||||
- DoorPassable
|
||||
- type: Damageable
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
collection: GlassSmash
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: Pullable
|
||||
- type: Clickable
|
||||
- type: InteractionOutline
|
||||
- type: Sprite
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@
|
|||
arrows:
|
||||
- offset: 0, -1.35
|
||||
- offset: 0, 0
|
||||
|
||||
- type: CollideMaterialReclaimer
|
||||
- type: MaterialReclaimer
|
||||
enabled: false
|
||||
|
|
@ -132,3 +131,136 @@
|
|||
- type: Speech
|
||||
speechVerb: Robotic
|
||||
speechSounds: SyndieBorg
|
||||
|
||||
- type: entity
|
||||
parent: [ BaseMachinePowered, StructureHealthMachineStrong ]
|
||||
id: IndustrialSmelter
|
||||
name: industrial smelter
|
||||
suffix: Do Not Map
|
||||
description: A massive stationary machine capable of chewing through flooring and walls. Must be powered to function.
|
||||
components:
|
||||
- type: Sprite
|
||||
drawdepth: Doors
|
||||
sprite: Structures/Machines/smelter.rsi
|
||||
layers:
|
||||
- state: smelter0
|
||||
map: ["enum.RecyclerVisualLayers.Main"]
|
||||
offset: 0, 0.5
|
||||
- type: Appearance
|
||||
- type: RecyclerVisuals
|
||||
baseKey: smelter
|
||||
- type: Conveyor
|
||||
angle: 90 # Conveyor goes sideways
|
||||
- type: DeviceLinkSink
|
||||
ports:
|
||||
- Reverse
|
||||
- Forward
|
||||
- Off
|
||||
- type: MaterialStorage
|
||||
insertOnInteract: false
|
||||
- type: CollideMaterialReclaimer
|
||||
- type: MaterialReclaimer
|
||||
enabled: false
|
||||
scaleProcessSpeed: false
|
||||
minimumProcessDuration: 0
|
||||
efficiency: 0.1
|
||||
blacklist: # TODO: This will need to be iterated on to properly balance all items
|
||||
components:
|
||||
- Material
|
||||
- Pda
|
||||
- IdCard
|
||||
- GrapplingProjectile
|
||||
- Circuitboard
|
||||
- Computer
|
||||
tags:
|
||||
- HighRiskItem
|
||||
- SmeltingImmune
|
||||
sound:
|
||||
path: /Audio/Effects/saw.ogg
|
||||
params:
|
||||
volume: -3
|
||||
cutOffSound: false
|
||||
- type: TileReclaimer
|
||||
sound:
|
||||
path: /Audio/Effects/grind.ogg # TODO: Needs more CRONCH, more SMELT
|
||||
params:
|
||||
volume: -3
|
||||
recyclingBox: "-0.35, 0.5, 0.35, 1"
|
||||
blacklist:
|
||||
components:
|
||||
- StationMember
|
||||
- CargoShuttle
|
||||
- ArrivalsShuttle
|
||||
- EmergencyShuttle
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
brrt:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.5, -0.15, 0.5, 1.5"
|
||||
hard: false
|
||||
layer:
|
||||
- FullTileLayer
|
||||
- DoorPassable # Here to hit floor objects like carpets etc.
|
||||
mask:
|
||||
- FullTileMask # Necessary for grilles.
|
||||
- TabletopMachineLayer # This is needed for lights.
|
||||
collision:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.49,-0.49,0.49,0.49"
|
||||
hard: true
|
||||
mask:
|
||||
- Impassable
|
||||
layer:
|
||||
- Opaque
|
||||
- BulletImpassable
|
||||
conveyor:
|
||||
shape: !type:PolygonShape
|
||||
vertices:
|
||||
- -0.55,-0.55
|
||||
- 0.55,-0.55
|
||||
- 0.55,0.55
|
||||
- -0.55,0.55
|
||||
layer:
|
||||
- Impassable
|
||||
- MidImpassable
|
||||
- LowImpassable
|
||||
hard: False
|
||||
- type: AmbientSound
|
||||
enabled: false
|
||||
volume: -8
|
||||
range: 5
|
||||
sound:
|
||||
path: /Audio/Ambience/Objects/circular_saw.ogg
|
||||
- type: Transform
|
||||
anchored: true
|
||||
noRot: false
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger:
|
||||
!type:DamageTrigger
|
||||
damage: 200
|
||||
behaviors:
|
||||
- !type:DoActsBehavior
|
||||
acts: ["Breakage"]
|
||||
- !type:PlaySoundBehavior
|
||||
sound:
|
||||
collection: MetalBreak
|
||||
- type: Repairable
|
||||
doAfterDelay: 5
|
||||
fuelCost: 25
|
||||
- type: Tag
|
||||
tags:
|
||||
- EmagImmune
|
||||
- type: Speech
|
||||
speechVerb: Robotic
|
||||
speechSounds: SyndieBorg
|
||||
|
||||
- type: entity
|
||||
parent: IndustrialSmelter
|
||||
id: IndustrialSmelterAdmeme
|
||||
suffix: No Grid Whitelist, Admeme
|
||||
components:
|
||||
- type: TileReclaimer
|
||||
blacklist: null
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
components:
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: Pullable
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
- type: Sprite
|
||||
|
|
@ -19,6 +20,8 @@
|
|||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.5,-0.5,0.5,0.5"
|
||||
mask:
|
||||
- DoorPassable
|
||||
- type: Airtight
|
||||
noAirWhenFullyAirBlocked: false
|
||||
- type: Clickable
|
||||
|
|
@ -35,6 +38,7 @@
|
|||
components:
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: Pullable
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
- type: Sprite
|
||||
|
|
@ -46,6 +50,8 @@
|
|||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.48,-0.48,0.48,-0.40"
|
||||
mask:
|
||||
- DoorPassable
|
||||
- type: Airtight
|
||||
noAirWhenFullyAirBlocked: false
|
||||
airBlockedDirection:
|
||||
|
|
|
|||
|
|
@ -129,6 +129,15 @@
|
|||
guides:
|
||||
- VoltageNetworks
|
||||
- Power
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.25,-0.45,0.25,0.05"
|
||||
density: 5
|
||||
mask:
|
||||
- FullTileMask
|
||||
|
||||
# APC under construction
|
||||
- type: entity
|
||||
|
|
|
|||
|
|
@ -132,13 +132,11 @@
|
|||
|
||||
# Compact Wall Substation Base
|
||||
- type: entity
|
||||
parent: [ CoreSubstation, StructureHealthMachine ]
|
||||
parent: [ CoreSubstation, BaseWallmount, StructureHealthMachine ]
|
||||
id: BaseSubstationWall
|
||||
categories: [ HideSpawnMenu ]
|
||||
name: wallmount substation
|
||||
description: A substation designed for compact shuttles and spaces.
|
||||
placement:
|
||||
mode: SnapgridCenter
|
||||
components:
|
||||
- type: AmbientSound
|
||||
range: 2
|
||||
|
|
@ -149,20 +147,12 @@
|
|||
netsync: false
|
||||
castShadows: false
|
||||
offset: 0, -0.2
|
||||
- type: Clickable
|
||||
- type: ContainerFill
|
||||
containers:
|
||||
board: [ WallmountSubstationElectronics ]
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
board: !type:Container
|
||||
- type: InteractionOutline
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
canCollide: false
|
||||
- type: Fixtures
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: Sprite # TODO: add sprite for maintenance panel open
|
||||
drawdepth: WallMountedItems
|
||||
sprite: Structures/Power/substation.rsi
|
||||
|
|
@ -196,7 +186,15 @@
|
|||
maxIntensity: 50
|
||||
intensitySlope: 2
|
||||
totalIntensity: 100
|
||||
- type: WallMount
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.35,-0.45,0.35,0.20"
|
||||
density: 5
|
||||
mask:
|
||||
- FullTileMask
|
||||
|
||||
# Substations in use
|
||||
|
||||
|
|
|
|||
|
|
@ -171,6 +171,15 @@
|
|||
- entity_storage
|
||||
- type: Paintable
|
||||
group: WallCloset
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.25,-0.35,0.25,0.35"
|
||||
density: 5
|
||||
mask:
|
||||
- FullTileMask
|
||||
|
||||
#Wall locker
|
||||
- type: entity
|
||||
|
|
|
|||
|
|
@ -97,8 +97,6 @@
|
|||
- type: DeviceLinkSource
|
||||
ports:
|
||||
- Pressed
|
||||
- type: Transform
|
||||
anchored: false
|
||||
- type: Destructible
|
||||
thresholds:
|
||||
- trigger: *DamageMachineFlimsy
|
||||
|
|
@ -493,7 +491,18 @@
|
|||
sprite: Structures/Wallmounts/switch-frame.rsi
|
||||
state: grey
|
||||
- type: Rotatable
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: Pullable
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.45,-0.45,0.45,0.45"
|
||||
density: 5
|
||||
mask:
|
||||
- FullTileMask
|
||||
|
||||
- type: entity
|
||||
id: ButtonFrameGrey
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
- type: Rotatable
|
||||
- type: Physics
|
||||
canCollide: false
|
||||
- type: Fixtures
|
||||
- type: Clickable
|
||||
- type: WallMount
|
||||
- type: InteractionOutline
|
||||
|
|
@ -23,6 +22,16 @@
|
|||
- Structure
|
||||
- type: Sprite
|
||||
drawdepth: WallMountedItems
|
||||
- type: Pullable
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.45,-0.45,0.45,0.45"
|
||||
density: 5
|
||||
mask:
|
||||
- FullTileMask
|
||||
|
||||
- type: entity
|
||||
abstract: true
|
||||
|
|
|
|||
|
|
@ -160,7 +160,17 @@
|
|||
graph: Grille
|
||||
node: grilleBroken
|
||||
deconstructionTarget: start
|
||||
- type: Fixtures # overwrite BaseStructure parent.
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.5,-0.5,0.5,-0.28125"
|
||||
density: 5
|
||||
mask:
|
||||
- DoorPassable
|
||||
layer:
|
||||
- DoorPassable
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
canCollide: false
|
||||
|
|
|
|||
|
|
@ -321,6 +321,9 @@
|
|||
density: 4000
|
||||
- type: RadiationBlocker
|
||||
resistance: 5
|
||||
- type: Tag
|
||||
tags:
|
||||
- SmeltingImmune
|
||||
|
||||
- type: entity
|
||||
parent: [ WallPlastitaniumIndestructible, StructureHealthWallStrong ]
|
||||
|
|
@ -353,6 +356,10 @@
|
|||
state: state0
|
||||
- type: RadiationBlocker
|
||||
resistance: 5
|
||||
- type: Tag
|
||||
tags:
|
||||
- Diagonal
|
||||
- SmeltingImmune
|
||||
|
||||
- type: entity
|
||||
parent: [ WallPlastitaniumDiagonalIndestructible, StructureHealthWallStrong ]
|
||||
|
|
|
|||
|
|
@ -86,6 +86,11 @@
|
|||
components:
|
||||
- type: ExaminableDamage
|
||||
messages: null
|
||||
- type: Tag
|
||||
tags:
|
||||
- ForceFixRotations
|
||||
- Window
|
||||
- SmeltingImmune
|
||||
|
||||
- type: entity
|
||||
parent: [ PlastitaniumWindowSquareBase, StructureHealthBarrierStrong ]
|
||||
|
|
@ -171,6 +176,11 @@
|
|||
components:
|
||||
- type: ExaminableDamage
|
||||
messages: null
|
||||
- type: Tag
|
||||
tags:
|
||||
- ForceFixRotations
|
||||
- Window
|
||||
- SmeltingImmune
|
||||
|
||||
- type: entity
|
||||
id: PlastitaniumWindowDiagonal
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# TODO move this to tiles once tile smoothing is supported
|
||||
- type: entity
|
||||
parent: StructureHealthFurniture
|
||||
parent: [ BaseStructure, StructureHealthFurniture ]
|
||||
id: Catwalk
|
||||
name: catwalk
|
||||
description: A catwalk for easier EVA maneuvering and cable placement.
|
||||
|
|
@ -17,8 +17,6 @@
|
|||
- type: Icon
|
||||
sprite: Structures/catwalk.rsi
|
||||
state: catwalk_preview
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: IconSmooth
|
||||
key: catwalk
|
||||
base: catwalk_
|
||||
|
|
@ -51,3 +49,16 @@
|
|||
cost: 2
|
||||
delay: 2
|
||||
fx: EffectRCDDeconstruct2
|
||||
- type: Physics
|
||||
canCollide: false
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeAabb
|
||||
bounds: "-0.45,-0.45,0.45,0.45"
|
||||
density: 5
|
||||
mask:
|
||||
- LowImpassable
|
||||
layer:
|
||||
- DoorPassable
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
- FloorDirt
|
||||
- PlatingRCD
|
||||
- FloorHullReinforced
|
||||
materialComposition:
|
||||
Steel: 100 # 0.5 for lattice, 0.25 for plating, 0.25 for tile
|
||||
|
||||
- type: tile
|
||||
id: FloorSteelCheckerLight
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
isSubfloor: true
|
||||
footstepSounds:
|
||||
collection: FootstepPlating
|
||||
materialComposition:
|
||||
Steel: 75 # 0.75 sheets; 0.5 for the lattice, 0.25 for the tile
|
||||
baseTurf: Lattice
|
||||
|
||||
- type: tile
|
||||
|
|
@ -77,3 +79,5 @@
|
|||
heatCapacity: 10000
|
||||
mass: 200
|
||||
variants: 3
|
||||
materialComposition:
|
||||
Steel: 50 # 0.5 sheets = 1 rod
|
||||
|
|
|
|||
|
|
@ -1289,6 +1289,9 @@
|
|||
- type: Tag
|
||||
id: Shiv # CargoBounty: BountyShiv
|
||||
|
||||
- type: Tag
|
||||
id: SmeltingImmune # for entities that should not be deleted industrial smelter's MaterialReclaimer
|
||||
|
||||
- type: Tag
|
||||
id: Sidearm # Storage whitelist: ClothingBeltSecurity, ClothingShoesMilitaryBase
|
||||
|
||||
|
|
|
|||
39
Resources/Textures/Structures/Machines/smelter.rsi/meta.json
Normal file
39
Resources/Textures/Structures/Machines/smelter.rsi/meta.json
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Smelter sprites by SlamBamActionman (Github)",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 64
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "smelter0"
|
||||
},
|
||||
{
|
||||
"name": "smelter1",
|
||||
"delays": [
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "smelter1-0",
|
||||
"delays": [
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "smelter2"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
Resources/Textures/Structures/Machines/smelter.rsi/smelter0.png
Normal file
BIN
Resources/Textures/Structures/Machines/smelter.rsi/smelter0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
Resources/Textures/Structures/Machines/smelter.rsi/smelter1.png
Normal file
BIN
Resources/Textures/Structures/Machines/smelter.rsi/smelter1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
Resources/Textures/Structures/Machines/smelter.rsi/smelter2.png
Normal file
BIN
Resources/Textures/Structures/Machines/smelter.rsi/smelter2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Loading…
Add table
Reference in a new issue