Add buff/debuff/heal/rust shaders for enemies and throwing glue jar immobilization
This commit is contained in:
@@ -21,6 +21,12 @@ namespace Zennysoft.Ma.Adapter.Entity
|
|||||||
|
|
||||||
public void OnMorph();
|
public void OnMorph();
|
||||||
|
|
||||||
|
public void OnBuff();
|
||||||
|
|
||||||
|
public void OnDebuff();
|
||||||
|
|
||||||
|
public void OnHealed();
|
||||||
|
|
||||||
public void IncrementDefeatCount();
|
public void IncrementDefeatCount();
|
||||||
|
|
||||||
public int GetDefeatCount(IEnemy enemyType);
|
public int GetDefeatCount(IEnemy enemyType);
|
||||||
@@ -39,6 +45,8 @@ namespace Zennysoft.Ma.Adapter.Entity
|
|||||||
|
|
||||||
public ElementalResistanceSet ElementalResistanceSet { get; }
|
public ElementalResistanceSet ElementalResistanceSet { get; }
|
||||||
|
|
||||||
|
public void SetEnemySpeedByMultiplier(double multiplier);
|
||||||
|
|
||||||
public int InitialHP { get; }
|
public int InitialHP { get; }
|
||||||
|
|
||||||
public int InitialAttack { get; }
|
public int InitialAttack { get; }
|
||||||
|
|||||||
@@ -213,6 +213,23 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
|||||||
tweener.TweenCallback(Callable.From(QueueFree));
|
tweener.TweenCallback(Callable.From(QueueFree));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void OnBuff()
|
||||||
|
{
|
||||||
|
EnemyModelView.PlayBuffAnimation();
|
||||||
|
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnDebuff()
|
||||||
|
{
|
||||||
|
EnemyModelView.PlayDebuffAnimation();
|
||||||
|
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnHealed()
|
||||||
|
{
|
||||||
|
EnemyModelView.PlayHealAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
public IDungeonRoom GetCurrentRoom(ImmutableList<IDungeonRoom> roomList)
|
public IDungeonRoom GetCurrentRoom(ImmutableList<IDungeonRoom> roomList)
|
||||||
{
|
{
|
||||||
foreach (var room in roomList)
|
foreach (var room in roomList)
|
||||||
@@ -233,6 +250,16 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
|||||||
EnemyModelView.HitPlayer -= EnemyModelView_HitPlayer;
|
EnemyModelView.HitPlayer -= EnemyModelView_HitPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetEnemySpeedByMultiplier(double multiplier)
|
||||||
|
{
|
||||||
|
if (this is IHaveFleeBehavior fleeBehavior)
|
||||||
|
fleeBehavior.FleeBehavior.FleeSpeed *= multiplier;
|
||||||
|
if (this is IHavePatrolBehavior patrolBehavior)
|
||||||
|
patrolBehavior.PatrolBehavior.PatrolSpeed *= multiplier;
|
||||||
|
if (this is IHaveFollowBehavior followBehavior)
|
||||||
|
followBehavior.FollowBehavior.FollowSpeed *= multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void MoveEnemyToNewRoom(IDungeonRoom newRoom)
|
public virtual void MoveEnemyToNewRoom(IDungeonRoom newRoom)
|
||||||
{
|
{
|
||||||
if (newRoom is MonsterRoom monsterRoom)
|
if (newRoom is MonsterRoom monsterRoom)
|
||||||
@@ -277,6 +304,7 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
|||||||
{
|
{
|
||||||
_rustTimer.Start();
|
_rustTimer.Start();
|
||||||
_rustDuration.Start();
|
_rustDuration.Start();
|
||||||
|
EnemyModelView.PlayRustActivateAnimation();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -287,7 +315,7 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
|||||||
private void _rustTimer_Timeout()
|
private void _rustTimer_Timeout()
|
||||||
{
|
{
|
||||||
HealthComponent.Damage(3, ElementType.Ferrum);
|
HealthComponent.Damage(3, ElementType.Ferrum);
|
||||||
TakeHit(ElementType.Ferrum);
|
EnemyModelView.PlayRustDamageAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _rustDuration_Timeout()
|
private void _rustDuration_Timeout()
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://gvgpe17jldat"]
|
||||||
|
|
||||||
|
[ext_resource type="Shader" uid="uid://cjvysm0rhhdgi" path="res://src/vfx/shaders/DamageHit.gdshader" id="1_23uje"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
resource_local_to_scene = true
|
||||||
|
shader = ExtResource("1_23uje")
|
||||||
|
shader_parameter/shock_color = Color(1, 0, 0, 1)
|
||||||
|
shader_parameter/amplitude = 30.0
|
||||||
|
shader_parameter/progress = -1.0
|
||||||
|
shader_parameter/frequecy = 10.0
|
||||||
@@ -117,6 +117,16 @@ public abstract partial class EnemyModelView : Node3D, IEnemyModelView
|
|||||||
|
|
||||||
public virtual void PlayHitAnimation() => throw new System.NotImplementedException();
|
public virtual void PlayHitAnimation() => throw new System.NotImplementedException();
|
||||||
|
|
||||||
|
public virtual void PlayBuffAnimation() => throw new System.NotImplementedException();
|
||||||
|
|
||||||
|
public virtual void PlayDebuffAnimation() => throw new System.NotImplementedException();
|
||||||
|
|
||||||
|
public virtual void PlayHealAnimation() => throw new System.NotImplementedException();
|
||||||
|
|
||||||
|
public virtual void PlayRustActivateAnimation() => throw new System.NotImplementedException();
|
||||||
|
|
||||||
|
public virtual void PlayRustDamageAnimation() => throw new System.NotImplementedException();
|
||||||
|
|
||||||
protected virtual void OnPlayerHit(AttackEventArgs arg) => HitPlayer?.Invoke(this, arg);
|
protected virtual void OnPlayerHit(AttackEventArgs arg) => HitPlayer?.Invoke(this, arg);
|
||||||
|
|
||||||
protected void AnimationTree_AnimationFinished(StringName animName)
|
protected void AnimationTree_AnimationFinished(StringName animName)
|
||||||
|
|||||||
@@ -37,14 +37,14 @@ public partial class EnemyModelView2D : EnemyModelView, IEnemyModelView
|
|||||||
|
|
||||||
public new void OnReady()
|
public new void OnReady()
|
||||||
{
|
{
|
||||||
Hitbox.AreaEntered += Hitbox_AreaEntered;
|
Hitbox.AreaEntered += Hitbox_AreaEntered;
|
||||||
base.OnReady();
|
base.OnReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override Vector2 GetSize()
|
public override Vector2 GetSize()
|
||||||
{
|
{
|
||||||
return Sprite3D.GetItemRect().Size;
|
return Sprite3D.GetItemRect().Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Hitbox_AreaEntered(Area3D area) => OnPlayerHit(new AttackEventArgs(AttackData));
|
private void Hitbox_AreaEntered(Area3D area) => OnPlayerHit(new AttackEventArgs(AttackData));
|
||||||
@@ -53,144 +53,176 @@ public partial class EnemyModelView2D : EnemyModelView, IEnemyModelView
|
|||||||
|
|
||||||
public override void PlayHitAnimation()
|
public override void PlayHitAnimation()
|
||||||
{
|
{
|
||||||
LoadShader("res://src/vfx/shaders/DamageHit.gdshader");
|
LoadShader("res://src/vfx/shaders/DamageHit.gdshader");
|
||||||
var tweener = GetTree().CreateTween();
|
var tweener = GetTree().CreateTween();
|
||||||
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 1.0f);
|
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void PlayDeathAnimation()
|
public override void PlayDeathAnimation()
|
||||||
{
|
{
|
||||||
AnimationPlayer.Stop();
|
AnimationPlayer.Stop();
|
||||||
LoadShader("res://src/vfx/shaders/PixelMelt.gdshader");
|
LoadShader("res://src/vfx/shaders/PixelMelt.gdshader");
|
||||||
var tweener = GetTree().CreateTween();
|
var tweener = GetTree().CreateTween();
|
||||||
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 0.1f, 0.8f);
|
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 0.1f, 0.8f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PlayBuffAnimation()
|
||||||
|
{
|
||||||
|
LoadShader("res://src/vfx/shaders/EnemyBuff.gdshader");
|
||||||
|
var tweener = GetTree().CreateTween();
|
||||||
|
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PlayDebuffAnimation()
|
||||||
|
{
|
||||||
|
LoadShader("res://src/vfx/shaders/EnemyDebuff.gdshader");
|
||||||
|
var tweener = GetTree().CreateTween();
|
||||||
|
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PlayHealAnimation()
|
||||||
|
{
|
||||||
|
LoadShader("res://src/vfx/shaders/EnemyHeal.gdshader");
|
||||||
|
var tweener = GetTree().CreateTween();
|
||||||
|
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PlayRustActivateAnimation()
|
||||||
|
{
|
||||||
|
RustHitAnimation.Play("RustActivate");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PlayRustDamageAnimation()
|
||||||
|
{
|
||||||
|
LoadShader("res://src/vfx/shaders/EnemyRust.gdshader");
|
||||||
|
var tweener = GetTree().CreateTween();
|
||||||
|
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void PlayElementalDamageAnimation(ElementType elementType)
|
public override void PlayElementalDamageAnimation(ElementType elementType)
|
||||||
{
|
{
|
||||||
if (elementType == ElementType.Igneous)
|
if (elementType == ElementType.Igneous)
|
||||||
{
|
{
|
||||||
if (FlameHitAnimation.IsPlaying())
|
if (FlameHitAnimation.IsPlaying())
|
||||||
FlameHitAnimation.Stop();
|
FlameHitAnimation.Stop();
|
||||||
FlameHitAnimation.Play("FireHit");
|
FlameHitAnimation.Play("FireHit");
|
||||||
}
|
}
|
||||||
else if (elementType == ElementType.Sankta)
|
else if (elementType == ElementType.Sankta)
|
||||||
{
|
{
|
||||||
if (HolyHitAnimation.IsPlaying())
|
if (HolyHitAnimation.IsPlaying())
|
||||||
HolyHitAnimation.Stop();
|
HolyHitAnimation.Stop();
|
||||||
HolyHitAnimation.Play("HolyHit");
|
HolyHitAnimation.Play("HolyHit");
|
||||||
}
|
}
|
||||||
else if (elementType == ElementType.Aeolic)
|
else if (elementType == ElementType.Aeolic)
|
||||||
{
|
{
|
||||||
if (WindHitAnimation.IsPlaying())
|
if (WindHitAnimation.IsPlaying())
|
||||||
WindHitAnimation.Stop();
|
WindHitAnimation.Stop();
|
||||||
WindHitAnimation.Play("WindHit");
|
WindHitAnimation.Play("WindHit");
|
||||||
}
|
}
|
||||||
else if (elementType == ElementType.Shura)
|
else if (elementType == ElementType.Shura)
|
||||||
{
|
{
|
||||||
if (CurseHitAnimation.IsPlaying())
|
if (CurseHitAnimation.IsPlaying())
|
||||||
CurseHitAnimation.Stop();
|
CurseHitAnimation.Stop();
|
||||||
CurseHitAnimation.Play("CurseHit");
|
CurseHitAnimation.Play("CurseHit");
|
||||||
}
|
}
|
||||||
else if (elementType == ElementType.Hydric)
|
else if (elementType == ElementType.Hydric)
|
||||||
{
|
{
|
||||||
if (WaterHitAnimation.IsPlaying())
|
if (WaterHitAnimation.IsPlaying())
|
||||||
WaterHitAnimation.Stop();
|
WaterHitAnimation.Stop();
|
||||||
WaterHitAnimation.Play("WaterHit");
|
WaterHitAnimation.Play("WaterHit");
|
||||||
}
|
}
|
||||||
else if (elementType == ElementType.Telluric)
|
else if (elementType == ElementType.Telluric)
|
||||||
{
|
{
|
||||||
if (EarthHitAnimation.IsPlaying())
|
if (EarthHitAnimation.IsPlaying())
|
||||||
EarthHitAnimation.Stop();
|
EarthHitAnimation.Stop();
|
||||||
EarthHitAnimation.Play("EarthHit");
|
EarthHitAnimation.Play("EarthHit");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private EnemyDirection GetEnemyDirection(
|
private EnemyDirection GetEnemyDirection(
|
||||||
Basis enemyBasis,
|
Basis enemyBasis,
|
||||||
Vector3 cameraDirection,
|
Vector3 cameraDirection,
|
||||||
float rotateUpperThreshold,
|
float rotateUpperThreshold,
|
||||||
float rotateLowerThreshold)
|
float rotateLowerThreshold)
|
||||||
{
|
{
|
||||||
var enemyForwardDirection = enemyBasis.Z;
|
var enemyForwardDirection = enemyBasis.Z;
|
||||||
var enemyLeftDirection = enemyBasis.X;
|
var enemyLeftDirection = enemyBasis.X;
|
||||||
|
|
||||||
var leftDotProduct = enemyLeftDirection.Dot(cameraDirection);
|
var leftDotProduct = enemyLeftDirection.Dot(cameraDirection);
|
||||||
var forwardDotProduct = enemyForwardDirection.Dot(cameraDirection);
|
var forwardDotProduct = enemyForwardDirection.Dot(cameraDirection);
|
||||||
|
|
||||||
// Check if forward facing. If the dot product is -1, the enemy is facing the camera.
|
// Check if forward facing. If the dot product is -1, the enemy is facing the camera.
|
||||||
if (forwardDotProduct < _lowerThreshold)
|
if (forwardDotProduct < _lowerThreshold)
|
||||||
{
|
{
|
||||||
SetForward();
|
SetForward();
|
||||||
return EnemyDirection.Forward;
|
return EnemyDirection.Forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if backward facing. If the dot product is 1, the enemy is facing the same direction as the camera.
|
// Check if backward facing. If the dot product is 1, the enemy is facing the same direction as the camera.
|
||||||
else if (forwardDotProduct > rotateUpperThreshold)
|
else if (forwardDotProduct > rotateUpperThreshold)
|
||||||
{
|
{
|
||||||
SetBack();
|
SetBack();
|
||||||
return EnemyDirection.Backward;
|
return EnemyDirection.Backward;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If the dot product of the perpendicular direction is positive (up to 1), the enemy is facing to the left (since it's mirrored).
|
// If the dot product of the perpendicular direction is positive (up to 1), the enemy is facing to the left (since it's mirrored).
|
||||||
if (leftDotProduct < _lowerThreshold)
|
if (leftDotProduct < _lowerThreshold)
|
||||||
{
|
{
|
||||||
SetRight();
|
SetRight();
|
||||||
return EnemyDirection.Left;
|
return EnemyDirection.Left;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if side facing. If the dot product is close to zero in the positive or negative direction, its close to the threshold for turning.
|
// Check if side facing. If the dot product is close to zero in the positive or negative direction, its close to the threshold for turning.
|
||||||
if (leftDotProduct > rotateUpperThreshold)
|
if (leftDotProduct > rotateUpperThreshold)
|
||||||
{
|
{
|
||||||
SetLeft();
|
SetLeft();
|
||||||
return EnemyDirection.Right;
|
return EnemyDirection.Right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _enemyDirection;
|
return _enemyDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadShader(string shaderPath)
|
private void LoadShader(string shaderPath)
|
||||||
{
|
{
|
||||||
var shader = GD.Load<Shader>(shaderPath);
|
var shader = GD.Load<Shader>(shaderPath);
|
||||||
var sprites = FindChildren("*", "AnimatedSprite2D", true).Cast<AnimatedSprite2D>();
|
var sprites = FindChildren("*", "AnimatedSprite2D", true).Cast<AnimatedSprite2D>();
|
||||||
foreach (var sprite in sprites)
|
foreach (var sprite in sprites)
|
||||||
{
|
{
|
||||||
sprite.Material = new ShaderMaterial();
|
sprite.Material = new ShaderMaterial();
|
||||||
var shaderMaterial = (ShaderMaterial)sprite.Material;
|
var shaderMaterial = (ShaderMaterial)sprite.Material;
|
||||||
shaderMaterial.Shader = shader;
|
shaderMaterial.Shader = shader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetShaderValue(float shaderValue)
|
private void SetShaderValue(float shaderValue)
|
||||||
{
|
{
|
||||||
var sprites = FindChildren("*", "AnimatedSprite2D", true).Cast<AnimatedSprite2D>();
|
var sprites = FindChildren("*", "AnimatedSprite2D", true).Cast<AnimatedSprite2D>();
|
||||||
foreach (var sprite in sprites)
|
foreach (var sprite in sprites)
|
||||||
{
|
{
|
||||||
var shaderMaterial = (ShaderMaterial)sprite.Material;
|
var shaderMaterial = (ShaderMaterial)sprite.Material;
|
||||||
shaderMaterial.SetShaderParameter("progress", shaderValue);
|
shaderMaterial.SetShaderParameter("progress", shaderValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetForward()
|
private void SetForward()
|
||||||
{
|
{
|
||||||
_enemyDirection = EnemyDirection.Forward;
|
_enemyDirection = EnemyDirection.Forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetLeft()
|
private void SetLeft()
|
||||||
{
|
{
|
||||||
_enemyDirection = EnemyDirection.Left;
|
_enemyDirection = EnemyDirection.Left;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetRight()
|
private void SetRight()
|
||||||
{
|
{
|
||||||
_enemyDirection = EnemyDirection.Right;
|
_enemyDirection = EnemyDirection.Right;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetBack()
|
private void SetBack()
|
||||||
{
|
{
|
||||||
_enemyDirection = EnemyDirection.Backward;
|
_enemyDirection = EnemyDirection.Backward;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,16 @@ public interface IEnemyModelView : INode3D
|
|||||||
|
|
||||||
public void PlayDeathAnimation();
|
public void PlayDeathAnimation();
|
||||||
|
|
||||||
|
public void PlayBuffAnimation();
|
||||||
|
|
||||||
|
public void PlayDebuffAnimation();
|
||||||
|
|
||||||
|
public void PlayHealAnimation();
|
||||||
|
|
||||||
|
public void PlayRustActivateAnimation();
|
||||||
|
|
||||||
|
public void PlayRustDamageAnimation();
|
||||||
|
|
||||||
public void PlayElementalDamageAnimation(ElementType elementType);
|
public void PlayElementalDamageAnimation(ElementType elementType);
|
||||||
|
|
||||||
public double ViewerSize { get; }
|
public double ViewerSize { get; }
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public partial class FleeBehavior : Node3D, IBehavior
|
|||||||
{
|
{
|
||||||
public override void _Notification(int what) => this.Notify(what);
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
|
|
||||||
[Export] private double _fleeSpeed { get; set; } = 300f;
|
[Export] public double FleeSpeed { get; set; } = 300f;
|
||||||
|
|
||||||
[Export] private double _thinkTime { get; set; } = 2f;
|
[Export] private double _thinkTime { get; set; } = 2f;
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ public partial class FleeBehavior : Node3D, IBehavior
|
|||||||
{
|
{
|
||||||
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
||||||
var parent = GetParent() as Node3D;
|
var parent = GetParent() as Node3D;
|
||||||
var velocity = parent.GlobalPosition.DirectionTo(nextVelocity) * (float)_fleeSpeed * (float)delta;
|
var velocity = parent.GlobalPosition.DirectionTo(nextVelocity) * (float)FleeSpeed * (float)delta;
|
||||||
EmitSignal(SignalName.OnVelocityComputed, velocity);
|
EmitSignal(SignalName.OnVelocityComputed, velocity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public partial class FollowBehavior : Node3D, IBehavior
|
|||||||
{
|
{
|
||||||
public override void _Notification(int what) => this.Notify(what);
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
|
|
||||||
[Export] private double _followSpeed { get; set; } = 100f;
|
[Export] public double FollowSpeed { get; set; } = 100f;
|
||||||
|
|
||||||
[Export] private double _thinkTime { get; set; } = 2f;
|
[Export] private double _thinkTime { get; set; } = 2f;
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ public partial class FollowBehavior : Node3D, IBehavior
|
|||||||
{
|
{
|
||||||
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
||||||
var parent = GetParent() as Node3D;
|
var parent = GetParent() as Node3D;
|
||||||
var velocity = parent.GlobalPosition.DirectionTo(nextVelocity) * (float)_followSpeed * (float)delta;
|
var velocity = parent.GlobalPosition.DirectionTo(nextVelocity) * (float)FollowSpeed * (float)delta;
|
||||||
EmitSignal(SignalName.OnVelocityComputed, velocity);
|
EmitSignal(SignalName.OnVelocityComputed, velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public partial class PatrolBehavior : Node3D, IBehavior
|
|||||||
{
|
{
|
||||||
public override void _Notification(int what) => this.Notify(what);
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
|
|
||||||
[Export] private double _patrolSpeed { get; set; } = 100f;
|
[Export] public double PatrolSpeed { get; set; } = 100f;
|
||||||
|
|
||||||
[Export] private double _thinkTime { get; set; } = 0.8f;
|
[Export] private double _thinkTime { get; set; } = 0.8f;
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ public partial class PatrolBehavior : Node3D, IBehavior
|
|||||||
{
|
{
|
||||||
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
||||||
var parent = GetParent() as Node3D;
|
var parent = GetParent() as Node3D;
|
||||||
var velocity = parent.GlobalPosition.DirectionTo(nextVelocity) * (float)_patrolSpeed * (float)delta;
|
var velocity = parent.GlobalPosition.DirectionTo(nextVelocity) * (float)PatrolSpeed * (float)delta;
|
||||||
EmitSignal(SignalName.OnVelocityComputed, velocity);
|
EmitSignal(SignalName.OnVelocityComputed, velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ public class EffectService
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
currentRoom.EnemiesInRoom.ForEach(e => e.HealthComponent.SetCurrentHealth(e.HealthComponent.MaximumHP.Value));
|
currentRoom.EnemiesInRoom.ForEach(e => e.HealthComponent.SetCurrentHealth(e.HealthComponent.MaximumHP.Value));
|
||||||
|
currentRoom.EnemiesInRoom.ForEach(e => e.OnHealed());
|
||||||
_player.HealthComponent.SetCurrentHealth(_player.HealthComponent.MaximumHP.Value);
|
_player.HealthComponent.SetCurrentHealth(_player.HealthComponent.MaximumHP.Value);
|
||||||
SfxDatabase.Instance.Play(SoundEffect.HealHP);
|
SfxDatabase.Instance.Play(SoundEffect.HealHP);
|
||||||
}
|
}
|
||||||
@@ -225,6 +226,11 @@ public class EffectService
|
|||||||
enemy.MoveEnemyToNewRoom(randomRoom);
|
enemy.MoveEnemyToNewRoom(randomRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DisableEnemyMovement(IEnemy enemy)
|
||||||
|
{
|
||||||
|
enemy.SetEnemySpeedByMultiplier(0);
|
||||||
|
}
|
||||||
|
|
||||||
public void CloneEnemy(IEnemy enemy)
|
public void CloneEnemy(IEnemy enemy)
|
||||||
{
|
{
|
||||||
var enemyPosition = new Vector3(enemy.GlobalPosition.X, 0f, enemy.GlobalPosition.Z);
|
var enemyPosition = new Vector3(enemy.GlobalPosition.X, 0f, enemy.GlobalPosition.Z);
|
||||||
|
|||||||
@@ -116,35 +116,40 @@ public partial class ThrownItem : RigidBody3D, IThrownItem
|
|||||||
{
|
{
|
||||||
case UsableItemTag.LowerTargetTo1HP:
|
case UsableItemTag.LowerTargetTo1HP:
|
||||||
enemy.HealthComponent.SetCurrentHealth(1);
|
enemy.HealthComponent.SetCurrentHealth(1);
|
||||||
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
|
enemy.OnDebuff();
|
||||||
break;
|
break;
|
||||||
case UsableItemTag.DecreaseAllStats:
|
case UsableItemTag.DecreaseAllStats:
|
||||||
enemy.AttackComponent.Reduce(usableItem.Stats.BonusAttack);
|
enemy.AttackComponent.Reduce(usableItem.Stats.BonusAttack);
|
||||||
enemy.DefenseComponent.Reduce(usableItem.Stats.BonusDefense);
|
enemy.DefenseComponent.Reduce(usableItem.Stats.BonusDefense);
|
||||||
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
|
enemy.OnDebuff();
|
||||||
break;
|
break;
|
||||||
case UsableItemTag.DecreaseAttack:
|
case UsableItemTag.DecreaseAttack:
|
||||||
enemy.AttackComponent.LowerMaximumAttack(usableItem.Stats.BonusAttack);
|
enemy.AttackComponent.LowerMaximumAttack(usableItem.Stats.BonusAttack);
|
||||||
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
|
enemy.OnDebuff();
|
||||||
break;
|
break;
|
||||||
case UsableItemTag.DecreaseDefense:
|
case UsableItemTag.DecreaseDefense:
|
||||||
enemy.DefenseComponent.LowerMaximumDefense(usableItem.Stats.BonusDefense);
|
enemy.DefenseComponent.LowerMaximumDefense(usableItem.Stats.BonusDefense);
|
||||||
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
|
enemy.OnDebuff();
|
||||||
break;
|
break;
|
||||||
case UsableItemTag.IncreaseAttack:
|
case UsableItemTag.IncreaseAttack:
|
||||||
enemy.AttackComponent.RaiseMaximumAttack(usableItem.Stats.BonusAttack);
|
enemy.AttackComponent.RaiseMaximumAttack(usableItem.Stats.BonusAttack);
|
||||||
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
|
enemy.OnBuff();
|
||||||
break;
|
break;
|
||||||
case UsableItemTag.IncreaseDefense:
|
case UsableItemTag.IncreaseDefense:
|
||||||
enemy.DefenseComponent.RaiseMaximumDefense(usableItem.Stats.BonusDefense);
|
enemy.DefenseComponent.RaiseMaximumDefense(usableItem.Stats.BonusDefense);
|
||||||
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
|
enemy.OnBuff();
|
||||||
break;
|
break;
|
||||||
case UsableItemTag.TeleportToRandomLocation:
|
case UsableItemTag.TeleportToRandomLocation:
|
||||||
_effectService.TeleportToRandomRoom(enemy);
|
_effectService.TeleportToRandomRoom(enemy);
|
||||||
SfxDatabase.Instance.Play(SoundEffect.TeleportToRandomRoom);
|
SfxDatabase.Instance.Play(SoundEffect.TeleportToRandomRoom);
|
||||||
break;
|
break;
|
||||||
|
case UsableItemTag.GlueAllEquipment:
|
||||||
|
_effectService.DisableEnemyMovement(enemy);
|
||||||
|
enemy.OnDebuff();
|
||||||
|
break;
|
||||||
case UsableItemTag.Clone:
|
case UsableItemTag.Clone:
|
||||||
_effectService.CloneEnemy(enemy);
|
_effectService.CloneEnemy(enemy);
|
||||||
|
enemy.OnBuff();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
var damageDealt = DamageCalculator.CalculateDamage(new AttackData(usableItem.ThrowDamage, ElementType.None), enemy.DefenseComponent.CurrentDefense.Value, enemy.ElementalResistanceSet);
|
var damageDealt = DamageCalculator.CalculateDamage(new AttackData(usableItem.ThrowDamage, ElementType.None), enemy.DefenseComponent.CurrentDefense.Value, enemy.ElementalResistanceSet);
|
||||||
@@ -152,6 +157,20 @@ public partial class ThrownItem : RigidBody3D, IThrownItem
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ItemThatIsThrown is BoxItem boxItem)
|
||||||
|
{
|
||||||
|
switch (boxItem.Stats.ItemTag)
|
||||||
|
{
|
||||||
|
case ItemTag.RestrictUnequip:
|
||||||
|
_effectService.DisableEnemyMovement(enemy);
|
||||||
|
enemy.OnDebuff();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
var damageDealt = DamageCalculator.CalculateDamage(new AttackData(boxItem.ThrowDamage, ElementType.None), enemy.DefenseComponent.CurrentDefense.Value, enemy.ElementalResistanceSet);
|
||||||
|
enemy.HealthComponent.Damage(damageDealt, ElementType.None);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var damageDealt = DamageCalculator.CalculateDamage(new AttackData(ItemThatIsThrown.ThrowDamage, ElementType.None), enemy.DefenseComponent.CurrentDefense.Value, enemy.ElementalResistanceSet);
|
var damageDealt = DamageCalculator.CalculateDamage(new AttackData(ItemThatIsThrown.ThrowDamage, ElementType.None), enemy.DefenseComponent.CurrentDefense.Value, enemy.ElementalResistanceSet);
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
shader_type canvas_item;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Color to use for the shock.
|
||||||
|
*/
|
||||||
|
uniform vec3 shock_color : source_color = vec3(0.0, 0.0, 0.6);
|
||||||
|
/**
|
||||||
|
Initial amplitude of the shock. This will start at this amplitude and
|
||||||
|
gradually attenuate.
|
||||||
|
*/
|
||||||
|
uniform float amplitude = 12.0;
|
||||||
|
|
||||||
|
uniform float progress: hint_range(0.0, 1.0) = -1.0;
|
||||||
|
/**
|
||||||
|
How fast shold it move side to side, more frequency means it'll move more quickly
|
||||||
|
side to side.
|
||||||
|
*/
|
||||||
|
uniform float frequecy = 10.0;
|
||||||
|
|
||||||
|
void vertex() {
|
||||||
|
float exponent = mod(progress, 3.0);
|
||||||
|
VERTEX.x += amplitude * exp(-3.0*exponent) * sin(frequecy*exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
float exponent = mod(progress, 3.0);
|
||||||
|
vec3 normal_color = texture(TEXTURE, UV).rgb;
|
||||||
|
COLOR.rgb = normal_color + shock_color * exp(-3.0*exponent);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://d4a0aeg7ud76g
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
shader_type canvas_item;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Color to use for the shock.
|
||||||
|
*/
|
||||||
|
uniform vec3 shock_color : source_color = vec3(0.3, 0.0, 0.5);
|
||||||
|
/**
|
||||||
|
Initial amplitude of the shock. This will start at this amplitude and
|
||||||
|
gradually attenuate.
|
||||||
|
*/
|
||||||
|
uniform float amplitude = 20.0;
|
||||||
|
|
||||||
|
uniform float progress: hint_range(0.0, 1.0) = -1.0;
|
||||||
|
/**
|
||||||
|
How fast shold it move side to side, more frequency means it'll move more quickly
|
||||||
|
side to side.
|
||||||
|
*/
|
||||||
|
uniform float frequecy = 10.0;
|
||||||
|
|
||||||
|
void vertex() {
|
||||||
|
float exponent = mod(progress, 3.0);
|
||||||
|
VERTEX.x += amplitude * exp(-3.0*exponent) * sin(frequecy*exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
float exponent = mod(progress, 3.0);
|
||||||
|
vec3 normal_color = texture(TEXTURE, UV).rgb;
|
||||||
|
COLOR.rgb = normal_color + shock_color * exp(-3.0*exponent);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dv81aqs1cd1br
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
shader_type canvas_item;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Color to use for the shock.
|
||||||
|
*/
|
||||||
|
uniform vec3 shock_color : source_color = vec3(0.0, 0.6, 0.0);
|
||||||
|
/**
|
||||||
|
Initial amplitude of the shock. This will start at this amplitude and
|
||||||
|
gradually attenuate.
|
||||||
|
*/
|
||||||
|
uniform float amplitude = 12.0;
|
||||||
|
|
||||||
|
uniform float progress: hint_range(0.0, 1.0) = -1.0;
|
||||||
|
/**
|
||||||
|
How fast shold it move side to side, more frequency means it'll move more quickly
|
||||||
|
side to side.
|
||||||
|
*/
|
||||||
|
uniform float frequecy = 10.0;
|
||||||
|
|
||||||
|
void vertex() {
|
||||||
|
float exponent = mod(progress, 3.0);
|
||||||
|
VERTEX.x += amplitude * exp(-3.0*exponent) * sin(frequecy*exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
float exponent = mod(progress, 3.0);
|
||||||
|
vec3 normal_color = texture(TEXTURE, UV).rgb;
|
||||||
|
COLOR.rgb = normal_color + shock_color * exp(-3.0*exponent);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bgf5fav78hmuj
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
shader_type canvas_item;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Color to use for the shock.
|
||||||
|
*/
|
||||||
|
uniform vec3 shock_color : source_color = vec3(0.6, 0.3, 0.0);
|
||||||
|
/**
|
||||||
|
Initial amplitude of the shock. This will start at this amplitude and
|
||||||
|
gradually attenuate.
|
||||||
|
*/
|
||||||
|
uniform float amplitude = 30.0;
|
||||||
|
|
||||||
|
uniform float progress: hint_range(0.0, 1.0) = -1.0;
|
||||||
|
/**
|
||||||
|
How fast shold it move side to side, more frequency means it'll move more quickly
|
||||||
|
side to side.
|
||||||
|
*/
|
||||||
|
uniform float frequecy = 10.0;
|
||||||
|
|
||||||
|
void vertex() {
|
||||||
|
float exponent = mod(progress, 3.0);
|
||||||
|
VERTEX.x += amplitude * exp(-3.0*exponent) * sin(frequecy*exponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
float exponent = mod(progress, 3.0);
|
||||||
|
vec3 normal_color = texture(TEXTURE, UV).rgb;
|
||||||
|
COLOR.rgb = normal_color + shock_color * exp(-3.0*exponent);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://uq8jl6jjs453
|
||||||
Reference in New Issue
Block a user