Borg hands & hand whitelisting (#38668)

* Borg hands & hand whitelisting

* yaml linted

* yaml linted (x2)

* yaml linted (x3)

* my storage tests so pass

* no need for SetCount

* ok new stuff you can get fixed too

* oops

* staque

* what if we addressed feedback

* my place so holder

* what if we addresesd feedback

* what if i did it correctly

* terminating or deleted
This commit is contained in:
pathetic meowmeow
2025-08-12 18:21:42 -04:00
committed by GitHub
parent 8b76ace136
commit 39cb27fe21
34 changed files with 732 additions and 667 deletions

View File

@@ -28,22 +28,8 @@ namespace Content.Client.Stack
base.SetCount(uid, amount, component); base.SetCount(uid, amount, component);
if (component.Lingering &&
TryComp<SpriteComponent>(uid, out var sprite))
{
// tint the stack gray and make it transparent if it's lingering.
var color = component.Count == 0 && component.Lingering
? Color.DarkGray.WithAlpha(0.65f)
: Color.White;
for (var i = 0; i < sprite.AllLayers.Count(); i++)
{
_sprite.LayerSetColor((uid, sprite), i, color);
}
}
// TODO PREDICT ENTITY DELETION: This should really just be a normal entity deletion call. // TODO PREDICT ENTITY DELETION: This should really just be a normal entity deletion call.
if (component.Count <= 0 && !component.Lingering) if (component.Count <= 0)
{ {
Xform.DetachEntity(uid, Transform(uid)); Xform.DetachEntity(uid, Transform(uid));
return; return;

View File

@@ -1,9 +1,11 @@
using System.Numerics; using System.Numerics;
using Content.Client.Cooldown; using Content.Client.Cooldown;
using Content.Client.UserInterface.Systems.Inventory.Controls; using Content.Client.UserInterface.Systems.Inventory.Controls;
using Robust.Client.GameObjects;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Shared.Input; using Robust.Shared.Input;
using Robust.Shared.Prototypes;
namespace Content.Client.UserInterface.Controls namespace Content.Client.UserInterface.Controls
{ {
@@ -20,6 +22,7 @@ namespace Content.Client.UserInterface.Controls
public CooldownGraphic CooldownDisplay { get; } public CooldownGraphic CooldownDisplay { get; }
private SpriteView SpriteView { get; } private SpriteView SpriteView { get; }
private EntityPrototypeView ProtoView { get; }
public EntityUid? Entity => SpriteView.Entity; public EntityUid? Entity => SpriteView.Entity;
@@ -141,6 +144,13 @@ namespace Content.Client.UserInterface.Controls
SetSize = new Vector2(DefaultButtonSize, DefaultButtonSize), SetSize = new Vector2(DefaultButtonSize, DefaultButtonSize),
OverrideDirection = Direction.South OverrideDirection = Direction.South
}); });
AddChild(ProtoView = new EntityPrototypeView
{
Visible = false,
Scale = new Vector2(2, 2),
SetSize = new Vector2(DefaultButtonSize, DefaultButtonSize),
OverrideDirection = Direction.South
});
AddChild(HoverSpriteView = new SpriteView AddChild(HoverSpriteView = new SpriteView
{ {
@@ -209,12 +219,35 @@ namespace Content.Client.UserInterface.Controls
HoverSpriteView.SetEntity(null); HoverSpriteView.SetEntity(null);
} }
/// <summary>
/// Causes the control to display a placeholder prototype, optionally faded
/// </summary>
public void SetEntity(EntityUid? ent) public void SetEntity(EntityUid? ent)
{ {
SpriteView.SetEntity(ent); SpriteView.SetEntity(ent);
SpriteView.Visible = true;
ProtoView.Visible = false;
UpdateButtonTexture(); UpdateButtonTexture();
} }
/// <summary>
/// Causes the control to display a placeholder prototype, optionally faded
/// </summary>
public void SetPrototype(EntProtoId? proto, bool fade)
{
ProtoView.SetPrototype(proto);
SpriteView.Visible = false;
ProtoView.Visible = true;
UpdateButtonTexture();
if (ProtoView.Entity is not { } ent || !fade)
return;
var sprites = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<SpriteSystem>();
sprites.SetColor((ent.Owner, ent.Comp1), Color.DarkGray.WithAlpha(0.65f));
}
private void UpdateButtonTexture() private void UpdateButtonTexture()
{ {
var fullTexture = Theme.ResolveTextureOrNull(_fullButtonTexturePath); var fullTexture = Theme.ResolveTextureOrNull(_fullButtonTexturePath);

View File

@@ -12,6 +12,7 @@ using Robust.Client.Player;
using Robust.Client.UserInterface; using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controllers;
using Robust.Shared.Input; using Robust.Shared.Input;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -73,7 +74,8 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
{ {
if (entity.Owner != _player.LocalEntity) if (entity.Owner != _player.LocalEntity)
return; return;
AddHand(name, location); if (_handsSystem.TryGetHand((entity.Owner, entity.Comp), name, out var hand))
AddHand(name, hand.Value);
} }
private void OnRemoveHand(Entity<HandsComponent> entity, string name) private void OnRemoveHand(Entity<HandsComponent> entity, string name)
@@ -139,7 +141,7 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
_playerHandsComponent = handsComp; _playerHandsComponent = handsComp;
foreach (var (name, hand) in handsComp.Comp.Hands) foreach (var (name, hand) in handsComp.Comp.Hands)
{ {
var handButton = AddHand(name, hand.Location); var handButton = AddHand(name, hand);
if (_handsSystem.TryGetHeldItem(handsComp.AsNullable(), name, out var held) && if (_handsSystem.TryGetHeldItem(handsComp.AsNullable(), name, out var held) &&
_entities.TryGetComponent(held, out VirtualItemComponent? virt)) _entities.TryGetComponent(held, out VirtualItemComponent? virt))
@@ -147,11 +149,25 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
handButton.SetEntity(virt.BlockingEntity); handButton.SetEntity(virt.BlockingEntity);
handButton.Blocked = true; handButton.Blocked = true;
} }
else else if (held != null)
{ {
handButton.SetEntity(held); handButton.SetEntity(held);
handButton.Blocked = false; handButton.Blocked = false;
} }
else
{
if (hand.EmptyRepresentative is { } representative)
{
// placeholder, view it
SetRepresentative(handButton, representative);
}
else
{
// otherwise empty
handButton.SetEntity(null);
}
handButton.Blocked = false;
}
} }
if (handsComp.Comp.ActiveHandId == null) if (handsComp.Comp.ActiveHandId == null)
@@ -159,6 +175,11 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
SetActiveHand(handsComp.Comp.ActiveHandId); SetActiveHand(handsComp.Comp.ActiveHandId);
} }
private void SetRepresentative(HandButton handButton, EntProtoId prototype)
{
handButton.SetPrototype(prototype, true);
}
private void HandBlocked(string handName) private void HandBlocked(string handName)
{ {
if (!_handLookup.TryGetValue(handName, out var hand)) if (!_handLookup.TryGetValue(handName, out var hand))
@@ -203,7 +224,12 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
hand.Blocked = false; hand.Blocked = false;
} }
UpdateHandStatus(hand, entity); if (_playerHandsComponent != null &&
_player.LocalSession?.AttachedEntity is { } playerEntity &&
_handsSystem.TryGetHand((playerEntity, _playerHandsComponent), name, out var handData))
{
UpdateHandStatus(hand, entity, handData);
}
} }
private void OnItemRemoved(string name, EntityUid entity) private void OnItemRemoved(string name, EntityUid entity)
@@ -212,8 +238,19 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
if (hand == null) if (hand == null)
return; return;
if (_playerHandsComponent != null &&
_player.LocalSession?.AttachedEntity is { } playerEntity &&
_handsSystem.TryGetHand((playerEntity, _playerHandsComponent), name, out var handData))
{
UpdateHandStatus(hand, null, handData);
if (handData?.EmptyRepresentative is { } representative)
{
SetRepresentative(hand, representative);
return;
}
}
hand.SetEntity(null); hand.SetEntity(null);
UpdateHandStatus(hand, null);
} }
private HandsContainer GetFirstAvailableContainer() private HandsContainer GetFirstAvailableContainer()
@@ -276,13 +313,13 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
if (foldedLocation == HandUILocation.Left) if (foldedLocation == HandUILocation.Left)
{ {
_statusHandLeft = handControl; _statusHandLeft = handControl;
HandsGui.UpdatePanelEntityLeft(heldEnt); HandsGui.UpdatePanelEntityLeft(heldEnt, hand.Value);
} }
else else
{ {
// Middle or right // Middle or right
_statusHandRight = handControl; _statusHandRight = handControl;
HandsGui.UpdatePanelEntityRight(heldEnt); HandsGui.UpdatePanelEntityRight(heldEnt, hand.Value);
} }
HandsGui.SetHighlightHand(foldedLocation); HandsGui.SetHighlightHand(foldedLocation);
@@ -295,9 +332,9 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
return handControl; return handControl;
} }
private HandButton AddHand(string handName, HandLocation location) private HandButton AddHand(string handName, Hand hand)
{ {
var button = new HandButton(handName, location); var button = new HandButton(handName, hand.Location);
button.StoragePressed += StorageActivate; button.StoragePressed += StorageActivate;
button.Pressed += HandPressed; button.Pressed += HandPressed;
@@ -313,10 +350,16 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
GetFirstAvailableContainer().AddButton(button); GetFirstAvailableContainer().AddButton(button);
} }
if (hand.EmptyRepresentative is { } representative)
{
SetRepresentative(button, representative);
}
UpdateHandStatus(button, null, hand);
// If we don't have a status for this hand type yet, set it. // If we don't have a status for this hand type yet, set it.
// This means we have status filled by default in most scenarios, // This means we have status filled by default in most scenarios,
// otherwise the user'd need to switch hands to "activate" the hands the first time. // otherwise the user'd need to switch hands to "activate" the hands the first time.
if (location.GetUILocation() == HandUILocation.Left) if (hand.Location.GetUILocation() == HandUILocation.Left)
_statusHandLeft ??= button; _statusHandLeft ??= button;
else else
_statusHandRight ??= button; _statusHandRight ??= button;
@@ -480,12 +523,12 @@ public sealed class HandsUIController : UIController, IOnStateEntered<GameplaySt
} }
} }
private void UpdateHandStatus(HandButton hand, EntityUid? entity) private void UpdateHandStatus(HandButton hand, EntityUid? entity, Hand? handData)
{ {
if (hand == _statusHandLeft) if (hand == _statusHandLeft)
HandsGui?.UpdatePanelEntityLeft(entity); HandsGui?.UpdatePanelEntityLeft(entity, handData);
if (hand == _statusHandRight) if (hand == _statusHandRight)
HandsGui?.UpdatePanelEntityRight(entity); HandsGui?.UpdatePanelEntityRight(entity, handData);
} }
} }

