diff --git a/Assets/Animations/stun.res b/Assets/Animations/stun.res new file mode 100644 index 0000000..24458f6 Binary files /dev/null and b/Assets/Animations/stun.res differ diff --git a/Assets/Fonts/alagard-spaced.tres b/Assets/Fonts/alagard-spaced.tres new file mode 100644 index 0000000..432e03f --- /dev/null +++ b/Assets/Fonts/alagard-spaced.tres @@ -0,0 +1,7 @@ +[gd_resource type="FontVariation" load_steps=2 format=3 uid="uid://ndkrorerbxft"] + +[ext_resource type="FontFile" uid="uid://cgwa8bjiyv534" path="res://Assets/Fonts/alagard.ttf" id="1_krbnd"] + +[resource] +base_font = ExtResource("1_krbnd") +spacing_glyph = 4 diff --git a/Assets/Fonts/compass-pro-spaced.tres b/Assets/Fonts/compass-pro-spaced.tres new file mode 100644 index 0000000..335a2f0 --- /dev/null +++ b/Assets/Fonts/compass-pro-spaced.tres @@ -0,0 +1,7 @@ +[gd_resource type="FontVariation" load_steps=2 format=3 uid="uid://bjnmfgt5yqle7"] + +[ext_resource type="FontFile" uid="uid://bo3obq6sos7lu" path="res://Assets/Fonts/compass-pro.ttf" id="1_brr65"] + +[resource] +base_font = ExtResource("1_brr65") +spacing_glyph = 4 diff --git a/Assets/Fonts/compass-pro.ttf b/Assets/Fonts/compass-pro.ttf new file mode 100644 index 0000000..5432d65 Binary files /dev/null and b/Assets/Fonts/compass-pro.ttf differ diff --git a/Assets/Fonts/compass-pro.ttf.import b/Assets/Fonts/compass-pro.ttf.import new file mode 100644 index 0000000..89ed156 --- /dev/null +++ b/Assets/Fonts/compass-pro.ttf.import @@ -0,0 +1,33 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://bo3obq6sos7lu" +path="res://.godot/imported/compass-pro.ttf-5e813dda823d14f9501edd94273a527c.fontdata" + +[deps] + +source_file="res://Assets/Fonts/compass-pro.ttf" +dest_files=["res://.godot/imported/compass-pro.ttf-5e813dda823d14f9501edd94273a527c.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/Assets/Music/gillette.mp3 b/Assets/Music/gillette.mp3 new file mode 100644 index 0000000..bdf52b0 Binary files /dev/null and b/Assets/Music/gillette.mp3 differ diff --git a/Assets/Music/gillette.mp3.import b/Assets/Music/gillette.mp3.import new file mode 100644 index 0000000..35c9a70 --- /dev/null +++ b/Assets/Music/gillette.mp3.import @@ -0,0 +1,19 @@ +[remap] + +importer="mp3" +type="AudioStreamMP3" +uid="uid://ipss4y2gkk3y" +path="res://.godot/imported/gillette.mp3-5dd6f93f1f9df01778f80e3dd2caeb1e.mp3str" + +[deps] + +source_file="res://Assets/Music/gillette.mp3" +dest_files=["res://.godot/imported/gillette.mp3-5dd6f93f1f9df01778f80e3dd2caeb1e.mp3str"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/Assets/Sounds/parry.wav b/Assets/Sounds/parry.wav index 7ed32bf..9558d8b 100644 Binary files a/Assets/Sounds/parry.wav and b/Assets/Sounds/parry.wav differ diff --git a/Assets/Sounds/rauuul.wav b/Assets/Sounds/rauuul.wav new file mode 100644 index 0000000..5d8bfea Binary files /dev/null and b/Assets/Sounds/rauuul.wav differ diff --git a/Assets/Sounds/rauuul.wav.import b/Assets/Sounds/rauuul.wav.import new file mode 100644 index 0000000..1d8d538 --- /dev/null +++ b/Assets/Sounds/rauuul.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://cqj44je3mvk60" +path="res://.godot/imported/rauuul.wav-9eb73999b440b60f20c6cb1832d4cb17.sample" + +[deps] + +source_file="res://Assets/Sounds/rauuul.wav" +dest_files=["res://.godot/imported/rauuul.wav-9eb73999b440b60f20c6cb1832d4cb17.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=0 diff --git a/Assets/Sounds/rock-smash.wav b/Assets/Sounds/rock-smash.wav new file mode 100644 index 0000000..8cda6ef Binary files /dev/null and b/Assets/Sounds/rock-smash.wav differ diff --git a/Assets/Sounds/rock-smash.wav.import b/Assets/Sounds/rock-smash.wav.import new file mode 100644 index 0000000..3025169 --- /dev/null +++ b/Assets/Sounds/rock-smash.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://jsnjoyaj6p5a" +path="res://.godot/imported/rock-smash.wav-5412810912e8fdbd3060f5accd900f03.sample" + +[deps] + +source_file="res://Assets/Sounds/rock-smash.wav" +dest_files=["res://.godot/imported/rock-smash.wav-5412810912e8fdbd3060f5accd900f03.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=0 diff --git a/Assets/Sounds/unsheathe.wav b/Assets/Sounds/unsheathe.wav new file mode 100644 index 0000000..b2a4170 Binary files /dev/null and b/Assets/Sounds/unsheathe.wav differ diff --git a/Assets/Sounds/unsheathe.wav.import b/Assets/Sounds/unsheathe.wav.import new file mode 100644 index 0000000..4debf52 --- /dev/null +++ b/Assets/Sounds/unsheathe.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://cceld51anbm1m" +path="res://.godot/imported/unsheathe.wav-44389853e33f8a5eeb838ecbc38c9e52.sample" + +[deps] + +source_file="res://Assets/Sounds/unsheathe.wav" +dest_files=["res://.godot/imported/unsheathe.wav-44389853e33f8a5eeb838ecbc38c9e52.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=0 diff --git a/Assets/Sounds/whoosh.wav b/Assets/Sounds/whoosh.wav new file mode 100644 index 0000000..7d4d197 Binary files /dev/null and b/Assets/Sounds/whoosh.wav differ diff --git a/Assets/Sounds/whoosh.wav.import b/Assets/Sounds/whoosh.wav.import new file mode 100644 index 0000000..f336874 --- /dev/null +++ b/Assets/Sounds/whoosh.wav.import @@ -0,0 +1,24 @@ +[remap] + +importer="wav" +type="AudioStreamWAV" +uid="uid://qvthq6tppp63" +path="res://.godot/imported/whoosh.wav-ed2d61376c9fa3c90f1bcd8d0d47a04b.sample" + +[deps] + +source_file="res://Assets/Sounds/whoosh.wav" +dest_files=["res://.godot/imported/whoosh.wav-ed2d61376c9fa3c90f1bcd8d0d47a04b.sample"] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=0 diff --git a/Assets/Sprites/Characters/doc.ase b/Assets/Sprites/Characters/doc.ase index edb9f18..14a189e 100644 Binary files a/Assets/Sprites/Characters/doc.ase and b/Assets/Sprites/Characters/doc.ase differ diff --git a/Assets/Sprites/Characters/doc.png b/Assets/Sprites/Characters/doc.png index cd4c281..2141d27 100644 Binary files a/Assets/Sprites/Characters/doc.png and b/Assets/Sprites/Characters/doc.png differ diff --git a/Assets/Sprites/Characters/forsen-hand.ase b/Assets/Sprites/Characters/forsen-hand.ase new file mode 100644 index 0000000..ddccb85 Binary files /dev/null and b/Assets/Sprites/Characters/forsen-hand.ase differ diff --git a/Assets/Sprites/Characters/forsen-hand.png b/Assets/Sprites/Characters/forsen-hand.png new file mode 100644 index 0000000..8deb621 Binary files /dev/null and b/Assets/Sprites/Characters/forsen-hand.png differ diff --git a/Assets/Sprites/Characters/forsen-hand.png.import b/Assets/Sprites/Characters/forsen-hand.png.import new file mode 100644 index 0000000..c7966e6 --- /dev/null +++ b/Assets/Sprites/Characters/forsen-hand.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dpepm54hjuyga" +path="res://.godot/imported/forsen-hand.png-d22d8449d49935bb2be976828e8a6ea2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Characters/forsen-hand.png" +dest_files=["res://.godot/imported/forsen-hand.png-d22d8449d49935bb2be976828e8a6ea2.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/Assets/Sprites/Characters/forsen2-portrait.png b/Assets/Sprites/Characters/forsen2-portrait.png new file mode 100644 index 0000000..d2e13c8 Binary files /dev/null and b/Assets/Sprites/Characters/forsen2-portrait.png differ diff --git a/Assets/Sprites/Characters/forsen2-portrait.png.import b/Assets/Sprites/Characters/forsen2-portrait.png.import new file mode 100644 index 0000000..d43f62c --- /dev/null +++ b/Assets/Sprites/Characters/forsen2-portrait.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bwlk47lcbhlds" +path="res://.godot/imported/forsen2-portrait.png-ca8f11b7ad39ec3d34d5a24ad210303a.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Characters/forsen2-portrait.png" +dest_files=["res://.godot/imported/forsen2-portrait.png-ca8f11b7ad39ec3d34d5a24ad210303a.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/Assets/Sprites/Characters/forsen2.ase b/Assets/Sprites/Characters/forsen2.ase index 614a72c..561ec0f 100644 Binary files a/Assets/Sprites/Characters/forsen2.ase and b/Assets/Sprites/Characters/forsen2.ase differ diff --git a/Assets/Sprites/Characters/forsen2.png b/Assets/Sprites/Characters/forsen2.png index cf9d00c..15d9adc 100644 Binary files a/Assets/Sprites/Characters/forsen2.png and b/Assets/Sprites/Characters/forsen2.png differ diff --git a/Assets/Sprites/Characters/lost-soul.ase b/Assets/Sprites/Characters/lost-soul.ase new file mode 100644 index 0000000..7666210 Binary files /dev/null and b/Assets/Sprites/Characters/lost-soul.ase differ diff --git a/Assets/Sprites/Misc/compact-disc.ase b/Assets/Sprites/Misc/compact-disc.ase new file mode 100644 index 0000000..2b4f5eb Binary files /dev/null and b/Assets/Sprites/Misc/compact-disc.ase differ diff --git a/Assets/Sprites/Misc/compact-disc.png b/Assets/Sprites/Misc/compact-disc.png new file mode 100644 index 0000000..05cfc7f Binary files /dev/null and b/Assets/Sprites/Misc/compact-disc.png differ diff --git a/Assets/Sprites/Misc/compact-disc.png.import b/Assets/Sprites/Misc/compact-disc.png.import new file mode 100644 index 0000000..9c834db --- /dev/null +++ b/Assets/Sprites/Misc/compact-disc.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://qc6agawkad5k" +path="res://.godot/imported/compact-disc.png-5b17d460d1330809bc650ebf5321160e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Misc/compact-disc.png" +dest_files=["res://.godot/imported/compact-disc.png-5b17d460d1330809bc650ebf5321160e.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/Assets/Sprites/Particles/DocIntroParticles.tres b/Assets/Sprites/Particles/DocIntroParticles.tres new file mode 100644 index 0000000..ab58291 --- /dev/null +++ b/Assets/Sprites/Particles/DocIntroParticles.tres @@ -0,0 +1,22 @@ +[gd_resource type="ParticleProcessMaterial" load_steps=3 format=3 uid="uid://rcjujd5dv7lm"] + +[sub_resource type="Gradient" id="Gradient_v7xci"] +offsets = PackedFloat32Array(0.525926, 0.6) +colors = PackedColorArray(0, 0, 0, 1, 1, 0, 0, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_pntll"] +gradient = SubResource("Gradient_v7xci") + +[resource] +particle_flag_disable_z = true +spread = 180.0 +gravity = Vector3(0, 0, 0) +initial_velocity_min = 64.0 +initial_velocity_max = 96.0 +orbit_velocity_min = 0.0 +orbit_velocity_max = 0.0 +linear_accel_min = -128.0 +linear_accel_max = -96.0 +scale_min = 0.1 +scale_max = 0.2 +color_initial_ramp = SubResource("GradientTexture1D_pntll") diff --git a/Assets/Sprites/Particles/NPCDamageProcessMaterial.tres b/Assets/Sprites/Particles/NPCDamageProcessMaterial.tres new file mode 100644 index 0000000..7789477 --- /dev/null +++ b/Assets/Sprites/Particles/NPCDamageProcessMaterial.tres @@ -0,0 +1,25 @@ +[gd_resource type="ParticleProcessMaterial" load_steps=3 format=3 uid="uid://bat28samf7ukd"] + +[sub_resource type="Curve" id="Curve_jqr7v"] +_data = [Vector2(0, 0), 0.0, 2.0, 0, 1, Vector2(0.5, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), -2.0, 0.0, 1, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_s2csc"] +curve = SubResource("Curve_jqr7v") + +[resource] +emission_shape = 1 +emission_sphere_radius = 8.0 +particle_flag_disable_z = true +direction = Vector3(0, -1, 0) +gravity = Vector3(0, 0, 0) +initial_velocity_min = 64.0 +initial_velocity_max = 128.0 +orbit_velocity_min = 0.0 +orbit_velocity_max = 0.0 +linear_accel_min = -256.0 +linear_accel_max = -128.0 +scale_min = 0.01 +scale_max = 0.02 +scale_curve = SubResource("CurveTexture_s2csc") +attractor_interaction_enabled = false diff --git a/Assets/Sprites/Particles/ParryParticles.tres b/Assets/Sprites/Particles/ParryParticles.tres new file mode 100644 index 0000000..7b255aa --- /dev/null +++ b/Assets/Sprites/Particles/ParryParticles.tres @@ -0,0 +1,32 @@ +[gd_resource type="ParticleProcessMaterial" load_steps=5 format=3 uid="uid://cbfaqolx1ydvv"] + +[sub_resource type="Gradient" id="Gradient_44upg"] +offsets = PackedFloat32Array(0, 0.5) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_droiy"] +gradient = SubResource("Gradient_44upg") + +[sub_resource type="Curve" id="Curve_4kf4j"] +_data = [Vector2(0, 0.5), 0.0, 0.0, 0, 0, Vector2(0.1, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.5), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_qqrjb"] +curve = SubResource("Curve_4kf4j") + +[resource] +emission_shape = 1 +emission_sphere_radius = 4.0 +particle_flag_disable_z = true +spread = 180.0 +gravity = Vector3(0, 0, 0) +initial_velocity_min = 256.0 +initial_velocity_max = 256.0 +orbit_velocity_min = 0.0 +orbit_velocity_max = 0.0 +linear_accel_min = -512.0 +linear_accel_max = -512.0 +scale_min = 2.0 +scale_max = 2.0 +scale_curve = SubResource("CurveTexture_qqrjb") +color_ramp = SubResource("GradientTexture1D_droiy") diff --git a/Assets/Sprites/Particles/PlayerDamageProcessMaterial.tres b/Assets/Sprites/Particles/PlayerDamageProcessMaterial.tres new file mode 100644 index 0000000..1436696 --- /dev/null +++ b/Assets/Sprites/Particles/PlayerDamageProcessMaterial.tres @@ -0,0 +1,42 @@ +[gd_resource type="ParticleProcessMaterial" load_steps=7 format=3 uid="uid://x5qcq5muvc3g"] + +[sub_resource type="Gradient" id="Gradient_6k7fi"] +offsets = PackedFloat32Array(0, 0.540741, 0.592593, 1) +colors = PackedColorArray(0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_1phkb"] +gradient = SubResource("Gradient_6k7fi") + +[sub_resource type="Gradient" id="Gradient_3tax5"] +offsets = PackedFloat32Array(0, 0.533333, 1) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_13jjx"] +gradient = SubResource("Gradient_3tax5") + +[sub_resource type="Curve" id="Curve_0565g"] +_data = [Vector2(0, 0.5), 0.0, 5.0, 0, 1, Vector2(0.1, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), -1.11111, 0.0, 1, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_k4txv"] +curve = SubResource("Curve_0565g") + +[resource] +emission_shape = 2 +emission_sphere_radius = 32.0 +particle_flag_disable_z = true +direction = Vector3(0, -1, 0) +gravity = Vector3(0, 0, 0) +initial_velocity_min = 128.0 +initial_velocity_max = 256.0 +orbit_velocity_min = 0.0 +orbit_velocity_max = 0.0 +tangential_accel_min = -16.0 +tangential_accel_max = 16.0 +scale_min = 0.25 +scale_max = 0.25 +scale_curve = SubResource("CurveTexture_k4txv") +color_ramp = SubResource("GradientTexture1D_13jjx") +color_initial_ramp = SubResource("GradientTexture1D_1phkb") +turbulence_enabled = true +turbulence_noise_scale = 4.0 diff --git a/Assets/Sprites/Particles/circle-16.png b/Assets/Sprites/Particles/circle-16.png new file mode 100644 index 0000000..4d99d1b Binary files /dev/null and b/Assets/Sprites/Particles/circle-16.png differ diff --git a/Assets/Sprites/Particles/circle-16.png.import b/Assets/Sprites/Particles/circle-16.png.import new file mode 100644 index 0000000..539b139 --- /dev/null +++ b/Assets/Sprites/Particles/circle-16.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://c1a7lvb4uuwfy" +path="res://.godot/imported/circle-16.png-2c9910635b94cf262d735877f73c9d54.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Particles/circle-16.png" +dest_files=["res://.godot/imported/circle-16.png-2c9910635b94cf262d735877f73c9d54.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/Assets/Sprites/Particles/circle-64.png b/Assets/Sprites/Particles/circle-64.png new file mode 100644 index 0000000..6318d34 Binary files /dev/null and b/Assets/Sprites/Particles/circle-64.png differ diff --git a/Assets/Sprites/Particles/circle-64.png.import b/Assets/Sprites/Particles/circle-64.png.import new file mode 100644 index 0000000..86930a0 --- /dev/null +++ b/Assets/Sprites/Particles/circle-64.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d75jkoev5v3w" +path="res://.godot/imported/circle-64.png-14e0a440e19bf6b7889c28107bfd3189.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Particles/circle-64.png" +dest_files=["res://.godot/imported/circle-64.png-14e0a440e19bf6b7889c28107bfd3189.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/Assets/Sprites/Particles/circle.png b/Assets/Sprites/Particles/circle.png new file mode 100644 index 0000000..35051c4 Binary files /dev/null and b/Assets/Sprites/Particles/circle.png differ diff --git a/Assets/Sprites/Particles/circle.png.import b/Assets/Sprites/Particles/circle.png.import new file mode 100644 index 0000000..e013f1e --- /dev/null +++ b/Assets/Sprites/Particles/circle.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bd8l8kafb42dt" +path="res://.godot/imported/circle.png-e947f0f855ee4b3d0717c4cb325e029e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Particles/circle.png" +dest_files=["res://.godot/imported/circle.png-e947f0f855ee4b3d0717c4cb325e029e.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/Assets/Sprites/Particles/player-light.ase b/Assets/Sprites/Particles/player-light.ase new file mode 100644 index 0000000..4566692 Binary files /dev/null and b/Assets/Sprites/Particles/player-light.ase differ diff --git a/Assets/Sprites/Particles/player-light.png b/Assets/Sprites/Particles/player-light.png new file mode 100644 index 0000000..c161968 Binary files /dev/null and b/Assets/Sprites/Particles/player-light.png differ diff --git a/Assets/Sprites/Particles/player-light.png.import b/Assets/Sprites/Particles/player-light.png.import new file mode 100644 index 0000000..22671be --- /dev/null +++ b/Assets/Sprites/Particles/player-light.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d1ukste16yq6v" +path="res://.godot/imported/player-light.png-261881914c11364b14e2af7628defbb7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Particles/player-light.png" +dest_files=["res://.godot/imported/player-light.png-261881914c11364b14e2af7628defbb7.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/Assets/Sprites/UI/boss-bar.png b/Assets/Sprites/UI/boss-bar.png new file mode 100644 index 0000000..d6d935c Binary files /dev/null and b/Assets/Sprites/UI/boss-bar.png differ diff --git a/Assets/Sprites/UI/boss-bar.png.import b/Assets/Sprites/UI/boss-bar.png.import new file mode 100644 index 0000000..cde30dd --- /dev/null +++ b/Assets/Sprites/UI/boss-bar.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b07x1uedfexfi" +path="res://.godot/imported/boss-bar.png-14402f9e8d9c8a30b766d18572a90e44.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/UI/boss-bar.png" +dest_files=["res://.godot/imported/boss-bar.png-14402f9e8d9c8a30b766d18572a90e44.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/Assets/Sprites/UI/over-under-bar.png b/Assets/Sprites/UI/over-under-bar.png new file mode 100644 index 0000000..9308bff Binary files /dev/null and b/Assets/Sprites/UI/over-under-bar.png differ diff --git a/Assets/Sprites/UI/over-under-bar.png.import b/Assets/Sprites/UI/over-under-bar.png.import new file mode 100644 index 0000000..d13d8ef --- /dev/null +++ b/Assets/Sprites/UI/over-under-bar.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b75oak1nd2q6x" +path="res://.godot/imported/over-under-bar.png-2dd8e0831ce7b8d0ab833d2ac7ca543b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/UI/over-under-bar.png" +dest_files=["res://.godot/imported/over-under-bar.png-2dd8e0831ce7b8d0ab833d2ac7ca543b.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/Assets/Sprites/UI/progress-bar.ase b/Assets/Sprites/UI/progress-bar.ase new file mode 100644 index 0000000..1cc8c77 Binary files /dev/null and b/Assets/Sprites/UI/progress-bar.ase differ diff --git a/Assets/Sprites/UI/progress-bar.png b/Assets/Sprites/UI/progress-bar.png new file mode 100644 index 0000000..50a7897 Binary files /dev/null and b/Assets/Sprites/UI/progress-bar.png differ diff --git a/Assets/Sprites/UI/progress-bar.png.import b/Assets/Sprites/UI/progress-bar.png.import new file mode 100644 index 0000000..1663caa --- /dev/null +++ b/Assets/Sprites/UI/progress-bar.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://co7xm7i5f6n51" +path="res://.godot/imported/progress-bar.png-0e003ec68d4d1aedbb2c4345d3d47107.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/UI/progress-bar.png" +dest_files=["res://.godot/imported/progress-bar.png-0e003ec68d4d1aedbb2c4345d3d47107.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/Assets/Sprites/arena-tileset-normal.png b/Assets/Sprites/arena-tileset-normal.png index 2082f9e..16bb549 100644 Binary files a/Assets/Sprites/arena-tileset-normal.png and b/Assets/Sprites/arena-tileset-normal.png differ diff --git a/Assets/Sprites/arena-tileset.ase b/Assets/Sprites/arena-tileset.ase index 3fefc84..0c50590 100644 Binary files a/Assets/Sprites/arena-tileset.ase and b/Assets/Sprites/arena-tileset.ase differ diff --git a/Assets/Sprites/doc-lance.ase b/Assets/Sprites/doc-lance.ase new file mode 100644 index 0000000..747007b Binary files /dev/null and b/Assets/Sprites/doc-lance.ase differ diff --git a/Assets/Sprites/doc-lance.png b/Assets/Sprites/doc-lance.png new file mode 100644 index 0000000..9ba2ebb Binary files /dev/null and b/Assets/Sprites/doc-lance.png differ diff --git a/Assets/Sprites/doc-lance.png.import b/Assets/Sprites/doc-lance.png.import new file mode 100644 index 0000000..8ece2eb --- /dev/null +++ b/Assets/Sprites/doc-lance.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://o7enu13gvji5" +path="res://.godot/imported/doc-lance.png-2fd1894aa4282b30b176bb21b10e8c6f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/doc-lance.png" +dest_files=["res://.godot/imported/doc-lance.png-2fd1894aa4282b30b176bb21b10e8c6f.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/Assets/Sprites/night-grass-side.ase b/Assets/Sprites/night-grass-side.ase new file mode 100644 index 0000000..2e5e978 Binary files /dev/null and b/Assets/Sprites/night-grass-side.ase differ diff --git a/Assets/Sprites/sword-swing-large.ase b/Assets/Sprites/sword-swing-large.ase new file mode 100644 index 0000000..561f0cd Binary files /dev/null and b/Assets/Sprites/sword-swing-large.ase differ diff --git a/Assets/Sprites/sword-swing-large.png b/Assets/Sprites/sword-swing-large.png new file mode 100644 index 0000000..5a9daf0 Binary files /dev/null and b/Assets/Sprites/sword-swing-large.png differ diff --git a/Assets/Sprites/sword-swing-large.png.import b/Assets/Sprites/sword-swing-large.png.import new file mode 100644 index 0000000..e400a73 --- /dev/null +++ b/Assets/Sprites/sword-swing-large.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cmvh6pc71ir1m" +path="res://.godot/imported/sword-swing-large.png-d24bea57b216aba22c9a1cccd93085d2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/sword-swing-large.png" +dest_files=["res://.godot/imported/sword-swing-large.png-d24bea57b216aba22c9a1cccd93085d2.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/Assets/Sprites/sword.ase b/Assets/Sprites/sword.ase index 1826a21..4c3fa58 100644 Binary files a/Assets/Sprites/sword.ase and b/Assets/Sprites/sword.ase differ diff --git a/Assets/Sprites/sword.png b/Assets/Sprites/sword.png index 546593d..ec42116 100644 Binary files a/Assets/Sprites/sword.png and b/Assets/Sprites/sword.png differ diff --git a/BoundingBoxes/CameraBounds.cs b/BoundingBoxes/CameraBounds.cs new file mode 100644 index 0000000..10cdb94 --- /dev/null +++ b/BoundingBoxes/CameraBounds.cs @@ -0,0 +1,21 @@ +using Godot; + +namespace SupaLidlGame.BoundingBoxes; + +public partial class CameraBounds : Area2D +{ + public override void _Ready() + { + BodyEntered += OnBodyEntered; + base._Ready(); + } + + private void OnBodyEntered(Node2D body) + { + if (body is Characters.Player player) + { + var camera = player.Camera; + //camera.LimitLeft = + } + } +} diff --git a/BoundingBoxes/Hurtbox.cs b/BoundingBoxes/Hurtbox.cs index ca36c51..0d661d5 100644 --- a/BoundingBoxes/Hurtbox.cs +++ b/BoundingBoxes/Hurtbox.cs @@ -11,8 +11,13 @@ public partial class Hurtbox : BoundingBox, IFaction float damage, Character inflictor, float knockback, - Vector2 knockbackOrigin = default, - Vector2 knockbackVector = default); + Vector2 knockbackDir = default); + + /// + /// The timer to use for invincibility frames + /// + [Export] + public Timer InvincibilityTimer { get; set; } public override void _Ready() { @@ -20,6 +25,15 @@ public partial class Hurtbox : BoundingBox, IFaction { Faction = factionEntity.Faction; } + + if (InvincibilityTimer is not null) + { + InvincibilityTimer.Timeout += () => + { + GD.Print("invincibility off"); + Monitorable = true; + }; + } } public void InflictDamage( @@ -29,11 +43,48 @@ public partial class Hurtbox : BoundingBox, IFaction Vector2 knockbackOrigin = default, Vector2 knockbackVector = default) { + if (!IsInstanceValid(this)) + { + // this should fix the error of the object being invalid + return; + } + + Vector2 knockbackDir = knockbackVector; + if (knockbackDir == default) + { + if (knockbackOrigin == default) + { + if (inflictor is null) + { + knockbackOrigin = GlobalPosition + Vector2.Down; + } + else + { + knockbackOrigin = inflictor.GlobalPosition; + } + } + + knockbackDir = knockbackOrigin.DirectionTo(GlobalPosition); + } + + if (InvincibilityTimer is not null) + { + if (!InvincibilityTimer.IsStopped()) + { + return; + } + + InvincibilityTimer.Start(); + //Monitorable = false; + SetDeferred("monitorable", false); + GD.Print("invincible"); + } + EmitSignal( SignalName.ReceivedDamage, damage, inflictor, knockback, - knockbackOrigin, knockbackVector); + knockbackDir); } } diff --git a/Characters/Boss.cs b/Characters/Boss.cs new file mode 100644 index 0000000..a04cdef --- /dev/null +++ b/Characters/Boss.cs @@ -0,0 +1,34 @@ +using Godot; +using GodotUtilities; + +namespace SupaLidlGame.Characters; + +public abstract partial class Boss : Enemy +{ + [Export] + public State.NPC.NPCStateMachine BossStateMachine { get; set; } + + [Export] + public string BossName { get; set; } + + [Export] + public AudioStream Music { get; set; } + + public abstract int Intensity { get; } + + private bool _isActive; + + [Export] + public bool IsActive + { + get => _isActive; + set + { + _isActive = value; + + // register or deregister ourselves when we are active/inactive + this.GetAncestor() + .RegisterBoss(_isActive ? this : null); + } + } +} diff --git a/Characters/Character.cs b/Characters/Character.cs index e986353..8986137 100644 --- a/Characters/Character.cs +++ b/Characters/Character.cs @@ -13,7 +13,7 @@ public partial class Character : CharacterBody2D, IFaction public float Speed { get; protected set; } = 32.0f; [Export] - public float Friction { get; protected set; } = 4.0f; + public float Friction { get; set; } = 4.0f; [Export] public float Mass @@ -39,9 +39,12 @@ public partial class Character : CharacterBody2D, IFaction public Vector2 Direction { get; set; } = Vector2.Zero; public Vector2 Target { get; set; } = Vector2.Zero; + + [Export] + public Texture2D HandTexture { get; set; } [Export] - public float Health + public virtual float Health { get => _health; set @@ -66,7 +69,7 @@ public partial class Character : CharacterBody2D, IFaction public double StunTime { get; set; } [Export] - public AnimatedSprite2D Sprite { get; set; } + public Sprite2D Sprite { get; set; } [Export] public Inventory Inventory { get; set; } @@ -80,8 +83,19 @@ public partial class Character : CharacterBody2D, IFaction [Export] public ushort Faction { get; set; } + public AnimationPlayer MovementAnimation { get; set; } + + public AnimationPlayer HurtAnimation { get; set; } + + public AnimationPlayer StunAnimation { get; set; } + public override void _Ready() { + // TODO: 80+ char line + MovementAnimation = GetNode("Animations/Movement"); + HurtAnimation = GetNode("Animations/Hurt"); + StunAnimation = GetNode("Animations/Stun"); + GD.Print(Name + " " + MovementAnimation.CurrentAnimation); Hurtbox.ReceivedDamage += OnReceivedDamage; } @@ -92,6 +106,15 @@ public partial class Character : CharacterBody2D, IFaction StateMachine.Process(delta); } + if (StunTime > 0 && !StunAnimation.IsPlaying()) + { + StunAnimation.Play("stun"); + } + else if (StunTime < 0 && StunAnimation.IsPlaying()) + { + StunAnimation.Stop(); + } + Sprite.FlipH = Target.X < 0; DrawTarget(); } @@ -113,6 +136,18 @@ public partial class Character : CharacterBody2D, IFaction { Velocity *= 0.25f; } + + var state = StateMachine.CurrentState; + if (state is State.Character.CharacterDashState dashState) + { + Velocity *= dashState.VelocityModifier; + } + // TODO: make PlayerRollState a CharacterRollState instead + else if (state is State.Character.PlayerRollState rollState) + { + Velocity *= 2; + //Velocity *= rollState.VelocityModifier; + } } public virtual void Die() @@ -131,7 +166,7 @@ public partial class Character : CharacterBody2D, IFaction public virtual void Stun(float time) { - StunTime += time; + StunTime = Mathf.Max(time, StunTime); } protected virtual void DrawTarget() @@ -156,13 +191,25 @@ public partial class Character : CharacterBody2D, IFaction { if (StunTime > 0) { - GD.Print("tried to use weapon but stunned"); return; } if (Inventory.SelectedItem is Weapon weapon) { weapon.Use(); + if (weapon.IsUsing) + { + Inventory.EmitSignal(Inventory.SignalName.UsedItem, weapon); + } + } + } + + public void DeuseCurrentItem() + { + if (Inventory.SelectedItem is Weapon weapon) + { + weapon.Deuse(); + // TODO: DeusedItem signal, implement when needed } } @@ -174,12 +221,18 @@ public partial class Character : CharacterBody2D, IFaction } } + protected virtual float ReceiveDamage( + float damage, + Character inflictor, + float knockback, + Vector2 knockbackDir = default) => damage; + + public virtual void OnReceivedDamage( float damage, Character inflictor, float knockback, - Vector2 knockbackOrigin = default, - Vector2 knockbackVector = default) + Vector2 knockbackDir = default) { if (Health <= 0) { @@ -187,7 +240,7 @@ public partial class Character : CharacterBody2D, IFaction } float oldHealth = Health; - Health -= damage; + Health -= ReceiveDamage(damage, inflictor, knockback, knockbackDir); // create damage text var textScene = GD.Load("res://UI/FloatingText.tscn"); @@ -197,41 +250,25 @@ public partial class Character : CharacterBody2D, IFaction this.GetAncestor().AddChild(instance); // apply knockback - Vector2 knockbackDir = knockbackVector; - if (knockbackDir == default) - { - if (knockbackOrigin == default) - { - if (inflictor is null) - { - knockbackOrigin = GlobalPosition + Vector2.Down; - } - else - { - knockbackOrigin = inflictor.GlobalPosition; - } - } - - knockbackDir = knockbackOrigin.DirectionTo(GlobalPosition); - } ApplyImpulse(knockbackDir.Normalized() * knockback); GD.Print("lol"); // play damage animation - var anim = GetNode("FlashAnimation"); + var anim = GetNode("Animations/Hurt"); if (anim != null) { anim.Stop(); - anim.Play("Hurt"); + anim.Play("hurt"); + anim.Queue("hurt_flash"); } // if anyone involved is a player, shake their screen Player plr = inflictor as Player ?? this as Player; if (plr is not null) { - plr.Camera.Shake(1, 0.4f); + //plr.Camera.Shake(1, 0.4f); } if (this.GetNode("HurtSound") is AudioStreamPlayer2D sound) diff --git a/Characters/Doc.cs b/Characters/Doc.cs index 67d9a2b..b54c7a5 100644 --- a/Characters/Doc.cs +++ b/Characters/Doc.cs @@ -1,21 +1,45 @@ using Godot; +using GodotUtilities; +using SupaLidlGame.State.Character; namespace SupaLidlGame.Characters; -public partial class Doc : Enemy +public partial class Doc : Boss { - [Export] - public State.NPC.NPCStateMachine BossStateMachine { get; set; } + public AnimationPlayer TelegraphAnimation { get; set; } - public int Intensity + [Export] + public Items.Weapons.Sword Lance { get; set; } + + protected bool _dashedAway = false; + + public override float Health + { + get => base.Health; + set + { + if (IsActive) + { + base.Health = value; + } + else + { + // play opening animation + // then become active when it finishes + base.Health = value; + } + } + } + + public override int Intensity { get { switch (Health) { - case < 250: + case < 200: return 3; - case < 500: + case < 400: return 2; default: return 1; @@ -23,15 +47,115 @@ public partial class Doc : Enemy } } + public Doc() + { + ShouldMove = false; + } + public override void _Ready() { - GD.Print(Health); + TelegraphAnimation = GetNode("Animations/Telegraph"); base._Ready(); + + // when we are hurt, start the boss fight + Hurt += (Events.HealthChangedArgs args) => + { + if (!IsActive) + { + IsActive = true; + Inventory.SelectedItem = Lance; + } + }; } public override void _Process(double delta) { - BossStateMachine.Process(delta); + if (IsActive) + { + BossStateMachine.Process(delta); + } base._Process(delta); } + + protected override float ReceiveDamage( + float damage, + Character inflictor, + float knockback, + Vector2 knockbackDir = default) + { + if (IsActive) + { + return base.ReceiveDamage( + damage, inflictor, knockback, knockbackDir); + } + + return 1; + } + + public override void OnReceivedDamage( + float damage, + Character inflictor, + float knockback, + Vector2 knockbackDir = default) + { + GetNode("Effects/HurtParticles") + .SetDirection(knockbackDir); + + base.OnReceivedDamage(damage, inflictor, knockback, knockbackDir); + } + + protected override void Think() + { + if (BossStateMachine.CurrentState is State.NPC.Doc.DocLanceState) + { + ThirdPhaseThink(); + } + else + { + base.Think(); + } + } + + protected void ThirdPhaseThink() + { + Character bestTarget = FindBestTarget(); + if (bestTarget is not null) + { + Vector2 pos = bestTarget.GlobalPosition; + Target = pos - GlobalPosition; + Vector2 dir = GlobalPosition.DirectionTo(pos); + float dist = GlobalPosition.DistanceSquaredTo(pos); + UpdateWeights(pos); + + if (CanAttack && StunTime <= 0) + { + bool isTargetStunned = bestTarget.StunTime > 0; + if (!isTargetStunned && dist < 2500) + { + if (Inventory.SelectedItem is Items.Weapon weapon) + { + // dash away if too close + DashTo(-dir); + UseCurrentItem(); + _dashedAway = true; + } + } + else if (isTargetStunned || (dist < 3600 && _dashedAway)) + { + if (!Inventory.SelectedItem.IsUsing) + { + DashTo(dir); + UseCurrentItem(); + _dashedAway = false; + } + } + } + } + } + + private void DashTo(Vector2 direction) + { + StateMachine.ChangeState(out var state); + state.DashDirection = direction; + } } diff --git a/Characters/Doc.tscn b/Characters/Doc.tscn index 5593f81..7b71310 100644 --- a/Characters/Doc.tscn +++ b/Characters/Doc.tscn @@ -1,30 +1,155 @@ -[gd_scene load_steps=38 format=3 uid="uid://d2skjvvx6fal0"] +[gd_scene load_steps=61 format=3 uid="uid://d2skjvvx6fal0"] [ext_resource type="Script" path="res://Characters/Doc.cs" id="2_3elet"] [ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="2_5jxom"] +[ext_resource type="AudioStream" uid="uid://ipss4y2gkk3y" path="res://Assets/Music/gillette.mp3" id="3_eo4lg"] [ext_resource type="Texture2D" uid="uid://baiuqgrqipppt" path="res://Assets/Sprites/Characters/doc.png" id="3_rs44f"] [ext_resource type="Script" path="res://State/Character/CharacterStateMachine.cs" id="3_t5jjc"] +[ext_resource type="Texture2D" uid="uid://dpepm54hjuyga" path="res://Assets/Sprites/Characters/forsen-hand.png" id="4_8lqj6"] [ext_resource type="Script" path="res://State/Character/NPCIdleState.cs" id="4_b35px"] [ext_resource type="Script" path="res://State/Character/NPCMoveState.cs" id="5_pejsd"] [ext_resource type="Script" path="res://State/NPC/NPCStateMachine.cs" id="6_kjpug"] +[ext_resource type="Script" path="res://State/Character/CharacterDashState.cs" id="7_0ks57"] [ext_resource type="Script" path="res://State/NPC/Doc/DocTelegraphState.cs" id="7_tfwbh"] [ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="7_tnve0"] [ext_resource type="Script" path="res://State/NPC/Doc/DocShungiteDartState.cs" id="8_1hoax"] [ext_resource type="Script" path="res://Items/Inventory.cs" id="8_r8ejq"] [ext_resource type="Script" path="res://State/NPC/Doc/DocExitState.cs" id="9_6com1"] [ext_resource type="PackedScene" uid="uid://1tiswf3gtyvv" path="res://Entities/ShungiteSpike.tscn" id="9_7kavk"] -[ext_resource type="PackedScene" uid="uid://djaljmco3xo4g" path="res://Entities/ShungiteDart.tscn" id="9_kthpr"] [ext_resource type="AudioStream" uid="uid://k6kpdj1kv0jg" path="res://Assets/Sounds/splat.ogg" id="9_stm0e"] [ext_resource type="Script" path="res://State/NPC/Doc/DocShungiteSpikeState.cs" id="10_bgs6o"] +[ext_resource type="PackedScene" uid="uid://cqx56u46g2c16" path="res://Entities/CompactDisc.tscn" id="11_23p3o"] [ext_resource type="Script" path="res://State/NPC/Doc/DocChooseAttackState.cs" id="12_45x13"] [ext_resource type="Script" path="res://State/NPC/Doc/DocUnwantedFrequencyState.cs" id="12_d51jv"] [ext_resource type="PackedScene" uid="uid://1y5r6sklwgrp" path="res://Entities/UnwantedFrequency.tscn" id="13_lpj21"] +[ext_resource type="Script" path="res://State/NPC/Doc/DocLanceState.cs" id="15_dmd05"] +[ext_resource type="Script" path="res://Utils/AnimationManager.cs" id="16_bsvls"] +[ext_resource type="Texture2D" uid="uid://bd8l8kafb42dt" path="res://Assets/Sprites/Particles/circle.png" id="16_x277j"] +[ext_resource type="Material" uid="uid://bat28samf7ukd" path="res://Assets/Sprites/Particles/NPCDamageProcessMaterial.tres" id="17_iomdx"] +[ext_resource type="Texture2D" uid="uid://c1a7lvb4uuwfy" path="res://Assets/Sprites/Particles/circle-16.png" id="19_p0p6c"] +[ext_resource type="Material" uid="uid://rcjujd5dv7lm" path="res://Assets/Sprites/Particles/DocIntroParticles.tres" id="19_q4rt1"] +[ext_resource type="Animation" uid="uid://8e8r3y1imvsx" path="res://Assets/Animations/stun.res" id="21_ixn4k"] +[ext_resource type="PackedScene" uid="uid://p7oijq6dbvvk" path="res://Items/Weapons/DocLance.tscn" id="24_2es2r"] +[ext_resource type="PackedScene" uid="uid://bauucuqvjwbxp" path="res://Items/Weapons/DocLanceHold.tscn" id="26_0tntj"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_7n7iy"] resource_local_to_scene = true shader = ExtResource("2_5jxom") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 +shader_parameter/alpha_modulate = 1.0 + +[sub_resource type="Animation" id="Animation_7ay6e"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} + +[sub_resource type="Animation" id="Animation_px7yx"] +resource_name = "idle" +length = 0.5 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.3), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [0, 1] +} + +[sub_resource type="Animation" id="Animation_a7sk6"] +resource_name = "move" +length = 0.6 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 1, +"values": [2, 3, 4, 5, 6, 7] +} + +[sub_resource type="Animation" id="Animation_j0d8o"] +resource_name = "dash" +length = 0.1 + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_1xv7m"] +_data = { +"RESET": SubResource("Animation_7ay6e"), +"dash": SubResource("Animation_j0d8o"), +"idle": SubResource("Animation_px7yx"), +"move": SubResource("Animation_a7sk6") +} + +[sub_resource type="Animation" id="Animation_dbist"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Effects/UnwantedFrequenciesParticles:emitting") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("../Sprite:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("../Sprite:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector2(1, 1)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("..:material:shader_parameter/alpha_modulate") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [1.0] +} [sub_resource type="Animation" id="Animation_7oukw"] resource_name = "enter_in" @@ -44,14 +169,38 @@ tracks/0/keys = { tracks/1/type = "value" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("../Sprite:modulate") +tracks/1/path = NodePath("../Sprite:frame") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("../Effects/UnwantedFrequenciesParticles:emitting") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("..:material:shader_parameter/alpha_modulate") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { "times": PackedFloat32Array(0, 0.5), -"transitions": PackedFloat32Array(2, 1), +"transitions": PackedFloat32Array(1, 1), "update": 0, -"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0.5)] +"values": [0.0, 1.0] } [sub_resource type="Animation" id="Animation_j3s0y"] @@ -72,112 +221,113 @@ tracks/0/keys = { tracks/1/type = "value" tracks/1/imported = false tracks/1/enabled = true -tracks/1/path = NodePath("../Sprite:modulate") +tracks/1/path = NodePath("../Sprite:frame") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("../Effects/UnwantedFrequenciesParticles:emitting") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("..:material:shader_parameter/alpha_modulate") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { "times": PackedFloat32Array(0, 0.5), -"transitions": PackedFloat32Array(1, 2), +"transitions": PackedFloat32Array(1, 1), "update": 0, -"values": [Color(1, 1, 1, 0.5), Color(1, 1, 1, 0)] +"values": [1.0, 0.0] +} + +[sub_resource type="Animation" id="Animation_8dhub"] +resource_name = "shungite_spike" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprite:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [15] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("../Sprite:scale") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3), +"transitions": PackedFloat32Array(2, 5, 5, 5), +"update": 0, +"values": [Vector2(1.5, 0.75), Vector2(1, 1), Vector2(0.75, 1.5), Vector2(1, 1)] +} + +[sub_resource type="Animation" id="Animation_qggcf"] +resource_name = "unwanted_frequencies" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Effects/UnwantedFrequenciesParticles:emitting") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, false] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("../Sprite:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 1, +"values": [8, 9, 10, 11, 12, 13, 14, 8, 9] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("../Sprite:scale") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1.5, 0.75), Vector2(1, 1)] } [sub_resource type="AnimationLibrary" id="AnimationLibrary_rpply"] _data = { +"RESET": SubResource("Animation_dbist"), "enter_in": SubResource("Animation_7oukw"), -"exit_out": SubResource("Animation_j3s0y") -} - -[sub_resource type="AtlasTexture" id="AtlasTexture_dib6t"] -atlas = ExtResource("3_rs44f") -region = Rect2(0, 0, 12, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_cwqre"] -atlas = ExtResource("3_rs44f") -region = Rect2(12, 0, 12, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_r8xjl"] -atlas = ExtResource("3_rs44f") -region = Rect2(24, 0, 12, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_7hkj4"] -atlas = ExtResource("3_rs44f") -region = Rect2(36, 0, 12, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_w04w0"] -atlas = ExtResource("3_rs44f") -region = Rect2(48, 0, 12, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_ym6tg"] -atlas = ExtResource("3_rs44f") -region = Rect2(60, 0, 12, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_3rbas"] -atlas = ExtResource("3_rs44f") -region = Rect2(72, 0, 12, 16) - -[sub_resource type="AtlasTexture" id="AtlasTexture_63wkp"] -atlas = ExtResource("3_rs44f") -region = Rect2(84, 0, 12, 16) - -[sub_resource type="SpriteFrames" id="SpriteFrames_kb0pl"] -resource_local_to_scene = true -animations = [{ -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_dib6t") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_cwqre") -}], -"loop": true, -"name": &"idle", -"speed": 5.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_r8xjl") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_7hkj4") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_w04w0") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_ym6tg") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_3rbas") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_63wkp") -}], -"loop": true, -"name": &"move", -"speed": 12.0 -}] - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_uict5"] -size = Vector2(16, 8) - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_8lxmf"] -size = Vector2(16, 18) - -[sub_resource type="Animation" id="Animation_dxevc"] -resource_name = "Hurt" -length = 0.6 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath(".:material:shader_parameter/intensity") -tracks/0/interp = 2 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6), -"transitions": PackedFloat32Array(4, 4, 4, 4, 4, 4, 4), -"update": 0, -"values": [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0] +"exit_out": SubResource("Animation_j3s0y"), +"shungite_spike": SubResource("Animation_8dhub"), +"unwanted_frequencies": SubResource("Animation_qggcf") } [sub_resource type="Animation" id="Animation_k6l16"] @@ -194,27 +344,134 @@ tracks/0/keys = { "update": 0, "values": [0.0] } +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Effects/HurtParticles:emitting") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} + +[sub_resource type="Animation" id="Animation_dxevc"] +resource_name = "hurt" +length = 0.6 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:material:shader_parameter/intensity") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6), +"transitions": PackedFloat32Array(4, 4, 4, 4, 4, 4, 4), +"update": 0, +"values": [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Effects/HurtParticles:emitting") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, false] +} [sub_resource type="AnimationLibrary" id="AnimationLibrary_xe5eq"] _data = { -"Hurt": SubResource("Animation_dxevc"), -"RESET": SubResource("Animation_k6l16") +"RESET": SubResource("Animation_k6l16"), +"hurt": SubResource("Animation_dxevc") } -[node name="Doc" type="CharacterBody2D" node_paths=PackedStringArray("BossStateMachine", "Sprite", "Inventory", "StateMachine", "Hurtbox")] +[sub_resource type="AnimationLibrary" id="AnimationLibrary_kks2p"] +_data = { +"stun": ExtResource("21_ixn4k") +} + +[sub_resource type="Animation" id="Animation_uemm6"] +resource_name = "intro" + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_kjxam"] +_data = { +"intro": SubResource("Animation_uemm6") +} + +[sub_resource type="Gradient" id="Gradient_lcoxi"] +offsets = PackedFloat32Array(0.37037, 0.651852) +colors = PackedColorArray(0.367549, 0.894801, 1, 1, 0.992095, 0.364069, 1, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_5606i"] +gradient = SubResource("Gradient_lcoxi") + +[sub_resource type="Gradient" id="Gradient_pikjh"] +offsets = PackedFloat32Array(0.533333, 1) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_pjeh8"] +gradient = SubResource("Gradient_pikjh") + +[sub_resource type="Curve" id="Curve_x3x4q"] +_data = [Vector2(0, 0.463636), 0.0, 0.0, 0, 0, Vector2(0.325301, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_ssoms"] +curve = SubResource("Curve_x3x4q") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_s1tqp"] +emission_shape = 3 +emission_box_extents = Vector3(8, 1, 1) +particle_flag_disable_z = true +direction = Vector3(0, -1, 0) +spread = 0.0 +gravity = Vector3(0, 0, 0) +initial_velocity_min = 32.0 +initial_velocity_max = 64.0 +orbit_velocity_min = 0.0 +orbit_velocity_max = 0.0 +scale_max = 1.5 +scale_curve = SubResource("CurveTexture_ssoms") +color_ramp = SubResource("GradientTexture1D_pjeh8") +color_initial_ramp = SubResource("GradientTexture1D_5606i") + +[sub_resource type="CanvasTexture" id="CanvasTexture_hs7xn"] + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_j1srf"] +particle_flag_disable_z = true +gravity = Vector3(0, 98, 0) +orbit_velocity_min = 0.0 +orbit_velocity_max = 0.0 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_uict5"] +size = Vector2(11, 5) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_8lxmf"] +size = Vector2(16, 19) + +[node name="Doc" type="CharacterBody2D" node_paths=PackedStringArray("Lance", "BossStateMachine", "Sprite", "Inventory", "StateMachine", "Hurtbox")] y_sort_enabled = true texture_filter = 3 material = SubResource("ShaderMaterial_7n7iy") collision_layer = 10 collision_mask = 17 script = ExtResource("2_3elet") +Lance = NodePath("Inventory/DocLance") BossStateMachine = NodePath("BossStateMachine") -Health = 1000.0 +BossName = "Doc, The Two-Time" +Music = ExtResource("3_eo4lg") +HandTexture = ExtResource("4_8lqj6") +Health = 800.0 Sprite = NodePath("Sprite") Inventory = NodePath("Inventory") StateMachine = NodePath("StateMachine") Hurtbox = NodePath("Hurtbox") -Faction = 2 [node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState", "Character")] script = ExtResource("3_t5jjc") @@ -231,6 +488,13 @@ script = ExtResource("5_pejsd") IdleState = NodePath("../Idle") Character = NodePath("../..") +[node name="Dash" type="Node" parent="StateMachine" node_paths=PackedStringArray("IdleState", "Character")] +script = ExtResource("7_0ks57") +IdleState = NodePath("../Idle") +TimeToDash = 0.1 +VelocityModifier = 10.0 +Character = NodePath("../..") + [node name="BossStateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState")] script = ExtResource("6_kjpug") InitialState = NodePath("Telegraph") @@ -245,14 +509,14 @@ NPC = NodePath("../..") script = ExtResource("8_1hoax") Duration = 8.0 AttackDuration = 1.0 -Projectile = ExtResource("9_kthpr") +Projectile = ExtResource("11_23p3o") ChooseAttackState = NodePath("../ChooseAttack") Doc = NodePath("../..") NPC = NodePath("../..") [node name="Spike" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("ChooseAttackState", "Doc", "NPC")] script = ExtResource("10_bgs6o") -Duration = 8.0 +Duration = 4.0 AttackDuration = 1.0 Projectile = ExtResource("9_7kavk") ChooseAttackState = NodePath("../ChooseAttack") @@ -268,11 +532,17 @@ ChooseAttackState = NodePath("../ChooseAttack") Doc = NodePath("../..") NPC = NodePath("../..") -[node name="ChooseAttack" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("DartState", "SpikeState", "UnwantedFrequencyState", "ExitState", "NPC")] +[node name="Lance" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("ExitState", "NPC")] +script = ExtResource("15_dmd05") +ExitState = NodePath("../Exit") +NPC = NodePath("../..") + +[node name="ChooseAttack" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("DartState", "SpikeState", "UnwantedFrequencyState", "LanceState", "ExitState", "NPC")] script = ExtResource("12_45x13") DartState = NodePath("../Dart") SpikeState = NodePath("../Spike") UnwantedFrequencyState = NodePath("../UnwantedFrequency") +LanceState = NodePath("../Lance") ExitState = NodePath("../Exit") NPC = NodePath("../..") @@ -283,33 +553,85 @@ TelegraphState = NodePath("../Telegraph") NPC = NodePath("../..") [node name="Animations" type="Node" parent="."] +script = ExtResource("16_bsvls") + +[node name="Movement" type="AnimationPlayer" parent="Animations"] +libraries = { +"": SubResource("AnimationLibrary_1xv7m") +} [node name="Telegraph" type="AnimationPlayer" parent="Animations"] libraries = { "": SubResource("AnimationLibrary_rpply") } -[node name="Sprite" type="AnimatedSprite2D" parent="."] +[node name="Hurt" type="AnimationPlayer" parent="Animations"] +root_node = NodePath("../..") +libraries = { +"": SubResource("AnimationLibrary_xe5eq") +} + +[node name="Stun" type="AnimationPlayer" parent="Animations"] +libraries = { +"": SubResource("AnimationLibrary_kks2p") +} + +[node name="Misc" type="AnimationPlayer" parent="Animations"] +libraries = { +"": SubResource("AnimationLibrary_kjxam") +} + +[node name="Effects" type="Node2D" parent="."] + +[node name="UnwantedFrequenciesParticles" type="GPUParticles2D" parent="Effects"] +emitting = false +process_material = SubResource("ParticleProcessMaterial_s1tqp") +texture = SubResource("CanvasTexture_hs7xn") +lifetime = 0.5 +trail_enabled = true +trail_sections = 4 + +[node name="HurtParticles" type="GPUParticles2D" parent="Effects"] +position = Vector2(0, -8) +emitting = false +process_material = ExtResource("17_iomdx") +texture = ExtResource("16_x277j") +lifetime = 0.4 +one_shot = true +explosiveness = 1.0 + +[node name="IntroParticles" type="GPUParticles2D" parent="Effects"] +position = Vector2(0, -8) +emitting = false +amount = 32 +process_material = ExtResource("19_q4rt1") +texture = ExtResource("19_p0p6c") + +[node name="Dash" type="GPUParticles2D" parent="Effects"] +position = Vector2(0, -8) +emitting = false +amount = 32 +process_material = SubResource("ParticleProcessMaterial_j1srf") + +[node name="Sprite" type="Sprite2D" parent="."] modulate = Color(1, 1, 1, 0.5) +y_sort_enabled = true use_parent_material = true -position = Vector2(0, -4) -sprite_frames = SubResource("SpriteFrames_kb0pl") -animation = &"move" -frame_progress = 0.563144 -offset = Vector2(0, 4) +position = Vector2(-0.5, 0) +texture = ExtResource("3_rs44f") +offset = Vector2(0, -8) +hframes = 16 [node name="CollisionShape2D" type="CollisionShape2D" parent="."] -visible = false -position = Vector2(0, 4) +position = Vector2(-0.5, -1.5) shape = SubResource("RectangleShape2D_uict5") [node name="Hurtbox" parent="." instance=ExtResource("7_tnve0")] -visible = false position = Vector2(0, -4) Faction = 2 [node name="CollisionShape2D" parent="Hurtbox" index="0"] -position = Vector2(0, 4) +position = Vector2(0, -3.5) shape = SubResource("RectangleShape2D_8lxmf") [node name="Inventory" type="Node2D" parent="."] @@ -317,10 +639,9 @@ y_sort_enabled = true script = ExtResource("8_r8ejq") Items = Array[Node2D]([]) -[node name="FlashAnimation" type="AnimationPlayer" parent="."] -libraries = { -"": SubResource("AnimationLibrary_xe5eq") -} +[node name="DocLance" parent="Inventory" instance=ExtResource("24_2es2r")] + +[node name="DocLanceHold" parent="Inventory" instance=ExtResource("26_0tntj")] [node name="HurtSound" type="AudioStreamPlayer2D" parent="."] stream = ExtResource("9_stm0e") diff --git a/Characters/NPC.cs b/Characters/NPC.cs index 96ecb65..f903d7e 100644 --- a/Characters/NPC.cs +++ b/Characters/NPC.cs @@ -1,3 +1,5 @@ +#undef DEBUG_NPC + using Godot; using SupaLidlGame.Extensions; using SupaLidlGame.Items; @@ -41,6 +43,10 @@ public partial class NPC : Character } } + public bool ShouldMove { get; set; } = true; + + public bool CanAttack { get; set; } = true; + protected float[] _weights = new float[16]; protected int _bestWeightIdx; protected double _thinkTimeElapsed = 0; @@ -65,7 +71,7 @@ public partial class NPC : Character public override void _Draw() { -#if DEBUG +#if DEBUG_NPC for (int i = 0; i < 16; i++) { Vector2 vec = _weightDirs[i] * _weights[i] * 32; @@ -116,12 +122,19 @@ public partial class NPC : Character { _thinkTimeElapsed = 0; Think(); -#if DEBUG +#if DEBUG_NPC QueueRedraw(); #endif } - Direction = _weightDirs[_bestWeightIdx]; + if (ShouldMove) + { + Direction = _weightDirs[_bestWeightIdx]; + } + else + { + Direction = Vector2.Zero; + } } public void UpdateWeights(Vector2 pos) @@ -221,7 +234,7 @@ public partial class NPC : Character float dist = GlobalPosition.DistanceSquaredTo(pos); UpdateWeights(pos); - if (dist < 1024) + if (dist < 1600 && CanAttack) { if (Inventory.SelectedItem is Weapon weapon) { diff --git a/Characters/Player.cs b/Characters/Player.cs index 04e2171..0bbdb59 100644 --- a/Characters/Player.cs +++ b/Characters/Player.cs @@ -8,7 +8,6 @@ namespace SupaLidlGame.Characters; [Scene] public sealed partial class Player : Character { - private AnimatedSprite2D _sprite; private string _spriteAnim; [Export] @@ -17,40 +16,32 @@ public sealed partial class Player : Character [Export] public Marker2D DirectionMarker { get; private set; } + [Export] + public AnimationTree AnimationTree { get; private set; } + public InteractionRay InteractionRay { get; private set; } - public string Animation - { - get => _sprite.Animation; - set - { - // the Player.Animation property might be set before this node is - // even ready, so if _sprite is null, then we just hold the new - // animation in a temp value, which will be assigned once this node - // is ready - if (_sprite is null) - { - _spriteAnim = value; - return; - } - - _sprite.Play(value); - } - } + public AnimationPlayer AttackAnimation { get; set; } public override void _Ready() { InteractionRay = GetNode("Direction2D/InteractionRay"); - _sprite = GetNode("Sprite"); - if (_spriteAnim != default) - { - _sprite.Animation = _spriteAnim; - } - base._Ready(); Death += (Events.HealthChangedArgs args) => { Visible = false; }; + + AttackAnimation = GetNode("Animations/Attack"); + + base._Ready(); + + Inventory.UsedItem += (Items.Item item) => + { + if (item is Items.Weapons.Sword) + { + AttackAnimation.Play("sword"); + } + }; } public override void _Input(InputEvent @event) @@ -69,11 +60,6 @@ public sealed partial class Player : Character public override void ModifyVelocity() { - if (StateMachine.CurrentState is SupaLidlGame.State.Character.PlayerRollState) - { - Velocity *= 2; - } - base.ModifyVelocity(); } @@ -88,19 +74,17 @@ public sealed partial class Player : Character float damage, Character inflictor, float knockback, - Vector2 knockbackOrigin = default, - Vector2 knockbackVector = default) + Vector2 knockbackDir = default) { if (damage >= 10 && IsAlive) { Camera.Shake(2, 0.5f); } - base.OnReceivedDamage( - damage, - inflictor, - knockback, - knockbackOrigin, - knockbackVector); + + GetNode("Effects/HurtParticles") + .SetDirection(knockbackDir); + + base.OnReceivedDamage(damage, inflictor, knockback, knockbackDir); } public override void Die() diff --git a/Characters/Player.tscn b/Characters/Player.tscn index b3a2f7e..e06ff3a 100644 --- a/Characters/Player.tscn +++ b/Characters/Player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=39 format=3 uid="uid://b2254pup8k161"] +[gd_scene load_steps=55 format=3 uid="uid://b2254pup8k161"] [ext_resource type="Script" path="res://Characters/Player.cs" id="1_flygr"] [ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="2_ngsgt"] @@ -8,111 +8,163 @@ [ext_resource type="Script" path="res://State/Character/PlayerIdleState.cs" id="6_wkfdm"] [ext_resource type="PackedScene" uid="uid://dvqap2uhcah63" path="res://Items/Weapons/Sword.tscn" id="7_4rxuv"] [ext_resource type="Script" path="res://State/Character/PlayerMoveState.cs" id="7_dfqd8"] +[ext_resource type="Script" path="res://Utils/AnimationManager.cs" id="7_sdgvb"] [ext_resource type="Script" path="res://Items/Inventory.cs" id="7_xyenu"] [ext_resource type="Script" path="res://State/Character/PlayerRollState.cs" id="8_fy0v5"] +[ext_resource type="Animation" uid="uid://8e8r3y1imvsx" path="res://Assets/Animations/stun.res" id="8_m08fh"] +[ext_resource type="Material" uid="uid://x5qcq5muvc3g" path="res://Assets/Sprites/Particles/PlayerDamageProcessMaterial.tres" id="8_yf112"] +[ext_resource type="Texture2D" uid="uid://c1a7lvb4uuwfy" path="res://Assets/Sprites/Particles/circle-16.png" id="9_7gumm"] [ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="9_avyu4"] [ext_resource type="AudioStream" uid="uid://bkeyg8weaqnuu" path="res://Assets/Sounds/splat-player.ogg" id="12_vvem5"] [ext_resource type="Script" path="res://BoundingBoxes/InteractionRay.cs" id="13_hs3u1"] -[ext_resource type="Texture2D" uid="uid://coarr28adgo1u" path="res://Assets/Sprites/Particles/point-light.png" id="14_l4ekh"] +[ext_resource type="PackedScene" uid="uid://p7oijq6dbvvk" path="res://Items/Weapons/DocLance.tscn" id="14_bj0lo"] +[ext_resource type="Texture2D" uid="uid://d1ukste16yq6v" path="res://Assets/Sprites/Particles/player-light.png" id="15_3hahh"] [ext_resource type="Script" path="res://Utils/DamageTime.cs" id="15_4xl06"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"] shader = ExtResource("2_ngsgt") -shader_parameter/color = Quaternion(1, 1, 1, 1) +shader_parameter/color = Vector4(1, 1, 1, 1) shader_parameter/intensity = 0.0 +shader_parameter/alpha_modulate = 1.0 -[sub_resource type="AtlasTexture" id="AtlasTexture_55yt4"] -atlas = ExtResource("4_5vird") -region = Rect2(0, 0, 24, 24) - -[sub_resource type="AtlasTexture" id="AtlasTexture_xa1bi"] -atlas = ExtResource("4_5vird") -region = Rect2(24, 0, 24, 24) - -[sub_resource type="AtlasTexture" id="AtlasTexture_hiodl"] -atlas = ExtResource("4_5vird") -region = Rect2(48, 0, 24, 24) - -[sub_resource type="AtlasTexture" id="AtlasTexture_tok7d"] -atlas = ExtResource("4_5vird") -region = Rect2(72, 0, 24, 24) - -[sub_resource type="AtlasTexture" id="AtlasTexture_dp8x6"] -atlas = ExtResource("4_5vird") -region = Rect2(96, 0, 24, 24) - -[sub_resource type="AtlasTexture" id="AtlasTexture_sglor"] -atlas = ExtResource("4_5vird") -region = Rect2(120, 0, 24, 24) - -[sub_resource type="AtlasTexture" id="AtlasTexture_gb41o"] -atlas = ExtResource("4_5vird") -region = Rect2(144, 0, 24, 24) - -[sub_resource type="AtlasTexture" id="AtlasTexture_bx6qq"] -atlas = ExtResource("4_5vird") -region = Rect2(168, 0, 24, 24) - -[sub_resource type="SpriteFrames" id="SpriteFrames_2h7cf"] -animations = [{ -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_55yt4") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_xa1bi") -}], -"loop": true, -"name": &"idle", -"speed": 2.0 -}, { -"frames": [{ -"duration": 1.0, -"texture": SubResource("AtlasTexture_hiodl") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_tok7d") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_dp8x6") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_sglor") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_gb41o") -}, { -"duration": 1.0, -"texture": SubResource("AtlasTexture_bx6qq") -}], -"loop": true, -"name": &"move", -"speed": 10.0 -}] - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_bfqew"] -size = Vector2(12, 8) - -[sub_resource type="LabelSettings" id="LabelSettings_q5h1n"] -font_size = 24 - -[sub_resource type="RectangleShape2D" id="RectangleShape2D_cjk6b"] -size = Vector2(8, 8) - -[sub_resource type="Animation" id="Animation_dxevc"] -resource_name = "Hurt" -length = 0.6 +[sub_resource type="Animation" id="Animation_imqdv"] +length = 0.001 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath(".:material:shader_parameter/intensity") -tracks/0/interp = 2 +tracks/0/path = NodePath("../Sprites/Node2D/Character:frame") +tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { -"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6), -"transitions": PackedFloat32Array(4, 4, 4, 4, 4, 4, 4), +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("../Sprites/Node2D/Character:rotation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), "update": 0, -"values": [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0] +"values": [0.0] +} + +[sub_resource type="Animation" id="Animation_mg66i"] +resource_name = "idle" +length = 0.5 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprites/Node2D/Character:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.3), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [0, 1] +} + +[sub_resource type="Animation" id="Animation_iyr4r"] +resource_name = "move" +length = 0.6 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprites/Node2D/Character:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1), +"update": 1, +"values": [2, 3, 4, 5, 6, 7] +} + +[sub_resource type="Animation" id="Animation_vobpw"] +resource_name = "roll" +length = 0.5 +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprites/Node2D/Character:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 6.28319] +} + +[sub_resource type="Animation" id="Animation_tpnyg"] +resource_name = "stop" +length = 0.2 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprites/Node2D/Character:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [10, 0] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_0tohi"] +_data = { +"RESET": SubResource("Animation_imqdv"), +"idle": SubResource("Animation_mg66i"), +"move": SubResource("Animation_iyr4r"), +"roll": SubResource("Animation_vobpw"), +"stop": SubResource("Animation_tpnyg") +} + +[sub_resource type="Animation" id="Animation_adxyh"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprites/Node2D/Character:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} + +[sub_resource type="Animation" id="Animation_3w3u1"] +resource_name = "sword" +length = 0.3 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprites/Node2D/Character:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [12, 13, 14] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_73mj7"] +_data = { +"RESET": SubResource("Animation_adxyh"), +"sword": SubResource("Animation_3w3u1") } [sub_resource type="Animation" id="Animation_k6l16"] @@ -129,87 +181,205 @@ tracks/0/keys = { "update": 0, "values": [0.0] } - -[sub_resource type="AnimationLibrary" id="AnimationLibrary_xe5eq"] -_data = { -"Hurt": SubResource("Animation_dxevc"), -"RESET": SubResource("Animation_k6l16") -} - -[sub_resource type="Animation" id="Animation_yejx2"] -length = 0.001 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Sprite:rotation") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Sprites/Node2D/Character:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), -"update": 0, -"values": [0.0] +"update": 1, +"values": [0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Effects/HurtParticles:emitting") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] } -[sub_resource type="Animation" id="Animation_rx2pj"] -resource_name = "roll" -length = 0.5 +[sub_resource type="Animation" id="Animation_dxevc"] +resource_name = "hurt" +length = 0.2 step = 0.05 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("Sprite:rotation") -tracks/0/interp = 1 +tracks/0/path = NodePath(".:material:shader_parameter/intensity") +tracks/0/interp = 2 tracks/0/loop_wrap = true tracks/0/keys = { -"times": PackedFloat32Array(0, 0.25, 0.5), -"transitions": PackedFloat32Array(1, 1, 1), +"times": PackedFloat32Array(0, 0.05, 0.1, 0.2), +"transitions": PackedFloat32Array(4, 4, 4, 4), "update": 0, -"values": [0.0, 3.14159, 6.28319] +"values": [1.0, 0.0, 1.0, 0.0] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Sprites/Node2D/Character:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [11] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Effects/HurtParticles:emitting") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [true, false] +} +tracks/3/type = "method" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Effects/HurtParticles") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0.2), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"restart" +}] } -[sub_resource type="AnimationLibrary" id="AnimationLibrary_jai06"] +[sub_resource type="Animation" id="Animation_pjey7"] +resource_name = "hurt_flash" +length = 0.4 +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:material:shader_parameter/intensity") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2, 0.4), +"transitions": PackedFloat32Array(4, 4, 4), +"update": 0, +"values": [0.0, 1.0, 0.0] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_xe5eq"] _data = { -"RESET": SubResource("Animation_yejx2"), -"roll": SubResource("Animation_rx2pj") +"RESET": SubResource("Animation_k6l16"), +"hurt": SubResource("Animation_dxevc"), +"hurt_flash": SubResource("Animation_pjey7") } -[sub_resource type="Gradient" id="Gradient_3tax5"] -offsets = PackedFloat32Array(0.533333, 1) -colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) +[sub_resource type="AnimationLibrary" id="AnimationLibrary_kks2p"] +_data = { +"stun": ExtResource("8_m08fh") +} -[sub_resource type="GradientTexture1D" id="GradientTexture1D_pjeh8"] -gradient = SubResource("Gradient_3tax5") +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_kwett"] +animation = &"idle" -[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_humq0"] -emission_shape = 1 -emission_sphere_radius = 1.0 +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_vqdng"] +animation = &"move" + +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_4np0m"] +animation = &"roll" + +[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_suhx1"] +animation = &"stop" + +[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_sorqc"] +advance_mode = 2 + +[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_ujrp0"] +advance_condition = &"move" + +[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_kjkm8"] +advance_condition = &"idle" + +[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_1ywlq"] +switch_mode = 2 +advance_mode = 2 +advance_condition = &"idle" + +[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_abs7t"] +advance_condition = &"roll" + +[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_qlka8"] +advance_condition = &"idle" + +[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_ql2f3"] +advance_condition = &"move" + +[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_g1yba"] +advance_condition = &"roll" + +[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_0ukul"] +states/End/position = Vector2(613, 100) +states/Start/position = Vector2(89, 100) +states/idle/node = SubResource("AnimationNodeAnimation_kwett") +states/idle/position = Vector2(259, 100) +states/move/node = SubResource("AnimationNodeAnimation_vqdng") +states/move/position = Vector2(259, 18) +states/roll/node = SubResource("AnimationNodeAnimation_4np0m") +states/roll/position = Vector2(89, 18) +states/stop/node = SubResource("AnimationNodeAnimation_suhx1") +states/stop/position = Vector2(438, 100) +transitions = ["Start", "idle", SubResource("AnimationNodeStateMachineTransition_sorqc"), "idle", "move", SubResource("AnimationNodeStateMachineTransition_ujrp0"), "move", "stop", SubResource("AnimationNodeStateMachineTransition_kjkm8"), "stop", "idle", SubResource("AnimationNodeStateMachineTransition_1ywlq"), "idle", "roll", SubResource("AnimationNodeStateMachineTransition_abs7t"), "roll", "idle", SubResource("AnimationNodeStateMachineTransition_qlka8"), "roll", "move", SubResource("AnimationNodeStateMachineTransition_ql2f3"), "move", "roll", SubResource("AnimationNodeStateMachineTransition_g1yba")] +graph_offset = Vector2(-335.315, -63.5708) + +[sub_resource type="AnimationNodeStateMachinePlayback" id="AnimationNodeStateMachinePlayback_jln87"] + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_852jj"] particle_flag_disable_z = true -direction = Vector3(0, 0, 0) spread = 180.0 gravity = Vector3(0, 0, 0) -initial_velocity_min = 32.0 -initial_velocity_max = 32.0 +initial_velocity_min = 8.0 +initial_velocity_max = 16.0 orbit_velocity_min = 0.0 -orbit_velocity_max = 0.1 -tangential_accel_min = 64.0 -tangential_accel_max = 64.0 -color_ramp = SubResource("GradientTexture1D_pjeh8") +orbit_velocity_max = 0.0 +linear_accel_min = -32.0 +linear_accel_max = -16.0 +scale_min = 0.1 +scale_max = 0.1 [sub_resource type="CanvasTexture" id="CanvasTexture_pited"] +diffuse_texture = ExtResource("9_7gumm") + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_bfqew"] +size = Vector2(12, 8) + +[sub_resource type="LabelSettings" id="LabelSettings_q5h1n"] +font_size = 24 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_cjk6b"] +size = Vector2(8, 8) [node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("Camera", "DirectionMarker", "Sprite", "Inventory", "StateMachine", "Hurtbox")] y_sort_enabled = true texture_filter = 3 material = SubResource("ShaderMaterial_h78y7") -position = Vector2(1, -12) collision_layer = 6 collision_mask = 17 script = ExtResource("1_flygr") Camera = NodePath("Camera2D") DirectionMarker = NodePath("Direction2D") -Speed = 64.0 -Sprite = NodePath("Sprite") +Speed = 80.0 +Sprite = NodePath("Sprites/Node2D/Character") Inventory = NodePath("Inventory") StateMachine = NodePath("StateMachine") Hurtbox = NodePath("Hurtbox") @@ -237,18 +407,89 @@ script = ExtResource("8_fy0v5") IdleState = NodePath("../Idle") Character = NodePath("../..") +[node name="Animations" type="Node" parent="."] +script = ExtResource("7_sdgvb") + +[node name="Movement" type="AnimationPlayer" parent="Animations"] +libraries = { +"": SubResource("AnimationLibrary_0tohi") +} + +[node name="Attack" type="AnimationPlayer" parent="Animations"] +libraries = { +"": SubResource("AnimationLibrary_73mj7") +} + +[node name="Hurt" type="AnimationPlayer" parent="Animations"] +root_node = NodePath("../..") +libraries = { +"": SubResource("AnimationLibrary_xe5eq") +} + +[node name="Stun" type="AnimationPlayer" parent="Animations"] +libraries = { +"": SubResource("AnimationLibrary_kks2p") +} + +[node name="AnimationTree" type="AnimationTree" parent="Animations"] +tree_root = SubResource("AnimationNodeStateMachine_0ukul") +anim_player = NodePath("../Movement") +parameters/playback = SubResource("AnimationNodeStateMachinePlayback_jln87") +parameters/conditions/idle = false +parameters/conditions/move = false +parameters/conditions/roll = false + +[node name="Effects" type="Node2D" parent="."] + +[node name="RollParticles" type="GPUParticles2D" parent="Effects"] +emitting = false +amount = 16 +process_material = SubResource("ParticleProcessMaterial_852jj") +texture = ExtResource("9_7gumm") +lifetime = 0.8 + +[node name="DeathParticles" type="GPUParticles2D" parent="Effects"] +emitting = false +amount = 32 +process_material = ExtResource("8_yf112") +texture = SubResource("CanvasTexture_pited") +lifetime = 2.0 +preprocess = 0.1 +explosiveness = 0.9 + +[node name="HurtParticles" type="GPUParticles2D" parent="Effects"] +emitting = false +amount = 32 +process_material = ExtResource("8_yf112") +texture = ExtResource("9_7gumm") +lifetime = 1.5 +one_shot = true +preprocess = 0.1 +explosiveness = 0.9 + [node name="Camera2D" parent="." instance=ExtResource("4_ym125")] +limit_left = -256 +limit_top = -256 +limit_right = 256 +limit_bottom = 256 position_smoothing_speed = 8.0 -[node name="Sprite" type="AnimatedSprite2D" parent="."] +[node name="Sprites" type="Node2D" parent="."] +y_sort_enabled = true use_parent_material = true -position = Vector2(0, 4) -sprite_frames = SubResource("SpriteFrames_2h7cf") -animation = &"idle" +rotation = 6.28319 + +[node name="Node2D" type="Node2D" parent="Sprites"] + +[node name="Character" type="Sprite2D" parent="Sprites/Node2D"] +use_parent_material = true +position = Vector2(-1, -8) +texture = ExtResource("4_5vird") offset = Vector2(0, -4) +hframes = 24 [node name="CollisionShape2D" type="CollisionShape2D" parent="."] -position = Vector2(0, 8) +position = Vector2(0, -4) shape = SubResource("RectangleShape2D_bfqew") [node name="Debug" type="Control" parent="."] @@ -266,10 +507,8 @@ text = "lol" label_settings = SubResource("LabelSettings_q5h1n") horizontal_alignment = 1 -[node name="Node" type="Node" parent="."] - [node name="Inventory" type="Node2D" parent="."] -position = Vector2(0, 4) +position = Vector2(0, -4) script = ExtResource("7_xyenu") InventoryMap = { "equip_1": 0, @@ -278,56 +517,50 @@ InventoryMap = { [node name="Node2D" parent="Inventory" instance=ExtResource("7_4rxuv")] visible = false -ShouldHideIdle = false -[node name="Hurtbox" parent="." instance=ExtResource("9_avyu4")] +[node name="DocLance" parent="Inventory" instance=ExtResource("14_bj0lo")] + +[node name="Hurtbox" parent="." node_paths=PackedStringArray("InvincibilityTimer") instance=ExtResource("9_avyu4")] +visible = false +InvincibilityTimer = NodePath("Timer") Faction = 1 [node name="CollisionShape2D" parent="Hurtbox" index="0"] -position = Vector2(0, 6) +visible = false +position = Vector2(0, 4) shape = SubResource("RectangleShape2D_cjk6b") -[node name="FlashAnimation" type="AnimationPlayer" parent="."] -libraries = { -"": SubResource("AnimationLibrary_xe5eq") -} - -[node name="RollAnimation" type="AnimationPlayer" parent="."] -libraries = { -"": SubResource("AnimationLibrary_jai06") -} +[node name="Timer" type="Timer" parent="Hurtbox"] +one_shot = true [node name="HurtSound" type="AudioStreamPlayer2D" parent="."] +visible = false stream = ExtResource("12_vvem5") max_distance = 64.0 [node name="AudioListener2D" type="AudioListener2D" parent="."] +visible = false current = true [node name="Direction2D" type="Marker2D" parent="."] +visible = false position = Vector2(0, 6) [node name="InteractionRay" type="RayCast2D" parent="Direction2D"] +visible = false target_position = Vector2(16, 0) collision_mask = 64 collide_with_areas = true script = ExtResource("13_hs3u1") -[node name="DeathParticles" type="GPUParticles2D" parent="."] -emitting = false -amount = 16 -process_material = SubResource("ParticleProcessMaterial_humq0") -texture = SubResource("CanvasTexture_pited") -one_shot = true -explosiveness = 0.9 - [node name="PointLight2D" type="PointLight2D" parent="."] +visible = false blend_mode = 2 shadow_enabled = true shadow_filter = 2 shadow_filter_smooth = 3.0 -texture = ExtResource("14_l4ekh") -texture_scale = 0.5 +texture = ExtResource("15_3hahh") +height = 10.0 [node name="DamageTime" type="Node" parent="."] script = ExtResource("15_4xl06") diff --git a/Entities/CompactDisc.tscn b/Entities/CompactDisc.tscn new file mode 100644 index 0000000..192ee99 --- /dev/null +++ b/Entities/CompactDisc.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=7 format=3 uid="uid://cqx56u46g2c16"] + +[ext_resource type="PackedScene" uid="uid://djaljmco3xo4g" path="res://Entities/ShungiteDart.tscn" id="1_md2qh"] +[ext_resource type="Texture2D" uid="uid://qc6agawkad5k" path="res://Assets/Sprites/Misc/compact-disc.png" id="3_8r6gc"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_wvy7p"] +atlas = ExtResource("3_8r6gc") +region = Rect2(0, 0, 12, 12) + +[sub_resource type="AtlasTexture" id="AtlasTexture_0ibsw"] +atlas = ExtResource("3_8r6gc") +region = Rect2(12, 0, 12, 12) + +[sub_resource type="SpriteFrames" id="SpriteFrames_80dw6"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_wvy7p") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_0ibsw") +}], +"loop": true, +"name": &"default", +"speed": 5.0 +}] + +[sub_resource type="CircleShape2D" id="CircleShape2D_v6kob"] +radius = 4.0 + +[node name="ShungiteDart" instance=ExtResource("1_md2qh")] + +[node name="Sprite2D" parent="." index="0"] +sprite_frames = SubResource("SpriteFrames_80dw6") +frame_progress = 0.70222 +speed_scale = 2.0 + +[node name="CollisionShape2D" parent="Hitbox" index="0"] +shape = SubResource("CircleShape2D_v6kob") + +[editable path="Hitbox"] diff --git a/Entities/Projectile.cs b/Entities/Projectile.cs index 31718a9..b617181 100644 --- a/Entities/Projectile.cs +++ b/Entities/Projectile.cs @@ -6,7 +6,15 @@ namespace SupaLidlGame.Entities; public partial class Projectile : RigidBody2D { - public Vector2 Velocity => Direction * Speed; + //public virtual Vector2 Velocity => Direction * Speed; + public virtual Vector2 Velocity + { + get => Direction * Speed; + set + { + throw new System.NotImplementedException(); + } + } [Export] public string ProjectileName { get; set; } @@ -14,6 +22,12 @@ public partial class Projectile : RigidBody2D [Export] public float Speed { get; set; } + [Export] + public Vector2 AccelerationDirection { get; set; } + + [Export] + public float AccelerationMagnitude { get; set; } + [Export] public Vector2 Direction { get; set; } diff --git a/Entities/ShungiteSpike.cs b/Entities/ShungiteSpike.cs index c88eb64..26fc2a2 100644 --- a/Entities/ShungiteSpike.cs +++ b/Entities/ShungiteSpike.cs @@ -63,8 +63,7 @@ public partial class ShungiteSpike : Projectile float damage, Characters.Character inflictor, float knockback, - Vector2 knockbackOrigin = default, - Vector2 knockbackVector = default) + Vector2 knockbackDir) { // if we were hit by the player before the spike freezes, // spawn a dart towards where the player is aiming diff --git a/Entities/ShungiteSpike.tscn b/Entities/ShungiteSpike.tscn index f3dec6c..37ae25d 100644 --- a/Entities/ShungiteSpike.tscn +++ b/Entities/ShungiteSpike.tscn @@ -5,10 +5,10 @@ [ext_resource type="Texture2D" uid="uid://dvx2b0y6dup53" path="res://Assets/Sprites/Misc/shungite-spike.png" id="2_klp8v"] [ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="3_kojrj"] [ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="4_d8dl4"] -[ext_resource type="AudioStream" uid="uid://c4n7ioxpukdwi" path="res://Assets/Sounds/parry.wav" id="6_fepye"] +[ext_resource type="AudioStream" uid="uid://jsnjoyaj6p5a" path="res://Assets/Sounds/rock-smash.wav" id="6_vr2ui"] [sub_resource type="CircleShape2D" id="CircleShape2D_hrev2"] -radius = 8.0 +radius = 6.0 [sub_resource type="CircleShape2D" id="CircleShape2D_kumrg"] radius = 12.0 @@ -144,7 +144,7 @@ shape = SubResource("CircleShape2D_hrev2") shape = SubResource("CircleShape2D_kumrg") [node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."] -stream = ExtResource("6_fepye") +stream = ExtResource("6_vr2ui") [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { diff --git a/Entities/Torch.tscn b/Entities/Torch.tscn index 3d13af6..6aee75c 100644 --- a/Entities/Torch.tscn +++ b/Entities/Torch.tscn @@ -57,7 +57,7 @@ animations = [{ }], "loop": true, "name": &"default", -"speed": 5.0 +"speed": 10.0 }] [node name="Torch" type="Node2D"] @@ -67,8 +67,7 @@ texture_filter = 1 position = Vector2(0, -12) sprite_frames = SubResource("SpriteFrames_gf7ku") autoplay = "default" -frame = 5 -frame_progress = 0.743234 +frame_progress = 0.337799 [node name="PointLight2D" type="PointLight2D" parent="."] color = Color(1, 0.898039, 0.686275, 1) diff --git a/Entities/TorchLamp.tscn b/Entities/TorchLamp.tscn index ba5c3fa..973648d 100644 --- a/Entities/TorchLamp.tscn +++ b/Entities/TorchLamp.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=16 format=3 uid="uid://ceadk7pam7vab"] [ext_resource type="Texture2D" uid="uid://cyldr0ck3yfrp" path="res://Assets/Sprites/Misc/torch-lamp.png" id="1_dlkl0"] -[ext_resource type="Texture2D" uid="uid://b8ann6yb8qox4" path="res://Assets/Sprites/Particles/light-pixel.png" id="2_yuj6j"] +[ext_resource type="Texture2D" uid="uid://coarr28adgo1u" path="res://Assets/Sprites/Particles/point-light.png" id="2_0xpf8"] [sub_resource type="AtlasTexture" id="AtlasTexture_ikvnd"] atlas = ExtResource("1_dlkl0") @@ -98,17 +98,18 @@ animations = [{ [node name="TorchLamp" type="Node2D"] [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] +y_sort_enabled = true texture_filter = 1 -position = Vector2(0, -12) sprite_frames = SubResource("SpriteFrames_gf7ku") autoplay = "default" frame = 6 frame_progress = 0.743234 +offset = Vector2(0, -12) [node name="PointLight2D" type="PointLight2D" parent="."] -color = Color(1, 0.827451, 0.619608, 1) +color = Color(1, 0.803922, 0.698039, 1) +energy = 1.2 blend_mode = 2 -shadow_enabled = true shadow_filter_smooth = 3.0 -texture = ExtResource("2_yuj6j") -offset = Vector2(0, 2) +texture = ExtResource("2_0xpf8") +texture_scale = 0.25 diff --git a/Entities/UnwantedFrequency.cs b/Entities/UnwantedFrequency.cs index e2c9932..5a1f8a4 100644 --- a/Entities/UnwantedFrequency.cs +++ b/Entities/UnwantedFrequency.cs @@ -15,6 +15,7 @@ public partial class UnwantedFrequency : Projectile public Node2D TrailRotation { get; set; } public Node2D TrailPosition { get; set; } public GpuParticles2D DeathParticles { get; set; } + public GpuParticles2D SpawnParticles { get; set; } public Timer DeferDeathTimer { get; set; } private double _currentLifetime = 0; @@ -26,6 +27,8 @@ public partial class UnwantedFrequency : Projectile Trail = TrailPosition.GetNode("Trail"); DeferDeathTimer = GetNode("DeferDeath"); DeathParticles = GetNode("DeathParticles"); + SpawnParticles = GetNode("SpawnParticles"); + SpawnParticles.Emitting = true; Hitbox.Hit += (BoundingBoxes.BoundingBox box) => { if (box is BoundingBoxes.Hurtbox && box.Faction != Hitbox.Faction) @@ -62,7 +65,8 @@ public partial class UnwantedFrequency : Projectile public override void Die() { - IsDead = Trail.IsDead = Hitbox.IsDisabled = true; + IsDead = Trail.IsDead = true; + Hitbox.SetDeferred("monitoring", false); DeferDeathTimer.Timeout += () => { QueueFree(); diff --git a/Entities/UnwantedFrequency.tscn b/Entities/UnwantedFrequency.tscn index 8087070..0a21254 100644 --- a/Entities/UnwantedFrequency.tscn +++ b/Entities/UnwantedFrequency.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=14 format=3 uid="uid://1y5r6sklwgrp"] +[gd_scene load_steps=19 format=3 uid="uid://1y5r6sklwgrp"] [ext_resource type="Script" path="res://Entities/UnwantedFrequency.cs" id="1_6sbe0"] [ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="2_gxtvd"] @@ -34,6 +34,36 @@ orbit_velocity_min = 0.0 orbit_velocity_max = 2.0 color_ramp = SubResource("GradientTexture1D_yfhnr") +[sub_resource type="Gradient" id="Gradient_5hy7c"] +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_iyaih"] +gradient = SubResource("Gradient_5hy7c") + +[sub_resource type="Curve" id="Curve_wt1cb"] +_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.2, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.5), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_5uulw"] +curve = SubResource("Curve_wt1cb") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_olfm2"] +particle_flag_disable_z = true +spread = 180.0 +gravity = Vector3(0, 0, 0) +initial_velocity_min = 32.0 +initial_velocity_max = 32.0 +angular_velocity_min = 90.0 +angular_velocity_max = 90.0 +orbit_velocity_min = 0.0 +orbit_velocity_max = 0.0 +tangential_accel_min = 8.0 +tangential_accel_max = 8.0 +scale_max = 2.0 +scale_curve = SubResource("CurveTexture_5uulw") +color = Color(1, 0, 0, 1) +color_ramp = SubResource("GradientTexture1D_iyaih") + [sub_resource type="Animation" id="Animation_w1abs"] length = 0.001 tracks/0/type = "value" @@ -73,12 +103,12 @@ _data = { [node name="UnwantedFrequency" type="RigidBody2D" node_paths=PackedStringArray("Hitbox")] script = ExtResource("1_6sbe0") -HomingVelocity = 1.4 +HomingVelocity = 1.2 ProjectileName = "Unwanted Frequency" -Speed = 140.0 +Speed = 124.0 Direction = Vector2(1, 1) Hitbox = NodePath("Hitbox") -Lifetime = 8.0 +Lifetime = 7.0 [node name="Hitbox" parent="." instance=ExtResource("2_gxtvd")] collision_layer = 0 @@ -122,6 +152,14 @@ lifetime = 2.0 one_shot = true explosiveness = 0.8 +[node name="SpawnParticles" type="GPUParticles2D" parent="."] +emitting = false +amount = 12 +process_material = SubResource("ParticleProcessMaterial_olfm2") +lifetime = 2.0 +one_shot = true +explosiveness = 1.0 + [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { "": SubResource("AnimationLibrary_v8fdt") diff --git a/Extensions/Node.cs b/Extensions/Node.cs index cf7191c..d29dd43 100644 --- a/Extensions/Node.cs +++ b/Extensions/Node.cs @@ -38,4 +38,17 @@ public static class NodeExtensions { return node.GetNode(name) as T; } + + public static T FindChildOfType(this Node node) where T : Node + { + foreach (Node child in node.GetChildren()) + { + if (child is T t) + { + return t; + } + } + + return null; + } } diff --git a/Extensions/Node2DExtensions.cs b/Extensions/Node2DExtensions.cs index ab70549..c62366e 100644 --- a/Extensions/Node2DExtensions.cs +++ b/Extensions/Node2DExtensions.cs @@ -30,6 +30,7 @@ public static class Node2DExtensions var clone = node.Duplicate() as T; world.AddChild(clone); clone.GlobalPosition = node.GlobalPosition; + GD.Print("clone on world: " + clone.GlobalPosition); return clone; } diff --git a/Extensions/Particles2D.cs b/Extensions/Particles2D.cs index fb76d57..9fdee78 100644 --- a/Extensions/Particles2D.cs +++ b/Extensions/Particles2D.cs @@ -10,5 +10,6 @@ public static class Particles2D { particles.QueueFree(); }; + particles.Emitting = true; } } diff --git a/Items/Inventory.cs b/Items/Inventory.cs index fe50d2f..18190fb 100644 --- a/Items/Inventory.cs +++ b/Items/Inventory.cs @@ -14,6 +14,9 @@ public partial class Inventory : Node2D [Export] public Dictionary InventoryMap { get; set; } + [Signal] + public delegate void UsedItemEventHandler(Item item); + public const int MaxCapacity = 32; private Item _selectedItem; diff --git a/Items/Weapon.cs b/Items/Weapon.cs index 2d6a497..26d74eb 100644 --- a/Items/Weapon.cs +++ b/Items/Weapon.cs @@ -53,6 +53,9 @@ public abstract partial class Weapon : Item [Export] public float MaxDistanceHint { get; set; } + [Export] + public Sprite2D HandAnchor { get; set; } + public virtual bool IsParryable { get; protected set; } = false; public bool IsParried { get; set; } @@ -70,6 +73,12 @@ public abstract partial class Weapon : Item Visible = true; } Character = character; + + // set the hand textures to the character's + if (HandAnchor is not null && character.HandTexture is not null) + { + HandAnchor.Texture = character.HandTexture; + } } public override void Unequip(Character character) @@ -99,7 +108,7 @@ public abstract partial class Weapon : Item } } - public virtual void _on_hitbox_hit(BoundingBox box) + public virtual void OnHitboxHit(BoundingBox box) { if (box is Hurtbox hurtbox) { diff --git a/Items/Weapons/DocLance.tscn b/Items/Weapons/DocLance.tscn new file mode 100644 index 0000000..6db849d --- /dev/null +++ b/Items/Weapons/DocLance.tscn @@ -0,0 +1,293 @@ +[gd_scene load_steps=21 format=3 uid="uid://p7oijq6dbvvk"] + +[ext_resource type="Script" path="res://Items/Weapons/Sword.cs" id="1_1oyma"] +[ext_resource type="Script" path="res://State/Weapon/WeaponStateMachine.cs" id="2_c41ov"] +[ext_resource type="Script" path="res://State/Weapon/SwordIdleState.cs" id="3_sxffm"] +[ext_resource type="Script" path="res://State/Weapon/SwordAnticipateState.cs" id="4_t7af2"] +[ext_resource type="Script" path="res://State/Weapon/SwordAttackState.cs" id="5_i5v42"] +[ext_resource type="Texture2D" uid="uid://o7enu13gvji5" path="res://Assets/Sprites/doc-lance.png" id="6_7t87o"] +[ext_resource type="Material" uid="uid://cbfaqolx1ydvv" path="res://Assets/Sprites/Particles/ParryParticles.tres" id="8_y2qyn"] +[ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="9_buajm"] +[ext_resource type="Texture2D" uid="uid://cmvh6pc71ir1m" path="res://Assets/Sprites/sword-swing-large.png" id="11_46l1i"] +[ext_resource type="AudioStream" uid="uid://qvthq6tppp63" path="res://Assets/Sounds/whoosh.wav" id="12_85vwu"] +[ext_resource type="AudioStream" uid="uid://cceld51anbm1m" path="res://Assets/Sounds/unsheathe.wav" id="12_khh4e"] +[ext_resource type="AudioStream" uid="uid://c4n7ioxpukdwi" path="res://Assets/Sounds/parry.wav" id="13_p4djk"] + +[sub_resource type="Curve" id="Curve_36q15"] +_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(0.5, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.5), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_383y7"] +curve = SubResource("Curve_36q15") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_duy55"] +emission_shape = 3 +emission_box_extents = Vector3(1, 1, 1) +particle_flag_disable_z = true +direction = Vector3(0, 1, 0) +spread = 60.0 +gravity = Vector3(0, 0, 0) +initial_velocity_min = 8.0 +initial_velocity_max = 16.0 +orbit_velocity_min = 0.0 +orbit_velocity_max = 0.0 +scale_min = 2.0 +scale_max = 2.0 +scale_curve = SubResource("CurveTexture_383y7") +color = Color(1, 0, 1, 1) + +[sub_resource type="Animation" id="Animation_b7327"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Anchor:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [1.5708] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("SwingSprite:frame") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Anchor:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(0, 0)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Anchor/Node2D:rotation") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.0001, 0.0002), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [0.0, 0.0, 0.0] +} +tracks/4/type = "method" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath(".") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": ["is_alternate", false], +"method": &"SetAnimationCondition" +}] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("SwingSprite:modulate") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(2, 2, 2, 1)] +} + +[sub_resource type="Animation" id="Animation_ameas"] +resource_name = "anticipate" +length = 0.1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Anchor:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(0, 0), Vector2(-8, 0)] +} +tracks/1/type = "method" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("UnsheatheSound") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [0.0], +"method": &"play" +}] +} + +[sub_resource type="Animation" id="Animation_6jphj"] +resource_name = "attack" +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Anchor:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 0.65), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [Vector2(-8, 0), Vector2(8, 0), Vector2(0, 0)] +} +tracks/1/type = "method" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("SwingSound") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0.1), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [0.0], +"method": &"play" +}] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_tao4k"] +_data = { +"RESET": SubResource("Animation_b7327"), +"anticipate": SubResource("Animation_ameas"), +"attack": SubResource("Animation_6jphj") +} + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_rrgwb"] +size = Vector2(8, 32) + +[node name="DocLance" type="Node2D" node_paths=PackedStringArray("Hitbox", "AnimationPlayer", "ParryParticles", "StateMachine", "Anchor", "HandAnchor")] +y_sort_enabled = true +texture_filter = 3 +script = ExtResource("1_1oyma") +Hitbox = NodePath("Hitbox") +AnimationPlayer = NodePath("AnimationPlayer") +AttackTime = 0.2 +AttackAnimationDuration = 0.75 +ParryParticles = NodePath("Anchor/Node2D/Sprite2D/ParryParticles") +NPCAnticipateTime = 0.3 +StateMachine = NodePath("State") +Anchor = NodePath("Anchor") +Damage = 20.0 +UseTime = 0.55 +Knockback = 64.0 +ShouldHideIdle = true +HandAnchor = NodePath("Anchor/Node2D/Sprite2D/Hand") +ItemName = "VSM-93" +Description = "\"Violence. Speed. Momentum.\"" + +[node name="State" type="Node" parent="." node_paths=PackedStringArray("InitialState")] +script = ExtResource("2_c41ov") +InitialState = NodePath("Idle") + +[node name="Idle" type="Node" parent="State" node_paths=PackedStringArray("AnticipateState", "Sword")] +script = ExtResource("3_sxffm") +AnticipateState = NodePath("../Anticipate") +Sword = NodePath("../..") + +[node name="Anticipate" type="Node" parent="State" node_paths=PackedStringArray("Sword", "AttackState")] +script = ExtResource("4_t7af2") +Sword = NodePath("../..") +AttackState = NodePath("../Attack") + +[node name="Attack" type="Node" parent="State" node_paths=PackedStringArray("Sword", "IdleState")] +script = ExtResource("5_i5v42") +Sword = NodePath("../..") +IdleState = NodePath("../Idle") + +[node name="Anchor" type="Node2D" parent="."] +y_sort_enabled = true +rotation = 1.5708 + +[node name="Node2D" type="Node2D" parent="Anchor"] +y_sort_enabled = true +position = Vector2(-4, 0) + +[node name="Sprite2D" type="Sprite2D" parent="Anchor/Node2D"] +y_sort_enabled = true +position = Vector2(0, -8) +texture = ExtResource("6_7t87o") + +[node name="ParryParticles" type="GPUParticles2D" parent="Anchor/Node2D/Sprite2D"] +modulate = Color(1.2, 1.2, 1.2, 1) +position = Vector2(-0.221825, -3.12132) +rotation = 0.785398 +emitting = false +amount = 16 +process_material = ExtResource("8_y2qyn") +lifetime = 2.0 +one_shot = true +explosiveness = 1.0 +trail_enabled = true +trail_lifetime = 0.1 +trail_sections = 4 + +[node name="GPUParticles2D" type="GPUParticles2D" parent="Anchor/Node2D/Sprite2D"] +position = Vector2(-2.28882e-05, -6) +amount = 4 +process_material = SubResource("ParticleProcessMaterial_duy55") +lifetime = 0.25 + +[node name="Hand" type="Sprite2D" parent="Anchor/Node2D/Sprite2D"] +position = Vector2(-2.52724e-05, 7) +rotation = 1.5708 + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_tao4k") +} + +[node name="Hitbox" parent="." instance=ExtResource("9_buajm")] +position = Vector2(16, -4) +IsDisabled = true + +[node name="CollisionShape2D" parent="Hitbox" index="0"] +rotation = 1.5708 +shape = SubResource("RectangleShape2D_rrgwb") +disabled = true + +[node name="SwingSprite" type="Sprite2D" parent="."] +modulate = Color(2, 2, 2, 1) +texture = ExtResource("11_46l1i") +offset = Vector2(8, 0) +hframes = 5 + +[node name="SwingSound" type="AudioStreamPlayer2D" parent="."] +stream = ExtResource("12_85vwu") +max_distance = 256.0 + +[node name="ParrySound" type="AudioStreamPlayer2D" parent="."] +stream = ExtResource("13_p4djk") +max_distance = 256.0 + +[node name="UnsheatheSound" type="AudioStreamPlayer2D" parent="."] +stream = ExtResource("12_khh4e") + +[editable path="Hitbox"] diff --git a/Items/Weapons/DocLanceHold.tscn b/Items/Weapons/DocLanceHold.tscn new file mode 100644 index 0000000..5e13544 --- /dev/null +++ b/Items/Weapons/DocLanceHold.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=3 format=3 uid="uid://bauucuqvjwbxp"] + +[ext_resource type="PackedScene" uid="uid://p7oijq6dbvvk" path="res://Items/Weapons/DocLance.tscn" id="1_kmq5r"] +[ext_resource type="Script" path="res://State/Weapon/SwordHoldAttackState.cs" id="2_7fom6"] + +[node name="DocLance" instance=ExtResource("1_kmq5r")] +NPCAnticipateTime = 0.1 + +[node name="Anticipate" parent="State" index="1" node_paths=PackedStringArray("AttackState")] +AttackState = NodePath("../HoldAttack") + +[node name="Attack" parent="State" index="2"] +script = ExtResource("2_7fom6") + +[node name="HoldAttack" type="Node" parent="State" index="3" node_paths=PackedStringArray("Sword", "IdleState")] +script = ExtResource("2_7fom6") +Sword = NodePath("../..") +IdleState = NodePath("../Idle") + +[editable path="Hitbox"] diff --git a/Items/Weapons/Lance.cs b/Items/Weapons/Lance.cs new file mode 100644 index 0000000..b8702a2 --- /dev/null +++ b/Items/Weapons/Lance.cs @@ -0,0 +1,13 @@ +/* +using Godot; + +namespace SupaLidlGame.Items.Weapons; + +public partial class Lance : Sword +{ + public override void _Ready() + { + + } +} +*/ diff --git a/Items/Weapons/Sword.cs b/Items/Weapons/Sword.cs index 12a719d..29bb16b 100644 --- a/Items/Weapons/Sword.cs +++ b/Items/Weapons/Sword.cs @@ -20,9 +20,6 @@ public partial class Sword : Weapon, IParryable [Export] public AnimationPlayer AnimationPlayer { get; set; } - [Export] - public AnimationTree AnimationTree { get; set; } - /// /// The time frame in seconds for which the weapon will deal damage. /// @@ -37,7 +34,7 @@ public partial class Sword : Weapon, IParryable public double AttackAnimationDuration { get; set; } [Export] - public CpuParticles2D ParryParticles { get; set; } + public GpuParticles2D ParryParticles { get; set; } [Export] public double NPCAnticipateTime { get; set; } @@ -69,41 +66,7 @@ public partial class Sword : Weapon, IParryable public override void Use() { - // we can't use if we're still using the weapon - if (RemainingUseTime > 0) - { - //return; - } - StateMachine.Use(); - - /* - // reset state of the weapon - IsParried = false; - IsParryable = true; - ParryTimeOrigin = Time.GetTicksMsec(); - - _playback.Travel("use"); - */ - - // play animation depending on rotation of weapon - /* - string anim = "use"; - - if (GetNode("Anchor").Rotation > Mathf.DegToRad(50)) - { - anim = "use2"; - } - - if (Character is NPC) - { - // NPCs have a slower attack - anim += "-npc"; - } - - AnimationPlayer.Play(anim); - */ - base.Use(); } @@ -112,7 +75,6 @@ public partial class Sword : Weapon, IParryable IsParried = false; IsParryable = true; ParryTimeOrigin = Time.GetTicksMsec(); - GD.Print(Character.Name); } public void DisableParry() @@ -123,7 +85,8 @@ public partial class Sword : Weapon, IParryable public override void Deuse() { //AnimationPlayer.Stop(); - Deattack(); + //Deattack(); + StateMachine.Deuse(); base.Deuse(); } @@ -147,8 +110,7 @@ public partial class Sword : Weapon, IParryable public override void _Ready() { Hitbox.Damage = Damage; - _playback = (AnimationNodeStateMachinePlayback)AnimationTree - .Get("parameters/playback"); + Hitbox.Hit += OnHitboxHit; } public override void _Process(double delta) @@ -166,9 +128,9 @@ public partial class Sword : Weapon, IParryable foreach (BoundingBox box in Hitbox.Hits) { - GD.Print("processing hit"); if (box is Hurtbox hurtbox) { + GD.Print("LUL"); hurtbox.InflictDamage(Damage, Character, Knockback); } } @@ -176,32 +138,33 @@ public partial class Sword : Weapon, IParryable public void AttemptParry(Weapon otherWeapon) { - //if (IsParryable && otherWeapon.IsParryable) if (otherWeapon.IsParryable && - otherWeapon is IParryable otherParryable) + otherWeapon is IParryable otherParryable) { - ParryParticles.Emitting = true; if (ParryTimeOrigin < otherParryable.ParryTimeOrigin) { // our character was parried + ParryParticles.CloneOnWorld().EmitOneShot(); } else { otherParryable.Stun(); } } - //this.GetAncestor().AddChild(instance); } public void Stun() { IsParried = true; AnimationPlayer.SpeedScale = 0.25f; - Character.Stun(1.5f); - GetNode("ParrySound").OnWorld().PlayOneShot(); + Character.Stun(1); + GetNode("ParrySound") + .OnWorld() + .WithPitchDeviation(0.125f) + .PlayOneShot(); } - public override void _on_hitbox_hit(BoundingBox box) + public override void OnHitboxHit(BoundingBox box) { if (IsParried) { @@ -232,6 +195,6 @@ public partial class Sword : Weapon, IParryable protected void SetAnimationCondition(string condition, bool value) { - AnimationTree.Set("parameters/conditions/" + condition, value); + } } diff --git a/Items/Weapons/Sword.tscn b/Items/Weapons/Sword.tscn index 0b53cac..c9d0d02 100644 --- a/Items/Weapons/Sword.tscn +++ b/Items/Weapons/Sword.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=35 format=3 uid="uid://dvqap2uhcah63"] +[gd_scene load_steps=36 format=3 uid="uid://dvqap2uhcah63"] [ext_resource type="Script" path="res://Items/Weapons/Sword.cs" id="1_mlo73"] [ext_resource type="Script" path="res://State/Weapon/WeaponStateMachine.cs" id="2_vwirq"] @@ -8,8 +8,11 @@ [ext_resource type="Script" path="res://State/Weapon/SwordAnticipateState.cs" id="4_j3cud"] [ext_resource type="PackedScene" uid="uid://cojxmcin13ihm" path="res://Utils/Trail.tscn" id="4_pt6lq"] [ext_resource type="Script" path="res://State/Weapon/SwordAttackState.cs" id="5_hmisb"] -[ext_resource type="Texture2D" uid="uid://do1bui3bblkk7" path="res://Assets/Sprites/sword-swing.png" id="5_pywek"] [ext_resource type="AudioStream" uid="uid://c4n7ioxpukdwi" path="res://Assets/Sounds/parry.wav" id="6_8nxjm"] +[ext_resource type="Material" uid="uid://cbfaqolx1ydvv" path="res://Assets/Sprites/Particles/ParryParticles.tres" id="8_10gir"] +[ext_resource type="Shape2D" uid="uid://dw4e4r2yxwk1b" path="res://Items/Weapons/SwordCollisionShape.tres" id="9_wsprl"] +[ext_resource type="Texture2D" uid="uid://cmvh6pc71ir1m" path="res://Assets/Sprites/sword-swing-large.png" id="10_672jv"] +[ext_resource type="AudioStream" uid="uid://qvthq6tppp63" path="res://Assets/Sounds/whoosh.wav" id="10_mfnl7"] [sub_resource type="Environment" id="Environment_72txp"] background_mode = 3 @@ -24,10 +27,6 @@ point_count = 3 offsets = PackedFloat32Array(0.835938, 0.992188) colors = PackedColorArray(1, 1, 1, 0.498039, 1, 1, 1, 0) -[sub_resource type="Gradient" id="Gradient_jjxq2"] -offsets = PackedFloat32Array(0, 0.945312) -colors = PackedColorArray(1, 1, 1, 1, 0.687215, 0.687215, 0.687215, 0) - [sub_resource type="Animation" id="Animation_b7327"] length = 0.001 tracks/0/type = "value" @@ -92,6 +91,18 @@ tracks/4/keys = { "method": &"SetAnimationCondition" }] } +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("SwingSprite:modulate") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Color(2, 2, 2, 1)] +} [sub_resource type="Animation" id="Animation_ameas"] resource_name = "anticipate" @@ -162,7 +173,7 @@ tracks/1/path = NodePath("SwingSprite:frame") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { -"times": PackedFloat32Array(0.1, 0.2, 0.4), +"times": PackedFloat32Array(0.1, 0.3, 0.35), "transitions": PackedFloat32Array(1, 1, 1), "update": 1, "values": [1, 2, 0] @@ -202,6 +213,20 @@ tracks/4/keys = { "transitions": PackedFloat32Array(), "values": [] } +tracks/5/type = "method" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("SwingSound") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0.1), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [0.0], +"method": &"play" +}] +} [sub_resource type="Animation" id="Animation_pclfs"] resource_name = "attack_alternate" @@ -225,10 +250,10 @@ tracks/1/path = NodePath("SwingSprite:frame") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { -"times": PackedFloat32Array(0.1, 0.2, 0.4), +"times": PackedFloat32Array(0.1, 0.3, 0.35), "transitions": PackedFloat32Array(1, 1, 1), "update": 1, -"values": [1, 3, 0] +"values": [3, 4, 0] } tracks/2/type = "value" tracks/2/imported = false @@ -328,11 +353,7 @@ graph_offset = Vector2(0, -104.073) [sub_resource type="AnimationNodeStateMachinePlayback" id="AnimationNodeStateMachinePlayback_o5g2u"] -[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_ic623"] -radius = 20.0 -height = 48.0 - -[node name="Sword" type="Node2D" node_paths=PackedStringArray("Hitbox", "AnimationPlayer", "AnimationTree", "ParryParticles", "StateMachine", "Anchor")] +[node name="Sword" type="Node2D" node_paths=PackedStringArray("Hitbox", "AnimationPlayer", "AnimationTree", "ParryParticles", "StateMachine", "Anchor", "HandAnchor")] y_sort_enabled = true texture_filter = 3 script = ExtResource("1_mlo73") @@ -349,6 +370,7 @@ Damage = 20.0 UseTime = 0.55 Knockback = 64.0 ShouldHideIdle = true +HandAnchor = NodePath("Anchor/Node2D/Sprite2D/Hand") [node name="State" type="Node" parent="." node_paths=PackedStringArray("InitialState")] script = ExtResource("2_vwirq") @@ -392,23 +414,23 @@ y_sort_enabled = true position = Vector2(0, -8) texture = ExtResource("3_r75ni") -[node name="ParryParticles" type="CPUParticles2D" parent="Anchor/Node2D/Sprite2D"] +[node name="ParryParticles" type="GPUParticles2D" parent="Anchor/Node2D/Sprite2D"] modulate = Color(1.2, 1.2, 1.2, 1) position = Vector2(-0.221825, -3.12132) rotation = 0.785398 emitting = false -amount = 24 -lifetime = 0.4 +amount = 16 +process_material = ExtResource("8_10gir") +lifetime = 2.0 one_shot = true explosiveness = 1.0 -emission_shape = 1 -emission_sphere_radius = 4.0 -direction = Vector2(0, -1) -spread = 180.0 -gravity = Vector2(0, 200) -initial_velocity_min = 8.0 -initial_velocity_max = 64.0 -color_ramp = SubResource("Gradient_jjxq2") +trail_enabled = true +trail_lifetime = 0.1 +trail_sections = 4 + +[node name="Hand" type="Sprite2D" parent="Anchor/Node2D/Sprite2D"] +position = Vector2(-2.52724e-05, 7) +rotation = 1.5708 [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { @@ -428,22 +450,21 @@ IsDisabled = true [node name="CollisionShape2D" parent="Hitbox" index="0"] position = Vector2(4, 0) rotation = 1.5708 -shape = SubResource("CapsuleShape2D_ic623") +shape = ExtResource("9_wsprl") disabled = true [node name="SwingSprite" type="Sprite2D" parent="."] modulate = Color(2, 2, 2, 1) -texture = ExtResource("5_pywek") +texture = ExtResource("10_672jv") offset = Vector2(8, 0) -hframes = 4 +hframes = 5 [node name="SwingSound" type="AudioStreamPlayer2D" parent="."] +stream = ExtResource("10_mfnl7") max_distance = 256.0 [node name="ParrySound" type="AudioStreamPlayer2D" parent="."] stream = ExtResource("6_8nxjm") max_distance = 256.0 -[connection signal="Hit" from="Hitbox" to="." method="_on_hitbox_hit"] - [editable path="Hitbox"] diff --git a/Items/Weapons/SwordCollisionShape.tres b/Items/Weapons/SwordCollisionShape.tres new file mode 100644 index 0000000..5a21280 --- /dev/null +++ b/Items/Weapons/SwordCollisionShape.tres @@ -0,0 +1,4 @@ +[gd_resource type="ConvexPolygonShape2D" format=3 uid="uid://dw4e4r2yxwk1b"] + +[resource] +points = PackedVector2Array(0, 0, -21.213, 21.213, -30, 0, -21.213, -21.213, 0, -30, 21.213, -21.213, 30, 0, 21.213, 21.213, 0, 0) diff --git a/README.org b/README.org index af43069..18eb7fa 100644 --- a/README.org +++ b/README.org @@ -2,8 +2,5 @@ Forsen-related game -Issue below fixed with [[https://github.com/godotengine/godot/pull/68866]]. Please update your version to ~4.0.beta6.mono~. - -+*NOTE:* although the latest version at the time of writing is ~4.0.beta5.mono~, this project only works under ~4.0.beta4.mono~. The latest beta does not include node exports, which was previously in Beta 4.+ - -+[[https://github.com/godotengine/godot/pull/67055]]+ +#+attr_html: :style margin-left: auto; margin-right: auto; +[[./Assets/Sprites/Characters/forsen2-portrait.png]] diff --git a/Scenes/Level.tscn b/Scenes/Level.tscn index 910e672..4493032 100644 --- a/Scenes/Level.tscn +++ b/Scenes/Level.tscn @@ -1,8 +1,56 @@ -[gd_scene load_steps=3 format=3 uid="uid://1pb3mpmrl7lc"] +[gd_scene load_steps=6 format=3 uid="uid://1pb3mpmrl7lc"] [ext_resource type="Script" path="res://Utils/World.cs" id="1_1k6ew"] [ext_resource type="PackedScene" uid="uid://b2x17su05ou5w" path="res://Scenes/Maps/Arena.tscn" id="2_avsrq"] +[ext_resource type="PackedScene" uid="uid://bxo553hblp6nf" path="res://UI/HealthBar.tscn" id="3_5rhge"] +[ext_resource type="Script" path="res://UI/UIController.cs" id="3_fe62s"] +[ext_resource type="PackedScene" uid="uid://01d24ij5av1y" path="res://UI/BossBar.tscn" id="5_8njq4"] [node name="World" type="Node2D"] script = ExtResource("1_1k6ew") StartingArea = ExtResource("2_avsrq") + +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="UI" type="Control" parent="CanvasLayer"] +z_index = 128 +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("3_fe62s") + +[node name="Top" type="HBoxContainer" parent="CanvasLayer/UI"] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 40.0 +grow_horizontal = 2 + +[node name="Margin" type="MarginContainer" parent="CanvasLayer/UI/Top"] +layout_mode = 2 +theme_override_constants/margin_left = 16 +theme_override_constants/margin_top = 16 + +[node name="HealthBar" parent="CanvasLayer/UI/Top/Margin" instance=ExtResource("3_5rhge")] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Bottom" type="HBoxContainer" parent="CanvasLayer/UI"] +visible = false +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -44.0 +grow_horizontal = 2 +grow_vertical = 0 +alignment = 1 + +[node name="BossBar" parent="CanvasLayer/UI/Bottom" instance=ExtResource("5_8njq4")] +layout_mode = 2 diff --git a/Scenes/Maps/Arena.tscn b/Scenes/Maps/Arena.tscn index 4cf9b93..edd55cc 100644 --- a/Scenes/Maps/Arena.tscn +++ b/Scenes/Maps/Arena.tscn @@ -1,23 +1,51 @@ -[gd_scene load_steps=13 format=3 uid="uid://b2x17su05ou5w"] +[gd_scene load_steps=15 format=3 uid="uid://b2x17su05ou5w"] [ext_resource type="PackedScene" uid="uid://clwv2owvk6abe" path="res://Scenes/BaseMap.tscn" id="1_ifiic"] [ext_resource type="Texture2D" uid="uid://b0yiy7w8nxmas" path="res://Assets/Sprites/arena-tileset.png" id="2_wnjm0"] -[ext_resource type="PackedScene" uid="uid://d2skjvvx6fal0" path="res://Characters/Doc.tscn" id="4_c0csw"] -[ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="5_aevwf"] +[ext_resource type="PackedScene" uid="uid://d2skjvvx6fal0" path="res://Characters/Doc.tscn" id="4_ej0f3"] +[ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="5_h8k5p"] [ext_resource type="PackedScene" uid="uid://c1w7t6irnohfx" path="res://Entities/Torch.tscn" id="6_1wwor"] [ext_resource type="PackedScene" uid="uid://ceadk7pam7vab" path="res://Entities/TorchLamp.tscn" id="6_jy3pc"] +[ext_resource type="Texture2D" uid="uid://d1ukste16yq6v" path="res://Assets/Sprites/Particles/player-light.png" id="7_y7j0e"] -[sub_resource type="OccluderPolygon2D" id="OccluderPolygon2D_8jil2"] -polygon = PackedVector2Array(-8, -4, -6, -5, -6, -18, 6, -18, 6, -5, 8, -4, 8, 4, 4, 8, -4, 8, -8, 3.5) +[sub_resource type="CanvasTexture" id="CanvasTexture_3n6aa"] +diffuse_texture = ExtResource("2_wnjm0") [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_fcd6d"] -texture = ExtResource("2_wnjm0") +texture = SubResource("CanvasTexture_3n6aa") +use_texture_padding = false 0:0/0 = 0 0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 0:0/0/physics_layer_0/angular_velocity = 0.0 +1:1/0 = 0 +1:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:1/0/physics_layer_0/angular_velocity = 0.0 +2:1/0 = 0 +2:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:1/0/physics_layer_0/angular_velocity = 0.0 +2:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +2:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:2/0/physics_layer_0/angular_velocity = 0.0 +2:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, 0, 8, 0, 8, 8, -8, 8) 1:0/0 = 0 1:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 1:0/0/physics_layer_0/angular_velocity = 0.0 +0:1/0 = 0 +0:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:1/0/physics_layer_0/angular_velocity = 0.0 +0:2/0 = 0 +0:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:2/0/physics_layer_0/angular_velocity = 0.0 +0:3/0 = 0 +0:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:3/0/physics_layer_0/angular_velocity = 0.0 +1:3/0 = 0 +1:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:3/0/physics_layer_0/angular_velocity = 0.0 +1:2/0 = 0 +1:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:2/0/physics_layer_0/angular_velocity = 0.0 2:0/0 = 0 2:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 2:0/0/physics_layer_0/angular_velocity = 0.0 @@ -35,94 +63,68 @@ texture = ExtResource("2_wnjm0") 6:0/0 = 0 6:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) 6:0/0/physics_layer_0/angular_velocity = 0.0 -7:0/size_in_atlas = Vector2i(1, 2) -7:0/0 = 0 -7:0/0/texture_origin = Vector2i(0, 8) -7:0/0/occlusion_layer_0/polygon = SubResource("OccluderPolygon2D_8jil2") -7:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) -7:0/0/physics_layer_0/angular_velocity = 0.0 -7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -4, 8, -4, 8, 3.5, 4.5, 8, -4, 8, -8, 4) -0:1/0 = 0 -0:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) -0:1/0/physics_layer_0/angular_velocity = 0.0 -1:1/0 = 0 -1:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) -1:1/0/physics_layer_0/angular_velocity = 0.0 -2:1/0 = 0 -2:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) -2:1/0/physics_layer_0/angular_velocity = 0.0 -2:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) -3:1/0 = 0 -3:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) -3:1/0/physics_layer_0/angular_velocity = 0.0 -3:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) -4:1/0 = 0 -4:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) -4:1/0/physics_layer_0/angular_velocity = 0.0 -4:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) -5:1/0 = 0 -5:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) -5:1/0/physics_layer_0/angular_velocity = 0.0 -5:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) 6:1/0 = 0 6:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) 6:1/0/physics_layer_0/angular_velocity = 0.0 6:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) -0:2/0 = 0 -0:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) -0:2/0/physics_layer_0/angular_velocity = 0.0 -0:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) -1:2/0 = 0 -1:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) -1:2/0/physics_layer_0/angular_velocity = 0.0 -1:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) -2:2/0 = 0 -2:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) -2:2/0/physics_layer_0/angular_velocity = 0.0 +5:1/0 = 0 +5:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:1/0/physics_layer_0/angular_velocity = 0.0 +5:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +4:1/0 = 0 +4:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:1/0/physics_layer_0/angular_velocity = 0.0 +4:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:1/0 = 0 +3:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:1/0/physics_layer_0/angular_velocity = 0.0 +3:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) 3:2/0 = 0 3:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) 3:2/0/physics_layer_0/angular_velocity = 0.0 -3:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 0, -8, 0) +3:3/0 = 0 +3:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:3/0/physics_layer_0/angular_velocity = 0.0 +3:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(0, -8, 8, -8, 8, 8, 0, 8) +2:3/0 = 0 +2:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:3/0/physics_layer_0/angular_velocity = 0.0 +2:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -8, 0, 8, -8, 8) +4:3/0 = 0 +4:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:3/0/physics_layer_0/angular_velocity = 0.0 +4:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(8, -8, 8, 0, 0, 0, 0, -8) 4:2/0 = 0 4:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) 4:2/0/physics_layer_0/angular_velocity = 0.0 +4:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(0, 0, 8, 0, 8, 8, 0, 8) 5:2/0 = 0 5:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) 5:2/0/physics_layer_0/angular_velocity = 0.0 +5:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, 0, 0, 0, 0, 8, -8, 8) +5:3/0 = 0 +5:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:3/0/physics_layer_0/angular_velocity = 0.0 +5:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -8, 0, 0, -8, 0) +6:3/0 = 0 +6:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:3/0/physics_layer_0/angular_velocity = 0.0 6:2/0 = 0 6:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) 6:2/0/physics_layer_0/angular_velocity = 0.0 7:2/0 = 0 7:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) 7:2/0/physics_layer_0/angular_velocity = 0.0 -0:3/0 = 0 -0:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) -0:3/0/physics_layer_0/angular_velocity = 0.0 -0:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) -1:3/0 = 0 -1:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) -1:3/0/physics_layer_0/angular_velocity = 0.0 -1:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) -2:3/0 = 0 -2:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) -2:3/0/physics_layer_0/angular_velocity = 0.0 -2:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) -3:3/0 = 0 -3:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) -3:3/0/physics_layer_0/angular_velocity = 0.0 -3:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) -4:3/0 = 0 -4:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) -4:3/0/physics_layer_0/angular_velocity = 0.0 -5:3/0 = 0 -5:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) -5:3/0/physics_layer_0/angular_velocity = 0.0 -6:3/0 = 0 -6:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) -6:3/0/physics_layer_0/angular_velocity = 0.0 7:3/0 = 0 7:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) 7:3/0/physics_layer_0/angular_velocity = 0.0 +7:0/size_in_atlas = Vector2i(1, 2) +7:0/0 = 0 +7:0/0/texture_origin = Vector2i(0, 8) +7:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:0/0/physics_layer_0/angular_velocity = 0.0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -5, 8, -5, 8, 4, 4, 8, -4, 8, -8, 4) [sub_resource type="OccluderPolygon2D" id="OccluderPolygon2D_kbvre"] polygon = PackedVector2Array(-4, 8, -8, 4, -8, -4, -6, -4, -6, -20, 6, -20, 6, -4, 8, -4, 8, 4, 4, 8) @@ -249,11 +251,15 @@ physics_layer_0/collision_layer = 1 sources/2 = SubResource("TileSetAtlasSource_5yxvt") sources/0 = SubResource("TileSetAtlasSource_fcd6d") -[sub_resource type="ShaderMaterial" id="ShaderMaterial_im5g2"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_q3ile"] resource_local_to_scene = true -shader = ExtResource("5_aevwf") +shader = ExtResource("5_h8k5p") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 +shader_parameter/alpha_modulate = 1.0 + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_gwpea"] +size = Vector2(256, 256) [node name="TileMap" instance=ExtResource("1_ifiic")] tile_set = SubResource("TileSet_k1u48") @@ -262,42 +268,99 @@ layer_3/tile_data = PackedInt32Array(-196612, 65536, 1, -131076, 65536, 1, -6554 layer_4/tile_data = PackedInt32Array(-524296, 327680, 0, -589818, 262144, 0, -589817, 262144, 1, -589819, 327680, 0, -589820, 196608, 1, -589821, 327680, 1, -589822, 131072, 1, -589823, 262144, 1, -589824, 327680, 0, -524289, 131072, 1, -524290, 327680, 0, -524291, 327680, 1, -524292, 327680, 1, -524293, 327680, 0, -524294, 131072, 1, -524295, 262144, 1, -589832, 131072, 2, -589831, 131072, 2, -589830, 131072, 2, -589829, 131072, 2, -589828, 131072, 2, -589827, 131072, 2, -589826, 131072, 2, -589825, 131072, 2, -655360, 131072, 2, -655359, 131072, 2, -655358, 131072, 2, -655357, 131072, 2, -655356, 131072, 2, -655355, 131072, 2, -655354, 131072, 2, -655353, 131072, 2, -655352, 327680, 2, -589833, 262144, 2, -524297, 196608, 3, -458761, 196608, 3, -393225, 196608, 3, -327689, 196608, 3, -262153, 196608, 3, -196617, 196608, 3, -131081, 196608, 3, -65545, 196608, 3, -9, 196608, 3, 65527, 196608, 3, 131063, 196608, 3, 196599, 196608, 3, 262135, 196608, 3, 327671, 196608, 3, 393207, 196608, 3, 458743, 196608, 3, 524279, 196608, 3, 262152, 131072, 3, 327688, 131072, 3, 393224, 131072, 3, 458760, 131072, 3, 196616, 131072, 3, 131080, 131072, 3, 65544, 131072, 3, 8, 131072, 3, -65528, 131072, 3, -131064, 131072, 3, -196600, 131072, 3, -262136, 131072, 3, -589816, 131072, 3, -524280, 131072, 3, -458744, 131072, 3, -393208, 131072, 3, -327672, 131072, 3, 589816, 196608, 2, 589817, 196608, 2, 589818, 196608, 2, 589819, 196608, 2, 589820, 196608, 2, 589821, 196608, 2, 589822, 196608, 2, 589823, 196608, 2, 524288, 196608, 2, 524289, 196608, 2, 524290, 196608, 2, 524291, 196608, 2, 524292, 196608, 2, 524293, 196608, 2, 524294, 196608, 2, 524295, 196608, 2, 524296, 327680, 3, 589815, 262144, 3) [node name="CanvasModulate" parent="." index="0"] -color = Color(0.501961, 0.501961, 0.501961, 1) +color = Color(0.682353, 0.643137, 0.866667, 1) -[node name="Doc" parent="Entities" index="0" instance=ExtResource("4_c0csw")] -material = SubResource("ShaderMaterial_im5g2") -PreferredWeightDistance = 256.0 -MaxWeightDistance = 32.0 - -[node name="Torch" parent="Entities" index="1" instance=ExtResource("6_1wwor")] -position = Vector2(-120, -112) - -[node name="Torch2" parent="Entities" index="2" instance=ExtResource("6_1wwor")] -position = Vector2(-72, -112) - -[node name="Torch3" parent="Entities" index="3" instance=ExtResource("6_1wwor")] -position = Vector2(-24, -113) - -[node name="Torch4" parent="Entities" index="4" instance=ExtResource("6_1wwor")] -position = Vector2(24, -112) - -[node name="Torch5" parent="Entities" index="5" instance=ExtResource("6_1wwor")] -position = Vector2(72, -112) - -[node name="Torch6" parent="Entities" index="6" instance=ExtResource("6_1wwor")] -position = Vector2(120, -112) - -[node name="TorchLamp" parent="." index="6" instance=ExtResource("6_jy3pc")] +[node name="TorchLamp" parent="Entities" index="0" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true position = Vector2(-96, -120) -[node name="TorchLamp2" parent="." index="7" instance=ExtResource("6_jy3pc")] -position = Vector2(-48, -120) - -[node name="TorchLamp3" parent="." index="8" instance=ExtResource("6_jy3pc")] +[node name="TorchLamp3" parent="Entities" index="1" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true position = Vector2(0, -120) -[node name="TorchLamp4" parent="." index="9" instance=ExtResource("6_jy3pc")] -position = Vector2(48, -120) - -[node name="TorchLamp5" parent="." index="10" instance=ExtResource("6_jy3pc")] +[node name="TorchLamp5" parent="Entities" index="2" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true position = Vector2(96, -120) + +[node name="TorchLamp6" parent="Entities" index="3" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true +position = Vector2(-120, -96) + +[node name="TorchLamp7" parent="Entities" index="4" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true +position = Vector2(120, -96) + +[node name="TorchLamp9" parent="Entities" index="5" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true +position = Vector2(120, -1) + +[node name="TorchLamp11" parent="Entities" index="6" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true +position = Vector2(120, 95) + +[node name="TorchLamp12" parent="Entities" index="7" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true +position = Vector2(97, 120) + +[node name="TorchLamp14" parent="Entities" index="8" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true +position = Vector2(0, 120) + +[node name="TorchLamp16" parent="Entities" index="9" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true +position = Vector2(-96, 120) + +[node name="TorchLamp17" parent="Entities" index="10" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true +position = Vector2(-120, 95) + +[node name="TorchLamp19" parent="Entities" index="11" instance=ExtResource("6_jy3pc")] +y_sort_enabled = true +position = Vector2(-120, -1) + +[node name="Torch" parent="Entities" index="12" instance=ExtResource("6_1wwor")] +visible = false +position = Vector2(-120, -112) + +[node name="Torch2" parent="Entities" index="13" instance=ExtResource("6_1wwor")] +visible = false +position = Vector2(-72, -112) + +[node name="Torch3" parent="Entities" index="14" instance=ExtResource("6_1wwor")] +visible = false +position = Vector2(-24, -113) + +[node name="Torch4" parent="Entities" index="15" instance=ExtResource("6_1wwor")] +visible = false +position = Vector2(24, -112) + +[node name="Torch5" parent="Entities" index="16" instance=ExtResource("6_1wwor")] +visible = false +position = Vector2(72, -112) + +[node name="Torch6" parent="Entities" index="17" instance=ExtResource("6_1wwor")] +visible = false +position = Vector2(120, -112) + +[node name="Doc" parent="Entities" index="18" instance=ExtResource("4_ej0f3")] +material = SubResource("ShaderMaterial_q3ile") + +[node name="PointLight2D" type="PointLight2D" parent="Entities" index="19"] +position = Vector2(168, -42) +energy = 1.5 +blend_mode = 2 +range_item_cull_mask = 0 +shadow_enabled = true +shadow_color = Color(0.572549, 0.572549, 0.572549, 0) +texture = ExtResource("7_y7j0e") +height = 16.0 + +[node name="CanvasGroup" type="CanvasGroup" parent="Entities" index="20"] + +[node name="Areas" parent="." index="2"] +visible = false + +[node name="Area2D" type="Area2D" parent="Areas" index="0"] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Areas/Area2D" index="0"] +shape = SubResource("RectangleShape2D_gwpea") diff --git a/Shaders/Flash.gdshader b/Shaders/Flash.gdshader index 46a0666..9a668ec 100644 --- a/Shaders/Flash.gdshader +++ b/Shaders/Flash.gdshader @@ -2,9 +2,11 @@ shader_type canvas_item; uniform vec4 color = vec4(1.0); uniform float intensity : hint_range(0.0, 1.0) = 0.0; +uniform float alpha_modulate : hint_range(0.0, 1.0) = 1.0; void fragment() { vec4 tex = texture(TEXTURE, UV); tex.rgb = mix(tex.rgb, color.rgb, intensity); COLOR = tex; + COLOR.a *= alpha_modulate; } \ No newline at end of file diff --git a/State/Character/CharacterDashState.cs b/State/Character/CharacterDashState.cs new file mode 100644 index 0000000..2e972fc --- /dev/null +++ b/State/Character/CharacterDashState.cs @@ -0,0 +1,56 @@ +using Godot; +using SupaLidlGame.Extensions; + +namespace SupaLidlGame.State.Character; + +public partial class CharacterDashState : CharacterState +{ + [Export] + public CharacterState IdleState { get; set; } + + [Export] + public double TimeToDash { get; set; } + + [Export] + public float VelocityModifier { get; set; } + + private double _timeLeftToDash = 0; + + public Vector2 DashDirection = Vector2.Zero; + + public override IState Enter(IState previousState) + { + _timeLeftToDash = TimeToDash; + // dash the direction we were previously moving in + DashDirection = Character.Direction; + Character.MovementAnimation.Play("dash"); + Character.MovementAnimation.Queue("idle"); + + // create ghost effect + var ghost = Character.Sprite.CloneOnWorld(); + ghost.GlobalPosition = Character.Sprite.GlobalPosition; + var tween = ghost.GetTree().CreateTween(); + tween.TweenProperty(ghost, "self_modulate", Colors.Transparent, 0.5); + tween.TweenCallback(new Callable(ghost, "queue_free")); + tween.Play(); + + return base.Enter(previousState); + } + + public override void Exit(IState nextState) + { + _timeLeftToDash = 0; + DashDirection = Character.Direction; + base.Exit(nextState); + } + + public override CharacterState Process(double delta) + { + Character.Direction = DashDirection; + if ((_timeLeftToDash -= delta) <= 0 || Character.Health <= 0) + { + return IdleState; + } + return null; + } +} diff --git a/State/Character/NPCIdleState.cs b/State/Character/NPCIdleState.cs index 617bf06..910b978 100644 --- a/State/Character/NPCIdleState.cs +++ b/State/Character/NPCIdleState.cs @@ -10,7 +10,7 @@ public partial class NPCIdleState : NPCState public override CharacterState Process(double delta) { base.Process(delta); - if (Character.Direction.LengthSquared() > 0) + if (Character.Direction.LengthSquared() > 0.01f) { return MoveState; } @@ -19,7 +19,7 @@ public partial class NPCIdleState : NPCState public override IState Enter(IState previousState) { - Character.Sprite.Play("idle"); + Character.MovementAnimation.Play("idle"); return base.Enter(previousState); } } diff --git a/State/Character/NPCMoveState.cs b/State/Character/NPCMoveState.cs index 4a6879a..b428d72 100644 --- a/State/Character/NPCMoveState.cs +++ b/State/Character/NPCMoveState.cs @@ -19,7 +19,7 @@ public partial class NPCMoveState : NPCState public override IState Enter(IState prev) { - Character.Sprite.Play("move"); + Character.MovementAnimation.Play("move"); return base.Enter(prev); } } diff --git a/State/Character/PlayerIdleState.cs b/State/Character/PlayerIdleState.cs index fcc12f4..e6eff0e 100644 --- a/State/Character/PlayerIdleState.cs +++ b/State/Character/PlayerIdleState.cs @@ -9,7 +9,6 @@ public partial class PlayerIdleState : PlayerState public override IState Enter(IState previousState) { - GD.Print("Entered idle state"); if (previousState is not PlayerMoveState) { if (Character.Direction.LengthSquared() > 0.01f) @@ -21,7 +20,26 @@ public partial class PlayerIdleState : PlayerState return MoveState; } } - _player.Animation = "idle"; + + // must be moving at least 4 u/s for more than 0.5 seconds + bool shouldPlayStopAnim = false; + + if (previousState is PlayerMoveState move) + { + shouldPlayStopAnim = move.MoveDuration > 0.5; + // NOTE: more conditions may be added soon + } + + if (shouldPlayStopAnim) + { + _player.MovementAnimation.Play("stop"); + _player.MovementAnimation.Queue("idle"); + } + else + { + _player.MovementAnimation.Play("idle"); + } + return base.Enter(previousState); } diff --git a/State/Character/PlayerMoveState.cs b/State/Character/PlayerMoveState.cs index 38334e6..64d3732 100644 --- a/State/Character/PlayerMoveState.cs +++ b/State/Character/PlayerMoveState.cs @@ -7,16 +7,19 @@ public partial class PlayerMoveState : PlayerState [Export] public PlayerRollState RollState { get; set; } + public double MoveDuration { get; private set; } + public override IState Enter(IState previousState) { - Godot.GD.Print("Started moving"); - _player.Animation = "move"; + _player.MovementAnimation.Play("move"); + MoveDuration = 0; return base.Enter(previousState); } public override CharacterState Process(double delta) { base.Process(delta); + MoveDuration += delta; if (Character.Direction.LengthSquared() == 0) { return IdleState; diff --git a/State/Character/PlayerRollState.cs b/State/Character/PlayerRollState.cs index 4c0ddbc..dde6ce3 100644 --- a/State/Character/PlayerRollState.cs +++ b/State/Character/PlayerRollState.cs @@ -8,12 +8,12 @@ public partial class PlayerRollState : PlayerState private Vector2 _rollDirection = Vector2.Zero; - private AnimationPlayer _rollAnimation; + private GpuParticles2D _particles; public override void _Ready() { - _rollAnimation = _player.GetNode("RollAnimation"); base._Ready(); + _particles = _player.GetNode("Effects/RollParticles"); } public override IState Enter(IState previousState) @@ -24,12 +24,14 @@ public partial class PlayerRollState : PlayerState Character.Target = Character.Direction; if (Character.Direction.X >= 0) { - _rollAnimation.Play("roll"); + _player.MovementAnimation.Play("roll"); } else { - _rollAnimation.PlayBackwards("roll"); + _player.MovementAnimation.PlayBackwards("roll"); } + _player.MovementAnimation.Queue("idle"); + _particles.Emitting = true; return base.Enter(previousState); } @@ -39,7 +41,7 @@ public partial class PlayerRollState : PlayerState // this state (e.g. from death) _timeLeftToRoll = 0; _rollDirection = Character.Direction; - _rollAnimation.Stop(); + _particles.Emitting = false; base.Exit(nextState); } diff --git a/State/Character/PlayerState.cs b/State/Character/PlayerState.cs index ed57644..11ea5a8 100644 --- a/State/Character/PlayerState.cs +++ b/State/Character/PlayerState.cs @@ -51,9 +51,9 @@ public abstract partial class PlayerState : CharacterState { if (Character.Inventory.SelectedItem is Items.Weapon weapon) { + var isPressed = Godot.Input.IsActionPressed("attack1"); if (!weapon.IsUsing) { - var isPressed = Godot.Input.IsActionPressed("attack1"); var ret = false; if (!weapon.ShouldHideIdle || isPressed) @@ -69,6 +69,13 @@ public abstract partial class PlayerState : CharacterState return ret; } + else + { + if (!isPressed) + { + Character.DeuseCurrentItem(); + } + } } return false; } diff --git a/State/NPC/Doc/DocAttackState.cs b/State/NPC/Doc/DocAttackState.cs index 2caf1ec..e8e6428 100644 --- a/State/NPC/Doc/DocAttackState.cs +++ b/State/NPC/Doc/DocAttackState.cs @@ -1,4 +1,5 @@ using Godot; +using GodotUtilities; namespace SupaLidlGame.State.NPC.Doc; @@ -12,5 +13,25 @@ public abstract partial class DocAttackState : NPCState public abstract DocChooseAttackState ChooseAttackState { get; set; } + protected Scenes.Map _map; + protected Utils.World _world; + protected Characters.Doc _doc; + protected double _currentDuration = 0; + protected double _currentAttackDuration = 0; + + public override void _Ready() + { + _doc = NPC as Characters.Doc; + } + + public override NPCState Enter(IState previousState) + { + _map = this.GetAncestor(); + _world = this.GetAncestor(); + _currentDuration = Duration; + _currentAttackDuration = AttackDuration; + return null; + } + protected abstract void Attack(); } diff --git a/State/NPC/Doc/DocChooseAttackState.cs b/State/NPC/Doc/DocChooseAttackState.cs index 0a31395..2b0453f 100644 --- a/State/NPC/Doc/DocChooseAttackState.cs +++ b/State/NPC/Doc/DocChooseAttackState.cs @@ -15,6 +15,9 @@ public partial class DocChooseAttackState : NPCState [Export] public DocUnwantedFrequencyState UnwantedFrequencyState { get; set; } + [Export] + public DocLanceState LanceState { get; set; } + [Export] public DocExitState ExitState { get; set; } @@ -39,18 +42,24 @@ public partial class DocChooseAttackState : NPCState public override NPCState Enter(IState previous) { + if (Doc.Intensity == 3) + { + return LanceState; + } + if (previous is not DocTelegraphState) { _consecutiveAttacks++; } else { - _consecutiveAttacks = 0; + _consecutiveAttacks = 1; } if (_consecutiveAttacks > Doc.Intensity) { - _consecutiveAttacks = 0; + _consecutiveAttacks = 1; + ResetStates(); return ExitState; } diff --git a/State/NPC/Doc/DocLanceState.cs b/State/NPC/Doc/DocLanceState.cs new file mode 100644 index 0000000..59792ee --- /dev/null +++ b/State/NPC/Doc/DocLanceState.cs @@ -0,0 +1,90 @@ +using Godot; + +namespace SupaLidlGame.State.NPC.Doc; + +public partial class DocLanceState : DocAttackState +{ + [Export] + public float DashSpeed { get; set; } = 212; + + [Export] + public DocExitState ExitState { get; set; } + + public override DocChooseAttackState ChooseAttackState + { + get => null; + set { } + } + + public override PackedScene Projectile + { + get => null; + set { } + } + + public override double AttackDuration { get; set; } + + public override double Duration { get; set; } + + protected Vector2 _dashDirection; + + protected double _dashTime; + + protected float _oldFriction = 0; + + public override NPCState Enter(IState previousState) + { + var state = base.Enter(previousState); + _doc.ShouldMove = true; + + //if (_doc.Intensity > 2) + //{ + // if (_doc.Inventory.SelectedItem != _doc.LanceHold) + // { + // _doc.Inventory.SelectedItem = _doc.LanceHold; + // _doc.UseCurrentItem(); + // _doc.CanAttack = false; + // } + //} + //else + //{ + // // wtf are we doing here? + // throw new System.InvalidOperationException(); + //} + + //_oldFriction = _doc.Friction; + //_doc.Friction = 0; + + //Attack(); + + return state; + } + + public override void Exit(IState nextState) + { + //_doc.Friction = _oldFriction; + //_doc.ApplyImpulse(Vector2.Zero, true); + //_doc.DeuseCurrentItem(); + //_doc.CanAttack = true; + base.Exit(nextState); + } + + protected override void Attack() + { + //var pos = _doc.GlobalPosition; + //var player = _world.CurrentPlayer; + //var playerPos = player.GlobalPosition; + //var predictedPos = Utils.Physics.PredictNewPosition( + // pos, DashSpeed, playerPos, player.Velocity, out float time); + //var dir = _doc.GlobalPosition.DirectionTo(predictedPos); + + //_currentAttackDuration = AttackDuration = time; + + //_doc.ApplyImpulse(dir * DashSpeed, true); + } + + public override NPCState Process(double delta) + { + return null; + } +} diff --git a/State/NPC/Doc/DocShungiteDartState.cs b/State/NPC/Doc/DocShungiteDartState.cs index 23d90d5..f7515f6 100644 --- a/State/NPC/Doc/DocShungiteDartState.cs +++ b/State/NPC/Doc/DocShungiteDartState.cs @@ -6,12 +6,6 @@ namespace SupaLidlGame.State.NPC.Doc; public partial class DocShungiteDartState : DocAttackState { - protected Scenes.Map _map; - protected Utils.World _world; - - protected double _currentDuration = 0; - protected double _currentAttackDuration = 0; - [Export] public override double Duration { get; set; } @@ -27,18 +21,8 @@ public partial class DocShungiteDartState : DocAttackState [Export] public Characters.Doc Doc { get; set; } - public override NPCState Enter(IState previousState) - { - _map = this.GetAncestor(); - _world = this.GetAncestor(); - _currentDuration = Duration; - _currentAttackDuration = AttackDuration; - return null; - } - public override void Exit(IState nextState) { - } protected virtual Projectile SpawnProjectile( @@ -71,6 +55,11 @@ public partial class DocShungiteDartState : DocAttackState public override NPCState Process(double delta) { + if (Doc.StunTime > 0) + { + return null; + } + if ((_currentDuration -= delta) <= 0) { return ChooseAttackState; diff --git a/State/NPC/Doc/DocShungiteSpikeState.cs b/State/NPC/Doc/DocShungiteSpikeState.cs index aee3b37..c28f4ea 100644 --- a/State/NPC/Doc/DocShungiteSpikeState.cs +++ b/State/NPC/Doc/DocShungiteSpikeState.cs @@ -9,20 +9,38 @@ public partial class DocShungiteSpikeState : DocShungiteDartState public override NPCState Enter(IState previous) { + Doc.CanAttack = false; + if (this is not DocUnwantedFrequencyState) + { + Doc.TelegraphAnimation.Play("shungite_spike"); + } _currentAttacks = 0; _currentAttackDuration = 1; + Doc.ShouldMove = true; + Doc.CanAttack = true; return base.Enter(previous); } + public override void Exit(IState nextState) + { + //Doc.TelegraphAnimation.Stop(); + //Doc.TelegraphAnimation.Stop(); + } + protected override Projectile SpawnProjectile( Vector2 position, Vector2 direction) { + Doc.TelegraphAnimation.Play("shungite_spike"); var projectile = base.SpawnProjectile(position, direction) as ShungiteSpike; projectile.GlobalRotation = 0; projectile.Delay = 0; - projectile.Hitbox.Faction = projectile.Hurtbox.Faction = Doc.Faction; + projectile.Hitbox.Faction = Doc.Faction; + if (projectile.Hurtbox is not null) + { + projectile.Hurtbox.Faction = Doc.Faction; + } return projectile; } @@ -43,7 +61,6 @@ public partial class DocShungiteSpikeState : DocShungiteDartState out float time); projectile.Direction = projectile.GlobalPosition.DirectionTo(targetPos); projectile.FreezeTime = time + 0.25; // freeze when it reaches target - GD.Print("projectile velocity: " + projectile.Velocity); _currentAttackDuration = 1; _currentAttacks++; @@ -51,6 +68,11 @@ public partial class DocShungiteSpikeState : DocShungiteDartState public override NPCState Process(double delta) { + if (Doc.StunTime > 0) + { + return null; + } + if ((_currentAttackDuration -= delta) <= 0) { Attack(); diff --git a/State/NPC/Doc/DocTelegraphState.cs b/State/NPC/Doc/DocTelegraphState.cs index 33649af..baa1cd6 100644 --- a/State/NPC/Doc/DocTelegraphState.cs +++ b/State/NPC/Doc/DocTelegraphState.cs @@ -1,4 +1,5 @@ using Godot; +using GodotUtilities; namespace SupaLidlGame.State.NPC.Doc; @@ -17,11 +18,28 @@ public partial class DocTelegraphState : NPCState public override NPCState Enter(IState previousState) { + // TODO: clean this up + if (!(NPC as Characters.Doc).IsActive) + { + return null; + } + _currentDuration = Duration; TelegraphAnimationPlayer.Play("enter_in"); - float randX = GD.RandRange(-128, 128); - float randY = GD.RandRange(-128, 128); - NPC.GlobalPosition = new Vector2(randX, randY); + + var player = this.GetAncestor().CurrentPlayer; + Vector2 randVec; + + do + { + float randX = GD.RandRange(-112, 112); + float randY = GD.RandRange(-112, 112); + randVec = new Vector2(randX, randY); + } + while (randVec.DistanceSquaredTo(player.GlobalPosition) < 1024); + // can not teleport within 32 units of the player + + NPC.GlobalPosition = randVec; return null; } diff --git a/State/NPC/Doc/DocUnwantedFrequencyState.cs b/State/NPC/Doc/DocUnwantedFrequencyState.cs index e2b1048..f65d405 100644 --- a/State/NPC/Doc/DocUnwantedFrequencyState.cs +++ b/State/NPC/Doc/DocUnwantedFrequencyState.cs @@ -5,6 +5,20 @@ namespace SupaLidlGame.State.NPC.Doc; public partial class DocUnwantedFrequencyState : DocShungiteSpikeState { + public override NPCState Enter(IState previous) + { + Doc.TelegraphAnimation.Play("unwanted_frequencies"); + return base.Enter(previous); + } + + public override void Exit(IState nextState) + { + GetNode("../../Effects/UnwantedFrequenciesParticles") + .Emitting = false; + GD.Print("Exit unwanted frequency"); + base.Exit(nextState); + } + protected override Projectile SpawnProjectile( Vector2 position, Vector2 direction) @@ -19,6 +33,8 @@ public partial class DocUnwantedFrequencyState : DocShungiteSpikeState protected override void Attack() { + Doc.TelegraphAnimation.Play("unwanted_frequencies"); + GD.Print("unwanted frequency"); var player = _world.CurrentPlayer; var playerPos = player.GlobalPosition; var docPos = NPC.GlobalPosition; diff --git a/State/StateMachine.cs b/State/StateMachine.cs index e204cc9..9b16242 100644 --- a/State/StateMachine.cs +++ b/State/StateMachine.cs @@ -1,8 +1,9 @@ using Godot; +using SupaLidlGame.Extensions; namespace SupaLidlGame.State; -public abstract partial class StateMachine : Node where T : IState +public abstract partial class StateMachine : Node where T : Node, IState { public T CurrentState { get; protected set; } @@ -20,16 +21,19 @@ public abstract partial class StateMachine : Node where T : IState return false; } + // NOTE: proxied states can call Exit() more than once if (CurrentState is not null) { CurrentState.Exit(nextState); } + var previousState = CurrentState; CurrentState = nextState; // if the next state decides it should enter a different state, // then we enter that different state instead - var nextNextState = nextState.Enter(CurrentState); + var nextNextState = nextState.Enter(previousState); + if (nextNextState is T t) { return ChangeState(t, true); @@ -37,4 +41,13 @@ public abstract partial class StateMachine : Node where T : IState return true; } + + /// + /// Changes the current state to a state of type U which must inherit from T. + /// + public bool ChangeState(out U state) where U : T + { + state = this.FindChildOfType(); + return ChangeState(state); + } } diff --git a/State/Weapon/SwordAnticipateState.cs b/State/Weapon/SwordAnticipateState.cs index f393a65..789487f 100644 --- a/State/Weapon/SwordAnticipateState.cs +++ b/State/Weapon/SwordAnticipateState.cs @@ -10,18 +10,20 @@ public partial class SwordAnticipateState : WeaponState [Export] public SwordAttackState AttackState { get; set; } + [Export] + public bool HasAlternateAninmation { get; set; } = false; + private double _anticipateTime; public override WeaponState Enter(IState prevState) { - Sword.EnableParry(); - if (Sword.Character is SupaLidlGame.Characters.Player) { return AttackState; } - if (Sword.Anchor.Rotation > Mathf.DegToRad(50)) + float rotThreshold = Mathf.DegToRad(50); + if (HasAlternateAninmation && Sword.Anchor.Rotation > rotThreshold) { Sword.AnimationPlayer.Play("anticipate_alternate"); } diff --git a/State/Weapon/SwordAttackState.cs b/State/Weapon/SwordAttackState.cs index 11014c7..3b921bd 100644 --- a/State/Weapon/SwordAttackState.cs +++ b/State/Weapon/SwordAttackState.cs @@ -8,10 +8,10 @@ public partial class SwordAttackState : WeaponState public SupaLidlGame.Items.Weapons.Sword Sword { get; set; } [Export] - public SwordAnticipateState AnticipateState { get; set; } + public SwordIdleState IdleState { get; set; } [Export] - public SwordIdleState IdleState { get; set; } + public bool HasAlternateAnimation { get; set; } = false; private double _attackDuration = 0; @@ -23,10 +23,10 @@ public partial class SwordAttackState : WeaponState public override WeaponState Enter(IState prevState) { - //Sword.AnimationPlayer.Stop(); + Sword.EnableParry(); Sword.Attack(); - if (_isAlternate) + if (HasAlternateAnimation && _isAlternate) { Sword.AnimationPlayer.Play("attack_alternate"); } diff --git a/State/Weapon/SwordHoldAttackState.cs b/State/Weapon/SwordHoldAttackState.cs new file mode 100644 index 0000000..2edd697 --- /dev/null +++ b/State/Weapon/SwordHoldAttackState.cs @@ -0,0 +1,72 @@ +using Godot; + +namespace SupaLidlGame.State.Weapon; + +/// +/// This is a special state only meant to be used with certain bosses. +/// +public partial class SwordHoldAttackState : SwordAttackState +{ + private bool _isAlternate = false; + + public override WeaponState Enter(IState prevState) + { + Sword.EnableParry(); + Sword.Attack(); + + if (HasAlternateAnimation && _isAlternate) + { + Sword.AnimationPlayer.Play("attack_alternate"); + } + else + { + Sword.AnimationPlayer.Play("attack"); + } + + Sword.Visible = true; + Sword.UseDirection = Sword.Character.Target; + Sword.Hitbox.Hit += OnHitboxHit; + return null; + } + + private void OnHitboxHit(BoundingBoxes.BoundingBox box) + { + if (box is BoundingBoxes.Hurtbox hurtbox) + { + hurtbox.InflictDamage(Sword.Damage, + Sword.Character, + Sword.Knockback); + } + // damage player if not parried + //Sword.OnHitboxHit(box); + } + + public override void Exit(IState nextState) + { + // reset hit & ignore list first because players are not immediately + // removed from the list after being hit + Sword.Hitbox.Hit -= OnHitboxHit; + Sword.Hitbox.Hits.Clear(); + GD.Print("Cleared now with " + Sword.Hitbox.Hits.Count); + Sword.Deattack(); + } + + public override WeaponState Use() + { + if (!Sword.IsAttacking) + { + GD.Print("Used (hold)"); + Sword.Attack(); + } + + return null; + } + + public override WeaponState Deuse() + { + GD.Print("Deused"); + return IdleState; + } + + public override WeaponState Process(double delta) => null; +} diff --git a/UI/BossBar.cs b/UI/BossBar.cs new file mode 100644 index 0000000..cc09fd6 --- /dev/null +++ b/UI/BossBar.cs @@ -0,0 +1,63 @@ +using Godot; +using SupaLidlGame.Characters; + +namespace SupaLidlGame.UI; + +public partial class BossBar : VBoxContainer +{ + public TextureProgressBar ProgressBar { get; set; } + public Label BossNameLabel { get; set; } + + private Boss _boss; + + public Boss Boss + { + get => _boss; + set + { + SetupBoss(value); + _boss = value; + } + } + + public override void _Ready() + { + ProgressBar = GetNode("BarMargin/BossBar"); + BossNameLabel = GetNode