diff --git a/Assets/Sprites/railgun.ase b/Assets/Sprites/railgun.ase index 44f6ad0..2ca5b1e 100644 Binary files a/Assets/Sprites/railgun.ase and b/Assets/Sprites/railgun.ase differ diff --git a/Assets/Sprites/railgun.png b/Assets/Sprites/railgun.png new file mode 100644 index 0000000..dd44117 Binary files /dev/null and b/Assets/Sprites/railgun.png differ diff --git a/Assets/Sprites/railgun.png.import b/Assets/Sprites/railgun.png.import new file mode 100644 index 0000000..f772cf3 --- /dev/null +++ b/Assets/Sprites/railgun.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://bdidfdee6rhv4" +path="res://.godot/imported/railgun.png-ea880f6d75ff5c52f6ef9b2f35ca009e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/railgun.png" +dest_files=["res://.godot/imported/railgun.png-ea880f6d75ff5c52f6ef9b2f35ca009e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/BoundingBoxes/Hitbox.cs b/BoundingBoxes/Hitbox.cs index d6ceb13..b7950ae 100644 --- a/BoundingBoxes/Hitbox.cs +++ b/BoundingBoxes/Hitbox.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using Godot; using SupaLidlGame.Characters; using SupaLidlGame.Items; @@ -81,6 +80,7 @@ namespace SupaLidlGame.BoundingBoxes { if (area is BoundingBox box) { + GD.Print("hit"); // we don't want to hurt teammates if (Faction != box.Faction) { diff --git a/Characters/ExampleEnemy.tscn b/Characters/ExampleEnemy.tscn index 0bc0347..1569e97 100644 --- a/Characters/ExampleEnemy.tscn +++ b/Characters/ExampleEnemy.tscn @@ -8,7 +8,7 @@ [ext_resource type="Script" path="res://State/Character/NPCMoveState.cs" id="6_73mr6"] [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://d72ehtv1ks0e" path="res://Items/Weapons/Sword.tscn" id="8_s3c8r"] +[ext_resource type="PackedScene" uid="uid://dvqap2uhcah63" path="res://Items/Weapons/Sword.tscn" id="8_s3c8r"] [ext_resource type="AudioStream" uid="uid://njun3e6v4854" path="res://Assets/Sounds/hurt.wav" id="10_n1e64"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_ms3xg"] diff --git a/Characters/Player.tscn b/Characters/Player.tscn index edf0a8f..119c503 100644 --- a/Characters/Player.tscn +++ b/Characters/Player.tscn @@ -6,7 +6,7 @@ [ext_resource type="PackedScene" uid="uid://cl56eadpklnbo" path="res://Utils/PlayerCamera.tscn" id="4_ym125"] [ext_resource type="Script" path="res://State/Character/CharacterStateMachine.cs" id="5_rgckv"] [ext_resource type="Script" path="res://State/Character/PlayerIdleState.cs" id="6_wkfdm"] -[ext_resource type="PackedScene" uid="uid://d72ehtv1ks0e" path="res://Items/Weapons/Sword.tscn" id="7_4rxuv"] +[ext_resource type="PackedScene" uid="uid://dvqap2uhcah63" path="res://Items/Weapons/Sword.tscn" id="7_4rxuv"] [ext_resource type="Script" path="res://State/Character/PlayerMoveState.cs" id="7_dfqd8"] [ext_resource type="Script" path="res://Items/Inventory.cs" id="7_xyenu"] [ext_resource type="Script" path="res://State/Character/PlayerRollState.cs" id="8_fy0v5"] @@ -208,8 +208,7 @@ InventoryMap = { "equip_2": 1 } -[node name="Sword" parent="Inventory" instance=ExtResource("7_4rxuv")] -position = Vector2(0, 2) +[node name="Node2D" parent="Inventory" instance=ExtResource("7_4rxuv")] [node name="Hurtbox" parent="." instance=ExtResource("9_avyu4")] Faction = 1 diff --git a/Entities/Projectile.cs b/Entities/Projectile.cs index 97c258f..7996bc1 100644 --- a/Entities/Projectile.cs +++ b/Entities/Projectile.cs @@ -1,8 +1,41 @@ using Godot; +using SupaLidlGame.Characters; +using SupaLidlGame.BoundingBoxes; namespace SupaLidlGame.Entities { - public abstract partial class Projectile : RigidBody2D + public partial class Projectile : RigidBody2D { + public Vector2 Velocity => Direction * Speed; + + [Export] + public float Speed { get; set; } + + [Export] + public Vector2 Direction { get; set; } + + [Export] + public Hitbox Hitbox { get; set; } + + public Character Character { get; set; } + + public override void _PhysicsProcess(double delta) + { + Vector2 velocity = Velocity; + MoveAndCollide(velocity * (float)delta); + } + + public void _on_hitbox_hit(BoundingBox box) + { + if (box is Hurtbox hurtbox) + { + hurtbox.InflictDamage( + Hitbox.Damage, + Character, + Hitbox.Knockback, + knockbackVector: Direction + ); + } + } } } diff --git a/Entities/RailBeam.tscn b/Entities/RailBeam.tscn new file mode 100644 index 0000000..1a41828 --- /dev/null +++ b/Entities/RailBeam.tscn @@ -0,0 +1,32 @@ +[gd_scene load_steps=5 format=3 uid="uid://bqvseo3sbs1aj"] + +[ext_resource type="Script" path="res://Entities/Projectile.cs" id="1_hhb4t"] +[ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="2_pcf4i"] + +[sub_resource type="CanvasTexture" id="CanvasTexture_cc88g"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_j0tne"] +size = Vector2(16, 4) + +[node name="RailBeam" type="RigidBody2D" node_paths=PackedStringArray("Hitbox")] +script = ExtResource("1_hhb4t") +Speed = 512.0 +Direction = Vector2(1, 0) +Hitbox = NodePath("Hitbox") + +[node name="Sprite2D" type="Sprite2D" parent="."] +modulate = Color(1.4, 0, 1.2, 1) +self_modulate = Color(2, 2, 2, 1) +scale = Vector2(8, 4) +texture = SubResource("CanvasTexture_cc88g") + +[node name="Hitbox" parent="." instance=ExtResource("2_pcf4i")] +Damage = 25.0 +Knockback = 256.0 + +[node name="CollisionShape2D" parent="Hitbox" index="0"] +shape = SubResource("RectangleShape2D_j0tne") + +[connection signal="Hit" from="Hitbox" to="." method="_on_hitbox_hit"] + +[editable path="Hitbox"] diff --git a/Items/Weapon.cs b/Items/Weapon.cs index c926d38..dc70add 100644 --- a/Items/Weapon.cs +++ b/Items/Weapon.cs @@ -47,18 +47,17 @@ namespace SupaLidlGame.Items [Export] public float MaxDistanceHint { get; set; } - [Export] - public Node2D Anchor { get; set; } - public override bool StacksWith(Item item) => false; public override void Equip(Character character) { + Visible = true; Character = character; } public override void Unequip(Character character) { + Visible = false; Character = null; } @@ -78,7 +77,7 @@ namespace SupaLidlGame.Items { if ((RemainingUseTime -= delta) <= 0) { - Deuse(); + //Deuse(); } } } diff --git a/Items/Weapons/HitscanRanged.cs b/Items/Weapons/HitscanRanged.cs index ce5240d..e69de29 100644 --- a/Items/Weapons/HitscanRanged.cs +++ b/Items/Weapons/HitscanRanged.cs @@ -1,10 +0,0 @@ -namespace SupaLidlGame.Items.Weapons -{ - public partial class HitscanRanged : Ranged - { - public override void Attack() - { - - } - } -} diff --git a/Items/Weapons/Railgun.cs b/Items/Weapons/Railgun.cs new file mode 100644 index 0000000..5946d67 --- /dev/null +++ b/Items/Weapons/Railgun.cs @@ -0,0 +1,22 @@ +using Godot; +using SupaLidlGame.Extensions; + +namespace SupaLidlGame.Items.Weapons +{ + public partial class Railgun : Ranged + { + public override void Attack() + { + // create projectile + PackedScene scene = GD.Load("res://Entities/RailBeam.tscn"); + GD.Print("lol"); + var projectile = scene.Instantiate(); + projectile.Hitbox.Faction = Character.Faction; + projectile.Direction = Character.Target; + projectile.GlobalPosition = GlobalPosition; + projectile.GlobalRotation = projectile.Direction.Angle(); + this.GetAncestor() + .Entities.AddChild(projectile); + } + } +} diff --git a/Items/Weapons/Railgun.tscn b/Items/Weapons/Railgun.tscn new file mode 100644 index 0000000..e03bf7e --- /dev/null +++ b/Items/Weapons/Railgun.tscn @@ -0,0 +1,42 @@ +[gd_scene load_steps=7 format=3 uid="uid://g7wfcubs6bdd"] + +[ext_resource type="Texture2D" uid="uid://bdidfdee6rhv4" path="res://Assets/Sprites/railgun.png" id="1_4lqn3"] +[ext_resource type="Script" path="res://Items/Weapons/Railgun.cs" id="1_pami3"] +[ext_resource type="Script" path="res://State/Weapon/WeaponStateMachine.cs" id="1_xynim"] +[ext_resource type="Script" path="res://State/Weapon/RangedIdleState.cs" id="2_a4hhy"] +[ext_resource type="Script" path="res://State/Weapon/RangedFireState.cs" id="3_dcbnq"] + +[sub_resource type="SpriteFrames" id="SpriteFrames_wjqqh"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": ExtResource("1_4lqn3") +}], +"loop": true, +"name": &"default", +"speed": 5.0 +}] + +[node name="Railgun" type="Node2D" node_paths=PackedStringArray("StateMachine")] +script = ExtResource("1_pami3") +StateMachine = NodePath("State") +Damage = 50.0 +UseTime = 1.0 + +[node name="State" type="Node" parent="." node_paths=PackedStringArray("InitialState")] +script = ExtResource("1_xynim") +InitialState = NodePath("Idle") + +[node name="Idle" type="Node" parent="State" node_paths=PackedStringArray("FireState")] +script = ExtResource("2_a4hhy") +FireState = NodePath("../Fire") + +[node name="Fire" type="Node" parent="State" node_paths=PackedStringArray("Weapon", "IdleState")] +script = ExtResource("3_dcbnq") +Weapon = NodePath("../..") +IdleState = NodePath("../Idle") + +[node name="Sprite2D" type="AnimatedSprite2D" parent="."] +texture_filter = 1 +position = Vector2(8, 0) +sprite_frames = SubResource("SpriteFrames_wjqqh") diff --git a/Items/Weapons/Ranged.cs b/Items/Weapons/Ranged.cs index b5e21f7..79dbbd7 100644 --- a/Items/Weapons/Ranged.cs +++ b/Items/Weapons/Ranged.cs @@ -10,49 +10,31 @@ namespace SupaLidlGame.Items.Weapons [Export] public float ChargeTime { get; set; } - public bool IsChargeable => ChargeTime > 0; + [Export] + public State.Weapon.WeaponStateMachine StateMachine { get; set; } - public double ChargeProgress { get; protected set; } + public override bool IsUsing => StateMachine.CurrentState + is State.Weapon.RangedFireState; + + public bool IsChargeable => ChargeTime > 0; public bool IsCharging { get; protected set; } public override void Use() { - if (RemainingUseTime > 0) - { - return; - } - - if (IsChargeable) - { - IsCharging = true; - } - else - { - Attack(); - } - + StateMachine.Use(); base.Use(); } public override void Deuse() { - if (IsChargeable && IsCharging) - { - Attack(); - IsCharging = false; - } - + StateMachine.Deuse(); base.Deuse(); } public override void _Process(double delta) { - if (IsCharging) - { - ChargeProgress += delta; - } - + StateMachine.Process(delta); base._Process(delta); } diff --git a/Items/Weapons/Sword.cs b/Items/Weapons/Sword.cs index a06c424..679a830 100644 --- a/Items/Weapons/Sword.cs +++ b/Items/Weapons/Sword.cs @@ -44,6 +44,9 @@ namespace SupaLidlGame.Items.Weapons [Export] public WeaponStateMachine StateMachine { get; set; } + [Export] + public Node2D Anchor { get; set; } + public override bool IsParryable { get; protected set; } public ulong ParryTimeOrigin { get; protected set; } @@ -54,14 +57,12 @@ namespace SupaLidlGame.Items.Weapons public override void Equip(Character character) { - Visible = true; base.Equip(character); Hitbox.Faction = character.Faction; // character is null before base } public override void Unequip(Character character) { - Visible = false; base.Unequip(character); } diff --git a/Items/Weapons/Sword.tscn b/Items/Weapons/Sword.tscn index 3ffcd8a..6d5351f 100644 --- a/Items/Weapons/Sword.tscn +++ b/Items/Weapons/Sword.tscn @@ -342,12 +342,12 @@ AnimationTree = NodePath("AnimationTree") AttackTime = 0.2 AttackAnimationDuration = 1.0 ParryParticles = NodePath("Anchor/Node2D/Sprite2D/ParryParticles") -NPCAnticipateTime = 0.4 +NPCAnticipateTime = 0.3 StateMachine = NodePath("State") -Damage = 20.0 -UseTime = 0.4 -Knockback = 64.0 Anchor = NodePath("Anchor") +Damage = 20.0 +UseTime = 0.8 +Knockback = 64.0 [node name="State" type="Node" parent="." node_paths=PackedStringArray("InitialState")] script = ExtResource("2_vwirq") diff --git a/Scenes/Maps/Hills.tscn b/Scenes/Maps/Hills.tscn index 123a833..ec5ba97 100644 --- a/Scenes/Maps/Hills.tscn +++ b/Scenes/Maps/Hills.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=6 format=3 uid="uid://bxtpv6jqodj4v"] +[gd_scene load_steps=7 format=3 uid="uid://bxtpv6jqodj4v"] [ext_resource type="PackedScene" uid="uid://clwv2owvk6abe" path="res://Scenes/BaseMap.tscn" id="1_vly6f"] [ext_resource type="Texture2D" uid="uid://dl2h266oa2x31" path="res://Assets/Sprites/night-grass.png" id="2_ote21"] [ext_resource type="PackedScene" uid="uid://bf55wbq7m1gpp" path="res://Characters/ExampleEnemy.tscn" id="3_hwof6"] +[ext_resource type="PackedScene" uid="uid://bqvseo3sbs1aj" path="res://Entities/RailBeam.tscn" id="4_vxueq"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_dvbe3"] texture = ExtResource("2_ote21") @@ -217,3 +218,6 @@ layer_5/tile_data = PackedInt32Array(786438, 262144, 3, 720899, 262144, 3, 85197 [node name="ExampleEnemy" parent="Entities" index="0" instance=ExtResource("3_hwof6")] position = Vector2(169, 115) + +[node name="RailBeam" parent="." index="6" instance=ExtResource("4_vxueq")] +position = Vector2(55, 8) diff --git a/State/Character/CharacterStateMachine.cs b/State/Character/CharacterStateMachine.cs index 5386c9a..87cde18 100644 --- a/State/Character/CharacterStateMachine.cs +++ b/State/Character/CharacterStateMachine.cs @@ -31,7 +31,7 @@ namespace SupaLidlGame.State.Character public void Input(InputEvent @event) { var state = CurrentState.Input(@event); - if (state is not null) + if (state is CharacterState) { ChangeState(state); } diff --git a/State/Character/PlayerState.cs b/State/Character/PlayerState.cs index f50da3c..29cef44 100644 --- a/State/Character/PlayerState.cs +++ b/State/Character/PlayerState.cs @@ -46,8 +46,14 @@ namespace SupaLidlGame.State.Character if (Godot.Input.IsActionPressed("attack1")) { - if (Character.Inventory.SelectedItem is not null) + var item = Character.Inventory.SelectedItem; + if (item is not null) { + if (!item.IsUsing) + { + Character.Target = dirToMouse; + } + Character.Target = dirToMouse; Character.UseCurrentItem(); } } diff --git a/State/Weapon/RangedFireState.cs b/State/Weapon/RangedFireState.cs new file mode 100644 index 0000000..bacfc85 --- /dev/null +++ b/State/Weapon/RangedFireState.cs @@ -0,0 +1,37 @@ +using Godot; + +namespace SupaLidlGame.State.Weapon +{ + public partial class RangedFireState : WeaponState + { + [Export] + public Items.Weapons.Ranged Weapon { get; set; } + + [Export] + public RangedIdleState IdleState { get; set; } + + private double _timeLeft = 0; + + public override IState Enter(IState prev) + { + //_timeLeft + _timeLeft = Weapon.UseTime; + Weapon.Attack(); + return null; + } + + public override WeaponState Process(double delta) + { + if ((_timeLeft -= delta) <= 0) + { + return IdleState; + } + return null; + } + + public override void Exit(IState nextState) + { + + } + } +} diff --git a/State/Weapon/RangedIdleState.cs b/State/Weapon/RangedIdleState.cs new file mode 100644 index 0000000..3bdbc91 --- /dev/null +++ b/State/Weapon/RangedIdleState.cs @@ -0,0 +1,22 @@ +using Godot; + +namespace SupaLidlGame.State.Weapon +{ + public partial class RangedIdleState : WeaponState + { + [Export] + public RangedFireState FireState { get; set; } + + public override IState Enter(IState prev) => null; + + public override WeaponState Use() + { + return FireState; + } + + public override void Exit(IState nextState) + { + + } + } +} diff --git a/State/Weapon/SwordState.cs b/State/Weapon/SwordState.cs deleted file mode 100644 index 69a8811..0000000 --- a/State/Weapon/SwordState.cs +++ /dev/null @@ -1,5 +0,0 @@ -using Godot; - -namespace SupaLidlGame.State.Weapon -{ -} diff --git a/State/Weapon/SwordStateMachine.cs b/State/Weapon/SwordStateMachine.cs deleted file mode 100644 index 1d068b6..0000000 --- a/State/Weapon/SwordStateMachine.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Godot; - -namespace SupaLidlGame.State.Weapon -{ -} - -/* - - public void Use() - { - var state = CurrentState.Use(); - if (state is not null) - { - ChangeState(state); - } - } - - public void Process(double delta) - { - var state = CurrentState.Process(delta); - if (state is SwordState s) - { - ChangeState(s); - } - } - - */ diff --git a/State/Weapon/WeaponState.cs b/State/Weapon/WeaponState.cs index fd20588..2a817e3 100644 --- a/State/Weapon/WeaponState.cs +++ b/State/Weapon/WeaponState.cs @@ -6,6 +6,8 @@ namespace SupaLidlGame.State.Weapon { public virtual WeaponState Use() => null; + public virtual WeaponState Deuse() => null; + public abstract IState Enter(IState previousState); public virtual void Exit(IState nextState) diff --git a/State/Weapon/WeaponStateMachine.cs b/State/Weapon/WeaponStateMachine.cs index bc75894..223693b 100644 --- a/State/Weapon/WeaponStateMachine.cs +++ b/State/Weapon/WeaponStateMachine.cs @@ -10,7 +10,16 @@ namespace SupaLidlGame.State.Weapon public void Use() { var state = CurrentState.Use(); - if (state is not null) + if (state is WeaponState) + { + ChangeState(state); + } + } + + public void Deuse() + { + var state = CurrentState.Deuse(); + if (state is WeaponState) { ChangeState(state); } diff --git a/Tests/ProjectileTest.tscn b/Tests/ProjectileTest.tscn new file mode 100644 index 0000000..9dbcef9 --- /dev/null +++ b/Tests/ProjectileTest.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=2 format=3 uid="uid://8hqnkll3x7tr"] + +[ext_resource type="PackedScene" uid="uid://bqvseo3sbs1aj" path="res://Entities/RailBeam.tscn" id="1_os4wy"] + +[node name="Node2D" type="Node2D"] + +[node name="RailBeam" parent="." instance=ExtResource("1_os4wy")] +gravity_scale = 0.0