View File

@@ -19,14 +19,14 @@ public sealed partial class HotbarGui : UIWidget
LayoutContainer.SetGrowVertical(this, LayoutContainer.GrowDirection.Begin); LayoutContainer.SetGrowVertical(this, LayoutContainer.GrowDirection.Begin);
} }
public void UpdatePanelEntityLeft(EntityUid? entity) public void UpdatePanelEntityLeft(EntityUid? entity, Hand? hand)
{ {
StatusPanelLeft.Update(entity); StatusPanelLeft.Update(entity, hand);
} }
public void UpdatePanelEntityRight(EntityUid? entity) public void UpdatePanelEntityRight(EntityUid? entity, Hand? hand)
{ {
StatusPanelRight.Update(entity); StatusPanelRight.Update(entity, hand);
} }
public void SetHighlightHand(HandUILocation? hand) public void SetHighlightHand(HandUILocation? hand)

View File

@@ -17,6 +17,7 @@ public sealed partial class ItemStatusPanel : Control
[Dependency] private readonly IEntityManager _entityManager = default!; [Dependency] private readonly IEntityManager _entityManager = default!;
[ViewVariables] private EntityUid? _entity; [ViewVariables] private EntityUid? _entity;
[ViewVariables] private Hand? _hand;
// Tracked so we can re-run SetSide() if the theme changes. // Tracked so we can re-run SetSide() if the theme changes.
private HandUILocation _side; private HandUILocation _side;
@@ -101,29 +102,45 @@ public sealed partial class ItemStatusPanel : Control
protected override void FrameUpdate(FrameEventArgs args) protected override void FrameUpdate(FrameEventArgs args)
{ {
base.FrameUpdate(args); base.FrameUpdate(args);
UpdateItemName(); UpdateItemName(_hand);
} }
public void Update(EntityUid? entity) public void Update(EntityUid? entity, Hand? hand)
{ {
ItemNameLabel.Visible = entity != null; if (entity == _entity && hand == _hand)
NoItemLabel.Visible = entity == null; return;
_hand = hand;
if (entity == null) if (entity == null)
{ {
ItemNameLabel.Text = "";
ClearOldStatus(); ClearOldStatus();
_entity = null; _entity = null;
if (hand?.EmptyLabel is { } label)
{
ItemNameLabel.Visible = true;
NoItemLabel.Visible = false;
ItemNameLabel.Text = Loc.GetString(label);
}
else
{
ItemNameLabel.Visible = false;
NoItemLabel.Visible = true;
ItemNameLabel.Text = "";
}
return; return;
} }
if (entity != _entity) ItemNameLabel.Visible = true;
{ NoItemLabel.Visible = false;
_entity = entity.Value;
BuildNewEntityStatus();
UpdateItemName(); _entity = entity.Value;
} BuildNewEntityStatus();
UpdateItemName(hand);
} }
public void UpdateHighlight(bool highlight) public void UpdateHighlight(bool highlight)
@@ -131,14 +148,14 @@ public sealed partial class ItemStatusPanel : Control
HighlightPanel.Visible = highlight; HighlightPanel.Visible = highlight;
} }
private void UpdateItemName() private void UpdateItemName(Hand? hand)
{ {
if (_entity == null) if (_entity == null)
return; return;
if (!_entityManager.TryGetComponent<MetaDataComponent>(_entity, out var meta) || meta.Deleted) if (!_entityManager.TryGetComponent<MetaDataComponent>(_entity, out var meta) || meta.Deleted)
{ {
Update(null); Update(null, hand);
return; return;
} }

View File

@@ -276,8 +276,8 @@ namespace Content.Server.Construction
if(!insertStep.EntityValid(insert, EntityManager, Factory)) if(!insertStep.EntityValid(insert, EntityManager, Factory))
return HandleResult.False; return HandleResult.False;
// Unremovable items can't be inserted, unless they are a lingering stack // Unremovable items can't be inserted
if(HasComp<UnremoveableComponent>(insert) && (!TryComp<StackComponent>(insert, out var comp) || !comp.Lingering)) if(HasComp<UnremoveableComponent>(insert))
return HandleResult.False; return HandleResult.False;
// If we're only testing whether this step would be handled by the given event, then we're done. // If we're only testing whether this step would be handled by the given event, then we're done.

View File

@@ -52,7 +52,7 @@ public sealed partial class BorgSystem
private void OnProvideItemStartup(EntityUid uid, ItemBorgModuleComponent component, ComponentStartup args) private void OnProvideItemStartup(EntityUid uid, ItemBorgModuleComponent component, ComponentStartup args)
{ {
component.ProvidedContainer = Container.EnsureContainer<Container>(uid, component.ProvidedContainerId); Container.EnsureContainer<Container>(uid, component.HoldingContainer);
} }
private void OnSelectableInstalled(EntityUid uid, SelectableBorgModuleComponent component, ref BorgModuleInstalledEvent args) private void OnSelectableInstalled(EntityUid uid, SelectableBorgModuleComponent component, ref BorgModuleInstalledEvent args)
@@ -187,43 +187,43 @@ public sealed partial class BorgSystem
if (!TryComp<HandsComponent>(chassis, out var hands)) if (!TryComp<HandsComponent>(chassis, out var hands))
return; return;
var xform = Transform(chassis); if (!_container.TryGetContainer(uid, component.HoldingContainer, out var container))
foreach (var itemProto in component.Items) return;
{
EntityUid item;
if (!component.ItemsCreated) var xform = Transform(chassis);
for (var i = 0; i < component.Hands.Count; i++)
{
var hand = component.Hands[i];
var handId = $"{uid}-hand-{i}";
_hands.AddHand((chassis, hands), handId, hand.Hand);
EntityUid? item = null;
if (component.StoredItems is not null)
{
if (component.StoredItems.TryGetValue(handId, out var storedItem))
{
item = storedItem;
_container.Remove(storedItem, container, force: true);
}
}
else if (hand.Item is { } itemProto)
{ {
item = Spawn(itemProto, xform.Coordinates); item = Spawn(itemProto, xform.Coordinates);
} }
else
if (item is { } pickUp)
{ {
item = component.ProvidedContainer.ContainedEntities _hands.DoPickup(chassis, handId, pickUp, hands);
.FirstOrDefault(ent => Prototype(ent)?.ID == itemProto.Id); if (!hand.ForceRemovable && hand.Hand.Whitelist == null && hand.Hand.Blacklist == null)
if (!item.IsValid())
{ {
Log.Debug($"no items found: {component.ProvidedContainer.ContainedEntities.Count}"); EnsureComp<UnremoveableComponent>(pickUp);
continue;
} }
_container.Remove(item, component.ProvidedContainer, force: true);
} }
if (!item.IsValid())
{
Log.Debug("no valid item");
continue;
}
var handId = $"{uid}-item{component.HandCounter}";
component.HandCounter++;
_hands.AddHand((chassis, hands), handId, HandLocation.Middle);
_hands.DoPickup(chassis, handId, item, hands);
EnsureComp<UnremoveableComponent>(item);
component.ProvidedItems.Add(handId, item);
} }
component.ItemsCreated = true; Dirty(uid, component);
} }
private void RemoveProvidedItems(EntityUid chassis, EntityUid uid, BorgChassisComponent? chassisComponent = null, ItemBorgModuleComponent? component = null) private void RemoveProvidedItems(EntityUid chassis, EntityUid uid, BorgChassisComponent? chassisComponent = null, ItemBorgModuleComponent? component = null)
@@ -234,27 +234,33 @@ public sealed partial class BorgSystem
if (!TryComp<HandsComponent>(chassis, out var hands)) if (!TryComp<HandsComponent>(chassis, out var hands))
return; return;
if (TerminatingOrDeleted(uid)) if (!_container.TryGetContainer(uid, component.HoldingContainer, out var container))
{
foreach (var (hand, item) in component.ProvidedItems)
{
QueueDel(item);
_hands.RemoveHand(chassis, hand);
}
component.ProvidedItems.Clear();
return; return;
}
foreach (var (handId, item) in component.ProvidedItems) if (TerminatingOrDeleted(uid))
return;
component.StoredItems ??= new();
for (var i = 0; i < component.Hands.Count; i++)
{ {
if (LifeStage(item) <= EntityLifeStage.MapInitialized) var handId = $"{uid}-hand-{i}";
if (_hands.TryGetHeldItem(chassis, handId, out var held))
{ {
RemComp<UnremoveableComponent>(item); RemComp<UnremoveableComponent>(held.Value);
_container.Insert(item, component.ProvidedContainer); _container.Insert(held.Value, container);
component.StoredItems[handId] = held.Value;
} }
else
{
component.StoredItems.Remove(handId);
}
_hands.RemoveHand(chassis, handId); _hands.RemoveHand(chassis, handId);
} }
component.ProvidedItems.Clear();
Dirty(uid, component);
} }
/// <summary> /// <summary>
@@ -286,8 +292,8 @@ public sealed partial class BorgSystem
if (!TryComp<ItemBorgModuleComponent>(containedModuleUid, out var containedItemModuleComp)) if (!TryComp<ItemBorgModuleComponent>(containedModuleUid, out var containedItemModuleComp))
continue; continue;
if (containedItemModuleComp.Items.Count == itemModuleComp.Items.Count && if (containedItemModuleComp.Hands.Count == itemModuleComp.Hands.Count &&
containedItemModuleComp.Items.All(itemModuleComp.Items.Contains)) containedItemModuleComp.Hands.All(itemModuleComp.Hands.Contains))
{ {
if (user != null) if (user != null)
Popup.PopupEntity(Loc.GetString("borg-module-duplicate"), uid, user.Value); Popup.PopupEntity(Loc.GetString("borg-module-duplicate"), uid, user.Value);

View File

@@ -33,7 +33,7 @@ namespace Content.Server.Stack
base.SetCount(uid, amount, component); base.SetCount(uid, amount, component);
// Queue delete stack if count reaches zero. // Queue delete stack if count reaches zero.
if (component.Count <= 0 && !component.Lingering) if (component.Count <= 0)
QueueDel(uid); QueueDel(uid);
} }

