using Godot; using System.Collections; using System.Collections.Generic; using Godot.Collections; namespace Rokojori { [Tool] [GlobalClass] public abstract partial class Caster:Node3D { [Export] public Selector includeSelector; [Export] public Selector excludeSelector; [Export] public bool sortByPointerPriority; public int NumColliders() { return collisions == null ? 0 : numCollisions; } public Node GetCollider( int index ) { return collisions[ index ].collider; } public Vector3 GetCollisionNormal( int index ) { return collisions[ index ].normal; } public Vector3 GetCollisionPosition( int index ) { return collisions[ index ].position; } public Shape3D GetCollisionShape( int index ) { return collisions[ index ].shape; } ValueSorter singleSorter; MultiValueSorter multiSorter; protected List collisions = new List(); protected int numCollisions = 0; protected bool IsSelected( Node node ) { if ( includeSelector != null && ! includeSelector.Selects( node ) ) { return false; } if ( excludeSelector != null && excludeSelector.Selects( node ) ) { return false; } return true; } protected bool IsSelected( CollisionData cd ) { return IsSelected( cd.collider ); } protected void SortCollisions() { if ( ! sortByPointerPriority ) { if ( singleSorter == null ) { singleSorter = ValueSorter.Create( cd => GetDistance( cd ) ); } singleSorter.Sort( 0, numCollisions, collisions ); } else { if ( multiSorter == null ) { multiSorter = MultiValueSorter.Create( cd => GetPointablePriority( cd ), cd => GetDistance( cd ) ); } multiSorter.Sort( 0, numCollisions, collisions ); } } protected float GetPointablePriority( CollisionData cd ) { float priority = 0; var pointable = Nodes.Find( cd.collider ); if ( pointable != null ) { priority = pointable.pointingPriority; } return priority; } protected float GetDistance( CollisionData cd ) { return ( cd.position - GlobalPosition ).Length(); } } }