Add cigarettes and matches to SS14 (#2522)
* Add resources for cigs/matches * Add files for cigarettes * Remove Shared Components * Applied some of the suggestions * Change priority to allow matches to be set alight by matchbox * Added item for pack of cigars * Add swepts resources. Fix naming * Fix naming, implement suggestions. * Addressed Paul's suggestions * Remove unused resources * Fix Paul's suggestions
@@ -0,0 +1,66 @@
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Nutrition
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class BurnStateVisualizer : AppearanceVisualizer
|
||||
{
|
||||
private string _burntIcon = "burnt-icon";
|
||||
private string _litIcon = "lit-icon";
|
||||
private string _unlitIcon = "icon";
|
||||
|
||||
public override void LoadData(YamlMappingNode node)
|
||||
{
|
||||
base.LoadData(node);
|
||||
|
||||
if (node.TryGetNode("unlitIcon", out var unlitIcon))
|
||||
{
|
||||
_unlitIcon = unlitIcon.AsString();
|
||||
}
|
||||
|
||||
if (node.TryGetNode("litIcon", out var litIcon))
|
||||
{
|
||||
_litIcon = litIcon.AsString();
|
||||
}
|
||||
|
||||
if (node.TryGetNode("burntIcon", out var burntIcon))
|
||||
{
|
||||
_burntIcon = burntIcon.AsString();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
if (component.TryGetData<SharedBurningStates>(SmokingVisuals.Smoking, out var smoking))
|
||||
{
|
||||
SetState(component, smoking);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetState(AppearanceComponent component, SharedBurningStates burnState)
|
||||
{
|
||||
if (component.Owner.TryGetComponent<ISpriteComponent>(out var sprite))
|
||||
{
|
||||
switch (burnState)
|
||||
{
|
||||
case SharedBurningStates.Lit:
|
||||
sprite.LayerSetState(0, _litIcon);
|
||||
break;
|
||||
case SharedBurningStates.Burnt:
|
||||
sprite.LayerSetState(0, _burntIcon);
|
||||
break;
|
||||
default:
|
||||
sprite.LayerSetState(0, _unlitIcon);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,6 +169,9 @@ namespace Content.Client
|
||||
"Flammable",
|
||||
"CreamPie",
|
||||
"CreamPied",
|
||||
"Smoking",
|
||||
"Matchstick",
|
||||
"Matchbox",
|
||||
"BlockGameArcade",
|
||||
"KitchenSpike",
|
||||
"Butcherable",
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Interactable
|
||||
{
|
||||
// TODO make changes in icons when different threshold reached
|
||||
// e.g. different icons for 10% 50% 100%
|
||||
[RegisterComponent]
|
||||
public class MatchboxComponent : Component, IInteractUsing
|
||||
{
|
||||
public override string Name => "Matchbox";
|
||||
|
||||
public int Priority => 1;
|
||||
|
||||
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||
{
|
||||
if (eventArgs.Using.TryGetComponent<MatchstickComponent>(out var matchstick)
|
||||
&& matchstick.CurrentState == SharedBurningStates.Unlit)
|
||||
{
|
||||
matchstick.Ignite(eventArgs.User);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.ComponentDependencies;
|
||||
using Robust.Shared.GameObjects.Components.Timers;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Interactable
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IHotItem))]
|
||||
public class MatchstickComponent : Component, IHotItem, IInteractUsing
|
||||
{
|
||||
public override string Name => "Matchstick";
|
||||
|
||||
private SharedBurningStates _currentState = SharedBurningStates.Unlit;
|
||||
|
||||
/// <summary>
|
||||
/// How long will matchstick last in seconds.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadOnly)] private int _duration;
|
||||
|
||||
/// <summary>
|
||||
/// Sound played when you ignite the matchstick.
|
||||
/// </summary>
|
||||
private string? _igniteSound;
|
||||
|
||||
/// <summary>
|
||||
/// Point light component. Gives matches a glow in dark effect.
|
||||
/// </summary>
|
||||
[ComponentDependency]
|
||||
private readonly PointLightComponent? _pointLightComponent = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Current state to matchstick. Can be <code>Unlit</code>, <code>Lit</code> or <code>Burnt</code>.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
public SharedBurningStates CurrentState
|
||||
{
|
||||
get => _currentState;
|
||||
private set
|
||||
{
|
||||
_currentState = value;
|
||||
|
||||
if (_pointLightComponent != null)
|
||||
{
|
||||
_pointLightComponent.Enabled = _currentState == SharedBurningStates.Lit;
|
||||
}
|
||||
|
||||
if (Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||
{
|
||||
appearance.SetData(SmokingVisuals.Smoking, _currentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
|
||||
serializer.DataField(ref _duration, "duration", 10);
|
||||
serializer.DataField(ref _igniteSound, "igniteSound", null);
|
||||
}
|
||||
|
||||
bool IHotItem.IsCurrentlyHot()
|
||||
{
|
||||
return CurrentState == SharedBurningStates.Lit;
|
||||
}
|
||||
|
||||
public void Ignite(IEntity user)
|
||||
{
|
||||
// Play Sound
|
||||
if (!string.IsNullOrEmpty(_igniteSound))
|
||||
{
|
||||
EntitySystem.Get<AudioSystem>().PlayFromEntity(_igniteSound, Owner,
|
||||
AudioHelpers.WithVariation(0.125f).WithVolume(-0.125f));
|
||||
}
|
||||
|
||||
// Change state
|
||||
CurrentState = SharedBurningStates.Lit;
|
||||
Owner.SpawnTimer(_duration * 1000, () => CurrentState = SharedBurningStates.Burnt);
|
||||
}
|
||||
|
||||
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||
{
|
||||
if (eventArgs.Target.TryGetComponent<IHotItem>(out var hotItem)
|
||||
&& hotItem.IsCurrentlyHot()
|
||||
&& CurrentState == SharedBurningStates.Unlit)
|
||||
{
|
||||
Ignite(eventArgs.User);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,8 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(ToolComponent))]
|
||||
[ComponentReference(typeof(IToolComponent))]
|
||||
public class WelderComponent : ToolComponent, IExamine, IUse, ISuicideAct, ISolutionChange
|
||||
[ComponentReference(typeof(IHotItem))]
|
||||
public class WelderComponent : ToolComponent, IExamine, IUse, ISuicideAct, ISolutionChange, IHotItem
|
||||
{
|
||||
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
|
||||
|
||||
@@ -73,6 +74,11 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
}
|
||||
}
|
||||
|
||||
bool IHotItem.IsCurrentlyHot()
|
||||
{
|
||||
return WelderLit;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -285,5 +291,7 @@ namespace Content.Server.GameObjects.Components.Interactable
|
||||
{
|
||||
Dirty();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
#nullable enable
|
||||
using System.Threading.Tasks;
|
||||
using Content.Server.GameObjects.Components.Items.Clothing;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.ComponentDependencies;
|
||||
using Robust.Shared.GameObjects.Components.Timers;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Nutrition
|
||||
{
|
||||
/// <summary>
|
||||
/// This item acts as a representation for smokable consumables.
|
||||
///
|
||||
/// To smoke a cigar, you need:
|
||||
/// <list type="bullet">
|
||||
/// <item><description> a hot item (implements IHotItem interface)</description></item>
|
||||
/// <item><description> that's a alight.</description></item>
|
||||
/// <item><description> for the target cigar be Unlit. Lit cigars are already lit and butt's don't have any "fuel" left.</description></item>
|
||||
///</list>
|
||||
/// TODO: Add reagents that interact when smoking
|
||||
/// TODO: Allow suicide via excessive Smoking
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
public class SmokingComponent : Component, IInteractUsing, IHotItem
|
||||
{
|
||||
public override string Name => "Smoking";
|
||||
|
||||
private SharedBurningStates _currentState = SharedBurningStates.Unlit;
|
||||
|
||||
[ComponentDependency] private readonly ClothingComponent? _clothingComponent = default!;
|
||||
[ComponentDependency] private readonly AppearanceComponent? _appearanceComponent = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Duration represents how long will this item last.
|
||||
/// Generally it ticks down whether it's time-based
|
||||
/// or consumption-based.
|
||||
/// </summary>
|
||||
[ViewVariables] private int _duration;
|
||||
|
||||
/// <summary>
|
||||
/// What is the temperature of the cigar?
|
||||
///
|
||||
/// For a regular cigar, the temp approaches around 400°C or 580°C
|
||||
/// dependant on where you measure.
|
||||
/// </summary>
|
||||
[ViewVariables] private float _temperature;
|
||||
|
||||
[ViewVariables]
|
||||
private SharedBurningStates CurrentState
|
||||
{
|
||||
get => _currentState;
|
||||
set
|
||||
{
|
||||
_currentState = value;
|
||||
|
||||
if (_clothingComponent != null)
|
||||
{
|
||||
switch (_currentState)
|
||||
{
|
||||
case SharedBurningStates.Lit:
|
||||
_clothingComponent.EquippedPrefix = "lit";
|
||||
_clothingComponent.ClothingEquippedPrefix = "lit";
|
||||
break;
|
||||
default:
|
||||
_clothingComponent.EquippedPrefix = "unlit";
|
||||
_clothingComponent.ClothingEquippedPrefix = "unlit";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_appearanceComponent?.SetData(SmokingVisuals.Smoking, _currentState);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
{
|
||||
base.ExposeData(serializer);
|
||||
serializer.DataField(ref _duration, "duration", 30);
|
||||
serializer.DataField(ref _temperature, "temperature", 673.15f);
|
||||
}
|
||||
|
||||
public async Task<bool> InteractUsing(InteractUsingEventArgs eventArgs)
|
||||
{
|
||||
if (eventArgs.Using.TryGetComponent(out IHotItem? lighter)
|
||||
&& lighter.IsCurrentlyHot()
|
||||
&& CurrentState == SharedBurningStates.Unlit
|
||||
)
|
||||
{
|
||||
CurrentState = SharedBurningStates.Lit;
|
||||
// TODO More complex handling of cigar consumption
|
||||
Owner.SpawnTimer(_duration * 1000, () => CurrentState = SharedBurningStates.Burnt);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IHotItem.IsCurrentlyHot()
|
||||
{
|
||||
return _currentState == SharedBurningStates.Lit;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Content.Shared/GameObjects/Components/SharedBurningStates.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public enum SharedBurningStates : byte
|
||||
{
|
||||
Unlit,
|
||||
Lit,
|
||||
Burnt,
|
||||
}
|
||||
}
|
||||
11
Content.Shared/GameObjects/Components/SmokingVisuals.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public enum SmokingVisuals : byte
|
||||
{
|
||||
Smoking,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.Shared.Interfaces.GameObjects.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface gives components hot quality when they are used.
|
||||
/// E.g if you hold a lit match or a welder then it will be hot,
|
||||
/// presuming match is lit or the welder is on respectively.
|
||||
/// However say you hold an item that is always hot like lava rock,
|
||||
/// it will be permanently hot.
|
||||
/// </summary>
|
||||
public interface IHotItem
|
||||
{
|
||||
bool IsCurrentlyHot();
|
||||
}
|
||||
}
|
||||
BIN
Resources/Audio/Items/match_strike.ogg
Normal file
@@ -4,3 +4,6 @@
|
||||
description: A vending machine containing smoking supplies.
|
||||
animationDuration: 2.1
|
||||
spriteName: cigs
|
||||
startingInventory:
|
||||
CigarettePack: 20
|
||||
Matchbox: 10
|
||||
|
||||
42
Resources/Prototypes/Entities/Objects/Consumable/fancy.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
- type: entity
|
||||
name: "Base Cigarette"
|
||||
id: BaseCigarette
|
||||
parent: BaseItem
|
||||
abstract: true
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Consumable/Fancy/mask_cig.rsi
|
||||
netsync: false
|
||||
state: icon
|
||||
- type: Clothing
|
||||
sprite: Objects/Consumable/Fancy/mask_cig.rsi
|
||||
Slots: [ mask ]
|
||||
HeldPrefix: unlit
|
||||
size: 1
|
||||
- type: Smoking
|
||||
duration: 30
|
||||
- type: Appearance
|
||||
visuals:
|
||||
- type: BurnStateVisualizer
|
||||
|
||||
- type: entity
|
||||
id: Cigarette
|
||||
parent: BaseCigarette
|
||||
name: cigarette
|
||||
description: "If you want to get cancer, might as well do it in style."
|
||||
|
||||
- type: entity
|
||||
id: CigarettePack
|
||||
parent: SmallboxItem
|
||||
name: cigarette pack
|
||||
description: "Pack of cigarettes"
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Consumable/Fancy/cigarettes.rsi
|
||||
layers:
|
||||
- state: cig
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- name: Cigarette
|
||||
amount: 6
|
||||
|
||||
53
Resources/Prototypes/Entities/Objects/Tools/matches.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
- type: entity
|
||||
id: SmallboxItem
|
||||
parent: BaseItem
|
||||
abstract: true
|
||||
components:
|
||||
- type: Storage
|
||||
capacity: 10
|
||||
- type: Item
|
||||
size: 6
|
||||
|
||||
- type: entity
|
||||
name: match stick
|
||||
parent: BaseItem
|
||||
id: Matchstick
|
||||
description: "A simple match stick, used for lighting fine smokables."
|
||||
components:
|
||||
- type: Sprite
|
||||
netsync: false
|
||||
sprite: Objects/Tools/matches.rsi
|
||||
layers:
|
||||
- state: match_unlit
|
||||
- type: Item
|
||||
size: 1
|
||||
sprite: Objects/Tools/matches.rsi
|
||||
- type: Matchstick
|
||||
duration: 10
|
||||
igniteSound: /Audio/Items/match_strike.ogg
|
||||
- type: PointLight
|
||||
enabled: false
|
||||
radius: 1.1
|
||||
color: darkorange
|
||||
- type: Appearance
|
||||
visuals:
|
||||
- type: BurnStateVisualizer
|
||||
unlitIcon: match_unlit
|
||||
litIcon: match_lit
|
||||
burntIcon: match_burnt
|
||||
|
||||
- type: entity
|
||||
name: match box
|
||||
parent: SmallboxItem
|
||||
id: Matchbox
|
||||
description: "A small box of Almost But Not Quite Plasma Premium Matches."
|
||||
components:
|
||||
- type: Matchbox
|
||||
- type: Sprite
|
||||
sprite: Objects/Tools/matches.rsi
|
||||
layers:
|
||||
- state: matchbox
|
||||
- type: StorageFill
|
||||
contents:
|
||||
- name: Matchstick
|
||||
amount: 6
|
||||
|
After Width: | Height: | Size: 249 B |
|
After Width: | Height: | Size: 280 B |
|
After Width: | Height: | Size: 171 B |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/bfc9c6ba8126ee8c41564d68c4bfb9ce37faa8f8",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "cig",
|
||||
"directions": 1
|
||||
},
|
||||
{
|
||||
"name": "cig_empty",
|
||||
"directions": 1
|
||||
},
|
||||
{
|
||||
"name": "cig_open",
|
||||
"directions": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 135 B |
|
After Width: | Height: | Size: 140 B |
|
After Width: | Height: | Size: 429 B |
|
After Width: | Height: | Size: 344 B |
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/bfc9c6ba8126ee8c41564d68c4bfb9ce37faa8f8",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "unlit-equipped-MASK",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "lit-equipped-MASK",
|
||||
"directions": 4,
|
||||
"delays": [
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
],
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "burnt-icon",
|
||||
"directions": 1
|
||||
},
|
||||
{
|
||||
"name": "icon",
|
||||
"directions": 1
|
||||
},
|
||||
{
|
||||
"name": "lit-icon",
|
||||
"directions": 1,
|
||||
"delays": [
|
||||
[
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1,
|
||||
0.1
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 133 B |
BIN
Resources/Textures/Objects/Tools/matches.rsi/match_burnt.png
Normal file
|
After Width: | Height: | Size: 150 B |
BIN
Resources/Textures/Objects/Tools/matches.rsi/match_lit.png
Normal file
|
After Width: | Height: | Size: 518 B |
BIN
Resources/Textures/Objects/Tools/matches.rsi/match_unlit.png
Normal file
|
After Width: | Height: | Size: 194 B |
BIN
Resources/Textures/Objects/Tools/matches.rsi/matchbox.png
Normal file
|
After Width: | Height: | Size: 532 B |
|
After Width: | Height: | Size: 524 B |
|
After Width: | Height: | Size: 524 B |
BIN
Resources/Textures/Objects/Tools/matches.rsi/matchbox_e.png
Normal file
|
After Width: | Height: | Size: 511 B |
46
Resources/Textures/Objects/Tools/matches.rsi/meta.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/bfc9c6ba8126ee8c41564d68c4bfb9ce37faa8f8",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
},
|
||||
"states": [
|
||||
{
|
||||
"name": "match_burnt",
|
||||
"directions": 1
|
||||
},
|
||||
{
|
||||
"name": "match_lit",
|
||||
"directions": 1,
|
||||
"delays": [
|
||||
[
|
||||
0.2,
|
||||
0.2,
|
||||
0.2
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "match_unlit",
|
||||
"directions": 1
|
||||
},
|
||||
{
|
||||
"name": "matchbox",
|
||||
"directions": 1
|
||||
},
|
||||
{
|
||||
"name": "matchbox_almostempty",
|
||||
"directions": 1
|
||||
},
|
||||
{
|
||||
"name": "matchbox_almostfull",
|
||||
"directions": 1
|
||||
},
|
||||
{
|
||||
"name": "matchbox_e",
|
||||
"directions": 1
|
||||
}
|
||||
]
|
||||
}
|
||||