Cargo: pizza & bureaucracy (#5123)
* add paper label component * git mv * rename namespace * add cargo printouts * more crates * directly attach paper * comment typo
This commit is contained in:
@@ -25,6 +25,7 @@ namespace Content.Client.Entry
|
|||||||
"MeleeWeapon",
|
"MeleeWeapon",
|
||||||
"MeleeChemicalInjector",
|
"MeleeChemicalInjector",
|
||||||
"Dice",
|
"Dice",
|
||||||
|
"PaperLabel",
|
||||||
"Construction",
|
"Construction",
|
||||||
"PoweredLight",
|
"PoweredLight",
|
||||||
"Smes",
|
"Smes",
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using Content.Shared.HandLabeler;
|
using Content.Shared.Labels;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
|
||||||
namespace Content.Client.HandLabeler.UI
|
namespace Content.Client.Labels.UI
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a <see cref="HandLabelerWindow"/> and updates it when new server messages are received.
|
/// Initializes a <see cref="HandLabelerWindow"/> and updates it when new server messages are received.
|
||||||
@@ -4,7 +4,7 @@ using Robust.Client.AutoGenerated;
|
|||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
|
|
||||||
namespace Content.Client.HandLabeler.UI
|
namespace Content.Client.Labels.UI
|
||||||
{
|
{
|
||||||
[GenerateTypedNameReferences]
|
[GenerateTypedNameReferences]
|
||||||
public partial class HandLabelerWindow : SS14Window
|
public partial class HandLabelerWindow : SS14Window
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
using Content.Shared.Morgue;
|
using Content.Shared.Labels;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ namespace Content.Client.Morgue.Visualizers
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component.TryGetData(BodyBagVisuals.Label, out bool labelVal))
|
if (component.TryGetData(PaperLabelVisuals.HasLabel, out bool labelVal))
|
||||||
{
|
{
|
||||||
sprite.LayerSetVisible(BodyBagVisualLayers.Label, labelVal);
|
sprite.LayerSetVisible(BodyBagVisualLayers.Label, labelVal);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
using Content.Server.Access.Components;
|
using Content.Server.Access.Components;
|
||||||
|
using Content.Server.Inventory.Components;
|
||||||
|
using Content.Server.Items;
|
||||||
|
using Content.Server.PDA;
|
||||||
using Content.Shared.Access;
|
using Content.Shared.Access;
|
||||||
|
using Content.Shared.Hands.Components;
|
||||||
|
using Content.Shared.Inventory;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Content.Server.Access.Systems
|
namespace Content.Server.Access.Systems
|
||||||
{
|
{
|
||||||
@@ -74,5 +80,53 @@ namespace Content.Server.Access.Systems
|
|||||||
("fullName", id.FullName),
|
("fullName", id.FullName),
|
||||||
("jobSuffix", jobSuffix));
|
("jobSuffix", jobSuffix));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempt to find an ID card on an entity. This will look in the entity itself, in the entity's hands, and
|
||||||
|
/// in the entity's inventory.
|
||||||
|
/// </summary>
|
||||||
|
public bool TryFindIdCard(EntityUid uid, [NotNullWhen(true)] out IdCardComponent? idCard)
|
||||||
|
{
|
||||||
|
// check held item?
|
||||||
|
if (EntityManager.TryGetComponent(uid, out SharedHandsComponent? hands) &&
|
||||||
|
hands.TryGetActiveHeldEntity(out var heldItem) &&
|
||||||
|
TryGetIdCard(heldItem.Uid, out idCard))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check entity itself
|
||||||
|
if (TryGetIdCard(uid, out idCard))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// check inventory slot?
|
||||||
|
if (EntityManager.TryGetComponent(uid, out InventoryComponent? inventoryComponent) &&
|
||||||
|
inventoryComponent.HasSlot(EquipmentSlotDefines.Slots.IDCARD) &&
|
||||||
|
inventoryComponent.TryGetSlotItem(EquipmentSlotDefines.Slots.IDCARD, out ItemComponent? item) &&
|
||||||
|
TryGetIdCard(item.Owner.Uid, out idCard))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempt to get an id card component from an entity, either by getting it directly from the entity, or by
|
||||||
|
/// getting the contained id from a <see cref="PDAComponent"/>.
|
||||||
|
/// </summary>
|
||||||
|
private bool TryGetIdCard(EntityUid uid, [NotNullWhen(true)] out IdCardComponent? idCard)
|
||||||
|
{
|
||||||
|
if (EntityManager.TryGetComponent(uid, out idCard))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (EntityManager.TryGetComponent(uid, out PDAComponent? pda) && pda.ContainedID != null)
|
||||||
|
{
|
||||||
|
idCard = pda.ContainedID;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Content.Server.Access.Components;
|
||||||
|
using Content.Server.Access.Systems;
|
||||||
using Content.Server.Cargo.Components;
|
using Content.Server.Cargo.Components;
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
using Content.Shared.GameTicking;
|
using Content.Shared.GameTicking;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
|
||||||
namespace Content.Server.Cargo
|
namespace Content.Server.Cargo
|
||||||
{
|
{
|
||||||
@@ -43,6 +46,9 @@ namespace Content.Server.Cargo
|
|||||||
|
|
||||||
public CargoOrderDatabase StationOrderDatabase => GetOrderDatabase(0);
|
public CargoOrderDatabase StationOrderDatabase => GetOrderDatabase(0);
|
||||||
|
|
||||||
|
[Dependency] private readonly IdCardSystem _idCardSystem = default!;
|
||||||
|
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
|
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
|
||||||
@@ -171,12 +177,25 @@ namespace Content.Server.Cargo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ApproveOrder(int id, int orderNumber)
|
public bool ApproveOrder(EntityUid uid, EntityUid approver, int id, int orderNumber, AccessReader? reader = null)
|
||||||
{
|
{
|
||||||
|
// does the approver have permission to approve orders?
|
||||||
|
if (Resolve(uid, ref reader) && !_accessReaderSystem.IsAllowed(reader, approver))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// get the approver's name
|
||||||
|
_idCardSystem.TryFindIdCard(approver, out var idCard);
|
||||||
|
var approverName = idCard?.FullName ?? string.Empty;
|
||||||
|
|
||||||
if (!TryGetOrderDatabase(id, out var database))
|
if (!TryGetOrderDatabase(id, out var database))
|
||||||
return false;
|
return false;
|
||||||
if (!database.ApproveOrder(orderNumber))
|
|
||||||
|
if (!database.TryGetOrder(orderNumber, out var order))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!database.ApproveOrder(approverName, orderNumber))
|
||||||
|
return false;
|
||||||
|
|
||||||
SyncComponentsWithId(id);
|
SyncComponentsWithId(id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Server.Access.Systems;
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Localization;
|
using Robust.Shared.Localization;
|
||||||
|
|
||||||
namespace Content.Server.Cargo
|
namespace Content.Server.Cargo
|
||||||
@@ -84,7 +86,7 @@ namespace Content.Server.Cargo
|
|||||||
/// Approves an order in the database.
|
/// Approves an order in the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="order">The order to be approved.</param>
|
/// <param name="order">The order to be approved.</param>
|
||||||
public bool ApproveOrder(int orderNumber)
|
public bool ApproveOrder(string approver, int orderNumber)
|
||||||
{
|
{
|
||||||
if (CurrentOrderSize == MaxOrderSize ||
|
if (CurrentOrderSize == MaxOrderSize ||
|
||||||
!_orders.TryGetValue(orderNumber, out var order) ||
|
!_orders.TryGetValue(orderNumber, out var order) ||
|
||||||
@@ -104,6 +106,8 @@ namespace Content.Server.Cargo
|
|||||||
}
|
}
|
||||||
|
|
||||||
order.Approved = true;
|
order.Approved = true;
|
||||||
|
order.Approver = approver;
|
||||||
|
|
||||||
CurrentOrderSize += order.Amount;
|
CurrentOrderSize += order.Amount;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,6 +135,10 @@ namespace Content.Server.Cargo.Components
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var uid = msg.Session.AttachedEntityUid;
|
||||||
|
if (uid == null)
|
||||||
|
break;
|
||||||
|
|
||||||
PrototypeManager.TryIndex(order.ProductId, out CargoProductPrototype? product);
|
PrototypeManager.TryIndex(order.ProductId, out CargoProductPrototype? product);
|
||||||
if (product == null!)
|
if (product == null!)
|
||||||
break;
|
break;
|
||||||
@@ -143,13 +147,14 @@ namespace Content.Server.Cargo.Components
|
|||||||
(capacity.CurrentCapacity == capacity.MaxCapacity
|
(capacity.CurrentCapacity == capacity.MaxCapacity
|
||||||
|| capacity.CurrentCapacity + order.Amount > capacity.MaxCapacity
|
|| capacity.CurrentCapacity + order.Amount > capacity.MaxCapacity
|
||||||
|| !_cargoConsoleSystem.CheckBalance(_bankAccount.Id, (-product.PointCost) * order.Amount)
|
|| !_cargoConsoleSystem.CheckBalance(_bankAccount.Id, (-product.PointCost) * order.Amount)
|
||||||
|| !_cargoConsoleSystem.ApproveOrder(orders.Database.Id, msg.OrderNumber)
|
|| !_cargoConsoleSystem.ApproveOrder(Owner.Uid, uid.Value, orders.Database.Id, msg.OrderNumber)
|
||||||
|| !_cargoConsoleSystem.ChangeBalance(_bankAccount.Id, (-product.PointCost) * order.Amount))
|
|| !_cargoConsoleSystem.ChangeBalance(_bankAccount.Id, (-product.PointCost) * order.Amount))
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
SoundSystem.Play(Filter.Local(), _errorSound.GetSound(), Owner, AudioParams.Default);
|
SoundSystem.Play(Filter.Local(), _errorSound.GetSound(), Owner, AudioParams.Default);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateUIState();
|
UpdateUIState();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -189,12 +194,7 @@ namespace Content.Server.Cargo.Components
|
|||||||
orders.Database.ClearOrderCapacity();
|
orders.Database.ClearOrderCapacity();
|
||||||
foreach (var order in approvedOrders)
|
foreach (var order in approvedOrders)
|
||||||
{
|
{
|
||||||
if (!PrototypeManager.TryIndex(order.ProductId, out CargoProductPrototype? product))
|
telepadComponent.QueueTeleport(order);
|
||||||
continue;
|
|
||||||
for (var i = 0; i < order.Amount; i++)
|
|
||||||
{
|
|
||||||
telepadComponent.QueueTeleport(product);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.Labels.Components;
|
||||||
|
using Content.Server.Paper;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Shared.Cargo;
|
using Content.Shared.Cargo;
|
||||||
|
using Content.Shared.Containers.ItemSlots;
|
||||||
using Content.Shared.Sound;
|
using Content.Shared.Sound;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
namespace Content.Server.Cargo.Components
|
namespace Content.Server.Cargo.Components
|
||||||
{
|
{
|
||||||
@@ -17,14 +24,23 @@ namespace Content.Server.Cargo.Components
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class CargoTelepadComponent : Component
|
public class CargoTelepadComponent : Component
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
[Dependency] private readonly IEntityManager _entityManager = default!;
|
||||||
|
|
||||||
public override string Name => "CargoTelepad";
|
public override string Name => "CargoTelepad";
|
||||||
|
|
||||||
private const float TeleportDuration = 0.5f;
|
private const float TeleportDuration = 0.5f;
|
||||||
private const float TeleportDelay = 15f;
|
private const float TeleportDelay = 15f;
|
||||||
private List<CargoProductPrototype> _teleportQueue = new List<CargoProductPrototype>();
|
private List<CargoOrderData> _teleportQueue = new();
|
||||||
private CargoTelepadState _currentState = CargoTelepadState.Unpowered;
|
private CargoTelepadState _currentState = CargoTelepadState.Unpowered;
|
||||||
[DataField("teleportSound")] private SoundSpecifier _teleportSound = new SoundPathSpecifier("/Audio/Machines/phasein.ogg");
|
[DataField("teleportSound")] private SoundSpecifier _teleportSound = new SoundPathSpecifier("/Audio/Machines/phasein.ogg");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The paper-type prototype to spawn with the order information.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("printerOutput", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||||
|
public string PrinterOutput = "Paper";
|
||||||
|
|
||||||
[Obsolete("Component Messages are deprecated, use Entity Events instead.")]
|
[Obsolete("Component Messages are deprecated, use Entity Events instead.")]
|
||||||
public override void HandleMessage(ComponentMessage message, IComponent? component)
|
public override void HandleMessage(ComponentMessage message, IComponent? component)
|
||||||
{
|
{
|
||||||
@@ -39,9 +55,12 @@ namespace Content.Server.Cargo.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueTeleport(CargoProductPrototype product)
|
public void QueueTeleport(CargoOrderData order)
|
||||||
{
|
{
|
||||||
_teleportQueue.Add(product);
|
for (var i = 0; i < order.Amount; i++)
|
||||||
|
{
|
||||||
|
_teleportQueue.Add(order);
|
||||||
|
}
|
||||||
TeleportLoop();
|
TeleportLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +98,7 @@ namespace Content.Server.Cargo.Components
|
|||||||
if (!Deleted && !Owner.Deleted && _currentState == CargoTelepadState.Teleporting && _teleportQueue.Count > 0)
|
if (!Deleted && !Owner.Deleted && _currentState == CargoTelepadState.Teleporting && _teleportQueue.Count > 0)
|
||||||
{
|
{
|
||||||
SoundSystem.Play(Filter.Pvs(Owner), _teleportSound.GetSound(), Owner, AudioParams.Default.WithVolume(-8f));
|
SoundSystem.Play(Filter.Pvs(Owner), _teleportSound.GetSound(), Owner, AudioParams.Default.WithVolume(-8f));
|
||||||
Owner.EntityManager.SpawnEntity(_teleportQueue[0].Product, Owner.Transform.Coordinates);
|
SpawnProduct(_teleportQueue[0]);
|
||||||
_teleportQueue.RemoveAt(0);
|
_teleportQueue.RemoveAt(0);
|
||||||
if (Owner.TryGetComponent<SpriteComponent>(out var spriteComponent) && spriteComponent.LayerCount > 0)
|
if (Owner.TryGetComponent<SpriteComponent>(out var spriteComponent) && spriteComponent.LayerCount > 0)
|
||||||
spriteComponent.LayerSetState(0, "idle");
|
spriteComponent.LayerSetState(0, "idle");
|
||||||
@@ -92,6 +111,38 @@ namespace Content.Server.Cargo.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Spawn the product and a piece of paper. Attempt to attach the paper to the product.
|
||||||
|
/// </summary>
|
||||||
|
private void SpawnProduct(CargoOrderData data)
|
||||||
|
{
|
||||||
|
// spawn the order
|
||||||
|
if (!_prototypeManager.TryIndex(data.ProductId, out CargoProductPrototype? prototype))
|
||||||
|
return;
|
||||||
|
var product = Owner.EntityManager.SpawnEntity(prototype.Product, Owner.Transform.Coordinates);
|
||||||
|
|
||||||
|
// spawn a piece of paper.
|
||||||
|
var printed = Owner.EntityManager.SpawnEntity(PrinterOutput, Owner.Transform.Coordinates);
|
||||||
|
if (!_entityManager.TryGetComponent(printed.Uid, out PaperComponent paper))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// fill in the order data
|
||||||
|
printed.Name = Loc.GetString("cargo-console-paper-print-name", ("orderNumber", data.OrderNumber));
|
||||||
|
paper.SetContent(Loc.GetString(
|
||||||
|
"cargo-console-paper-print-text",
|
||||||
|
("orderNumber", data.OrderNumber),
|
||||||
|
("requester", data.Requester),
|
||||||
|
("reason", data.Reason),
|
||||||
|
("approver", data.Approver)));
|
||||||
|
|
||||||
|
// attempt to attach the label
|
||||||
|
if (_entityManager.TryGetComponent(product.Uid, out PaperLabelComponent label) &&
|
||||||
|
_entityManager.TryGetComponent(product.Uid, out SharedItemSlotsComponent slots))
|
||||||
|
{
|
||||||
|
EntitySystem.Get<SharedItemSlotsSystem>().TryInsertContent(slots, printed, label.LabelSlot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private enum CargoTelepadState { Unpowered, Idle, Charging, Teleporting };
|
private enum CargoTelepadState { Unpowered, Idle, Charging, Teleporting };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
using Content.Server.HandLabeler.Components;
|
|
||||||
using Content.Shared.Examine;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Utility;
|
|
||||||
|
|
||||||
namespace Content.Server.HandLabeler
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A system that lets players see the contents of a label on an object.
|
|
||||||
/// </summary>
|
|
||||||
[UsedImplicitly]
|
|
||||||
public class LabelSystem : EntitySystem
|
|
||||||
{
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
|
|
||||||
SubscribeLocalEvent<LabelComponent, ExaminedEvent>(OnExamine);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnExamine(EntityUid uid, LabelComponent? label, ExaminedEvent args)
|
|
||||||
{
|
|
||||||
if (!Resolve(uid, ref label))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (label.CurrentLabel == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var message = new FormattedMessage();
|
|
||||||
message.AddText(Loc.GetString("hand-labeler-has-label", ("label", label.CurrentLabel)));
|
|
||||||
args.PushMessage(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@ using Robust.Shared.GameObjects;
|
|||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.HandLabeler.Components
|
namespace Content.Server.Labels.Components
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class HandLabelerComponent : Component
|
public class HandLabelerComponent : Component
|
||||||
@@ -2,7 +2,7 @@ using Robust.Shared.GameObjects;
|
|||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Server.HandLabeler.Components
|
namespace Content.Server.Labels.Components
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class LabelComponent : Component
|
public class LabelComponent : Component
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Serialization.Manager.Attributes;
|
||||||
|
|
||||||
|
namespace Content.Server.Labels.Components
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This component allows you to attach and remove a piece of paper to an entity.
|
||||||
|
/// </summary>
|
||||||
|
[RegisterComponent]
|
||||||
|
public class PaperLabelComponent : Component
|
||||||
|
{
|
||||||
|
public override string Name => "PaperLabel";
|
||||||
|
|
||||||
|
[DataField("labelSlot")]
|
||||||
|
public string LabelSlot = "labelSlot";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Content.Server.HandLabeler.Components;
|
using Content.Server.Labels.Components;
|
||||||
using Content.Server.UserInterface;
|
using Content.Server.UserInterface;
|
||||||
using Content.Shared.ActionBlocker;
|
using Content.Shared.ActionBlocker;
|
||||||
using Content.Shared.HandLabeler;
|
using Content.Shared.Labels;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
@@ -12,7 +12,7 @@ using Robust.Shared.Localization;
|
|||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Content.Server.HandLabeler
|
namespace Content.Server.Labels
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A hand labeler system that lets an object apply labels to objects with the <see cref="LabelComponent"/> .
|
/// A hand labeler system that lets an object apply labels to objects with the <see cref="LabelComponent"/> .
|
||||||
97
Content.Server/Labels/Label/LabelSystem.cs
Normal file
97
Content.Server/Labels/Label/LabelSystem.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
using Content.Server.Labels.Components;
|
||||||
|
using Content.Server.Paper;
|
||||||
|
using Content.Shared.Containers.ItemSlots;
|
||||||
|
using Content.Shared.Examine;
|
||||||
|
using Content.Shared.Labels;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Localization;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Content.Server.Labels
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A system that lets players see the contents of a label on an object.
|
||||||
|
/// </summary>
|
||||||
|
[UsedImplicitly]
|
||||||
|
public class LabelSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly SharedItemSlotsSystem _itemSlotsSystem = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<LabelComponent, ExaminedEvent>(OnExamine);
|
||||||
|
SubscribeLocalEvent<PaperLabelComponent, ComponentInit>(InitializePaperLabel);
|
||||||
|
SubscribeLocalEvent<PaperLabelComponent, ItemSlotChangedEvent>(OnItemSlotChanged);
|
||||||
|
SubscribeLocalEvent<PaperLabelComponent, ExaminedEvent>(OnExamined);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializePaperLabel(EntityUid uid, PaperLabelComponent component, ComponentInit args)
|
||||||
|
{
|
||||||
|
if (!EntityManager.TryGetComponent(uid, out SharedAppearanceComponent appearance))
|
||||||
|
return;
|
||||||
|
|
||||||
|
appearance.SetData(PaperLabelVisuals.HasLabel, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnExamine(EntityUid uid, LabelComponent? label, ExaminedEvent args)
|
||||||
|
{
|
||||||
|
if (!Resolve(uid, ref label))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (label.CurrentLabel == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var message = new FormattedMessage();
|
||||||
|
message.AddText(Loc.GetString("hand-labeler-has-label", ("label", label.CurrentLabel)));
|
||||||
|
args.PushMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnExamined(EntityUid uid, PaperLabelComponent comp, ExaminedEvent args)
|
||||||
|
{
|
||||||
|
if (!EntityManager.TryGetComponent(uid, out SharedItemSlotsComponent slots))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var label = _itemSlotsSystem.PeekItemInSlot(slots, comp.LabelSlot);
|
||||||
|
|
||||||
|
if (label == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!args.IsInDetailsRange)
|
||||||
|
{
|
||||||
|
args.PushMarkup(Loc.GetString("comp-paper-label-has-label-cant-read"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EntityManager.TryGetComponent(label.Uid, out PaperComponent paper))
|
||||||
|
// should never happen
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(paper.Content))
|
||||||
|
{
|
||||||
|
args.PushMarkup(Loc.GetString("comp-paper-label-has-label-blank"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.PushMarkup(Loc.GetString("comp-paper-label-has-label"));
|
||||||
|
var text = paper.Content;
|
||||||
|
args.PushMarkup(text.TrimEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void OnItemSlotChanged(EntityUid uid, PaperLabelComponent component, ItemSlotChangedEvent args)
|
||||||
|
{
|
||||||
|
if (args.SlotName != component.LabelSlot)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!EntityManager.TryGetComponent(uid, out SharedAppearanceComponent appearance))
|
||||||
|
return;
|
||||||
|
|
||||||
|
appearance.SetData(PaperLabelVisuals.HasLabel, args.ContainedItem != null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,81 +22,14 @@ namespace Content.Server.Morgue.Components
|
|||||||
[ComponentReference(typeof(EntityStorageComponent))]
|
[ComponentReference(typeof(EntityStorageComponent))]
|
||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
[ComponentReference(typeof(IStorageComponent))]
|
[ComponentReference(typeof(IStorageComponent))]
|
||||||
#pragma warning disable 618
|
public class BodyBagEntityStorageComponent : EntityStorageComponent
|
||||||
public class BodyBagEntityStorageComponent : EntityStorageComponent, IExamine, IInteractUsing
|
|
||||||
#pragma warning restore 618
|
|
||||||
{
|
{
|
||||||
public override string Name => "BodyBagEntityStorage";
|
public override string Name => "BodyBagEntityStorage";
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
[ComponentDependency] private readonly AppearanceComponent? _appearance = null;
|
|
||||||
|
|
||||||
[ViewVariables] public ContainerSlot? LabelContainer { get; private set; }
|
|
||||||
|
|
||||||
protected override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
_appearance?.SetData(BodyBagVisuals.Label, false);
|
|
||||||
LabelContainer = Owner.EnsureContainer<ContainerSlot>("body_bag_label", out _);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool AddToContents(IEntity entity)
|
protected override bool AddToContents(IEntity entity)
|
||||||
{
|
{
|
||||||
if (entity.HasComponent<SharedBodyComponent>() && !EntitySystem.Get<StandingStateSystem>().IsDown(entity.Uid)) return false;
|
if (entity.HasComponent<SharedBodyComponent>() && !EntitySystem.Get<StandingStateSystem>().IsDown(entity.Uid)) return false;
|
||||||
return base.AddToContents(entity);
|
return base.AddToContents(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IExamine.Examine(FormattedMessage message, bool inDetailsRange)
|
|
||||||
{
|
|
||||||
if (inDetailsRange)
|
|
||||||
{
|
|
||||||
if (LabelContainer?.ContainedEntity != null && LabelContainer.ContainedEntity.TryGetComponent<PaperComponent>(out var paper))
|
|
||||||
{
|
|
||||||
message.AddText(Loc.GetString("body-bag-entity-storage-component-on-examine-details", ("paper", paper.Content)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task<bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
if (LabelContainer == null) return false;
|
|
||||||
|
|
||||||
if (LabelContainer.ContainedEntity != null)
|
|
||||||
{
|
|
||||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("body-bag-entity-storage-component-interact-using-already-attached"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var handsComponent = eventArgs.User.GetComponent<HandsComponent>();
|
|
||||||
if (!handsComponent.Drop(eventArgs.Using, LabelContainer))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_appearance?.SetData(BodyBagVisuals.Label, true);
|
|
||||||
|
|
||||||
Owner.PopupMessage(eventArgs.User, Loc.GetString("body-bag-entity-storage-component-interact-using-success",("entity", eventArgs.Using)));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveLabel(IEntity user)
|
|
||||||
{
|
|
||||||
if (LabelContainer == null) return;
|
|
||||||
|
|
||||||
var ent = LabelContainer.ContainedEntity;
|
|
||||||
if(ent is null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (user.TryGetComponent(out HandsComponent? hands))
|
|
||||||
{
|
|
||||||
hands.PutInHandOrDrop(ent.GetComponent<ItemComponent>());
|
|
||||||
_appearance?.SetData(BodyBagVisuals.Label, false);
|
|
||||||
}
|
|
||||||
else if (LabelContainer.Remove(ent))
|
|
||||||
{
|
|
||||||
ent.Transform.Coordinates = Owner.Transform.Coordinates;
|
|
||||||
_appearance?.SetData(BodyBagVisuals.Label, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ namespace Content.Server.Morgue
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<CrematoriumEntityStorageComponent, GetAlternativeVerbsEvent>(AddCremateVerb);
|
SubscribeLocalEvent<CrematoriumEntityStorageComponent, GetAlternativeVerbsEvent>(AddCremateVerb);
|
||||||
SubscribeLocalEvent<BodyBagEntityStorageComponent, GetAlternativeVerbsEvent>(AddRemoveLabelVerb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddCremateVerb(EntityUid uid, CrematoriumEntityStorageComponent component, GetAlternativeVerbsEvent args)
|
private void AddCremateVerb(EntityUid uid, CrematoriumEntityStorageComponent component, GetAlternativeVerbsEvent args)
|
||||||
@@ -32,22 +31,6 @@ namespace Content.Server.Morgue
|
|||||||
args.Verbs.Add(verb);
|
args.Verbs.Add(verb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This adds the "remove label" verb to the list of verbs. Yes, this is a stupid function name, but it's
|
|
||||||
/// consistent with other get-verb event handlers.
|
|
||||||
/// </summary>
|
|
||||||
private void AddRemoveLabelVerb(EntityUid uid, BodyBagEntityStorageComponent component, GetAlternativeVerbsEvent args)
|
|
||||||
{
|
|
||||||
if (args.Hands == null || !args.CanAccess || !args.CanInteract || component.LabelContainer?.ContainedEntity == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Verb verb = new();
|
|
||||||
verb.Text = Loc.GetString("remove-label-verb-get-data-text");
|
|
||||||
// TODO VERB ICON Add cancel/X icon? or maybe just use the pick-up or eject icon?
|
|
||||||
verb.Act = () => component.RemoveLabel(args.User);
|
|
||||||
args.Verbs.Add(verb);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
public override void Update(float frameTime)
|
||||||
{
|
{
|
||||||
_accumulatedFrameTime += frameTime;
|
_accumulatedFrameTime += frameTime;
|
||||||
|
|||||||
@@ -36,6 +36,22 @@ namespace Content.Server.Paper
|
|||||||
_mode = PaperAction.Read;
|
_mode = PaperAction.Read;
|
||||||
UpdateUserInterface();
|
UpdateUserInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetContent(string content)
|
||||||
|
{
|
||||||
|
Content = content + '\n';
|
||||||
|
UpdateUserInterface();
|
||||||
|
|
||||||
|
if (!Owner.TryGetComponent(out AppearanceComponent? appearance))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var status = string.IsNullOrWhiteSpace(content)
|
||||||
|
? PaperStatus.Blank
|
||||||
|
: PaperStatus.Written;
|
||||||
|
|
||||||
|
appearance.SetData(PaperVisuals.Status, status);
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateUserInterface()
|
private void UpdateUserInterface()
|
||||||
{
|
{
|
||||||
UserInterface?.SetState(new PaperBoundUserInterfaceState(Content, _mode));
|
UserInterface?.SetState(new PaperBoundUserInterfaceState(Content, _mode));
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.Cargo
|
namespace Content.Shared.Cargo
|
||||||
@@ -15,6 +15,7 @@ namespace Content.Shared.Cargo
|
|||||||
public int Amount;
|
public int Amount;
|
||||||
public int PayingAccountId;
|
public int PayingAccountId;
|
||||||
public bool Approved;
|
public bool Approved;
|
||||||
|
public string Approver = string.Empty;
|
||||||
|
|
||||||
public CargoOrderData(int orderNumber, string requester, string reason, string productId, int amount, int payingAccountId)
|
public CargoOrderData(int orderNumber, string requester, string reason, string productId, int amount, int payingAccountId)
|
||||||
{
|
{
|
||||||
@@ -24,7 +25,6 @@ namespace Content.Shared.Cargo
|
|||||||
ProductId = productId;
|
ProductId = productId;
|
||||||
Amount = amount;
|
Amount = amount;
|
||||||
PayingAccountId = payingAccountId;
|
PayingAccountId = payingAccountId;
|
||||||
Approved = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using System;
|
|||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.HandLabeler
|
namespace Content.Shared.Labels
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Key representing which <see cref="BoundUserInterface"/> is currently open.
|
/// Key representing which <see cref="BoundUserInterface"/> is currently open.
|
||||||
@@ -14,6 +14,12 @@ namespace Content.Shared.HandLabeler
|
|||||||
Key,
|
Key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public enum PaperLabelVisuals
|
||||||
|
{
|
||||||
|
HasLabel,
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a <see cref="HandLabelerComponent"/> state that can be sent to the client
|
/// Represents a <see cref="HandLabelerComponent"/> state that can be sent to the client
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -17,10 +17,4 @@ namespace Content.Shared.Morgue
|
|||||||
{
|
{
|
||||||
Burning,
|
Burning,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
|
||||||
public enum BodyBagVisuals
|
|
||||||
{
|
|
||||||
Label,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,3 +18,10 @@ cargo-console-menu-populate-categories-all-text = All
|
|||||||
cargo-console-menu-populate-orders-cargo-order-row-product-name-text = {$productName} (x{$orderAmount}) by {$orderRequester}
|
cargo-console-menu-populate-orders-cargo-order-row-product-name-text = {$productName} (x{$orderAmount}) by {$orderRequester}
|
||||||
cargo-console-menu-cargo-order-row-approve-button = Approve
|
cargo-console-menu-cargo-order-row-approve-button = Approve
|
||||||
cargo-console-menu-cargo-order-row-cancel-button = Cancel
|
cargo-console-menu-cargo-order-row-cancel-button = Cancel
|
||||||
|
|
||||||
|
cargo-console-paper-print-name = Order #{$orderNumber}
|
||||||
|
cargo-console-paper-print-text =
|
||||||
|
Order #{$orderNumber}
|
||||||
|
Requested by: {$requester}
|
||||||
|
Reason: {$reason}
|
||||||
|
Approved by: {$approver}
|
||||||
|
|||||||
3
Resources/Locale/en-US/label/paper-label-component.ftl
Normal file
3
Resources/Locale/en-US/label/paper-label-component.ftl
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
comp-paper-label-has-label = There is a label attached, it reads:
|
||||||
|
comp-paper-label-has-label-blank = There is a label attached, but it's blank.
|
||||||
|
comp-paper-label-has-label-cant-read = There is a label attached, but you can't read it from this distance.
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
body-bag-entity-storage-component-on-examine-details = The label reads: {$paper}
|
|
||||||
body-bag-entity-storage-component-interact-using-already-attached = There's already a label attached.
|
|
||||||
body-bag-entity-storage-component-interact-using-success = You attach {$entity} to the body bag.
|
|
||||||
|
|
||||||
# RemoveLabelVerb
|
|
||||||
remove-label-verb-get-data-text = Remove label
|
|
||||||
11
Resources/Prototypes/Catalog/Cargo/cargo_food.yml
Normal file
11
Resources/Prototypes/Catalog/Cargo/cargo_food.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
- type: cargoProduct
|
||||||
|
name: "emergency pizza crate"
|
||||||
|
id: FoodPizza
|
||||||
|
description: Help do your part to end station hunger by distributing pizza to underfunded departments!
|
||||||
|
icon:
|
||||||
|
sprite: Objects/Consumable/Food/Baked/pizza.rsi
|
||||||
|
state: margherita
|
||||||
|
product: CrateFoodPizza
|
||||||
|
cost: 1000
|
||||||
|
category: Food
|
||||||
|
group: market
|
||||||
11
Resources/Prototypes/Catalog/Cargo/cargo_medical.yml
Normal file
11
Resources/Prototypes/Catalog/Cargo/cargo_medical.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
- type: cargoProduct
|
||||||
|
name: "Medical Supplies"
|
||||||
|
id: MedicalSupplies
|
||||||
|
description: Basic medical supplies.
|
||||||
|
icon:
|
||||||
|
sprite: Objects/Specific/Medical/firstaidkits.rsi
|
||||||
|
state: firstaid
|
||||||
|
product: CrateMedicalSupplies
|
||||||
|
cost: 1000
|
||||||
|
category: Mdeical
|
||||||
|
group: market
|
||||||
@@ -33,3 +33,15 @@
|
|||||||
cost: 2000
|
cost: 2000
|
||||||
category: Service
|
category: Service
|
||||||
group: market
|
group: market
|
||||||
|
|
||||||
|
- type: cargoProduct
|
||||||
|
name: "DIY lung cancer crate"
|
||||||
|
id: ServiceCustomSmokable
|
||||||
|
description: "Want to get a little creative with what you use to destroy your lungs? Then this crate is for you! Has everything you need to roll your own Cigarettes."
|
||||||
|
icon:
|
||||||
|
sprite: Objects/Consumable/Smokeables/Cigarettes/Cartons/green.rsi
|
||||||
|
state: closed
|
||||||
|
product: CrateServiceCustomSmokable
|
||||||
|
cost: 1000
|
||||||
|
category: Service
|
||||||
|
group: market
|
||||||
|
|||||||
@@ -1 +1,11 @@
|
|||||||
# Bro what do I PUT here
|
- type: entity
|
||||||
|
id: CrateFoodPizza
|
||||||
|
name: emergency pizza delivery
|
||||||
|
description: Help do your part to end station hunger by distributing pizza to underfunded departments!
|
||||||
|
parent: CratePlastic
|
||||||
|
components:
|
||||||
|
- type: StorageFill
|
||||||
|
contents:
|
||||||
|
- id: FoodBoxPizzaFilled
|
||||||
|
amount: 4
|
||||||
|
- id: KnifePlastic
|
||||||
@@ -56,4 +56,19 @@
|
|||||||
- id: CigarCase
|
- id: CigarCase
|
||||||
orGroup: Cigars
|
orGroup: Cigars
|
||||||
- id: Matchbox
|
- id: Matchbox
|
||||||
amount: 2
|
amount: 2
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: CrateServiceCustomSmokable
|
||||||
|
name: DIY smokeables crate
|
||||||
|
description: Want to get a little creative with what you use to destroy your lungs? Then this crate is for you! Has everything you need to roll your own Cigarettes.
|
||||||
|
parent: CrateGenericonimo
|
||||||
|
components:
|
||||||
|
- type: StorageFill
|
||||||
|
contents:
|
||||||
|
- id: PackPaperRolling
|
||||||
|
- id: CigaretteFilter
|
||||||
|
amount: 8
|
||||||
|
- id: GroundTobacco
|
||||||
|
amount: 4
|
||||||
|
- id: Matchbox
|
||||||
|
|||||||
@@ -32,6 +32,13 @@
|
|||||||
path: /Audio/Misc/zip.ogg
|
path: /Audio/Misc/zip.ogg
|
||||||
openSound:
|
openSound:
|
||||||
path: /Audio/Misc/zip.ogg
|
path: /Audio/Misc/zip.ogg
|
||||||
|
- type: PaperLabel
|
||||||
|
- type: ItemSlots
|
||||||
|
slots:
|
||||||
|
labelSlot:
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Paper
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
visuals:
|
||||||
- type: StorageVisualizer
|
- type: StorageVisualizer
|
||||||
|
|||||||
@@ -226,6 +226,7 @@
|
|||||||
- type: CargoOrderDatabase
|
- type: CargoOrderDatabase
|
||||||
- type: GalacticMarket
|
- type: GalacticMarket
|
||||||
products:
|
products:
|
||||||
|
- MedicalSupplies
|
||||||
- EmergencyExplosive
|
- EmergencyExplosive
|
||||||
- EmergencyFire
|
- EmergencyFire
|
||||||
- EmergencyInternals
|
- EmergencyInternals
|
||||||
@@ -242,8 +243,11 @@
|
|||||||
- HydroponicsSeeds
|
- HydroponicsSeeds
|
||||||
- HydroponicsSeedsExotic
|
- HydroponicsSeedsExotic
|
||||||
- LivestockMonkeyCube
|
- LivestockMonkeyCube
|
||||||
|
- FoodPizza
|
||||||
- ServiceJanitorial
|
- ServiceJanitorial
|
||||||
- ServiceLightsReplacement
|
- ServiceLightsReplacement
|
||||||
|
- ServiceSmokeables
|
||||||
|
- ServiceCustomSmokable
|
||||||
- EngineeringCableLv
|
- EngineeringCableLv
|
||||||
- EngineeringCableMv
|
- EngineeringCableMv
|
||||||
- EngineeringCableHv
|
- EngineeringCableHv
|
||||||
@@ -282,6 +286,8 @@
|
|||||||
radius: 1.5
|
radius: 1.5
|
||||||
energy: 1.6
|
energy: 1.6
|
||||||
color: "#b89f25"
|
color: "#b89f25"
|
||||||
|
- type: AccessReader
|
||||||
|
access: [["Cargo"]]
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: ComputerSupplyRequest
|
id: ComputerSupplyRequest
|
||||||
|
|||||||
@@ -53,3 +53,10 @@
|
|||||||
- type: StorageVisualizer
|
- type: StorageVisualizer
|
||||||
state_open: crate_open
|
state_open: crate_open
|
||||||
state_closed: crate_door
|
state_closed: crate_door
|
||||||
|
- type: PaperLabel
|
||||||
|
- type: ItemSlots
|
||||||
|
slots:
|
||||||
|
labelSlot:
|
||||||
|
whitelist:
|
||||||
|
components:
|
||||||
|
- Paper
|
||||||
|
|||||||
Reference in New Issue
Block a user