[Port] Playing Cards (#1451)

# Description

This ports Playing Cards from:
Estacao Pirata...
Frontier...
and GoobStation...

More specifically, ports
https://github.com/Goob-Station/Goob-Station/pull/1215 and
https://github.com/Goob-Station/Goob-Station/pull/1311 sequentially.

In short...
 - Adds 3 skins of the playing cards: Nanotrasen, Syndicate, and Black.
- NT can be obtained as an item in your loadout but is locked behind a
command job.
 - Syndicate can be obtained as a pointless item in the uplink for 1 TC.
- Black can be obtained both as an item in your loadout and from the
Games Vendor.

---

# TODO before review

<!--
A list of everything you have to do before this PR is "complete"
You probably won't have to complete everything before merging but it's
good to leave future references
-->

- [X] De-namespace all of (_)EstacaoPirata? (not required, it is an EE
fork)
- [X] **_TO MAINTAINERS/CONTRIBS, NEED YOUR INPUT!!!_**: See
`Content.Client/Inventory/StrippableBoundUserInterface.cs:220`'s "DRAFT
TODO". Basically its me asking how to involve the thieving trait in the
omission of the playing cards in the strip menu. Currently, it does not
take into account the trait and simply obscures. (prolly dont take the
trait into account, obscure regardless)
- [X] Figure out what to do with the Nanotrasen deck variant: should it
remain free like the black deck or restricted like the syndicate? Locked
behind any command job? (prolly this)
- [X] Get media actually filled in

---

<!--
This is default collapsed, readers click to expand it and see all your
media
The PR media section can get very large at times, so this is a good way
to keep it clean
The title is written using HTML tags
The title must be within the <summary> tags or you won't see it
-->

<details><summary><h1>Media</h1></summary>
<p>

![image](https://github.com/user-attachments/assets/66c94a1d-4389-4a65-a547-c11c54efac42)

</p>
</details>

---

# Changelog

<!--
You can add an author after the `🆑` to change the name that appears
in the changelog (ex: `🆑 Death`)
Leaving it blank will default to your GitHub display name
This includes all available types for the changelog
-->

🆑
- add: Playing Cards. You may get one in the Games Vendor or as an item
in your loadout.

---------

Co-authored-by: VMSolidus <evilexecutive@gmail.com>
(cherry picked from commit 9b5cce20f185d8da3cdddd2fa6cad14ccd38db77)
This commit is contained in:
RadsammyT
2025-01-25 13:34:14 -05:00
committed by Spatison
parent d6697927b2
commit bb612d3ac7
251 changed files with 4949 additions and 2 deletions

View File

@@ -6,6 +6,8 @@ using Content.Client.Stylesheets;
using Content.Client.UserInterface.Controls;
using Content.Client.UserInterface.Systems.Hands.Controls;
using Content.Client.Verbs.UI;
using Content.Shared._EstacaoPirata.Cards.Card;
using Content.Shared._EstacaoPirata.Cards.Hand;
using Content.Shared.Cuffs;
using Content.Shared.Cuffs.Components;
using Content.Shared.Ensnaring.Components;
@@ -173,8 +175,7 @@ namespace Content.Client.Inventory
if (EntMan.TryGetComponent<CuffableComponent>(Owner, out var cuff) && _cuffable.GetAllCuffs(cuff).Contains(virt.BlockingEntity))
button.BlockedRect.MouseFilter = MouseFilterMode.Ignore;
}
UpdateEntityIcon(button, hand.HeldEntity);
UpdateEntityIcon(button, EntMan.HasComponent<StripMenuHiddenComponent>(hand.HeldEntity) ? _virtualHiddenEntity : hand.HeldEntity);
_strippingMenu!.HandsContainer.AddChild(button);
}
@@ -213,6 +214,10 @@ namespace Content.Client.Inventory
&& thiefComponent.IgnoreStripHidden))
entity = _virtualHiddenEntity;
if (entity != null && EntMan.HasComponent<StripMenuHiddenComponent>(entity))
entity = _virtualHiddenEntity;
var button = new SlotButton(new SlotData(slotDef, container));
button.Pressed += SlotPressed;

View File

@@ -0,0 +1,78 @@
using System.Linq;
using Content.Shared._EstacaoPirata.Cards.Card;
using Robust.Client.GameObjects;
using Robust.Shared.Utility;
namespace Content.Client._EstacaoPirata.Cards.Card;
/// <summary>
/// This handles...
/// </summary>
public sealed class CardSystem : EntitySystem
{
[Dependency] private readonly SpriteSystem _spriteSystem = default!;
[Dependency] private readonly CardSpriteSystem _cardSpriteSystem = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<CardComponent, ComponentStartup>(OnComponentStartupEvent);
SubscribeNetworkEvent<CardFlipUpdatedEvent>(OnFlip);
}
private void OnComponentStartupEvent(EntityUid uid, CardComponent comp, ComponentStartup args)
{
if (!TryComp(uid, out SpriteComponent? spriteComponent))
return;
for (var i = 0; i < spriteComponent.AllLayers.Count(); i++)
{
//Log.Debug($"Layer {i}");
if (!spriteComponent.TryGetLayer(i, out var layer) || layer.State.Name == null)
continue;
var rsi = layer.RSI ?? spriteComponent.BaseRSI;
if (rsi == null)
continue;
//Log.Debug("FOI");
comp.FrontSprite.Add(new SpriteSpecifier.Rsi(rsi.Path, layer.State.Name));
}
comp.BackSprite ??= comp.FrontSprite;
DirtyEntity(uid);
UpdateSprite(uid, comp);
}
private void OnFlip(CardFlipUpdatedEvent args)
{
if (!TryComp(GetEntity(args.Card), out CardComponent? comp))
return;
UpdateSprite(GetEntity(args.Card), comp);
}
private void UpdateSprite(EntityUid uid, CardComponent comp)
{
var newSprite = comp.Flipped ? comp.BackSprite : comp.FrontSprite;
//if (newSprite == null)
// return;
if (!TryComp(uid, out SpriteComponent? spriteComponent))
return;
var layerCount = newSprite.Count();
//inserts Missing Layers
if (spriteComponent.AllLayers.Count() < layerCount)
for (var i = spriteComponent.AllLayers.Count(); i < layerCount; i++)
spriteComponent.AddBlankLayer(i);
//Removes extra layers
else if (spriteComponent.AllLayers.Count() > layerCount)
for (var i = spriteComponent.AllLayers.Count() - 1; i >= layerCount; i--)
spriteComponent.RemoveLayer(i);
for (var i = 0; i < newSprite.Count(); i++)
{
var layer = newSprite[i];
spriteComponent.LayerSetSprite(i, layer);
}
}
}

View File

@@ -0,0 +1,76 @@
using System.Linq;
using Content.Shared._EstacaoPirata.Cards.Stack;
using Robust.Client.GameObjects;
namespace Content.Client._EstacaoPirata.Cards;
/// <summary>
/// This handles...
/// </summary>
public sealed class CardSpriteSystem : EntitySystem
{
/// <inheritdoc/>
public override void Initialize() { }
public bool TryAdjustLayerQuantity(Entity<SpriteComponent, CardStackComponent> uid, int? cardLimit = null)
{
var sprite = uid.Comp1;
var stack = uid.Comp2;
var cardCount = cardLimit == null ? stack.Cards.Count : Math.Min(stack.Cards.Count, cardLimit.Value);
var layerCount = 0;
//Gets the quantity of layers
var relevantCards = stack.Cards.TakeLast(cardCount).ToList();
foreach (var card in relevantCards)
{
if (!TryComp(card, out SpriteComponent? cardSprite))
return false;
layerCount += cardSprite.AllLayers.Count();
}
layerCount = int.Max(1, layerCount); // Frontier: you need one layer.
//inserts Missing Layers
if (sprite.AllLayers.Count() < layerCount)
for (var i = sprite.AllLayers.Count(); i < layerCount; i++)
sprite.AddBlankLayer(i);
//Removes extra layers
else if (sprite.AllLayers.Count() > layerCount)
for (var i = sprite.AllLayers.Count() - 1; i >= layerCount; i--)
sprite.RemoveLayer(i);
return true;
}
public bool TryHandleLayerConfiguration(Entity<SpriteComponent, CardStackComponent> uid, int cardCount, Func<Entity<SpriteComponent>, int, int, bool> layerFunc)
{
var sprite = uid.Comp1;
var stack = uid.Comp2;
// int = index of what card it is from
List<(int, ISpriteLayer)> layers = [];
var i = 0;
var cards = stack.Cards.TakeLast(cardCount).ToList();
foreach (var card in cards)
{
if (!TryComp(card, out SpriteComponent? cardSprite))
return false;
layers.AddRange(cardSprite.AllLayers.Select(layer => (i, layer)));
i++;
}
var j = 0;
foreach (var obj in layers)
{
var (cardIndex, layer) = obj;
sprite.LayerSetVisible(j, true);
sprite.LayerSetTexture(j, layer.Texture);
sprite.LayerSetState(j, layer.RsiState.Name);
layerFunc.Invoke((uid, sprite), cardIndex, j);
j++;
}
return true;
}
}

View File

@@ -0,0 +1,151 @@
using System.Linq;
using System.Numerics;
using Content.Shared._EstacaoPirata.Cards.Deck;
using Content.Shared._EstacaoPirata.Cards.Stack;
using Robust.Client.GameObjects;
namespace Content.Client._EstacaoPirata.Cards.Deck;
/// <summary>
/// This handles...
/// </summary>
public sealed class CardDeckSystem : EntitySystem
{
private readonly Dictionary<Entity<CardDeckComponent>, int> _notInitialized = [];
[Dependency] private readonly CardSpriteSystem _cardSpriteSystem = default!;
/// <inheritdoc/>
public override void Initialize()
{
UpdatesOutsidePrediction = false;
SubscribeLocalEvent<CardDeckComponent, ComponentStartup>(OnComponentStartupEvent);
SubscribeNetworkEvent<CardStackInitiatedEvent>(OnStackStart);
SubscribeNetworkEvent<CardStackQuantityChangeEvent>(OnStackUpdate);
SubscribeNetworkEvent<CardStackReorderedEvent>(OnReorder);
SubscribeNetworkEvent<CardStackFlippedEvent>(OnStackFlip);
SubscribeLocalEvent<CardDeckComponent, AppearanceChangeEvent>(OnAppearanceChanged);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
// Lazy way to make sure the sprite starts correctly
foreach (var kv in _notInitialized)
{
var ent = kv.Key;
if (kv.Value >= 5)
{
_notInitialized.Remove(ent);
continue;
}
_notInitialized[ent] = kv.Value + 1;
if (!TryComp(ent.Owner, out CardStackComponent? stack) || stack.Cards.Count <= 0)
continue;
// If the card was STILL not initialized, we skip it
if (!TryGetCardLayer(stack.Cards.Last(), out var _))
continue;
// If cards were correctly initialized, we update the sprite
UpdateSprite(ent.Owner, ent.Comp);
_notInitialized.Remove(ent);
}
}
private bool TryGetCardLayer(EntityUid card, out SpriteComponent.Layer? layer)
{
layer = null;
if (!TryComp(card, out SpriteComponent? cardSprite)
|| !cardSprite.TryGetLayer(0, out var l))
return false;
layer = l;
return true;
}
private void UpdateSprite(EntityUid uid, CardDeckComponent comp)
{
if (!TryComp(uid, out SpriteComponent? sprite)
|| !TryComp(uid, out CardStackComponent? cardStack))
return;
// Prevents error appearing at spawnMenu
if (cardStack.Cards.Count <= 0 || !TryGetCardLayer(cardStack.Cards.Last(), out var cardlayer) ||
cardlayer == null)
{
_notInitialized[(uid, comp)] = 0;
return;
}
_cardSpriteSystem.TryAdjustLayerQuantity((uid, sprite, cardStack), comp.CardLimit);
_cardSpriteSystem.TryHandleLayerConfiguration(
(uid, sprite, cardStack),
comp.CardLimit,
(_, cardIndex, layerIndex) =>
{
sprite.LayerSetRotation(layerIndex, Angle.FromDegrees(90));
sprite.LayerSetOffset(layerIndex, new Vector2(0, (comp.YOffset * cardIndex)));
sprite.LayerSetScale(layerIndex, new Vector2(comp.Scale, comp.Scale));
return true;
}
);
}
private void OnStackUpdate(CardStackQuantityChangeEvent args)
{
if (!TryComp(GetEntity(args.Stack), out CardDeckComponent? comp))
return;
UpdateSprite(GetEntity(args.Stack), comp);
}
private void OnStackFlip(CardStackFlippedEvent args)
{
if (!TryComp(GetEntity(args.CardStack), out CardDeckComponent? comp))
return;
UpdateSprite(GetEntity(args.CardStack), comp);
}
private void OnReorder(CardStackReorderedEvent args)
{
if (!TryComp(GetEntity(args.Stack), out CardDeckComponent? comp))
return;
UpdateSprite(GetEntity(args.Stack), comp);
}
private void OnAppearanceChanged(EntityUid uid, CardDeckComponent comp, AppearanceChangeEvent args)
{
UpdateSprite(uid, comp);
}
private void OnComponentStartupEvent(EntityUid uid, CardDeckComponent comp, ComponentStartup args)
{
if (!TryComp(uid, out CardStackComponent? stack))
{
_notInitialized[(uid, comp)] = 0;
return;
}
if(stack.Cards.Count <= 0)
_notInitialized[(uid, comp)] = 0;
UpdateSprite(uid, comp);
}
private void OnStackStart(CardStackInitiatedEvent args)
{
var entity = GetEntity(args.CardStack);
if (!TryComp(entity, out CardDeckComponent? comp))
return;
UpdateSprite(entity, comp);
}
}

View File

