ECS thrown items (#4110)
This commit is contained in:
@@ -1,49 +1,13 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using Content.Shared.GameObjects.EntitySystems;
|
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
|
||||||
using Content.Shared.Physics;
|
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Physics;
|
|
||||||
using Robust.Shared.Physics.Collision;
|
|
||||||
using Robust.Shared.Physics.Dynamics;
|
|
||||||
|
|
||||||
namespace Content.Shared.GameObjects.Components.Items
|
namespace Content.Shared.GameObjects.Components.Items
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public class ThrownItemComponent : Component, IStartCollide, ICollideSpecial, IThrown, ILand
|
public class ThrownItemComponent : Component
|
||||||
{
|
{
|
||||||
public override string Name => "ThrownItem";
|
public override string Name => "ThrownItem";
|
||||||
|
|
||||||
public IEntity? Thrower { get; set; }
|
public IEntity? Thrower { get; set; }
|
||||||
|
|
||||||
private Fixture? _fixture;
|
|
||||||
|
|
||||||
void IStartCollide.CollideWith(Fixture ourFixture, Fixture otherFixture, in Manifold manifold)
|
|
||||||
{
|
|
||||||
if (otherFixture.Body.Owner == Thrower) return;
|
|
||||||
EntitySystem.Get<ThrownItemSystem>().ThrowCollideInteraction(Thrower, ourFixture.Body, otherFixture.Body);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ICollideSpecial.PreventCollide(IPhysBody collidedwith)
|
|
||||||
{
|
|
||||||
return collidedwith.Owner == Thrower;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IThrown.Thrown(ThrownEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
if (!Owner.TryGetComponent(out PhysicsComponent? physicsComponent) ||
|
|
||||||
physicsComponent.Fixtures.Count != 1) return;
|
|
||||||
|
|
||||||
var shape = physicsComponent.Fixtures[0].Shape;
|
|
||||||
_fixture = new Fixture(physicsComponent, shape) {CollisionLayer = (int) CollisionGroup.ThrownItem, Hard = false};
|
|
||||||
physicsComponent.AddFixture(_fixture);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ILand.Land(LandEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
if (!Owner.TryGetComponent(out PhysicsComponent? physicsComponent) || _fixture == null) return;
|
|
||||||
|
|
||||||
physicsComponent.RemoveFixture(_fixture);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ using System.Linq;
|
|||||||
using Content.Shared.GameObjects.Components.Items;
|
using Content.Shared.GameObjects.Components.Items;
|
||||||
using Content.Shared.Physics.Pull;
|
using Content.Shared.Physics.Pull;
|
||||||
using Content.Shared.Interfaces.GameObjects.Components;
|
using Content.Shared.Interfaces.GameObjects.Components;
|
||||||
|
using Content.Shared.Physics;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.Log;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
using Robust.Shared.Physics.Dynamics;
|
using Robust.Shared.Physics.Dynamics;
|
||||||
|
|
||||||
@@ -17,13 +19,65 @@ namespace Content.Shared.GameObjects.EntitySystems
|
|||||||
{
|
{
|
||||||
private List<IThrowCollide> _throwCollide = new();
|
private List<IThrowCollide> _throwCollide = new();
|
||||||
|
|
||||||
|
private const string ThrowingFixture = "throw-fixture";
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
SubscribeLocalEvent<ThrownItemComponent, PhysicsSleepMessage>(HandleSleep);
|
SubscribeLocalEvent<ThrownItemComponent, PhysicsSleepMessage>(HandleSleep);
|
||||||
|
SubscribeLocalEvent<ThrownItemComponent, StartCollideEvent>(HandleCollision);
|
||||||
|
SubscribeLocalEvent<ThrownItemComponent, PreventCollideEvent>(PreventCollision);
|
||||||
|
SubscribeLocalEvent<ThrownItemComponent, ThrownEvent>(ThrowItem);
|
||||||
|
SubscribeLocalEvent<ThrownItemComponent, LandEvent>(LandItem);
|
||||||
SubscribeLocalEvent<PullStartedMessage>(HandlePullStarted);
|
SubscribeLocalEvent<PullStartedMessage>(HandlePullStarted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LandItem(EntityUid uid, ThrownItemComponent component, LandEvent args)
|
||||||
|
{
|
||||||
|
if (!component.Owner.TryGetComponent(out PhysicsComponent? physicsComponent)) return;
|
||||||
|
|
||||||
|
var fixture = physicsComponent.GetFixture(ThrowingFixture);
|
||||||
|
if (fixture == null)
|
||||||
|
{
|
||||||
|
Logger.Error($"Tried to remove throwing fixture for {component.Owner} but none found?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
physicsComponent.RemoveFixture(fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ThrowItem(EntityUid uid, ThrownItemComponent component, ThrownEvent args)
|
||||||
|
{
|
||||||
|
if (!component.Owner.TryGetComponent(out PhysicsComponent? physicsComponent) ||
|
||||||
|
physicsComponent.Fixtures.Count != 1) return;
|
||||||
|
|
||||||
|
if (physicsComponent.GetFixture(ThrowingFixture) != null)
|
||||||
|
{
|
||||||
|
Logger.Error($"Found existing throwing fixture on {component.Owner}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var shape = physicsComponent.Fixtures[0].Shape;
|
||||||
|
var fixture = new Fixture(physicsComponent, shape) {CollisionLayer = (int) CollisionGroup.ThrownItem, Hard = false, Name = ThrowingFixture};
|
||||||
|
physicsComponent.AddFixture(fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleCollision(EntityUid uid, ThrownItemComponent component, StartCollideEvent args)
|
||||||
|
{
|
||||||
|
var thrower = component.Thrower;
|
||||||
|
var otherBody = args.OtherFixture.Body;
|
||||||
|
|
||||||
|
if (otherBody.Owner == thrower) return;
|
||||||
|
ThrowCollideInteraction(thrower, args.OurFixture.Body, otherBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PreventCollision(EntityUid uid, ThrownItemComponent component, PreventCollideEvent args)
|
||||||
|
{
|
||||||
|
if (args.BodyB.Owner == component.Thrower)
|
||||||
|
{
|
||||||
|
args.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleSleep(EntityUid uid, ThrownItemComponent thrownItem, PhysicsSleepMessage message)
|
private void HandleSleep(EntityUid uid, ThrownItemComponent thrownItem, PhysicsSleepMessage message)
|
||||||
{
|
{
|
||||||
LandComponent(thrownItem);
|
LandComponent(thrownItem);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace Content.Shared.Physics
|
|||||||
MapGrid = MapGridHelpers.CollisionGroup, // Map grids, like shuttles. This is the actual grid itself, not the walls or other entities connected to the grid.
|
MapGrid = MapGridHelpers.CollisionGroup, // Map grids, like shuttles. This is the actual grid itself, not the walls or other entities connected to the grid.
|
||||||
|
|
||||||
MobMask = Impassable | MobImpassable | VaultImpassable | SmallImpassable,
|
MobMask = Impassable | MobImpassable | VaultImpassable | SmallImpassable,
|
||||||
ThrownItem = MobImpassable | Impassable,
|
ThrownItem = VaultImpassable,
|
||||||
// 32 possible groups
|
// 32 possible groups
|
||||||
AllMask = -1,
|
AllMask = -1,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user