ECS thrown items (#4110)

This commit is contained in:
metalgearsloth
2021-05-31 17:13:40 +10:00
committed by GitHub
parent 8a6ab624ab
commit 10615c233c
3 changed files with 56 additions and 38 deletions

View File

@@ -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);
}
} }
} }

View File

@@ -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);

View File

@@ -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,
} }