--- /dev/null
+using Content.Server.Storage.EntitySystems;
+using Content.Shared.EntityTable.EntitySelectors;
+
+namespace Content.Server.Storage.Components;
+
+/// <summary>
+/// Spawns items from an entity table when used in hand.
+/// </summary>
+[RegisterComponent, Access(typeof(SpawnTableOnUseSystem))]
+public sealed partial class SpawnTableOnUseComponent : Component
+{
+ /// <summary>
+ /// The entity table to select entities from.
+ /// </summary>
+ [DataField(required: true)]
+ public EntityTableSelector Table = default!;
+}
--- /dev/null
+using Content.Server.Administration.Logs;
+using Content.Server.Storage.Components;
+using Content.Shared.Database;
+using Content.Shared.EntityTable;
+using Content.Shared.Hands.EntitySystems;
+using Content.Shared.Interaction.Events;
+
+namespace Content.Server.Storage.EntitySystems;
+
+public sealed class SpawnTableOnUseSystem : EntitySystem
+{
+ [Dependency] private readonly EntityTableSystem _entityTable = default!;
+ [Dependency] private readonly IAdminLogManager _adminLogger = default!;
+ [Dependency] private readonly SharedHandsSystem _hands = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent<SpawnTableOnUseComponent, UseInHandEvent>(OnUseInHand);
+ }
+
+ private void OnUseInHand(Entity<SpawnTableOnUseComponent> ent, ref UseInHandEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ args.Handled = true;
+
+ var coords = Transform(ent).Coordinates;
+ var spawns = _entityTable.GetSpawns(ent.Comp.Table);
+ foreach (var id in spawns)
+ {
+ var spawned = Spawn(id, coords);
+ _adminLogger.Add(LogType.EntitySpawn, LogImpact.Low, $"{ToPrettyString(args.User):user} used {ToPrettyString(ent):spawner} which spawned {ToPrettyString(spawned)}");
+ _hands.TryPickupAnyHand(args.User, spawned);
+ }
+
+ Del(ent);
+ }
+}
[ViewVariables(VVAccess.ReadWrite)]
[DataField(required: true)]
public SoundSpecifier? Sound;
+
+ /// <summary>
+ /// Play the sound at the position instead of parented to the source entity.
+ /// Useful if the entity is deleted after.
+ /// </summary>
+ [DataField]
+ public bool Positional;
}
if (component.Sound == null)
return;
- if (predict)
+ if (component.Positional)
{
- _audioSystem.PlayPredicted(component.Sound, uid, user);
+ var coords = Transform(uid).Coordinates;
+ if (predict)
+ _audioSystem.PlayPredicted(component.Sound, coords, user);
+ else if (_netMan.IsServer)
+ // don't predict sounds that client couldn't have played already
+ _audioSystem.PlayPvs(component.Sound, coords);
}
- else if (_netMan.IsServer)
+ else
{
- // don't predict sounds that client couldn't have played already
- _audioSystem.PlayPvs(component.Sound, uid);
+ if (predict)
+ _audioSystem.PlayPredicted(component.Sound, uid, user);
+ else if (_netMan.IsServer)
+ // don't predict sounds that client couldn't have played already
+ _audioSystem.PlayPvs(component.Sound, uid);
}
}