2020-12-27 10:30:47 +01:00
|
|
|
using Content.Server.GameObjects.EntitySystems.Click;
|
2018-12-13 07:47:19 -06:00
|
|
|
using Content.Shared.GameObjects;
|
2018-10-30 01:13:10 -07:00
|
|
|
using Content.Shared.Physics;
|
2021-02-11 01:13:03 -08:00
|
|
|
using Robust.Server.GameObjects;
|
2019-07-18 23:33:02 +02:00
|
|
|
using Robust.Shared.GameObjects;
|
|
|
|
|
using Robust.Shared.IoC;
|
2020-07-02 23:24:27 +02:00
|
|
|
using Robust.Shared.Maths;
|
2021-02-11 01:13:03 -08:00
|
|
|
using Robust.Shared.Physics;
|
2018-10-30 01:13:10 -07:00
|
|
|
|
2020-08-13 14:40:27 +02:00
|
|
|
namespace Content.Server.GameObjects.Components.Projectiles
|
2018-10-30 01:13:10 -07:00
|
|
|
{
|
2019-07-31 15:02:36 +02:00
|
|
|
[RegisterComponent]
|
2020-01-11 14:12:20 -08:00
|
|
|
internal class ThrownItemComponent : ProjectileComponent, ICollideBehavior
|
2018-10-30 01:13:10 -07:00
|
|
|
{
|
2020-07-02 23:24:27 +02:00
|
|
|
public const float DefaultThrowTime = 0.25f;
|
2019-07-18 23:33:02 +02:00
|
|
|
|
2020-05-23 01:23:36 +02:00
|
|
|
private bool _shouldCollide = true;
|
2020-07-23 01:51:31 +02:00
|
|
|
private bool _shouldStop = false;
|
2020-05-23 01:23:36 +02:00
|
|
|
|
2018-10-30 01:13:10 -07:00
|
|
|
public override string Name => "ThrownItem";
|
2020-07-02 23:24:27 +02:00
|
|
|
public override uint? NetID => ContentNetIDs.THROWN_ITEM;
|
2018-10-30 01:13:10 -07:00
|
|
|
|
2019-07-18 23:33:02 +02:00
|
|
|
/// <summary>
|
|
|
|
|
/// User who threw the item.
|
|
|
|
|
/// </summary>
|
2020-12-21 13:22:16 +01:00
|
|
|
public IEntity User { get; set; }
|
2019-07-18 23:33:02 +02:00
|
|
|
|
2020-05-23 01:23:36 +02:00
|
|
|
void ICollideBehavior.CollideWith(IEntity entity)
|
2018-10-30 01:13:10 -07:00
|
|
|
{
|
2021-01-02 12:03:10 -06:00
|
|
|
if (!_shouldCollide || entity.Deleted) return;
|
2020-10-11 16:36:58 +02:00
|
|
|
if (entity.TryGetComponent(out PhysicsComponent collid))
|
2020-07-23 01:51:31 +02:00
|
|
|
{
|
|
|
|
|
if (!collid.Hard) // ignore non hard
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
_shouldStop = true; // hit something hard => stop after this collision
|
2020-09-22 15:34:30 +02:00
|
|
|
|
|
|
|
|
// Raise an event.
|
|
|
|
|
EntitySystem.Get<InteractionSystem>().ThrowCollideInteraction(User, Owner, entity, Owner.Transform.Coordinates);
|
2020-07-23 01:51:31 +02:00
|
|
|
}
|
2020-07-02 23:24:27 +02:00
|
|
|
|
2018-10-30 01:13:10 -07:00
|
|
|
// Stop colliding with mobs, this mimics not having enough velocity to do damage
|
|
|
|
|
// after impacting the first object.
|
|
|
|
|
// For realism this should actually be changed when the velocity of the object is less than a threshold.
|
|
|
|
|
// This would allow ricochets off walls, and weird gravity effects from slowing the object.
|
2021-01-18 17:16:34 +07:00
|
|
|
if (!Owner.Deleted && Owner.TryGetComponent(out IPhysicsComponent body) && body.PhysicsShapes.Count >= 1)
|
2020-05-23 01:23:36 +02:00
|
|
|
{
|
|
|
|
|
_shouldCollide = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-02 23:24:27 +02:00
|
|
|
private void StopThrow()
|
2020-05-23 01:23:36 +02:00
|
|
|
{
|
2020-07-08 16:44:56 +02:00
|
|
|
if (Deleted)
|
2020-07-08 16:39:05 +02:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-11 16:36:58 +02:00
|
|
|
if (Owner.TryGetComponent(out IPhysicsComponent body) && body.PhysicsShapes.Count >= 1)
|
2018-10-30 01:13:10 -07:00
|
|
|
{
|
2020-07-02 23:24:27 +02:00
|
|
|
body.PhysicsShapes[0].CollisionMask &= (int) ~CollisionGroup.ThrownItem;
|
2018-10-30 01:13:10 -07:00
|
|
|
|
2020-07-23 18:33:37 +02:00
|
|
|
if (body.TryGetController(out ThrownController controller))
|
|
|
|
|
{
|
|
|
|
|
controller.LinearVelocity = Vector2.Zero;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-02 23:24:27 +02:00
|
|
|
body.Status = BodyStatus.OnGround;
|
2020-07-23 18:33:37 +02:00
|
|
|
|
2018-10-30 01:13:10 -07:00
|
|
|
Owner.RemoveComponent<ThrownItemComponent>();
|
2020-09-06 16:11:53 +02:00
|
|
|
EntitySystem.Get<InteractionSystem>().LandInteraction(User, Owner, Owner.Transform.Coordinates);
|
2020-07-02 23:24:27 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ICollideBehavior.PostCollide(int collideCount)
|
|
|
|
|
{
|
2020-07-23 01:51:31 +02:00
|
|
|
if (_shouldStop && collideCount > 0)
|
2020-07-02 23:24:27 +02:00
|
|
|
{
|
|
|
|
|
StopThrow();
|
2018-10-30 01:13:10 -07:00
|
|
|
}
|
|
|
|
|
}
|
2020-07-02 23:24:27 +02:00
|
|
|
|
2020-07-23 18:33:37 +02:00
|
|
|
public void StartThrow(Vector2 direction, float speed)
|
2020-07-02 23:24:27 +02:00
|
|
|
{
|
2020-10-11 16:36:58 +02:00
|
|
|
var comp = Owner.GetComponent<IPhysicsComponent>();
|
2020-07-02 23:24:27 +02:00
|
|
|
comp.Status = BodyStatus.InAir;
|
2020-07-23 18:33:37 +02:00
|
|
|
|
|
|
|
|
var controller = comp.EnsureController<ThrownController>();
|
|
|
|
|
controller.Push(direction, speed);
|
|
|
|
|
|
2020-12-27 10:30:47 +01:00
|
|
|
EntitySystem.Get<AudioSystem>()
|
|
|
|
|
.PlayFromEntity("/Audio/Effects/toss.ogg", Owner);
|
|
|
|
|
|
2020-07-02 23:24:27 +02:00
|
|
|
StartStopTimer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StartStopTimer()
|
|
|
|
|
{
|
2020-10-30 05:02:49 +01:00
|
|
|
Owner.SpawnTimer((int) (DefaultThrowTime * 1000), MaybeStopThrow);
|
2020-07-02 23:24:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void MaybeStopThrow()
|
|
|
|
|
{
|
|
|
|
|
if (Deleted)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-06 16:11:53 +02:00
|
|
|
if (IoCManager.Resolve<IPhysicsManager>().IsWeightless(Owner.Transform.Coordinates))
|
2020-07-02 23:24:27 +02:00
|
|
|
{
|
|
|
|
|
StartStopTimer();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StopThrow();
|
|
|
|
|
}
|
2018-10-30 01:13:10 -07:00
|
|
|
}
|
|
|
|
|
}
|