mirror of
https://github.com/WWhiteDreamProject/wwdpublic.git
synced 2026-04-21 07:28:31 +03:00
# Description This cherry-picks the following two PRs of mine from delta-v: - https://github.com/DeltaV-Station/Delta-v/pull/1118 (this one is a port of two other frontier PRs, see the original description for details) - https://github.com/DeltaV-Station/Delta-v/pull/1232 Encompassing a total of 8 distinct changes: 1. Fixes dropping the carried person when walking to a different grid (from station to shuttle or vice versa. Walking into space however will still make you drop them) and also makes sure that pressing shift while being carried does not make you escape. 2. Ensures that the carried person is always centered relative to the parent (under certain conditions, such as walking near a gravitational anomaly, their position can change, and that leads to really weird effects) 3. Fixes the mass contest in CarryingSystem that caused stronger entities to take longer to escape than weaker ones. 4. Adds popups for when you're getting picked up or being stuffed into a bag as a pseudo-item (e.g. a felinid) 5. Adds an action to stop escaping an inventory. This action gets added to your action bar when you attempt escaping and gets removed when you stop or escape. It applies both to carrying and items (hampsters, felinids, whatever else). 6. Adds a sleep action for pseudo-items stuffed inside a suitable bag. The bag must have a special component, which is added to the base backpack item and thus inherited by all soft bags (duffels, satchels, etc). Contrary to a popular belief, sleeping IS PURELY COSMETICAL and does not provide healing. (Beds provide healing when you buckle into them and that healing does not depend on whether or not you're sleeping) 7. Makes it so that when you try to take a pseudo-item out of the bag (e.g. a felinid), you automatically try to carry them (if you don't have enough free hands, they will be dropped on the floor like usually), and enables you to insert the carried person into a bag, but only if they're a pseudo-item (e.g. felinid). 8. Allows pseudoitems to be inserted into bags even when there are other items (as long as there's enough space) --- ## For technical details and video showcases, see the original PRs This PR is split into separate commits so different parts can be reverted if deemed unneccessary. --- <!-- This is default collapsed, readers click to expand it and see all your media The PR media section can get very large at times, so this is a good way to keep it clean The title is written using HTML tags The title must be within the <summary> tags or you won't see it <details><summary><h1>Media</h1></summary> <p>  </p> </details> --- --> # Changelog 🆑 - fix: Carrying is less likely to behave erratically or suddenly interrupt now. - add: You can now see when someone is trying to pick you up, and also you can interrupt your attempt at escaping from their hands or inventory. - add: You can now properly take Felinids out of bags and place them inside. - add: Scientists have discovered that Felinids can sleep in bags.
139 lines
5.5 KiB
C#
139 lines
5.5 KiB
C#
using Content.Server.Popups;
|
|
using Content.Shared.Storage;
|
|
using Content.Server.Carrying; // Carrying system from Nyanotrasen.
|
|
using Content.Shared.Inventory;
|
|
using Content.Shared.Hands.EntitySystems;
|
|
using Content.Server.Storage.Components;
|
|
using Content.Shared.ActionBlocker;
|
|
using Content.Shared.Actions;
|
|
using Content.Shared.DoAfter;
|
|
using Content.Shared.Hands.EntitySystems;
|
|
using Content.Shared.Interaction.Events;
|
|
using Content.Shared.Inventory;
|
|
using Content.Shared.Movement.Events;
|
|
using Content.Shared.Resist;
|
|
using Content.Shared.Storage;
|
|
using Robust.Shared.Containers;
|
|
using Robust.Shared.Prototypes;
|
|
|
|
namespace Content.Server.Resist;
|
|
|
|
public sealed class EscapeInventorySystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
|
|
[Dependency] private readonly PopupSystem _popupSystem = default!;
|
|
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
|
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
|
|
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
|
[Dependency] private readonly CarryingSystem _carryingSystem = default!; // Carrying system from Nyanotrasen.
|
|
[Dependency] private readonly SharedActionsSystem _actions = default!;
|
|
|
|
/// <summary>
|
|
/// You can't escape the hands of an entity this many times more massive than you.
|
|
/// </summary>
|
|
public const float MaximumMassDisadvantage = 6f;
|
|
/// <summary>
|
|
/// Action to cancel inventory escape
|
|
/// </summary>
|
|
[ValidatePrototypeId<EntityPrototype>]
|
|
private readonly string _escapeCancelAction = "ActionCancelEscape";
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<CanEscapeInventoryComponent, MoveInputEvent>(OnRelayMovement);
|
|
SubscribeLocalEvent<CanEscapeInventoryComponent, EscapeInventoryEvent>(OnEscape);
|
|
SubscribeLocalEvent<CanEscapeInventoryComponent, DroppedEvent>(OnDropped);
|
|
SubscribeLocalEvent<CanEscapeInventoryComponent, EscapeInventoryCancelActionEvent>(OnCancelEscape);
|
|
}
|
|
|
|
private void OnRelayMovement(EntityUid uid, CanEscapeInventoryComponent component, ref MoveInputEvent args)
|
|
{
|
|
if (!args.HasDirectionalMovement)
|
|
return;
|
|
|
|
if (!_containerSystem.TryGetContainingContainer(uid, out var container) || !_actionBlockerSystem.CanInteract(uid, container.Owner))
|
|
return;
|
|
|
|
// Make sure there's nothing stopped the removal (like being glued)
|
|
if (!_containerSystem.CanRemove(uid, container))
|
|
{
|
|
_popupSystem.PopupEntity(Loc.GetString("escape-inventory-component-failed-resisting"), uid, uid);
|
|
return;
|
|
}
|
|
|
|
// Contested
|
|
if (_handsSystem.IsHolding(container.Owner, uid, out _))
|
|
{
|
|
AttemptEscape(uid, container.Owner, component);
|
|
return;
|
|
}
|
|
|
|
// Uncontested
|
|
if (HasComp<StorageComponent>(container.Owner) || HasComp<InventoryComponent>(container.Owner) || HasComp<SecretStashComponent>(container.Owner))
|
|
AttemptEscape(uid, container.Owner, component);
|
|
}
|
|
|
|
public void AttemptEscape(EntityUid user, EntityUid container, CanEscapeInventoryComponent component, float multiplier = 1f) //private to public for carrying system.
|
|
{
|
|
if (component.IsEscaping)
|
|
return;
|
|
|
|
var doAfterEventArgs = new DoAfterArgs(EntityManager, user, component.BaseResistTime * multiplier, new EscapeInventoryEvent(), user, target: container)
|
|
{
|
|
BreakOnTargetMove = false,
|
|
BreakOnUserMove = true,
|
|
BreakOnDamage = true,
|
|
NeedHand = false
|
|
};
|
|
|
|
if (!_doAfterSystem.TryStartDoAfter(doAfterEventArgs, out component.DoAfter))
|
|
return;
|
|
|
|
_popupSystem.PopupEntity(Loc.GetString("escape-inventory-component-start-resisting"), user, user);
|
|
_popupSystem.PopupEntity(Loc.GetString("escape-inventory-component-start-resisting-target"), container, container);
|
|
|
|
// Add an escape cancel action
|
|
if (component.EscapeCancelAction is not { Valid: true })
|
|
_actions.AddAction(user, ref component.EscapeCancelAction, _escapeCancelAction);
|
|
}
|
|
|
|
private void OnEscape(EntityUid uid, CanEscapeInventoryComponent component, EscapeInventoryEvent args)
|
|
{
|
|
component.DoAfter = null;
|
|
|
|
// Remove the cancel action regardless of do-after result
|
|
_actions.RemoveAction(uid, component.EscapeCancelAction);
|
|
component.EscapeCancelAction = null;
|
|
|
|
if (args.Handled || args.Cancelled)
|
|
return;
|
|
|
|
if (TryComp<BeingCarriedComponent>(uid, out var carried)) // Start of carrying system of nyanotrasen.
|
|
{
|
|
_carryingSystem.DropCarried(carried.Carrier, uid);
|
|
return;
|
|
} // End of carrying system of nyanotrasen.
|
|
|
|
|
|
_containerSystem.AttachParentToContainerOrGrid((uid, Transform(uid)));
|
|
args.Handled = true;
|
|
}
|
|
|
|
private void OnDropped(EntityUid uid, CanEscapeInventoryComponent component, DroppedEvent args)
|
|
{
|
|
if (component.DoAfter != null)
|
|
_doAfterSystem.Cancel(component.DoAfter);
|
|
}
|
|
|
|
private void OnCancelEscape(EntityUid uid, CanEscapeInventoryComponent component, EscapeInventoryCancelActionEvent args)
|
|
{
|
|
if (component.DoAfter != null)
|
|
_doAfterSystem.Cancel(component.DoAfter);
|
|
|
|
_actions.RemoveAction(uid, component.EscapeCancelAction);
|
|
component.EscapeCancelAction = null;
|
|
}
|
|
}
|