Revamp boss logic

This commit is contained in:
2025-03-18 00:12:36 -07:00
parent f50eaa1847
commit 13e2ef90c8
84 changed files with 2547 additions and 3655 deletions

View File

@@ -0,0 +1,134 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Generic;
using System;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class BossTypeA : Enemy, IHasPrimaryAttack, IHasSecondaryAttack, ICanActivate
{
public override void _Notification(int what) => this.Notify(what);
[Export]
public ElementType PrimaryAttackElementalType { get; set; } = ElementType.None;
[Export]
public double PrimaryAttackElementalDamageBonus { get; set; } = 1.0;
public ElementType SecondaryAttackElementalType { get; set; } = ElementType.None;
public double SecondaryAttackElementalDamageBonus { get; set; } = 1.0;
[Node] public new EnemyModelView3D _enemyModelView { get; set; }
[Node] public CollisionShape3D EnemyHitbox { get; set; } = default!;
private Vector3 _target;
public void OnReady()
{
_target = GlobalPosition;
SetPhysicsProcess(true);
_enemyModelView.Hitbox.AreaEntered += Hitbox_AreaEntered;
_attackTimer.Start();
}
public void OnPhysicsProcess(double delta)
{
_enemyLogic.Input(new EnemyLogic.Input.PhysicsTick(delta));
if (_enemyLogic.Value is not EnemyLogic.State.Activated)
return;
if (_enemyLogic.Value is EnemyLogic.State.FollowPlayer && GlobalPosition.DistanceTo(_player.CurrentPosition) < 5f)
_enemyLogic.Input(new EnemyLogic.Input.StartAttacking());
if (_enemyLogic.Value is EnemyLogic.State.Attacking && GlobalPosition.DistanceTo(_player.CurrentPosition) > 5f)
_enemyLogic.Input(new EnemyLogic.Input.Alerted());
var direction = (_target - GlobalPosition).Normalized();
LookAt(direction);
if (_enemyLogic.Value is EnemyLogic.State.FollowPlayer)
{
Velocity = direction * _movementSpeed;
MoveAndSlide();
_enemyModelView.PlayWalkAnimation();
}
else
{
_enemyModelView.PlayIdleAnimation();
}
}
public override void TakeAction()
{
var rng = new RandomNumberGenerator();
var options = new List<Action>() { PrimaryAttack, SecondaryAttack };
var selection = rng.RandWeighted([0.875f, 0.125f]);
options[(int)selection].Invoke();
}
public void PrimaryAttack()
{
_enemyModelView.PlayPrimaryAttackAnimation();
}
public void SecondaryAttack()
{
_enemyModelView.PlaySecondaryAttackAnimation();
}
public override void StartAttackTimer()
{
_attackTimer.Timeout += OnAttackTimeout;
}
public override void StopAttackTimer()
{
_attackTimer.Timeout -= OnAttackTimeout;
}
public override void SetTarget(Vector3 target) => _target = target;
private void Hitbox_AreaEntered(Area3D area)
{
var target = area.GetOwner();
if (target is IPlayer player)
{
var damage = _enemyStatResource.CurrentAttack * PrimaryAttackElementalDamageBonus;
player.TakeDamage(damage, PrimaryAttackElementalType, BattleExtensions.IsCriticalHit(_enemyStatResource.Luck));
}
}
public void Activate()
{
Show();
_enemyLogic.Input(new EnemyLogic.Input.Alerted());
EnemyHitbox.SetDeferred(CollisionShape3D.PropertyName.Disabled, false);
}
private void OnAttackTimeout()
{
if (GlobalPosition.DistanceTo(_player.CurrentPosition) > 5f)
{
_enemyLogic.Input(new EnemyLogic.Input.Alerted());
return;
}
var rng = new RandomNumberGenerator();
rng.Randomize();
_enemyLogic.Input(new EnemyLogic.Input.AttackTimer());
_attackTimer.Stop();
_attackTimer.WaitTime = rng.RandfRange(2f, 5.0f);
_attackTimer.Start();
}
public override void _ExitTree()
{
CurrentHP.OnCompleted();
StopAttackTimer();
_enemyModelView.Hitbox.AreaEntered -= Hitbox_AreaEntered;
}
}

