From 6fc9568137601fac49efbb908837533f4212cf1f Mon Sep 17 00:00:00 2001 From: Zenny Date: Wed, 4 Sep 2024 18:31:35 -0700 Subject: [PATCH] Random patrol --- src/enemy/Enemy.cs | 15 +++++++++++++++ .../floating_enemy/FloatingEnemy.tscn | 5 +++++ src/enemy/state/EnemyLogic.Input.cs | 7 ++++++- .../state/states/EnemyLogic.State.Idle.cs | 18 +++++++++++++++++- 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/enemy/Enemy.cs b/src/enemy/Enemy.cs index 9a602774..482f726c 100644 --- a/src/enemy/Enemy.cs +++ b/src/enemy/Enemy.cs @@ -47,6 +47,8 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide [Node] public Area3D LineOfSight { get; set; } = default!; + [Node] public Timer PatrolTimer { get; set; } = default!; + public void Setup() { EnemyLogic = new EnemyLogic(); @@ -60,6 +62,19 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide CurrentHP = new AutoProp(EnemyStatInfo.MaximumHP); CurrentHP.Sync += OnHPChanged; LineOfSight.BodyEntered += LineOfSight_BodyEntered; + PatrolTimer.Timeout += OnPatrolTimeout; + var rng = new RandomNumberGenerator(); + rng.Randomize(); + PatrolTimer.WaitTime = rng.RandfRange(7.0f, 15.0f); + } + + private void OnPatrolTimeout() + { + var rng = new RandomNumberGenerator(); + rng.Randomize(); + var randomizedSpot = new Vector3(rng.RandfRange(-3.0f, 3.0f), 0, rng.RandfRange(-3.0f, 3.0f)); + EnemyLogic.Input(new EnemyLogic.Input.PatrolToRandomSpot(GlobalPosition + randomizedSpot)); + PatrolTimer.WaitTime = rng.RandfRange(7.0f, 15.0f); } private void LineOfSight_BodyEntered(Node3D body) diff --git a/src/enemy/enemy_types/floating_enemy/FloatingEnemy.tscn b/src/enemy/enemy_types/floating_enemy/FloatingEnemy.tscn index 2f6afcfb..a100d3f4 100644 --- a/src/enemy/enemy_types/floating_enemy/FloatingEnemy.tscn +++ b/src/enemy/enemy_types/floating_enemy/FloatingEnemy.tscn @@ -139,3 +139,8 @@ collision_mask = 2 [node name="CollisionShape3D" type="CollisionShape3D" parent="LineOfSight"] transform = Transform3D(1, 0, 0, 0, 0.0745088, 0.99722, 0, -0.99722, 0.0745088, 0, 0, -1.46944) shape = SubResource("CylinderShape3D_jbgmx") + +[node name="PatrolTimer" type="Timer" parent="."] +unique_name_in_owner = true +wait_time = 10.0 +autostart = true diff --git a/src/enemy/state/EnemyLogic.Input.cs b/src/enemy/state/EnemyLogic.Input.cs index d5feb16f..c3d0fd62 100644 --- a/src/enemy/state/EnemyLogic.Input.cs +++ b/src/enemy/state/EnemyLogic.Input.cs @@ -1,4 +1,7 @@ -namespace GameJamDungeon + +using Godot; + +namespace GameJamDungeon { public partial class EnemyLogic { @@ -13,6 +16,8 @@ public readonly record struct HitByPlayer(double Damage); public readonly record struct Killed(); + + public readonly record struct PatrolToRandomSpot(Vector3 PatrolTarget); } } } diff --git a/src/enemy/state/states/EnemyLogic.State.Idle.cs b/src/enemy/state/states/EnemyLogic.State.Idle.cs index 8d6f7c77..74564941 100644 --- a/src/enemy/state/states/EnemyLogic.State.Idle.cs +++ b/src/enemy/state/states/EnemyLogic.State.Idle.cs @@ -8,7 +8,7 @@ public partial class EnemyLogic public partial record State { [Meta, Id("enemy_logic_state_idle")] - public partial record Idle : Alive, IGet, IGet + public partial record Idle : Alive, IGet, IGet, IGet { public Transition On(in Input.Alerted _) { @@ -20,6 +20,22 @@ public partial class EnemyLogic var delta = input.Delta; var gameRepo = Get(); var enemy = Get(); + + var nextPosition = enemy.NavAgent.GetNextPathPosition(); + var lookAtPos = enemy.NavAgent.GetNextPathPosition(); + + var direction = enemy.NavAgent.GetNextPathPosition() - enemy.GlobalPosition; + enemy.Velocity = enemy.Velocity.MoveToward(direction.Normalized() * 0.01f, (float)delta); + + Output(new Output.MovementComputed(enemy.Velocity)); + return ToSelf(); + } + + public Transition On(in Input.PatrolToRandomSpot input) + { + var enemy = Get(); + enemy.NavAgent.TargetPosition = input.PatrolTarget; + enemy.LookAt(new Vector3(input.PatrolTarget.X, enemy.GlobalPosition.Y, input.PatrolTarget.Z), Vector3.Up); return ToSelf(); } }