Quantum Spin Inverter (#23756)
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
using Content.Shared.Teleportation.Systems;
|
||||||
|
using Content.Shared.Whitelist;
|
||||||
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||||
|
|
||||||
|
namespace Content.Shared.Teleportation.Components;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is used for an entity that, when linked to another valid entity, allows the two to swap positions,
|
||||||
|
/// additionally swapping the positions of the parents.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
[Access(typeof(SwapTeleporterSystem))]
|
||||||
|
public sealed partial class SwapTeleporterComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The other SwapTeleporterComponent that this one is linked to
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public EntityUid? LinkedEnt;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// the time at which <see cref="TeleportDelay"/> ends and the teleportation occurs
|
||||||
|
/// </summary>
|
||||||
|
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public TimeSpan? TeleportTime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delay after starting the teleport and it occuring.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public TimeSpan TeleportDelay = TimeSpan.FromSeconds(2.5f);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The time at which <see cref="Cooldown"/> ends and teleportation can occur again.
|
||||||
|
/// </summary>
|
||||||
|
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
|
||||||
|
public TimeSpan NextTeleportUse;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A minimum waiting period inbetween teleports.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public TimeSpan Cooldown = TimeSpan.FromMinutes(5);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sound played when teleportation begins
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public SoundSpecifier? TeleportSound = new SoundPathSpecifier("/Audio/Weapons/flash.ogg");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A whitelist for what entities are valid for <see cref="LinkedEnt"/>.
|
||||||
|
/// </summary>
|
||||||
|
[DataField]
|
||||||
|
public EntityWhitelist TeleporterWhitelist = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum SwapTeleporterVisuals : byte
|
||||||
|
{
|
||||||
|
Linked
|
||||||
|
}
|
||||||
246
Content.Shared/Teleportation/Systems/SwapTeleporterSystem.cs
Normal file
246
Content.Shared/Teleportation/Systems/SwapTeleporterSystem.cs
Normal file
@@ -0,0 +1,246 @@
|
|||||||
|
using Content.Shared.Examine;
|
||||||
|
using Content.Shared.IdentityManagement;
|
||||||
|
using Content.Shared.Interaction;
|
||||||
|
using Content.Shared.Popups;
|
||||||
|
using Content.Shared.Teleportation.Components;
|
||||||
|
using Content.Shared.Verbs;
|
||||||
|
using Robust.Shared.Audio.Systems;
|
||||||
|
using Robust.Shared.Map.Components;
|
||||||
|
using Robust.Shared.Physics;
|
||||||
|
using Robust.Shared.Physics.Components;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Shared.Teleportation.Systems;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This handles <see cref="SwapTeleporterComponent"/>
|
||||||
|
/// </summary>
|
||||||
|
public sealed class SwapTeleporterSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
|
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||||
|
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||||
|
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||||
|
|
||||||
|
private EntityQuery<TransformComponent> _xformQuery;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
SubscribeLocalEvent<SwapTeleporterComponent, AfterInteractEvent>(OnInteract);
|
||||||
|
SubscribeLocalEvent<SwapTeleporterComponent, GetVerbsEvent<AlternativeVerb>>(OnGetAltVerb);
|
||||||
|
SubscribeLocalEvent<SwapTeleporterComponent, ActivateInWorldEvent>(OnActivateInWorld);
|
||||||
|
SubscribeLocalEvent<SwapTeleporterComponent, ExaminedEvent>(OnExamined);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<SwapTeleporterComponent, EntityUnpausedEvent>(OnUnpaused);
|
||||||
|
SubscribeLocalEvent<SwapTeleporterComponent, ComponentShutdown>(OnShutdown);
|
||||||
|
|
||||||
|
_xformQuery = GetEntityQuery<TransformComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnInteract(Entity<SwapTeleporterComponent> ent, ref AfterInteractEvent args)
|
||||||
|
{
|
||||||
|
var (uid, comp) = ent;
|
||||||
|
if (args.Target == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var target = args.Target.Value;
|
||||||
|
|
||||||
|
if (!TryComp<SwapTeleporterComponent>(target, out var targetComp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!comp.TeleporterWhitelist.IsValid(target, EntityManager) ||
|
||||||
|
!targetComp.TeleporterWhitelist.IsValid(uid, EntityManager))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comp.LinkedEnt != null)
|
||||||
|
{
|
||||||
|
_popup.PopupClient(Loc.GetString("swap-teleporter-popup-link-fail-already"), uid, args.User);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetComp.LinkedEnt != null)
|
||||||
|
{
|
||||||
|
_popup.PopupClient(Loc.GetString("swap-teleporter-popup-link-fail-already-other"), uid, args.User);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
comp.LinkedEnt = target;
|
||||||
|
targetComp.LinkedEnt = uid;
|
||||||
|
Dirty(uid, comp);
|
||||||
|
Dirty(target, targetComp);
|
||||||
|
_appearance.SetData(uid, SwapTeleporterVisuals.Linked, true);
|
||||||
|
_appearance.SetData(target, SwapTeleporterVisuals.Linked, true);
|
||||||
|
_popup.PopupClient(Loc.GetString("swap-teleporter-popup-link-create"), uid, args.User);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGetAltVerb(Entity<SwapTeleporterComponent> ent, ref GetVerbsEvent<AlternativeVerb> args)
|
||||||
|
{
|
||||||
|
var (uid, comp) = ent;
|
||||||
|
if (!args.CanAccess || !args.CanInteract || args.Hands == null || comp.TeleportTime != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp<SwapTeleporterComponent>(comp.LinkedEnt, out var otherComp) || otherComp.TeleportTime != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var user = args.User;
|
||||||
|
args.Verbs.Add(new AlternativeVerb
|
||||||
|
{
|
||||||
|
Text = Loc.GetString("swap-teleporter-verb-destroy-link"),
|
||||||
|
Priority = 1,
|
||||||
|
Act = () =>
|
||||||
|
{
|
||||||
|
DestroyLink((uid, comp), user);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnActivateInWorld(Entity<SwapTeleporterComponent> ent, ref ActivateInWorldEvent args)
|
||||||
|
{
|
||||||
|
var (uid, comp) = ent;
|
||||||
|
var user = args.User;
|
||||||
|
if (comp.TeleportTime != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (comp.LinkedEnt == null)
|
||||||
|
{
|
||||||
|
_popup.PopupClient(Loc.GetString("swap-teleporter-popup-teleport-cancel-link"), ent, user);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't allow teleporting to happen if the linked one is already teleporting
|
||||||
|
if (!TryComp<SwapTeleporterComponent>(comp.LinkedEnt, out var otherComp)
|
||||||
|
|| otherComp.TeleportTime != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_timing.CurTime < comp.NextTeleportUse)
|
||||||
|
{
|
||||||
|
_popup.PopupClient(Loc.GetString("swap-teleporter-popup-teleport-cancel-time"), ent, user);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_audio.PlayPredicted(comp.TeleportSound, uid, user);
|
||||||
|
_audio.PlayPredicted(otherComp.TeleportSound, comp.LinkedEnt.Value, user);
|
||||||
|
comp.NextTeleportUse = _timing.CurTime + comp.Cooldown;
|
||||||
|
comp.TeleportTime = _timing.CurTime + comp.TeleportDelay;
|
||||||
|
Dirty(uid, comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DoTeleport(Entity<SwapTeleporterComponent, TransformComponent> ent)
|
||||||
|
{
|
||||||
|
var (uid, comp, xform) = ent;
|
||||||
|
|
||||||
|
comp.TeleportTime = null;
|
||||||
|
|
||||||
|
Dirty(uid, comp);
|
||||||
|
if (comp.LinkedEnt is not { } linkedEnt)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var teleEnt = GetTeleportingEntity((uid, xform));
|
||||||
|
var teleEntXform = Transform(teleEnt);
|
||||||
|
var otherTeleEnt = GetTeleportingEntity((linkedEnt, Transform(linkedEnt)));
|
||||||
|
var otherTeleEntXform = Transform(otherTeleEnt);
|
||||||
|
|
||||||
|
_popup.PopupEntity(Loc.GetString("swap-teleporter-popup-teleport-other",
|
||||||
|
("entity", Identity.Entity(linkedEnt, EntityManager))),
|
||||||
|
otherTeleEnt,
|
||||||
|
otherTeleEnt,
|
||||||
|
PopupType.MediumCaution);
|
||||||
|
var pos = teleEntXform.Coordinates;
|
||||||
|
var otherPos = otherTeleEntXform.Coordinates;
|
||||||
|
|
||||||
|
_transform.SetCoordinates(teleEnt, otherPos);
|
||||||
|
_transform.SetCoordinates(otherTeleEnt, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <remarks>
|
||||||
|
/// HYAH -link
|
||||||
|
/// </remarks>
|
||||||
|
public void DestroyLink(Entity<SwapTeleporterComponent?> ent, EntityUid? user)
|
||||||
|
{
|
||||||
|
if (!Resolve(ent, ref ent.Comp, false))
|
||||||
|
return;
|
||||||
|
var linkedNullable = ent.Comp.LinkedEnt;
|
||||||
|
|
||||||
|
ent.Comp.LinkedEnt = null;
|
||||||
|
ent.Comp.TeleportTime = null;
|
||||||
|
_appearance.SetData(ent, SwapTeleporterVisuals.Linked, false);
|
||||||
|
Dirty(ent, ent.Comp);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
_popup.PopupClient(Loc.GetString("swap-teleporter-popup-link-destroyed"), ent, user.Value);
|
||||||
|
else
|
||||||
|
_popup.PopupEntity(Loc.GetString("swap-teleporter-popup-link-destroyed"), ent);
|
||||||
|
|
||||||
|
if (linkedNullable is {} linked)
|
||||||
|
DestroyLink(linked, user); // the linked one is shown globally
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityUid GetTeleportingEntity(Entity<TransformComponent> ent)
|
||||||
|
{
|
||||||
|
var parent = ent.Comp.ParentUid;
|
||||||
|
|
||||||
|
if (HasComp<MapGridComponent>(parent) || HasComp<MapComponent>(parent))
|
||||||
|
return ent;
|
||||||
|
|
||||||
|
if (!_xformQuery.TryGetComponent(parent, out var parentXform) || parentXform.Anchored)
|
||||||
|
return ent;
|
||||||
|
|
||||||
|
if (!TryComp<PhysicsComponent>(parent, out var body) || body.BodyType == BodyType.Static)
|
||||||
|
return ent;
|
||||||
|
|
||||||
|
return GetTeleportingEntity((parent, parentXform));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnExamined(Entity<SwapTeleporterComponent> ent, ref ExaminedEvent args)
|
||||||
|
{
|
||||||
|
var (_, comp) = ent;
|
||||||
|
using (args.PushGroup(nameof(SwapTeleporterComponent)))
|
||||||
|
{
|
||||||
|
var locale = comp.LinkedEnt == null
|
||||||
|
? "swap-teleporter-examine-link-absent"
|
||||||
|
: "swap-teleporter-examine-link-present";
|
||||||
|
args.PushMarkup(Loc.GetString(locale));
|
||||||
|
|
||||||
|
if (_timing.CurTime < comp.NextTeleportUse)
|
||||||
|
{
|
||||||
|
args.PushMarkup(Loc.GetString("swap-teleporter-examine-time-remaining",
|
||||||
|
("second", (int) ((comp.NextTeleportUse - _timing.CurTime).TotalSeconds + 0.5f))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnUnpaused(Entity<SwapTeleporterComponent> ent, ref EntityUnpausedEvent args)
|
||||||
|
{
|
||||||
|
ent.Comp.NextTeleportUse += args.PausedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnShutdown(Entity<SwapTeleporterComponent> ent, ref ComponentShutdown args)
|
||||||
|
{
|
||||||
|
DestroyLink((ent, ent), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
var query = EntityQueryEnumerator<SwapTeleporterComponent, TransformComponent>();
|
||||||
|
while (query.MoveNext(out var uid, out var comp, out var xform))
|
||||||
|
{
|
||||||
|
if (comp.TeleportTime == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (_timing.CurTime < comp.TeleportTime)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DoTeleport((uid, comp, xform));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
Resources/Locale/en-US/portal/swap-teleporter.ftl
Normal file
17
Resources/Locale/en-US/portal/swap-teleporter.ftl
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
swap-teleporter-popup-link-create = Quantum link established!
|
||||||
|
swap-teleporter-popup-link-fail-already = Quantum link failed! Link already present on device.
|
||||||
|
swap-teleporter-popup-link-fail-already-other = Quantum link failed! Link already present on secondary device.
|
||||||
|
swap-teleporter-popup-link-destroyed = Quantum link destroyed!
|
||||||
|
swap-teleporter-popup-teleport-cancel-time = It's still recharging!
|
||||||
|
swap-teleporter-popup-teleport-cancel-link = It's not linked with another device!
|
||||||
|
swap-teleporter-popup-teleport-other = {CAPITALIZE(THE($entity))} activates, and you find yourself somewhere else.
|
||||||
|
|
||||||
|
swap-teleporter-verb-destroy-link = Destroy Quantum Link
|
||||||
|
|
||||||
|
swap-teleporter-examine-link-present = [color=forestgreen]It is linked to another device.[/color] Alt-Click to break the quantum link.
|
||||||
|
swap-teleporter-examine-link-absent = [color=yellow]It is not currently linked.[/color] Use on another device to establish a quantum link.
|
||||||
|
swap-teleporter-examine-time-remaining = Time left to recharge: [color=purple]{$second} second{$second ->
|
||||||
|
[one].
|
||||||
|
*[other]s.
|
||||||
|
}[/color]
|
||||||
|
|
||||||
@@ -56,6 +56,7 @@ research-technology-anomaly-harnessing = Anomaly Core Harnessing
|
|||||||
research-technology-grappling = Grappling
|
research-technology-grappling = Grappling
|
||||||
research-technology-abnormal-artifact-manipulation = Abnormal Artifact Manipulation
|
research-technology-abnormal-artifact-manipulation = Abnormal Artifact Manipulation
|
||||||
research-technology-gravity-manipulation = Gravity Manipulation
|
research-technology-gravity-manipulation = Gravity Manipulation
|
||||||
|
research-technology-quantum-leaping = Quantum Leaping
|
||||||
research-technology-advanced-anomaly-research = Advanced Anomaly Research
|
research-technology-advanced-anomaly-research = Advanced Anomaly Research
|
||||||
research-technology-rped = Rapid Part Exchange
|
research-technology-rped = Rapid Part Exchange
|
||||||
research-technology-super-parts = Super Parts
|
research-technology-super-parts = Super Parts
|
||||||
|
|||||||
27
Resources/Prototypes/Entities/Objects/Devices/swapper.yml
Normal file
27
Resources/Prototypes/Entities/Objects/Devices/swapper.yml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
- type: entity
|
||||||
|
parent: BaseItem
|
||||||
|
id: DeviceQuantumSpinInverter
|
||||||
|
name: quantum spin inverter
|
||||||
|
description: An experimental device that is able to swap the locations of two entities by switching their particles' spin values. Must be linked to another device to function.
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Devices/swapper.rsi
|
||||||
|
layers:
|
||||||
|
- state: icon
|
||||||
|
map: ["base"]
|
||||||
|
- type: Item
|
||||||
|
size: Small
|
||||||
|
- type: Appearance
|
||||||
|
- type: SwapTeleporter
|
||||||
|
teleporterWhitelist:
|
||||||
|
tags:
|
||||||
|
- QuantumSpinInverter
|
||||||
|
- type: GenericVisualizer
|
||||||
|
visuals:
|
||||||
|
enum.SwapTeleporterVisuals.Linked:
|
||||||
|
base:
|
||||||
|
True: { state: linked }
|
||||||
|
False: { state: icon }
|
||||||
|
- type: Tag
|
||||||
|
tags:
|
||||||
|
- QuantumSpinInverter
|
||||||
@@ -300,6 +300,7 @@
|
|||||||
- FauxTileAstroGrass
|
- FauxTileAstroGrass
|
||||||
- FauxTileAstroIce
|
- FauxTileAstroIce
|
||||||
- OreBagOfHolding
|
- OreBagOfHolding
|
||||||
|
- DeviceQuantumSpinInverter
|
||||||
- type: EmagLatheRecipes
|
- type: EmagLatheRecipes
|
||||||
emagDynamicRecipes:
|
emagDynamicRecipes:
|
||||||
- ExplosivePayload
|
- ExplosivePayload
|
||||||
|
|||||||
@@ -188,6 +188,15 @@
|
|||||||
Glass: 400
|
Glass: 400
|
||||||
Silver: 200
|
Silver: 200
|
||||||
|
|
||||||
|
- type: latheRecipe
|
||||||
|
id: DeviceQuantumSpinInverter
|
||||||
|
result: DeviceQuantumSpinInverter
|
||||||
|
completetime: 5
|
||||||
|
materials:
|
||||||
|
Steel: 700
|
||||||
|
Glass: 100
|
||||||
|
Uranium: 100
|
||||||
|
|
||||||
- type: latheRecipe
|
- type: latheRecipe
|
||||||
id: WeaponProtoKineticAccelerator
|
id: WeaponProtoKineticAccelerator
|
||||||
result: WeaponProtoKineticAccelerator
|
result: WeaponProtoKineticAccelerator
|
||||||
|
|||||||
@@ -152,3 +152,15 @@
|
|||||||
recipeUnlocks:
|
recipeUnlocks:
|
||||||
- WeaponForceGun
|
- WeaponForceGun
|
||||||
- WeaponTetherGun
|
- WeaponTetherGun
|
||||||
|
|
||||||
|
- type: technology
|
||||||
|
id: QuantumLeaping
|
||||||
|
name: research-technology-quantum-leaping
|
||||||
|
icon:
|
||||||
|
sprite: Objects/Devices/swapper.rsi
|
||||||
|
state: icon
|
||||||
|
discipline: Experimental
|
||||||
|
tier: 3
|
||||||
|
cost: 10000
|
||||||
|
recipeUnlocks:
|
||||||
|
- DeviceQuantumSpinInverter
|
||||||
|
|||||||
@@ -931,6 +931,9 @@
|
|||||||
- type: Tag
|
- type: Tag
|
||||||
id: ProximitySensor
|
id: ProximitySensor
|
||||||
|
|
||||||
|
- type: Tag
|
||||||
|
id: QuantumSpinInverter
|
||||||
|
|
||||||
- type: Tag
|
- type: Tag
|
||||||
id: Radio
|
id: Radio
|
||||||
|
|
||||||
|
|||||||
BIN
Resources/Textures/Objects/Devices/swapper.rsi/icon.png
Normal file
BIN
Resources/Textures/Objects/Devices/swapper.rsi/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 325 B |
BIN
Resources/Textures/Objects/Devices/swapper.rsi/inhand-left.png
Normal file
BIN
Resources/Textures/Objects/Devices/swapper.rsi/inhand-left.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 363 B |
BIN
Resources/Textures/Objects/Devices/swapper.rsi/inhand-right.png
Normal file
BIN
Resources/Textures/Objects/Devices/swapper.rsi/inhand-right.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 359 B |
BIN
Resources/Textures/Objects/Devices/swapper.rsi/linked.png
Normal file
BIN
Resources/Textures/Objects/Devices/swapper.rsi/linked.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 555 B |
36
Resources/Textures/Objects/Devices/swapper.rsi/meta.json
Normal file
36
Resources/Textures/Objects/Devices/swapper.rsi/meta.json
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "tgstation at https://github.com/tgstation/tgstation/commit/71a1fee2f13730adee5302d34bfa0f0262314d63",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "linked",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-left",
|
||||||
|
"directions": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "inhand-right",
|
||||||
|
"directions": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user