PreventCollision with strap component while buckled to it (#2694)
* AvoidCollision if collided entity is the one that the character is buckled to * Attempt to PreventCollision after the player is unbuckled but still colliding with StrapComponent * Moved PreventCollide to the Shared script. * Add WakeBody to keep updating the physics collision while being on a collidable strap component. * Addressed some of metalgearsloth's suggestions: - Made EntityBuckledTo,IsOnStrapEntityThisFrame and DontCollide not virtual -Made EntityBuckledTo nullable -Don't call update on Paused BuckleComponents -Removed EntityBuckledTo variable declaration in BuckleComponent because it's not needed anymore -Call TryUnbuckle if (!IsOnStrapEntityThisFrame && DontCollide) to set BuckledTo entity to null. * Formatting Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com> * Formatting Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com> * Formatting again :P Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com> * Formatting Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com> * Formatting Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com> * Renamed variable EntityBuckledTo to LastEntityBuckledTo * As per DrSmugLeaf suggestion: Added [ComponentDependency] to the Body variable. Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using Content.Shared.GameObjects.Components.Buckle;
|
||||
using Content.Shared.GameObjects.Components.Buckle;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
@@ -27,6 +27,8 @@ namespace Content.Client.GameObjects.Components.Buckle
|
||||
}
|
||||
|
||||
_buckled = buckle.Buckled;
|
||||
LastEntityBuckledTo = buckle.LastEntityBuckledTo;
|
||||
DontCollide = buckle.DontCollide;
|
||||
|
||||
if (!Owner.TryGetComponent(out SpriteComponent ownerSprite))
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ using Robust.Shared.Interfaces.Timing;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -49,7 +50,6 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
private float _range;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of time that must pass for this entity to
|
||||
/// be able to unbuckle after recently buckling.
|
||||
@@ -70,6 +70,7 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
|
||||
private StrapComponent? _buckledTo;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The strap that this component is buckled to.
|
||||
/// </summary>
|
||||
@@ -266,6 +267,8 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
AppearanceComponent?.SetData(BuckleVisuals.Buckled, true);
|
||||
|
||||
BuckledTo = strap;
|
||||
LastEntityBuckledTo = BuckledTo.Owner.Uid;
|
||||
DontCollide = true;
|
||||
|
||||
ReAttach(strap);
|
||||
UpdateBuckleStatus();
|
||||
@@ -419,7 +422,8 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
drawDepth = BuckledTo.SpriteComponent.DrawDepth - 1;
|
||||
}
|
||||
|
||||
return new BuckleComponentState(Buckled, drawDepth);
|
||||
|
||||
return new BuckleComponentState(Buckled, drawDepth, LastEntityBuckledTo, DontCollide);
|
||||
}
|
||||
|
||||
bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs)
|
||||
@@ -427,6 +431,24 @@ namespace Content.Server.GameObjects.Components.Buckle
|
||||
return TryUnbuckle(eventArgs.User);
|
||||
}
|
||||
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (!DontCollide || Body == null)
|
||||
return;
|
||||
|
||||
Body.WakeBody();
|
||||
|
||||
if (!IsOnStrapEntityThisFrame && DontCollide)
|
||||
{
|
||||
DontCollide = false;
|
||||
TryUnbuckle(Owner);
|
||||
Dirty();
|
||||
}
|
||||
|
||||
IsOnStrapEntityThisFrame = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the unbuckling of the owning entity through a verb if
|
||||
/// anyone right clicks them.
|
||||
|
||||
@@ -26,6 +26,14 @@ namespace Content.Server.GameObjects.EntitySystems
|
||||
SubscribeLocalEvent<EntRemovedFromContainerMessage>(ContainerModified);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
foreach (var comp in ComponentManager.EntityQuery<BuckleComponent>(false))
|
||||
{
|
||||
comp.Update();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
|
||||
@@ -1,30 +1,54 @@
|
||||
using System;
|
||||
#nullable enable
|
||||
using System;
|
||||
using Content.Shared.GameObjects.Components.Strap;
|
||||
using Content.Shared.GameObjects.EntitySystems;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.ComponentDependencies;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Buckle
|
||||
{
|
||||
public abstract class SharedBuckleComponent : Component, IActionBlocker, IEffectBlocker, IDraggable
|
||||
public abstract class SharedBuckleComponent : Component, IActionBlocker, IEffectBlocker, IDraggable, ICollideSpecial
|
||||
{
|
||||
public sealed override string Name => "Buckle";
|
||||
|
||||
public sealed override uint? NetID => ContentNetIDs.BUCKLE;
|
||||
|
||||
/// <summary>
|
||||
/// True if the entity is buckled, false otherwise.
|
||||
/// </summary>
|
||||
public abstract bool Buckled { get; }
|
||||
public EntityUid? LastEntityBuckledTo { get; set; }
|
||||
|
||||
public bool IsOnStrapEntityThisFrame { get; set; }
|
||||
public bool DontCollide { get; set; }
|
||||
public abstract bool TryBuckle(IEntity user, IEntity to);
|
||||
|
||||
[ComponentDependency] protected IPhysicsComponent? Body;
|
||||
|
||||
bool ICollideSpecial.PreventCollide(IPhysBody collidedwith)
|
||||
{
|
||||
if (collidedwith.Entity.Uid == LastEntityBuckledTo)
|
||||
{
|
||||
IsOnStrapEntityThisFrame = true;
|
||||
return Buckled || DontCollide;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanMove()
|
||||
{
|
||||
return !Buckled;
|
||||
}
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
Owner.TryGetComponent(out Body);
|
||||
}
|
||||
|
||||
bool IActionBlocker.CanChangeDirection()
|
||||
{
|
||||
@@ -50,13 +74,17 @@ namespace Content.Shared.GameObjects.Components.Buckle
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class BuckleComponentState : ComponentState
|
||||
{
|
||||
public BuckleComponentState(bool buckled, int? drawDepth) : base(ContentNetIDs.BUCKLE)
|
||||
public BuckleComponentState(bool buckled, int? drawDepth, EntityUid? lastEntityBuckledTo, bool dontCollide) : base(ContentNetIDs.BUCKLE)
|
||||
{
|
||||
Buckled = buckled;
|
||||
DrawDepth = drawDepth;
|
||||
LastEntityBuckledTo = lastEntityBuckledTo;
|
||||
DontCollide = dontCollide;
|
||||
}
|
||||
|
||||
public bool Buckled { get; }
|
||||
public EntityUid? LastEntityBuckledTo { get; }
|
||||
public bool DontCollide { get; }
|
||||
public int? DrawDepth;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user