View File

@@ -33,6 +33,12 @@ public sealed partial class MachineBoardComponent : Component
public EntProtoId Prototype; public EntProtoId Prototype;
} }
/// <summary>
/// Marker component for any item that's machine board-like without necessarily being a MachineBoardComponent
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class CircuitboardComponent : Component;
[DataDefinition, Serializable] [DataDefinition, Serializable]
public partial struct GenericPartInfo public partial struct GenericPartInfo
{ {

View File

@@ -1,6 +1,8 @@
using Content.Shared.DisplacementMap; using Content.Shared.DisplacementMap;
using Content.Shared.Hands.EntitySystems; using Content.Shared.Hands.EntitySystems;
using Content.Shared.Whitelist;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
namespace Content.Shared.Hands.Components; namespace Content.Shared.Hands.Components;
@@ -106,16 +108,45 @@ public sealed partial class HandsComponent : Component
public partial record struct Hand public partial record struct Hand
{ {
[DataField] [DataField]
public HandLocation Location = HandLocation.Right; public HandLocation Location = HandLocation.Middle;
/// <summary>
/// The label to be displayed for this hand when it does not contain an entity
/// </summary>
[DataField]
public LocId? EmptyLabel;
/// <summary>
/// The prototype ID of a "representative" entity prototype for what this hand could hold, used in the UI.
/// It is not map-initted.
/// </summary>
[DataField]
public EntProtoId? EmptyRepresentative;
/// <summary>
/// What this hand is allowed to hold
/// </summary>
[DataField]
public EntityWhitelist? Whitelist;
/// <summary>
/// What this hand is not allowed to hold
/// </summary>
[DataField]
public EntityWhitelist? Blacklist;
public Hand() public Hand()
{ {
} }
public Hand(HandLocation location) public Hand(HandLocation location, LocId? emptyLabel = null, EntProtoId? emptyRepresentative = null, EntityWhitelist? whitelist = null, EntityWhitelist? blacklist = null)
{ {
Location = location; Location = location;
EmptyLabel = emptyLabel;
EmptyRepresentative = emptyRepresentative;
Whitelist = whitelist;
Blacklist = blacklist;
} }
} }

View File

@@ -185,6 +185,9 @@ public abstract partial class SharedHandsSystem
if (checkActionBlocker && !_actionBlocker.CanPickup(uid, entity)) if (checkActionBlocker && !_actionBlocker.CanPickup(uid, entity))
return false; return false;
if (!CheckWhitelists((uid, handsComp), handId, entity))
return false;
if (ContainerSystem.TryGetContainingContainer((entity, null, null), out var container)) if (ContainerSystem.TryGetContainingContainer((entity, null, null), out var container))
{ {
if (!ContainerSystem.CanRemove(entity, container)) if (!ContainerSystem.CanRemove(entity, container))

View File

@@ -0,0 +1,15 @@
using Content.Shared.Hands.Components;
using Content.Shared.Whitelist;
namespace Content.Shared.Hands.EntitySystems;
public abstract partial class SharedHandsSystem
{
private bool CheckWhitelists(Entity<HandsComponent?> ent, string handId, EntityUid toTest)
{
if (!TryGetHand(ent, handId, out var hand))
return false;
return _entityWhitelist.CheckBoth(toTest, hand.Value.Blacklist, hand.Value.Whitelist);
}
}

View File

@@ -7,8 +7,10 @@ using Content.Shared.Interaction;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Inventory.VirtualItem; using Content.Shared.Inventory.VirtualItem;
using Content.Shared.Storage.EntitySystems; using Content.Shared.Storage.EntitySystems;
using Content.Shared.Whitelist;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Input.Binding; using Robust.Shared.Input.Binding;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Shared.Hands.EntitySystems; namespace Content.Shared.Hands.EntitySystems;
@@ -23,6 +25,7 @@ public abstract partial class SharedHandsSystem
[Dependency] private readonly SharedStorageSystem _storage = default!; [Dependency] private readonly SharedStorageSystem _storage = default!;
[Dependency] protected readonly SharedTransformSystem TransformSystem = default!; [Dependency] protected readonly SharedTransformSystem TransformSystem = default!;
[Dependency] private readonly SharedVirtualItemSystem _virtualSystem = default!; [Dependency] private readonly SharedVirtualItemSystem _virtualSystem = default!;
[Dependency] private readonly EntityWhitelistSystem _entityWhitelist = default!;
public event Action<Entity<HandsComponent>, string, HandLocation>? OnPlayerAddHand; public event Action<Entity<HandsComponent>, string, HandLocation>? OnPlayerAddHand;
public event Action<Entity<HandsComponent>, string>? OnPlayerRemoveHand; public event Action<Entity<HandsComponent>, string>? OnPlayerRemoveHand;
@@ -66,9 +69,9 @@ public abstract partial class SharedHandsSystem
/// <summary> /// <summary>
/// Adds a hand with the given container id and supplied location to the specified entity. /// Adds a hand with the given container id and supplied location to the specified entity.
/// </summary> /// </summary>
public void AddHand(Entity<HandsComponent?> ent, string handName, HandLocation handLocation) public void AddHand(Entity<HandsComponent?> ent, string handName, HandLocation handLocation, LocId? emptyLabel = null, EntProtoId? emptyRepresentative = null, EntityWhitelist? whitelist = null, EntityWhitelist? blacklist = null)
{ {
AddHand(ent, handName, new Hand(handLocation)); AddHand(ent, handName, new Hand(handLocation, emptyLabel, emptyRepresentative, whitelist, blacklist));
} }
/// <summary> /// <summary>

View File

@@ -1,6 +1,8 @@
using Robust.Shared.Containers; using Content.Shared.Hands.Components;
using Robust.Shared.Containers;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Silicons.Borgs.Components; namespace Content.Shared.Silicons.Borgs.Components;
@@ -11,40 +13,40 @@ namespace Content.Shared.Silicons.Borgs.Components;
public sealed partial class ItemBorgModuleComponent : Component public sealed partial class ItemBorgModuleComponent : Component
{ {
/// <summary> /// <summary>
/// The items that are provided. /// The hands that are provided.
/// </summary> /// </summary>
[DataField(required: true)] [DataField(required: true)]
public List<EntProtoId> Items = new(); public List<BorgHand> Hands = new();
/// <summary> /// <summary>
/// The entities from <see cref="Items"/> that were spawned. /// The items stored within the hands. Null until the first time items are stored.
/// </summary> /// </summary>
[DataField("providedItems")] [DataField]
public SortedDictionary<string, EntityUid> ProvidedItems = new(); public Dictionary<string, EntityUid>? StoredItems;
/// <summary> /// <summary>
/// A counter that ensures a unique /// An ID for the container where items are stored when not in use.
/// </summary> /// </summary>
[DataField("handCounter")] [DataField]
public int HandCounter; public string HoldingContainer = "holding_container";
/// <summary>
/// Whether or not the items have been created and stored in <see cref="ProvidedContainer"/>
/// </summary>
[DataField("itemsCrated")]
public bool ItemsCreated;
/// <summary>
/// A container where provided items are stored when not being used.
/// This is helpful as it means that items retain state.
/// </summary>
[ViewVariables]
public Container ProvidedContainer = default!;
/// <summary>
/// An ID for the container where provided items are stored when not used.
/// </summary>
[DataField("providedContainerId")]
public string ProvidedContainerId = "provided_container";
} }
[DataDefinition, Serializable, NetSerializable]
public partial record struct BorgHand
{
[DataField]
public EntProtoId? Item;
[DataField]
public Hand Hand = new();
[DataField]
public bool ForceRemovable = false;
public BorgHand(EntProtoId? item, Hand hand, bool forceRemovable = false)
{
Item = item;
Hand = hand;
ForceRemovable = forceRemovable;
}
}

View File

@@ -352,10 +352,6 @@ namespace Content.Shared.Stacks
private void OnStackStarted(EntityUid uid, StackComponent component, ComponentStartup args) private void OnStackStarted(EntityUid uid, StackComponent component, ComponentStartup args)
{ {
// on client, lingering stacks that start at 0 need to be darkened
// on server this does nothing
SetCount(uid, component.Count, component);
if (!TryComp(uid, out AppearanceComponent? appearance)) if (!TryComp(uid, out AppearanceComponent? appearance))
return; return;
@@ -366,7 +362,7 @@ namespace Content.Shared.Stacks
private void OnStackGetState(EntityUid uid, StackComponent component, ref ComponentGetState args) private void OnStackGetState(EntityUid uid, StackComponent component, ref ComponentGetState args)
{ {
args.State = new StackComponentState(component.Count, component.MaxCountOverride, component.Lingering); args.State = new StackComponentState(component.Count, component.MaxCountOverride);
} }
private void OnStackHandleState(EntityUid uid, StackComponent component, ref ComponentHandleState args) private void OnStackHandleState(EntityUid uid, StackComponent component, ref ComponentHandleState args)
@@ -375,7 +371,6 @@ namespace Content.Shared.Stacks
return; return;
component.MaxCountOverride = cast.MaxCount; component.MaxCountOverride = cast.MaxCount;
component.Lingering = cast.Lingering;
// This will change the count and call events. // This will change the count and call events.
SetCount(uid, cast.Count, component); SetCount(uid, cast.Count, component);
} }
@@ -428,7 +423,7 @@ namespace Content.Shared.Stacks
return; return;
// We haven't eaten the whole stack yet or are unable to eat it completely. // We haven't eaten the whole stack yet or are unable to eat it completely.
if (eaten.Comp.Count > 0 || eaten.Comp.Lingering) if (eaten.Comp.Count > 0)
{ {
args.Refresh = true; args.Refresh = true;
return; return;

View File

@@ -34,13 +34,6 @@ namespace Content.Shared.Stacks
[ViewVariables(VVAccess.ReadOnly)] [ViewVariables(VVAccess.ReadOnly)]
public bool Unlimited { get; set; } public bool Unlimited { get; set; }
/// <summary>
/// Lingering stacks will remain present even when there are no items.
/// Instead, they will become transparent.
/// </summary>
[DataField("lingering"), ViewVariables(VVAccess.ReadWrite)]
public bool Lingering;
[DataField("throwIndividually"), ViewVariables(VVAccess.ReadWrite)] [DataField("throwIndividually"), ViewVariables(VVAccess.ReadWrite)]
public bool ThrowIndividually { get; set; } = false; public bool ThrowIndividually { get; set; } = false;
@@ -93,13 +86,10 @@ namespace Content.Shared.Stacks
public int Count { get; } public int Count { get; }
public int? MaxCount { get; } public int? MaxCount { get; }
public bool Lingering; public StackComponentState(int count, int? maxCount)
public StackComponentState(int count, int? maxCount, bool lingering)
{ {
Count = count; Count = count;
MaxCount = maxCount; MaxCount = maxCount;
Lingering = lingering;
} }
} }

View File

@@ -0,0 +1,12 @@
borg-slot-cables-empty = Cables
borg-slot-construction-empty = Construction materials
borg-slot-circuitboards-empty = Circuitboards
borg-slot-flatpacks-empty = Flatpacks
borg-slot-tiles-empty = Floor tiles
borg-slot-topicals-empty = Topicals
borg-slot-small-containers-empty = Small containers
borg-slot-chemical-containers-empty = Chemical containers
borg-slot-documents-empty = Books and papers
borg-slot-soap-empty = Soap
borg-slot-instruments-empty = Instruments
borg-slot-beakers-empty = Beakers

View File

@@ -18,4 +18,5 @@
Glass: 230 Glass: 230
chemicalComposition: chemicalComposition:
Silicon: 20 Silicon: 20
- type: Circuitboard

View File

@@ -17,6 +17,7 @@
Glass: 230 Glass: 230
chemicalComposition: chemicalComposition:
Silicon: 20 Silicon: 20
- type: Circuitboard
- type: entity - type: entity
parent: BaseComputerCircuitboard parent: BaseComputerCircuitboard

View File

@@ -17,3 +17,4 @@
Glass: 200 Glass: 200
chemicalComposition: chemicalComposition:
Silicon: 20 Silicon: 20
- type: Circuitboard

View File

@@ -15,6 +15,7 @@
- type: Tag - type: Tag
tags: tags:
- Sheet - Sheet
- ConstructionMaterial
- type: Material - type: Material
- type: Damageable - type: Damageable
damageContainer: Inorganic damageContainer: Inorganic
@@ -108,15 +109,6 @@
stackType: Glass stackType: Glass
count: 1 count: 1
- type: entity
parent: SheetGlass
id: SheetGlassLingering0
suffix: Lingering, 0
components:
- type: Stack
lingering: true
count: 0
- type: entity - type: entity
parent: SheetGlassBase parent: SheetGlassBase
id: SheetRGlass id: SheetRGlass
@@ -197,15 +189,6 @@
Quantity: 0.5 Quantity: 0.5
canReact: false canReact: false
- type: entity
parent: SheetRGlass
id: SheetRGlassLingering0
suffix: Lingering, 0
components:
- type: Stack
lingering: true
count: 0
- type: entity - type: entity
parent: SheetGlassBase parent: SheetGlassBase
id: SheetPGlass id: SheetPGlass
@@ -336,15 +319,6 @@
stackType: ReinforcedPlasmaGlass stackType: ReinforcedPlasmaGlass
count: 1 count: 1
- type: entity
parent: SheetRPGlass
id: SheetRPGlassLingering0
suffix: Lingering, 0
components:
- type: Stack
lingering: true
count: 0
- type: entity - type: entity
parent: SheetGlassBase parent: SheetGlassBase
id: SheetUGlass id: SheetUGlass

View File

@@ -15,6 +15,7 @@
tags: tags:
- Sheet - Sheet
- Metal - Metal
- ConstructionMaterial
- type: Damageable - type: Damageable
damageContainer: Inorganic damageContainer: Inorganic
damageModifierSet: Metallic damageModifierSet: Metallic
@@ -94,15 +95,6 @@
stackType: Steel stackType: Steel
count: 1 count: 1
- type: entity
parent: SheetSteel
id: SheetSteelLingering0
suffix: Lingering, 0
components:
- type: Stack
lingering: true
count: 0
- type: entity - type: entity
parent: SheetMetalBase parent: SheetMetalBase
id: SheetBrass id: SheetBrass
@@ -229,12 +221,3 @@
- type: Stack - type: Stack
stackType: Plasteel stackType: Plasteel
count: 1 count: 1
- type: entity
parent: SheetPlasteel
id: SheetPlasteelLingering0
suffix: Lingering, 0
components:
- type: Stack
lingering: true
count: 0

View File

@@ -12,6 +12,7 @@
- type: Tag - type: Tag
tags: tags:
- Sheet - Sheet
- ConstructionMaterial
- type: Damageable - type: Damageable
damageContainer: Inorganic damageContainer: Inorganic
- type: Destructible - type: Destructible
@@ -110,6 +111,7 @@
- type: Tag - type: Tag
tags: tags:
- Sheet - Sheet
- ConstructionMaterial
- type: entity - type: entity
parent: SheetPlasma parent: SheetPlasma
@@ -132,16 +134,6 @@
- type: Stack - type: Stack
count: 1 count: 1
- type: entity
parent: SheetPlasma
id: SheetPlasmaLingering0
name: plasma
suffix: 0, Lingering
components:
- type: Stack
lingering: true
count: 0
- type: entity - type: entity
parent: SheetOtherBase parent: SheetOtherBase
id: SheetPlastic id: SheetPlastic
@@ -152,6 +144,7 @@
tags: tags:
- Plastic - Plastic
- Sheet - Sheet
- ConstructionMaterial
- type: Material - type: Material
- type: PhysicalComposition - type: PhysicalComposition
materialComposition: materialComposition:

View File

@@ -14,6 +14,7 @@
- type: Tag - type: Tag
tags: tags:
- Ingot - Ingot
- ConstructionMaterial
- type: Damageable - type: Damageable
damageContainer: Inorganic damageContainer: Inorganic
damageModifierSet: Metallic damageModifierSet: Metallic

View File

@@ -147,6 +147,7 @@
- ClothMade - ClothMade
- Gauze - Gauze
- RawMaterial - RawMaterial
- ConstructionMaterial
- type: Construction - type: Construction
graph: WebObjects # not sure if I should either keep this here or just make another prototype. Will keep it here just in case. graph: WebObjects # not sure if I should either keep this here or just make another prototype. Will keep it here just in case.
node: cloth node: cloth
@@ -212,6 +213,7 @@
tags: tags:
- ClothMade - ClothMade
- RawMaterial - RawMaterial
- ConstructionMaterial
- type: Item - type: Item
heldPrefix: durathread heldPrefix: durathread
@@ -261,6 +263,7 @@
tags: tags:
- Wooden - Wooden
- RawMaterial - RawMaterial
- ConstructionMaterial
- type: Extractable - type: Extractable
grindableSolutionName: wood grindableSolutionName: wood
- type: SolutionContainerManager - type: SolutionContainerManager

View File

@@ -19,6 +19,9 @@
behaviors: behaviors:
- !type:DoActsBehavior - !type:DoActsBehavior
acts: [ "Destruction" ] acts: [ "Destruction" ]
- type: Tag
tags:
- ConstructionMaterial
- type: entity - type: entity
parent: PartBase parent: PartBase
@@ -81,6 +84,7 @@
- type: Tag - type: Tag
tags: tags:
- RodMetal1 - RodMetal1
- ConstructionMaterial
- type: Sprite - type: Sprite
state: rods state: rods
- type: Stack - type: Stack
@@ -95,43 +99,8 @@
- type: Tag - type: Tag
tags: tags:
- RodMetal1 - RodMetal1
- ConstructionMaterial
- type: Sprite - type: Sprite
state: rods state: rods
- type: Stack - type: Stack
count: 1 count: 1
- type: entity
parent: PartRodMetal
id: PartRodMetalLingering0
suffix: Lingering, 0
components:
- type: Stack
lingering: true
count: 0
- type: entity
parent: FloorTileItemSteel
id: FloorTileItemSteelLingering0
suffix: Lingering, 0
components:
- type: Stack
lingering: true
count: 0
- type: entity
parent: FloorTileItemWhite
id: FloorTileItemWhiteLingering0
suffix: Lingering, 0
components:
- type: Stack
lingering: true
count: 0
- type: entity
parent: FloorTileItemDark
id: FloorTileItemDarkLingering0
suffix: Lingering, 0
components:
- type: Stack
lingering: true
count: 0

View File

@@ -11,6 +11,9 @@
size: Tiny size: Tiny
- type: Stack - type: Stack
count: 1 count: 1
- type: Tag
tags:
- ConstructionMaterial
- type: entity - type: entity
id: MicroManipulatorStockPart id: MicroManipulatorStockPart

View File

@@ -239,25 +239,3 @@
- type: Residue - type: Residue
residueAdjective: residue-slippery residueAdjective: residue-slippery
residueColor: residue-blue residueColor: residue-blue
- type: entity
name: soap
id: SoapBorg # Intended for borg internals, not slippery or food, not a container for soap reagent
parent: BaseItem
description: A Nanotrasen brand bar of soap. Smells of plasma and machines.
components:
- type: Sprite
sprite: Objects/Specific/Janitorial/soap.rsi
layers:
- state: nt-4
- type: Appearance
- type: Item
sprite: Objects/Specific/Janitorial/soap.rsi
storedRotation: -90
- type: CleansForensics
- type: Residue
residueAdjective: residue-slippery
residueColor: residue-grey
- type: Tag
tags:
- Soap

View File

@@ -61,15 +61,6 @@
stackType: Ointment stackType: Ointment
count: 1 count: 1
- type: entity
id: Ointment10Lingering
parent: Ointment
suffix: 10, Lingering
components:
- type: Stack
lingering: true
count: 10
- type: entity - type: entity
name: regenerative mesh name: regenerative mesh
description: Used to treat even the nastiest burns. Also effective against caustic burns. description: Used to treat even the nastiest burns. Also effective against caustic burns.
@@ -118,15 +109,6 @@
stackType: RegenerativeMesh stackType: RegenerativeMesh
count: 1 count: 1
- type: entity
parent: RegenerativeMesh
id: RegenerativeMeshLingering0
suffix: 0, Lingering
components:
- type: Stack
lingering: true
count: 0
- type: entity - type: entity
name: bruise pack name: bruise pack
description: A therapeutic gel pack and bandages designed to treat blunt-force trauma. description: A therapeutic gel pack and bandages designed to treat blunt-force trauma.
@@ -172,15 +154,6 @@
stackType: Brutepack stackType: Brutepack
count: 1 count: 1
- type: entity
id: Brutepack10Lingering
parent: Brutepack
suffix: 10, Lingering
components:
- type: Stack
lingering: true
count: 10
- type: entity - type: entity
name: medicated suture name: medicated suture
description: A suture soaked in medicine, treats blunt-force trauma effectively and closes wounds. description: A suture soaked in medicine, treats blunt-force trauma effectively and closes wounds.
@@ -228,15 +201,6 @@
stackType: MedicatedSuture stackType: MedicatedSuture
count: 1 count: 1
- type: entity
parent: MedicatedSuture
id: MedicatedSutureLingering0
suffix: 0, Lingering
components:
- type: Stack
lingering: true
count: 0
- type: entity - type: entity
name: blood pack name: blood pack
description: Contains a groundbreaking universal blood replacement created by Nanotrasen's advanced medical science. description: Contains a groundbreaking universal blood replacement created by Nanotrasen's advanced medical science.
@@ -283,15 +247,6 @@
stackType: Bloodpack stackType: Bloodpack
count: 1 count: 1
- type: entity
parent: Bloodpack
id: Bloodpack10Lingering
suffix: 10, Lingering
components:
- type: Stack
lingering: true
count: 10
- type: entity - type: entity
parent: BaseHealingItem parent: BaseHealingItem
id: Tourniquet id: Tourniquet
@@ -375,15 +330,6 @@
- type: Stack - type: Stack
count: 1 count: 1
- type: entity
id: Gauze10Lingering
parent: Gauze
suffix: 10, Lingering
components:
- type: Stack
lingering: true
count: 10
- type: entity - type: entity
name: aloe cream name: aloe cream
description: A topical cream for burns. description: A topical cream for burns.

View File

@@ -46,7 +46,7 @@
- type: SelectableBorgModule - type: SelectableBorgModule
- type: ContainerContainer - type: ContainerContainer
containers: containers:
provided_container: !type:Container { } holding_container: !type:Container { }
- type: entity - type: entity
parent: BaseAction parent: BaseAction
@@ -422,13 +422,31 @@
- state: generic - state: generic
- state: icon-cables - state: icon-cables
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- CableApcStackLingering10 - item: CableApcStack10
- CableMVStackLingering10 hand:
- CableHVStackLingering10 emptyRepresentative: CableApcStack10
- Wirecutter emptyLabel: borg-slot-cables-empty
- Crowbar whitelist:
- trayScanner tags:
- CableCoil
- item: CableMVStack10
hand:
emptyRepresentative: CableMVStack10
emptyLabel: borg-slot-cables-empty
whitelist:
tags:
- CableCoil
- item: CableHVStack10
hand:
emptyRepresentative: CableHVStack10
emptyLabel: borg-slot-cables-empty
whitelist:
tags:
- CableCoil
- item: Wirecutter
- item: Crowbar
- item: trayScanner
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: wire-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: wire-module }
@@ -443,11 +461,11 @@
- state: generic - state: generic
- state: icon-fire-extinguisher - state: icon-fire-extinguisher
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- BorgFireExtinguisher - item: BorgFireExtinguisher
- BorgHandheldGPSBasic - item: BorgHandheldGPSBasic
- HandheldStationMapUnpowered - item: HandheldStationMapUnpowered
- HandHeldMassScannerBorg - item: HandHeldMassScannerBorg
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: extinguisher-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: extinguisher-module }
@@ -461,13 +479,13 @@
- state: generic - state: generic
- state: icon-tools - state: icon-tools
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- Crowbar - item: Crowbar
- Wrench - item: Wrench
- Screwdriver - item: Screwdriver
- Wirecutter - item: Wirecutter
- WelderIndustrial - item: WelderIndustrial
- Multitool - item: Multitool
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: tool-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: tool-module }
@@ -482,13 +500,13 @@
- state: cargo - state: cargo
- state: icon-appraisal - state: icon-appraisal
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- AppraisalTool - item: AppraisalTool
- Pen - item: Pen
- HandLabeler - item: HandLabeler
- RubberStampApproved - item: RubberStampApproved
- RubberStampDenied - item: RubberStampDenied
- RadioHandheld - item: RadioHandheld
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: appraisal-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: appraisal-module }
@@ -502,11 +520,11 @@
- state: cargo - state: cargo
- state: icon-mining - state: icon-mining
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- MiningDrill - item: MiningDrill
- Shovel - item: Shovel
- MineralScannerUnpowered - item: MineralScannerUnpowered
- BorgOreBag - item: BorgOreBag
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: mining-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: mining-module }
@@ -521,11 +539,11 @@
- state: cargo - state: cargo
- state: icon-mining-adv - state: icon-mining-adv
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- MiningDrillDiamond - item: MiningDrillDiamond
- Shovel - item: Shovel
- AdvancedMineralScannerUnpowered - item: AdvancedMineralScannerUnpowered
- OreBagOfHolding - item: OreBagOfHolding
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-mining-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-mining-module }
@@ -539,11 +557,11 @@
- state: cargo - state: cargo
- state: icon-grappling-gun - state: icon-grappling-gun
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- WeaponGrapplingGun - item: WeaponGrapplingGun
- BorgFireExtinguisher - item: BorgFireExtinguisher
- BorgHandheldGPSBasic - item: BorgHandheldGPSBasic
- HandHeldMassScannerBorg - item: HandHeldMassScannerBorg
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: grappling-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: grappling-module }
@@ -559,15 +577,23 @@
- state: engineering - state: engineering
- state: icon-tools-adv - state: icon-tools-adv
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- JawsOfLife - item: JawsOfLife
- PowerDrill - item: PowerDrill
- WelderExperimental - item: WelderExperimental
- Multitool - item: Multitool
- RemoteSignallerAdvanced - item: RemoteSignallerAdvanced
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-tools-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-tools-module }
- type: entity
id: BorgModuleConstructionMaterialPlaceholder
parent: BaseItem
components:
- type: Sprite
sprite: Objects/Materials/Sheets/other.rsi
state: generic_materials
- type: entity - type: entity
id: BorgModuleConstruction id: BorgModuleConstruction
parent: [ BaseBorgModuleEngineering, BaseProviderBorgModule ] parent: [ BaseBorgModuleEngineering, BaseProviderBorgModule ]
@@ -578,16 +604,61 @@
- state: engineering - state: engineering
- state: icon-construction - state: icon-construction
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- SheetSteelLingering0 - hand:
- SheetGlassLingering0 emptyRepresentative: BorgModuleConstructionMaterialPlaceholder
- SheetRGlassLingering0 emptyLabel: borg-slot-construction-empty
- SheetRPGlassLingering0 whitelist:
- SheetPlasteelLingering0 tags:
- PartRodMetalLingering0 - ConstructionMaterial
- FloorTileItemSteelLingering0 - hand:
- FloorTileItemWhiteLingering0 emptyRepresentative: BorgModuleConstructionMaterialPlaceholder
- FloorTileItemDarkLingering0 emptyLabel: borg-slot-construction-empty
whitelist:
tags:
- ConstructionMaterial
- hand:
emptyRepresentative: BorgModuleConstructionMaterialPlaceholder
emptyLabel: borg-slot-construction-empty
whitelist:
tags:
- ConstructionMaterial
- hand:
emptyRepresentative: DoorElectronics
emptyLabel: borg-slot-circuitboards-empty
whitelist:
components:
- Circuitboard
- hand:
emptyRepresentative: MicroManipulatorStockPart
emptyLabel: borg-slot-construction-empty
whitelist:
tags:
- ConstructionMaterial
- hand:
emptyRepresentative: SpaceHeaterFlatpack
emptyLabel: borg-slot-flatpacks-empty
whitelist:
components:
- Flatpack
- hand:
emptyRepresentative: FloorTileItemSteel
emptyLabel: borg-slot-tiles-empty
whitelist:
components:
- FloorTile
- hand:
emptyRepresentative: FloorTileItemWhite
emptyLabel: borg-slot-tiles-empty
whitelist:
components:
- FloorTile
- hand:
emptyRepresentative: FloorTileItemDark
emptyLabel: borg-slot-tiles-empty
whitelist:
components:
- FloorTile
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: construction-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: construction-module }
@@ -601,13 +672,13 @@
- state: engineering - state: engineering
- state: icon-rcd - state: icon-rcd
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- RCDRecharging - item: RCDRecharging
- BorgFireExtinguisher - item: BorgFireExtinguisher
- BorgHandheldGPSBasic - item: BorgHandheldGPSBasic
- GasAnalyzer - item: GasAnalyzer
- HolofanProjectorBorg - item: HolofanProjectorBorg
- GeigerCounter - item: GeigerCounter
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: rcd-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: rcd-module }
@@ -622,11 +693,17 @@
- state: janitor - state: janitor
- state: icon-light-replacer - state: icon-light-replacer
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- LightReplacer - item: LightReplacer
- BorgTrashBag - item: BorgTrashBag
- Plunger - item: Plunger
- SoapBorg - item: SoapNT
hand:
emptyLabel: borg-slot-soap-empty
emptyRepresentative: SoapNT
whitelist:
tags:
- Soap
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: light-replacer-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: light-replacer-module }
@@ -640,11 +717,11 @@
- state: janitor - state: janitor
- state: icon-mop - state: icon-mop
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- MopItem - item: MopItem
- BorgBucket - item: BorgBucket
- BorgSprayBottle - item: BorgSprayBottle
- HoloprojectorBorg - item: HoloprojectorBorg
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: cleaning-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: cleaning-module }
@@ -659,12 +736,18 @@
- state: janitor - state: janitor
- state: icon-mop-adv - state: icon-mop-adv
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- AdvMopItem - item: AdvMopItem
- BorgMegaSprayBottle - item: BorgMegaSprayBottle
- HoloprojectorBorg - item: HoloprojectorBorg
- BorgDropper - item: BorgDropper
- BorgBeaker - item: Beaker
hand:
emptyLabel: borg-slot-beakers-empty
emptyRepresentative: Beaker
whitelist:
tags:
- GlassBeaker
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-cleaning-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-cleaning-module }
@@ -679,9 +762,9 @@
- state: medical - state: medical
- state: icon-diagnosis - state: icon-diagnosis
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- HandheldHealthAnalyzerUnpowered - item: HandheldHealthAnalyzerUnpowered
- ClothingNeckStethoscope - item: ClothingNeckStethoscope
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: diagnosis-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: diagnosis-module }
@@ -695,14 +778,36 @@
- state: medical - state: medical
- state: icon-treatment - state: icon-treatment
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- HandheldHealthAnalyzerUnpowered - item: HandheldHealthAnalyzerUnpowered
- Gauze10Lingering - item: Gauze
- Brutepack10Lingering hand:
- Ointment10Lingering emptyLabel: borg-slot-topicals-empty
- Bloodpack10Lingering emptyRepresentative: Gauze
- RegenerativeMeshLingering0 whitelist:
- MedicatedSutureLingering0 components:
- Healing
- item: Brutepack
hand:
emptyLabel: borg-slot-topicals-empty
emptyRepresentative: Brutepack
whitelist:
components:
- Healing
- item: Ointment
hand:
emptyLabel: borg-slot-topicals-empty
emptyRepresentative: Ointment
whitelist:
components:
- Healing
- item: Bloodpack
hand:
emptyLabel: borg-slot-topicals-empty
emptyRepresentative: Bloodpack
whitelist:
components:
- Healing
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: treatment-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: treatment-module }
@@ -716,12 +821,12 @@
- state: medical - state: medical
- state: icon-defib - state: icon-defib
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- HandheldHealthAnalyzerUnpowered - item: HandheldHealthAnalyzerUnpowered
- DefibrillatorOneHandedUnpowered - item: DefibrillatorOneHandedUnpowered
- BorgFireExtinguisher - item: BorgFireExtinguisher
- BorgHandheldGPSBasic - item: BorgHandheldGPSBasic
- HandLabeler - item: HandLabeler
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: defib-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: defib-module }
@@ -735,13 +840,31 @@
- state: medical - state: medical
- state: icon-chem - state: icon-chem
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- HandheldHealthAnalyzerUnpowered - item: HandheldHealthAnalyzerUnpowered
- Syringe - item: Syringe
- BorgDropper - item: BorgDropper
- BorgVial - item: BaseChemistryEmptyVial
- BorgVial hand:
- BorgVial emptyLabel: borg-slot-small-containers-empty
emptyRepresentative: BaseChemistryEmptyVial
whitelist:
components:
- FitsInDispenser
- item: BaseChemistryEmptyVial
hand:
emptyLabel: borg-slot-small-containers-empty
emptyRepresentative: BaseChemistryEmptyVial
whitelist:
components:
- FitsInDispenser
- item: BaseChemistryEmptyVial
hand:
emptyLabel: borg-slot-small-containers-empty
emptyRepresentative: BaseChemistryEmptyVial
whitelist:
components:
- FitsInDispenser
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: chem-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: chem-module }
@@ -756,13 +879,38 @@
- state: medical - state: medical
- state: icon-chemist - state: icon-chemist
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- HandheldHealthAnalyzerUnpowered - item: HandheldHealthAnalyzerUnpowered
- BorgHypo - item: BorgHypo
- Syringe - item: Syringe
- BorgDropper - item: BorgDropper
- BorgBeaker - item: Beaker
- BorgBeaker hand:
emptyLabel: borg-slot-chemical-containers-empty
emptyRepresentative: Beaker
whitelist:
components:
- FitsInDispenser
tags:
- ChemDispensable
- item: Beaker
hand:
emptyLabel: borg-slot-chemical-containers-empty
emptyRepresentative: Beaker
whitelist:
components:
- FitsInDispenser
tags:
- ChemDispensable
- item: Beaker
hand:
emptyLabel: borg-slot-chemical-containers-empty
emptyRepresentative: Beaker
whitelist:
components:
- FitsInDispenser
tags:
- ChemDispensable
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-chem-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-chem-module }
@@ -778,13 +926,19 @@
- state: science - state: science
- state: icon-artifacts - state: icon-artifacts
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- NodeScanner - item: NodeScanner
- SprayBottle - item: SprayBottle
- GasAnalyzer - item: GasAnalyzer
- BorgDropper - item: BorgDropper
- BorgVial - item: BaseChemistryEmptyVial
- GeigerCounter hand:
emptyLabel: borg-slot-small-containers-empty
emptyRepresentative: BaseChemistryEmptyVial
whitelist:
components:
- FitsInDispenser
- item: GeigerCounter
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: node-scanner-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: node-scanner-module }
@@ -798,13 +952,23 @@
- state: science - state: science
- state: icon-anomalies - state: icon-anomalies
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- AnomalyScanner - item: AnomalyScanner
- AnomalyLocatorUnpowered - item: AnomalyLocatorUnpowered
- AnomalyLocatorWideUnpowered - item: AnomalyLocatorWideUnpowered
- HandLabeler - item: HandLabeler
- SheetRGlassLingering0 - hand:
- SheetRPGlassLingering0 emptyRepresentative: SheetRGlass
emptyLabel: borg-slot-construction-empty
whitelist:
tags:
- ConstructionMaterial
- hand:
emptyRepresentative: SheetRPGlass
emptyLabel: borg-slot-construction-empty
whitelist:
tags:
- ConstructionMaterial
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: anomaly-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: anomaly-module }
@@ -819,14 +983,43 @@
- state: service - state: service
- state: icon-pen - state: icon-pen
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- Pen - item: Pen
#- BooksBag (Add back when hand whitelisting exists, at the moment they can only use it like an orebag.) - item: BooksBag
- HandLabeler - hand:
- RubberStampApproved emptyLabel: borg-slot-documents-empty
- RubberStampDenied emptyRepresentative: BookBase
- BorgDropper whitelist:
- BorgVial tags:
- Book
- Dice
- Document
- Figurine
- TabletopBoard
- Write
- hand:
emptyLabel: borg-slot-documents-empty
emptyRepresentative: Paper
whitelist:
tags:
- Book
- Dice
- Document
- Figurine
- TabletopBoard
- Write
- item: HandLabeler
- item: RubberStampApproved
- item: RubberStampDenied
- item: BorgDropper
- item: DrinkShaker
hand:
emptyLabel: borg-slot-small-containers-empty
emptyRepresentative: DrinkShaker
whitelist:
components:
- FitsInDispenser
- item: BarSpoon
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: service-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: service-module }
@@ -840,10 +1033,28 @@
- state: service - state: service
- state: icon-musique - state: icon-musique
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- SynthesizerInstrument - item: SynthesizerInstrument
- ElectricGuitarInstrument hand:
- SaxophoneInstrument emptyLabel: borg-slot-instruments-empty
emptyRepresentative: SynthesizerInstrument
whitelist:
components:
- Instrument
- item: ElectricGuitarInstrument
hand:
emptyLabel: borg-slot-instruments-empty
emptyRepresentative: ElectricGuitarInstrument
whitelist:
components:
- Instrument
- item: SaxophoneInstrument
hand:
emptyLabel: borg-slot-instruments-empty
emptyRepresentative: SaxophoneInstrument
whitelist:
components:
- Instrument
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: musical-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: musical-module }
@@ -857,11 +1068,11 @@
- state: service - state: service
- state: icon-gardening - state: icon-gardening
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- HydroponicsToolMiniHoe - item: HydroponicsToolMiniHoe
- HydroponicsToolSpade - item: HydroponicsToolSpade
- HydroponicsToolClippers - item: HydroponicsToolClippers
- Bucket - item: Bucket
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: gardening-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: gardening-module }
@@ -875,10 +1086,10 @@
- state: service - state: service
- state: icon-harvesting - state: icon-harvesting
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- HydroponicsToolScythe - item: HydroponicsToolScythe
- HydroponicsToolHatchet - item: HydroponicsToolHatchet
- PlantBag - item: PlantBag
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: harvesting-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: harvesting-module }
@@ -892,10 +1103,10 @@
- state: service - state: service
- state: icon-clown - state: icon-clown
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- BikeHorn - item: BikeHorn
- ClownRecorder - item: ClownRecorder
- BikeHornInstrument - item: BikeHornInstrument
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: clowning-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: clowning-module }
@@ -910,12 +1121,12 @@
- state: service - state: service
- state: icon-clown-adv - state: icon-clown-adv
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- HoloprojectorClownBorg - item: HoloprojectorClownBorg
- BorgLauncherCreamPie - item: BorgLauncherCreamPie
- ClownRecorder - item: ClownRecorder
- PushHorn - item: PushHorn
- BikeHornInstrument - item: BikeHornInstrument
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-clowning-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: adv-clowning-module }
@@ -930,9 +1141,9 @@
- state: syndicate - state: syndicate
- state: icon-syndicate - state: icon-syndicate
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- WeaponPistolEchis - item: WeaponPistolEchis
- EnergyDaggerLoud - item: EnergyDaggerLoud
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-weapon-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-weapon-module }
- type: Item - type: Item
@@ -967,11 +1178,11 @@
- state: syndicate - state: syndicate
- state: icon-syndicate - state: icon-syndicate
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- Crowbar - item: Crowbar
- Emag - item: Emag
- AccessBreaker - item: AccessBreaker
- PinpointerSyndicateNuclear - item: PinpointerSyndicateNuclear
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-operative-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-operative-module }
@@ -986,9 +1197,9 @@
- state: syndicate - state: syndicate
- state: icon-syndicate - state: icon-syndicate
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- CyborgEnergySwordDouble - item: CyborgEnergySwordDouble
- PinpointerSyndicateNuclear - item: PinpointerSyndicateNuclear
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-esword-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-esword-module }
@@ -1003,9 +1214,9 @@
- state: syndicate - state: syndicate
- state: icon-syndicate - state: icon-syndicate
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- WeaponLightMachineGunL6C - item: WeaponLightMachineGunL6C
- PinpointerSyndicateNuclear - item: PinpointerSyndicateNuclear
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-l6c-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-l6c-module }
@@ -1020,8 +1231,8 @@
- state: syndicateborgbomb - state: syndicateborgbomb
- state: icon-bomb - state: icon-bomb
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- SelfDestructSeq - item: SelfDestructSeq
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-martyr-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: syndicate-martyr-module }
- type: Item - type: Item
@@ -1057,10 +1268,10 @@
- state: xenoborg_generic - state: xenoborg_generic
- state: icon-xenoborg-basic - state: icon-xenoborg-basic
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- MaterialBag - item: MaterialBag
- PinpointerMothership - item: PinpointerMothership
- HandheldGPSBasic - item: HandheldGPSBasic
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-basic-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-basic-module }
@@ -1075,13 +1286,13 @@
- state: xenoborg_generic - state: xenoborg_generic
- state: icon-xenoborg-tools - state: icon-xenoborg-tools
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- Crowbar - item: Crowbar
- Wrench - item: Wrench
- Screwdriver - item: Screwdriver
- Wirecutter - item: Wirecutter
- Multitool - item: Multitool
- RefuelingWelder - item: RefuelingWelder
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-tool-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-tool-module }
@@ -1096,8 +1307,8 @@
- state: xenoborg_engi - state: xenoborg_engi
- state: icon-xenoborg-access-breaker - state: icon-xenoborg-access-breaker
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- AccessBreaker - item: AccessBreaker
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-access-breaker-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-access-breaker-module }
@@ -1112,8 +1323,8 @@
- state: xenoborg_engi - state: xenoborg_engi
- state: icon-xenoborg-fire-extinguisher - state: icon-xenoborg-fire-extinguisher
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- SelfRechargingFireExtinguisher - item: SelfRechargingFireExtinguisher
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-extinguisher-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-extinguisher-module }
@@ -1128,8 +1339,8 @@
- state: xenoborg_heavy - state: xenoborg_heavy
- state: icon-xenoborg-jammer - state: icon-xenoborg-jammer
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- XenoborgRadioJammer - item: XenoborgRadioJammer
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-jammer-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-jammer-module }
@@ -1144,8 +1355,8 @@
- state: xenoborg_heavy - state: xenoborg_heavy
- state: icon-xenoborg-laser - state: icon-xenoborg-laser
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- XenoborgLaserGun - item: XenoborgLaserGun
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-laser-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-laser-module }
@@ -1160,8 +1371,8 @@
- state: xenoborg_heavy - state: xenoborg_heavy
- state: icon-xenoborg-laser2 - state: icon-xenoborg-laser2
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- XenoborgHeavyLaserGun - item: XenoborgHeavyLaserGun
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-laser2-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-laser2-module }
@@ -1176,12 +1387,12 @@
- state: xenoborg_scout - state: xenoborg_scout
- state: icon-xenoborg-space-movement - state: icon-xenoborg-space-movement
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- HandheldGPSBasic - item: HandheldGPSBasic
- HandHeldMassScannerBorg - item: HandHeldMassScannerBorg
- HandheldStationMapUnpowered - item: HandheldStationMapUnpowered
- WeaponGrapplingGun - item: WeaponGrapplingGun
- JetpackXenoborg - item: JetpackXenoborg
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-space-movement-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-space-movement-module }
@@ -1196,9 +1407,9 @@
- state: xenoborg_scout - state: xenoborg_scout
- state: icon-xenoborg-sword - state: icon-xenoborg-sword
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- KukriKnife - item: KukriKnife
- JetpackXenoborg - item: JetpackXenoborg
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-sword-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-sword-module }
@@ -1213,9 +1424,9 @@
- state: xenoborg_scout - state: xenoborg_scout
- state: icon-xenoborg-sword2 - state: icon-xenoborg-sword2
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- EnergyDaggerLoudBlue - item: EnergyDaggerLoudBlue
- JetpackXenoborg - item: JetpackXenoborg
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-sword2-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-sword2-module }
@@ -1230,8 +1441,8 @@
- state: xenoborg_stealth - state: xenoborg_stealth
- state: icon-xenoborg-hypo - state: icon-xenoborg-hypo
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- NocturineHypo - item: NocturineHypo
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-hypo-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-hypo-module }
@@ -1246,8 +1457,8 @@
- state: xenoborg_stealth - state: xenoborg_stealth
- state: icon-xenoborg-projector - state: icon-xenoborg-projector
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- ChameleonProjector - item: ChameleonProjector
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-projector-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-projector-module }
@@ -1262,8 +1473,8 @@
- state: xenoborg_stealth - state: xenoborg_stealth
- state: icon-xenoborg-cloak - state: icon-xenoborg-cloak
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- CloakingDevice - item: CloakingDevice
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-eye-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-eye-module }
@@ -1278,7 +1489,7 @@
- state: xenoborg_stealth - state: xenoborg_stealth
- state: icon-xenoborg-cloak2 - state: icon-xenoborg-cloak2
- type: ItemBorgModule - type: ItemBorgModule
items: hands:
- SuperCloakingDevice - item: SuperCloakingDevice
- type: BorgModuleIcon - type: BorgModuleIcon
icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-eye2-module } icon: { sprite: Interface/Actions/actions_borg.rsi, state: xenoborg-eye2-module }

