35
Content.Server/Containers/ThrowInsertContainerComponent.cs
Normal file
35
Content.Server/Containers/ThrowInsertContainerComponent.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Robust.Shared.Audio;
|
||||
|
||||
namespace Content.Server.Containers;
|
||||
|
||||
/// <summary>
|
||||
/// Allows objects to fall inside the Container when thrown
|
||||
/// </summary>
|
||||
[RegisterComponent]
|
||||
[Access(typeof(ThrowInsertContainerSystem))]
|
||||
public sealed partial class ThrowInsertContainerComponent : Component
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public string? ContainerId;
|
||||
|
||||
/// <summary>
|
||||
/// Throw chance of hitting into the container
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public float Probability = 0.75f;
|
||||
|
||||
/// <summary>
|
||||
/// Sound played when an object is throw into the container.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier? InsertSound = new SoundPathSpecifier("/Audio/Effects/trashbag1.ogg");
|
||||
|
||||
/// <summary>
|
||||
/// Sound played when an item is thrown and misses the container.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public SoundSpecifier? MissSound = new SoundPathSpecifier("/Audio/Effects/thudswoosh.ogg");
|
||||
|
||||
[DataField]
|
||||
public LocId MissLocString = "container-thrown-missed";
|
||||
}
|
||||
53
Content.Server/Containers/ThrowInsertContainerSystem.cs
Normal file
53
Content.Server/Containers/ThrowInsertContainerSystem.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Content.Server.Administration.Logs;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Throwing;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.Random;
|
||||
|
||||
namespace Content.Server.Containers;
|
||||
|
||||
public sealed class ThrowInsertContainerSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||
[Dependency] private readonly SharedPopupSystem _popup = default!;
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ThrowInsertContainerComponent, ThrowHitByEvent>(OnThrowCollide);
|
||||
}
|
||||
|
||||
private void OnThrowCollide(Entity<ThrowInsertContainerComponent> ent, ref ThrowHitByEvent args)
|
||||
{
|
||||
if (ent.Comp.ContainerId == null)
|
||||
return;
|
||||
|
||||
var container = _containerSystem.GetContainer(ent, ent.Comp.ContainerId);
|
||||
|
||||
if (!_containerSystem.CanInsert(args.Thrown, container))
|
||||
return;
|
||||
|
||||
|
||||
var rand = _random.NextFloat();
|
||||
if (rand > ent.Comp.Probability)
|
||||
{
|
||||
_audio.PlayPvs(ent.Comp.MissSound, ent);
|
||||
_popup.PopupEntity(Loc.GetString(ent.Comp.MissLocString), ent);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_containerSystem.Insert(args.Thrown, container))
|
||||
_audio.PlayPvs(ent.Comp.InsertSound, ent);
|
||||
else
|
||||
throw new InvalidOperationException("Container insertion failed but CanInsert returned true");
|
||||
|
||||
if (args.Component.Thrower != null)
|
||||
_adminLogger.Add(LogType.Landed, LogImpact.Low, $"{ToPrettyString(args.Thrown)} thrown by {ToPrettyString(args.Component.Thrower.Value):player} landed in {ToPrettyString(ent)}");
|
||||
}
|
||||
}
|
||||
@@ -73,8 +73,6 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
||||
SubscribeLocalEvent<DisposalUnitComponent, PowerChangedEvent>(OnPowerChange);
|
||||
SubscribeLocalEvent<DisposalUnitComponent, ComponentInit>(OnDisposalInit);
|
||||
|
||||
SubscribeLocalEvent<DisposalUnitComponent, ThrowHitByEvent>(OnThrowCollide);
|
||||
|
||||
SubscribeLocalEvent<DisposalUnitComponent, ActivateInWorldEvent>(OnActivate);
|
||||
SubscribeLocalEvent<DisposalUnitComponent, AfterInteractUsingEvent>(OnAfterInteractUsing);
|
||||
SubscribeLocalEvent<DisposalUnitComponent, DragDropTargetEvent>(OnDragDropOn);
|
||||
@@ -294,40 +292,6 @@ public sealed class DisposalUnitSystem : SharedDisposalUnitSystem
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Thrown items have a chance of bouncing off the unit and not going in.
|
||||
/// </summary>
|
||||
private void OnThrowCollide(EntityUid uid, SharedDisposalUnitComponent component, ThrowHitByEvent args)
|
||||
{
|
||||
var canInsert = CanInsert(uid, component, args.Thrown);
|
||||
var randDouble = _robustRandom.NextDouble();
|
||||
|
||||
if (!canInsert)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (randDouble > 0.75)
|
||||
{
|
||||
_audioSystem.PlayPvs(component.MissSound, uid);
|
||||
|
||||
_popupSystem.PopupEntity(Loc.GetString("disposal-unit-thrown-missed"), uid);
|
||||
return;
|
||||
}
|
||||
|
||||
var inserted = _containerSystem.Insert(args.Thrown, component.Container);
|
||||
|
||||
if (!inserted)
|
||||
{
|
||||
throw new InvalidOperationException("Container insertion failed but CanInsert returned true");
|
||||
}
|
||||
|
||||
if (args.Component.Thrower != null)
|
||||
_adminLogger.Add(LogType.Landed, LogImpact.Low, $"{ToPrettyString(args.Thrown)} thrown by {ToPrettyString(args.Component.Thrower.Value):player} landed in {ToPrettyString(uid)}");
|
||||
|
||||
AfterInsert(uid, component, args.Thrown);
|
||||
}
|
||||
|
||||
private void OnDisposalInit(EntityUid uid, SharedDisposalUnitComponent component, ComponentInit args)
|
||||
{
|
||||
component.Container = _containerSystem.EnsureContainer<Container>(uid, SharedDisposalUnitComponent.ContainerId);
|
||||
|
||||
@@ -36,13 +36,6 @@ public abstract partial class SharedDisposalUnitComponent : Component
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("soundInsert")]
|
||||
public SoundSpecifier? InsertSound = new SoundPathSpecifier("/Audio/Effects/trashbag1.ogg");
|
||||
|
||||
/// <summary>
|
||||
/// Sound played when an item is thrown and misses the disposal unit.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField("soundMiss")]
|
||||
public SoundSpecifier? MissSound = new SoundPathSpecifier("/Audio/Effects/thudswoosh.ogg");
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// State for this disposals unit.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
container-verb-text-enter = Enter
|
||||
container-verb-text-empty = Empty
|
||||
|
||||
## missed
|
||||
container-thrown-missed = Missed!
|
||||
@@ -18,9 +18,6 @@ disposal-eject-verb-get-data-text = Eject contents
|
||||
## No hands
|
||||
disposal-unit-no-hands = You don't have hands!
|
||||
|
||||
## missed
|
||||
disposal-unit-thrown-missed = Missed!
|
||||
|
||||
# state
|
||||
disposal-unit-state-Ready = Ready
|
||||
# Yes I want it to always say Pressurizing
|
||||
|
||||
@@ -77,6 +77,8 @@
|
||||
graph: DisposalMachine
|
||||
node: disposal_unit
|
||||
- type: DisposalUnit
|
||||
- type: ThrowInsertContainer
|
||||
containerId: disposals
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
enum.DisposalUnitUiKey.Key:
|
||||
|
||||
Reference in New Issue
Block a user