Rough collision avoidance implementation using pre-generated floors (just floor 01)

This commit is contained in:
2025-02-24 21:48:40 -08:00
parent 45f1f5df01
commit 22a930358c
26 changed files with 398 additions and 128 deletions

View File

@@ -2,6 +2,9 @@ using Chickensoft.AutoInject;
using Chickensoft.Collections;
using Chickensoft.Introspection;
using Godot;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace GameJamDungeon;
@@ -22,7 +25,7 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide<IEnemyLogic>
[Dependency] IGameEventDepot GameEventDepot => this.DependOn<IGameEventDepot>();
[Dependency] protected IPlayer Player => this.DependOn<IPlayer>();
[Dependency] protected IPlayer Player => this.DependOn<IPlayer>(() => GetParent().GetChildren().OfType<IPlayer>().Single());
#endregion
#region Exports
@@ -53,12 +56,51 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide<IEnemyLogic>
private Vector3 _knockbackDirection = Vector3.Zero;
private Vector3 _currentTarget = Vector3.Zero;
private Timer _thinkTimer;
public void Setup()
{
_enemyLogic = new EnemyLogic();
_enemyLogic.Set(_enemyStatResource);
_enemyLogic.Set(this as IEnemy);
_enemyLogic.Set(Player);
NavAgent.VelocityComputed += NavAgent_VelocityComputed;
NavAgent.TargetReached += NavAgent_TargetReached;
_thinkTimer = new Timer
{
WaitTime = 1f
};
AddChild(_thinkTimer);
_thinkTimer.Timeout += NavAgent_TargetReached;
_thinkTimer.Start();
}
private void NavAgent_TargetReached()
{
NavAgent.TargetPosition = _currentTarget;
}
private void NavAgent_VelocityComputed(Vector3 safeVelocity)
{
if (CurrentHP <= 0)
return;
var lookDir = GlobalPosition - safeVelocity;
var leveledLookDir = new Vector3(lookDir.X, Position.Y, lookDir.Z);
if (leveledLookDir.DistanceTo(GlobalPosition) > 0.2f)
LookAt(new Vector3(lookDir.X, Position.Y, lookDir.Z), Vector3.Up);
_knockbackStrength = _knockbackStrength * 0.9f;
MoveAndCollide(safeVelocity + (_knockbackDirection * _knockbackStrength));
}
public void SetTarget(Vector3 target)
{
Task.Delay(TimeSpan.FromSeconds(1.5)).ContinueWith(_ => _currentTarget = new Vector3(target.X, -1.75f, target.Z));
}
public void TakeDamage(double damage, ElementType elementType, bool isCriticalHit = false, bool ignoreDefense = false, bool ignoreElementalResistance = false)
@@ -80,26 +122,29 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide<IEnemyLogic>
EnemyModelView.PlayHitAnimation();
_enemyLogic.Input(new EnemyLogic.Input.Alerted());
if (Player.EquippedWeapon.Value.WeaponTags.Contains(WeaponTag.SelfDamage))
Player.Stats.SetCurrentHP(Player.Stats.CurrentHP.Value - 5);
}
}
public void MoveToLocation(Vector3 target, float delta)
public override void _PhysicsProcess(double delta)
{
NavAgent.TargetPosition = target;
var targetPosition = NavAgent.GetNextPathPosition();
if (CurrentHP <= 0)
return;
var velocity = (targetPosition - GlobalTransform.Origin).Normalized() * 2f * delta;
var lookAtDir = GlobalTransform.Origin - velocity;
var lookAtPosition = new Vector3(lookAtDir.X, GlobalPosition.Y, lookAtDir.Z);
var nextPathPosition = NavAgent.GetNextPathPosition();
var movementDelta = 2f * (float)delta;
if (GlobalPosition.DistanceTo(target) > 1.0f && !velocity.IsEqualApprox(Vector3.Zero) && !Position.IsEqualApprox(lookAtPosition))
LookAt(lookAtPosition + new Vector3(0.001f, 0.001f, 0.001f), Vector3.Up);
var newVelocity = GlobalPosition.DirectionTo(nextPathPosition) * movementDelta;
if (NavAgent.AvoidanceEnabled)
NavAgent.Velocity = newVelocity;
else
NavAgent_VelocityComputed(newVelocity);
var isWalking = _enemyLogic.Value is EnemyLogic.State.Patrolling or EnemyLogic.State.FollowPlayer;
EnemyModelView.RotateModel(GlobalTransform.Basis, -Player.CurrentBasis.Z, isWalking);
_knockbackStrength = _knockbackStrength * 0.9f;
MoveAndCollide(velocity + (_knockbackDirection * _knockbackStrength));
}
public void Knockback(float impulse, Vector3 direction)