base.Draw(handle);
// really just an "oh shit" catch.
- if (!_entityManager.EntityExists(Entity))
+ if (!_entityManager.EntityExists(Entity) || !_entityManager.TryGetComponent<ItemComponent>(Entity, out var itemComponent))
{
Dispose();
return;
if (_storageController.IsDragging && _storageController.CurrentlyDragging == this)
return;
- var adjustedShape = _entityManager.System<ItemSystem>().GetAdjustedItemShape((Entity, null), Location.Rotation, Vector2i.Zero);
+ var adjustedShape = _entityManager.System<ItemSystem>().GetAdjustedItemShape((Entity, itemComponent), Location.Rotation, Vector2i.Zero);
var boundingGrid = adjustedShape.GetBoundingBox();
var size = _centerTexture!.Size * 2 * UIScale;
}
// typically you'd divide by two, but since the textures are half a tile, this is done implicitly
- var iconOffset = new Vector2((boundingGrid.Width + 1) * size.X ,
+ var iconPosition = new Vector2((boundingGrid.Width + 1) * size.X ,
(boundingGrid.Height + 1) * size.Y);
+ var iconRotation = Location.Rotation + Angle.FromDegrees(itemComponent.StoredRotation);
- _entityManager.System<SpriteSystem>().ForceUpdate(Entity);
- handle.DrawEntity(Entity,
- PixelPosition + iconOffset,
- Vector2.One * 2 * UIScale,
- Angle.Zero,
- overrideDirection: Direction.South);
+ if (itemComponent.StoredSprite is { } storageSprite)
+ {
+ var scale = 2 * UIScale;
+ var offset = (((Box2) boundingGrid).Size - Vector2.One) * size;
+ var sprite = _entityManager.System<SpriteSystem>().Frame0(storageSprite);
+
+ var spriteBox = new Box2Rotated(new Box2(0f, sprite.Height * scale, sprite.Width * scale, 0f), -iconRotation, Vector2.Zero);
+ var root = spriteBox.CalcBoundingBox().BottomLeft;
+ var pos = PixelPosition * 2
+ + (Parent?.GlobalPixelPosition ?? Vector2.Zero)
+ + offset;
+
+ handle.SetTransform(pos, iconRotation);
+ var box = new UIBox2(root, root + sprite.Size * scale);
+ handle.DrawTextureRect(sprite, box);
+ handle.SetTransform(Matrix3.Identity);
+ }
+ else
+ {
+ _entityManager.System<SpriteSystem>().ForceUpdate(Entity);
+ handle.DrawEntity(Entity,
+ PixelPosition + iconPosition,
+ Vector2.One * 2 * UIScale,
+ Angle.Zero,
+ eyeRotation: iconRotation,
+ overrideDirection: Direction.South);
+ }
}
protected override bool HasPoint(Vector2 point)
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
+using Robust.Shared.Utility;
namespace Content.Shared.Item;
/// </summary>
[DataField, AutoNetworkedField]
public List<Box2i>? Shape;
+
+ /// <summary>
+ /// A sprite used to depict this entity specifically when it is displayed in the storage UI.
+ /// </summary>
+ [DataField, AutoNetworkedField]
+ public SpriteSpecifier? StoredSprite;
+
+ /// <summary>
+ /// An additional angle offset, in degrees, applied to the visual depiction of the item when displayed in the storage UI.
+ /// </summary>
+ [DataField, AutoNetworkedField]
+ public float StoredRotation = 0;
}
[Serializable, NetSerializable]
cutters: Rainbow
- type: Item
sprite: Objects/Tools/wirecutters.rsi
+ storedRotation: -90
- type: LatticeCutting
- type: PhysicalComposition
materialComposition:
- state: screwdriver-screwybits
- type: Item
sprite: Objects/Tools/screwdriver.rsi
+ storedRotation: -90
- type: ItemCooldown
- type: MeleeWeapon
wideAnimationRotation: -90
state: icon
- type: Item
sprite: Objects/Tools/wrench.rsi
+ storedSprite:
+ sprite: Objects/Tools/wrench.rsi
+ state: storage
- type: ItemCooldown
- type: MeleeWeapon
wideAnimationRotation: 135
- type: Item
sprite: Objects/Tools/crowbar.rsi
size: Small
+ storedSprite:
+ sprite: Objects/Tools/crowbar.rsi
+ state: storage
- type: ItemCooldown
- type: MeleeWeapon
wideAnimationRotation: -135
state: red-icon
- type: Item
heldPrefix: red
+ storedSprite:
+ sprite: Objects/Tools/crowbar.rsi
+ state: red-storage
- type: entity
name: multitool