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/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/Sprites/Characters/doc.ase b/Assets/Sprites/Characters/doc.ase index 98350fc..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 3c5fb02..2141d27 100644 Binary files a/Assets/Sprites/Characters/doc.png and b/Assets/Sprites/Characters/doc.png differ 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/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/Characters/Boss.cs b/Characters/Boss.cs index a4786dc..a04cdef 100644 --- a/Characters/Boss.cs +++ b/Characters/Boss.cs @@ -11,6 +11,9 @@ public abstract partial class Boss : Enemy [Export] public string BossName { get; set; } + [Export] + public AudioStream Music { get; set; } + public abstract int Intensity { get; } private bool _isActive; diff --git a/Characters/Character.cs b/Characters/Character.cs index f53cdf7..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 @@ -87,11 +87,14 @@ public partial class Character : CharacterBody2D, IFaction 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; } @@ -103,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(); } @@ -124,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() @@ -142,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() @@ -167,7 +191,6 @@ public partial class Character : CharacterBody2D, IFaction { if (StunTime > 0) { - GD.Print("tried to use weapon but stunned"); return; } @@ -181,6 +204,15 @@ public partial class Character : CharacterBody2D, IFaction } } + public void DeuseCurrentItem() + { + if (Inventory.SelectedItem is Weapon weapon) + { + weapon.Deuse(); + // TODO: DeusedItem signal, implement when needed + } + } + public void LookTowardsDirection() { if (!Direction.IsZeroApprox()) diff --git a/Characters/Doc.cs b/Characters/Doc.cs index 0e90ed2..b54c7a5 100644 --- a/Characters/Doc.cs +++ b/Characters/Doc.cs @@ -1,5 +1,6 @@ using Godot; using GodotUtilities; +using SupaLidlGame.State.Character; namespace SupaLidlGame.Characters; @@ -7,6 +8,11 @@ public partial class Doc : Boss { public AnimationPlayer TelegraphAnimation { get; set; } + [Export] + public Items.Weapons.Sword Lance { get; set; } + + protected bool _dashedAway = false; + public override float Health { get => base.Health; @@ -31,9 +37,9 @@ public partial class Doc : Boss { switch (Health) { - case < 250: + case < 200: return 3; - case < 500: + case < 400: return 2; default: return 1; @@ -57,7 +63,7 @@ public partial class Doc : Boss if (!IsActive) { IsActive = true; - Inventory.SelectedItem = Inventory.Items[0]; + Inventory.SelectedItem = Lance; } }; } @@ -97,4 +103,59 @@ public partial class Doc : Boss 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 d64ab16..7b71310 100644 --- a/Characters/Doc.tscn +++ b/Characters/Doc.tscn @@ -1,12 +1,15 @@ -[gd_scene load_steps=52 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"] @@ -19,18 +22,22 @@ [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="PackedScene" uid="uid://dvqap2uhcah63" path="res://Items/Weapons/Sword.tscn" id="24_y1go8"] +[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 @@ -81,9 +88,14 @@ tracks/0/keys = { "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") } @@ -129,14 +141,14 @@ tracks/2/keys = { tracks/3/type = "value" tracks/3/imported = false tracks/3/enabled = true -tracks/3/path = NodePath("../Sprite:modulate") +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": [Color(1, 1, 1, 1)] +"values": [1.0] } [sub_resource type="Animation" id="Animation_7oukw"] @@ -157,38 +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, 0.5), -"transitions": PackedFloat32Array(2, 1), -"update": 0, -"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0.5)] +"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:frame") +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": [0] +"values": [false] } tracks/3/type = "value" tracks/3/imported = false tracks/3/enabled = true -tracks/3/path = NodePath("../Effects/UnwantedFrequenciesParticles:emitting") +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": 1, -"values": [false] +"times": PackedFloat32Array(0, 0.5), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 1.0] } [sub_resource type="Animation" id="Animation_j3s0y"] @@ -209,38 +221,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, 0.5), -"transitions": PackedFloat32Array(1, 2), -"update": 0, -"values": [Color(1, 1, 1, 0.5), Color(1, 1, 1, 0)] +"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:frame") +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": [0] +"values": [false] } tracks/3/type = "value" tracks/3/imported = false tracks/3/enabled = true -tracks/3/path = NodePath("../Effects/UnwantedFrequenciesParticles:emitting") +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": 1, -"values": [false] +"times": PackedFloat32Array(0, 0.5), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [1.0, 0.0] } [sub_resource type="Animation" id="Animation_8dhub"] @@ -379,6 +391,11 @@ _data = { "hurt": SubResource("Animation_dxevc") } +[sub_resource type="AnimationLibrary" id="AnimationLibrary_kks2p"] +_data = { +"stun": ExtResource("21_ixn4k") +} + [sub_resource type="Animation" id="Animation_uemm6"] resource_name = "intro" @@ -426,22 +443,31 @@ 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("BossStateMachine", "Sprite", "Inventory", "StateMachine", "Hurtbox")] +[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") BossName = "Doc, The Two-Time" -Health = 1000.0 +Music = ExtResource("3_eo4lg") +HandTexture = ExtResource("4_8lqj6") +Health = 800.0 Sprite = NodePath("Sprite") Inventory = NodePath("Inventory") StateMachine = NodePath("StateMachine") @@ -462,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") @@ -499,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("../..") @@ -532,6 +571,11 @@ 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") @@ -563,9 +607,17 @@ 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.5, 0) texture = ExtResource("3_rs44f") offset = Vector2(0, -8) hframes = 16 @@ -587,7 +639,9 @@ y_sort_enabled = true script = ExtResource("8_r8ejq") Items = Array[Node2D]([]) -[node name="Sword" parent="Inventory" instance=ExtResource("24_y1go8")] +[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/Player.cs b/Characters/Player.cs index d920be6..0bbdb59 100644 --- a/Characters/Player.cs +++ b/Characters/Player.cs @@ -60,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(); } diff --git a/Characters/Player.tscn b/Characters/Player.tscn index 1012180..e06ff3a 100644 --- a/Characters/Player.tscn +++ b/Characters/Player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=52 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"] @@ -11,11 +11,13 @@ [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="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"] @@ -23,6 +25,7 @@ shader = ExtResource("2_ngsgt") shader_parameter/color = Vector4(1, 1, 1, 1) shader_parameter/intensity = 0.0 +shader_parameter/alpha_modulate = 1.0 [sub_resource type="Animation" id="Animation_imqdv"] length = 0.001 @@ -282,6 +285,11 @@ _data = { "hurt_flash": SubResource("Animation_pjey7") } +[sub_resource type="AnimationLibrary" id="AnimationLibrary_kks2p"] +_data = { +"stun": ExtResource("8_m08fh") +} + [sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_kwett"] animation = &"idle" @@ -418,6 +426,11 @@ 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") @@ -470,7 +483,7 @@ rotation = 6.28319 [node name="Character" type="Sprite2D" parent="Sprites/Node2D"] use_parent_material = true -position = Vector2(0, -8) +position = Vector2(-1, -8) texture = ExtResource("4_5vird") offset = Vector2(0, -4) hframes = 24 @@ -505,6 +518,8 @@ InventoryMap = { [node name="Node2D" parent="Inventory" instance=ExtResource("7_4rxuv")] visible = false +[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") 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/UnwantedFrequency.tscn b/Entities/UnwantedFrequency.tscn index 0fa78c1..0a21254 100644 --- a/Entities/UnwantedFrequency.tscn +++ b/Entities/UnwantedFrequency.tscn @@ -103,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 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/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 16545b1..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(); } @@ -122,7 +85,8 @@ public partial class Sword : Weapon, IParryable public override void Deuse() { //AnimationPlayer.Stop(); - Deattack(); + //Deattack(); + StateMachine.Deuse(); base.Deuse(); } @@ -147,8 +111,6 @@ public partial class Sword : Weapon, IParryable { Hitbox.Damage = Damage; Hitbox.Hit += OnHitboxHit; - _playback = (AnimationNodeStateMachinePlayback)AnimationTree - .Get("parameters/playback"); } public override void _Process(double delta) @@ -168,6 +130,7 @@ public partial class Sword : Weapon, IParryable { if (box is Hurtbox hurtbox) { + GD.Print("LUL"); hurtbox.InflictDamage(Damage, Character, Knockback); } } @@ -175,29 +138,30 @@ 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 OnHitboxHit(BoundingBox box) @@ -231,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 5f39e29..c9d0d02 100644 --- a/Items/Weapons/Sword.tscn +++ b/Items/Weapons/Sword.tscn @@ -9,6 +9,7 @@ [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="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"] @@ -26,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" @@ -417,23 +414,19 @@ 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) diff --git a/Scenes/Level.tscn b/Scenes/Level.tscn index 3ac7368..4493032 100644 --- a/Scenes/Level.tscn +++ b/Scenes/Level.tscn @@ -6,14 +6,13 @@ [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" node_paths=PackedStringArray("UIController")] +[node name="World" type="Node2D"] script = ExtResource("1_1k6ew") StartingArea = ExtResource("2_avsrq") -UIController = NodePath("CanvasLayer/UI") [node name="CanvasLayer" type="CanvasLayer" parent="."] -[node name="UI" type="Control" parent="CanvasLayer" node_paths=PackedStringArray("BossBar")] +[node name="UI" type="Control" parent="CanvasLayer"] z_index = 128 layout_mode = 3 anchors_preset = 15 @@ -24,7 +23,6 @@ grow_vertical = 2 size_flags_horizontal = 3 size_flags_vertical = 3 script = ExtResource("3_fe62s") -BossBar = NodePath("Bottom/BossBar") [node name="Top" type="HBoxContainer" parent="CanvasLayer/UI"] layout_mode = 1 @@ -43,6 +41,7 @@ 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 diff --git a/Scenes/Maps/Arena.tscn b/Scenes/Maps/Arena.tscn index 7bf91d5..edd55cc 100644 --- a/Scenes/Maps/Arena.tscn +++ b/Scenes/Maps/Arena.tscn @@ -251,11 +251,12 @@ physics_layer_0/collision_layer = 1 sources/2 = SubResource("TileSetAtlasSource_5yxvt") sources/0 = SubResource("TileSetAtlasSource_fcd6d") -[sub_resource type="ShaderMaterial" id="ShaderMaterial_spvk4"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_q3ile"] resource_local_to_scene = true 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) @@ -342,7 +343,7 @@ visible = false position = Vector2(120, -112) [node name="Doc" parent="Entities" index="18" instance=ExtResource("4_ej0f3")] -material = SubResource("ShaderMaterial_spvk4") +material = SubResource("ShaderMaterial_q3ile") [node name="PointLight2D" type="PointLight2D" parent="Entities" index="19"] position = Vector2(168, -42) 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/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 39cadee..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,6 +42,11 @@ public partial class DocChooseAttackState : NPCState public override NPCState Enter(IState previous) { + if (Doc.Intensity == 3) + { + return LanceState; + } + if (previous is not DocTelegraphState) { _consecutiveAttacks++; 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 a92973d..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,15 +21,6 @@ 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) { } @@ -70,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 af34fa6..c28f4ea 100644 --- a/State/NPC/Doc/DocShungiteSpikeState.cs +++ b/State/NPC/Doc/DocShungiteSpikeState.cs @@ -9,13 +9,15 @@ 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; - NPC.ShouldMove = false; + Doc.ShouldMove = true; + Doc.CanAttack = true; return base.Enter(previous); } @@ -23,7 +25,6 @@ public partial class DocShungiteSpikeState : DocShungiteDartState { //Doc.TelegraphAnimation.Stop(); //Doc.TelegraphAnimation.Stop(); - NPC.ShouldMove = true; } protected override Projectile SpawnProjectile( @@ -45,7 +46,6 @@ public partial class DocShungiteSpikeState : DocShungiteDartState protected override void Attack() { - GD.Print("shungite spike"); var player = _world.CurrentPlayer; var playerPos = player.GlobalPosition; var docPos = NPC.GlobalPosition; @@ -61,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++; @@ -69,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 37d157c..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(-112, 112); - float randY = GD.RandRange(-112, 112); - 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/StateMachine.cs b/State/StateMachine.cs index 04039cf..9b16242 100644 --- a/State/StateMachine.cs +++ b/State/StateMachine.cs @@ -1,4 +1,5 @@ using Godot; +using SupaLidlGame.Extensions; namespace SupaLidlGame.State; @@ -40,4 +41,13 @@ public abstract partial class StateMachine : Node where T : Node, 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 25c89cf..789487f 100644 --- a/State/Weapon/SwordAnticipateState.cs +++ b/State/Weapon/SwordAnticipateState.cs @@ -10,6 +10,9 @@ 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) @@ -19,7 +22,8 @@ public partial class SwordAnticipateState : WeaponState 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"); } @@ -27,7 +31,6 @@ public partial class SwordAnticipateState : WeaponState { Sword.AnimationPlayer.Play("anticipate"); } - GD.Print("Anticipating time"); _anticipateTime = Sword.NPCAnticipateTime; return null; } diff --git a/State/Weapon/SwordAttackState.cs b/State/Weapon/SwordAttackState.cs index 86b8f93..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; @@ -26,7 +26,7 @@ public partial class SwordAttackState : WeaponState 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/HealthBar.tscn b/UI/HealthBar.tscn index 960162e..74f27d1 100644 --- a/UI/HealthBar.tscn +++ b/UI/HealthBar.tscn @@ -16,7 +16,7 @@ texture_filter = 1 layout_mode = 0 offset_right = 128.0 offset_bottom = 8.0 -value = 50.0 +value = 100.0 nine_patch_stretch = true stretch_margin_left = 3 stretch_margin_top = 3 diff --git a/project.godot b/project.godot index 7f6eba5..62ac2ac 100644 --- a/project.godot +++ b/project.godot @@ -18,7 +18,7 @@ config/icon="res://icon.svg" [display] window/size/viewport_width=640 -window/size/viewport_height=480 +window/size/viewport_height=360 window/stretch/mode="viewport" window/stretch/aspect="expand"