@@ -0,0 +1,167 @@
using System.Linq;
using System.Numerics;
using Content.Shared._EstacaoPirata.Cards.Hand;
using Content.Shared._EstacaoPirata.Cards.Stack;
using Robust.Client.GameObjects;
namespace Content.Client._EstacaoPirata.Cards.Hand;
/// <summary>
/// This handles...
/// </summary>
public sealed class CardHandSystem : EntitySystem
{
private readonly Dictionary<Entity<CardHandComponent>, int> _notInit = [];
[Dependency] private readonly CardSpriteSystem _cardSpriteSystem = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<CardHandComponent, ComponentStartup>(OnComponentStartupEvent);
SubscribeNetworkEvent<CardStackInitiatedEvent>(OnStackStart);
SubscribeNetworkEvent<CardStackQuantityChangeEvent>(OnStackUpdate);
SubscribeNetworkEvent<CardStackReorderedEvent>(OnStackReorder);
SubscribeNetworkEvent<CardStackFlippedEvent>(OnStackFlip);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
foreach (var (ent, value) in _notInit)
{
if (value >= 5)
{
_notInit.Remove(ent);
continue;
}
_notInit[ent] = value + 1;
if(!TryComp(ent.Owner, out CardStackComponent? stack) || stack.Cards.Count <= 0)
continue;
// If cards were correctly initialized, we update the sprite
UpdateSprite(ent.Owner, ent.Comp);
_notInit.Remove(ent);
}
}
private bool TryGetCardLayer(EntityUid card, out SpriteComponent.Layer? layer)
{
layer = null;
if (!TryComp(card, out SpriteComponent? cardSprite)
|| !cardSprite.TryGetLayer(0, out var l))
return false;
layer = l;
return true;
}
private void UpdateSprite(EntityUid uid, CardHandComponent comp)
{
if (!TryComp(uid, out SpriteComponent? sprite)
|| !TryComp(uid, out CardStackComponent? cardStack))
return;
// Prevents error appearing at spawnMenu
if (cardStack.Cards.Count <= 0 || !TryGetCardLayer(cardStack.Cards.Last(), out var cardlayer) ||
cardlayer == null)
{
_notInit[(uid, comp)] = 0;
return;
}
_cardSpriteSystem.TryAdjustLayerQuantity((uid, sprite, cardStack), comp.CardLimit);
var cardCount = Math.Min(cardStack.Cards.Count, comp.CardLimit);
// Frontier: zero/one card case
if (cardCount <= 0)
{
// Placeholder - we need to have a valid sprite.
sprite.LayerSetVisible(0, true);
sprite.LayerSetState(0, "singlecard_down_black");
sprite.LayerSetOffset(0, new Vector2(0f, 0f));
sprite.LayerSetScale(0, new Vector2(1f, 1f));
}
else if (cardCount == 1)
{
_cardSpriteSystem.TryHandleLayerConfiguration(
(uid, sprite, cardStack),
cardCount,
(sprt, cardIndex, layerIndex) =>
{
sprt.Comp.LayerSetRotation(layerIndex, Angle.FromDegrees(0));
sprt.Comp.LayerSetOffset(layerIndex, new Vector2(0, 0.10f));
sprt.Comp.LayerSetScale(layerIndex, new Vector2(comp.Scale, comp.Scale));
return true;
}
);
}
else
{
var intervalAngle = comp.Angle / (cardCount-1);
var intervalSize = comp.XOffset / (cardCount - 1);
_cardSpriteSystem.TryHandleLayerConfiguration(
(uid, sprite, cardStack),
cardCount,
(sprt, cardIndex, layerIndex) =>
{
var angle = (-(comp.Angle/2)) + cardIndex * intervalAngle;
var x = (-(comp.XOffset / 2)) + cardIndex * intervalSize;
var y = -(x * x) + 0.10f;
sprt.Comp.LayerSetRotation(layerIndex, Angle.FromDegrees(-angle));
sprt.Comp.LayerSetOffset(layerIndex, new Vector2(x, y));
sprt.Comp.LayerSetScale(layerIndex, new Vector2(comp.Scale, comp.Scale));
return true;
}
);
}
}
private void OnStackUpdate(CardStackQuantityChangeEvent args)
{
if (!TryComp(GetEntity(args.Stack), out CardHandComponent? comp))
return;
UpdateSprite(GetEntity(args.Stack), comp);
}
private void OnStackStart(CardStackInitiatedEvent args)
{
var entity = GetEntity(args.CardStack);
if (!TryComp(entity, out CardHandComponent? comp))
return;
UpdateSprite(entity, comp);
}
private void OnComponentStartupEvent(EntityUid uid, CardHandComponent comp, ComponentStartup args)
{
if (!TryComp(uid, out CardStackComponent? stack))
{
_notInit[(uid, comp)] = 0;
return;
}
if(stack.Cards.Count <= 0)
_notInit[(uid, comp)] = 0;
UpdateSprite(uid, comp);
}
// Frontier
private void OnStackReorder(CardStackReorderedEvent args)
{
if (!TryComp(GetEntity(args.Stack), out CardHandComponent? comp))
return;
UpdateSprite(GetEntity(args.Stack), comp);
}
private void OnStackFlip(CardStackFlippedEvent args)
{
var entity = GetEntity(args.CardStack);
if (!TryComp(entity, out CardHandComponent? comp))
return;
UpdateSprite(entity, comp);
}
}

View File

@@ -0,0 +1,12 @@
<ui:RadialMenu xmlns="https://spacestation14.io"
xmlns:ui="clr-namespace:Content.Client.UserInterface.Controls"
xmlns:cardhand="Content.Client._EstacaoPirata.Cards.Hand.UI"
BackButtonStyleClass="RadialMenuBackButton"
CloseButtonStyleClass="RadialMenuCloseButton"
VerticalExpand="True"
HorizontalExpand="True"
MinSize="450 450">
<ui:RadialContainer Name="Main" VerticalExpand="True" HorizontalExpand="True" Radius="64" ReserveSpaceForHiddenChildren="False"></ui:RadialContainer>
</ui:RadialMenu>

View File

@@ -0,0 +1,97 @@
using Content.Client.UserInterface.Controls;
using Content.Shared.Popups;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using System.Numerics;
using Content.Shared._EstacaoPirata.Cards.Card;
using Content.Shared._EstacaoPirata.Cards.Stack;
namespace Content.Client._EstacaoPirata.Cards.Hand.UI;
[GenerateTypedNameReferences]
public sealed partial class CardHandMenu : RadialMenu
{
[Dependency] private readonly EntityManager _entManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
private readonly SpriteSystem _spriteSystem;
private readonly SharedPopupSystem _popup;
public event Action<NetEntity>? CardHandDrawMessageAction;
private EntityUid _owner;
public CardHandMenu(EntityUid owner, CardHandMenuBoundUserInterface bui)
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
_spriteSystem = _entManager.System<SpriteSystem>();
_popup = _entManager.System<SharedPopupSystem>();
_owner = owner;
// Find the main radial container
var main = FindControl<RadialContainer>("Main");
if (!_entManager.TryGetComponent<CardStackComponent>(owner, out var stack))
return;
foreach (var card in stack.Cards)
{
if (_playerManager.LocalSession == null
|| !_entManager.TryGetComponent<CardComponent>(card, out var cardComp))
return;
string cardName;
if (cardComp.Flipped && _entManager.TryGetComponent<MetaDataComponent>(card, out var metadata))
cardName = metadata.EntityName;
else
cardName = Loc.GetString(cardComp.Name);
var button = new CardMenuButton()
{
StyleClasses = { "RadialMenuButton" },
SetSize = new Vector2(64f, 64f),
ToolTip = cardName,
};
if (_entManager.TryGetComponent<SpriteComponent>(card, out var sprite))
{
if (sprite.Icon == null)
continue;
var tex = new TextureRect()
{
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center,
Texture = sprite.Icon?.Default,
TextureScale = new Vector2(2f, 2f),
};
button.AddChild(tex);
}
main.AddChild(button);
button.OnButtonUp += _ =>
{
CardHandDrawMessageAction?.Invoke(_entManager.GetNetEntity(card));
Close();
};
}
CardHandDrawMessageAction += bui.SendCardHandDrawMessage;
}
}
public sealed class CardMenuButton : RadialMenuTextureButton
{
public CardMenuButton()
{
}
}

View File

@@ -0,0 +1,44 @@
using Content.Shared._EstacaoPirata.Cards.Hand;
using Content.Shared.RCD;
using JetBrains.Annotations;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Shared.Prototypes;
namespace Content.Client._EstacaoPirata.Cards.Hand.UI;
[UsedImplicitly]
public sealed class CardHandMenuBoundUserInterface : BoundUserInterface
{
[Dependency] private readonly IClyde _displayManager = default!;
[Dependency] private readonly IInputManager _inputManager = default!;
private CardHandMenu? _menu;
public CardHandMenuBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
{
IoCManager.InjectDependencies(this);
}
protected override void Open()
{
base.Open();
_menu = new(Owner, this);
_menu.OnClose += Close;
// Open the menu, centered on the mouse
var vpSize = _displayManager.ScreenSize;
_menu.OpenCenteredAt(_inputManager.MouseScreenPosition.Position / vpSize);
}
public void SendCardHandDrawMessage(NetEntity e) => SendMessage(new CardHandDrawMessage(e));
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing) return;
_menu?.Dispose();
}
}

View File

@@ -0,0 +1,14 @@
using Content.Shared.Storage;
using Robust.Shared.Prototypes;
namespace Content.Server._EstacaoPirata.OpenTriggeredStorageFill;
/// <summary>
/// This is used for storing an item prototype to be inserted into a container when the trigger is activated. This is deleted from the entity after the item is inserted.
/// </summary>
[RegisterComponent]
public sealed partial class OpenTriggeredStorageFillComponent : Component
{
[DataField]
public List<EntitySpawnEntry> Contents = new();
}

View File

@@ -0,0 +1,67 @@
using Content.Server.Popups;
using Content.Server.Spawners.Components;
using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Item;
using Content.Shared.Localizations;
using Content.Shared.Prototypes;
using Content.Shared.Storage;
using Content.Shared.Storage.EntitySystems;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server._EstacaoPirata.OpenTriggeredStorageFill;
/// <summary>
/// This handles...
/// </summary>
public sealed class OpenTriggeredStorageFillSystem : EntitySystem
{
[Dependency] private readonly SharedStorageSystem _storage = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<OpenTriggeredStorageFillComponent, ActivateInWorldEvent>(OnOpenEvent);
SubscribeLocalEvent<OpenTriggeredStorageFillComponent, ExaminedEvent>(OnExamineEvent);
}
private void OnExamineEvent(EntityUid uid, OpenTriggeredStorageFillComponent component, ExaminedEvent args)
{
args.PushText(Loc.GetString("container-sealed"));
}
//Yes, that's a copy of StorageSystem StorageFill method
private void OnOpenEvent(EntityUid uid, OpenTriggeredStorageFillComponent comp, ActivateInWorldEvent args)
{
Log.Debug($"Processing storage fill trigger for entity {ToPrettyString(uid)}");
var coordinates = Transform(uid).Coordinates;
var spawnItems = EntitySpawnCollection.GetSpawns(comp.Contents);
foreach (var item in spawnItems)
{
DebugTools.Assert(!_prototype.Index<EntityPrototype>(item)
.HasComponent(typeof(RandomSpawnerComponent)));
var ent = Spawn(item, coordinates);
if (!TryComp<ItemComponent>(ent, out var itemComp))
{
Log.Error($"Tried to fill {ToPrettyString(uid)} with non-item {item}.");
Del(ent);
continue;
}
if (!_storage.Insert(uid, ent, out var remainingEnt, out var reason, playSound: false))
{
Log.Error($"Failed to fill {ToPrettyString(uid)} with {ToPrettyString(ent)}. Reason: {reason}");
// Clean up the spawned entity if insertion fails
Del(ent);
}
}
_popup.PopupEntity(Loc.GetString("container-unsealed"), args.Target);
RemComp(uid, comp);
}
}

View File

@@ -0,0 +1,10 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Strip.Components;
/// <summary>
/// An item with this component is always hidden in the strip menu, regardless of other circumstances.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class StripMenuHiddenComponent : Component;

View File

@@ -0,0 +1,44 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
namespace Content.Shared._EstacaoPirata.Cards.Card;
/// <summary>
/// This is used for...
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class CardComponent : Component
{
/// <summary>
/// The back of the card
/// </summary>
[DataField(readOnly: true)]
public List<SpriteSpecifier> BackSprite = [];
/// <summary>
/// The front of the card
/// </summary>
[DataField(readOnly: true)]
public List<SpriteSpecifier> FrontSprite = [];
/// <summary>
/// If it is currently flipped. This is used to update sprite and name.
/// </summary>
[DataField(readOnly: true), AutoNetworkedField]
public bool Flipped = false;
/// <summary>
/// The name of the card.
/// </summary>
[DataField(readOnly: true), AutoNetworkedField]
public string Name = "";
}
[Serializable, NetSerializable]
public sealed class CardFlipUpdatedEvent(NetEntity card) : EntityEventArgs
{
public NetEntity Card = card;
}

View File

