combat system
|  | @ -0,0 +1,32 @@ | |||
| [remap] | ||||
| 
 | ||||
| importer="font_data_dynamic" | ||||
| type="FontFile" | ||||
| uid="uid://cgwa8bjiyv534" | ||||
| path="res://.godot/imported/alagard.ttf-ed7015ed0e84e70ec06fd3d65515ce04.fontdata" | ||||
| 
 | ||||
| [deps] | ||||
| 
 | ||||
| source_file="res://Assets/Fonts/alagard.ttf" | ||||
| dest_files=["res://.godot/imported/alagard.ttf-ed7015ed0e84e70ec06fd3d65515ce04.fontdata"] | ||||
| 
 | ||||
| [params] | ||||
| 
 | ||||
| Rendering=null | ||||
| antialiasing=0 | ||||
| generate_mipmaps=false | ||||
| multichannel_signed_distance_field=false | ||||
| msdf_pixel_range=8 | ||||
| msdf_size=48 | ||||
| force_autohinter=false | ||||
| hinting=1 | ||||
| subpixel_positioning=1 | ||||
| oversampling=0.0 | ||||
| Fallbacks=null | ||||
| fallbacks=[] | ||||
| Compress=null | ||||
| compress=true | ||||
| preload=[] | ||||
| language_support={} | ||||
| script_support={} | ||||
| opentype_features={} | ||||
| Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB | 
|  | @ -3,15 +3,15 @@ | |||
| importer="texture" | ||||
| type="CompressedTexture2D" | ||||
| uid="uid://dxymfduyrbuvx" | ||||
| path="res://.godot/imported/forsen.png-fce73bdb02d4ae9ad3a1c7a29f120a10.ctex" | ||||
| path="res://.godot/imported/forsen.png-c75844516d35dfe104cf50cd521a7820.ctex" | ||||
| metadata={ | ||||
| "vram_texture": false | ||||
| } | ||||
| 
 | ||||
| [deps] | ||||
| 
 | ||||
| source_file="res://Sprites/Characters/forsen.png" | ||||
| dest_files=["res://.godot/imported/forsen.png-fce73bdb02d4ae9ad3a1c7a29f120a10.ctex"] | ||||
| source_file="res://Assets/Sprites/Characters/forsen.png" | ||||
| dest_files=["res://.godot/imported/forsen.png-c75844516d35dfe104cf50cd521a7820.ctex"] | ||||
| 
 | ||||
| [params] | ||||
| 
 | ||||
| Before Width: | Height: | Size: 310 B After Width: | Height: | Size: 310 B | 
|  | @ -3,15 +3,15 @@ | |||
| importer="texture" | ||||
| type="CompressedTexture2D" | ||||
| uid="uid://dt6u8p4h6g7le" | ||||
| path="res://.godot/imported/knife.png-95e39b161a14477923b7daae97a5ccae.ctex" | ||||
| path="res://.godot/imported/knife.png-29bc4ddc148b964cb9b086eec2187a96.ctex" | ||||
| metadata={ | ||||
| "vram_texture": false | ||||
| } | ||||
| 
 | ||||
| [deps] | ||||
| 
 | ||||
| source_file="res://Sprites/knife.png" | ||||
| dest_files=["res://.godot/imported/knife.png-95e39b161a14477923b7daae97a5ccae.ctex"] | ||||
| source_file="res://Assets/Sprites/knife.png" | ||||
| dest_files=["res://.godot/imported/knife.png-29bc4ddc148b964cb9b086eec2187a96.ctex"] | ||||
| 
 | ||||
| [params] | ||||
| 
 | ||||
| After Width: | Height: | Size: 395 B | 
|  | @ -0,0 +1,34 @@ | |||
| [remap] | ||||
| 
 | ||||
| importer="texture" | ||||
| type="CompressedTexture2D" | ||||
| uid="uid://do1bui3bblkk7" | ||||
| path="res://.godot/imported/sword-swing.png-b3fe38b6ad54820f8f9984baa9ea79b7.ctex" | ||||
| metadata={ | ||||
| "vram_texture": false | ||||
| } | ||||
| 
 | ||||
| [deps] | ||||
| 
 | ||||
| source_file="res://Assets/Sprites/sword-swing.png" | ||||
| dest_files=["res://.godot/imported/sword-swing.png-b3fe38b6ad54820f8f9984baa9ea79b7.ctex"] | ||||
| 
 | ||||
| [params] | ||||
| 
 | ||||
| compress/mode=0 | ||||
| compress/lossy_quality=0.7 | ||||
| compress/hdr_compression=1 | ||||
| compress/bptc_ldr=0 | ||||
| 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 | ||||
| Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB | 
|  | @ -3,15 +3,15 @@ | |||
| importer="texture" | ||||
| type="CompressedTexture2D" | ||||
| uid="uid://gm2pcnfg7h8j" | ||||
| path="res://.godot/imported/tileset.png-c259079e18121438fd392d302e3ca0d5.ctex" | ||||
| path="res://.godot/imported/tileset.png-f52e8e44f74a535dd898a49592afe6d9.ctex" | ||||
| metadata={ | ||||
| "vram_texture": false | ||||
| } | ||||
| 
 | ||||
| [deps] | ||||
| 
 | ||||
| source_file="res://Sprites/tileset.png" | ||||
| dest_files=["res://.godot/imported/tileset.png-c259079e18121438fd392d302e3ca0d5.ctex"] | ||||
| source_file="res://Assets/Sprites/tileset.png" | ||||
| dest_files=["res://.godot/imported/tileset.png-f52e8e44f74a535dd898a49592afe6d9.ctex"] | ||||
| 
 | ||||
| [params] | ||||
| 
 | ||||
|  | @ -0,0 +1,11 @@ | |||
| using Godot; | ||||
| using SupaLidlGame.Utils; | ||||
| 
 | ||||
| namespace SupaLidlGame.BoundingBoxes | ||||
| { | ||||
|     public abstract partial class BoundingBox : Area2D, IFaction | ||||
|     { | ||||
|         [Export] | ||||
|         public ushort Faction { get; set; } | ||||
|     } | ||||
| } | ||||
|  | @ -1,13 +1,17 @@ | |||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using Godot; | ||||
| using SupaLidlGame.Characters; | ||||
| using SupaLidlGame.Utils; | ||||
| using SupaLidlGame.Items; | ||||
| 
 | ||||