View File

@@ -104,64 +104,6 @@
solution: beaker solution: beaker
- type: DnaSubstanceTrace - type: DnaSubstanceTrace
- type: entity
parent: BaseItem
id: BorgVial
name: integrated vial
description: An internal compartment installed into a cyborg. Rated for 30 units of any liquid.
components:
# All this shit is here to avoid inheriting breakable, since borgs can't replace broken vials.
- type: Sprite
sprite: Objects/Specific/Chemistry/vial.rsi
layers:
- state: vial-1
- state: vial-1-1
map: ["enum.SolutionContainerLayers.Fill"]
visible: false
- type: Appearance
- type: SolutionContainerVisuals
maxFillLevels: 6
fillBaseName: vial-1-
inHandsMaxFillLevels: 4
inHandsFillBaseName: -fill-
- type: Drink
solution: beaker
- type: SolutionContainerManager
solutions:
beaker:
maxVol: 30
- type: MixableSolution
solution: beaker
- type: RefillableSolution
solution: beaker
- type: DrainableSolution
solution: beaker
- type: ExaminableSolution
solution: beaker
exactVolume: true
- type: DrawableSolution
solution: beaker
- type: SolutionTransfer
maxTransferAmount: 30
canChangeTransferAmount: true
- type: SolutionItemStatus
solution: beaker
- type: UserInterface
interfaces:
enum.TransferAmountUiKey.Key:
type: TransferAmountBoundUserInterface
- type: Item
size: Tiny
sprite: Objects/Specific/Chemistry/vial.rsi
shape:
- 0,0,0,0
- type: MeleeWeapon
soundNoDamage:
path: "/Audio/Effects/Fluids/splat.ogg"
damage:
types:
Blunt: 0
- type: entity - type: entity
id: VestineChemistryVial id: VestineChemistryVial
parent: BaseChemistryEmptyVial parent: BaseChemistryEmptyVial

