Changes physics and collidables (#543)

This is for projectile weapons, adds some enhancements and modifiers for collision behavior which will help out
This commit is contained in:
clusterfack
2018-04-05 17:34:24 -05:00
committed by Pieter-Jan Briers
parent b13af4cd8d
commit 5f5c5f13c9
7 changed files with 99 additions and 19 deletions

View File

@@ -9,6 +9,8 @@ using SS14.Shared.Map;
using SS14.Shared.Maths;
using SS14.Shared.Utility;
using YamlDotNet.RepresentationModel;
using System.Linq;
using System.Collections.Generic;
namespace SS14.Client.GameObjects
{
@@ -43,14 +45,23 @@ namespace SS14.Client.GameObjects
/// <inheritdoc />
public MapId MapID => Owner.GetComponent<ITransformComponent>().MapID;
/// <summary>
/// Called when the collidable is bumped into by someone/something
/// </summary>
void ICollidable.Bump(IEntity ent)
/// <inheritdoc />
void ICollidable.Bumped(IEntity bumpedby)
{
SendMessage(new BumpedEntMsg(ent));
SendMessage(new BumpedEntMsg(bumpedby));
OnBump?.Invoke(this, new BumpEventArgs(this.Owner, ent));
OnBump?.Invoke(this, new BumpEventArgs(this.Owner, bumpedby));
}
/// <inheritdoc />
void ICollidable.Bump(List<IEntity> bumpedinto)
{
List<ICollideBehavior> collidecomponents = Owner.GetComponents<ICollideBehavior>().ToList();
for (var i = 0; i < collidecomponents.Count; i++)
{
collidecomponents[i].CollideWith(bumpedinto);
}
}
/// <inheritdoc />

View File

@@ -7,6 +7,8 @@ using SS14.Shared.Interfaces.Physics;
using SS14.Shared.IoC;
using SS14.Shared.Map;
using SS14.Shared.Maths;
using System.Collections.Generic;
using System.Linq;
namespace SS14.Server.GameObjects
{
@@ -55,9 +57,20 @@ namespace SS14.Server.GameObjects
}
/// <inheritdoc />
void ICollidable.Bump(IEntity ent)
void ICollidable.Bumped(IEntity bumpedby)
{
OnBump?.Invoke(this, new BumpEventArgs(Owner, ent));
OnBump?.Invoke(this, new BumpEventArgs(Owner, bumpedby));
}
/// <inheritdoc />
void ICollidable.Bump(List<IEntity> bumpedinto)
{
List<ICollideBehavior> collidecomponents = Owner.GetComponents<ICollideBehavior>().ToList();
for (var i = 0; i < collidecomponents.Count; i++)
{
collidecomponents[i].CollideWith(bumpedinto);
}
}
/// <summary>

View File

@@ -50,6 +50,8 @@ namespace SS14.Server.GameObjects
set => _angVelocity = value;
}
public bool EdgeSlide = true;
/// <inheritdoc />
public override void OnAdd()
{
@@ -68,6 +70,7 @@ namespace SS14.Server.GameObjects
serializer.DataField(ref _mass, "mass", 1);
serializer.DataField(ref _linVelocity, "vel", Vector2.Zero);
serializer.DataField(ref _angVelocity, "avel", 0.0f);
serializer.DataField(ref EdgeSlide, "edgeslide", true);
}
/// <inheritdoc />

View File

@@ -4,6 +4,7 @@ using SS14.Shared.GameObjects;
using SS14.Shared.GameObjects.System;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Maths;
using SS14.Shared.Interfaces.Physics;
namespace SS14.Server.GameObjects.EntitySystems
{
@@ -54,13 +55,25 @@ namespace SS14.Server.GameObjects.EntitySystems
//Check for collision
if (movement.LengthSquared > Epsilon && entity.TryGetComponent(out CollidableComponent collider))
{
var collided = collider.TryCollision(movement);
var collided = collider.TryCollision(movement, true);
if (collided)
{
var xBlocked = collider.TryCollision(new Vector2(movement.X, 0), true);
var yBlocked = collider.TryCollision(new Vector2(0, movement.Y), true);
var v = velocity.LinearVelocity;
velocity.LinearVelocity = new Vector2(xBlocked ? 0 : v.X, yBlocked ? 0 : v.Y);
if(velocity.EdgeSlide)
{
//Slide along the blockage in the non-blocked direction
var xBlocked = collider.TryCollision(new Vector2(movement.X, 0));
var yBlocked = collider.TryCollision(new Vector2(0, movement.Y));
var v = velocity.LinearVelocity;
velocity.LinearVelocity = new Vector2(xBlocked ? 0 : v.X, yBlocked ? 0 : v.Y);
}
else
{
//Stop movement entirely at first blockage
velocity.LinearVelocity = new Vector2(0, 0);
}
movement = velocity.LinearVelocity * frameTime;
}
}

View File

@@ -27,4 +27,14 @@ namespace SS14.Shared.Interfaces.GameObjects.Components
event EventHandler<BumpEventArgs> OnBump;
bool TryCollision(Vector2 offset, bool bump = false);
}
public interface ICollideSpecial
{
bool PreventCollide(ICollidable collidedwith);
}
public interface ICollideBehavior
{
void CollideWith(List<IEntity> collidedwith);
}
}