View File

@@ -0,0 +1 @@
uid://dveonnhcxcp08

View File

@@ -31,7 +31,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
[Export] protected EnemyStatResource _enemyStatResource { get; set; } = default!;
[Export]
private float _movementSpeed = 2f;
protected float _movementSpeed = 2f;
#endregion
#region Node Dependencies
@@ -39,16 +39,14 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
[Node] private Area3D _lineOfSight { get; set; } = default!;
[Node] private Timer _attackTimer { get; set; } = default!;
[Node] protected Timer _attackTimer { get; set; } = default!;
[Node] private RayCast3D _raycast { get; set; } = default!;
[Node] protected IEnemyModelView _enemyModelView { get; set; } = default!;
#endregion
public double CurrentHP => _currentHP.Value;
private AutoProp<double> _currentHP { get; set; }
public AutoProp<double> CurrentHP { get; set; }
private float _knockbackStrength = 0.0f;
@@ -80,14 +78,14 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
_enemyLogic.Start();
_currentHP = new AutoProp<double>(_enemyStatResource.MaximumHP);
_currentHP.Sync += OnHPChanged;
CurrentHP = new AutoProp<double>(_enemyStatResource.MaximumHP);
CurrentHP.Sync += OnHPChanged;
_lineOfSight.BodyEntered += LineOfSight_BodyEntered;
}
public override void _PhysicsProcess(double delta)
{
if (CurrentHP <= 0)
if (CurrentHP.Value <= 0)
return;
var lookDir = GlobalPosition + Velocity;
@@ -118,7 +116,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
public virtual void TakeDamage(double damage, ElementType elementType, bool isCriticalHit = false, bool ignoreDefense = false, bool ignoreElementalResistance = false)
{
if (_currentHP.Value > 0)
if (CurrentHP.Value > 0)
{
if (!ignoreElementalResistance)
damage = CalculateElementalResistance(damage, elementType);
@@ -127,10 +125,10 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
if (isCriticalHit)
damage *= 2;
GD.Print($"Enemy Hit for {damage} damage.");
_currentHP.OnNext(_currentHP.Value - damage);
GD.Print("Current HP: " + _currentHP.Value);
CurrentHP.OnNext(CurrentHP.Value - damage);
GD.Print("Current HP: " + CurrentHP.Value);
if (_currentHP.Value <= 0)
if (CurrentHP.Value <= 0)
return;
_enemyModelView.PlayHitAnimation();
@@ -149,7 +147,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
public void Die()
{
_currentHP.OnNext(0);
CurrentHP.OnNext(0);
_enemyLogic.Input(new EnemyLogic.Input.EnemyDefeated());
_collisionShape.SetDeferred("disabled", true);
_enemyModelView.PlayDeathAnimation();
@@ -161,7 +159,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
public void SetCurrentHP(int targetHP)
{
_currentHP.OnNext(targetHP);
CurrentHP.OnNext(targetHP);
}
public int GetMaximumHP()
@@ -169,12 +167,12 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
return _enemyStatResource.MaximumHP;
}
public void StartAttackTimer()
public virtual void StartAttackTimer()
{
_attackTimer.Timeout += OnAttackTimeout;
}
public void StopAttackTimer()
public virtual void StopAttackTimer()
{
_attackTimer.Timeout -= OnAttackTimeout;
}

View File

@@ -1,4 +1,4 @@
using Chickensoft.AutoInject;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
@@ -10,12 +10,8 @@ public partial class EnemyModelView3D : Node3D, IEnemyModelView
private const string PRIMARY_ATTACK = "primary_attack";
private const string SECONDARY_ATTACK = "secondary_attack";
private const string PRIMARY_SKILL = "primary_skill";
private const string IDLE_FORWARD = "idle_front";
private const string IDLE_LEFT = "idle_left";
private const string IDLE_BACK = "idle_back";
private const string IDLE_FORWARD_WALK = "idle_front_walk";
private const string IDLE_LEFT_WALK = "idle_left_walk";
private const string IDLE_BACK_WALK = "idle_back_walk";
private const string WALK = "walk";
private const string IDLE = "idle";
private const string TAKE_DAMAGE = "take_damage";
private const string DEFEATED = "defeated";
private const string PARAMETERS_PLAYBACK = "parameters/playback";
@@ -24,34 +20,48 @@ public partial class EnemyModelView3D : Node3D, IEnemyModelView
[Export] public EnemyLoreInfo EnemyLoreInfo { get; set; } = default!;
[Node] private MeshInstance3D _meshInstance { get; set; } = default!;
[Node] private AnimationPlayer _animationPlayer { get; set; } = default!;
[Node] public AnimationTree AnimationTree { get; set; } = default!;
[Node] public IHitbox Hitbox { get; set; } = default!;
public void Setup()
{
}
public void PlayPrimaryAttackAnimation()
{
_animationPlayer.Play(PRIMARY_ATTACK);
AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().Travel(PRIMARY_ATTACK);
}
public void PlaySecondaryAttackAnimation()
{
AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().Travel(SECONDARY_ATTACK);
}
public void PlayPrimarySkillAnimation()
{
AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().Travel(PRIMARY_SKILL);
}
public void PlayHitAnimation()
{
_animationPlayer.Play(TAKE_DAMAGE);
_animationPlayer.Play(TAKE_DAMAGE);
}
public void PlayDeathAnimation()
{
_animationPlayer.Play(DEFEATED);
_animationPlayer.Play(DEFEATED);
}
public void PlayWalkAnimation()
{
AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().Travel(WALK);
}
public void PlayIdleAnimation()
{
AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().Travel(IDLE);
}
}

View File

@@ -0,0 +1,6 @@
namespace Zennysoft.Game.Ma;
public interface ICanActivate
{
public void Activate();
}

View File

@@ -0,0 +1 @@
uid://btxdf6ncxkk02

View File

@@ -1,4 +1,5 @@
using Godot;
using Chickensoft.Collections;
using Godot;
using Zennysoft.Game.Abstractions;
using Zennysoft.Ma.Adapter;
@@ -14,7 +15,7 @@ public interface IEnemy : IKillable
public void Knockback(float impulse, Vector3 direction);
public double CurrentHP { get; }
public AutoProp<double> CurrentHP { get; }
public void SetCurrentHP(int newHP);

View File

@@ -7,7 +7,7 @@ using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class Chinthe : Enemy, IHasPrimaryAttack, ICanPatrol
public partial class Chinthe : Enemy, IHasPrimaryAttack, ICanPatrol, ICanActivate
{
public override void _Notification(int what) => this.Notify(what);
@@ -24,72 +24,72 @@ public partial class Chinthe : Enemy, IHasPrimaryAttack, ICanPatrol
public void OnReady()
{
SetPhysicsProcess(true);
EnemyModelView.Hitbox.AreaEntered += Hitbox_AreaEntered;
SetPhysicsProcess(true);
EnemyModelView.Hitbox.AreaEntered += Hitbox_AreaEntered;
}
public void OnPhysicsProcess(double delta)
{
_enemyLogic.Input(new EnemyLogic.Input.PhysicsTick(delta));
_enemyLogic.Input(new EnemyLogic.Input.PhysicsTick(delta));
if (_enemyLogic.Value is not EnemyLogic.State.Activated)
return;
if (_enemyLogic.Value is not EnemyLogic.State.Activated)
return;
if (_enemyLogic.Value is EnemyLogic.State.FollowPlayer && GlobalPosition.DistanceTo(_player.CurrentPosition) < 2.5f)
_enemyLogic.Input(new EnemyLogic.Input.StartAttacking());
if (_enemyLogic.Value is EnemyLogic.State.FollowPlayer && GlobalPosition.DistanceTo(_player.CurrentPosition) > 45f)
_enemyLogic.Input(new EnemyLogic.Input.LostPlayer());
if (_enemyLogic.Value is EnemyLogic.State.Attacking && GlobalPosition.DistanceTo(_player.CurrentPosition) > 2.5f)
_enemyLogic.Input(new EnemyLogic.Input.Alerted());
if (_enemyLogic.Value is EnemyLogic.State.FollowPlayer && GlobalPosition.DistanceTo(_player.CurrentPosition) < 2.5f)
_enemyLogic.Input(new EnemyLogic.Input.StartAttacking());
if (_enemyLogic.Value is EnemyLogic.State.FollowPlayer && GlobalPosition.DistanceTo(_player.CurrentPosition) > 45f)
_enemyLogic.Input(new EnemyLogic.Input.LostPlayer());
if (_enemyLogic.Value is EnemyLogic.State.Attacking && GlobalPosition.DistanceTo(_player.CurrentPosition) > 2.5f)
_enemyLogic.Input(new EnemyLogic.Input.Alerted());
_navigationAgentClient.CalculateVelocity(GlobalPosition, EnemyModelView.CanMove);
_navigationAgentClient.CalculateVelocity(GlobalPosition, EnemyModelView.CanMove);
base._PhysicsProcess(delta);
base._PhysicsProcess(delta);
}
public override void TakeAction()
{
PrimaryAttack();
PrimaryAttack();
}
public void PrimaryAttack()
{
_enemyModelView.PlayPrimaryAttackAnimation();
_enemyModelView.PlayPrimaryAttackAnimation();
}
public override void SetTarget(Vector3 target) => _navigationAgentClient.SetTarget(target);
public void Patrol()
{
var rng = new RandomNumberGenerator();
rng.Randomize();
var randomizedSpot = new Vector3(rng.RandfRange(-5.0f, 5.0f), 0, rng.RandfRange(-5.0f, 5.0f));
_enemyLogic.Input(new EnemyLogic.Input.PatrolToRandomSpot(GlobalPosition + randomizedSpot));
_enemyLogic.Input(new EnemyLogic.Input.StartPatrol());
var rng = new RandomNumberGenerator();
rng.Randomize();
var randomizedSpot = new Vector3(rng.RandfRange(-5.0f, 5.0f), 0, rng.RandfRange(-5.0f, 5.0f));
_enemyLogic.Input(new EnemyLogic.Input.PatrolToRandomSpot(GlobalPosition + randomizedSpot));
_enemyLogic.Input(new EnemyLogic.Input.StartPatrol());
}
public void Activate()
{
if (EnemyModelView.AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().GetCurrentNode().ToString().Contains("front"))
EnemyModelView.PlayActivateFrontAnimation();
if (EnemyModelView.AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().GetCurrentNode().ToString().Contains("left"))
EnemyModelView.PlayActivateLeftAnimation();
if (EnemyModelView.AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().GetCurrentNode().ToString().Contains("back"))
EnemyModelView.PlayActivateBackAnimation();
if (EnemyModelView.AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().GetCurrentNode().ToString().Contains("front"))
EnemyModelView.PlayActivateFrontAnimation();
if (EnemyModelView.AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().GetCurrentNode().ToString().Contains("left"))
EnemyModelView.PlayActivateLeftAnimation();
if (EnemyModelView.AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().GetCurrentNode().ToString().Contains("back"))
EnemyModelView.PlayActivateBackAnimation();
}
public void Teleport()
{
EnemyModelView.PlayTeleportAnimation();
EnemyModelView.PlayTeleportAnimation();
}
private void Hitbox_AreaEntered(Area3D area)
{
var target = area.GetOwner();
if (target is IPlayer player)
{
var damage = _enemyStatResource.CurrentAttack * PrimaryAttackElementalDamageBonus;
player.TakeDamage(damage, PrimaryAttackElementalType, BattleExtensions.IsCriticalHit(_enemyStatResource.Luck));
}
var target = area.GetOwner();
if (target is IPlayer player)
{
var damage = _enemyStatResource.CurrentAttack * PrimaryAttackElementalDamageBonus;
player.TakeDamage(damage, PrimaryAttackElementalType, BattleExtensions.IsCriticalHit(_enemyStatResource.Luck));
}
}
}
}

View File

@@ -3,7 +3,7 @@
[ext_resource type="Texture2D" uid="uid://cvst7yhbw0sxt" path="res://src/enemy/enemy_types/10. Eden Pillar/model/PILLAR EXPORT 1_ENEMY_PILLAR_TEXTURE2.jpg" id="1_1kpl1"]
[ext_resource type="Script" uid="uid://ckv5dmrw6pvn6" path="res://src/enemy/EnemyModelView3D.cs" id="1_11eq8"]
[ext_resource type="Texture2D" uid="uid://bnbveonobhyhc" path="res://src/enemy/enemy_types/10. Eden Pillar/model/PILLAR EXPORT 1_cannon_edge.png" id="2_11eq8"]
[ext_resource type="Material" uid="uid://brwu51ylevbmg" path="res://src/enemy/enemy_types/14. horse_head/BossHit.tres" id="2_xf2ga"]
[ext_resource type="Material" uid="uid://brwu51ylevbmg" path="res://src/enemy/enemy_types/14. horse_head/animation/BossHit.tres" id="2_xf2ga"]
[ext_resource type="Texture2D" uid="uid://by7k6crx6fmpv" path="res://src/enemy/enemy_types/10. Eden Pillar/model/PILLAR EXPORT 1_floral_single_tile.jpg" id="3_oxjs8"]
[ext_resource type="Texture2D" uid="uid://cc1tenm6p3pca" path="res://src/enemy/enemy_types/10. Eden Pillar/model/PILLAR EXPORT 1_ENEMY_PILLAR_TEXTURE.jpg" id="4_xf2ga"]
[ext_resource type="Texture2D" uid="uid://bydfevqfagpq8" path="res://src/enemy/enemy_types/10. Eden Pillar/model/PILLAR EXPORT 1_concrete_0025_height_1k.png" id="5_qhmtu"]

View File

@@ -0,0 +1 @@
uid://clt3sfgb5m3xq

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +0,0 @@
using Godot;
namespace Zennysoft.Game.Ma;
public partial class HorseHead : Node3D
{
}

View File

@@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://8yaqqojv4nuv"]
[ext_resource type="PackedScene" uid="uid://c4uus6q6c4ocg" path="res://src/enemy/enemy_types/14. horse_head/Horse Head 1.0 STATUE.glb" id="1_ktvqd"]
[ext_resource type="PackedScene" uid="uid://c4uus6q6c4ocg" path="res://src/enemy/enemy_types/14. horse_head/animation/Horse Head 1.0 STATUE.glb" id="1_ktvqd"]
[node name="Node3D" type="Node3D"]

View File

@@ -4,12 +4,12 @@ importer="scene"
importer_version=1
type="PackedScene"
uid="uid://cvqaccot8ltrf"
path="res://.godot/imported/HORSE-FACE 1.1.glb-a095bfe8da5727e267e8a8185cd8aaee.scn"
path="res://.godot/imported/HORSE-FACE 1.1.glb-8c0ac9d603554b32a1666de9bd9b1814.scn"
[deps]
source_file="res://src/enemy/enemy_types/14. horse_head/HORSE-FACE 1.1.glb"
dest_files=["res://.godot/imported/HORSE-FACE 1.1.glb-a095bfe8da5727e267e8a8185cd8aaee.scn"]
source_file="res://src/enemy/enemy_types/14. horse_head/animation/HORSE-FACE 1.1.glb"
dest_files=["res://.godot/imported/HORSE-FACE 1.1.glb-8c0ac9d603554b32a1666de9bd9b1814.scn"]
[params]

View File

@@ -3,7 +3,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://csj3kjwyn3s2u"
path="res://.godot/imported/HORSE-FACE 1_Metal054C_1K-JPG_Color.jpg-dd3ebefab63cbbf56a2e0e52b75bc691.ctex"
path="res://.godot/imported/HORSE-FACE 1_Metal054C_1K-JPG_Color.jpg-1f1a8445de0bb81a567077e5aec18194.ctex"
metadata={
"vram_texture": false
}
@@ -13,8 +13,8 @@ generator_parameters={
[deps]
source_file="res://src/enemy/enemy_types/14. horse_head/HORSE-FACE 1_Metal054C_1K-JPG_Color.jpg"
dest_files=["res://.godot/imported/HORSE-FACE 1_Metal054C_1K-JPG_Color.jpg-dd3ebefab63cbbf56a2e0e52b75bc691.ctex"]
source_file="res://src/enemy/enemy_types/14. horse_head/animation/HORSE-FACE 1_Metal054C_1K-JPG_Color.jpg"
dest_files=["res://.godot/imported/HORSE-FACE 1_Metal054C_1K-JPG_Color.jpg-1f1a8445de0bb81a567077e5aec18194.ctex"]
[params]

View File

@@ -3,7 +3,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dd7ocxanos2o7"
path="res://.godot/imported/HORSE-FACE 1_Metal054C_1K-JPG_Displacement.jpg-5771feccb31b5f0e73720e8a3e7a5725.ctex"
path="res://.godot/imported/HORSE-FACE 1_Metal054C_1K-JPG_Displacement.jpg-386dacafcbff768209a8a638cefcea95.ctex"
metadata={
"vram_texture": false
}
@@ -13,8 +13,8 @@ generator_parameters={
[deps]
source_file="res://src/enemy/enemy_types/14. horse_head/HORSE-FACE 1_Metal054C_1K-JPG_Displacement.jpg"
dest_files=["res://.godot/imported/HORSE-FACE 1_Metal054C_1K-JPG_Displacement.jpg-5771feccb31b5f0e73720e8a3e7a5725.ctex"]
source_file="res://src/enemy/enemy_types/14. horse_head/animation/HORSE-FACE 1_Metal054C_1K-JPG_Displacement.jpg"
dest_files=["res://.godot/imported/HORSE-FACE 1_Metal054C_1K-JPG_Displacement.jpg-386dacafcbff768209a8a638cefcea95.ctex"]
[params]

View File

@@ -4,12 +4,12 @@ importer="scene"
importer_version=1
type="PackedScene"
uid="uid://c4uus6q6c4ocg"
path="res://.godot/imported/Horse Head 1.0 STATUE.glb-e0c74b4195e0fc27f4658130960774ea.scn"
path="res://.godot/imported/Horse Head 1.0 STATUE.glb-0ffebc243c4ceff8865a777101feadec.scn"
[deps]
source_file="res://src/enemy/enemy_types/14. horse_head/Horse Head 1.0 STATUE.glb"
dest_files=["res://.godot/imported/Horse Head 1.0 STATUE.glb-e0c74b4195e0fc27f4658130960774ea.scn"]
source_file="res://src/enemy/enemy_types/14. horse_head/animation/Horse Head 1.0 STATUE.glb"
dest_files=["res://.godot/imported/Horse Head 1.0 STATUE.glb-0ffebc243c4ceff8865a777101feadec.scn"]
[params]

View File

@@ -8,7 +8,7 @@ valid=false
[deps]
source_file="res://src/enemy/enemy_types/14. horse_head/Horse Head 1.0 WALK.glb"
source_file="res://src/enemy/enemy_types/14. horse_head/animation/Horse Head 1.0 WALK.glb"
[params]

View File

@@ -4,12 +4,12 @@ importer="scene"
importer_version=1
type="PackedScene"
uid="uid://b8xs07d4ycm3s"
path="res://.godot/imported/Horse Head 1.0.glb-17c7ea9ea5d193e3a003f25b69f74650.scn"
path="res://.godot/imported/Horse Head 1.0.glb-1e71651be336a86299c334b8540d0758.scn"
[deps]
source_file="res://src/enemy/enemy_types/14. horse_head/Horse Head 1.0.glb"
dest_files=["res://.godot/imported/Horse Head 1.0.glb-17c7ea9ea5d193e3a003f25b69f74650.scn"]
source_file="res://src/enemy/enemy_types/14. horse_head/animation/Horse Head 1.0.glb"
dest_files=["res://.godot/imported/Horse Head 1.0.glb-1e71651be336a86299c334b8540d0758.scn"]
[params]

View File

@@ -3,7 +3,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://2e4cp477ex0t"
path="res://.godot/imported/Horse Head 1_Metal054C_1K-JPG_Color.jpg-309c20056c641a0bf0fe6eabcff04ca0.ctex"
path="res://.godot/imported/Horse Head 1_Metal054C_1K-JPG_Color.jpg-0c0531e87bbeff5b38eafc2808887dbf.ctex"
metadata={
"vram_texture": false
}
@@ -13,8 +13,8 @@ generator_parameters={
[deps]
source_file="res://src/enemy/enemy_types/14. horse_head/Horse Head 1_Metal054C_1K-JPG_Color.jpg"
dest_files=["res://.godot/imported/Horse Head 1_Metal054C_1K-JPG_Color.jpg-309c20056c641a0bf0fe6eabcff04ca0.ctex"]
source_file="res://src/enemy/enemy_types/14. horse_head/animation/Horse Head 1_Metal054C_1K-JPG_Color.jpg"
dest_files=["res://.godot/imported/Horse Head 1_Metal054C_1K-JPG_Color.jpg-0c0531e87bbeff5b38eafc2808887dbf.ctex"]
[params]

View File

@@ -3,7 +3,7 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://kdnitbg4n87p"
path="res://.godot/imported/Horse Head 1_Metal054C_1K-JPG_Displacement.jpg-22bf3780ddcc88b6230d35aebd896c20.ctex"
path="res://.godot/imported/Horse Head 1_Metal054C_1K-JPG_Displacement.jpg-0a8cfa8420b016a4333949db03bcf0e5.ctex"
metadata={
"vram_texture": false
}
@@ -13,8 +13,8 @@ generator_parameters={
[deps]
source_file="res://src/enemy/enemy_types/14. horse_head/Horse Head 1_Metal054C_1K-JPG_Displacement.jpg"
dest_files=["res://.godot/imported/Horse Head 1_Metal054C_1K-JPG_Displacement.jpg-22bf3780ddcc88b6230d35aebd896c20.ctex"]
source_file="res://src/enemy/enemy_types/14. horse_head/animation/Horse Head 1_Metal054C_1K-JPG_Displacement.jpg"
dest_files=["res://.godot/imported/Horse Head 1_Metal054C_1K-JPG_Displacement.jpg-0a8cfa8420b016a4333949db03bcf0e5.ctex"]
[params]

View File

@@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bv60n7epxktw5"
path="res://.godot/imported/Metal054C_1K-JPG_NormalDX.jpg-1cf1bfec87fee44ad90f8f8942ca9cd1.ctex"
path="res://.godot/imported/Metal054C_1K-JPG_NormalDX.jpg-8f619f53486c72857b0b0ce2b4ae98bd.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://src/enemy/enemy_types/14. horse_head/Metal054C_1K-JPG_NormalDX.jpg"
dest_files=["res://.godot/imported/Metal054C_1K-JPG_NormalDX.jpg-1cf1bfec87fee44ad90f8f8942ca9cd1.ctex"]
source_file="res://src/enemy/enemy_types/14. horse_head/animation/Metal054C_1K-JPG_NormalDX.jpg"
dest_files=["res://.godot/imported/Metal054C_1K-JPG_NormalDX.jpg-8f619f53486c72857b0b0ce2b4ae98bd.ctex"]
[params]

View File

@@ -1,57 +0,0 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class OxFace : Node3D
{
public override void _Notification(int what) => this.Notify(what);
[Node] public AnimationTree AnimationTree { get; set; } = default!;
[Dependency] public IPlayer Player => this.DependOn<IPlayer>();
[Node] public Timer AttackTimer { get; set; } = default!;
private bool isInRange = false;
public void Setup()
{
SetPhysicsProcess(false);
}
public void EngagePlayer()
{
SetPhysicsProcess(true);
Visible = true;
AttackTimer.Timeout += AttackTimer_Timeout;
AttackTimer.Start();
}
private void AttackTimer_Timeout()
{
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("SPEAR");
}
public override void _PhysicsProcess(double delta)
{
var playerPosition = new Vector3(Player.CurrentPosition.X, GlobalPosition.Y, Player.CurrentPosition.Z);
var targetDirection = GlobalPosition - Player.CurrentPosition;
GlobalRotation = new Vector3(GlobalRotation.X, Mathf.LerpAngle(GlobalRotation.Y, Mathf.Atan2(-targetDirection.X, -targetDirection.Z), (float)delta * 3f), GlobalRotation.Z);
if (GlobalPosition.DistanceTo(Player.CurrentPosition) > 5.0f)
{
isInRange = false;
var moveToward = GlobalPosition.MoveToward(playerPosition, (float)delta * 3f);
GlobalPosition = moveToward;
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("WALK");
}
else if (!isInRange)
{
isInRange = true;
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("IDLE");
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long