| namespace SupaLidlGame.BoundingBoxes | ||||
| { | ||||
|     public partial class Hitbox : Area2D, IFaction | ||||
|     public partial class Hitbox : BoundingBox | ||||
|     { | ||||
|         private HashSet<Hurtbox> _ignoreList = new HashSet<Hurtbox>(); | ||||
|         private HashSet<BoundingBox> _ignoreList = new HashSet<BoundingBox>(); | ||||
| 
 | ||||
|         [Signal] | ||||
|         public delegate void HitEventHandler(BoundingBox box); | ||||
| 
 | ||||
|         [Export] | ||||
|         public float Damage { get; set; } | ||||
|  | @ -19,40 +23,76 @@ namespace SupaLidlGame.BoundingBoxes | |||
|         public bool IsDisabled | ||||
|         { | ||||
|             get => _collisionShape.Disabled; | ||||
|             set => _collisionShape.Disabled = value; | ||||
|             set | ||||
|             { | ||||
|                 _collisionShape.Disabled = value; | ||||
|                 if (value) | ||||
|                 { | ||||
|                     DamageStartTime = Time.GetTicksMsec(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         [Export] | ||||
|         public float Knockback { get; set; } | ||||
| 
 | ||||
|         [Export] | ||||
|         public ushort Faction { get; set; } | ||||
| 
 | ||||
|         public Character Inflictor { get; set; } | ||||
| 
 | ||||
|         public ulong DamageStartTime { get; set; } | ||||
| 
 | ||||
|         private CollisionShape2D _collisionShape; | ||||
| 
 | ||||
|         private bool _isParrying = false; | ||||
| 
 | ||||
|         public override void _Ready() | ||||
|         { | ||||
|             _collisionShape = GetNode<CollisionShape2D>("CollisionShape2D"); | ||||
|         } | ||||
| 
 | ||||
|         private bool ShouldParry(Hitbox box) | ||||
|         { | ||||
|             Node parent = GetParent<Node>(); | ||||
| 
 | ||||
|             // if this hitbox does not even belong to a weapon, skip | ||||
|             if (parent is not Weapon) | ||||
|             { | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             var weapon = parent as Weapon; | ||||
| 
 | ||||
|             // if we hit a hitbox, we can parry if it can be parried | ||||
|             if (box.GetParent<Node>() is Weapon other) | ||||
|             { | ||||
|                 return weapon.IsParryable && other.IsParryable; | ||||
|             } | ||||
| 
 | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         public void _on_area_entered(Area2D area) | ||||
|         { | ||||
|             if (area is Hurtbox hurtbox) | ||||
|             if (area is BoundingBox box) | ||||
|             { | ||||
|                 // we don't want to hurt teammates | ||||
|                 if (Faction != hurtbox.Faction) | ||||
|                 if (Faction != box.Faction) | ||||
|                 { | ||||
|                     if (!_ignoreList.Contains(hurtbox)) | ||||
|                     if (!_ignoreList.Contains(box)) | ||||
|                     { | ||||
|                         _ignoreList.Add(hurtbox); | ||||
|                         hurtbox.InflictDamage(Damage, Inflictor, Knockback); | ||||
|                         _ignoreList.Add(box); | ||||
|                         EmitSignal(SignalName.Hit, box); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void ResetIgnoreList() => _ignoreList.Clear(); | ||||
| 
 | ||||
|         public bool HasHit(BoundingBox box) => _ignoreList.Contains(box); | ||||
| 
 | ||||
|         public HashSet<BoundingBox> Hits | ||||
|         { | ||||
|             get => _ignoreList; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| [sub_resource type="RectangleShape2D" id="RectangleShape2D_3w20g"] | ||||
| 
 | ||||
| [node name="Hitbox" type="Area2D"] | ||||
| priority = 5.0 | ||||
| script = ExtResource("1_44i8j") | ||||
| 
 | ||||
| [node name="CollisionShape2D" type="CollisionShape2D" parent="."] | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ using SupaLidlGame.Utils; | |||
| 
 | ||||
| namespace SupaLidlGame.BoundingBoxes | ||||
| { | ||||
|     public partial class Hurtbox : Area2D, IFaction | ||||
|     public partial class Hurtbox : BoundingBox, IFaction | ||||
|     { | ||||
|         [Signal] | ||||
|         public delegate void ReceivedDamageEventHandler( | ||||
|  | @ -14,9 +14,6 @@ namespace SupaLidlGame.BoundingBoxes | |||
|             Vector2 knockbackOrigin = default, | ||||
|             Vector2 knockbackVector = default); | ||||
| 
 | ||||
|         [Export] | ||||
|         public ushort Faction { get; set; } | ||||
| 
 | ||||
|         public override void _Ready() | ||||
|         { | ||||
|             if (Faction == default && GetParent() is IFaction factionEntity) | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| using Godot; | ||||
| using SupaLidlGame.Extensions; | ||||
| using SupaLidlGame.Items; | ||||
| using SupaLidlGame.Utils; | ||||
| 
 | ||||
|  | @ -9,6 +10,9 @@ namespace SupaLidlGame.Characters | |||
|         [Export] | ||||
|         public float Speed { get; protected set; } = 32.0f; | ||||
| 
 | ||||
|         [Export] | ||||
|         public float Friction { get; protected set; } = 4.0f; | ||||
| 
 | ||||
|         [Export] | ||||
|         public float Mass | ||||
|         { | ||||
|  | @ -28,10 +32,13 @@ namespace SupaLidlGame.Characters | |||
| 
 | ||||
|         public Vector2 Acceleration => Direction * AccelerationMagnitude; | ||||
| 
 | ||||
|         public Vector2 NetImpulse { get; set; } = Vector2.Zero; | ||||
| 
 | ||||
|         public Vector2 Direction { get; set; } = Vector2.Zero; | ||||
| 
 | ||||
|         public Vector2 Target { get; set; } = Vector2.Zero; | ||||
| 
 | ||||
|         [Export] | ||||
|         public float Health | ||||
|         { | ||||
|             get => _health; | ||||
|  | @ -51,9 +58,11 @@ namespace SupaLidlGame.Characters | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public bool IsAlive => Health > 0; | ||||
| 
 | ||||
|         protected float _health = 100f; | ||||
| 
 | ||||
|         public bool IsAlive => Health > 0; | ||||
|         public double StunTime { get; set; } | ||||
| 
 | ||||
|         [Export] | ||||
|         public AnimatedSprite2D Sprite { get; set; } | ||||
|  | @ -99,7 +108,10 @@ namespace SupaLidlGame.Characters | |||
|         /// </summary> | ||||
|         public virtual void ModifyVelocity() | ||||
|         { | ||||
| 
 | ||||
|             if (StunTime > 0) | ||||
|             { | ||||
|                 Velocity *= 0.25f; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public virtual void Die() | ||||
|  | @ -113,7 +125,12 @@ namespace SupaLidlGame.Characters | |||
|             // delta p = F delta t | ||||
|             if (resetVelocity) | ||||
|                 Velocity = Vector2.Zero; | ||||
|             Velocity += impulse / Mass; | ||||
|             NetImpulse += impulse / Mass; | ||||
|         } | ||||
| 
 | ||||
|         public virtual void Stun(float time) | ||||
|         { | ||||
|             StunTime += time; | ||||
|         } | ||||
| 
 | ||||
|         protected void DrawTarget() | ||||
|  | @ -134,6 +151,20 @@ namespace SupaLidlGame.Characters | |||
|             Inventory.Rotation = angle; | ||||
|         } | ||||
| 
 | ||||
|         public void UseCurrentItem() | ||||
|         { | ||||
|             if (StunTime > 0) | ||||
|             { | ||||
|                 GD.Print("tried to use weapon but stunned"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if (Inventory.SelectedItem is Weapon weapon) | ||||
|             { | ||||
|                 weapon.Use(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void _on_hurtbox_received_damage(float damage, | ||||
|             Character inflictor, | ||||
|             float knockback, | ||||
|  | @ -141,7 +172,13 @@ namespace SupaLidlGame.Characters | |||
|             Vector2 knockbackVector = default) | ||||
|         { | ||||
|             Health -= damage; | ||||
|             /* | ||||
| 
 | ||||
|             var textScene = GD.Load<PackedScene>("res://UI/FloatingText.tscn"); | ||||
|             var instance = textScene.Instantiate<UI.FloatingText>(); | ||||
|             instance.Text = Mathf.Round(damage).ToString(); | ||||
|             instance.GlobalPosition = GlobalPosition; | ||||
|             this.GetAncestor<TileMap>().AddChild(instance); | ||||
| 
 | ||||
|             Vector2 knockbackDir = knockbackVector; | ||||
|             if (knockbackDir == default) | ||||
|             { | ||||
|  | @ -153,8 +190,14 @@ namespace SupaLidlGame.Characters | |||
|                 knockbackDir = knockbackOrigin.DirectionTo(GlobalPosition); | ||||
|             } | ||||
| 
 | ||||
|             ApplyImpulse(knockback.) | ||||
|             */ | ||||
|             var player = GetNode<AnimationPlayer>("FlashAnimation"); | ||||
|             if (player != null) | ||||
|             { | ||||
|                 player.Stop(); | ||||
|                 player.Play("Hurt"); | ||||
|             } | ||||
| 
 | ||||
|             ApplyImpulse(knockbackDir.Normalized() * knockback); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,40 +1,47 @@ | |||
| [gd_scene load_steps=19 format=3 uid="uid://dymwd5ihpwyqm"] | ||||
| [gd_scene load_steps=24 format=3 uid="uid://ddcf6bfv212wj"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://Characters/Enemy.cs" id="1_2yopk"] | ||||
| [ext_resource type="Texture2D" uid="uid://dxymfduyrbuvx" path="res://Sprites/Characters/forsen.png" id="2_jfku3"] | ||||
| [ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="1_fx1w5"] | ||||
| [ext_resource type="Script" path="res://Characters/States/Machine.cs" id="3_k4ypw"] | ||||
| [ext_resource type="Texture2D" uid="uid://dxymfduyrbuvx" path="res://Assets/Sprites/Characters/forsen.png" id="3_oxsgl"] | ||||
| [ext_resource type="Script" path="res://Characters/States/NPCIdleState.cs" id="4_8r2qn"] | ||||
| [ext_resource type="Script" path="res://Characters/States/NPCMoveState.cs" id="5_utogm"] | ||||
| [ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="6_jo0cg"] | ||||
| [ext_resource type="Script" path="res://Items/Inventory.cs" id="7_43gq8"] | ||||
| [ext_resource type="PackedScene" uid="uid://cajlwb67xenfy" path="res://Items/Weapons/Sword.tscn" id="8_s3c8r"] | ||||
| [ext_resource type="PackedScene" uid="uid://d72ehtv1ks0e" path="res://Items/Weapons/Sword.tscn" id="8_s3c8r"] | ||||
| 
 | ||||
| [sub_resource type="ShaderMaterial" id="ShaderMaterial_8jbxb"] | ||||
| resource_local_to_scene = true | ||||
| shader = ExtResource("1_fx1w5") | ||||
| shader_parameter/color = null | ||||
| shader_parameter/intensity = 0.0 | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_6d2tf"] | ||||
| atlas = ExtResource("2_jfku3") | ||||
| atlas = ExtResource("3_oxsgl") | ||||
| region = Rect2(0, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_bdyma"] | ||||
| atlas = ExtResource("2_jfku3") | ||||
| atlas = ExtResource("3_oxsgl") | ||||
| region = Rect2(24, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_0dwbr"] | ||||
| atlas = ExtResource("2_jfku3") | ||||
| atlas = ExtResource("3_oxsgl") | ||||
| region = Rect2(48, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_r7fn6"] | ||||
| atlas = ExtResource("2_jfku3") | ||||
| atlas = ExtResource("3_oxsgl") | ||||
| region = Rect2(72, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_py8k0"] | ||||
| atlas = ExtResource("2_jfku3") | ||||
| atlas = ExtResource("3_oxsgl") | ||||
| region = Rect2(96, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_g3nb2"] | ||||
| atlas = ExtResource("2_jfku3") | ||||
| atlas = ExtResource("3_oxsgl") | ||||
| region = Rect2(120, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_jauql"] | ||||
| atlas = ExtResource("2_jfku3") | ||||
| atlas = ExtResource("3_oxsgl") | ||||
| region = Rect2(144, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="SpriteFrames" id="SpriteFrames_4tm2b"] | ||||
|  | @ -56,16 +63,57 @@ size = Vector2(16, 8) | |||
| [sub_resource type="RectangleShape2D" id="RectangleShape2D_8lxmf"] | ||||
| size = Vector2(16, 24) | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_dxevc"] | ||||
| resource_name = "Hurt" | ||||
| length = 0.6 | ||||
| tracks/0/type = "value" | ||||
| tracks/0/imported = false | ||||
| tracks/0/enabled = true | ||||
| tracks/0/path = NodePath(".:material:shader_parameter/intensity") | ||||
| tracks/0/interp = 2 | ||||
| tracks/0/loop_wrap = true | ||||
| tracks/0/keys = { | ||||
| "times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6), | ||||
| "transitions": PackedFloat32Array(4, 4, 4, 4, 4, 4, 4), | ||||
| "update": 0, | ||||
| "values": [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0] | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_k6l16"] | ||||
| length = 0.001 | ||||
| tracks/0/type = "value" | ||||
| tracks/0/imported = false | ||||
| tracks/0/enabled = true | ||||
| tracks/0/path = NodePath(".:material:shader_parameter/intensity") | ||||
| tracks/0/interp = 1 | ||||
| tracks/0/loop_wrap = true | ||||
| tracks/0/keys = { | ||||
| "times": PackedFloat32Array(0), | ||||
| "transitions": PackedFloat32Array(1), | ||||
| "update": 0, | ||||
| "values": [0.0] | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="AnimationLibrary" id="AnimationLibrary_xe5eq"] | ||||
| _data = { | ||||
| "Hurt": SubResource("Animation_dxevc"), | ||||
| "RESET": SubResource("Animation_k6l16") | ||||
| } | ||||
| 
 | ||||
| [node name="ExampleEnemy" type="CharacterBody2D" node_paths=PackedStringArray("Sprite", "Inventory", "StateMachine")] | ||||
| texture_filter = 3 | ||||
| material = SubResource("ShaderMaterial_8jbxb") | ||||
| y_sort_enabled = true | ||||
| collision_layer = 2 | ||||
| script = ExtResource("1_2yopk") | ||||
| Health = 50.0 | ||||
| Sprite = NodePath("Sprite") | ||||
| Inventory = NodePath("Inventory") | ||||
| StateMachine = NodePath("StateMachine") | ||||
| Faction = 2 | ||||
| 
 | ||||
| [node name="Sprite" type="AnimatedSprite2D" parent="."] | ||||
| use_parent_material = true | ||||
| frames = SubResource("SpriteFrames_4tm2b") | ||||
| animation = &"move" | ||||
| playing = true | ||||
|  | @ -98,6 +146,12 @@ y_sort_enabled = true | |||
| script = ExtResource("7_43gq8") | ||||
| 
 | ||||
| [node name="Sword" parent="Inventory" instance=ExtResource("8_s3c8r")] | ||||
| Knockback = 40.0 | ||||
| 
 | ||||
| [node name="FlashAnimation" type="AnimationPlayer" parent="."] | ||||
| libraries = { | ||||
| "": SubResource("AnimationLibrary_xe5eq") | ||||
| } | ||||
| 
 | ||||
| [connection signal="ReceivedDamage" from="Hurtbox" to="." method="_on_hurtbox_received_damage"] | ||||
| 
 | ||||
|  |  | |||
|  | @ -47,6 +47,7 @@ namespace SupaLidlGame.Characters | |||
| 
 | ||||
|         public override void _Draw() | ||||
|         { | ||||
|             #if DEBUG | ||||
|             for (int i = 0; i < 16; i++) | ||||
|             { | ||||
|                 Vector2 vec = _weightDirs[i] * _weights[i] * 128; | ||||
|  | @ -62,6 +63,7 @@ namespace SupaLidlGame.Characters | |||
|                 } | ||||
|                 DrawLine(Vector2.Zero, vec, c); | ||||
|             } | ||||
|             #endif | ||||
| 
 | ||||
|             base._Draw(); | ||||
|         } | ||||
|  | @ -93,7 +95,8 @@ namespace SupaLidlGame.Characters | |||
|                 Think(); | ||||
|             } | ||||
| 
 | ||||
|             Direction = _weightDirs[_bestWeightIdx]; | ||||
|             Direction = Target; | ||||
|             //Direction = _weightDirs[_bestWeightIdx]; | ||||
|         } | ||||
| 
 | ||||
|         protected virtual void Think() | ||||
|  | @ -105,14 +108,13 @@ namespace SupaLidlGame.Characters | |||
| 
 | ||||
|             if (Target.LengthSquared() < 1024) | ||||
|             { | ||||
|                 GD.Print("lol"); | ||||
|                 if (Inventory.SelectedItem is Weapon weapon) | ||||
|                 { | ||||
|                     GD.Print("use"); | ||||
|                     weapon.Use(); | ||||
|                     UseCurrentItem(); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             #if DEBUGs | ||||
|             for (int i = 0; i < 16; i++) | ||||
|             { | ||||
|                 float directDot = _weightDirs[i].Dot(dir); | ||||
|  | @ -203,6 +205,7 @@ namespace SupaLidlGame.Characters | |||
|             } | ||||
| 
 | ||||
|             QueueRedraw(); | ||||
|             #endif | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| using Godot; | ||||
| using SupaLidlGame.Items; | ||||
| 
 | ||||
| namespace SupaLidlGame.Characters | ||||
| { | ||||
|  | @ -43,21 +42,18 @@ namespace SupaLidlGame.Characters | |||
|                 Velocity *= 2; | ||||
|             } | ||||
| 
 | ||||
|             if (Inventory.SelectedItem is Weapon weapon) | ||||
|             { | ||||
|                 /*if (weapon is Sword sword) | ||||
|                 { | ||||
|                     if (sword.IsAttacking) | ||||
|                     { | ||||
|                         Velocity *= 0.5f; | ||||
|             base.ModifyVelocity(); | ||||
|         } | ||||
|                 } | ||||
|                 else*/ | ||||
|                 if (weapon.IsUsing) | ||||
| 
 | ||||
|         public override void Stun(float time) | ||||
|         { | ||||
|                     Velocity *= 0.75f; | ||||
|                 } | ||||
|             base.Stun(time); | ||||
|             // TODO: implement visual effects for stun | ||||
|         } | ||||
| 
 | ||||
|         public override void Die() | ||||
|         { | ||||
|             //base.Die(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,42 +1,47 @@ | |||
| [gd_scene load_steps=22 format=3 uid="uid://bncaar8vp3b84"] | ||||
| [gd_scene load_steps=26 format=3 uid="uid://b2254pup8k161"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://Characters/Player.cs" id="1_flygr"] | ||||
| [ext_resource type="Texture2D" uid="uid://dxymfduyrbuvx" path="res://Sprites/Characters/forsen.png" id="2_swjho"] | ||||
| [ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="2_ngsgt"] | ||||
| [ext_resource type="Texture2D" uid="uid://dxymfduyrbuvx" path="res://Assets/Sprites/Characters/forsen.png" id="3_ig4hs"] | ||||
| [ext_resource type="Script" path="res://Characters/States/Machine.cs" id="3_npkjp"] | ||||
| [ext_resource type="Script" path="res://Characters/States/PlayerIdleState.cs" id="4_4k4mb"] | ||||
| [ext_resource type="Script" path="res://Characters/States/PlayerMoveState.cs" id="5_tx5rw"] | ||||
| [ext_resource type="Script" path="res://Characters/States/PlayerRollState.cs" id="6_6bgrj"] | ||||
| [ext_resource type="Script" path="res://Characters/States/PlayerAttackState.cs" id="7_4cuhw"] | ||||
| [ext_resource type="PackedScene" uid="uid://cajlwb67xenfy" path="res://Items/Weapons/Sword.tscn" id="7_4rxuv"] | ||||
| [ext_resource type="PackedScene" uid="uid://d72ehtv1ks0e" path="res://Items/Weapons/Sword.tscn" id="7_4rxuv"] | ||||
| [ext_resource type="Script" path="res://Items/Inventory.cs" id="7_xyenu"] | ||||
| [ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="9_avyu4"] | ||||
| 
 | ||||
| [sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"] | ||||
| shader = ExtResource("2_ngsgt") | ||||
| shader_parameter/color = null | ||||
| shader_parameter/intensity = 0.0 | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_us1ce"] | ||||
| atlas = ExtResource("2_swjho") | ||||
| atlas = ExtResource("3_ig4hs") | ||||
| region = Rect2(0, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_hn4kf"] | ||||
| atlas = ExtResource("2_swjho") | ||||
| atlas = ExtResource("3_ig4hs") | ||||
| region = Rect2(24, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_wfbeq"] | ||||
| atlas = ExtResource("2_swjho") | ||||
| atlas = ExtResource("3_ig4hs") | ||||
| region = Rect2(48, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_qlmwk"] | ||||
| atlas = ExtResource("2_swjho") | ||||
| atlas = ExtResource("3_ig4hs") | ||||
| region = Rect2(72, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_l1vgu"] | ||||
| atlas = ExtResource("2_swjho") | ||||
| atlas = ExtResource("3_ig4hs") | ||||
| region = Rect2(96, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_ytlaa"] | ||||
| atlas = ExtResource("2_swjho") | ||||
| atlas = ExtResource("3_ig4hs") | ||||
| region = Rect2(120, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="AtlasTexture" id="AtlasTexture_1q30d"] | ||||
| atlas = ExtResource("2_swjho") | ||||
| atlas = ExtResource("3_ig4hs") | ||||
| region = Rect2(144, 0, 24, 24) | ||||
| 
 | ||||
| [sub_resource type="SpriteFrames" id="SpriteFrames_2h7cf"] | ||||
|  | @ -61,18 +66,59 @@ font_size = 24 | |||
| [sub_resource type="RectangleShape2D" id="RectangleShape2D_cjk6b"] | ||||
| size = Vector2(16, 24) | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_dxevc"] | ||||
| resource_name = "Hurt" | ||||
| length = 0.6 | ||||
| tracks/0/type = "value" | ||||
| tracks/0/imported = false | ||||
| tracks/0/enabled = true | ||||
| tracks/0/path = NodePath(".:material:shader_parameter/intensity") | ||||
| tracks/0/interp = 2 | ||||
| tracks/0/loop_wrap = true | ||||
| tracks/0/keys = { | ||||
| "times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6), | ||||
| "transitions": PackedFloat32Array(4, 4, 4, 4, 4, 4, 4), | ||||
| "update": 0, | ||||
| "values": [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0] | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_k6l16"] | ||||
| length = 0.001 | ||||
| tracks/0/type = "value" | ||||
| tracks/0/imported = false | ||||
| tracks/0/enabled = true | ||||
| tracks/0/path = NodePath(".:material:shader_parameter/intensity") | ||||
| tracks/0/interp = 1 | ||||
| tracks/0/loop_wrap = true | ||||
| tracks/0/keys = { | ||||
| "times": PackedFloat32Array(0), | ||||
| "transitions": PackedFloat32Array(1), | ||||
| "update": 0, | ||||
| "values": [0.0] | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="AnimationLibrary" id="AnimationLibrary_xe5eq"] | ||||
| _data = { | ||||
| "Hurt": SubResource("Animation_dxevc"), | ||||
| "RESET": SubResource("Animation_k6l16") | ||||
| } | ||||
| 
 | ||||
| [node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("Sprite", "Inventory", "StateMachine")] | ||||
| texture_filter = 3 | ||||
| material = SubResource("ShaderMaterial_h78y7") | ||||
| y_sort_enabled = true | ||||
| collision_layer = 2 | ||||
| script = ExtResource("1_flygr") | ||||
| Speed = 64.0 | ||||
| Mass = 1.0 | ||||
| Health = 100.0 | ||||
| Sprite = NodePath("Sprite") | ||||
| Inventory = NodePath("Inventory") | ||||
| StateMachine = NodePath("StateMachine") | ||||
| Faction = 1 | ||||
| 
 | ||||
| [node name="Sprite" type="AnimatedSprite2D" parent="."] | ||||
| use_parent_material = true | ||||
| frames = SubResource("SpriteFrames_2h7cf") | ||||
| animation = &"move" | ||||
| playing = true | ||||
|  | @ -105,10 +151,6 @@ IdleState = NodePath("../Idle") | |||
| script = ExtResource("6_6bgrj") | ||||
| IdleState = NodePath("../Idle") | ||||
| 
 | ||||
| [node name="Attack" type="Node" parent="StateMachine" node_paths=PackedStringArray("IdleState")] | ||||
| script = ExtResource("7_4cuhw") | ||||
| IdleState = NodePath("../Idle") | ||||
| 
 | ||||
| [node name="Debug" type="Control" parent="."] | ||||
| layout_mode = 3 | ||||
| anchors_preset = 0 | ||||
|  | @ -136,6 +178,11 @@ Faction = 1 | |||
| [node name="CollisionShape2D" parent="Hurtbox" index="0"] | ||||
| shape = SubResource("RectangleShape2D_cjk6b") | ||||
| 
 | ||||
| [node name="FlashAnimation" type="AnimationPlayer" parent="."] | ||||
| libraries = { | ||||
| "": SubResource("AnimationLibrary_xe5eq") | ||||
| } | ||||
| 
 | ||||
| [connection signal="ReceivedDamage" from="Hurtbox" to="." method="_on_hurtbox_received_damage"] | ||||
| 
 | ||||
| [editable path="Hurtbox"] | ||||
|  |  | |||
|  | @ -22,13 +22,32 @@ namespace SupaLidlGame.Characters.State | |||
|         /// </summary> | ||||
|         public virtual void Exit(CharacterState nextState) { } | ||||
| 
 | ||||
|         public virtual CharacterState Process(double delta) => null; | ||||
|         public virtual CharacterState Process(double delta) | ||||
|         { | ||||
|             if (Character.StunTime > 0) | ||||
|             { | ||||
|                 Character.StunTime -= delta; | ||||
|             } | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         public virtual CharacterState PhysicsProcess(double delta) | ||||
|         { | ||||
|             Character.Velocity = Character.Direction * Character.Speed; | ||||
|             Character.Velocity = Character.NetImpulse; | ||||
| 
 | ||||
|             if (Character.NetImpulse.LengthSquared() < Mathf.Pow(Character.Speed, 2)) | ||||
|             { | ||||
|                 Character.Velocity += Character.Direction.Normalized() | ||||
|                     * Character.Speed; | ||||
|             } | ||||
| 
 | ||||
|             Character.NetImpulse = Character.NetImpulse.MoveToward( | ||||
|                 Vector2.Zero, | ||||
|                 (float)delta * Character.Speed * Character.Friction); | ||||
| 
 | ||||
|             Character.ModifyVelocity(); | ||||
|             Character.MoveAndSlide(); | ||||
| 
 | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,7 +32,8 @@ namespace SupaLidlGame.Characters.State | |||
|             { | ||||
|                 if (Character.Inventory.SelectedItem is not null) | ||||
|                 { | ||||
|                     Character.Inventory.SelectedItem.Use(); | ||||
|                     Character.UseCurrentItem(); | ||||
|                     //Character.Inventory.SelectedItem.Use(); | ||||
|                     //return AttackState; | ||||
|                 } | ||||
|             } | ||||
|  | @ -61,6 +62,7 @@ namespace SupaLidlGame.Characters.State | |||
|                     Character.Target = dirToMouse; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return base.Process(delta); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -0,0 +1,28 @@ | |||
| using Godot; | ||||
| 
 | ||||
| namespace SupaLidlGame.Extensions | ||||
| { | ||||
|     public static class NodeExtensions | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// Iterates through each ancestor until it finds an ancestor of type | ||||
|         /// <c>T</c> | ||||
|         /// </summary> | ||||
|         public static T GetAncestor<T>(this Node node) where T : Node | ||||
|         { | ||||
|             Node parent; | ||||
| 
 | ||||
|             while ((parent = node.GetParent()) != null) | ||||
|             { | ||||
|                 if (parent is T t) | ||||
|                 { | ||||
|                     return t; | ||||
|                 } | ||||
| 
 | ||||
|                 node = parent; | ||||
|             } | ||||
| 
 | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -1,4 +1,5 @@ | |||
| using Godot; | ||||
| using SupaLidlGame.BoundingBoxes; | ||||
| using SupaLidlGame.Characters; | ||||
| 
 | ||||
| namespace SupaLidlGame.Items | ||||
|  | @ -34,6 +35,16 @@ namespace SupaLidlGame.Items | |||
|         [Export] | ||||
|         public float InitialVelocity { get; set; } = 0; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Whether or not the weapon can parry other weapons and is | ||||
|         /// parryable by other weapons. | ||||
|         /// </summary> | ||||
|         public virtual bool IsParryable { get; protected set; } = false; | ||||
| 
 | ||||
|         public bool IsParried { get; set; } | ||||
| 
 | ||||
|         public ulong ParryTimeOrigin { get; protected set; } | ||||
| 
 | ||||
|         public Character Character { get; set; } | ||||
| 
 | ||||
|         public override void Equip(Character character) | ||||
|  | @ -66,5 +77,13 @@ namespace SupaLidlGame.Items | |||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public virtual void _on_hitbox_hit(BoundingBox box) | ||||
|         { | ||||
|             if (box is Hurtbox hurtbox) | ||||
|             { | ||||
|                 hurtbox.InflictDamage(Damage, Character, Knockback); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,14 +1,13 @@ | |||
| using Godot; | ||||
| using SupaLidlGame.BoundingBoxes; | ||||
| using SupaLidlGame.Characters; | ||||
| using SupaLidlGame.Extensions; | ||||
| 
 | ||||
| namespace SupaLidlGame.Items.Weapons | ||||
| { | ||||
|     public partial class Sword : Weapon | ||||
|     { | ||||
|         public double RemainingAttackTime { get; protected set; } = 0; | ||||
| 
 | ||||
|         public bool IsAttacking => RemainingAttackTime > 0; | ||||
|         public bool IsAttacking { get; protected set; } | ||||
| 
 | ||||
|         [Export] | ||||
|         public Hitbox Hitbox { get; set; } | ||||
|  | @ -26,6 +25,11 @@ namespace SupaLidlGame.Items.Weapons | |||
|         [Export] | ||||
|         public double AttackTime { get; set; } = 0; | ||||
| 
 | ||||
|         [Export] | ||||
|         public CPUParticles2D ParryParticles { get; set; } | ||||
| 
 | ||||
|         public override bool IsParryable { get; protected set; } | ||||
| 
 | ||||
|         public override void Equip(Character character) | ||||
|         { | ||||
|             Visible = true; | ||||
|  | @ -46,24 +50,46 @@ namespace SupaLidlGame.Items.Weapons | |||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             RemainingAttackTime = AttackTime; | ||||
|             IsParried = false; | ||||
| 
 | ||||
|             AnimationPlayer.Stop(); | ||||
| 
 | ||||
|             if (GetNode<Node2D>("Anchor").Rotation < Mathf.DegToRad(50)) | ||||
|             { | ||||
|                 AnimationPlayer.Play("use"); | ||||
|             Hitbox.IsDisabled = false; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 AnimationPlayer.Play("use2"); | ||||
|             } | ||||
| 
 | ||||
|             base.Use(); | ||||
|         } | ||||
| 
 | ||||
|         public override void Deuse() | ||||
|         { | ||||
|             AnimationPlayer.Stop(); | ||||
|             //AnimationPlayer.Stop(); | ||||
|             Deattack(); | ||||
|             base.Deuse(); | ||||
|         } | ||||
| 
 | ||||
|         protected void Deattack() | ||||
|         public void Attack() | ||||
|         { | ||||
|             ParryTimeOrigin = Time.GetTicksMsec(); | ||||
|             IsParryable = true; | ||||
|             //RemainingAttackTime = AttackTime; | ||||
|             IsAttacking = true; | ||||
|             Hitbox.IsDisabled = false; | ||||
|         } | ||||
| 
 | ||||
|         public void Deattack() | ||||
|         { | ||||
|             IsAttacking = false; | ||||
|             IsParryable = false; | ||||
|             Hitbox.IsDisabled = true; | ||||
|             ProcessHits(); | ||||
|             Hitbox.ResetIgnoreList(); | ||||
|             AnimationPlayer.PlaybackSpeed = 1; | ||||
|         } | ||||
| 
 | ||||
|         public override void _Ready() | ||||
|  | @ -73,6 +99,7 @@ namespace SupaLidlGame.Items.Weapons | |||
| 
 | ||||
|         public override void _Process(double delta) | ||||
|         { | ||||
|             /* | ||||
|             if (RemainingAttackTime > 0) | ||||
|             { | ||||
|                 if ((RemainingAttackTime -= delta) <= 0) | ||||
|  | @ -80,7 +107,73 @@ namespace SupaLidlGame.Items.Weapons | |||
|                     Deattack(); | ||||
|                 } | ||||
|             } | ||||
|             */ | ||||
|             base._Process(delta); | ||||
|         } | ||||
| 
 | ||||
|         public void ProcessHits() | ||||
|         { | ||||
|             if (IsParried) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             foreach (BoundingBox box in Hitbox.Hits) | ||||
|             { | ||||
|                 GD.Print("processing hit"); | ||||
|                 if (box is Hurtbox hurtbox) | ||||
|                 { | ||||
|                     hurtbox.InflictDamage(Damage, Character, Knockback); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void AttemptParry(Weapon otherWeapon) | ||||
|         { | ||||
|             if (IsParryable && otherWeapon.IsParryable) | ||||
|             { | ||||
|                 ParryParticles.Emitting = true; | ||||
|                 if (ParryTimeOrigin < otherWeapon.ParryTimeOrigin) | ||||
|                 { | ||||
|                     // our character was parried | ||||
|                     IsParried = true; | ||||
|                     AnimationPlayer.PlaybackSpeed = 0.25f; | ||||
|                     Character.Stun(1.5f); | ||||
|                 } | ||||
|             } | ||||
|             //this.GetAncestor<TileMap>().AddChild(instance); | ||||
|         } | ||||
| 
 | ||||
|         public override void _on_hitbox_hit(BoundingBox box) | ||||
|         { | ||||
|             if (IsParried) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if (box is Hitbox hb) | ||||
|             { | ||||
|                 Weapon w = hb.GetAncestor<Weapon>(); | ||||
|                 if (w is not null) | ||||
|                 { | ||||
|                     //Vector2 a = new Vector2(2, 2) * new Vector2(5, 2); | ||||
|                     AttemptParry(w); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if (box is Hurtbox hurt) | ||||
|             { | ||||
|                 if (hurt.GetParent() is Character c) | ||||
|                 { | ||||
|                     var item = c.Inventory.SelectedItem; | ||||
|                     if (item is Weapon w) | ||||
|                     { | ||||
|                         AttemptParry(w); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             //base._on_hitbox_hit(box); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,13 +1,14 @@ | |||
| [gd_scene load_steps=13 format=3 uid="uid://cajlwb67xenfy"] | ||||
| [gd_scene load_steps=16 format=3 uid="uid://d72ehtv1ks0e"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://Items/Weapons/Sword.cs" id="1_mlo73"] | ||||
| [ext_resource type="Texture2D" uid="uid://dt6u8p4h6g7le" path="res://Sprites/knife.png" id="2_dmsp2"] | ||||
| [ext_resource type="Texture2D" uid="uid://dt6u8p4h6g7le" path="res://Assets/Sprites/knife.png" id="2_rnfo4"] | ||||
| [ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="3_up3ob"] | ||||
| [ext_resource type="PackedScene" uid="uid://cojxmcin13ihm" path="res://Utils/Trail.tscn" id="4_pt6lq"] | ||||
| [ext_resource type="Texture2D" uid="uid://do1bui3bblkk7" path="res://Assets/Sprites/sword-swing.png" id="5_pywek"] | ||||
| 
 | ||||
| [sub_resource type="CapsuleShape2D" id="CapsuleShape2D_yln58"] | ||||
| radius = 8.0 | ||||
| height = 32.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="Curve" id="Curve_4cxtp"] | ||||
| _data = [Vector2(0.00687286, 1), 0.0, 0.0, 0, 0, Vector2(0.879725, 0.190909), -2.93145, -2.93145, 0, 0, Vector2(1, 0.0454545), 0.0483926, 0.0, 0, 0] | ||||
|  | @ -29,31 +30,19 @@ tracks/0/keys = { | |||
| "times": PackedFloat32Array(0), | ||||
| "transitions": PackedFloat32Array(1), | ||||
| "update": 0, | ||||
| "values": [-0.785398] | ||||
| "values": [-1.0472] | ||||
| } | ||||
| tracks/1/type = "value" | ||||
| tracks/1/imported = false | ||||
| tracks/1/enabled = true | ||||
| tracks/1/path = NodePath("Anchor/Sprite2D:rotation") | ||||
| 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": 0, | ||||
| "values": [-1.19209e-07] | ||||
| } | ||||
| tracks/2/type = "value" | ||||
| tracks/2/imported = false | ||||
| tracks/2/enabled = true | ||||
| tracks/2/path = NodePath("Anchor/Sprite2D:position") | ||||
| tracks/2/interp = 1 | ||||
| tracks/2/loop_wrap = true | ||||
| tracks/2/keys = { | ||||
| "times": PackedFloat32Array(0), | ||||
| "transitions": PackedFloat32Array(1), | ||||
| "update": 0, | ||||
| "values": [Vector2(8, 1)] | ||||
| "update": 1, | ||||
| "values": [0] | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_mv7y2"] | ||||
|  | @ -61,8 +50,7 @@ resource_name = "idle" | |||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_orc8t"] | ||||
| resource_name = "use" | ||||
| length = 0.5 | ||||
| loop_mode = 1 | ||||
| length = 0.75 | ||||
| step = 0.05 | ||||
| tracks/0/type = "value" | ||||
| tracks/0/imported = false | ||||
|  | @ -71,77 +59,142 @@ tracks/0/path = NodePath("Anchor:rotation") | |||
| tracks/0/interp = 1 | ||||
| tracks/0/loop_wrap = true | ||||
| tracks/0/keys = { | ||||
| "times": PackedFloat32Array(0, 0.1, 0.3, 0.5), | ||||
| "transitions": PackedFloat32Array(1, 1, 1, 1), | ||||
| "times": PackedFloat32Array(0.05, 0.1, 0.2, 0.4, 0.75), | ||||
| "transitions": PackedFloat32Array(1, 4, 1, 2, 1), | ||||
| "update": 0, | ||||
| "values": [-0.785398, 1.5708, 1.5708, -0.785398] | ||||
| "values": [-0.610865, -0.959931, 3.92699, 3.92699, 3.75246] | ||||
| } | ||||
| tracks/1/type = "value" | ||||
| tracks/1/type = "method" | ||||
| tracks/1/imported = false | ||||
| tracks/1/enabled = true | ||||
| tracks/1/path = NodePath("Anchor/Sprite2D:rotation") | ||||
| tracks/1/path = NodePath(".") | ||||
| tracks/1/interp = 1 | ||||
| tracks/1/loop_wrap = true | ||||
| tracks/1/keys = { | ||||
| "times": PackedFloat32Array(0, 0.1, 0.3, 0.5), | ||||
| "transitions": PackedFloat32Array(1, 1, 1, 1), | ||||
| "update": 0, | ||||
| "values": [-1.19209e-07, 0.785398, 0.785398, -1.19209e-07] | ||||
| "times": PackedFloat32Array(0.05, 0.25), | ||||
| "transitions": PackedFloat32Array(1, 1), | ||||
| "values": [{ | ||||
| "args": [], | ||||
| "method": &"Attack" | ||||
| }, { | ||||
| "args": [], | ||||
| "method": &"Deattack" | ||||
| }] | ||||
| } | ||||
| tracks/2/type = "value" | ||||
| tracks/2/imported = false | ||||
| tracks/2/enabled = true | ||||
| tracks/2/path = NodePath("Anchor/Sprite2D:position") | ||||
| tracks/2/path = NodePath("SwingSprite:frame") | ||||
| tracks/2/interp = 1 | ||||
| tracks/2/loop_wrap = true | ||||
| tracks/2/keys = { | ||||
| "times": PackedFloat32Array(0, 0.1, 0.3, 0.5), | ||||
| "times": PackedFloat32Array(0, 0.2, 0.3, 0.4), | ||||
| "transitions": PackedFloat32Array(1, 1, 1, 1), | ||||
| "update": 1, | ||||
| "values": [0, 1, 2, 0] | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="Animation" id="Animation_y4mj3"] | ||||
| resource_name = "use2" | ||||
| length = 0.75 | ||||
| step = 0.05 | ||||
| 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.05, 0.1, 0.2, 0.4, 0.75), | ||||
| "transitions": PackedFloat32Array(1, 4, 1, 2, 1), | ||||
| "update": 0, | ||||
| "values": [Vector2(8, 1), Vector2(12, -1), Vector2(12, -1), Vector2(8, 1)] | ||||
| "values": [3.75246, 4.10152, -0.785398, -0.785398, -0.610865] | ||||
| } | ||||
| tracks/1/type = "method" | ||||
| tracks/1/imported = false | ||||
| tracks/1/enabled = true | ||||
| tracks/1/path = NodePath(".") | ||||
| tracks/1/interp = 1 | ||||
| tracks/1/loop_wrap = true | ||||
| tracks/1/keys = { | ||||
| "times": PackedFloat32Array(0.05, 0.25), | ||||
| "transitions": PackedFloat32Array(1, 1), | ||||
| "values": [{ | ||||
| "args": [], | ||||
| "method": &"Attack" | ||||
| }, { | ||||
| "args": [], | ||||
| "method": &"Deattack" | ||||
| }] | ||||
| } | ||||
| tracks/2/type = "value" | ||||
| tracks/2/imported = false | ||||
| tracks/2/enabled = true | ||||
| tracks/2/path = NodePath("SwingSprite:frame") | ||||
| tracks/2/interp = 1 | ||||
| tracks/2/loop_wrap = true | ||||
| tracks/2/keys = { | ||||
| "times": PackedFloat32Array(0, 0.2, 0.3, 0.4), | ||||
| "transitions": PackedFloat32Array(1, 1, 1, 1), | ||||
| "update": 1, | ||||
| "values": [0, 1, 3, 0] | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="AnimationLibrary" id="AnimationLibrary_tao4k"] | ||||
| _data = { | ||||
| "RESET": SubResource("Animation_b7327"), | ||||
| "idle": SubResource("Animation_mv7y2"), | ||||
| "use": SubResource("Animation_orc8t") | ||||
| "use": SubResource("Animation_orc8t"), | ||||
| "use2": SubResource("Animation_y4mj3") | ||||
| } | ||||
| 
 | ||||
| [sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_1lid1"] | ||||
| 
 | ||||
| [node name="Sword" type="Node2D" node_paths=PackedStringArray("Hitbox", "AnimationPlayer")] | ||||
| [sub_resource type="ConvexPolygonShape2D" id="ConvexPolygonShape2D_tv0o2"] | ||||
| points = PackedVector2Array(-11.314, -11.314, 0, -16, 11.314, -11.314, 16, 0, 11.314, 11.314, 0, 16, -11.314, 11.314, 0, 0) | ||||
| 
 | ||||
| [node name="Sword" type="Node2D" node_paths=PackedStringArray("Hitbox", "AnimationPlayer", "ParryParticles")] | ||||
| texture_filter = 3 | ||||
| y_sort_enabled = true | ||||
| script = ExtResource("1_mlo73") | ||||
| Hitbox = NodePath("Anchor/Sprite2D/Hitbox") | ||||
| Hitbox = NodePath("Hitbox") | ||||
| AnimationPlayer = NodePath("AnimationPlayer") | ||||
| AttackTime = 0.1 | ||||
| Damage = 20.0 | ||||
| UseTime = 0.5 | ||||
| ParryParticles = NodePath("Anchor/Sprite2D/ParryParticles") | ||||
| Damage = 30.0 | ||||
| UseTime = 0.8 | ||||
| Knockback = 80.0 | ||||
| Description = "A basic sword." | ||||
| 
 | ||||
| [node name="Anchor" type="Node2D" parent="."] | ||||
| rotation = -0.785398 | ||||
| rotation = -1.0472 | ||||
| y_sort_enabled = true | ||||
| 
 | ||||
| [node name="Sprite2D" type="Sprite2D" parent="Anchor"] | ||||
| position = Vector2(8, 1) | ||||
| position = Vector2(0, -8) | ||||
| y_sort_enabled = true | ||||
| texture = ExtResource("2_dmsp2") | ||||
| texture = ExtResource("2_rnfo4") | ||||
| 
 | ||||
| [node name="Hitbox" parent="Anchor/Sprite2D" instance=ExtResource("3_up3ob")] | ||||
| IsDisabled = true | ||||
| 
 | ||||
| [node name="CollisionShape2D" parent="Anchor/Sprite2D/Hitbox" index="0"] | ||||
| position = Vector2(0, -4) | ||||
| shape = SubResource("CapsuleShape2D_yln58") | ||||
| disabled = true | ||||
| [node name="ParryParticles" type="CPUParticles2D" parent="Anchor/Sprite2D"] | ||||
| position = Vector2(-0.221825, -3.12132) | ||||
| rotation = 0.785398 | ||||
| emitting = false | ||||
| amount = 12 | ||||
| lifetime = 0.4 | ||||
| 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") | ||||
| 
 | ||||
| [node name="Trail" parent="Anchor" node_paths=PackedStringArray("Tracking") instance=ExtResource("4_pt6lq")] | ||||
| position = Vector2(2.40734, -0.55655) | ||||
| rotation = 0.945464 | ||||
| scale = Vector2(1, 1) | ||||
| width_curve = SubResource("Curve_4cxtp") | ||||
| gradient = SubResource("Gradient_2ablm") | ||||
| Tracking = NodePath("../Sprite2D") | ||||
|  | @ -156,4 +209,21 @@ tree_root = SubResource("AnimationNodeAnimation_1lid1") | |||
| anim_player = NodePath("../AnimationPlayer") | ||||
| active = true | ||||
| 
 | ||||
| [editable path="Anchor/Sprite2D/Hitbox"] | ||||
| [node name="Hitbox" parent="." instance=ExtResource("3_up3ob")] | ||||
| IsDisabled = true | ||||
| 
 | ||||
| [node name="CollisionShape2D" parent="Hitbox" index="0"] | ||||
| shape = SubResource("ConvexPolygonShape2D_tv0o2") | ||||
| disabled = true | ||||
| 
 | ||||
| [node name="SwingSprite" type="Sprite2D" parent="."] | ||||
| texture = ExtResource("5_pywek") | ||||
| hframes = 4 | ||||
| 
 | ||||
| [node name="SwingSound" type="AudioStreamPlayer2D" parent="."] | ||||
| 
 | ||||
| [node name="ParrySound" type="AudioStreamPlayer2D" parent="."] | ||||
| 
 | ||||
| [connection signal="Hit" from="Hitbox" to="." method="_on_hitbox_hit"] | ||||
| 
 | ||||
| [editable path="Hitbox"] | ||||
|  |  | |||
|  | @ -1,8 +1,9 @@ | |||
| [gd_scene load_steps=6 format=3 uid="uid://cbsosmpnenfwu"] | ||||
| [gd_scene load_steps=8 format=3 uid="uid://dd6xy1y0m8smm"] | ||||
| 
 | ||||
| [ext_resource type="Texture2D" uid="uid://gm2pcnfg7h8j" path="res://Sprites/tileset.png" id="1_k6myx"] | ||||
| [ext_resource type="PackedScene" uid="uid://bncaar8vp3b84" path="res://Characters/Player.tscn" id="1_m35hr"] | ||||
| [ext_resource type="PackedScene" uid="uid://dymwd5ihpwyqm" path="res://Characters/ExampleEnemy.tscn" id="2_uti3y"] | ||||
| [ext_resource type="Texture2D" uid="uid://gm2pcnfg7h8j" path="res://Assets/Sprites/tileset.png" id="1_k6myx"] | ||||
| [ext_resource type="PackedScene" uid="uid://b2254pup8k161" path="res://Characters/Player.tscn" id="1_m35hr"] | ||||
| [ext_resource type="PackedScene" uid="uid://ddcf6bfv212wj" path="res://Characters/ExampleEnemy.tscn" id="2_uti3y"] | ||||
| [ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="4_056cf"] | ||||
| 
 | ||||
| [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_1pa1q"] | ||||
| texture = ExtResource("1_k6myx") | ||||
|  | @ -1100,6 +1101,12 @@ texture = ExtResource("1_k6myx") | |||
| physics_layer_0/collision_layer = 1 | ||||
| sources/0 = SubResource("TileSetAtlasSource_1pa1q") | ||||
| 
 | ||||
| [sub_resource type="ShaderMaterial" id="ShaderMaterial_mq5wa"] | ||||
| resource_local_to_scene = true | ||||
| shader = ExtResource("4_056cf") | ||||
| shader_parameter/color = null | ||||
| shader_parameter/intensity = 0.0 | ||||
| 
 | ||||
| [node name="Level" type="Node2D"] | ||||
| 
 | ||||
| [node name="TileMap" type="TileMap" parent="."] | ||||
|  | @ -1137,13 +1144,11 @@ position = Vector2(-81, -34) | |||
| motion_mode = 1 | ||||
| 
 | ||||
| [node name="ExampleEnemy" parent="TileMap" instance=ExtResource("2_uti3y")] | ||||
| material = SubResource("ShaderMaterial_mq5wa") | ||||
| position = Vector2(38, 42) | ||||
| scale = Vector2(1.00571, 1) | ||||
| 
 | ||||
| [node name="ExampleEnemy2" parent="TileMap" instance=ExtResource("2_uti3y")] | ||||
| position = Vector2(156, 58) | ||||
| scale = Vector2(1.00571, 1) | ||||
| 
 | ||||
| [node name="ExampleEnemy3" parent="TileMap" instance=ExtResource("2_uti3y")] | ||||
| position = Vector2(175, -15) | ||||
| material = SubResource("ShaderMaterial_mq5wa") | ||||
| position = Vector2(190, 99) | ||||
| scale = Vector2(1.00571, 1) | ||||
|  |  | |||
|  | @ -0,0 +1,10 @@ | |||
| shader_type canvas_item; | ||||
| 
 | ||||
| uniform vec4 color = vec4(1.0); | ||||
| uniform float intensity : hint_range(0.0, 1.0) = 0.0; | ||||
| 
 | ||||
| void fragment() { | ||||
|     vec4 tex = texture(TEXTURE, UV); | ||||
|     tex.rgb = mix(tex.rgb, color.rgb, intensity); | ||||
|     COLOR = tex; | ||||
| } | ||||
|  | @ -0,0 +1,51 @@ | |||
| using Godot; | ||||
| using System; | ||||
| 
 | ||||
| namespace SupaLidlGame.UI | ||||
| { | ||||
|     public partial class FloatingText : Node2D | ||||
|     { | ||||
|         private Label _label; | ||||
| 
 | ||||
|         [Export] | ||||
|         public string Text { get; set; } | ||||
| 
 | ||||
|         public override void _Ready() | ||||
|         { | ||||
|             _label = GetNode<Label>("Label"); | ||||
|             _label.Text = Text; | ||||
| 
 | ||||
|             Tween tween = GetTree().CreateTween() | ||||
|                 .SetEase(Tween.EaseType.Out) | ||||
|                 .SetTrans(Tween.TransitionType.Quint) | ||||
|                 .SetParallel(); | ||||
| 
 | ||||
|             Random rng = new Random(); | ||||
| 
 | ||||
|             float randomFloat(float min, float max) | ||||
|             { | ||||
|                 return (float)rng.NextDouble() * (max - min) + min; | ||||
|             } | ||||
| 
 | ||||
|             GD.Print(GlobalPosition); | ||||
|             Position += new Vector2(randomFloat(-8, 8), 0); | ||||
|             var endPos = Position + new Vector2(0, randomFloat(-16, -8)); | ||||
|             var endMod = new Color(1, 1, 1, 0); | ||||
|             var endScale = Scale * 0.5f; | ||||
| 
 | ||||
|             tween.TweenProperty(this, "position", endPos, 0.5f); | ||||
|             tween.SetTrans(Tween.TransitionType.Linear); | ||||
|             tween.TweenProperty(this, "modulate", endMod, 0.5f).SetDelay(1.0f); | ||||
|             tween.TweenProperty(this, "scale", endScale, 0.5f).SetDelay(1.0f); | ||||
|             tween.TweenCallback(new Callable(this, nameof(OnTweenFinished))) | ||||
|                 .SetDelay(2.5f); | ||||
| 
 | ||||
|             base._Ready(); | ||||
|         } | ||||
| 
 | ||||
|         public void OnTweenFinished() | ||||
|         { | ||||
|             QueueFree(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,26 @@ | |||
| [gd_scene load_steps=4 format=3 uid="uid://be80n7mxp62jd"] | ||||
| 
 | ||||
| [ext_resource type="Script" path="res://UI/FloatingText.cs" id="1_yejq1"] | ||||
| [ext_resource type="FontFile" uid="uid://cgwa8bjiyv534" path="res://Assets/Fonts/alagard.ttf" id="1_yns15"] | ||||
| 
 | ||||
| [sub_resource type="LabelSettings" id="LabelSettings_gs6ch"] | ||||
| font = ExtResource("1_yns15") | ||||
| font_color = Color(1, 0.792157, 0, 1) | ||||
| outline_size = 2 | ||||
| outline_color = Color(0.635294, 0.415686, 0, 1) | ||||
| shadow_color = Color(0, 0, 0, 1) | ||||
| 
 | ||||
| [node name="FloatingText" type="Node2D"] | ||||
| scale = Vector2(0.5, 0.5) | ||||
| script = ExtResource("1_yejq1") | ||||
| 
 | ||||
| [node name="Label" type="Label" parent="."] | ||||
| texture_filter = 3 | ||||
| offset_left = -128.0 | ||||
| offset_top = -16.0 | ||||
| offset_right = 128.0 | ||||
| offset_bottom = 16.0 | ||||
| text = "gruppa krovi" | ||||
| label_settings = SubResource("LabelSettings_gs6ch") | ||||
| horizontal_alignment = 1 | ||||
| vertical_alignment = 1 | ||||
|  | @ -0,0 +1,3 @@ | |||
| [gd_resource type="Theme" format=3 uid="uid://cksjbu3vrup5"] | ||||
| 
 | ||||
| [resource] | ||||
|  | @ -0,0 +1,47 @@ | |||
| [preset.0] | ||||
| 
 | ||||
| name="Windows Desktop" | ||||
| platform="Windows Desktop" | ||||
| runnable=true | ||||
| custom_features="" | ||||
| export_filter="all_resources" | ||||
| include_filter="" | ||||
| exclude_filter="" | ||||
| export_path="./SupaLidlGame.exe" | ||||
| encryption_include_filters="" | ||||
| encryption_exclude_filters="" | ||||
| encrypt_pck=false | ||||
| encrypt_directory=false | ||||
| script_export_mode=1 | ||||
| script_encryption_key="" | ||||
| 
 | ||||
| [preset.0.options] | ||||
| 
 | ||||
| custom_template/debug="" | ||||
| custom_template/release="" | ||||
| debug/export_console_script=1 | ||||
| binary_format/embed_pck=false | ||||
| texture_format/bptc=false | ||||
| texture_format/s3tc=true | ||||
| texture_format/etc=false | ||||
| texture_format/etc2=false | ||||
| texture_format/no_bptc_fallbacks=true | ||||
| binary_format/architecture="x86_64" | ||||
| codesign/enable=false | ||||
| codesign/identity_type=0 | ||||
| codesign/identity="" | ||||
| codesign/password="" | ||||
| codesign/timestamp=true | ||||
| codesign/timestamp_server_url="" | ||||
| codesign/digest_algorithm=1 | ||||
| codesign/description="" | ||||
| codesign/custom_options=PackedStringArray() | ||||
| application/modify_resources=true | ||||
| application/icon="" | ||||
| application/file_version="" | ||||
| application/product_version="" | ||||
| application/company_name="" | ||||
| application/product_name="" | ||||
| application/file_description="" | ||||
| application/copyright="" | ||||
| application/trademarks="" | ||||
|  | @ -0,0 +1,2 @@ | |||
| { | ||||
| } | ||||