116 lines
3.3 KiB
C#
116 lines
3.3 KiB
C#
using Havok;
|
|
using Sandbox.Engine.Physics;
|
|
using Sandbox.Game.Entities;
|
|
using VRage;
|
|
using VRage.Game.Components;
|
|
using VRage.Game.Entity;
|
|
using VRage.ObjectBuilders;
|
|
using VRageMath;
|
|
|
|
namespace AreaJumpDepleter.Utils;
|
|
|
|
public class TriggerArea : IDisposable, IEquatable<TriggerArea>
|
|
{
|
|
private Dummy? _entity;
|
|
public BoundingSphere Sphere { get; }
|
|
|
|
public event EventHandler<MyEntity>? EntityEntered;
|
|
public event EventHandler<MyEntity>? EntityLeft;
|
|
|
|
public TriggerArea(BoundingSphere sphere)
|
|
{
|
|
Sphere = sphere;
|
|
}
|
|
|
|
public void Create()
|
|
{
|
|
_entity = new Dummy(Sphere, EnterHandler, ExitHandler);
|
|
_entity.Init(null);
|
|
MyEntities.Add(_entity);
|
|
}
|
|
|
|
private void ExitHandler(MyEntity entity)
|
|
{
|
|
EntityEntered?.Invoke(this, entity);
|
|
}
|
|
|
|
private void EnterHandler(MyEntity entity)
|
|
{
|
|
EntityLeft?.Invoke(this, entity);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_entity != null)
|
|
MyEntities.Close(_entity);
|
|
}
|
|
|
|
public bool Equals(TriggerArea? other)
|
|
{
|
|
if (ReferenceEquals(null, other)) return false;
|
|
if (ReferenceEquals(this, other)) return true;
|
|
return Sphere.Equals(other.Sphere);
|
|
}
|
|
|
|
public override bool Equals(object? obj)
|
|
{
|
|
if (ReferenceEquals(null, obj)) return false;
|
|
if (ReferenceEquals(this, obj)) return true;
|
|
if (obj.GetType() != this.GetType()) return false;
|
|
return Equals((TriggerArea)obj);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
return Sphere.GetHashCode();
|
|
}
|
|
|
|
private class Dummy : MyEntity
|
|
{
|
|
private readonly BoundingSphere _sphere;
|
|
private readonly Action<MyEntity> _enterHandler;
|
|
private readonly Action<MyEntity> _exitHandler;
|
|
|
|
public Dummy(BoundingSphere sphere, Action<MyEntity> enterHandler, Action<MyEntity> exitHandler)
|
|
{
|
|
_sphere = sphere;
|
|
_enterHandler = enterHandler;
|
|
_exitHandler = exitHandler;
|
|
}
|
|
|
|
public override void Init(MyObjectBuilder_EntityBase? objectBuilder)
|
|
{
|
|
base.Init(objectBuilder);
|
|
PositionComp.LocalAABB = BoundingBox.CreateFromSphere(_sphere);
|
|
|
|
Physics = new MyPhysicsBody(this, RigidBodyFlag.RBF_STATIC);
|
|
Physics.IsPhantom = true;
|
|
|
|
var phantom = new HkPhantomCallbackShape(EnterCallback, LeaveCallback);
|
|
var shape = new HkBvShape(new HkSphereShape(_sphere.Radius), phantom, HkReferencePolicy.TakeOwnership);
|
|
|
|
((MyPhysicsBody)Physics).CreateFromCollisionObject(shape, _sphere.Center, MatrixD.Identity);
|
|
shape.Base.RemoveReference();
|
|
|
|
Physics.Enabled = true;
|
|
|
|
BoundingSphereD sphere = _sphere;
|
|
foreach (var entity in MyEntities.GetTopMostEntitiesInSphere(ref sphere))
|
|
{
|
|
_enterHandler(entity);
|
|
}
|
|
}
|
|
|
|
private void LeaveCallback(HkPhantomCallbackShape shape, HkRigidBody body)
|
|
{
|
|
if (body.GetSingleEntity() is MyEntity entity)
|
|
_exitHandler(entity);
|
|
}
|
|
|
|
private void EnterCallback(HkPhantomCallbackShape shape, HkRigidBody body)
|
|
{
|
|
if (body.GetSingleEntity() is MyEntity entity)
|
|
_enterHandler(entity);
|
|
}
|
|
}
|
|
} |