wip: doc lance
							parent
							
								
									82c8e85c63
								
							
						
					
					
						commit
						0d403044e1
					
				
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								|  | @ -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 | ||||
											
												Binary file not shown.
											
										
									
								|  | @ -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 | ||||
											
												Binary file not shown.
											
										
									
								|  | @ -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 | ||||
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								| Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB | 
|  | @ -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") | ||||
											
												Binary file not shown.
											
										
									
								
											
												Binary file not shown.
											
										
									
								| After Width: | Height: | Size: 342 B | 
|  | @ -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 | ||||
											
												Binary file not shown.
											
										
									
								|  | @ -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; | ||||
|  |  | |||
|  | @ -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<AnimationPlayer>("Animations/Movement"); | ||||
|         HurtAnimation = GetNode<AnimationPlayer>("Animations/Hurt"); | ||||
|         StunAnimation = GetNode<AnimationPlayer>("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()) | ||||
|  |  | |||
|  | @ -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<CharacterDashState>(out var state); | ||||
|         state.DashDirection = direction; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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") | ||||
|  |  | |||
|  | @ -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(); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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") | ||||
|  |  | |||
|  | @ -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 = { | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -38,4 +38,17 @@ public static class NodeExtensions | |||
|     { | ||||
|         return node.GetNode(name) as T; | ||||
|     } | ||||
| 
 | ||||
|     public static T FindChildOfType<T>(this Node node) where T : Node | ||||
|     { | ||||
|         foreach (Node child in node.GetChildren()) | ||||
|         { | ||||
|             if (child is T t) | ||||
|             { | ||||
|                 return t; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,5 +10,6 @@ public static class Particles2D | |||
|         { | ||||
|             particles.QueueFree(); | ||||
|         }; | ||||
|         particles.Emitting = true; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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"] | ||||
|  | @ -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"] | ||||
|  | @ -0,0 +1,13 @@ | |||
| /* | ||||
| using Godot; | ||||
| 
 | ||||
| namespace SupaLidlGame.Items.Weapons; | ||||
| 
 | ||||
| public partial class Lance : Sword | ||||
| { | ||||
|     public override void _Ready() | ||||
|     { | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| */ | ||||
|  | @ -20,9 +20,6 @@ public partial class Sword : Weapon, IParryable | |||
|     [Export] | ||||
|     public AnimationPlayer AnimationPlayer { get; set; } | ||||
| 
 | ||||
|     [Export] | ||||
|     public AnimationTree AnimationTree { get; set; } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// The time frame in seconds for which the weapon will deal damage. | ||||
|     /// </summary> | ||||
|  | @ -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<Node2D>("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<GpuParticles2D>().EmitOneShot(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 otherParryable.Stun(); | ||||
|             } | ||||
|         } | ||||
|         //this.GetAncestor<TileMap>().AddChild(instance); | ||||
|     } | ||||
| 
 | ||||
|     public void Stun() | ||||
|     { | ||||
|         IsParried = true; | ||||
|         AnimationPlayer.SpeedScale = 0.25f; | ||||
|         Character.Stun(1.5f); | ||||
|         GetNode<AudioStreamPlayer2D>("ParrySound").OnWorld().PlayOneShot(); | ||||
|         Character.Stun(1); | ||||
|         GetNode<AudioStreamPlayer2D>("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); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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; | ||||
| } | ||||
|  | @ -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<CharacterState> Enter(IState<CharacterState> 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<Sprite2D>(); | ||||
|         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<CharacterState> 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; | ||||
|     } | ||||
| } | ||||
|  | @ -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; | ||||
|         } | ||||
|  |  | |||
|  | @ -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<NPCState> previousState) | ||||
|     { | ||||
|         _map = this.GetAncestor<Scenes.Map>(); | ||||
|         _world = this.GetAncestor<Utils.World>(); | ||||
|         _currentDuration = Duration; | ||||
|         _currentAttackDuration = AttackDuration; | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     protected abstract void Attack(); | ||||
| } | ||||
|  |  | |||
|  | @ -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<NPCState> previous) | ||||
|     { | ||||
|         if (Doc.Intensity == 3) | ||||
|         { | ||||
|             return LanceState; | ||||
|         } | ||||
| 
 | ||||
|         if (previous is not DocTelegraphState) | ||||
|         { | ||||
|             _consecutiveAttacks++; | ||||
|  |  | |||
|  | @ -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<NPCState> 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<NPCState> 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; | ||||
|     } | ||||
| } | ||||
|  | @ -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<NPCState> previousState) | ||||
|     { | ||||
|         _map = this.GetAncestor<Scenes.Map>(); | ||||
|         _world = this.GetAncestor<Utils.World>(); | ||||
|         _currentDuration = Duration; | ||||
|         _currentAttackDuration = AttackDuration; | ||||
|         return null; | ||||
|     } | ||||
| 
 | ||||
|     public override void Exit(IState<NPCState> 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; | ||||
|  |  | |||
|  | @ -9,13 +9,15 @@ public partial class DocShungiteSpikeState : DocShungiteDartState | |||
| 
 | ||||
|     public override NPCState Enter(IState<NPCState> 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(); | ||||
|  |  | |||
|  | @ -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<NPCState> 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<Utils.World>().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; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| using Godot; | ||||
| using SupaLidlGame.Extensions; | ||||
| 
 | ||||
| namespace SupaLidlGame.State; | ||||
| 
 | ||||
|  | @ -40,4 +41,13 @@ public abstract partial class StateMachine<T> : Node where T : Node, IState<T> | |||
| 
 | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     /// Changes the current state to a state of type U which must inherit from T. | ||||
|     /// </summary> | ||||
|     public bool ChangeState<U>(out U state) where U : T | ||||
|     { | ||||
|         state = this.FindChildOfType<U>(); | ||||
|         return ChangeState(state); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -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<WeaponState> 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; | ||||
|     } | ||||
|  |  | |||
|  | @ -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"); | ||||
|         } | ||||
|  |  | |||
|  | @ -0,0 +1,72 @@ | |||
| using Godot; | ||||
| 
 | ||||
| namespace SupaLidlGame.State.Weapon; | ||||
| 
 | ||||
| /// <summary> | ||||
| /// This is a special state only meant to be used with certain bosses. | ||||
| /// </summary> | ||||
| public partial class SwordHoldAttackState : SwordAttackState | ||||
| { | ||||
|     private bool _isAlternate = false; | ||||
| 
 | ||||
|     public override WeaponState Enter(IState<WeaponState> 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<WeaponState> 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; | ||||
| } | ||||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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" | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue