73 lines
2.0 KiB
C#
73 lines
2.0 KiB
C#
using Chickensoft.AutoInject;
|
|
using Chickensoft.Introspection;
|
|
using Godot;
|
|
using Zennysoft.Ma.Adapter;
|
|
|
|
namespace Zennysoft.Game.Ma;
|
|
|
|
[Meta(typeof(IAutoNode))]
|
|
public abstract partial class Enemy2D : Enemy
|
|
{
|
|
public override void _Notification(int what) => this.Notify(what);
|
|
|
|
[Node] private Area3D LineOfSight { get; set; } = default!;
|
|
|
|
public override IEnemyModelView EnemyModelView => _enemyModelView;
|
|
|
|
[Node] private EnemyModelView2D _enemyModelView { get; set; } = default!;
|
|
|
|
private Vector3 _previousPosition = Vector3.Zero;
|
|
|
|
public void OnEnterTree()
|
|
{
|
|
LineOfSight.BodyEntered += LineOfSight_BodyEntered;
|
|
}
|
|
|
|
public override void _PhysicsProcess(double delta)
|
|
{
|
|
_enemyModelView.SetCurrentDirection(GlobalBasis, -_player.GlobalBasis.Z);
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
if (_enemyLogic.Value is EnemyLogic.State.FollowPlayer || _enemyLogic.Value is EnemyLogic.State.Patrolling)
|
|
{
|
|
var velocity = (GlobalPosition - _previousPosition) / (float)delta;
|
|
if (velocity.IsZeroApprox())
|
|
_enemyLogic.Input(new EnemyLogic.Input.Idle());
|
|
else
|
|
_enemyLogic.Input(new EnemyLogic.Input.Move());
|
|
_previousPosition = GlobalPosition;
|
|
}
|
|
}
|
|
|
|
protected void PlayerDetector_BodyEntered(Node3D node)
|
|
{
|
|
if (node is IPlayer)
|
|
_enemyLogic.Input(new EnemyLogic.Input.ReachedPlayer());
|
|
}
|
|
|
|
protected void PlayerDetector_BodyExited(Node3D node)
|
|
{
|
|
if (node is IPlayer)
|
|
_enemyLogic.Input(new EnemyLogic.Input.Follow());
|
|
}
|
|
|
|
protected void OnVelocityComputed(Vector3 safeVelocity)
|
|
{
|
|
Velocity = safeVelocity;
|
|
LookAtTarget(safeVelocity);
|
|
MoveAndSlide();
|
|
}
|
|
|
|
protected void EngagePlayerBehavior_TakeAction() => PerformAction();
|
|
|
|
protected void EngagePlayerBehavior_AcquireTarget() => LookAt(new Vector3(_player.GlobalPosition.X, GlobalPosition.Y, _player.GlobalPosition.Z), Vector3.Up, true);
|
|
|
|
private void LineOfSight_BodyEntered(Node3D body)
|
|
{
|
|
if (body is IPlayer)
|
|
_enemyLogic.Input(new EnemyLogic.Input.Alert());
|
|
}
|
|
}
|