View File

@@ -95,65 +95,6 @@
price: 30 price: 30
- type: DnaSubstanceTrace - type: DnaSubstanceTrace
- type: entity
parent: BaseItem
id: BorgBeaker
name: integrated beaker
description: An internal compartment installed into a cyborg. Rated for 50 units of any liquid.
components:
# 3 morbillion components are to avoid inheriting breakable since borgs can't replace beakers.
- type: Tag
tags:
- GlassBeaker
- type: Sprite
sprite: Objects/Specific/Chemistry/beaker.rsi
layers:
- state: beaker
- state: beaker1
map: ["enum.SolutionContainerLayers.Fill"]
visible: false
- type: Item
sprite: Objects/Specific/Chemistry/beaker.rsi
- type: MeleeWeapon
soundNoDamage:
path: "/Audio/Effects/Fluids/splat.ogg"
damage:
types:
Blunt: 0
- type: SolutionContainerManager
solutions:
beaker:
maxVol: 50
- type: MixableSolution
solution: beaker
- type: FitsInDispenser
solution: beaker
- type: RefillableSolution
solution: beaker
- type: DrainableSolution
solution: beaker
- type: ExaminableSolution
solution: beaker
exactVolume: true
- type: DrawableSolution
solution: beaker
- type: InjectableSolution
solution: beaker
- type: SolutionTransfer
canChangeTransferAmount: true
- type: SolutionItemStatus
solution: beaker
- type: UserInterface
interfaces:
enum.TransferAmountUiKey.Key:
type: TransferAmountBoundUserInterface
- type: Drink
solution: beaker
- type: Appearance
- type: SolutionContainerVisuals
maxFillLevels: 6
fillBaseName: beaker
- type: entity - type: entity
parent: BaseItem parent: BaseItem
id: BaseBeakerMetallic id: BaseBeakerMetallic

