mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 11:15:33 +00:00
115 lines
No EOL
3.9 KiB
C#
115 lines
No EOL
3.9 KiB
C#
using Cirno.Scripts.Enums;
|
|
using Godot;
|
|
using Godot.Collections;
|
|
|
|
namespace Cirno.Scripts.Components.FSM.Enemy;
|
|
|
|
public partial class PlayerDetectionModule : Area2D
|
|
{
|
|
[Signal]
|
|
public delegate void PlayerInRangeEventHandler();
|
|
|
|
[Signal]
|
|
public delegate void PlayerOutOfRangeEventHandler();
|
|
|
|
[Export(PropertyHint.Layers2DPhysics)]
|
|
public uint ObstaclesCollisionMask { get; private set; }
|
|
|
|
public Vector2? LastKnownPlayerPosition { get; set; }
|
|
|
|
//public bool PlayerInActiveArea { get; private set; }
|
|
private CollisionShape2D _collisionShape2D;
|
|
|
|
private bool _initialized = false;
|
|
public override void _Ready()
|
|
{
|
|
CallDeferred(MethodName.Initialize);
|
|
}
|
|
|
|
private void Initialize()
|
|
{
|
|
_initialized = true;
|
|
}
|
|
|
|
public void SetRange(float range)
|
|
{
|
|
_collisionShape2D ??= this.GetNode<CollisionShape2D>("CollisionShape2D");
|
|
if (_collisionShape2D.Shape is CircleShape2D shape2D)
|
|
{
|
|
shape2D.Radius = range;
|
|
}
|
|
}
|
|
|
|
public bool IsPlayerInRange(float range)
|
|
{
|
|
if (!_initialized) return false;
|
|
if (GameManager.Instance is null) return false;
|
|
|
|
if (!GameManager.Instance.PlayerPosition.HasValue)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return this.GlobalPosition.DistanceTo(GameManager.Instance.PlayerPosition.Value) <= range;
|
|
}
|
|
|
|
public bool IsPlayerInSight()
|
|
{
|
|
if (!_initialized) return false;
|
|
if (GameManager.Instance is null) return false;
|
|
//if (_cachedPlayer == null) return false;
|
|
if (!GameManager.Instance.PlayerPosition.HasValue) return false;
|
|
|
|
var found = HasLineOfSight(this.GlobalPosition, GameManager.Instance.PlayerPosition.Value);
|
|
|
|
// var spaceState = GetWorld2D().DirectSpaceState;
|
|
//
|
|
// // It needs to use its own collision mask because it's detecting obstacles rather than the player
|
|
// var query = PhysicsRayQueryParameters2D.Create(this.GlobalPosition, GameManager.Instance.PlayerPosition.Value, ObstaclesCollisionMask,
|
|
// [GetRid()]);
|
|
// //query.CollideWithBodies = true;
|
|
// //query.CollideWithAreas = true;
|
|
// // var query = PhysicsRayQueryParameters2D.Create(this.GlobalPosition, _cachedPlayer.GlobalPosition, CollisionMask, new Array<Rid> { GetRid() });
|
|
// var result = spaceState.IntersectRay(query);
|
|
//
|
|
// // If count is 0 then the player is in sight, otherwise there is level geometry in the way
|
|
// var found = result.Count == 0;
|
|
if (found)
|
|
{
|
|
LastKnownPlayerPosition = GameManager.Instance.PlayerPosition;
|
|
}
|
|
return found;
|
|
}
|
|
|
|
private void _on_area_entered(Area2D area)
|
|
{
|
|
if (area is not InteractionController player) return;
|
|
EmitSignal(SignalName.PlayerInRange);
|
|
//PlayerInActiveArea = true;
|
|
}
|
|
|
|
private void _on_area_exited(Area2D area)
|
|
{
|
|
if (area is not InteractionController player) return;
|
|
EmitSignal(SignalName.PlayerOutOfRange);
|
|
//PlayerInActiveArea = false;
|
|
}
|
|
|
|
public bool HasLineOfSight(Vector2 startPos, Vector2 endPos)
|
|
{
|
|
var spaceState = GetWorld2D().DirectSpaceState;
|
|
|
|
// It needs to use its own collision mask because it's detecting obstacles rather than the player
|
|
var query = PhysicsRayQueryParameters2D.Create(startPos, endPos, ObstaclesCollisionMask,
|
|
[GetRid()]);
|
|
//query.CollideWithBodies = true;
|
|
//query.CollideWithAreas = true;
|
|
// var query = PhysicsRayQueryParameters2D.Create(this.GlobalPosition, _cachedPlayer.GlobalPosition, CollisionMask, new Array<Rid> { GetRid() });
|
|
var result = spaceState.IntersectRay(query);
|
|
|
|
// If count is 0 then the player is in sight, otherwise there is level geometry in the way
|
|
var found = result.Count == 0;
|
|
|
|
return found;
|
|
}
|
|
} |