it's michael, what's michael

This commit is contained in:
2024-09-15 02:17:40 -07:00
parent 096bcd6168
commit 7680ab8b45
313 changed files with 6913 additions and 1760 deletions

View File

@@ -2,10 +2,7 @@ using Chickensoft.AutoInject;
using Chickensoft.Collections;
using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection;
using Chickensoft.LogicBlocks;
using Godot;
using System;
using System.Linq;
namespace GameJamDungeon;
@@ -21,8 +18,6 @@ public interface IEnemy : ICharacterBody3D
public Area3D LineOfSight { get; set; }
public AnimationPlayer AnimationPlayer { get; set; }
public Timer AttackTimer { get; set; }
}
@@ -56,10 +51,16 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
[Node] public Timer AttackTimer { get; set; } = default!;
[Node] public AnimationPlayer AnimationPlayer { get; set; } = default!;
[Node] public AnimatedSprite3D AnimatedSprite { get; set; } = default!;
[Node] public RayCast3D Raycast { get; set; } = default!;
private const string IDLE_FORWARD = "idle_front_walk";
private const string IDLE_LEFT = "idle_left_walk";
private const string IDLE_BACK = "idle_back_walk";
private const string ATTACK_FORWARD = "attack";
public void Setup()
{
EnemyLogic = new EnemyLogic();
@@ -68,18 +69,6 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
EnemyLogic.Set(GameRepo);
}
public void Initialize()
{
CurrentHP = new AutoProp<double>(EnemyStatResource.MaximumHP);
CurrentHP.Sync += OnHPChanged;
LineOfSight.BodyEntered += LineOfSight_BodyEntered;
PatrolTimer.Timeout += OnPatrolTimeout;
AttackTimer.Timeout += OnAttackTimeout;
var rng = new RandomNumberGenerator();
rng.Randomize();
PatrolTimer.WaitTime = rng.RandfRange(7.0f, 15.0f);
}
private void OnPatrolTimeout()
{
var rng = new RandomNumberGenerator();
@@ -103,20 +92,20 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
private void LineOfSight_BodyEntered(Node3D body)
{
var overlappingBodies = LineOfSight.GetOverlappingBodies();
foreach (var overlap in overlappingBodies)
{
Raycast.LookAt(GameRepo.PlayerGlobalPosition.Value, Vector3.Up);
Raycast.ForceRaycastUpdate();
if (Raycast.IsColliding())
{
var collider = Raycast.GetCollider();
if (collider is IPlayer player)
{
Raycast.DebugShapeCustomColor = Color.FromString("Purple", Colors.Purple);
EnemyLogic.Input(new EnemyLogic.Input.Alerted());
}
}
}
//foreach (var overlap in overlappingBodies)
//{
// Raycast.LookAt(GameRepo.PlayerGlobalPosition.Value, Vector3.Up);
// Raycast.ForceRaycastUpdate();
// if (Raycast.IsColliding())
// {
// var collider = Raycast.GetCollider();
// if (collider is IPlayer player)
// {
// Raycast.DebugShapeCustomColor = Color.FromString("Purple", Colors.Purple);
// EnemyLogic.Input(new EnemyLogic.Input.Alerted());
// }
// }
//}
}
public void OnResolved()
@@ -126,12 +115,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
EnemyBinding
.Handle((in EnemyLogic.Output.MovementComputed output) =>
{
var spriteNode = GetChildren().OfType<AnimatedSprite3D>();
if (spriteNode.Any())
PlayMovementAnimations(spriteNode.Single(), Velocity);
MoveAndCollide(output.Velocity);
MoveAndSlide();
})
.Handle((in EnemyLogic.Output.Die output) =>
{
@@ -139,6 +123,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
})
.Handle((in EnemyLogic.Output.HitByPlayer output) =>
{
// TODO: Make this an event to notify game that player hit someone
if (GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.SelfDamage))
GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.CurrentHP.Value - 5);
});
@@ -146,31 +131,48 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
this.Provide();
EnemyLogic.Start();
CurrentHP = new AutoProp<double>(EnemyStatResource.MaximumHP);
CurrentHP.Sync += OnHPChanged;
LineOfSight.BodyEntered += LineOfSight_BodyEntered;
PatrolTimer.Timeout += OnPatrolTimeout;
AttackTimer.Timeout += OnAttackTimeout;
var rng = new RandomNumberGenerator();
rng.Randomize();
PatrolTimer.WaitTime = rng.RandfRange(7.0f, 15.0f);
}
public void PlayMovementAnimations(AnimatedSprite3D sprite, Vector3 velocity)
private void RotateEnemy(Vector3 cameraDirection)
{
if (sprite != null && velocity.Length() > 0.2f)
{
var lookdir = (GlobalPosition).Normalized();
var sign = lookdir.Sign();
if (lookdir.MaxAxisIndex() == Vector3.Axis.X && sign.X == 1)
sprite.Play("walk_right");
if (lookdir.MaxAxisIndex() == Vector3.Axis.X && sign.X == -1)
sprite.Play("walk_left");
if (lookdir.MaxAxisIndex() == Vector3.Axis.Z && sign.Z == 1)
sprite.Play("walk_forward");
if (lookdir.MaxAxisIndex() == Vector3.Axis.Z && sign.Z == -1)
sprite.Play("walk_backward");
}
if (sprite != null && velocity.IsZeroApprox())
sprite.Stop();
}
var rotateUpperThreshold = 0.85f;
var rotateLowerThreshold = 0.3f;
var enemyForwardDirection = GlobalTransform.Basis.Z;
var enemyLeftDirection = GlobalTransform.Basis.X;
var leftDotProduct = enemyLeftDirection.Dot(cameraDirection);
var forwardDotProduct = enemyForwardDirection.Dot(cameraDirection);
// Check if forward facing. If the dot product is -1, the enemy is facing the camera.
if (forwardDotProduct < -rotateUpperThreshold)
AnimatedSprite.Play("idle_front_walk");
// Check if backward facing. If the dot product is 1, the enemy is facing the same direction as the camera.
else if (forwardDotProduct > rotateUpperThreshold)
AnimatedSprite.Play("idle_back_walk");
else
{
// If the dot product of the perpendicular dot product is positive (up to 1), the enemy is facing to the left (since it's mirrored).
AnimatedSprite.FlipH = leftDotProduct > 0;
// Check is side facing. If the dot product is close to zero in the positive or negative direction, its close to the threshold for turning.
if (Mathf.Abs(forwardDotProduct) < rotateLowerThreshold)
AnimatedSprite.Play("idle_left_walk");
}
}
public void OnPhysicsProcess(double delta)
{
EnemyLogic.Input(new EnemyLogic.Input.PhysicsTick(delta));
RotateEnemy(-GameRepo.PlayerGlobalTransform.Value.Basis.Z);
}
public void OnPlayerHitboxEntered(Area3D body)
@@ -195,7 +197,9 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
private void OnHPChanged(double newHP)
{
if (newHP <= 0)
{
EnemyLogic.Input(new EnemyLogic.Input.Killed());
}
}
public void OnReady()