View File

@@ -82,15 +82,6 @@
- type: Stack - type: Stack
count: 10 count: 10
- type: entity
parent: CableHVStack10
id: CableHVStackLingering10
suffix: Lingering, 10
components:
- type: Stack
lingering: true
count: 10
- type: entity - type: entity
parent: CableHVStack parent: CableHVStack
id: CableHVStack1 id: CableHVStack1
@@ -147,15 +138,6 @@
- type: Stack - type: Stack
count: 10 count: 10
- type: entity
parent: CableMVStack10
id: CableMVStackLingering10
suffix: Lingering, 10
components:
- type: Stack
lingering: true
count: 10
- type: entity - type: entity
parent: CableMVStack parent: CableMVStack
id: CableMVStack1 id: CableMVStack1
@@ -211,15 +193,6 @@
- type: Stack - type: Stack
count: 10 count: 10
- type: entity
parent: CableApcStack10
id: CableApcStackLingering10
suffix: Lingering, 10
components:
- type: Stack
lingering: true
count: 10
- type: entity - type: entity
parent: CableApcStack parent: CableApcStack
id: CableApcStack1 id: CableApcStack1

View File

@@ -347,6 +347,9 @@
- type: Tag - type: Tag
id: ComputerTelevisionCircuitboard id: ComputerTelevisionCircuitboard
- type: Tag
id: ConstructionMaterial
- type: Tag - type: Tag
id: ConveyorAssembly id: ConveyorAssembly