using Content.Client.Items;
+using Content.Client.Storage.Systems;
using Content.Shared.Stacks;
using JetBrains.Annotations;
+using Robust.Client.GameObjects;
namespace Content.Client.Stack
{
[UsedImplicitly]
public sealed class StackSystem : SharedStackSystem
{
+ [Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
+ [Dependency] private readonly ItemCounterSystem _counterSystem = default!;
+
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<StackComponent, ItemStatusCollectMessage>(OnItemStatus);
+ SubscribeLocalEvent<StackComponent, AppearanceChangeEvent>(OnAppearanceChange);
}
private void OnItemStatus(EntityUid uid, StackComponent component, ItemStatusCollectMessage args)
if (component is StackComponent clientComp)
clientComp.UiUpdateNeeded = true;
}
+
+ private void OnAppearanceChange(EntityUid uid, StackComponent comp, ref AppearanceChangeEvent args)
+ {
+ if (args.Sprite == null || comp.LayerStates.Count < 1)
+ return;
+
+ // Skip processing if no actual
+ if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.Actual, out var actual, args.Component))
+ return;
+
+ if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.MaxCount, out var maxCount, args.Component))
+ maxCount = comp.LayerStates.Count;
+
+ if (!_appearanceSystem.TryGetData<bool>(uid, StackVisuals.Hide, out var hidden, args.Component))
+ hidden = false;
+
+ if (comp.IsComposite)
+ _counterSystem.ProcessCompositeSprite(uid, actual, maxCount, comp.LayerStates, hidden, sprite: args.Sprite);
+ else
+ _counterSystem.ProcessOpaqueSprite(uid, comp.BaseLayer, actual, maxCount, comp.LayerStates, hidden, sprite: args.Sprite);
+ }
}
}
+++ /dev/null
-
-using System.Collections.Generic;
-using Content.Shared.Rounding;
-using Content.Shared.Stacks;
-using JetBrains.Annotations;
-using Robust.Client.GameObjects;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
-using Robust.Shared.Serialization.Manager.Attributes;
-using Robust.Shared.Utility;
-
-namespace Content.Client.Stack
-{
- /// <summary>
- /// Visualizer for items that come in stacks and have different appearance
- /// depending on the size of the stack. Visualizer can work by switching between different
- /// icons in <c>_spriteLayers</c> or if the sprite layers are supposed to be composed as transparent layers.
- /// The former behavior is default and the latter behavior can be defined in prototypes.
- ///
- /// <example>
- /// <para>To define a Stack Visualizer prototype insert the following
- /// snippet (you can skip Appearance if already defined)
- /// </para>
- /// <code>
- /// - type: Appearance
- /// visuals:
- /// - type: StackVisualizer
- /// stackLayers:
- /// - goldbar_10
- /// - goldbar_20
- /// - goldbar_30
- /// </code>
- /// </example>
- /// <example>
- /// <para>Defining a stack visualizer with composable transparent layers</para>
- /// <code>
- /// - type: StackVisualizer
- /// composite: true
- /// stackLayers:
- /// - cigarette_1
- /// - cigarette_2
- /// - cigarette_3
- /// - cigarette_4
- /// - cigarette_5
- /// - cigarette_6
- /// </code>
- /// </example>
- /// <seealso cref="_spriteLayers"/>
- /// </summary>
- [UsedImplicitly]
- public sealed class StackVisualizer : AppearanceVisualizer
- {
- /// <summary>
- /// Default IconLayer stack.
- /// </summary>
- private const int IconLayer = 0;
-
- /// <summary>
- /// Sprite layers used in stack visualizer. Sprites first in layer correspond to lower stack states
- /// e.g. <code>_spriteLayers[0]</code> is lower stack level than <code>_spriteLayers[1]</code>.
- /// </summary>
- [DataField("stackLayers")] private readonly List<string> _spriteLayers = new();
-
- /// <summary>
- /// Determines if the visualizer uses composite or non-composite layers for icons. Defaults to false.
- ///
- /// <list type="bullet">
- /// <item>
- /// <description>false: they are opaque and mutually exclusive (e.g. sprites in a cable coil). <b>Default value</b></description>
- /// </item>
- /// <item>
- /// <description>true: they are transparent and thus layered one over another in ascending order first</description>
- /// </item>
- /// </list>
- ///
- /// </summary>
- [DataField("composite")] private bool _isComposite;
-
- [DataField("sprite")] private ResPath? _spritePath;
-
- [Obsolete("Subscribe to your component being initialised instead.")]
- public override void InitializeEntity(EntityUid entity)
- {
- base.InitializeEntity(entity);
-
- if (_isComposite
- && _spriteLayers.Count > 0
- && IoCManager.Resolve<IEntityManager>().TryGetComponent<SpriteComponent?>(entity, out var spriteComponent))
- {
- var spritePath = _spritePath ?? spriteComponent.BaseRSI!.Path!;
-
- foreach (var sprite in _spriteLayers)
- {
- spriteComponent.LayerMapReserveBlank(sprite);
- spriteComponent.LayerSetSprite(sprite, new SpriteSpecifier.Rsi(spritePath, sprite));
- spriteComponent.LayerSetVisible(sprite, false);
- }
- }
- }
-
- [Obsolete("Subscribe to AppearanceChangeEvent instead.")]
- public override void OnChangeData(AppearanceComponent component)
- {
- base.OnChangeData(component);
-
- var entities = IoCManager.Resolve<IEntityManager>();
- if (entities.TryGetComponent(component.Owner, out SpriteComponent? spriteComponent))
- {
- if (_isComposite)
- {
- ProcessCompositeSprites(component, spriteComponent);
- }
- else
- {
- ProcessOpaqueSprites(component, spriteComponent);
- }
- }
- }
-
- private void ProcessOpaqueSprites(AppearanceComponent component, SpriteComponent spriteComponent)
- {
- // Skip processing if no actual
- if (!component.TryGetData<int>(StackVisuals.Actual, out var actual)) return;
- if (!component.TryGetData<int>(StackVisuals.MaxCount, out var maxCount))
- {
- maxCount = _spriteLayers.Count;
- }
-
- var activeLayer = ContentHelpers.RoundToEqualLevels(actual, maxCount, _spriteLayers.Count);
- spriteComponent.LayerSetState(IconLayer, _spriteLayers[activeLayer]);
- }
-
- private void ProcessCompositeSprites(AppearanceComponent component, SpriteComponent spriteComponent)
- {
- // If hidden, don't render any sprites
- if (component.TryGetData<bool>(StackVisuals.Hide, out var hide)
- && hide)
- {
- foreach (var transparentSprite in _spriteLayers)
- {
- spriteComponent.LayerSetVisible(transparentSprite, false);
- }
-
- return;
- }
-
- // Skip processing if no actual/maxCount
- if (!component.TryGetData<int>(StackVisuals.Actual, out var actual)) return;
- if (!component.TryGetData<int>(StackVisuals.MaxCount, out var maxCount))
- {
- maxCount = _spriteLayers.Count;
- }
-
-
- var activeTill = ContentHelpers.RoundToNearestLevels(actual, maxCount, _spriteLayers.Count);
- for (var i = 0; i < _spriteLayers.Count; i++)
- {
- spriteComponent.LayerSetVisible(_spriteLayers[i], i < activeTill);
- }
- }
- }
-}
--- /dev/null
+using Content.Shared.Rounding;
+using Content.Shared.Stacks;
+using Content.Shared.Storage.Components;
+using Content.Shared.Storage.EntitySystems;
+using Robust.Client.GameObjects;
+using Robust.Shared.Containers;
+
+namespace Content.Client.Storage.Systems;
+
+public sealed class ItemCounterSystem : SharedItemCounterSystem
+{
+ [Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent<ItemCounterComponent, AppearanceChangeEvent>(OnAppearanceChange);
+ }
+
+ private void OnAppearanceChange(EntityUid uid, ItemCounterComponent comp, ref AppearanceChangeEvent args)
+ {
+ if (args.Sprite == null || comp.LayerStates.Count < 1)
+ return;
+
+ // Skip processing if no actual
+ if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.Actual, out var actual, args.Component))
+ return;
+
+ if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.MaxCount, out var maxCount, args.Component))
+ maxCount = comp.LayerStates.Count;
+
+ if (!_appearanceSystem.TryGetData<bool>(uid, StackVisuals.Hide, out var hidden, args.Component))
+ hidden = false;
+
+ if (comp.IsComposite)
+ ProcessCompositeSprite(uid, actual, maxCount, comp.LayerStates, hidden, sprite: args.Sprite);
+ else
+ ProcessOpaqueSprite(uid, comp.BaseLayer, actual, maxCount, comp.LayerStates, hidden, sprite: args.Sprite);
+ }
+
+ public void ProcessOpaqueSprite(EntityUid uid, string layer, int count, int maxCount, List<string> states, bool hide = false, SpriteComponent? sprite = null)
+ {
+ if (!Resolve(uid, ref sprite)
+ || !sprite.LayerMapTryGet(layer, out var layerKey, logError: true))
+ return;
+
+ var activeState = ContentHelpers.RoundToEqualLevels(count, maxCount, states.Count);
+ sprite.LayerSetState(layerKey, states[activeState]);
+ sprite.LayerSetVisible(layerKey, !hide);
+ }
+
+ public void ProcessCompositeSprite(EntityUid uid, int count, int maxCount, List<string> layers, bool hide = false, SpriteComponent? sprite = null)
+ {
+ if(!Resolve(uid, ref sprite))
+ return;
+
+ var activeTill = ContentHelpers.RoundToNearestLevels(count, maxCount, layers.Count);
+ for(var i = 0; i < layers.Count; ++i)
+ {
+ sprite.LayerSetVisible(layers[i], !hide && i < activeTill);
+ }
+ }
+
+ protected override int? GetCount(ContainerModifiedMessage msg, ItemCounterComponent itemCounter)
+ {
+ if (_appearanceSystem.TryGetData<int>(msg.Container.Owner, StackVisuals.Actual, out var actual))
+ return actual;
+ return null;
+ }
+}
[ViewVariables]
public bool UiUpdateNeeded { get; set; }
+
+ /// <summary>
+ /// Default IconLayer stack.
+ /// </summary>
+ [DataField("baseLayer")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public string BaseLayer = "";
+
+ /// <summary>
+ /// Determines if the visualizer uses composite or non-composite layers for icons. Defaults to false.
+ ///
+ /// <list type="bullet">
+ /// <item>
+ /// <description>false: they are opaque and mutually exclusive (e.g. sprites in a cable coil). <b>Default value</b></description>
+ /// </item>
+ /// <item>
+ /// <description>true: they are transparent and thus layered one over another in ascending order first</description>
+ /// </item>
+ /// </list>
+ ///
+ /// </summary>
+ [DataField("composite")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public bool IsComposite;
+
+ /// <summary>
+ /// Sprite layers used in stack visualizer. Sprites first in layer correspond to lower stack states
+ /// e.g. <code>_spriteLayers[0]</code> is lower stack level than <code>_spriteLayers[1]</code>.
+ /// </summary>
+ [DataField("layerStates")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public List<string> LayerStates = new();
}
[Serializable, NetSerializable]
[DataField("amount")]
public int? MaxAmount { get; set; }
+
+ /// <summary>
+ /// Default IconLayer stack.
+ /// </summary>
+ [DataField("baseLayer")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public string BaseLayer = "";
+
+ /// <summary>
+ /// Determines if the visualizer uses composite or non-composite layers for icons. Defaults to false.
+ ///
+ /// <list type="bullet">
+ /// <item>
+ /// <description>false: they are opaque and mutually exclusive (e.g. sprites in a cable coil). <b>Default value</b></description>
+ /// </item>
+ /// <item>
+ /// <description>true: they are transparent and thus layered one over another in ascending order first</description>
+ /// </item>
+ /// </list>
+ ///
+ /// </summary>
+ [DataField("composite")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public bool IsComposite;
+
+ /// <summary>
+ /// Sprite layers used in counter visualizer. Sprites first in layer correspond to lower stack states
+ /// e.g. <code>_spriteLayers[0]</code> is lower stack level than <code>_spriteLayers[1]</code>.
+ /// </summary>
+ [DataField("layerStates")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public List<string> LayerStates = new();
}
}
sprite: Objects/Misc/6pack.rsi
layers:
- state: plastic-thingy
+ - state: 6pack1
+ map: ["6pack1"]
+ visible: false
+ - state: 6pack2
+ map: ["6pack2"]
+ visible: false
+ - state: 6pack3
+ map: ["6pack3"]
+ visible: false
+ - state: 6pack4
+ map: ["6pack4"]
+ visible: false
+ - state: 6pack5
+ map: ["6pack5"]
+ visible: false
+ - state: 6pack6
+ map: ["6pack6"]
+ visible: false
- type: Item
size: 6
- type: Storage
- type: ItemCounter
count:
tags: [Cola]
+ composite: true
+ layerStates:
+ - 6pack1
+ - 6pack2
+ - 6pack3
+ - 6pack4
+ - 6pack5
+ - 6pack6
- type: Appearance
- visuals:
- - type: StackVisualizer
- composite: true
- stackLayers:
- - 6pack1
- - 6pack2
- - 6pack3
- - 6pack4
- - 6pack5
- - 6pack6
- type: entity
parent: DrinkCanBaseFull
# Waffles/Pancakes
-# Once StackVisualizer is updated you should be able to mix/match stacks of pancakes.
+# Once StackVisuals is updated you should be able to mix/match stacks of pancakes.
- type: entity
name: pancake
- type: Stack
stackType: Pancake
count: 1
+ composite: true
+ layerStates:
+ - pancakes1
+ - pancakes2
+ - pancakes3
+ - pancakes4
+ - pancakes5
+ - pancakes6
+ - pancakes7
+ - pancakes8
+ - pancakes9
- type: Sprite
state: pancakes1
- # - type: Sprite
- # layers:
- # - state: plate-small
- # - state: pancakes1
+ layers:
+ - state: pancakes1
+ map: ["pancakes1"]
+ visible: false
+ - state: pancakes2
+ map: ["pancakes2"]
+ visible: false
+ - state: pancakes3
+ map: ["pancakes3"]
+ visible: false
+ - state: pancakes4
+ map: ["pancakes4"]
+ visible: false
+ - state: pancakes5
+ map: ["pancakes5"]
+ visible: false
+ - state: pancakes6
+ map: ["pancakes6"]
+ visible: false
+ - state: pancakes7
+ map: ["pancakes7"]
+ visible: false
+ - state: pancakes8
+ map: ["pancakes8"]
+ visible: false
+ - state: pancakes9
+ map: ["pancakes9"]
+ visible: false
- type: Appearance
- visuals:
- - type: StackVisualizer
- composite: true
- stackLayers:
- - pancakes1
- - pancakes2
- - pancakes3
- - pancakes4
- - pancakes5
- - pancakes6
- - pancakes7
- - pancakes8
- - pancakes9
- type: entity
name: blueberry pancake
- type: Stack
stackType: Pancake
count: 1
+ composite: true
+ layerStates:
+ - pancakesbb1
+ - pancakesbb2
+ - pancakesbb3
- type: Sprite
state: pancakesbb1
- # - type: Sprite
- # layers:
- # - state: plate-small
- # - state: pancakesbb1
+ layers:
+ - state: pancakesbb1
+ map: ["pancakesbb1"]
+ visible: false
+ - state: pancakesbb2
+ map: ["pancakesbb2"]
+ visible: false
+ - state: pancakesbb3
+ map: ["pancakesbb3"]
+ visible: false
- type: Appearance
- visuals:
- - type: StackVisualizer
- composite: true
- stackLayers:
- - pancakesbb1
- - pancakesbb2
- - pancakesbb3
- type: entity
name: chocolate chip pancake
- type: Stack
stackType: Pancake
count: 1
+ composite: true
+ layerStates:
+ - pancakescc1
+ - pancakescc2
+ - pancakescc3
- type: Sprite
state: pancakescc1
- # - type: Sprite
- # layers:
- # - state: plate-small
- # - state: pancakescc1
+ layers:
+ - state: pancakescc1
+ map: ["pancakescc1"]
+ visible: false
+ - state: pancakescc2
+ map: ["pancakescc2"]
+ visible: false
+ - state: pancakescc3
+ map: ["pancakescc3"]
+ visible: false
- type: Appearance
- visuals:
- - type: StackVisualizer
- composite: true
- stackLayers:
- - pancakescc1
- - pancakescc2
- - pancakescc3
- type: SolutionContainerManager
solutions:
food:
# Donut
# There is a newer, better version of the donutbox from tgstation included in the
-# donut.rsi. The reason it isn't implemented is it requires a StackVisualizer offsetting
+# donut.rsi. The reason it isn't implemented is it requires a StackVisuals offsetting
# the layer sprite by a couple pixels everytime a new donut is added. It also requires
# an alpha color which -Y- said he would implement.
- state: box
- state: box-open
map: ["openLayer"]
+ visible: false
+ - state: box1
+ map: ["box1"]
+ visible: false
+ - state: pink-box2
+ map: ["pink-box2"]
+ visible: false
+ - state: box3
+ map: ["box3"]
+ visible: false
+ - state: pink-box4
+ map: ["pink-box4"]
+ visible: false
+ - state: box5
+ map: ["box5"]
+ visible: false
+ - state: pink-box6
+ map: ["pink-box6"]
+ visible: false
- type: Storage
capacity: 6
whitelist:
- type: ItemCounter
count:
tags: [Donut]
+ composite: true
+ layerStates:
+ - box1
+ - pink-box2
+ - box3
+ - pink-box4
+ - box5
+ - pink-box6
- type: Appearance
- visuals:
- - type: StackVisualizer
- composite: true
- stackLayers:
- - box1
- - pink-box2
- - box3
- - pink-box4
- - box5
- - pink-box6
# Egg
- state: box-closed
- state: box-open
map: ["openLayer"]
+ visible: false
+ - state: box1
+ map: ["box1"]
+ visible: false
+ - state: box2
+ map: ["box2"]
+ visible: false
+ - state: box3
+ map: ["box3"]
+ visible: false
+ - state: box4
+ map: ["box4"]
+ visible: false
+ - state: box5
+ map: ["box5"]
+ visible: false
+ - state: box6
+ map: ["box6"]
+ visible: false
+ - state: box7
+ map: ["box7"]
+ visible: false
+ - state: box8
+ map: ["box8"]
+ visible: false
+ - state: box9
+ map: ["box9"]
+ visible: false
+ - state: box10
+ map: ["box10"]
+ visible: false
+ - state: box11
+ map: ["box11"]
+ visible: false
+ - state: box12
+ map: ["box12"]
+ visible: false
- type: Storage
capacity: 12
whitelist:
- type: ItemCounter
count:
tags: [Egg]
+ composite: true
+ layerStates:
+ - box1
+ - box2
+ - box3
+ - box4
+ - box5
+ - box6
+ - box7
+ - box8
+ - box9
+ - box10
+ - box11
+ - box12
- type: Appearance
- visuals:
- - type: StackVisualizer
- composite: true
- stackLayers:
- - box1
- - box2
- - box3
- - box4
- - box5
- - box6
- - box7
- - box8
- - box9
- - box10
- - box11
- - box12
# Someday...
# - type: DamageOnLand
# - type: DamageOtherOnHit
- state: box
- state: box-open
map: ["openLayer"]
+ visible: false
+ - state: box1
+ map: ["box1"]
+ visible: false
+ - state: box2
+ map: ["box2"]
+ visible: false
+ - state: box3
+ map: ["box3"]
+ visible: false
+ - state: box4
+ map: ["box4"]
+ visible: false
+ - state: box5
+ map: ["box5"]
+ visible: false
+ - state: box6
+ map: ["box6"]
+ visible: false
- type: Storage
capacity: 6
- type: Item
- type: ItemCounter
count:
tags: [Nugget]
+ composite: true
+ layerStates:
+ - box1
+ - box2
+ - box3
+ - box4
+ - box5
+ - box6
- type: Appearance
- visuals:
- - type: StackVisualizer
- composite: true
- stackLayers:
- - box1
- - box2
- - box3
- - box4
- - box5
- - box6
# Donkpocket
- state: closed
- state: open
map: ["openLayer"]
+ visible: false
+ - state: cig1
+ map: ["cig1"]
+ sprite: Objects/Consumable/Smokeables/Cigarettes/Packs/visualizer.rsi
+ visible: false
+ - state: cig2
+ map: ["cig2"]
+ sprite: Objects/Consumable/Smokeables/Cigarettes/Packs/visualizer.rsi
+ visible: false
+ - state: cig3
+ map: ["cig3"]
+ sprite: Objects/Consumable/Smokeables/Cigarettes/Packs/visualizer.rsi
+ visible: false
+ - state: cig4
+ map: ["cig4"]
+ sprite: Objects/Consumable/Smokeables/Cigarettes/Packs/visualizer.rsi
+ visible: false
+ - state: cig5
+ map: ["cig5"]
+ sprite: Objects/Consumable/Smokeables/Cigarettes/Packs/visualizer.rsi
+ visible: false
+ - state: cig6
+ map: ["cig6"]
+ sprite: Objects/Consumable/Smokeables/Cigarettes/Packs/visualizer.rsi
+ visible: false
- type: Tag
tags:
- CigPack
- type: ItemCounter
count:
tags: [Cigarette]
+ composite: true
+ layerStates:
+ - cig1
+ - cig2
+ - cig3
+ - cig4
+ - cig5
+ - cig6
- type: Appearance
- visuals:
- - type: StackVisualizer
- sprite: Objects/Consumable/Smokeables/Cigarettes/Packs/visualizer.rsi
- composite: true
- stackLayers:
- - cig1
- - cig2
- - cig3
- - cig4
- - cig5
- - cig6
- type: entity
id: CigPackGreen
- state: closed
- state: open
map: ["openLayer"]
+ - state: cigar1
+ map: ["cigar1"]
+ visible: false
+ - state: cigar2
+ map: ["cigar2"]
+ visible: false
+ - state: cigar3
+ map: ["cigar3"]
+ visible: false
+ - state: cigar4
+ map: ["cigar4"]
+ visible: false
+ - state: cigar5
+ map: ["cigar5"]
+ visible: false
+ - state: cigar6
+ map: ["cigar6"]
+ visible: false
+ - state: cigar7
+ map: ["cigar7"]
+ visible: false
+ - state: cigar8
+ map: ["cigar8"]
+ visible: false
- type: Storage
capacity: 8
- type: Item
- type: ItemCounter
count:
tags: [Cigar]
+ composite: true
+ layerStates:
+ - cigar1
+ - cigar2
+ - cigar3
+ - cigar4
+ - cigar5
+ - cigar6
+ - cigar7
+ - cigar8
- type: Appearance
- visuals:
- - type: StackVisualizer
- composite: true
- stackLayers:
- - cigar1
- - cigar2
- - cigar3
- - cigar4
- - cigar5
- - cigar6
- - cigar7
- - cigar8
- type: entity
id: CigarGoldCase
Glass: 100
- type: Stack
stackType: Glass
+ baseLayer: base
+ layerStates:
+ - glass
+ - glass_2
+ - glass_3
- type: Sprite
state: glass_3
+ layers:
+ - state: glass_3
+ map: ["base"]
- type: Item
heldPrefix: glass
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - glass
- - glass_2
- - glass_3
- type: FloorTile
outputs:
- FloorGlass
ReinforcedGlass: 100
- type: Stack
stackType: ReinforcedGlass
+ baseLayer: base
+ layerStates:
+ - rglass
+ - rglass_2
+ - rglass_3
- type: Sprite
state: rglass_3
+ layers:
+ - state: rglass_3
+ map: ["base"]
- type: Item
heldPrefix: rglass
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - rglass
- - rglass_2
- - rglass_3
- type: FloorTile
outputs:
- FloorRGlass
PlasmaGlass: 100
- type: Stack
stackType: PlasmaGlass
+ baseLayer: base
+ layerStates:
+ - pglass
+ - pglass_2
+ - pglass_3
- type: Sprite
state: pglass_3
+ layers:
+ - state: pglass_3
+ map: ["base"]
- type: Item
heldPrefix: pglass
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - pglass
- - pglass_2
- - pglass_3
- type: Construction
graph: Glass
node: SheetPGlass
ReinforcedPlasmaGlass: 100
- type: Stack
stackType: ReinforcedPlasmaGlass
+ baseLayer: base
+ layerStates:
+ - rpglass
+ - rpglass_2
+ - rpglass_3
- type: Sprite
state: rpglass_3
+ layers:
+ - state: rpglass_3
+ map: ["base"]
- type: Item
heldPrefix: rpglass
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - rpglass
- - rpglass_2
- - rpglass_3
- type: Construction
graph: Glass
node: SheetRPGlass
UraniumGlass: 100
- type: Stack
stackType: UraniumGlass
+ baseLayer: base
+ layerStates:
+ - uglass
+ - uglass_2
+ - uglass_3
- type: Sprite
state: uglass_3
+ layers:
+ - state: uglass_3
+ map: ["base"]
- type: Item
heldPrefix: uglass
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - uglass
- - uglass_2
- - uglass_3
- type: Construction
graph: Glass
node: SheetUGlass
ReinforcedUraniumGlass: 100
- type: Stack
stackType: ReinforcedUraniumGlass
+ baseLayer: base
+ layerStates:
+ - ruglass
+ - ruglass_2
+ - ruglass_3
- type: Sprite
state: ruglass_3
+ layers:
+ - state: ruglass_3
+ map: ["base"]
- type: Item
heldPrefix: ruglass
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - ruglass
- - ruglass_2
- - ruglass_3
- type: Construction
graph: Glass
node: SheetRUGlass
Steel: 100
- type: Stack
stackType: Steel
+ baseLayer: base
+ layerStates:
+ - steel
+ - steel_2
+ - steel_3
- type: Sprite
state: steel_3
+ layers:
+ - state: plasteel_3
+ map: ["base"]
- type: Item
heldPrefix: steel
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - steel
- - steel_2
- - steel_3
- type: FloorTile
outputs:
- Plating
Plasteel: 100
- type: Stack
stackType: Plasteel
+ baseLayer: base
+ layerStates:
+ - plasteel
+ - plasteel_2
+ - plasteel_3
- type: Sprite
state: plasteel_3
+ layers:
+ - state: plasteel_3
+ map: ["base"]
- type: Item
heldPrefix: plasteel
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - plasteel
- - plasteel_2
- - plasteel_3
- type: entity
parent: SheetPlasteel
components:
- type: Stack
stackType: Paper
+ baseLayer: base
+ layerStates:
+ - paper
+ - paper_2
+ - paper_3
- type: Sprite
state: paper_3
+ layers:
+ - state: paper_3
+ map: ["base"]
- type: Item
heldPrefix: paper
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - paper
- - paper_2
- - paper_3
- type: entity
parent: SheetPaper
Plasma: 100
- type: Stack
stackType: Plasma
+ baseLayer: base
+ layerStates:
+ - plasma
+ - plasma_2
+ - plasma_3
- type: Sprite
state: plasma_3
+ layers:
+ - state: plasma_3
+ map: ["base"]
- type: Item
heldPrefix: plasma
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - plasma
- - plasma_2
- - plasma_3
- type: Extractable
grindableSolutionName: plasma
- type: SolutionContainerManager
Plastic: 100
- type: Stack
stackType: Plastic
+ baseLayer: base
+ layerStates:
+ - plastic
+ - plastic_2
+ - plastic_3
- type: Sprite
state: plastic_3
+ layers:
+ - state: plastic_3
+ map: ["base"]
- type: Item
heldPrefix: plastic
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - plastic
- - plastic_2
- - plastic_3
- type: entity
parent: SheetPlastic
Uranium: 100
- type: Stack
stackType: Uranium
+ baseLayer: base
+ layerStates:
+ - uranium
+ - uranium_2
+ - uranium_3
- type: Sprite
state: uranium_3
+ layers:
+ - state: uranium_3
+ map: ["base"]
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - uranium
- - uranium_2
- - uranium_3
- type: Item
heldPrefix: uranium
- type: Extractable
Gold: 100
- type: Stack
stackType: Gold
+ baseLayer: base
+ layerStates:
+ - gold
+ - gold_2
+ - gold_3
- type: Sprite
state: gold_3
+ layers:
+ - state: gold_3
+ map: ["base"]
- type: Item
heldPrefix: gold
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - gold
- - gold_2
- - gold_3
- type: entity
parent: IngotGold
Silver: 100
- type: Stack
stackType: Silver
+ baseLayer: base
+ layerStates:
+ - silver
+ - silver_2
+ - silver_3
- type: Sprite
state: silver_3
+ layers:
+ - state: silver_3
+ map: ["base"]
- type: Item
heldPrefix: silver
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - silver
- - silver_2
- - silver_3
- type: entity
parent: IngotSilver
Cardboard: 100
- type: Stack
stackType: Cardboard
+ baseLayer: base
+ layerStates:
+ - cardboard
+ - cardboard_2
+ - cardboard_3
- type: Sprite
state: cardboard_3
+ layers:
+ - state: cardboard_3
+ map: ["base"]
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - cardboard
- - cardboard_2
- - cardboard_3
- type: entity
parent: MaterialCardboard
path: "/Audio/Items/Medical/brutepack_end.ogg"
- type: Stack
stackType: Cloth
+ baseLayer: base
+ layerStates:
+ - cloth
+ - cloth_2
+ - cloth_3
- type: Material
- type: PhysicalComposition
materialComposition:
Quantity: 3
- type: Sprite
state: cloth_3
+ layers:
+ - state: cloth_3
+ map: ["base"]
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - cloth
- - cloth_2
- - cloth_3
- type: entity
parent: MaterialCloth
components:
- type: Stack
stackType: Durathread
+ baseLayer: base
+ layerStates:
+ - durathread
+ - durathread_2
+ - durathread_3
- type: Material
- type: PhysicalComposition
materialComposition:
Durathread: 100
- type: Sprite
state: durathread_3
+ layers:
+ - state: durathread_3
+ map: ["base"]
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - durathread
- - durathread_2
- - durathread_3
- type: Construction
graph: Durathread
node: MaterialDurathread
Wood: 100
- type: Stack
stackType: WoodPlank
+ baseLayer: base
+ layerStates:
+ - wood
+ - wood_2
+ - wood_3
- type: Sprite
state: wood
+ layers:
+ - state: wood
+ map: ["base"]
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - wood
- - wood_2
- - wood_3
- type: Item
heldPrefix: wood
components:
- type: Stack
stackType: Cotton
+ baseLayer: base
+ layerStates:
+ - cotton
+ - cotton_2
+ - cotton_3
- type: Sprite
state: cotton_3
+ layers:
+ - state: cotton_3
+ map: ["base"]
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - cotton
- - cotton_2
- - cotton_3
- type: entity
parent: MaterialCotton
Bananium: 150
- type: Sprite
state: bananium_1
+ layers:
+ - state: bananium_1
+ map: ["base"]
- type: Stack
stackType: Bananium
count: 10
+ baseLayer: base
+ layerStates:
+ - bananium
+ - bananium_1
- type: RadiationSource
intensity: 0.3
- type: FlavorProfile
- ReagentId: Honk
Quantity: 5
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - bananium
- - bananium_1
- type: entity
parent: MaterialBananium
components:
- type: Stack
stackType: MetalRod
+ baseLayer: base
+ layerStates:
+ - rods
+ - rods_2
+ - rods_3
+ - rods_4
+ - rods_5
- type: Sprite
state: rods_5
+ layers:
+ - state: rods_5
+ map: ["base"]
# - type: Item
# heldPrefix: rods
- type: Construction
graph: MetalRod
node: MetalRod
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - rods
- - rods_2
- - rods_3
- - rods_4
- - rods_5
- type: FloorTile
outputs:
- Lattice
- type: Stack
stackType: Credit
count: 1
+ baseLayer: base
+ layerStates:
+ - cash
+ - cash_10
+ - cash_100
+ - cash_500
+ - cash_1000
+ - cash_1000000
- type: Sprite
sprite: Objects/Economy/cash.rsi
netsync: false
state: cash
+ layers:
+ - state: cash
+ map: ["base"]
- type: Physics
bodyType: Dynamic
- type: Fixtures
mask:
- ItemMask
- type: Appearance
- visuals:
- - type: StackVisualizer
- # TODO: This won't work because stackvisualizer works based off of an even count and not denominations.
- # Ideally we'd just be able to specify at what count does the new layer take place e.g.
- # - 10: cash_10
- # - 100: cash_100
- stackLayers:
- - cash
- - cash_10
- - cash_100
- - cash_500
- - cash_1000
- - cash_1000000
- type: material
id: Credit
components:
- type: Stack
stackType: CableHV
+ baseLayer: base
+ layerStates:
+ - coilhv-10
+ - coilhv-20
+ - coilhv-30
- type: Sprite
state: coilhv-30
+ layers:
+ - state: coilhv-30
+ map: ["base"]
- type: Item
heldPrefix: coilhv
- type: CablePlacer
cablePrototypeID: CableHV
blockingWireType: HighVoltage
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - coilhv-10
- - coilhv-20
- - coilhv-30
- type: entity
parent: CableHVStack
components:
- type: Stack
stackType: CableMV
+ baseLayer: base
+ layerStates:
+ - coilmv-10
+ - coilmv-20
+ - coilmv-30
- type: Sprite
state: coilmv-30
+ layers:
+ - state: coilmv-30
+ map: ["base"]
- type: Item
heldPrefix: coilmv
- type: CablePlacer
cablePrototypeID: CableMV
blockingWireType: MediumVoltage
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - coilmv-10
- - coilmv-20
- - coilmv-30
- type: entity
parent: CableMVStack
components:
- type: Sprite
state: coillv-30
+ layers:
+ - state: coillv-30
+ map: ["base"]
- type: Item
heldPrefix: coillv
+ - type: Stack
+ baseLayer: base
+ layerStates:
+ - coillv-10
+ - coillv-20
+ - coillv-30
- type: CablePlacer
cablePrototypeID: CableApcExtension
blockingWireType: Apc
- type: Appearance
- visuals:
- - type: StackVisualizer
- stackLayers:
- - coillv-10
- - coillv-20
- - coillv-30
- type: entity
parent: CableApcStack
- type: Tag
tags:
- DroneUsable
-# - type: Appearance # TODO: Add stack sprites
-# visuals:
-# - type: StackVisualizer
-# stackLayers:
-# - coillv-10
-# - coillv-20
-# - coillv-30
+# TODO: Add stack sprites + visuals.
- type: entity
id: InflatableDoorStack
- type: Tag
tags:
- DroneUsable
+# TODO: Add stack sprites + visuals.
- type: entity
parent: InflatableWallStack
- state: matchbox
- state: matchbox-open
map: ["openLayer"]
+ - state: matchbox1
+ map: ["matchbox1"]
+ visible: false
+ - state: matchbox2
+ map: ["matchbox2"]
+ visible: false
+ - state: matchbox3
+ map: ["matchbox3"]
+ visible: false
- type: Item
sprite: Objects/Tools/matches.rsi
heldPrefix: matchbox
- type: ItemCounter
count:
tags: [Matchstick]
+ composite: true
+ layerStates:
+ - matchbox1
+ - matchbox2
+ - matchbox3
- type: Appearance
- visuals:
- - type: StackVisualizer
- composite: true
- stackLayers:
- - matchbox1
- - matchbox2
- - matchbox3
- type: Tag
tags:
- Trash