using System;
using System.Collections.Generic;
using System.Linq;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.Interfaces.Physics;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
namespace Robust.Client.GameObjects
{
public class CollidableComponent : Component, ICollidableComponent
{
#pragma warning disable 649
[Dependency] private readonly IPhysicsManager _physicsManager;
#pragma warning restore 649
private bool _collisionIsActuallyEnabled;
private bool _collisionEnabled;
///
public override string Name => "Collidable";
///
public override uint? NetID => NetIDs.COLLIDABLE;
///
public override Type StateType => typeof(CollidableComponentState);
///
Box2 ICollidable.WorldAABB => Owner.GetComponent().WorldAABB;
///
Box2 ICollidable.AABB => Owner.GetComponent().AABB;
///
public MapId MapID => Owner.Transform.MapID;
///
void ICollidable.Bumped(IEntity bumpedby)
{
SendMessage(new BumpedEntMsg(bumpedby));
}
///
void ICollidable.Bump(List bumpedinto)
{
var collidecomponents = Owner.GetAllComponents().ToList();
for (var i = 0; i < collidecomponents.Count; i++)
{
collidecomponents[i].CollideWith(bumpedinto);
}
}
///
public bool CollisionEnabled
{
get => _collisionEnabled;
set
{
if (value == _collisionEnabled)
{
return;
}
_collisionEnabled = value;
if (value)
{
EnableCollision();
}
else
{
DisableCollision();
}
}
}
///
public bool IsHardCollidable { get; set; }
///
public int CollisionLayer { get; set; }
///
public int CollisionMask { get; set; }
///
/// gets the AABB from the sprite component and sends it to the CollisionManager.
///
public override void Initialize()
{
base.Initialize();
if (_collisionEnabled && !_collisionIsActuallyEnabled)
{
_physicsManager.AddCollidable(this);
_collisionIsActuallyEnabled = true;
}
}
///
/// removes the AABB from the CollisionManager.
///
public override void Shutdown()
{
if (_collisionEnabled)
{
_physicsManager.RemoveCollidable(this);
}
base.Shutdown();
}
///
public override void HandleComponentState(ComponentState curState, ComponentState nextState)
{
if (curState == null)
return;
var newState = (CollidableComponentState) curState;
// edge triggered
if (newState.CollisionEnabled == _collisionEnabled)
return;
if (newState.CollisionEnabled)
EnableCollision();
else
DisableCollision();
}
///
public bool TryCollision(Vector2 offset, bool bump = false)
{
return _physicsManager.TryCollide(Owner, offset, bump);
}
///
/// Enables collidable
///
private void EnableCollision()
{
_collisionEnabled = true;
_collisionIsActuallyEnabled = true;
_physicsManager.AddCollidable(this);
}
///
/// Disables Collidable
///
private void DisableCollision()
{
_collisionEnabled = false;
_collisionIsActuallyEnabled = false;
_physicsManager.RemoveCollidable(this);
}
}
}