Refactor Player class to use components, also use components in Enemy class types and fiddle with boss structure
This commit is contained in:
@@ -3,6 +3,7 @@ using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Zennysoft.Game.Implementation.Components;
|
||||
using Zennysoft.Ma.Adapter;
|
||||
using Zennysoft.Ma.Adapter.Entity;
|
||||
|
||||
@@ -25,17 +26,35 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
||||
[Dependency] protected IPlayer _player => this.DependOn(() => GetParent().GetChildren().OfType<IPlayer>().Single());
|
||||
#endregion
|
||||
|
||||
#region Node Dependencies
|
||||
[Node] private Area3D LineOfSight { get; set; } = default!;
|
||||
[Node] private RayCast3D Raycast { get; set; } = default!;
|
||||
public HealthComponent HealthComponent { get; private set; }
|
||||
|
||||
[Node] private HealthComponent _healthComponent { get; set; } = default!;
|
||||
#endregion
|
||||
public AttackComponent AttackComponent { get; private set; }
|
||||
|
||||
public DefenseComponent DefenseComponent { get; private set; }
|
||||
|
||||
public virtual IEnemyModelView EnemyModelView { get; set; } = default!;
|
||||
|
||||
public Vector3 TargetPosition { get; private set; }
|
||||
|
||||
[ExportGroup("Enemy Stats")]
|
||||
[Export] public int InitialHP { get; set; } = 50;
|
||||
|
||||
[Export] public int InitialAttack { get; set; } = 8;
|
||||
|
||||
[Export] public int InitialDefense { get; set; } = 8;
|
||||
|
||||
[Export] public int ExpGiven { get; set; } = 10;
|
||||
|
||||
public Enemy()
|
||||
{
|
||||
HealthComponent = new HealthComponent(InitialHP);
|
||||
HealthComponent.HealthReachedZero += Die;
|
||||
HealthComponent.DamageTaken += TakeHit;
|
||||
|
||||
AttackComponent = new AttackComponent(InitialAttack);
|
||||
DefenseComponent = new DefenseComponent(InitialDefense);
|
||||
}
|
||||
|
||||
#region Godot methods
|
||||
public void Setup()
|
||||
{
|
||||
@@ -43,8 +62,6 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
||||
_enemyLogic.Set(this as IEnemy);
|
||||
_enemyLogic.Set(_player);
|
||||
SetPhysicsProcess(true);
|
||||
_healthComponent.HealthReachedZero += Die;
|
||||
_healthComponent.HealthLowered += TakeHit;
|
||||
EnemyModelView.HitPlayer += EnemyModelView_HitPlayer;
|
||||
}
|
||||
|
||||
@@ -73,7 +90,6 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
||||
this.Provide();
|
||||
|
||||
_enemyLogic.Start();
|
||||
LineOfSight.BodyEntered += LineOfSight_BodyEntered;
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -124,12 +140,12 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
||||
public virtual void TakeDamage(int damage)
|
||||
{
|
||||
GD.Print($"Enemy Hit for {damage} damage.");
|
||||
_healthComponent.CurrentHP.OnNext(_healthComponent.CurrentHP.Value - damage);
|
||||
HealthComponent.Damage(damage);
|
||||
}
|
||||
|
||||
private void EnemyModelView_HitPlayer()
|
||||
private void EnemyModelView_HitPlayer(object sender, System.EventArgs e)
|
||||
{
|
||||
_player.TakeDamage(new Damage(30, ElementType.None, false, false, false));
|
||||
_player.TakeDamage(new Damage(AttackComponent.TotalAttack, ElementType.None, false, false, false));
|
||||
}
|
||||
|
||||
public virtual void TakeHit()
|
||||
@@ -141,8 +157,8 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
||||
public virtual void Die()
|
||||
{
|
||||
SetPhysicsProcess(false);
|
||||
_healthComponent.CurrentHP.OnCompleted();
|
||||
_enemyLogic.Input(new EnemyLogic.Input.Defeated());
|
||||
_player.ExperiencePointsComponent.Gain(ExpGiven);
|
||||
EnemyModelView.PlayDeathAnimation();
|
||||
var tweener = CreateTween();
|
||||
tweener.TweenInterval(1.0f);
|
||||
@@ -160,23 +176,6 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
||||
return null;
|
||||
}
|
||||
|
||||
private void LineOfSight_BodyEntered(Node3D body)
|
||||
{
|
||||
var overlappingBodies = LineOfSight.GetOverlappingBodies();
|
||||
foreach (var _ in overlappingBodies)
|
||||
{
|
||||
if (Raycast.GlobalPosition != _player.CurrentPosition)
|
||||
Raycast.LookAt(_player.CurrentPosition, Vector3.Up);
|
||||
Raycast.ForceRaycastUpdate();
|
||||
if (Raycast.IsColliding())
|
||||
{
|
||||
var collider = Raycast.GetCollider();
|
||||
if (collider is IPlayer)
|
||||
_enemyLogic.Input(new EnemyLogic.Input.Follow());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnExitTree()
|
||||
{
|
||||
_enemyLogic.Stop();
|
||||
|
||||
Reference in New Issue
Block a user