@@ -0,0 +1,223 @@
using Content.Shared._EstacaoPirata.Cards.Deck;
using Content.Shared._EstacaoPirata.Cards.Hand;
using Content.Shared._EstacaoPirata.Cards.Stack;
using Content.Shared.Examine;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Interaction.Events;
using Content.Shared.Verbs;
using Robust.Shared.Containers;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Shared._EstacaoPirata.Cards.Card;
/// <summary>
/// This handles...
/// </summary>
public sealed class CardSystem : EntitySystem
{
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly CardStackSystem _cardStack = default!;
[Dependency] private readonly CardDeckSystem _cardDeck = default!;
[Dependency] private readonly CardHandSystem _cardHand = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<CardComponent, GetVerbsEvent<AlternativeVerb>>(AddTurnOnVerb);
SubscribeLocalEvent<CardComponent, GetVerbsEvent<ActivationVerb>>(OnActivationVerb);
SubscribeLocalEvent<CardComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<CardComponent, UseInHandEvent>(OnUse);
SubscribeLocalEvent<CardComponent, ActivateInWorldEvent>(OnActivate);
}
private void OnExamined(EntityUid uid, CardComponent component, ExaminedEvent args)
{
if (args.IsInDetailsRange && !component.Flipped)
{
args.PushMarkup(Loc.GetString("card-examined", ("target", Loc.GetString(component.Name))));
}
}
private void AddTurnOnVerb(EntityUid uid, CardComponent component, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanAccess || !args.CanInteract || args.Hands == null)
return;
args.Verbs.Add(new AlternativeVerb()
{
Act = () => FlipCard(uid, component),
Text = Loc.GetString("cards-verb-flip"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/flip.svg.192dpi.png")),
Priority = 1
});
if (args.Using == null || args.Using == args.Target)
return;
if (TryComp<CardStackComponent>(args.Using, out var usingStack))
{
args.Verbs.Add(new AlternativeVerb()
{
Act = () => JoinCards(args.User, args.Target, component, (EntityUid)args.Using, usingStack),
Text = Loc.GetString("card-verb-join"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/refresh.svg.192dpi.png")),
Priority = 2
});
}
else if (TryComp<CardComponent>(args.Using, out var usingCard))
{
var pickup = _hands.IsHolding(args.User, args.Target);
args.Verbs.Add(new AlternativeVerb()
{
Act = () => _cardHand.TrySetupHandOfCards(args.User, args.Target, component, args.Using.Value, usingCard, pickup),
Text = Loc.GetString("card-verb-join"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/refresh.svg.192dpi.png")),
Priority = 2
});
}
}
private void OnUse(EntityUid uid, CardComponent comp, UseInHandEvent args)
{
if (args.Handled)
return;
FlipCard(uid, comp);
args.Handled = true;
}
/// <summary>
/// Server-Side only method to flip card. This starts CardFlipUpdatedEvent event
/// </summary>
/// <param name="uid"></param>
/// <param name="component"></param>
private void FlipCard(EntityUid uid, CardComponent component)
{
if (_net.IsClient)
return;
component.Flipped = !component.Flipped;
Dirty(uid, component);
RaiseNetworkEvent(new CardFlipUpdatedEvent(GetNetEntity(uid)));
}
private void JoinCards(EntityUid user, EntityUid first, CardComponent firstComp, EntityUid second, CardStackComponent secondStack)
{
if (_net.IsClient)
return;
bool pickup = _hands.IsHolding(user, first);
EntityUid cardStack;
bool? flip = null;
if (HasComp<CardDeckComponent>(second))
{
cardStack = SpawnInSameParent(_cardDeck.CardDeckBaseName, first);
}
else if (HasComp<CardHandComponent>(second))
{
cardStack = SpawnInSameParent(_cardHand.CardHandBaseName, first);
if(TryComp<CardHandComponent>(cardStack, out var stackHand))
stackHand.Flipped = firstComp.Flipped;
flip = firstComp.Flipped;
}
else
return;
if (!TryComp(cardStack, out CardStackComponent? stack))
return;
if (!_cardStack.TryInsertCard(cardStack, first, stack))
return;
_cardStack.TransferNLastCardFromStacks(user, secondStack.Cards.Count, second, secondStack, cardStack, stack);
if (flip != null)
_cardStack.FlipAllCards(cardStack, stack, flip); //???
if(pickup)
_hands.TryPickupAnyHand(user, cardStack);
}
// Frontier: tries to spawn an entity with the same parent as another given entity.
// Useful when spawning decks/hands in a backpack, for example.
private EntityUid SpawnInSameParent(EntProtoId prototype, EntityUid uid)
{
if (_container.IsEntityOrParentInContainer(uid) &&
_container.TryGetOuterContainer(uid, Transform(uid), out var container))
{
return SpawnInContainerOrDrop(prototype, container.Owner, container.ID);
}
return Spawn(prototype, Transform(uid).Coordinates);
}
// Frontier: hacky misuse of the activation verb, but allows us a separate way to draw cards without needing additional buttons and event fiddling
private void OnActivationVerb(EntityUid uid, CardComponent component, GetVerbsEvent<ActivationVerb> args)
{
if (!args.CanAccess || !args.CanInteract || args.Hands == null)
return;
if (args.Using == args.Target)
return;
if (HasComp<CardStackComponent>(uid))
return;
if (args.Using == null)
{
args.Verbs.Add(new ActivationVerb()
{
Act = () => _hands.TryPickupAnyHand(args.User, args.Target),
Text = Loc.GetString("cards-verb-draw"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")),
Priority = 16
});
}
else if (TryComp<CardStackComponent>(args.Using, out var cardStack))
{
args.Verbs.Add(new ActivationVerb()
{
Act = () => _cardStack.InsertCardOnStack(args.User, args.Using.Value, cardStack, args.Target),
Text = Loc.GetString("cards-verb-draw"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")),
Priority = 16
});
}
else if (TryComp<CardComponent>(args.Using, out var card))
{
args.Verbs.Add(new ActivationVerb()
{
Act = () => _cardHand.TrySetupHandOfCards(args.User, args.Using.Value, card, args.Target, component, true),
Text = Loc.GetString("cards-verb-draw"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")),
Priority = 16
});
}
}
// End Frontier
private void OnActivate(EntityUid uid, CardComponent component, ActivateInWorldEvent args)
{
if (!args.Complex || args.Handled)
return;
if (!TryComp<HandsComponent>(args.User, out var hands))
return;
// Card stacks are handled differently
if (HasComp<CardStackComponent>(args.Target))
return;
var activeItem = _hands.GetActiveItem((args.User, hands));
if (activeItem == null)
{
_hands.TryPickupAnyHand(args.User, args.Target);
}
else if (TryComp<CardStackComponent>(activeItem, out var cardStack))
{
_cardStack.InsertCardOnStack(args.User, activeItem.Value, cardStack, args.Target);
}
else if (TryComp<CardComponent>(activeItem, out var card))
{
_cardHand.TrySetupHandOfCards(args.User, activeItem.Value, card, args.Target, component, true);
}
}
}

View File

@@ -0,0 +1,28 @@
using Robust.Shared.Audio;
namespace Content.Shared._EstacaoPirata.Cards.Deck;
/// <summary>
/// This is used for...
/// </summary>
[RegisterComponent]
public sealed partial class CardDeckComponent : Component
{
[DataField]
public SoundSpecifier ShuffleSound = new SoundCollectionSpecifier("cardFan");
[DataField]
public SoundSpecifier PickUpSound = new SoundCollectionSpecifier("cardSlide");
[DataField]
public SoundSpecifier PlaceDownSound = new SoundCollectionSpecifier("cardShove");
[DataField]
public float YOffset = 0.02f;
[DataField]
public float Scale = 1;
[DataField]
public int CardLimit = 5;
}

View File

@@ -0,0 +1,123 @@
using Content.Shared._EstacaoPirata.Cards.Card;
using Content.Shared._EstacaoPirata.Cards.Stack;
using Content.Shared.Audio;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Item;
using Content.Shared.Popups;
using Content.Shared.Verbs;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Random;
using Robust.Shared.Utility;
namespace Content.Shared._EstacaoPirata.Cards.Deck;
/// <summary>
/// This handles card decks
/// </summary>
public sealed class CardDeckSystem : EntitySystem
{
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly CardStackSystem _cardStackSystem = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
public readonly EntProtoId CardDeckBaseName = "CardDeckBase";
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<CardDeckComponent, GetVerbsEvent<AlternativeVerb>>(AddTurnOnVerb);
}
private void AddTurnOnVerb(EntityUid uid, CardDeckComponent component, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanAccess || !args.CanInteract || args.Hands == null)
return;
if (!TryComp(uid, out CardStackComponent? comp))
return;
args.Verbs.Add(new AlternativeVerb()
{
Act = () => TryShuffle(uid, component, comp),
Text = Loc.GetString("cards-verb-shuffle"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/die.svg.192dpi.png")),
Priority = 4
});
args.Verbs.Add(new AlternativeVerb()
{
Act = () => TrySplit(args.Target, component, comp, args.User),
Text = Loc.GetString("cards-verb-split"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/dot.svg.192dpi.png")),
Priority = 3
});
args.Verbs.Add(new AlternativeVerb()
{
Act = () => TryOrganize(uid, component, comp, true),
Text = Loc.GetString("cards-verb-organize-down"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/flip.svg.192dpi.png")),
Priority = 2
});
args.Verbs.Add(new AlternativeVerb()
{
Act = () => TryOrganize(uid, component, comp, false),
Text = Loc.GetString("cards-verb-organize-up"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/flip.svg.192dpi.png")),
Priority = 1
});
}
private void TrySplit(EntityUid uid, CardDeckComponent deck, CardStackComponent stack, EntityUid user)
{
if (stack.Cards.Count <= 1)
return;
_audio.PlayPredicted(deck.PickUpSound, Transform(uid).Coordinates, user);
if (!_net.IsServer)
return;
var cardDeck = SpawnInSameParent(CardDeckBaseName, uid);
EnsureComp<CardStackComponent>(cardDeck, out var deckStack);
_cardStackSystem.TransferNLastCardFromStacks(user, stack.Cards.Count / 2, uid, stack, cardDeck, deckStack);
_hands.PickupOrDrop(user, cardDeck);
}
private void TryShuffle(EntityUid deck, CardDeckComponent comp, CardStackComponent? stack)
{
_cardStackSystem.ShuffleCards(deck, stack);
if (_net.IsClient)
return;
_audio.PlayPvs(comp.ShuffleSound, deck, AudioHelpers.WithVariation(0.05f, _random));
_popup.PopupEntity(Loc.GetString("card-verb-shuffle-success", ("target", MetaData(deck).EntityName)), deck);
}
private void TryOrganize(EntityUid deck, CardDeckComponent comp, CardStackComponent? stack, bool isFlipped)
{
if (_net.IsClient)
return;
_cardStackSystem.FlipAllCards(deck, stack, isFlipped: isFlipped);
_audio.PlayPvs(comp.ShuffleSound, deck, AudioHelpers.WithVariation(0.05f, _random));
_popup.PopupEntity(Loc.GetString("card-verb-organize-success", ("target", MetaData(deck).EntityName), ("facedown", isFlipped)), deck);
}
private EntityUid SpawnInSameParent(string prototype, EntityUid uid)
{
if (_container.IsEntityOrParentInContainer(uid) &&
_container.TryGetOuterContainer(uid, Transform(uid), out var container))
{
return SpawnInContainerOrDrop(prototype, container.Owner, container.ID);
}
return Spawn(prototype, Transform(uid).Coordinates);
}
}

View File

@@ -0,0 +1,38 @@
using Robust.Shared.Serialization;
namespace Content.Shared._EstacaoPirata.Cards.Hand;
/// <summary>
/// This is used for...
/// </summary>
[RegisterComponent]
public sealed partial class CardHandComponent : Component
{
[DataField]
public float Angle = 120f;
[DataField]
public float XOffset = 0.5f;
[DataField]
public float Scale = 1;
[DataField]
public int CardLimit = 10;
[DataField]
public bool Flipped = false;
}
[Serializable, NetSerializable]
public enum CardUiKey : byte
{
Key
}
[Serializable, NetSerializable]
public sealed class CardHandDrawMessage(NetEntity card) : BoundUserInterfaceMessage
{
public NetEntity Card = card;
}

View File

@@ -0,0 +1,237 @@
using System.Linq;
using Content.Shared._EstacaoPirata.Cards.Card;
using Content.Shared._EstacaoPirata.Cards.Deck;
using Content.Shared._EstacaoPirata.Cards.Stack;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Storage.EntitySystems;
using Content.Shared.Verbs;
using Robust.Shared.Containers;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Shared._EstacaoPirata.Cards.Hand;
/// <summary>
/// This handles...
/// </summary>
public sealed class CardHandSystem : EntitySystem
{
[ValidatePrototypeId<EntityPrototype>]
public readonly EntProtoId CardHandBaseName = "CardHandBase";
[ValidatePrototypeId<EntityPrototype>]
public readonly EntProtoId CardDeckBaseName = "CardDeckBase";
[Dependency] private readonly CardStackSystem _cardStack = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly SharedStorageSystem _storage = default!; // Frontier
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<CardComponent, InteractUsingEvent>(OnInteractUsing);
SubscribeLocalEvent<CardHandComponent, CardHandDrawMessage>(OnCardDraw);
SubscribeLocalEvent<CardHandComponent, CardStackQuantityChangeEvent>(OnStackQuantityChange);
SubscribeLocalEvent<CardHandComponent, GetVerbsEvent<AlternativeVerb>>(OnAlternativeVerb);
}
private void OnStackQuantityChange(EntityUid uid, CardHandComponent comp, CardStackQuantityChangeEvent args)
{
if (_net.IsClient)
return;
if (!TryComp(uid, out CardStackComponent? stack))
return;
if (stack.Cards.Count < 0)
{
Log.Warning($"Invalid negative card count {stack.Cards.Count} detected in stack {ToPrettyString(uid)}");
return;
}
var text = args.Type switch
{
StackQuantityChangeType.Added => "cards-stackquantitychange-added",
StackQuantityChangeType.Removed => "cards-stackquantitychange-removed",
StackQuantityChangeType.Joined => "cards-stackquantitychange-joined",
StackQuantityChangeType.Split => "cards-stackquantitychange-split",
_ => "cards-stackquantitychange-unknown"
};
_popupSystem.PopupEntity(Loc.GetString(text, ("quantity", stack.Cards.Count)), uid);
_cardStack.FlipAllCards(uid, stack, comp.Flipped);
}
private void OnCardDraw(EntityUid uid, CardHandComponent comp, CardHandDrawMessage args)
{
if (!TryComp(uid, out CardStackComponent? stack))
return;
var pickup = _hands.IsHolding(args.Actor, uid);
EntityUid? leftover = null;
var cardEnt = GetEntity(args.Card);
if (stack.Cards.Count == 2 && pickup)
{
leftover = stack.Cards[0] != cardEnt ? stack.Cards[0] : stack.Cards[1];
}
if (!_cardStack.TryRemoveCard(uid, cardEnt, stack))
return;
if (_net.IsServer)
_storage.PlayPickupAnimation(cardEnt, Transform(cardEnt).Coordinates, Transform(args.Actor).Coordinates, 0);
_hands.TryPickupAnyHand(args.Actor, cardEnt);
if (pickup && leftover != null)
{
_hands.TryPickupAnyHand(args.Actor, leftover.Value);
}
}
private void OpenHandMenu(EntityUid user, EntityUid hand)
{
if (!TryComp<ActorComponent>(user, out var actor))
return;
_ui.OpenUi(hand, CardUiKey.Key, actor.PlayerSession);
}
private void OnAlternativeVerb(EntityUid uid, CardHandComponent comp, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanAccess || !args.CanInteract || args.Hands == null)
return;
args.Verbs.Add(new AlternativeVerb()
{
Act = () => OpenHandMenu(args.User, uid),
Text = Loc.GetString("cards-verb-pickcard"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/die.svg.192dpi.png")),
Priority = 4
});
args.Verbs.Add(new AlternativeVerb()
{
Act = () => _cardStack.ShuffleCards(uid),
Text = Loc.GetString("cards-verb-shuffle"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/die.svg.192dpi.png")),
Priority = 3
});
args.Verbs.Add(new AlternativeVerb()
{
Act = () => FlipCards(uid, comp),
Text = Loc.GetString("cards-verb-flip"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/flip.svg.192dpi.png")),
Priority = 2
});
args.Verbs.Add(new AlternativeVerb()
{
Act = () => ConvertToDeck(args.User, uid),
Text = Loc.GetString("cards-verb-convert-to-deck"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/rotate_cw.svg.192dpi.png")),
Priority = 1
});
}
private void OnInteractUsing(EntityUid uid, CardComponent comp, InteractUsingEvent args)
{
if (args.Handled)
return;
if (HasComp<CardStackComponent>(args.Used) ||
!TryComp(args.Used, out CardComponent? usedComp))
return;
if (!HasComp<CardStackComponent>(args.Target) &&
TryComp(args.Target, out CardComponent? targetCardComp))
{
TrySetupHandOfCards(args.User, args.Used, usedComp, args.Target, targetCardComp, true);
args.Handled = true;
}
}
private void ConvertToDeck(EntityUid user, EntityUid hand)
{
if (_net.IsClient)
return;
var cardDeck = SpawnInSameParent(CardDeckBaseName, hand);
bool isHoldingCards = _hands.IsHolding(user, hand);
EnsureComp<CardStackComponent>(cardDeck, out var deckStack);
if (!TryComp(hand, out CardStackComponent? handStack))
return;
_cardStack.TryJoinStacks(cardDeck, hand, deckStack, handStack, null);
if (isHoldingCards)
_hands.TryPickupAnyHand(user, cardDeck);
}
public void TrySetupHandOfCards(EntityUid user, EntityUid card, CardComponent comp, EntityUid target, CardComponent targetComp, bool pickup)
{
if (card == target || _net.IsClient)
return;
var cardHand = SpawnInSameParent(CardHandBaseName, card);
if (TryComp<CardHandComponent>(cardHand, out var handComp))
handComp.Flipped = targetComp.Flipped;
if (!TryComp(cardHand, out CardStackComponent? stack))
return;
if (!_cardStack.TryInsertCard(cardHand, card, stack) || !_cardStack.TryInsertCard(cardHand, target, stack))
return;
if (_net.IsServer)
_storage.PlayPickupAnimation(card, Transform(card).Coordinates, Transform(cardHand).Coordinates, 0);
if (pickup && !_hands.TryPickupAnyHand(user, cardHand))
return;
_cardStack.FlipAllCards(cardHand, stack, targetComp.Flipped);
}
public void TrySetupHandFromStack(EntityUid user, EntityUid card, CardComponent comp, EntityUid target, CardStackComponent targetComp, bool pickup)
{
if (_net.IsClient)
return;
var cardHand = SpawnInSameParent(CardHandBaseName, card);
if (TryComp<CardHandComponent>(cardHand, out var handComp))
handComp.Flipped = comp.Flipped;
if (!TryComp(cardHand, out CardStackComponent? stack))
return;
if (!_cardStack.TryInsertCard(cardHand, card, stack))
return;
_cardStack.TransferNLastCardFromStacks(user, 1, target, targetComp, cardHand, stack);
if (pickup && !_hands.TryPickupAnyHand(user, cardHand))
return;
_cardStack.FlipAllCards(cardHand, stack, comp.Flipped);
}
private void FlipCards(EntityUid hand, CardHandComponent comp)
{
comp.Flipped = !comp.Flipped;
_cardStack.FlipAllCards(hand, null, comp.Flipped);
}
// Frontier: tries to spawn an entity with the same parent as another given entity.
// Useful when spawning decks/hands in a backpack, for example.
private EntityUid SpawnInSameParent(EntProtoId prototype, EntityUid uid)
{
if (prototype == default)
throw new ArgumentException("Cannot spawn with null prototype", nameof(prototype));
if (_container.IsEntityOrParentInContainer(uid) &&
_container.TryGetOuterContainer(uid, Transform(uid), out var container))
{
var entity = SpawnInContainerOrDrop(prototype, container.Owner, container.ID);
if (!Exists(entity))
Log.Error($"Failed to spawn {prototype} in container {container.ID}");
return entity;
}
var worldEntity = Spawn(prototype, Transform(uid).Coordinates);
if (!Exists(worldEntity))
Log.Error($"Failed to spawn {prototype} at coordinates {Transform(uid).Coordinates}");
return worldEntity;
}
}

View File

@@ -0,0 +1,83 @@
using Robust.Shared.Audio;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared._EstacaoPirata.Cards.Stack;
/// <summary>
/// This is used for holding the prototype ids of the cards in the stack or hand.
/// </summary>
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class CardStackComponent : Component
{
[DataField]
public List<EntProtoId> InitialContent = [];
[DataField]
public SoundSpecifier ShuffleSound = new SoundCollectionSpecifier("cardFan");
[DataField]
public SoundSpecifier PickUpSound = new SoundCollectionSpecifier("cardSlide");
[DataField]
public SoundSpecifier PlaceDownSound = new SoundCollectionSpecifier("cardShove");
/// <summary>
/// The containers that contain the items held in the stack
/// </summary>
[ViewVariables]
public Container ItemContainer = default!;
/// <summary>
/// The list EntityUIds of Cards
/// </summary>
[DataField, AutoNetworkedField]
public List<EntityUid> Cards = [];
}
[Serializable, NetSerializable]
public sealed class CardStackInitiatedEvent(NetEntity cardStack) : EntityEventArgs
{
public NetEntity CardStack = cardStack;
}
/// <summary>
/// This gets Updated when new cards are added or removed from the stack
/// </summary>
[Serializable, NetSerializable]
public sealed class CardStackQuantityChangeEvent(NetEntity stack, NetEntity? card, StackQuantityChangeType type) : EntityEventArgs
{
public NetEntity Stack = stack;
public NetEntity? Card = card;
public StackQuantityChangeType Type = type;
}
[Serializable, NetSerializable]
public enum StackQuantityChangeType : sbyte
{
Added,
Removed,
Joined,
Split
}
[Serializable, NetSerializable]
public sealed class CardStackReorderedEvent(NetEntity stack) : EntityEventArgs
{
public NetEntity Stack = stack;
}
[Serializable, NetSerializable]
public sealed class CardStackFlippedEvent(NetEntity cardStack) : EntityEventArgs
{
public NetEntity CardStack = cardStack;
}

View File

@@ -0,0 +1,482 @@
using System.Linq;
using Content.Shared._EstacaoPirata.Cards.Card;
using Content.Shared._EstacaoPirata.Cards.Deck;
using Content.Shared._EstacaoPirata.Cards.Hand;
using Content.Shared.Examine;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Storage.EntitySystems;
using Content.Shared.Verbs;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Random;
using Robust.Shared.Utility;
namespace Content.Shared._EstacaoPirata.Cards.Stack;
/// <summary>
/// This handles stack of cards.
/// It is used to shuffle, flip, insert, remove, and join stacks of cards.
/// It also handles the events related to the stack of cards.
/// </summary>
public sealed class CardStackSystem : EntitySystem
{
public const string ContainerId = "cardstack-container";
public const int MaxCardsInStack = 212; // Frontier: four 53-card decks.
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly EntityManager _entityManager = default!;
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly SharedStorageSystem _storage = default!;
[Dependency] private readonly CardHandSystem _cardHandSystem = default!; // Frontier
[Dependency] private readonly SharedHandsSystem _hands = default!;
/// <inheritdoc/>
public override void Initialize()
{
// Pretty much a rip-off of the BinSystem
SubscribeLocalEvent<CardStackComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<CardStackComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<CardStackComponent, EntRemovedFromContainerMessage>(OnEntRemoved);
SubscribeLocalEvent<CardStackComponent, GetVerbsEvent<AlternativeVerb>>(OnAlternativeVerb);
SubscribeLocalEvent<CardStackComponent, GetVerbsEvent<ActivationVerb>>(OnActivationVerb);
SubscribeLocalEvent<CardStackComponent, ActivateInWorldEvent>(OnActivate);
SubscribeLocalEvent<CardStackComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<InteractUsingEvent>(OnInteractUsing);
}
public bool TryRemoveCard(EntityUid uid, EntityUid card, CardStackComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return false;
if (!TryComp(card, out CardComponent? _))
return false;
_container.Remove(card, comp.ItemContainer);
comp.Cards.Remove(card);
// If there is a final card left over, remove that card from the container and delete the stack alltogether
if (comp.Cards.Count == 1)
{
_container.Remove(comp.Cards.First(), comp.ItemContainer);
comp.Cards.Clear();
}
Dirty(uid, comp);
RaiseLocalEvent(uid, new CardStackQuantityChangeEvent(GetNetEntity(uid), GetNetEntity(card), StackQuantityChangeType.Removed));
RaiseNetworkEvent(new CardStackQuantityChangeEvent(GetNetEntity(uid), GetNetEntity(card), StackQuantityChangeType.Removed));
// Prevents prediction ruining things
if (_net.IsServer && comp.Cards.Count <= 0)
{
_entityManager.DeleteEntity(uid);
}
return true;
}
public bool TryInsertCard(EntityUid uid, EntityUid card, CardStackComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return false;
if (!TryComp(card, out CardComponent? _))
return false;
if (comp.Cards.Count >= MaxCardsInStack)
return false;
_container.Insert(card, comp.ItemContainer);
comp.Cards.Add(card);
Dirty(uid, comp);
RaiseLocalEvent(uid, new CardStackQuantityChangeEvent(GetNetEntity(uid), GetNetEntity(card), StackQuantityChangeType.Added));
RaiseNetworkEvent(new CardStackQuantityChangeEvent(GetNetEntity(uid), GetNetEntity(card), StackQuantityChangeType.Added));
return true;
}
public bool ShuffleCards(EntityUid uid, CardStackComponent? comp = null)
{
if (!Resolve(uid, ref comp))
return false;
_random.Shuffle(comp.Cards);
Dirty(uid, comp);
RaiseLocalEvent(uid, new CardStackReorderedEvent(GetNetEntity(uid)));
RaiseNetworkEvent(new CardStackReorderedEvent(GetNetEntity(uid)));
return true;
}
/// <summary>
/// Server-Side only method to flip all cards within a stack. This starts CardFlipUpdatedEvent and CardStackFlippedEvent event
/// </summary>
/// <param name="uid"></param>
/// <param name="comp"></param>
/// <param name="isFlipped">If null, all cards will just invert direction, if it contains a value, then all cards will receive that value</param>
/// <returns></returns>
public bool FlipAllCards(EntityUid uid, CardStackComponent? comp = null, bool? isFlipped = null)
{
if (_net.IsClient)
return false;
if (!Resolve(uid, ref comp))
return false;
foreach (var card in comp.Cards)
{
if (!TryComp(card, out CardComponent? cardComponent))
continue;
cardComponent.Flipped = isFlipped ?? !cardComponent.Flipped;
Dirty(card, cardComponent);
RaiseNetworkEvent(new CardFlipUpdatedEvent(GetNetEntity(card)));
}
RaiseNetworkEvent(new CardStackFlippedEvent(GetNetEntity(uid)));
return true;
}
public bool TryJoinStacks(EntityUid firstStack, EntityUid secondStack, CardStackComponent? firstComp = null, CardStackComponent? secondComp = null, EntityUid? soundUser = null)
{
if (firstStack == secondStack)
return false;
if (!Resolve(firstStack, ref firstComp) || !Resolve(secondStack, ref secondComp))
return false;
bool changed = false;
var cardList = secondComp.Cards.ToList();
EntityUid? firstCard = secondComp.Cards.Count > 0 ? cardList[0] : null; // Cache the first card transferred for animations (better to have something moving than nothing, and we destroy the other stack)
foreach (var card in cardList)
{
if (firstComp.Cards.Count >= MaxCardsInStack)
break;
_container.Remove(card, secondComp.ItemContainer);
secondComp.Cards.Remove(card);
firstComp.Cards.Add(card);
_container.Insert(card, firstComp.ItemContainer);
changed = true;
}
if (changed)
{
if (soundUser != null)
{
_audio.PlayPredicted(firstComp.PlaceDownSound, Transform(firstStack).Coordinates, soundUser.Value);
if(_net.IsServer)
_storage.PlayPickupAnimation(firstCard!.Value, Transform(secondStack).Coordinates, Transform(firstStack).Coordinates, 0);
}
if (_net.IsClient)
return changed;
Dirty(firstStack, firstComp);
if (secondComp.Cards.Count <= 0)
{
_entityManager.DeleteEntity(secondStack);
}
else
{
Dirty(secondStack, secondComp);
RaiseLocalEvent(secondStack, new CardStackQuantityChangeEvent(GetNetEntity(secondStack), null, StackQuantityChangeType.Split));
RaiseNetworkEvent(new CardStackQuantityChangeEvent(GetNetEntity(secondStack), null, StackQuantityChangeType.Split));
}
RaiseLocalEvent(firstStack, new CardStackQuantityChangeEvent(GetNetEntity(firstStack), null, StackQuantityChangeType.Joined));
RaiseNetworkEvent(new CardStackQuantityChangeEvent(GetNetEntity(firstStack), null, StackQuantityChangeType.Joined));
}
return changed;
}
#region EventHandling
private void OnStartup(EntityUid uid, CardStackComponent component, ComponentStartup args)
{
component.ItemContainer = _container.EnsureContainer<Container>(uid, ContainerId);
}
private void OnMapInit(EntityUid uid, CardStackComponent comp, MapInitEvent args)
{
if (_net.IsClient)
return;
var coordinates = Transform(uid).Coordinates;
var spawnedEntities = new List<EntityUid>();
foreach (var id in comp.InitialContent)
{
var ent = Spawn(id, coordinates);
spawnedEntities.Add(ent);
if (TryInsertCard(uid, ent, comp))
continue;
Log.Error($"Entity {ToPrettyString(ent)} was unable to be initialized into stack {ToPrettyString(uid)}");
foreach (var spawned in spawnedEntities)
_entityManager.DeleteEntity(spawned);
return;
}
RaiseNetworkEvent(new CardStackInitiatedEvent(GetNetEntity(uid)));
}
// It seems the cards don't get removed if this event is not subscribed... strange right? thanks again bin system
private void OnEntRemoved(EntityUid uid, CardStackComponent component, EntRemovedFromContainerMessage args)
{
component.Cards.Remove(args.Entity);
}
private void OnExamine(EntityUid uid, CardStackComponent component, ExaminedEvent args)
{
args.PushText(Loc.GetString("card-stack-examine", ("count", component.Cards.Count)));
}
private void OnAlternativeVerb(EntityUid uid, CardStackComponent component, GetVerbsEvent<AlternativeVerb> args)
{
if (args.Using == args.Target)
return;
if (!TryComp(args.Target, out CardStackComponent? targetStack))
return;
if (TryComp(args.Using, out CardStackComponent? usingStack))
{
args.Verbs.Add(new AlternativeVerb()
{
Text = Loc.GetString("card-verb-join"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/refresh.svg.192dpi.png")),
Priority = 8,
Act = () => JoinStacks(args.User, args.Target, targetStack, (EntityUid)args.Using, usingStack)
});
}
else if (TryComp(args.Using, out CardComponent? usingCard)) // Frontier: single card interaction
{
args.Verbs.Add(new AlternativeVerb()
{
Text = Loc.GetString("card-verb-join"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/refresh.svg.192dpi.png")),
Priority = 8,
Act = () => InsertCardOnStack(args.User, args.Target, targetStack, (EntityUid)args.Using)
});
} // End Frontier: single card interaction
}
// Frontier: hacky misuse of the activation verb, but allows us a separate way to draw cards without needing additional buttons and event fiddling
private void OnActivationVerb(EntityUid uid, CardStackComponent component, GetVerbsEvent<ActivationVerb> args)
{
if (!args.CanAccess || !args.CanInteract || args.Hands == null)
return;
if (args.Using == args.Target)
return;
if (args.Using == null)
{
args.Verbs.Add(new ActivationVerb()
{
Act = () => OnInteractHand(args.Target, component, args.User),
Text = Loc.GetString("cards-verb-draw"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")),
Priority = 16
});
}
else if (TryComp<CardStackComponent>(args.Using, out var cardStack))
{
args.Verbs.Add(new ActivationVerb()
{
Act = () => TransferNLastCardFromStacks(args.User, 1, args.Target, component, args.Using.Value, cardStack),
Text = Loc.GetString("cards-verb-draw"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")),
Priority = 16
});
}
else if (TryComp<CardComponent>(args.Using, out var card))
{
args.Verbs.Add(new ActivationVerb()
{
Act = () => _cardHandSystem.TrySetupHandFromStack(args.User, args.Using.Value, card, args.Target, component, true),
Text = Loc.GetString("cards-verb-draw"),
Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/eject.svg.192dpi.png")),
Priority = 16
});
}
}
// End Frontier
private void JoinStacks(EntityUid user, EntityUid first, CardStackComponent firstComp, EntityUid second, CardStackComponent secondComp)
{
TryJoinStacks(first, second, firstComp, secondComp, user);
}
public void InsertCardOnStack(EntityUid user, EntityUid stack, CardStackComponent stackComponent, EntityUid card)
{
if (!TryInsertCard(stack, card))
return;
_audio.PlayPredicted(stackComponent.PlaceDownSound, Transform(stack).Coordinates, user);
if (_net.IsClient)
return;
_storage.PlayPickupAnimation(card, Transform(user).Coordinates, Transform(stack).Coordinates, 0);
}
/// <summary>
/// This takes the last card from the first stack and inserts it into the second stack
/// </summary>
public void TransferNLastCardFromStacks(EntityUid user, int n, EntityUid first, CardStackComponent firstComp, EntityUid second, CardStackComponent secondComp)
{
if (firstComp.Cards.Count <= 0)
return;
var cards = firstComp.Cards.TakeLast(n).ToList(); // Frontier: make a copy we don't munge during iteration
var firstCard = cards.First(); // Cache first card for animation - enumerable changes in foreach
bool changed = false;
foreach (var card in cards)
{
if (secondComp.Cards.Count >= MaxCardsInStack)
break;
_container.Remove(card, firstComp.ItemContainer);
firstComp.Cards.Remove(card);
secondComp.Cards.Add(card);
_container.Insert(card, secondComp.ItemContainer);
changed = true;
}
if (changed)
{
_audio.PlayPredicted(firstComp.PlaceDownSound, Transform(second).Coordinates, user);
if (_net.IsClient)
return;
_storage.PlayPickupAnimation(firstCard, Transform(first).Coordinates, Transform(second).Coordinates, 0);
Dirty(second, secondComp);
if (firstComp.Cards.Count == 1)
{
var card = firstComp.Cards.First();
_container.Remove(card, firstComp.ItemContainer);
if (_hands.IsHolding(user, first))
{
_hands.TryDrop(user, first);
_hands.TryPickupAnyHand(user, card);
}
firstComp.Cards.Clear();
}
if (firstComp.Cards.Count <= 0)
{
_entityManager.DeleteEntity(first);
}
else
{
Dirty(first, firstComp);
RaiseLocalEvent(first, new CardStackQuantityChangeEvent(GetNetEntity(first), null, StackQuantityChangeType.Removed));
RaiseNetworkEvent(new CardStackQuantityChangeEvent(GetNetEntity(first), null, StackQuantityChangeType.Removed));
}
RaiseLocalEvent(second, new CardStackQuantityChangeEvent(GetNetEntity(second), null, StackQuantityChangeType.Added));
RaiseNetworkEvent(new CardStackQuantityChangeEvent(GetNetEntity(second), null, StackQuantityChangeType.Added));
}
}
private void OnInteractUsing(InteractUsingEvent args)
{
if (args.Handled)
return;
if (args.Target == args.Used)
return;
// This checks if the user is using an item with Stack component
if (TryComp(args.Used, out CardStackComponent? usedStack))
{
// If the target is a card, then it will insert the card into the stack
if (TryComp(args.Target, out CardComponent? _))
{
InsertCardOnStack(args.User, args.Used, usedStack, args.Target);
args.Handled = true;
return;
}
// If instead, the target is a stack, then it will join the two stacks
if (!TryComp(args.Target, out CardStackComponent? targetStack))
return;
TransferNLastCardFromStacks(args.User, 1, args.Target, targetStack, args.Used, usedStack);
args.Handled = true;
}
// This handles the reverse case, where the user is using a card and inserting it to a stack
else if (TryComp(args.Target, out CardStackComponent? stack))
{
//InsertCardOnStack(args.User, args.Target, stack, args.Used); // Frontier: old version
if (TryComp(args.Used, out CardComponent? card))
{
_cardHandSystem.TrySetupHandFromStack(args.User, args.Used, card, args.Target, stack, true);
args.Handled = true;
}
}
}
private void OnInteractHand(EntityUid uid, CardStackComponent component, EntityUid user)
{
var pickup = _hands.IsHolding(user, uid);
if (component.Cards.Count <= 0)
return;
if (!component.Cards.TryGetValue(component.Cards.Count - 1, out var card))
return;
if (!component.Cards.TryGetValue(component.Cards.Count - 2, out var under))
return;
if (!TryRemoveCard(uid, card, component))
return;
_hands.TryPickupAnyHand(user, card);
if (!Exists(uid) && pickup)
_hands.TryPickupAnyHand(user, under);
if (TryComp<CardDeckComponent>(uid, out var deck))
_audio.PlayPredicted(deck.PickUpSound, Transform(card).Coordinates, user);
else
_audio.PlayPredicted(component.PickUpSound, Transform(card).Coordinates, user);
}
private void OnActivate(EntityUid uid, CardStackComponent component, ActivateInWorldEvent args)
{
if (!args.Complex || args.Handled)
return;
if (!TryComp<HandsComponent>(args.User, out var hands))
{
args.Handled = true;
return;
}
var activeItem = _hands.GetActiveItem((args.User, hands));
if (activeItem == null)
{
// Runs if active item is nothing
// behavior is to draw one card from this target onto active hand as a standalone card
OnInteractHand(args.Target, component, args.User);
}
else if (activeItem == args.Target)
{
// Added from a Frontier PR. Don't want to draw a card from a stack onto itself.
args.Handled = true;
return;
}
else if (TryComp<CardStackComponent>(activeItem, out var cardStack))
{
// If the active item contains a card stack, behavior is to draw from Target and place onto activeHand.
TransferNLastCardFromStacks(args.User, 1, args.Target, component, activeItem.Value, cardStack);
}
else if (TryComp<CardComponent>(activeItem, out var card))
{
_cardHandSystem.TrySetupHandFromStack(args.User, activeItem.Value, card, args.Target, component, true);
}
args.Handled = true;
}
#endregion
}

View File

@@ -0,0 +1,6 @@
- files: [ "cardFan1.ogg", "cardFan2.ogg", "cardOpenPackage1.ogg", "cardOpenPackage2.ogg", "cardPlace1.ogg", "cardPlace2.ogg", "cardPlace3.ogg", "cardPlace4.ogg", "cardShove1.ogg", "cardShove2.ogg", "cardShove3.ogg", "cardShove4.ogg", "cardShuffle.ogg", "cardSlide1.ogg", "cardSlide2.ogg", "cardSlide3.ogg", "cardSlide4.ogg", "cardSlide5.ogg", "cardSlide6.ogg", "cardSlide7.ogg", "cardSlide8.ogg", "cardTakeOutPackage1.ogg", "cardTakeOutPackage2.ogg"]
license: "CC0-1.0"
copyright: "Kenney.nl"
source: "https://opengameart.org/content/54-casino-sound-effects-cards-dice-chips"

View File

@@ -0,0 +1,89 @@
card-examined = This is the {$target}.
cards-verb-shuffle = Shuffle
card-verb-shuffle-success = Cards shuffled
cards-verb-draw = Draw card
cards-verb-flip = Flip cards
card-verb-join = Join cards
card-verb-organize-success = Cards flipped face { $facedown ->
[true] down
*[false] up
}
cards-verb-organize-up = Flip cards face up
cards-verb-organize-down = Flip cards face down
cards-verb-pickcard = Pick a card
card-stack-examine = { $count ->
[one] There is {$count} card in this stack.
*[other] There are {$count} cards in this stack.
}
cards-stackquantitychange-added = Card was added (Total cards: {$quantity})
cards-stackquantitychange-removed = Card was removed (Total cards: {$quantity})
cards-stackquantitychange-joined = Stack was merged (Total cards: {$quantity})
cards-stackquantitychange-split = Stack was split (Total cards: {$quantity})
cards-stackquantitychange-unknown = Stack count changed (Total cards: {$quantity})
cards-verb-convert-to-deck = Convert to deck
cards-verb-split = Split in half
card-base-name = card
card-deck-name = deck of cards
card-sc-2-clubs = 2 of clubs
card-sc-3-clubs = 3 of clubs
card-sc-4-clubs = 4 of clubs
card-sc-5-clubs = 5 of clubs
card-sc-6-clubs = 6 of clubs
card-sc-7-clubs = 7 of clubs
card-sc-8-clubs = 8 of clubs
card-sc-9-clubs = 9 of clubs
card-sc-10-clubs = 10 of clubs
card-sc-ace-clubs = ace of clubs
card-sc-jack-clubs = jack of clubs
card-sc-king-clubs = king of clubs
card-sc-queen-clubs = queen of clubs
card-sc-2-diamonds = 2 of diamonds
card-sc-3-diamonds = 3 of diamonds
card-sc-4-diamonds = 4 of diamonds
card-sc-5-diamonds = 5 of diamonds
card-sc-6-diamonds = 6 of diamonds
card-sc-7-diamonds = 7 of diamonds
card-sc-8-diamonds = 8 of diamonds
card-sc-9-diamonds = 9 of diamonds
card-sc-10-diamonds = 10 of diamonds
card-sc-ace-diamonds = ace of diamonds
card-sc-jack-diamonds = jack of diamonds
card-sc-king-diamonds = king of diamonds
card-sc-queen-diamonds = queen of diamonds
card-sc-2-hearts = 2 of hearts
card-sc-3-hearts = 3 of hearts
card-sc-4-hearts = 4 of hearts
card-sc-5-hearts = 5 of hearts
card-sc-6-hearts = 6 of hearts
card-sc-7-hearts = 7 of hearts
card-sc-8-hearts = 8 of hearts
card-sc-9-hearts = 9 of hearts
card-sc-10-hearts = 10 of hearts
card-sc-ace-hearts = ace of hearts
card-sc-jack-hearts = jack of hearts
card-sc-king-hearts = king of hearts
card-sc-queen-hearts = queen of hearts
card-sc-2-spades = 2 of spades
card-sc-3-spades = 3 of spades
card-sc-4-spades = 4 of spades
card-sc-5-spades = 5 of spades
card-sc-6-spades = 6 of spades
card-sc-7-spades = 7 of spades
card-sc-8-spades = 8 of spades
card-sc-9-spades = 9 of spades
card-sc-10-spades = 10 of spades
card-sc-ace-spades = ace of spades
card-sc-jack-spades = jack of spades
card-sc-king-spades = king of spades
card-sc-queen-spades = queen of spades
card-sc-joker = joker
container-sealed = A holographic security seal is on it. Opening it will have the seal dissipate.
container-unsealed = The seal attached to it dissipates.

View File

@@ -0,0 +1,2 @@
uplink-syndicate-deck-name = Syndicate Deck Box
uplink-syndicate-deck-desc = A deck box with the standard 53 playing cards with syndicate branding. Please gamble responsibly.

View File

@@ -1,3 +1,5 @@
loadout-description-LoadoutItemBlackDeck = A black box containing the standard 53 playing cards. Please gamble responsibly.
loadout-description-LoadoutItemNTDeck = A Nanotrasen-branded box containing the standard 53 playing cards. Please gamble responsibly.
loadout-description-LoadoutItemCig = Cool guys always have one.
loadout-description-LoadoutItemCigsGreen = A pack a day keeps the doctor well-paid!
loadout-description-LoadoutItemCigsRed = A pack a day keeps the doctor well-paid!

View File

@@ -19,6 +19,7 @@ character-item-group-LoadoutSmokes = Smokeables
character-item-group-LoadoutBoxKits = Survival Kits
character-item-group-LoadoutWritables = Writing Tools
character-item-group-LoadoutPets = Pets
character-item-group-LoadoutCards = Playing Cards
# Job Specific Template
character-item-group-LoadoutJOBBackpacks = JOB Backpacks

View File

@@ -16,3 +16,4 @@
PaperCNCSheet: 6
MysteryFigureBox: 2
BooksBag: 3
CardBoxBlack: 3

View File

@@ -134,3 +134,12 @@
id: LoadoutItemPetMothroach
- type: loadout
id: LoadoutItemPetCockroach
- type: characterItemGroup
id: LoadoutCards
maxItems: 1
items:
- type: loadout
id: LoadoutItemBlackDeck
- type: loadout
id: LoadoutItemNTDeck

View File

@@ -0,0 +1,9 @@
- type: listing
id: UplinkSyndicateDeck
name: uplink-syndicate-deck-name
description: uplink-syndicate-deck-desc
productEntity: CardBoxSyndicate
cost:
Telecrystal: 1
categories:
- UplinkPointless

View File

@@ -0,0 +1,780 @@
- type: entity
parent: [ BoxCardboard, BaseBagOpenClose ]
id: CardBoxBase
name: deck box
categories: [ HideSpawnMenu ]
components:
- type: Item
size: Small
shape:
- 0,0,1,1
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
layers:
- state: black_box
- state: black_box_open
map: [ "openLayer" ]
visible: false
- type: Storage
maxItemSize: Normal
grid:
- 0,0,1,1
whitelist:
components:
- CardDeck
- type: OpenTriggeredStorageFill
contents:
- id: CardDeckBase
amount: 1
- type: Appearance
# Frontier: base stack for card stack component
- type: entity
parent: [BaseItem]
id: CardStackBase
name: stack of cards
abstract: true
components:
- type: Item
size: Small
- type: CardStack
- type: StripMenuHidden
- type: ContainerContainer # Frontier
containers: # Frontier
cardstack-container: !type:Container # Frontier
# End Frontier
- type: entity
parent: CardStackBase
id: CardHandBase
categories: [ HideSpawnMenu ]
name: hand of cards
components:
- type: CardHand
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: singlecard_down_black
- type: UserInterface
interfaces:
enum.CardUiKey.Key:
type: CardHandMenuBoundUserInterface
# - type: ActivatableUI # Frontier
# key: enum.CardUiKey.Key # Frontier
- type: entity
parent: CardStackBase
id: CardDeckBase
categories: [ HideSpawnMenu ]
name: deck of cards
components:
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: deck_black_full
- type: Item
size: Normal
- type: CardDeck
- type: entity
parent: CardBoxBase
id: CardBoxBlack
name: black deck box
components:
- type: Item
size: Small
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
layers:
- state: black_box
- state: black_box_open
map: [ "openLayer" ]
visible: false
- type: OpenTriggeredStorageFill
contents:
- id: CardDeckBlack
amount: 1
- type: entity
parent: CardDeckBase
id: CardDeckBlack
name: deck of cards
components:
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: deck_black_full
- type: CardStack
initialContent:
# Clubs
- CardScAceOfClubsBlack
- CardSc2OfClubsBlack
- CardSc3OfClubsBlack
- CardSc4OfClubsBlack
- CardSc5OfClubsBlack
- CardSc6OfClubsBlack
- CardSc7OfClubsBlack
- CardSc8OfClubsBlack
- CardSc9OfClubsBlack
- CardSc10OfClubsBlack
- CardScJackOfClubsBlack
- CardScQueenOfClubsBlack
- CardScKingOfClubsBlack
# Diamonds
- CardScAceOfDiamondsBlack
- CardSc2OfDiamondsBlack
- CardSc3OfDiamondsBlack
- CardSc4OfDiamondsBlack
- CardSc5OfDiamondsBlack
- CardSc6OfDiamondsBlack
- CardSc7OfDiamondsBlack
- CardSc8OfDiamondsBlack
- CardSc9OfDiamondsBlack
- CardSc10OfDiamondsBlack
- CardScJackOfDiamondsBlack
- CardScQueenOfDiamondsBlack
- CardScKingOfDiamondsBlack
# Hearts
- CardScAceOfHeartsBlack
- CardSc2OfHeartsBlack
- CardSc3OfHeartsBlack
- CardSc4OfHeartsBlack
- CardSc5OfHeartsBlack
- CardSc6OfHeartsBlack
- CardSc7OfHeartsBlack
- CardSc8OfHeartsBlack
- CardSc9OfHeartsBlack
- CardSc10OfHeartsBlack
- CardScJackOfHeartsBlack
- CardScQueenOfHeartsBlack
- CardScKingOfHeartsBlack
# Spades
- CardScAceOfSpadesBlack
- CardSc2OfSpadesBlack
- CardSc3OfSpadesBlack
- CardSc4OfSpadesBlack
- CardSc5OfSpadesBlack
- CardSc6OfSpadesBlack
- CardSc7OfSpadesBlack
- CardSc8OfSpadesBlack
- CardSc9OfSpadesBlack
- CardSc10OfSpadesBlack
- CardScJackOfSpadesBlack
- CardScQueenOfSpadesBlack
- CardScKingOfSpadesBlack
# Joker
- CardScJokerBlack
- type: entity
parent: BaseItem
id: CardBase
name: card
categories: [ HideSpawnMenu ]
components:
- type: EmitSoundOnLand
sound:
collection: cardShove
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: singlecard_down_black
- type: Rotatable
- type: Item
size: Small
- type: UseDelay
delay: 0.5
- type: Card
backSprite:
- sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: singlecard_down_black
flipped: true
- type: StripMenuHidden
# region Black Cards
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc2OfClubsBlack
components:
- type: Card
name: card-sc-2-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc3OfClubsBlack
components:
- type: Card
name: card-sc-3-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc4OfClubsBlack
components:
- type: Card
name: card-sc-4-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc5OfClubsBlack
components:
- type: Card
name: card-sc-5-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc6OfClubsBlack
components:
- type: Card
name: card-sc-6-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc7OfClubsBlack
components:
- type: Card
name: card-sc-7-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc8OfClubsBlack
components:
- type: Card
name: card-sc-8-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc9OfClubsBlack
components:
- type: Card
name: card-sc-9-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc10OfClubsBlack
components:
- type: Card
name: card-sc-10-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScAceOfClubsBlack
components:
- type: Card
name: card-sc-ace-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScJackOfClubsBlack
components:
- type: Card
name: card-sc-jack-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScKingOfClubsBlack
components:
- type: Card
name: card-sc-king-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScQueenOfClubsBlack
components:
- type: Card
name: card-sc-queen-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Clubs_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScJackOfDiamondsBlack
components:
- type: Card
name: card-sc-jack-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScQueenOfDiamondsBlack
components:
- type: Card
name: card-sc-queen-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScKingOfDiamondsBlack
components:
- type: Card
name: card-sc-king-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScAceOfDiamondsBlack
components:
- type: Card
name: card-sc-ace-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc2OfDiamondsBlack
components:
- type: Card
name: card-sc-2-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc3OfDiamondsBlack
components:
- type: Card
name: card-sc-3-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc4OfDiamondsBlack
components:
- type: Card
name: card-sc-4-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc5OfDiamondsBlack
components:
- type: Card
name: card-sc-5-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc6OfDiamondsBlack
components:
- type: Card
name: card-sc-6-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc7OfDiamondsBlack
components:
- type: Card
name: card-sc-7-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc8OfDiamondsBlack
components:
- type: Card
name: card-sc-8-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc9OfDiamondsBlack
components:
- type: Card
name: card-sc-9-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc10OfDiamondsBlack
components:
- type: Card
name: card-sc-10-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Diamonds_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc2OfHeartsBlack
components:
- type: Card
name: card-sc-2-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc3OfHeartsBlack
components:
- type: Card
name: card-sc-3-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc4OfHeartsBlack
components:
- type: Card
name: card-sc-4-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc5OfHeartsBlack
components:
- type: Card
name: card-sc-5-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc6OfHeartsBlack
components:
- type: Card
name: card-sc-6-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc7OfHeartsBlack
components:
- type: Card
name: card-sc-7-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc8OfHeartsBlack
components:
- type: Card
name: card-sc-8-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc9OfHeartsBlack
components:
- type: Card
name: card-sc-9-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc10OfHeartsBlack
components:
- type: Card
name: card-sc-10-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScKingOfHeartsBlack
components:
- type: Card
name: card-sc-king-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScQueenOfHeartsBlack
components:
- type: Card
name: card-sc-queen-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScJackOfHeartsBlack
components:
- type: Card
name: card-sc-jack-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScAceOfHeartsBlack
components:
- type: Card
name: card-sc-ace-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Hearts_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc2OfSpadesBlack
components:
- type: Card
name: card-sc-2-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc3OfSpadesBlack
components:
- type: Card
name: card-sc-3-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc4OfSpadesBlack
components:
- type: Card
name: card-sc-4-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc5OfSpadesBlack
components:
- type: Card
name: card-sc-5-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc6OfSpadesBlack
components:
- type: Card
name: card-sc-6-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc7OfSpadesBlack
components:
- type: Card
name: card-sc-7-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc8OfSpadesBlack
components:
- type: Card
name: card-sc-8-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc9OfSpadesBlack
components:
- type: Card
name: card-sc-9-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardSc10OfSpadesBlack
components:
- type: Card
name: card-sc-10-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScKingOfSpadesBlack
components:
- type: Card
name: card-sc-king-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScQueenOfSpadesBlack
components:
- type: Card
name: card-sc-queen-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScJackOfSpadesBlack
components:
- type: Card
name: card-sc-jack-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScAceOfSpadesBlack
components:
- type: Card
name: card-sc-ace-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Spades_black
- type: entity
parent: CardBase
categories: [ HideSpawnMenu ]
id: CardScJokerBlack
components:
- type: Card
name: card-sc-joker
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: black_joker
# endregion Black Cards

View File

@@ -0,0 +1,690 @@
- type: entity
parent: CardBase
id: CardBaseNanotrasen
name: card
components:
- type: Card
backSprite:
- sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: singlecard_down_nanotrasen
- type: entity
parent: CardBoxBase
id: CardBoxNanotrasen
name: nanotrasen deck box
components:
- type: Item
size: Small
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
layers:
- state: nanotrasen_box
- state: nanotrasen_box_open
map: [ "openLayer" ]
visible: false
- type: OpenTriggeredStorageFill
contents:
- id: CardDeckNanotrasen
amount: 1
- type: entity
parent: CardDeckBase
id: CardDeckNanotrasen
name: deck of cards
components:
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: deck_nanotrasen_full
- type: CardStack
initialContent:
# Clubs
- CardScAceOfClubsNanotrasen
- CardSc2OfClubsNanotrasen
- CardSc3OfClubsNanotrasen
- CardSc4OfClubsNanotrasen
- CardSc5OfClubsNanotrasen
- CardSc6OfClubsNanotrasen
- CardSc7OfClubsNanotrasen
- CardSc8OfClubsNanotrasen
- CardSc9OfClubsNanotrasen
- CardSc10OfClubsNanotrasen
- CardScJackOfClubsNanotrasen
- CardScQueenOfClubsNanotrasen
- CardScKingOfClubsNanotrasen
# Diamonds
- CardScAceOfDiamondsNanotrasen
- CardSc2OfDiamondsNanotrasen
- CardSc3OfDiamondsNanotrasen
- CardSc4OfDiamondsNanotrasen
- CardSc5OfDiamondsNanotrasen
- CardSc6OfDiamondsNanotrasen
- CardSc7OfDiamondsNanotrasen
- CardSc8OfDiamondsNanotrasen
- CardSc9OfDiamondsNanotrasen
- CardSc10OfDiamondsNanotrasen
- CardScJackOfDiamondsNanotrasen
- CardScQueenOfDiamondsNanotrasen
- CardScKingOfDiamondsNanotrasen
# Hearts
- CardScAceOfHeartsNanotrasen
- CardSc2OfHeartsNanotrasen
- CardSc3OfHeartsNanotrasen
- CardSc4OfHeartsNanotrasen
- CardSc5OfHeartsNanotrasen
- CardSc6OfHeartsNanotrasen
- CardSc7OfHeartsNanotrasen
- CardSc8OfHeartsNanotrasen
- CardSc9OfHeartsNanotrasen
- CardSc10OfHeartsNanotrasen
- CardScJackOfHeartsNanotrasen
- CardScQueenOfHeartsNanotrasen
- CardScKingOfHeartsNanotrasen
# Spades
- CardScAceOfSpadesNanotrasen
- CardSc2OfSpadesNanotrasen
- CardSc3OfSpadesNanotrasen
- CardSc4OfSpadesNanotrasen
- CardSc5OfSpadesNanotrasen
- CardSc6OfSpadesNanotrasen
- CardSc7OfSpadesNanotrasen
- CardSc8OfSpadesNanotrasen
- CardSc9OfSpadesNanotrasen
- CardSc10OfSpadesNanotrasen
- CardScJackOfSpadesNanotrasen
- CardScQueenOfSpadesNanotrasen
- CardScKingOfSpadesNanotrasen
# Joker
- CardScJokerNanotrasen
# region Nanotrasen Cards
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc2OfClubsNanotrasen
components:
- type: Card
name: card-sc-2-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc3OfClubsNanotrasen
components:
- type: Card
name: card-sc-3-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc4OfClubsNanotrasen
components:
- type: Card
name: card-sc-4-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc5OfClubsNanotrasen
components:
- type: Card
name: card-sc-5-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc6OfClubsNanotrasen
components:
- type: Card
name: card-sc-6-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc7OfClubsNanotrasen
components:
- type: Card
name: card-sc-7-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc8OfClubsNanotrasen
components:
- type: Card
name: card-sc-8-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc9OfClubsNanotrasen
components:
- type: Card
name: card-sc-9-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc10OfClubsNanotrasen
components:
- type: Card
name: card-sc-10-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScAceOfClubsNanotrasen
components:
- type: Card
name: card-sc-ace-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScJackOfClubsNanotrasen
components:
- type: Card
name: card-sc-jack-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScKingOfClubsNanotrasen
components:
- type: Card
name: card-sc-king-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScQueenOfClubsNanotrasen
components:
- type: Card
name: card-sc-queen-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Clubs_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScJackOfDiamondsNanotrasen
components:
- type: Card
name: card-sc-jack-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScQueenOfDiamondsNanotrasen
components:
- type: Card
name: card-sc-queen-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScKingOfDiamondsNanotrasen
components:
- type: Card
name: card-sc-king-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScAceOfDiamondsNanotrasen
components:
- type: Card
name: card-sc-ace-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc2OfDiamondsNanotrasen
components:
- type: Card
name: card-sc-2-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc3OfDiamondsNanotrasen
components:
- type: Card
name: card-sc-3-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc4OfDiamondsNanotrasen
components:
- type: Card
name: card-sc-4-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc5OfDiamondsNanotrasen
components:
- type: Card
name: card-sc-5-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc6OfDiamondsNanotrasen
components:
- type: Card
name: card-sc-6-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc7OfDiamondsNanotrasen
components:
- type: Card
name: card-sc-7-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc8OfDiamondsNanotrasen
components:
- type: Card
name: card-sc-8-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc9OfDiamondsNanotrasen
components:
- type: Card
name: card-sc-9-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc10OfDiamondsNanotrasen
components:
- type: Card
name: card-sc-10-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Diamonds_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc2OfHeartsNanotrasen
components:
- type: Card
name: card-sc-2-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc3OfHeartsNanotrasen
components:
- type: Card
name: card-sc-3-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc4OfHeartsNanotrasen
components:
- type: Card
name: card-sc-4-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc5OfHeartsNanotrasen
components:
- type: Card
name: card-sc-5-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc6OfHeartsNanotrasen
components:
- type: Card
name: card-sc-6-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc7OfHeartsNanotrasen
components:
- type: Card
name: card-sc-7-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc8OfHeartsNanotrasen
components:
- type: Card
name: card-sc-8-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc9OfHeartsNanotrasen
components:
- type: Card
name: card-sc-9-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc10OfHeartsNanotrasen
components:
- type: Card
name: card-sc-10-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScKingOfHeartsNanotrasen
components:
- type: Card
name: card-sc-king-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScQueenOfHeartsNanotrasen
components:
- type: Card
name: card-sc-queen-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScJackOfHeartsNanotrasen
components:
- type: Card
name: card-sc-jack-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScAceOfHeartsNanotrasen
components:
- type: Card
name: card-sc-ace-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Hearts_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc2OfSpadesNanotrasen
components:
- type: Card
name: card-sc-2-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc3OfSpadesNanotrasen
components:
- type: Card
name: card-sc-3-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc4OfSpadesNanotrasen
components:
- type: Card
name: card-sc-4-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc5OfSpadesNanotrasen
components:
- type: Card
name: card-sc-5-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc6OfSpadesNanotrasen
components:
- type: Card
name: card-sc-6-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc7OfSpadesNanotrasen
components:
- type: Card
name: card-sc-7-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc8OfSpadesNanotrasen
components:
- type: Card
name: card-sc-8-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc9OfSpadesNanotrasen
components:
- type: Card
name: card-sc-9-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardSc10OfSpadesNanotrasen
components:
- type: Card
name: card-sc-10-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScKingOfSpadesNanotrasen
components:
- type: Card
name: card-sc-king-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScQueenOfSpadesNanotrasen
components:
- type: Card
name: card-sc-queen-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScJackOfSpadesNanotrasen
components:
- type: Card
name: card-sc-jack-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScAceOfSpadesNanotrasen
components:
- type: Card
name: card-sc-ace-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Spades_nanotrasen
- type: entity
parent: CardBaseNanotrasen
categories: [ HideSpawnMenu ]
id: CardScJokerNanotrasen
components:
- type: Card
name: card-sc-joker
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: nanotrasen_joker
# endregion Nanotrasen Cards

View File

@@ -0,0 +1,690 @@
- type: entity
parent: CardBase
id: CardBaseSyndicate
name: card
components:
- type: Card
backSprite:
- sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: singlecard_down_syndicate
- type: entity
parent: CardBoxBase
id: CardBoxSyndicate
name: syndicate deck box
components:
- type: Item
size: Small
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
layers:
- state: syndicate_box
- state: syndicate_box_open
map: [ "openLayer" ]
visible: false
- type: OpenTriggeredStorageFill
contents:
- id: CardDeckSyndicate
amount: 1
- type: entity
parent: CardDeckBase
id: CardDeckSyndicate
name: deck of cards
components:
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: deck_syndicate_full
- type: CardStack
initialContent:
# Clubs
- CardScAceOfClubsSyndicate
- CardSc2OfClubsSyndicate
- CardSc3OfClubsSyndicate
- CardSc4OfClubsSyndicate
- CardSc5OfClubsSyndicate
- CardSc6OfClubsSyndicate
- CardSc7OfClubsSyndicate
- CardSc8OfClubsSyndicate
- CardSc9OfClubsSyndicate
- CardSc10OfClubsSyndicate
- CardScJackOfClubsSyndicate
- CardScQueenOfClubsSyndicate
- CardScKingOfClubsSyndicate
# Diamonds
- CardScAceOfDiamondsSyndicate
- CardSc2OfDiamondsSyndicate
- CardSc3OfDiamondsSyndicate
- CardSc4OfDiamondsSyndicate
- CardSc5OfDiamondsSyndicate
- CardSc6OfDiamondsSyndicate
- CardSc7OfDiamondsSyndicate
- CardSc8OfDiamondsSyndicate
- CardSc9OfDiamondsSyndicate
- CardSc10OfDiamondsSyndicate
- CardScJackOfDiamondsSyndicate
- CardScQueenOfDiamondsSyndicate
- CardScKingOfDiamondsSyndicate
# Hearts
- CardScAceOfHeartsSyndicate
- CardSc2OfHeartsSyndicate
- CardSc3OfHeartsSyndicate
- CardSc4OfHeartsSyndicate
- CardSc5OfHeartsSyndicate
- CardSc6OfHeartsSyndicate
- CardSc7OfHeartsSyndicate
- CardSc8OfHeartsSyndicate
- CardSc9OfHeartsSyndicate
- CardSc10OfHeartsSyndicate
- CardScJackOfHeartsSyndicate
- CardScQueenOfHeartsSyndicate
- CardScKingOfHeartsSyndicate
# Spades
- CardScAceOfSpadesSyndicate
- CardSc2OfSpadesSyndicate
- CardSc3OfSpadesSyndicate
- CardSc4OfSpadesSyndicate
- CardSc5OfSpadesSyndicate
- CardSc6OfSpadesSyndicate
- CardSc7OfSpadesSyndicate
- CardSc8OfSpadesSyndicate
- CardSc9OfSpadesSyndicate
- CardSc10OfSpadesSyndicate
- CardScJackOfSpadesSyndicate
- CardScQueenOfSpadesSyndicate
- CardScKingOfSpadesSyndicate
# Joker
- CardScJokerSyndicate
# region Syndicate Cards
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc2OfClubsSyndicate
components:
- type: Card
name: card-sc-2-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc3OfClubsSyndicate
components:
- type: Card
name: card-sc-3-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc4OfClubsSyndicate
components:
- type: Card
name: card-sc-4-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc5OfClubsSyndicate
components:
- type: Card
name: card-sc-5-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc6OfClubsSyndicate
components:
- type: Card
name: card-sc-6-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc7OfClubsSyndicate
components:
- type: Card
name: card-sc-7-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc8OfClubsSyndicate
components:
- type: Card
name: card-sc-8-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc9OfClubsSyndicate
components:
- type: Card
name: card-sc-9-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc10OfClubsSyndicate
components:
- type: Card
name: card-sc-10-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScAceOfClubsSyndicate
components:
- type: Card
name: card-sc-ace-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScJackOfClubsSyndicate
components:
- type: Card
name: card-sc-jack-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScKingOfClubsSyndicate
components:
- type: Card
name: card-sc-king-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScQueenOfClubsSyndicate
components:
- type: Card
name: card-sc-queen-clubs
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Clubs_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScJackOfDiamondsSyndicate
components:
- type: Card
name: card-sc-jack-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScQueenOfDiamondsSyndicate
components:
- type: Card
name: card-sc-queen-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScKingOfDiamondsSyndicate
components:
- type: Card
name: card-sc-king-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScAceOfDiamondsSyndicate
components:
- type: Card
name: card-sc-ace-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc2OfDiamondsSyndicate
components:
- type: Card
name: card-sc-2-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc3OfDiamondsSyndicate
components:
- type: Card
name: card-sc-3-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc4OfDiamondsSyndicate
components:
- type: Card
name: card-sc-4-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc5OfDiamondsSyndicate
components:
- type: Card
name: card-sc-5-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc6OfDiamondsSyndicate
components:
- type: Card
name: card-sc-6-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc7OfDiamondsSyndicate
components:
- type: Card
name: card-sc-7-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc8OfDiamondsSyndicate
components:
- type: Card
name: card-sc-8-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc9OfDiamondsSyndicate
components:
- type: Card
name: card-sc-9-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc10OfDiamondsSyndicate
components:
- type: Card
name: card-sc-10-diamonds
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Diamonds_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc2OfHeartsSyndicate
components:
- type: Card
name: card-sc-2-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc3OfHeartsSyndicate
components:
- type: Card
name: card-sc-3-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc4OfHeartsSyndicate
components:
- type: Card
name: card-sc-4-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc5OfHeartsSyndicate
components:
- type: Card
name: card-sc-5-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc6OfHeartsSyndicate
components:
- type: Card
name: card-sc-6-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc7OfHeartsSyndicate
components:
- type: Card
name: card-sc-7-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc8OfHeartsSyndicate
components:
- type: Card
name: card-sc-8-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc9OfHeartsSyndicate
components:
- type: Card
name: card-sc-9-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc10OfHeartsSyndicate
components:
- type: Card
name: card-sc-10-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScKingOfHeartsSyndicate
components:
- type: Card
name: card-sc-king-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScQueenOfHeartsSyndicate
components:
- type: Card
name: card-sc-queen-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScJackOfHeartsSyndicate
components:
- type: Card
name: card-sc-jack-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScAceOfHeartsSyndicate
components:
- type: Card
name: card-sc-ace-hearts
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Hearts_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc2OfSpadesSyndicate
components:
- type: Card
name: card-sc-2-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_2_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc3OfSpadesSyndicate
components:
- type: Card
name: card-sc-3-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_3_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc4OfSpadesSyndicate
components:
- type: Card
name: card-sc-4-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_4_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc5OfSpadesSyndicate
components:
- type: Card
name: card-sc-5-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_5_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc6OfSpadesSyndicate
components:
- type: Card
name: card-sc-6-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_6_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc7OfSpadesSyndicate
components:
- type: Card
name: card-sc-7-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_7_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc8OfSpadesSyndicate
components:
- type: Card
name: card-sc-8-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_8_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc9OfSpadesSyndicate
components:
- type: Card
name: card-sc-9-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_9_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardSc10OfSpadesSyndicate
components:
- type: Card
name: card-sc-10-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_10_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScKingOfSpadesSyndicate
components:
- type: Card
name: card-sc-king-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_King_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScQueenOfSpadesSyndicate
components:
- type: Card
name: card-sc-queen-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Queen_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScJackOfSpadesSyndicate
components:
- type: Card
name: card-sc-jack-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Jack_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScAceOfSpadesSyndicate
components:
- type: Card
name: card-sc-ace-spades
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: sc_Ace_of_Spades_syndicate
- type: entity
parent: CardBaseSyndicate
categories: [ HideSpawnMenu ]
id: CardScJokerSyndicate
components:
- type: Card
name: card-sc-joker
- type: Sprite
sprite: EstacaoPirata/Objects/Misc/cards.rsi
state: syndicate_joker
# endregion Syndicate Cards

View File

@@ -0,0 +1,50 @@
- type: soundCollection
id: cardFan
files:
- /Audio/EstacaoPirata/Effects/Cards/cardFan1.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardFan2.ogg
- type: soundCollection
id: cardOpenPackage
files:
- /Audio/EstacaoPirata/Effects/Cards/cardOpenPackage1.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardOpenPackage2.ogg
- type: soundCollection
id: cardPlace
files:
- /Audio/EstacaoPirata/Effects/Cards/cardPlace1.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardPlace2.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardPlace3.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardPlace4.ogg
- type: soundCollection
id: cardShove
files:
- /Audio/EstacaoPirata/Effects/Cards/cardShove1.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardShove2.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardShove3.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardShove4.ogg
- type: soundCollection
id: cardShuffle
files:
- /Audio/EstacaoPirata/Effects/Cards/cardShuffle.ogg
- type: soundCollection
id: cardSlide
files:
- /Audio/EstacaoPirata/Effects/Cards/cardSlide1.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardSlide2.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardSlide3.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardSlide4.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardSlide5.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardSlide6.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardSlide7.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardSlide8.ogg
- type: soundCollection
id: cardTakeOutPackage
files:
- /Audio/EstacaoPirata/Effects/Cards/cardTakeOutPackage1.ogg
- /Audio/EstacaoPirata/Effects/Cards/cardTakeOutPackage2.ogg

View File

@@ -818,3 +818,28 @@
group: LoadoutPets
functions:
- !type:LoadoutMakeFollower
- type: loadout
id: LoadoutItemBlackDeck
category: Items
cost: 3
canBeHeirloom: false
items:
- CardBoxBlack
requirements:
- !type:CharacterItemGroupRequirement
group: LoadoutCards
- type: loadout
id: LoadoutItemNTDeck
category: Items
cost: 3
canBeHeirloom: false
items:
- CardBoxNanotrasen
requirements:
- !type:CharacterItemGroupRequirement
group: LoadoutCards
- !type:CharacterDepartmentRequirement
departments:
- Command

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 B

View File

@@ -0,0 +1,614 @@
{
"version": 1,
"copyright": "Cards, Decks and Hands Sprites were originally from Paradise Station (https://github.com/ParadiseSS13/Paradise) and modified by VictorJob. Boxes are from VictorJob.",
"license": "CC-BY-SA-3.0",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "black_hand1"
},
{
"name": "black_hand2"
},
{
"name": "black_hand3"
},
{
"name": "black_hand4"
},
{
"name": "black_hand5"
},
{
"name": "deck_black_empty"
},
{
"name": "deck_black_full"
},
{
"name": "deck_black_half"
},
{
"name": "deck_black_low"
},
{
"name": "deck_nanotrasen_empty"
},
{
"name": "deck_nanotrasen_full"
},
{
"name": "deck_nanotrasen_half"
},
{
"name": "deck_nanotrasen_low"
},
{
"name": "deck_syndicate_empty"
},
{
"name": "deck_syndicate_full"
},
{
"name": "deck_syndicate_half"
},
{
"name": "deck_syndicate_low"
},
{
"name": "nanotrasen_hand1"
},
{
"name": "nanotrasen_hand2"
},
{
"name": "nanotrasen_hand3"
},
{
"name": "nanotrasen_hand4"
},
{
"name": "nanotrasen_hand5"
},
{
"name": "sc_10_of_Clubs_black"
},
{
"name": "sc_10_of_Clubs_nanotrasen"
},
{
"name": "sc_10_of_Clubs_syndicate"
},
{
"name": "sc_10_of_Diamonds_black"
},
{
"name": "sc_10_of_Diamonds_nanotrasen"
},
{
"name": "sc_10_of_Diamonds_syndicate"
},
{
"name": "sc_10_of_Hearts_black"
},
{
"name": "sc_10_of_Hearts_nanotrasen"
},
{
"name": "sc_10_of_Hearts_syndicate"
},
{
"name": "sc_10_of_Spades_black"
},
{
"name": "sc_10_of_Spades_nanotrasen"
},
{
"name": "sc_10_of_Spades_syndicate"
},
{
"name": "sc_2_of_Clubs_black"
},
{
"name": "sc_2_of_Clubs_nanotrasen"
},
{
"name": "sc_2_of_Clubs_syndicate"
},
{
"name": "sc_2_of_Diamonds_black"
},
{
"name": "sc_2_of_Diamonds_nanotrasen"
},
{
"name": "sc_2_of_Diamonds_syndicate"
},
{
"name": "sc_2_of_Hearts_black"
},
{
"name": "sc_2_of_Hearts_nanotrasen"
},
{
"name": "sc_2_of_Hearts_syndicate"
},
{
"name": "sc_2_of_Spades_black"
},
{
"name": "sc_2_of_Spades_nanotrasen"
},
{
"name": "sc_2_of_Spades_syndicate"
},
{
"name": "sc_3_of_Clubs_black"
},
{
"name": "sc_3_of_Clubs_nanotrasen"
},
{
"name": "sc_3_of_Clubs_syndicate"
},
{
"name": "sc_3_of_Diamonds_black"
},
{
"name": "sc_3_of_Diamonds_nanotrasen"
},
{
"name": "sc_3_of_Diamonds_syndicate"
},
{
"name": "sc_3_of_Hearts_black"
},
{
"name": "sc_3_of_Hearts_nanotrasen"
},
{
"name": "sc_3_of_Hearts_syndicate"
},
{
"name": "sc_3_of_Spades_black"
},
{
"name": "sc_3_of_Spades_nanotrasen"
},
{
"name": "sc_3_of_Spades_syndicate"
},
{
"name": "sc_4_of_Clubs_black"
},
{
"name": "sc_4_of_Clubs_nanotrasen"
},
{
"name": "sc_4_of_Clubs_syndicate"
},
{
"name": "sc_4_of_Diamonds_black"
},
{
"name": "sc_4_of_Diamonds_nanotrasen"
},
{
"name": "sc_4_of_Diamonds_syndicate"
},
{
"name": "sc_4_of_Hearts_black"
},
{
"name": "sc_4_of_Hearts_nanotrasen"
},
{
"name": "sc_4_of_Hearts_syndicate"
},
{
"name": "sc_4_of_Spades_black"
},
{
"name": "sc_4_of_Spades_nanotrasen"
},
{
"name": "sc_4_of_Spades_syndicate"
},
{
"name": "sc_5_of_Clubs_black"
},
{
"name": "sc_5_of_Clubs_nanotrasen"
},
{
"name": "sc_5_of_Clubs_syndicate"
},
{
"name": "sc_5_of_Diamonds_black"
},
{
"name": "sc_5_of_Diamonds_nanotrasen"
},
{
"name": "sc_5_of_Diamonds_syndicate"
},
{
"name": "sc_5_of_Hearts_black"
},
{
"name": "sc_5_of_Hearts_nanotrasen"
},
{
"name": "sc_5_of_Hearts_syndicate"
},
{
"name": "sc_5_of_Spades_black"
},
{
"name": "sc_5_of_Spades_nanotrasen"
},
{
"name": "sc_5_of_Spades_syndicate"
},
{
"name": "sc_6_of_Clubs_black"
},
{
"name": "sc_6_of_Clubs_nanotrasen"
},
{
"name": "sc_6_of_Clubs_syndicate"
},
{
"name": "sc_6_of_Diamonds_black"
},
{
"name": "sc_6_of_Diamonds_nanotrasen"
},
{
"name": "sc_6_of_Diamonds_syndicate"
},
{
"name": "sc_6_of_Hearts_black"
},
{
"name": "sc_6_of_Hearts_nanotrasen"
},
{
"name": "sc_6_of_Hearts_syndicate"
},
{
"name": "sc_6_of_Spades_black"
},
{
"name": "sc_6_of_Spades_nanotrasen"
},
{
"name": "sc_6_of_Spades_syndicate"
},
{
"name": "sc_7_of_Clubs_black"
},
{
"name": "sc_7_of_Clubs_nanotrasen"
},
{
"name": "sc_7_of_Clubs_syndicate"
},
{
"name": "sc_7_of_Diamonds_black"
},
{
"name": "sc_7_of_Diamonds_nanotrasen"
},
{
"name": "sc_7_of_Diamonds_syndicate"
},
{
"name": "sc_7_of_Hearts_black"
},
{
"name": "sc_7_of_Hearts_nanotrasen"
},
{
"name": "sc_7_of_Hearts_syndicate"
},
{
"name": "sc_7_of_Spades_black"
},
{
"name": "sc_7_of_Spades_nanotrasen"
},
{
"name": "sc_7_of_Spades_syndicate"
},
{
"name": "sc_8_of_Clubs_black"
},
{
"name": "sc_8_of_Clubs_nanotrasen"
},
{
"name": "sc_8_of_Clubs_syndicate"
},
{
"name": "sc_8_of_Diamonds_black"
},
{
"name": "sc_8_of_Diamonds_nanotrasen"
},
{
"name": "sc_8_of_Diamonds_syndicate"
},
{
"name": "sc_8_of_Hearts_black"
},
{
"name": "sc_8_of_Hearts_nanotrasen"
},
{
"name": "sc_8_of_Hearts_syndicate"
},
{
"name": "sc_8_of_Spades_black"
},
{
"name": "sc_8_of_Spades_nanotrasen"
},
{
"name": "sc_8_of_Spades_syndicate"
},
{
"name": "sc_9_of_Clubs_black"
},
{
"name": "sc_9_of_Clubs_nanotrasen"
},
{
"name": "sc_9_of_Clubs_syndicate"
},
{
"name": "sc_9_of_Diamonds_black"
},
{
"name": "sc_9_of_Diamonds_nanotrasen"
},
{
"name": "sc_9_of_Diamonds_syndicate"
},
{
"name": "sc_9_of_Hearts_black"
},
{
"name": "sc_9_of_Hearts_nanotrasen"
},
{
"name": "sc_9_of_Hearts_syndicate"
},
{
"name": "sc_9_of_Spades_black"
},
{
"name": "sc_9_of_Spades_nanotrasen"
},
{
"name": "sc_9_of_Spades_syndicate"
},
{
"name": "sc_Ace_of_Clubs_black"
},
{
"name": "sc_Ace_of_Clubs_nanotrasen"
},
{
"name": "sc_Ace_of_Clubs_syndicate"
},
{
"name": "sc_Ace_of_Diamonds_black"
},
{
"name": "sc_Ace_of_Diamonds_nanotrasen"
},
{
"name": "sc_Ace_of_Diamonds_syndicate"
},
{
"name": "sc_Ace_of_Hearts_black"
},
{
"name": "sc_Ace_of_Hearts_nanotrasen"
},
{
"name": "sc_Ace_of_Hearts_syndicate"
},
{
"name": "sc_Ace_of_Spades_black"
},
{
"name": "sc_Ace_of_Spades_nanotrasen"
},
{
"name": "sc_Ace_of_Spades_syndicate"
},
{
"name": "sc_Jack_of_Clubs_black"
},
{
"name": "sc_Jack_of_Clubs_nanotrasen"
},
{
"name": "sc_Jack_of_Clubs_syndicate"
},
{
"name": "sc_Jack_of_Diamonds_black"
},
{
"name": "sc_Jack_of_Diamonds_nanotrasen"
},
{
"name": "sc_Jack_of_Diamonds_syndicate"
},
{
"name": "sc_Jack_of_Hearts_black"
},
{
"name": "sc_Jack_of_Hearts_nanotrasen"
},
{
"name": "sc_Jack_of_Hearts_syndicate"
},
{
"name": "sc_Jack_of_Spades_black"
},
{
"name": "sc_Jack_of_Spades_nanotrasen"
},
{
"name": "sc_Jack_of_Spades_syndicate"
},
{
"name": "sc_King_of_Clubs_black"
},
{
"name": "sc_King_of_Clubs_nanotrasen"
},
{
"name": "sc_King_of_Clubs_syndicate"
},
{
"name": "sc_King_of_Diamonds_black"
},
{
"name": "sc_King_of_Diamonds_nanotrasen"
},
{
"name": "sc_King_of_Diamonds_syndicate"
},
{
"name": "sc_King_of_Hearts_black"
},
{
"name": "sc_King_of_Hearts_nanotrasen"
},
{
"name": "sc_King_of_Hearts_syndicate"
},
{
"name": "sc_King_of_Spades_black"
},
{
"name": "sc_King_of_Spades_nanotrasen"
},
{
"name": "sc_King_of_Spades_syndicate"
},
{
"name": "sc_Queen_of_Clubs_black"
},
{
"name": "sc_Queen_of_Clubs_nanotrasen"
},
{
"name": "sc_Queen_of_Clubs_syndicate"
},
{
"name": "sc_Queen_of_Diamonds_black"
},
{
"name": "sc_Queen_of_Diamonds_nanotrasen"
},
{
"name": "sc_Queen_of_Diamonds_syndicate"
},
{
"name": "sc_Queen_of_Hearts_black"
},
{
"name": "sc_Queen_of_Hearts_nanotrasen"
},
{
"name": "sc_Queen_of_Hearts_syndicate"
},
{
"name": "sc_Queen_of_Spades_black"
},
{
"name": "sc_Queen_of_Spades_nanotrasen"
},
{
"name": "sc_Queen_of_Spades_syndicate"
},
{
"name": "singlecard_down_black"
},
{
"name": "singlecard_down_nanotrasen"
},
{
"name": "singlecard_down_syndicate"
},
{
"name": "syndicate_hand1"
},
{
"name": "syndicate_hand2"
},
{
"name": "syndicate_hand3"
},
{
"name": "syndicate_hand4"
},
{
"name": "syndicate_hand5"
},
{
"name": "syndicate_joker",
"delays": [
[
0.5,
0.5
]
]
},
{
"name": "nanotrasen_joker",
"delays": [
[
0.5,
0.5
]
]
},
{
"name": "black_joker",
"delays": [
[
0.5,
0.5
]
]
},
{
"name": "syndicate_box"
},
{
"name": "syndicate_box_open"
},
{
"name": "black_box"
},
{
"name": "black_box_open"
},
{
"name": "nanotrasen_box"
},
{
"name": "nanotrasen_box_open"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 550 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Some files were not shown because too many files have changed in this diff Show More