diff --git a/Classes/StatusEffects/Assets/Status_Dodge.png b/Classes/StatusEffects/Assets/Status_Dodge.png new file mode 100644 index 00000000..8b3d093b Binary files /dev/null and b/Classes/StatusEffects/Assets/Status_Dodge.png differ diff --git a/Classes/StatusEffects/Assets/Status_Dodge.png.import b/Classes/StatusEffects/Assets/Status_Dodge.png.import new file mode 100644 index 00000000..58c021b9 --- /dev/null +++ b/Classes/StatusEffects/Assets/Status_Dodge.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://li36jtg8c5ao" +path="res://.godot/imported/Status_Dodge.png-2abb54401cc55e9c1d845790ee310613.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Classes/StatusEffects/Assets/Status_Dodge.png" +dest_files=["res://.godot/imported/Status_Dodge.png-2abb54401cc55e9c1d845790ee310613.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Classes/StatusEffects/StatusEffect.cs b/Classes/StatusEffects/StatusEffect.cs index f2198b1e..6e040316 100644 --- a/Classes/StatusEffects/StatusEffect.cs +++ b/Classes/StatusEffects/StatusEffect.cs @@ -110,6 +110,29 @@ public partial class StatusEffect : TextureRect, IBattleEvent ) .SetTags(true); + private static readonly Action DodgeEffect = (e, self) => + { + if (e is BattleDirector.Harbinger.OnDamageInstanceArgs dmgArgs) + { + if (dmgArgs.Dmg.Target != self.Sufferer || dmgArgs.Dmg.Damage <= 0) + return; + if (StageProducer.GlobalRng.RandiRange(0, 1) == 0) + return; + + dmgArgs.Dmg.ModifyDamage(0, 0); + self.DecCount(); + } + }; + + public static readonly StatusEffect Dodge = new StatusEffect() + .InitStatus( + "Dodge", + DodgeEffect, + BattleEffectTrigger.OnDamageInstance, + GD.Load("res://Classes/StatusEffects/Assets/Status_Dodge.png") + ) + .SetTags(true); + public static readonly Action DisableEffect = (_, self) => { self.DecCount(); diff --git a/Scenes/BattleDirector/Scripts/NotePlacementBar.cs b/Scenes/BattleDirector/Scripts/NotePlacementBar.cs index 9b1b74ee..ad0f7cf7 100644 --- a/Scenes/BattleDirector/Scripts/NotePlacementBar.cs +++ b/Scenes/BattleDirector/Scripts/NotePlacementBar.cs @@ -196,6 +196,11 @@ public int GetCurrentCombo() return _currentCombo; } + public double GetCurrentBarValue() + { + return CurrentBarValue; + } + public void ResetCurrentCombo() { _currentCombo = 0; diff --git a/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader new file mode 100644 index 00000000..e31b6a06 --- /dev/null +++ b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader @@ -0,0 +1,54 @@ +/* + Glitch Effect Shader by Yui Kinomoto @arlez80 + + MIT License +*/ + +shader_type canvas_item; + +uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap; + +// 振動の強さ +uniform float shake_power = 0.03; +// 振動率 +uniform float shake_rate : hint_range( 0.0, 1.0 ) = 0.2; +// 振動速度 +uniform float shake_speed = 5.0; +// 振動ブロックサイズ +uniform float shake_block_size = 30.5; +// 色の分離率 +uniform float shake_color_rate : hint_range( 0.0, 1.0 ) = 0.01; + +float random( float seed ) +{ + return fract( 543.2543 * sin( dot( vec2( seed, seed ), vec2( 3525.46, -54.3415 ) ) ) ); +} + +void fragment( ) +{ + float enable_shift = float( + random( trunc( TIME * shake_speed ) ) + < shake_rate + ); + + vec2 fixed_uv = SCREEN_UV; + fixed_uv.x += ( + random( + ( trunc( SCREEN_UV.y * shake_block_size ) / shake_block_size ) + + TIME + ) - 0.5 + ) * shake_power * enable_shift; + + vec4 pixel_color = textureLod( SCREEN_TEXTURE, fixed_uv, 0.0 ); + pixel_color.r = mix( + pixel_color.r + , textureLod( SCREEN_TEXTURE, fixed_uv + vec2( shake_color_rate, 0.0 ), 0.0 ).r + , enable_shift + ); + pixel_color.b = mix( + pixel_color.b + , textureLod( SCREEN_TEXTURE, fixed_uv + vec2( -shake_color_rate, 0.0 ), 0.0 ).b + , enable_shift + ); + COLOR = pixel_color; +} diff --git a/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader.uid b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader.uid new file mode 100644 index 00000000..5c549d47 --- /dev/null +++ b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader.uid @@ -0,0 +1 @@ +uid://df5rjsuxn4o70 diff --git a/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs new file mode 100644 index 00000000..97d2013e --- /dev/null +++ b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs @@ -0,0 +1,47 @@ +using System; +using Godot; + +public partial class GlitchScript : Node +{ + private ShaderMaterial _glitchMaterial; + private Timer _glitchTimer; + + [Export] + public Sprite2D Sprite; + + public override void _Ready() + { + var shader = GD.Load( + "res://Scenes/Puppets/Enemies/CyberFox/Assets/GlitchEffect.gdshader" + ); + _glitchMaterial = new ShaderMaterial { Shader = shader }; + Sprite.Material = _glitchMaterial; + + DisableGlitch(); + _glitchTimer = new Timer { OneShot = true, Autostart = false }; + AddChild(_glitchTimer); + _glitchTimer.Timeout += OnGlitchTimerTimeout; + } + + public void TriggerGlitch(float duration) + { + EnableGlitch(); + _glitchTimer.WaitTime = duration; + _glitchTimer.Start(); + } + + private void OnGlitchTimerTimeout() + { + DisableGlitch(); + } + + private void EnableGlitch() + { + _glitchMaterial.SetShaderParameter("shake_rate", 0.8f); + } + + private void DisableGlitch() + { + _glitchMaterial.SetShaderParameter("shake_rate", 0.0f); + } +} diff --git a/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs.uid b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs.uid new file mode 100644 index 00000000..ec5951d6 --- /dev/null +++ b/Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs.uid @@ -0,0 +1 @@ +uid://3yclsl4kckx4 diff --git a/Scenes/Puppets/Enemies/CyberFox/CyberFox.tscn b/Scenes/Puppets/Enemies/CyberFox/CyberFox.tscn index 4ac8e277..ae63b465 100644 --- a/Scenes/Puppets/Enemies/CyberFox/CyberFox.tscn +++ b/Scenes/Puppets/Enemies/CyberFox/CyberFox.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=7 format=3 uid="uid://2iq6mp0o5eri"] +[gd_scene load_steps=8 format=3 uid="uid://2iq6mp0o5eri"] [ext_resource type="Script" uid="uid://dnkjrr1f5up7x" path="res://Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs" id="1_e1x4p"] [ext_resource type="PackedScene" uid="uid://cdoguwlxehbpg" path="res://Scenes/Puppets/StatusContainer.tscn" id="2_t5538"] [ext_resource type="Texture2D" uid="uid://dy61pskhqgjoo" path="res://Scenes/Puppets/Enemies/CyberFox/Assets/CyberFox.png" id="3_e1x4p"] [ext_resource type="PackedScene" uid="uid://bgomxovxs7sr8" path="res://Scenes/Puppets/HealthBar.tscn" id="4_lmj2w"] +[ext_resource type="Script" uid="uid://3yclsl4kckx4" path="res://Scenes/Puppets/Enemies/CyberFox/Assets/GlitchScript.cs" id="5_a0uir"] [sub_resource type="Gradient" id="Gradient_c7cx1"] offsets = PackedFloat32Array(0.0227273, 1) @@ -15,8 +16,9 @@ gradient = SubResource("Gradient_c7cx1") width = 100 height = 18 -[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("HealthBar", "Sprite", "_statusContainer")] +[node name="EnemPuppet" type="Node2D" node_paths=PackedStringArray("_effectNode", "HealthBar", "Sprite", "_statusContainer")] script = ExtResource("1_e1x4p") +_effectNode = NodePath("GlitchNode") HealthBar = NodePath("ProgressBar") Sprite = NodePath("Sprite") _statusContainer = NodePath("StatusContainer") @@ -26,7 +28,7 @@ offset_top = -6.0 offset_bottom = 30.0 [node name="Sprite" type="Sprite2D" parent="."] -position = Vector2(0, -12) +position = Vector2(10, -12) texture = ExtResource("3_e1x4p") [node name="ProgressBar" parent="." instance=ExtResource("4_lmj2w")] @@ -35,3 +37,12 @@ offset_top = 32.0 offset_right = 50.0 offset_bottom = 52.0 texture_progress = SubResource("GradientTexture2D_c0jk6") + +[node name="GlitchNode" type="Node2D" parent="." node_paths=PackedStringArray("Sprite")] +position = Vector2(10, 0) +script = ExtResource("5_a0uir") +Sprite = NodePath("Sprite2D") + +[node name="Sprite2D" type="Sprite2D" parent="GlitchNode"] +position = Vector2(0, -12) +texture = ExtResource("3_e1x4p") diff --git a/Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs b/Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs index 6d47e12d..7e381731 100644 --- a/Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs +++ b/Scenes/Puppets/Enemies/CyberFox/P_CyberFox.cs @@ -7,6 +7,9 @@ public partial class P_CyberFox : EnemyPuppet public static new readonly string LoadPath = "res://Scenes/Puppets/Enemies/CyberFox/CyberFox.tscn"; + [Export] + private GlitchScript _effectNode; + public override void _Ready() { MaxHealth = 130; @@ -26,5 +29,19 @@ public override void _Ready() enemTween.SetEase(Tween.EaseType.InOut); enemTween.SetLoops(); enemTween.Play(); + + BattleEvents = new EnemyEffect[] + { + new EnemyEffect( + this, + BattleEffectTrigger.OnLoop, + 1, + (e, eff, val) => + { + e.BD.AddStatus(Targetting.First, StatusEffect.Dodge, 1); + _effectNode.TriggerGlitch(1f); + } + ), + }; } } diff --git a/Scenes/Puppets/Enemies/Turtle/P_Turtle.cs b/Scenes/Puppets/Enemies/Turtle/P_Turtle.cs index 8006b907..5b25cc85 100644 --- a/Scenes/Puppets/Enemies/Turtle/P_Turtle.cs +++ b/Scenes/Puppets/Enemies/Turtle/P_Turtle.cs @@ -19,5 +19,24 @@ public override void _Ready() enemTween.SetEase(Tween.EaseType.InOut); enemTween.SetLoops(); enemTween.Play(); + + BattleEvents = new EnemyEffect[] + { + new EnemyEffect( + this, + BattleEffectTrigger.OnLoop, + 1, + (e, eff, val) => + { + // take 1/4th of player's energy, and heal that amount + int quarterEnergy = (int)e.BD.NPB.GetCurrentBarValue() / 4; + e.BD.NPB.IncreaseCharge(-quarterEnergy); + this.Heal(quarterEnergy); + + //gain block based on val + e.BD.AddStatus(Targetting.First, StatusEffect.Block, val); + } + ), + }; } }