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 OnBuff();
|
||||
|
||||
public void OnDebuff();
|
||||
|
||||
public void OnHealed();
|
||||
|
||||
public void IncrementDefeatCount();
|
||||
|
||||
public int GetDefeatCount(IEnemy enemyType);
|
||||
@@ -39,6 +45,8 @@ namespace Zennysoft.Ma.Adapter.Entity
|
||||
|
||||
public ElementalResistanceSet ElementalResistanceSet { get; }
|
||||
|
||||
public void SetEnemySpeedByMultiplier(double multiplier);
|
||||
|
||||
public int InitialHP { get; }
|
||||
|
||||
public int InitialAttack { get; }
|
||||
|
||||
@@ -213,6 +213,23 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
||||
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)
|
||||
{
|
||||
foreach (var room in roomList)
|
||||
@@ -233,6 +250,16 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
||||
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)
|
||||
{
|
||||
if (newRoom is MonsterRoom monsterRoom)
|
||||
@@ -277,6 +304,7 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
||||
{
|
||||
_rustTimer.Start();
|
||||
_rustDuration.Start();
|
||||
EnemyModelView.PlayRustActivateAnimation();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -287,7 +315,7 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLo
|
||||
private void _rustTimer_Timeout()
|
||||
{
|
||||
HealthComponent.Damage(3, ElementType.Ferrum);
|
||||
TakeHit(ElementType.Ferrum);
|
||||
EnemyModelView.PlayRustDamageAnimation();
|
||||
}
|
||||
|
||||
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 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 void AnimationTree_AnimationFinished(StringName animName)
|
||||
|
||||
@@ -66,6 +66,39 @@ public partial class EnemyModelView2D : EnemyModelView, IEnemyModelView
|
||||
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)
|
||||
{
|
||||
if (elementType == ElementType.Igneous)
|
||||
@@ -104,7 +137,6 @@ public partial class EnemyModelView2D : EnemyModelView, IEnemyModelView
|
||||
EarthHitAnimation.Stop();
|
||||
EarthHitAnimation.Play("EarthHit");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private EnemyDirection GetEnemyDirection(
|
||||
|
||||
@@ -27,6 +27,16 @@ public interface IEnemyModelView : INode3D
|
||||
|
||||
public void PlayDeathAnimation();
|
||||
|
||||
public void PlayBuffAnimation();
|
||||
|
||||
public void PlayDebuffAnimation();
|
||||
|
||||
public void PlayHealAnimation();
|
||||
|
||||
public void PlayRustActivateAnimation();
|
||||
|
||||
public void PlayRustDamageAnimation();
|
||||
|
||||
public void PlayElementalDamageAnimation(ElementType elementType);
|
||||
|
||||
public double ViewerSize { get; }
|
||||
|
||||
@@ -11,7 +11,7 @@ public partial class FleeBehavior : Node3D, IBehavior
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -52,7 +52,7 @@ public partial class FleeBehavior : Node3D, IBehavior
|
||||
{
|
||||
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ public partial class FollowBehavior : Node3D, IBehavior
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -56,7 +56,7 @@ public partial class FollowBehavior : Node3D, IBehavior
|
||||
{
|
||||
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ public partial class PatrolBehavior : Node3D, IBehavior
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -72,7 +72,7 @@ public partial class PatrolBehavior : Node3D, IBehavior
|
||||
{
|
||||
var nextVelocity = _navigationAgent.GetNextPathPosition();
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ public class EffectService
|
||||
return;
|
||||
|
||||
currentRoom.EnemiesInRoom.ForEach(e => e.HealthComponent.SetCurrentHealth(e.HealthComponent.MaximumHP.Value));
|
||||
currentRoom.EnemiesInRoom.ForEach(e => e.OnHealed());
|
||||
_player.HealthComponent.SetCurrentHealth(_player.HealthComponent.MaximumHP.Value);
|
||||
SfxDatabase.Instance.Play(SoundEffect.HealHP);
|
||||
}
|
||||
@@ -225,6 +226,11 @@ public class EffectService
|
||||
enemy.MoveEnemyToNewRoom(randomRoom);
|
||||
}
|
||||
|
||||
public void DisableEnemyMovement(IEnemy enemy)
|
||||
{
|
||||
enemy.SetEnemySpeedByMultiplier(0);
|
||||
}
|
||||
|
||||
public void CloneEnemy(IEnemy enemy)
|
||||
{
|
||||
var enemyPosition = new Vector3(enemy.GlobalPosition.X, 0f, enemy.GlobalPosition.Z);
|
||||
|
||||
@@ -116,35 +116,40 @@ public partial class ThrownItem : RigidBody3D, IThrownItem
|
||||
{
|
||||
case UsableItemTag.LowerTargetTo1HP:
|
||||
enemy.HealthComponent.SetCurrentHealth(1);
|
||||
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
|
||||
enemy.OnDebuff();
|
||||
break;
|
||||
case UsableItemTag.DecreaseAllStats:
|
||||
enemy.AttackComponent.Reduce(usableItem.Stats.BonusAttack);
|
||||
enemy.DefenseComponent.Reduce(usableItem.Stats.BonusDefense);
|
||||
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
|
||||
enemy.OnDebuff();
|
||||
break;
|
||||
case UsableItemTag.DecreaseAttack:
|
||||
enemy.AttackComponent.LowerMaximumAttack(usableItem.Stats.BonusAttack);
|
||||
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
|
||||
enemy.OnDebuff();
|
||||
break;
|
||||
case UsableItemTag.DecreaseDefense:
|
||||
enemy.DefenseComponent.LowerMaximumDefense(usableItem.Stats.BonusDefense);
|
||||
SfxDatabase.Instance.Play(SoundEffect.DecreaseStat);
|
||||
enemy.OnDebuff();
|
||||
break;
|
||||
case UsableItemTag.IncreaseAttack:
|
||||
enemy.AttackComponent.RaiseMaximumAttack(usableItem.Stats.BonusAttack);
|
||||
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
|
||||
enemy.OnBuff();
|
||||
break;
|
||||
case UsableItemTag.IncreaseDefense:
|
||||
enemy.DefenseComponent.RaiseMaximumDefense(usableItem.Stats.BonusDefense);
|
||||
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
|
||||
enemy.OnBuff();
|
||||
break;
|
||||
case UsableItemTag.TeleportToRandomLocation:
|
||||
_effectService.TeleportToRandomRoom(enemy);
|
||||
SfxDatabase.Instance.Play(SoundEffect.TeleportToRandomRoom);
|
||||
break;
|
||||
case UsableItemTag.GlueAllEquipment:
|
||||
_effectService.DisableEnemyMovement(enemy);
|
||||
enemy.OnDebuff();
|
||||
break;
|
||||
case UsableItemTag.Clone:
|
||||
_effectService.CloneEnemy(enemy);
|
||||
enemy.OnBuff();
|
||||
break;
|
||||
default:
|
||||
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;
|
||||
}
|
||||
}
|
||||
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
|
||||
{
|
||||
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