Janitor trashbag upgrade + FANCY ANIMATIONS (#3058)
* Janitor trashbag upgrade + FANCY ANIMATIONS * Review, Bug fixes and Sounds - Fixed hand-pickup animation playing if the entity originated from inside a container (e.g. bag on the ground) or from inside ourselves (e.g. something in our own inventory) * Fix/Change. Just log if AnimateEntityPickup is called with an entity that has no SpriteComponent. * More explicit log message. Error log. * Merge. Fix.
56
Content.Client/Animations/ReusableAnimations.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using Robust.Client.Animations;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.GameObjects.Components.Animations;
|
||||||
|
using Robust.Shared.Animations;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Maths;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Content.Client.Animations
|
||||||
|
{
|
||||||
|
public static class ReusableAnimations
|
||||||
|
{
|
||||||
|
|
||||||
|
public static void AnimateEntityPickup(IEntity entity, EntityCoordinates initialPosition, Vector2 finalPosition)
|
||||||
|
{
|
||||||
|
var animatableClone = entity.EntityManager.SpawnEntity("clientsideclone", initialPosition);
|
||||||
|
animatableClone.Name = entity.Name;
|
||||||
|
|
||||||
|
if(!entity.TryGetComponent(out SpriteComponent sprite0))
|
||||||
|
{
|
||||||
|
Logger.Error($"Entity ({0}) couldn't be animated for pickup since it doesn't have a {1}!", entity.Name, nameof(SpriteComponent));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var sprite = animatableClone.GetComponent<SpriteComponent>();
|
||||||
|
sprite.CopyFrom(sprite0);
|
||||||
|
|
||||||
|
var animations = animatableClone.GetComponent<AnimationPlayerComponent>();
|
||||||
|
animations.AnimationCompleted += (s) => {
|
||||||
|
animatableClone.Delete();
|
||||||
|
};
|
||||||
|
|
||||||
|
animations.Play(new Animation
|
||||||
|
{
|
||||||
|
Length = TimeSpan.FromMilliseconds(125),
|
||||||
|
AnimationTracks =
|
||||||
|
{
|
||||||
|
new AnimationTrackComponentProperty
|
||||||
|
{
|
||||||
|
ComponentType = typeof(ITransformComponent),
|
||||||
|
Property = nameof(ITransformComponent.WorldPosition),
|
||||||
|
InterpolationMode = AnimationInterpolationMode.Linear,
|
||||||
|
KeyFrames =
|
||||||
|
{
|
||||||
|
new AnimationTrackComponentProperty.KeyFrame(initialPosition.Position, 0),
|
||||||
|
new AnimationTrackComponentProperty.KeyFrame(finalPosition, 0.125f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "fancy_pickup_anim");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,23 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Client.Animations;
|
||||||
using Content.Client.UserInterface;
|
using Content.Client.UserInterface;
|
||||||
using Content.Shared.GameObjects.Components.Items;
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
|
using Robust.Client.Animations;
|
||||||
using Robust.Client.GameObjects;
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.GameObjects.Components.Animations;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Shared.Animations;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Shared.Interfaces.Network;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
using Robust.Shared.Players;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
|
||||||
namespace Content.Client.GameObjects.Components.Items
|
namespace Content.Client.GameObjects.Components.Items
|
||||||
@@ -244,6 +253,23 @@ namespace Content.Client.GameObjects.Components.Items
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel, ICommonSession? session = null)
|
||||||
|
{
|
||||||
|
base.HandleNetworkMessage(message, netChannel, session);
|
||||||
|
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case AnimatePickupEntityMessage msg:
|
||||||
|
{
|
||||||
|
if (Owner.EntityManager.TryGetEntity(msg.EntityId, out var entity))
|
||||||
|
{
|
||||||
|
ReusableAnimations.AnimateEntityPickup(entity, msg.EntityPosition, Owner.Transform.WorldPosition);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void SendChangeHand(string index)
|
public void SendChangeHand(string index)
|
||||||
{
|
{
|
||||||
SendNetworkMessage(new ClientChangedHandMsg(index));
|
SendNetworkMessage(new ClientChangedHandMsg(index));
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Client.Animations;
|
||||||
using Content.Client.GameObjects.Components.Items;
|
using Content.Client.GameObjects.Components.Items;
|
||||||
using Content.Shared.GameObjects.Components.Storage;
|
using Content.Shared.GameObjects.Components.Storage;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Robust.Client.Animations;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.GameObjects.Components.Animations;
|
||||||
using Robust.Client.Graphics.Drawing;
|
using Robust.Client.Graphics.Drawing;
|
||||||
using Robust.Client.Interfaces.GameObjects.Components;
|
using Robust.Client.Interfaces.GameObjects.Components;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
using Robust.Client.UserInterface;
|
using Robust.Client.UserInterface;
|
||||||
using Robust.Client.UserInterface.Controls;
|
using Robust.Client.UserInterface.Controls;
|
||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
|
using Robust.Shared.Animations;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Shared.Interfaces.Network;
|
using Robust.Shared.Interfaces.Network;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Maths;
|
||||||
@@ -77,6 +83,9 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
case CloseStorageUIMessage _:
|
case CloseStorageUIMessage _:
|
||||||
CloseUI();
|
CloseUI();
|
||||||
break;
|
break;
|
||||||
|
case AnimateInsertingEntitiesMessage msg:
|
||||||
|
HandleAnimatingInsertingEntities(msg);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +101,24 @@ namespace Content.Client.GameObjects.Components.Storage
|
|||||||
Window.BuildEntityList();
|
Window.BuildEntityList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Animate the newly stored entities in <paramref name="msg"/> flying towards this storage's position
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg"></param>
|
||||||
|
private void HandleAnimatingInsertingEntities(AnimateInsertingEntitiesMessage msg)
|
||||||
|
{
|
||||||
|
for (var i = 0; msg.StoredEntities.Count > i; i++)
|
||||||
|
{
|
||||||
|
var entityId = msg.StoredEntities[i];
|
||||||
|
var initialPosition = msg.EntityPositions[i];
|
||||||
|
|
||||||
|
if (Owner.EntityManager.TryGetEntity(entityId, out var entity))
|
||||||
|
{
|
||||||
|
ReusableAnimations.AnimateEntityPickup(entity, initialPosition, Owner.Transform.WorldPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the storage UI if closed. Closes it if opened.
|
/// Opens the storage UI if closed. Closes it if opened.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
@@ -176,9 +176,16 @@ namespace Content.Server.GameObjects.Components.GUI
|
|||||||
|
|
||||||
Dirty();
|
Dirty();
|
||||||
|
|
||||||
|
var position = item.Owner.Transform.Coordinates;
|
||||||
|
var contained = item.Owner.IsInContainer();
|
||||||
var success = hand.Container.Insert(item.Owner);
|
var success = hand.Container.Insert(item.Owner);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
|
//If the entity isn't in a container, and it isn't located exactly at our position (i.e. in our own storage), then we can safely play the animation
|
||||||
|
if (position != Owner.Transform.Coordinates && !contained)
|
||||||
|
{
|
||||||
|
SendNetworkMessage(new AnimatePickupEntityMessage(item.Owner.Uid, position));
|
||||||
|
}
|
||||||
item.Owner.Transform.LocalPosition = Vector2.Zero;
|
item.Owner.Transform.LocalPosition = Vector2.Zero;
|
||||||
OnItemChanged?.Invoke();
|
OnItemChanged?.Invoke();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.Server.GameObjects.Components.GUI;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
|
using Content.Server.GameObjects.EntitySystems.DoAfter;
|
||||||
using Content.Server.Interfaces.GameObjects.Components.Items;
|
using Content.Server.Interfaces.GameObjects.Components.Items;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.GameObjects.Components.Storage;
|
using Content.Shared.GameObjects.Components.Storage;
|
||||||
@@ -24,6 +26,7 @@ using Robust.Shared.GameObjects.Systems;
|
|||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.Network;
|
using Robust.Shared.Interfaces.Network;
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Log;
|
||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
@@ -36,7 +39,7 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
[ComponentReference(typeof(IActivate))]
|
[ComponentReference(typeof(IActivate))]
|
||||||
[ComponentReference(typeof(IStorageComponent))]
|
[ComponentReference(typeof(IStorageComponent))]
|
||||||
public class ServerStorageComponent : SharedStorageComponent, IInteractUsing, IUse, IActivate, IStorageComponent, IDestroyAct, IExAct
|
public class ServerStorageComponent : SharedStorageComponent, IInteractUsing, IUse, IActivate, IStorageComponent, IDestroyAct, IExAct, IAfterInteract
|
||||||
{
|
{
|
||||||
private const string LoggerName = "Storage";
|
private const string LoggerName = "Storage";
|
||||||
|
|
||||||
@@ -44,6 +47,8 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
|||||||
private readonly Dictionary<IEntity, int> _sizeCache = new();
|
private readonly Dictionary<IEntity, int> _sizeCache = new();
|
||||||
|
|
||||||
private bool _occludesLight;
|
private bool _occludesLight;
|
||||||
|
private bool _quickInsert; //Can insert storables by "attacking" them with the storage entity
|
||||||
|
private bool _areaInsert; //"Attacking" with the storage entity causes it to insert all nearby storables after a delay
|
||||||
private bool _storageInitialCalculated;
|
private bool _storageInitialCalculated;
|
||||||
private int _storageUsed;
|
private int _storageUsed;
|
||||||
private int _storageCapacityMax;
|
private int _storageCapacityMax;
|
||||||
@@ -184,7 +189,7 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="player">The player to insert an entity from</param>
|
/// <param name="player">The player to insert an entity from</param>
|
||||||
/// <returns>true if inserted, false otherwise</returns>
|
/// <returns>true if inserted, false otherwise</returns>
|
||||||
public bool PlayerInsertEntity(IEntity player)
|
public bool PlayerInsertHeldEntity(IEntity player)
|
||||||
{
|
{
|
||||||
EnsureInitialCalculated();
|
EnsureInitialCalculated();
|
||||||
|
|
||||||
@@ -212,6 +217,24 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inserts an Entity (<paramref name="toInsert"/>) in the world into storage, informing <paramref name="player"/> if it fails.
|
||||||
|
/// <paramref name="toInsert"/> is *NOT* held, see <see cref="PlayerInsertHeldEntity(IEntity)"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="player">The player to insert an entity with</param>
|
||||||
|
/// <returns>true if inserted, false otherwise</returns>
|
||||||
|
public bool PlayerInsertEntityInWorld(IEntity player, IEntity toInsert)
|
||||||
|
{
|
||||||
|
EnsureInitialCalculated();
|
||||||
|
|
||||||
|
if (!Insert(toInsert))
|
||||||
|
{
|
||||||
|
Owner.PopupMessage(player, "Can't insert.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the storage UI for an entity
|
/// Opens the storage UI for an entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -343,6 +366,8 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
|||||||
|
|
||||||
serializer.DataField(ref _storageCapacityMax, "capacity", 10000);
|
serializer.DataField(ref _storageCapacityMax, "capacity", 10000);
|
||||||
serializer.DataField(ref _occludesLight, "occludesLight", true);
|
serializer.DataField(ref _occludesLight, "occludesLight", true);
|
||||||
|
serializer.DataField(ref _quickInsert, "quickInsert", false);
|
||||||
|
serializer.DataField(ref _areaInsert, "areaInsert", false);
|
||||||
serializer.DataField(this, x => x.StorageSoundCollection, "storageSoundCollection", string.Empty);
|
serializer.DataField(this, x => x.StorageSoundCollection, "storageSoundCollection", string.Empty);
|
||||||
//serializer.DataField(ref StorageUsed, "used", 0);
|
//serializer.DataField(ref StorageUsed, "used", 0);
|
||||||
}
|
}
|
||||||
@@ -418,7 +443,7 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerInsertEntity(player);
|
PlayerInsertHeldEntity(player);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -449,7 +474,7 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PlayerInsertEntity(eventArgs.User);
|
return PlayerInsertHeldEntity(eventArgs.User);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -469,6 +494,97 @@ namespace Content.Server.GameObjects.Components.Items.Storage
|
|||||||
((IUse) this).UseEntity(new UseEntityEventArgs { User = eventArgs.User });
|
((IUse) this).UseEntity(new UseEntityEventArgs { User = eventArgs.User });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allows a user to pick up entities by clicking them, or pick up all entities in a certain radius
|
||||||
|
/// arround a click.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="eventArgs"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
async Task<bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
|
||||||
|
{
|
||||||
|
if (!eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true)) return false;
|
||||||
|
|
||||||
|
// Pick up all entities in a radius around the clicked location.
|
||||||
|
// The last half of the if is because carpets exist and this is terrible
|
||||||
|
if(_areaInsert && (eventArgs.Target == null || !eventArgs.Target.HasComponent<StorableComponent>()))
|
||||||
|
{
|
||||||
|
var validStorables = new List<IEntity>();
|
||||||
|
foreach (var entity in Owner.EntityManager.GetEntitiesInRange(eventArgs.ClickLocation, 1))
|
||||||
|
{
|
||||||
|
if (!entity.Transform.IsMapTransform
|
||||||
|
|| entity == eventArgs.User
|
||||||
|
|| !entity.HasComponent<StorableComponent>())
|
||||||
|
continue;
|
||||||
|
validStorables.Add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
//If there's only one then let's be generous
|
||||||
|
if (validStorables.Count > 1)
|
||||||
|
{
|
||||||
|
var doAfterSystem = EntitySystem.Get<DoAfterSystem>();
|
||||||
|
var doAfterArgs = new DoAfterEventArgs(eventArgs.User, 0.2f * validStorables.Count, CancellationToken.None, Owner)
|
||||||
|
{
|
||||||
|
BreakOnStun = true,
|
||||||
|
BreakOnDamage = true,
|
||||||
|
BreakOnUserMove = true,
|
||||||
|
NeedHand = true,
|
||||||
|
};
|
||||||
|
var result = await doAfterSystem.DoAfter(doAfterArgs);
|
||||||
|
if (result != DoAfterStatus.Finished) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var successfullyInserted = new List<EntityUid>();
|
||||||
|
var successfullyInsertedPositions = new List<EntityCoordinates>();
|
||||||
|
foreach (var entity in validStorables)
|
||||||
|
{
|
||||||
|
// Check again, situation may have changed for some entities, but we'll still pick up any that are valid
|
||||||
|
if (!entity.Transform.IsMapTransform
|
||||||
|
|| entity == eventArgs.User
|
||||||
|
|| !entity.HasComponent<StorableComponent>())
|
||||||
|
continue;
|
||||||
|
var coords = entity.Transform.Coordinates;
|
||||||
|
if (PlayerInsertEntityInWorld(eventArgs.User, entity))
|
||||||
|
{
|
||||||
|
successfullyInserted.Add(entity.Uid);
|
||||||
|
successfullyInsertedPositions.Add(coords);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we picked up atleast one thing, play a sound and do a cool animation!
|
||||||
|
if (successfullyInserted.Count>0)
|
||||||
|
{
|
||||||
|
PlaySoundCollection(StorageSoundCollection);
|
||||||
|
SendNetworkMessage(
|
||||||
|
new AnimateInsertingEntitiesMessage(
|
||||||
|
successfullyInserted,
|
||||||
|
successfullyInsertedPositions
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Pick up the clicked entity
|
||||||
|
else if(_quickInsert)
|
||||||
|
{
|
||||||
|
if (eventArgs.Target == null
|
||||||
|
|| !eventArgs.Target.Transform.IsMapTransform
|
||||||
|
|| eventArgs.Target == eventArgs.User
|
||||||
|
|| !eventArgs.Target.HasComponent<StorableComponent>())
|
||||||
|
return false;
|
||||||
|
var position = eventArgs.Target.Transform.Coordinates;
|
||||||
|
if(PlayerInsertEntityInWorld(eventArgs.User, eventArgs.Target))
|
||||||
|
{
|
||||||
|
SendNetworkMessage(new AnimateInsertingEntitiesMessage(
|
||||||
|
new List<EntityUid>() { eventArgs.Target.Uid },
|
||||||
|
new List<EntityCoordinates>() { position }
|
||||||
|
));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void IDestroyAct.OnDestroy(DestructionEventArgs eventArgs)
|
void IDestroyAct.OnDestroy(DestructionEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
var storedEntities = StoredEntities?.ToList();
|
var storedEntities = StoredEntities?.ToList();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Content.Server.GameObjects.Components.GUI;
|
using Content.Server.GameObjects.Components.GUI;
|
||||||
using Content.Server.GameObjects.Components.Items.Storage;
|
using Content.Server.GameObjects.Components.Items.Storage;
|
||||||
@@ -216,7 +216,7 @@ namespace Content.Server.GameObjects.EntitySystems
|
|||||||
|
|
||||||
if (heldItem != null)
|
if (heldItem != null)
|
||||||
{
|
{
|
||||||
storageComponent.PlayerInsertEntity(plyEnt);
|
storageComponent.PlayerInsertHeldEntity(plyEnt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.GameObjects.Components.Items
|
namespace Content.Shared.GameObjects.Components.Items
|
||||||
@@ -127,4 +128,20 @@ namespace Content.Shared.GameObjects.Components.Items
|
|||||||
Middle,
|
Middle,
|
||||||
Right
|
Right
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Component message for displaying an animation of an entity flying towards the owner of a HandsComponent
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public class AnimatePickupEntityMessage : ComponentMessage
|
||||||
|
{
|
||||||
|
public readonly EntityUid EntityId;
|
||||||
|
public readonly EntityCoordinates EntityPosition;
|
||||||
|
public AnimatePickupEntityMessage(EntityUid entity, EntityCoordinates entityPosition)
|
||||||
|
{
|
||||||
|
Directed = true;
|
||||||
|
EntityId = entity;
|
||||||
|
EntityPosition = entityPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
using Content.Shared.GameObjects.EntitySystems;
|
||||||
using Content.Shared.GameObjects.EntitySystems.ActionBlocker;
|
using Content.Shared.GameObjects.EntitySystems.ActionBlocker;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.GameObjects.Components.Storage
|
namespace Content.Shared.GameObjects.Components.Storage
|
||||||
@@ -100,6 +102,22 @@ namespace Content.Shared.GameObjects.Components.Storage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Component message for displaying an animation of entities flying into a storage entity
|
||||||
|
/// </summary>
|
||||||
|
[Serializable, NetSerializable]
|
||||||
|
public class AnimateInsertingEntitiesMessage : ComponentMessage
|
||||||
|
{
|
||||||
|
public readonly List<EntityUid> StoredEntities;
|
||||||
|
public readonly List<EntityCoordinates> EntityPositions;
|
||||||
|
public AnimateInsertingEntitiesMessage(List<EntityUid> storedEntities, List<EntityCoordinates> entityPositions)
|
||||||
|
{
|
||||||
|
Directed = true;
|
||||||
|
StoredEntities = storedEntities;
|
||||||
|
EntityPositions = entityPositions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Component message for removing a contained entity from the storage entity
|
/// Component message for removing a contained entity from the storage entity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
BIN
Resources/Audio/Effects/trashbag1.ogg
Normal file
BIN
Resources/Audio/Effects/trashbag2.ogg
Normal file
BIN
Resources/Audio/Effects/trashbag3.ogg
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
- type: entity
|
||||||
|
name: clientsideclone
|
||||||
|
id: clientsideclone
|
||||||
|
abstract: true
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
- type: Physics
|
||||||
|
- type: AnimationPlayer
|
||||||
@@ -154,17 +154,6 @@
|
|||||||
sprite: Objects/Consumable/Trash/tastybread.rsi
|
sprite: Objects/Consumable/Trash/tastybread.rsi
|
||||||
|
|
||||||
|
|
||||||
- type: entity
|
|
||||||
name: trash bag
|
|
||||||
parent: TrashBase
|
|
||||||
id: TrashBag
|
|
||||||
components:
|
|
||||||
- type: Sprite
|
|
||||||
sprite: Objects/Consumable/Trash/trashbag.rsi
|
|
||||||
|
|
||||||
- type: Storage
|
|
||||||
capacity: 125
|
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
name: tray (trash)
|
name: tray (trash)
|
||||||
parent: TrashBase
|
parent: TrashBase
|
||||||
|
|||||||
@@ -234,3 +234,18 @@
|
|||||||
reagents:
|
reagents:
|
||||||
- ReagentId: chem.SpaceCleaner
|
- ReagentId: chem.SpaceCleaner
|
||||||
Quantity: 100
|
Quantity: 100
|
||||||
|
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
name: trash bag
|
||||||
|
id: TrashBag
|
||||||
|
parent: BaseItem
|
||||||
|
components:
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Specific/Janitorial/trashbag.rsi
|
||||||
|
state: icon
|
||||||
|
- type: Storage
|
||||||
|
capacity: 125
|
||||||
|
quickInsert: true
|
||||||
|
areaInsert: true
|
||||||
|
storageSoundCollection: trashBagRustle
|
||||||
|
|||||||
@@ -6,3 +6,10 @@
|
|||||||
- /Audio/Effects/rustle3.ogg
|
- /Audio/Effects/rustle3.ogg
|
||||||
- /Audio/Effects/rustle4.ogg
|
- /Audio/Effects/rustle4.ogg
|
||||||
- /Audio/Effects/rustle5.ogg
|
- /Audio/Effects/rustle5.ogg
|
||||||
|
|
||||||
|
- type: soundCollection
|
||||||
|
id: trashBagRustle
|
||||||
|
files:
|
||||||
|
- /Audio/Effects/trashbag1.ogg
|
||||||
|
- /Audio/Effects/trashbag2.ogg
|
||||||
|
- /Audio/Effects/trashbag3.ogg
|
||||||
|
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 385 B |
|
Before Width: | Height: | Size: 453 B After Width: | Height: | Size: 453 B |
|
Before Width: | Height: | Size: 489 B After Width: | Height: | Size: 489 B |
|
Before Width: | Height: | Size: 529 B After Width: | Height: | Size: 529 B |
|
Before Width: | Height: | Size: 529 B After Width: | Height: | Size: 529 B |