Interaction Features (#101)

Various minor interaction features.

There is no concept of gravity in the game yet, so items drift through space or the hallways of a station until they are stopped. Thrown items do not collide with walls because making them collidable makes them collide with EVERYTHING, including the player. We need collision groups in the physics system.

Because of the previous problems the velocity things are throw at is set quite low, it can be tweaked after the other mentioned issues are resolved.
This commit is contained in:
Acruid
2018-08-22 01:19:47 -07:00
committed by Pieter-Jan Briers
parent cd4442b81e
commit ed39649721
11 changed files with 170 additions and 17 deletions

View File

@@ -1,15 +1,24 @@
using Content.Shared.Input;
using System;
using Content.Server.GameObjects.Components.Projectiles;
using Content.Shared.Input;
using SS14.Server.GameObjects;
using SS14.Server.GameObjects.EntitySystems;
using SS14.Server.Interfaces.Player;
using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.EntitySystemMessages;
using SS14.Shared.GameObjects.Systems;
using SS14.Shared.Input;
using SS14.Shared.Interfaces.GameObjects.Components;
using SS14.Shared.Map;
using SS14.Shared.Maths;
using SS14.Shared.Players;
namespace Content.Server.GameObjects.EntitySystems
{
internal class HandsSystem : EntitySystem
{
private const float ThrowSpeed = 1.0f;
/// <inheritdoc />
public override void Initialize()
{
@@ -17,10 +26,11 @@ namespace Content.Server.GameObjects.EntitySystems
var input = EntitySystemManager.GetEntitySystem<InputSystem>();
input.BindMap.BindFunction(ContentKeyFunctions.SwapHands, InputCmdHandler.FromDelegate(HandleSwapHands));
input.BindMap.BindFunction(ContentKeyFunctions.Drop, InputCmdHandler.FromDelegate(HandleDrop));
input.BindMap.BindFunction(ContentKeyFunctions.Drop, new PointerInputCmdHandler(HandleDrop));
input.BindMap.BindFunction(ContentKeyFunctions.ActivateItemInHand, InputCmdHandler.FromDelegate(HandleActivateItem));
input.BindMap.BindFunction(ContentKeyFunctions.ThrowItemInHand, new PointerInputCmdHandler(HandleThrowItem));
}
/// <inheritdoc />
public override void Shutdown()
{
@@ -29,11 +39,36 @@ namespace Content.Server.GameObjects.EntitySystems
input.BindMap.UnbindFunction(ContentKeyFunctions.SwapHands);
input.BindMap.UnbindFunction(ContentKeyFunctions.Drop);
input.BindMap.UnbindFunction(ContentKeyFunctions.ActivateItemInHand);
input.BindMap.UnbindFunction(ContentKeyFunctions.ThrowItemInHand);
}
base.Shutdown();
}
/// <inheritdoc />
public override void SubscribeEvents()
{
SubscribeEvent<EntParentChangedMessage>(HandleParented);
}
private static void HandleParented(object sender, EntitySystemMessage args)
{
var msg = (EntParentChangedMessage) args;
if (!msg.Entity.TryGetComponent(out ITransformComponent transform))
return;
// if item is in a container
if(transform.IsMapTransform)
return;
if(!msg.Entity.TryGetComponent(out PhysicsComponent physics))
return;
// set velocity to zero
physics.LinearVelocity = Vector2.Zero;
}
private static bool TryGetAttachedComponent<T>(IPlayerSession session, out T component)
where T : Component
{
@@ -59,12 +94,25 @@ namespace Content.Server.GameObjects.EntitySystems
handsComp.SwapHands();
}
private static void HandleDrop(ICommonSession session)
private static void HandleDrop(ICommonSession session, GridLocalCoordinates coords, EntityUid uid)
{
if (!TryGetAttachedComponent(session as IPlayerSession, out HandsComponent handsComp))
var ent = ((IPlayerSession) session).AttachedEntity;
if(ent == null || !ent.IsValid())
return;
handsComp.Drop(handsComp.ActiveIndex);
if (!ent.TryGetComponent(out HandsComponent handsComp))
return;
var transform = ent.Transform;
GridLocalCoordinates? dropPos = null;
if (transform.LocalPosition.InRange(coords, InteractionSystem.INTERACTION_RANGE))
{
dropPos = coords;
}
handsComp.Drop(handsComp.ActiveIndex, dropPos);
}
private static void HandleActivateItem(ICommonSession session)
@@ -74,5 +122,53 @@ namespace Content.Server.GameObjects.EntitySystems
handsComp.ActivateItem();
}
private static void HandleThrowItem(ICommonSession session, GridLocalCoordinates coords, EntityUid uid)
{
var plyEnt = ((IPlayerSession)session).AttachedEntity;
if (plyEnt == null || !plyEnt.IsValid())
return;
if (!plyEnt.TryGetComponent(out HandsComponent handsComp))
return;
if (handsComp.CanDrop(handsComp.ActiveIndex))
{
var throwEnt = handsComp.GetHand(handsComp.ActiveIndex).Owner;
handsComp.Drop(handsComp.ActiveIndex, null);
if (!throwEnt.TryGetComponent(out ProjectileComponent projComp))
{
projComp = throwEnt.AddComponent<ProjectileComponent>();
}
projComp.IgnoreEntity(plyEnt);
var transform = plyEnt.Transform;
var dirVec = (coords.ToWorld().Position - transform.WorldPosition).Normalized;
if (!throwEnt.TryGetComponent(out PhysicsComponent physComp))
{
physComp = throwEnt.AddComponent<PhysicsComponent>();
}
physComp.LinearVelocity = dirVec * ThrowSpeed;
var wHomoDir = Vector3.UnitX;
transform.InvWorldMatrix.Transform(ref wHomoDir, out var lHomoDir);
lHomoDir.Normalize();
var angle = new Angle(lHomoDir.Xy);
transform.LocalRotation = angle;
}
else
{
return;
}
}
}
}