View File

@@ -1,6 +1,7 @@
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Map;
using SS14.Shared.Maths;
using System.Collections.Generic;
namespace SS14.Shared.Interfaces.Physics
{
@@ -27,9 +28,16 @@ namespace SS14.Shared.Interfaces.Physics
bool IsHardCollidable { get; }
/// <summary>
/// Called when the collidable is bumped into by someone/something
/// Called when the collidable is bumped into by someone/something
/// </summary>
void Bump(IEntity ent);
/// <param name="bumpedby"></param>
void Bumped(IEntity bumpedby);
/// <summary>
/// Called when the collidable bumps into this entity
/// </summary>
/// <param name="bumpedinto"></param>
void Bump(List<IEntity> bumpedinto);
/// <summary>
/// The map index this collidable is located upon

View File

@@ -87,9 +87,10 @@ namespace SS14.Shared.Physics
/// </summary>
/// <param name="collider">Rectangle to check for collision</param>
/// <returns></returns>
public bool TryCollide(IEntity entity, Vector2 offset, bool bump = true)
public bool TryCollide(IEntity mover, Vector2 offset, bool bump = true)
{
var collider = entity.GetComponent<ICollidableComponent>();
if (mover == null) return false;
var collider = mover.GetComponent<ICollidableComponent>();
if (collider == null) return false;
var colliderAABB = collider.WorldAABB;
@@ -116,16 +117,37 @@ namespace SS14.Shared.Physics
aabb.Collidable.WorldAABB.Intersects(colliderAABB) &&
aabb.Collidable.MapID == collider.MapID); //try all of the AABBs against the target rect.
//See if our collision will be overriden by a component
List<ICollideSpecial> collisionmodifiers = mover.GetComponents<ICollideSpecial>().ToList();
List<IEntity> collidedwith = new List<IEntity>();
//try all of the AABBs against the target rect.
var collided = false;
foreach (var aabb in bounds)
{
if (aabb.Collidable.IsHardCollidable) //If the collider is supposed to prevent movement
//Provides component level overrides for collision behavior based on the entity we are trying to collide with
var preventcollision = false;
for (var i = 0; i < collisionmodifiers.Count; i++)
{
preventcollision |= collisionmodifiers[i].PreventCollide(aabb.Collidable);
}
if (preventcollision) //We were prevented, bail
continue;
if (aabb.Collidable.IsHardCollidable) //If the collider is meant to be collidable at the moment
{
collided = true;
if (bump) aabb.Collidable.Bump(entity);
if (bump)
{
aabb.Collidable.Bumped(mover);
collidedwith.Add(aabb.Collidable.Owner);
}
}
}
collider.Bump(collidedwith);
//TODO: This needs multi-grid support.
return collided;
}