From 5c8a9cb32be1e2c2c87266bba1786dd8e95cf642 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Tue, 6 Jun 2023 18:39:23 -0700 Subject: [PATCH 01/12] campfire wip --- BoundingBoxes/InteractionReceiver.cs | 70 ++++++++++++++++++++++++++ BoundingBoxes/InteractionReceiver.tscn | 18 +++++++ BoundingBoxes/InteractionTrigger.cs | 7 +++ Characters/Character.cs | 6 +++ Characters/Player.tscn | 6 +-- Events/Args.cs | 8 +++ Events/HealthChangedArgs.cs | 14 ++++++ Extensions/AudioStreamPlayer2D.cs | 1 - State/Character/PlayerState.cs | 6 ++- State/Health/AliveState.cs | 6 +++ State/Health/DeadState.cs | 1 + State/Health/HealthState.cs | 13 +++++ Utils/World.cs | 8 ++- project.godot | 2 + 14 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 BoundingBoxes/InteractionReceiver.cs create mode 100644 BoundingBoxes/InteractionReceiver.tscn create mode 100644 BoundingBoxes/InteractionTrigger.cs create mode 100644 Events/Args.cs create mode 100644 Events/HealthChangedArgs.cs create mode 100644 State/Health/AliveState.cs create mode 100644 State/Health/DeadState.cs create mode 100644 State/Health/HealthState.cs diff --git a/BoundingBoxes/InteractionReceiver.cs b/BoundingBoxes/InteractionReceiver.cs new file mode 100644 index 0000000..c5aba49 --- /dev/null +++ b/BoundingBoxes/InteractionReceiver.cs @@ -0,0 +1,70 @@ +using Godot; +using System.Collections.Generic; + +namespace SupaLidlGame.BoundingBoxes; + +public partial class InteractionReceiver : Area2D +{ + [Signal] + public delegate void TriggerEventHandler( + InteractionTrigger trigger, + InteractionTrigger closestTrigger); + + [Signal] + public delegate void ClosestTriggerEventHandler(InteractionTrigger trigger); + + private InteractionTrigger _closestTrigger; + + private HashSet _triggers; + + public InteractionReceiver() + { + _triggers = new HashSet(); + } + + private void UpdateClosestTrigger() + { + float minDist = float.MaxValue; + InteractionTrigger best = null; + + foreach (var trigger in _triggers) + { + float dist = trigger.GlobalPosition + .DistanceSquaredTo(GlobalPosition); + + if (dist <= minDist) + { + best = trigger; + minDist = dist; + } + } + + if (_closestTrigger != best) + { + EmitSignal(SignalName.ClosestTrigger, best); + _closestTrigger = best; + } + } + + public void _on_area_entered(Area2D area) + { + if (area is InteractionTrigger trigger) + { + EmitSignal(SignalName.Trigger, _closestTrigger); + } + } + + public void _on_area_exited(Area2D area) + { + // update closest trigger + if (area is InteractionTrigger trigger) + { + if (_triggers.Contains(trigger)) + { + _triggers.Remove(trigger); + } + UpdateClosestTrigger(); + } + GD.PushWarning("Area entered is not an InteractionTrigger."); + } +} diff --git a/BoundingBoxes/InteractionReceiver.tscn b/BoundingBoxes/InteractionReceiver.tscn new file mode 100644 index 0000000..a2d86bc --- /dev/null +++ b/BoundingBoxes/InteractionReceiver.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=3 format=3 uid="uid://cdxiutj5jdnvo"] + +[ext_resource type="Script" path="res://BoundingBoxes/InteractionReceiver.cs" id="1_y2pab"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_vcbnn"] +radius = 16.0 + +[node name="InteractionReceiver" type="Area2D"] +collision_layer = 32 +collision_mask = 64 +script = ExtResource("1_y2pab") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("CircleShape2D_vcbnn") +debug_color = Color(0.792157, 0.0705882, 1, 0.419608) + +[connection signal="area_entered" from="." to="." method="_on_area_entered"] +[connection signal="area_exited" from="." to="." method="_on_area_exited"] diff --git a/BoundingBoxes/InteractionTrigger.cs b/BoundingBoxes/InteractionTrigger.cs new file mode 100644 index 0000000..9c45016 --- /dev/null +++ b/BoundingBoxes/InteractionTrigger.cs @@ -0,0 +1,7 @@ +using Godot; + +namespace SupaLidlGame.BoundingBoxes; + +public partial class InteractionTrigger : Area2D +{ +} diff --git a/Characters/Character.cs b/Characters/Character.cs index 74fdbe6..da2d29d 100644 --- a/Characters/Character.cs +++ b/Characters/Character.cs @@ -25,6 +25,12 @@ public partial class Character : CharacterBody2D, IFaction } } + [Signal] + public delegate void HurtEventHandler(Events.HealthChangedArgs args); + + [Signal] + public delegate void DeathEventHandler(Events.HealthChangedArgs args); + protected float _mass = 1.0f; public Vector2 NetImpulse { get; set; } = Vector2.Zero; diff --git a/Characters/Player.tscn b/Characters/Player.tscn index cb23d86..59650ff 100644 --- a/Characters/Player.tscn +++ b/Characters/Player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=30 format=3 uid="uid://b2254pup8k161"] +[gd_scene load_steps=29 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,7 +11,6 @@ [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="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="9_avyu4"] -[ext_resource type="PackedScene" uid="uid://g7wfcubs6bdd" path="res://Items/Weapons/Railgun.tscn" id="10_7kb8b"] [ext_resource type="AudioStream" uid="uid://njun3e6v4854" path="res://Assets/Sounds/hurt.wav" id="12_h0x0g"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"] @@ -209,9 +208,8 @@ InventoryMap = { "equip_2": 1 } -[node name="Railgun" parent="Inventory" instance=ExtResource("10_7kb8b")] - [node name="Node2D" parent="Inventory" instance=ExtResource("7_4rxuv")] +visible = false ShouldHideIdle = false [node name="Hurtbox" parent="." instance=ExtResource("9_avyu4")] diff --git a/Events/Args.cs b/Events/Args.cs new file mode 100644 index 0000000..3deb8b1 --- /dev/null +++ b/Events/Args.cs @@ -0,0 +1,8 @@ +using Godot; + +namespace SupaLidlGame.Events; + +public abstract partial class Args : GodotObject +{ + +} diff --git a/Events/HealthChangedArgs.cs b/Events/HealthChangedArgs.cs new file mode 100644 index 0000000..ae6b957 --- /dev/null +++ b/Events/HealthChangedArgs.cs @@ -0,0 +1,14 @@ +namespace SupaLidlGame.Events; + +public partial class HealthChangedArgs : Args +{ + public Characters.Character Attacker { get; set; } + + public Items.Weapon Weapon { get; set; } + + public float OldHealth { get; set; } + + public float NewHealth { get; set; } + + public float Damage { get; set; } +} diff --git a/Extensions/AudioStreamPlayer2D.cs b/Extensions/AudioStreamPlayer2D.cs index 23339e7..20bdb4d 100644 --- a/Extensions/AudioStreamPlayer2D.cs +++ b/Extensions/AudioStreamPlayer2D.cs @@ -1,6 +1,5 @@ using Godot; using System; -using SupaLidlGame.Utils; namespace SupaLidlGame.Extensions; diff --git a/State/Character/PlayerState.cs b/State/Character/PlayerState.cs index 648d2e7..8476929 100644 --- a/State/Character/PlayerState.cs +++ b/State/Character/PlayerState.cs @@ -15,12 +15,16 @@ public abstract partial class PlayerState : CharacterState var inventory = Character.Inventory; if (this is PlayerIdleState or PlayerMoveState && - !_player.Inventory.IsUsingItem) + !_player.Inventory.IsUsingItem) { if (@event.IsActionPressed("equip_1")) { inventory.SelectedItem = inventory.GetItemByMap("equip_1"); } + else if (@event.IsActionPressed("equip_2")) + { + inventory.SelectedItem = inventory.GetItemByMap("equip_2"); + } } return base.Input(@event); diff --git a/State/Health/AliveState.cs b/State/Health/AliveState.cs new file mode 100644 index 0000000..5cc71dd --- /dev/null +++ b/State/Health/AliveState.cs @@ -0,0 +1,6 @@ +namespace SupaLidlGame.State.Health; + +public partial class AliveState : HealthState +{ + +} diff --git a/State/Health/DeadState.cs b/State/Health/DeadState.cs new file mode 100644 index 0000000..bcf71b1 --- /dev/null +++ b/State/Health/DeadState.cs @@ -0,0 +1 @@ +namespace SupaLidlGame.State.Health; diff --git a/State/Health/HealthState.cs b/State/Health/HealthState.cs new file mode 100644 index 0000000..f0f5ab1 --- /dev/null +++ b/State/Health/HealthState.cs @@ -0,0 +1,13 @@ +using Godot; + +namespace SupaLidlGame.State.Health; + +public abstract partial class HealthState : Node, IState +{ + public virtual IState Enter(IState prev) => null; + + public virtual void Exit(IState next) + { + + } +} diff --git a/Utils/World.cs b/Utils/World.cs index 4ffe2d6..aa7eb4d 100644 --- a/Utils/World.cs +++ b/Utils/World.cs @@ -1,7 +1,6 @@ using Godot; using SupaLidlGame.Characters; using SupaLidlGame.Scenes; -using SupaLidlGame.Extensions; using System.Collections.Generic; using System.Linq; @@ -24,6 +23,8 @@ public partial class World : Node2D private string _currentMapResourcePath; + private Entities.Campfire _lastCampfire = null; + private const string PLAYER_PATH = "res://Characters/Player.tscn"; private PackedScene _playerScene; @@ -43,6 +44,11 @@ public partial class World : Node2D // spawn the player in CreatePlayer(); + CurrentPlayer.Death += (Events.HealthChangedArgs args) => + { + // TODO: respawn the player at the last campfire. + }; + base._Ready(); } diff --git a/project.godot b/project.godot index c2544a1..8bdfda5 100644 --- a/project.godot +++ b/project.godot @@ -89,6 +89,8 @@ equip_3={ 2d_physics/layer_3="Player" 2d_physics/layer_4="NPC" 2d_physics/layer_5="World Clip" +2d_physics/layer_6="Interaction Receiver" +2d_physics/layer_7="Interaction Trigger" [physics] From e586ae0e6dffec504c6a77e9d8a55de7b326ce45 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Sat, 10 Jun 2023 22:15:28 -0700 Subject: [PATCH 02/12] campfire wip 2 --- BoundingBoxes/InteractionRay.cs | 54 ++++++++++++++++++ BoundingBoxes/InteractionReceiver.cs | 62 -------------------- BoundingBoxes/InteractionTrigger.cs | 17 ++++++ Characters/Character.cs | 27 ++++++++- Characters/ExampleEnemy.tscn | 5 +- Characters/Player.cs | 20 ++++++- Characters/Player.tscn | 18 ++++-- Entities/Campfire.cs | 20 +++++-- Entities/Campfire.tscn | 15 ++++- Scenes/Map.cs | 1 - Scenes/Maps/Hills.tscn | 30 ++++++---- State/Character/PlayerState.cs | 10 +++- SupaLidlGame.csproj | 3 + SupaLidlGame.sln | 14 ++--- Utils/IInteractive.cs | 6 ++ Utils/World.cs | 85 +++++++++++++++++++++++----- 16 files changed, 275 insertions(+), 112 deletions(-) create mode 100644 BoundingBoxes/InteractionRay.cs create mode 100644 Utils/IInteractive.cs diff --git a/BoundingBoxes/InteractionRay.cs b/BoundingBoxes/InteractionRay.cs new file mode 100644 index 0000000..8ca963e --- /dev/null +++ b/BoundingBoxes/InteractionRay.cs @@ -0,0 +1,54 @@ +using Godot; + +namespace SupaLidlGame.BoundingBoxes; + +public partial class InteractionRay : RayCast2D +{ + private InteractionTrigger _trigger; + + public InteractionTrigger Trigger + { + get => _trigger; + protected set + { + if (_trigger != value) + { + EmitSignal(SignalName.TriggerHit, value); + } + + if (_trigger is not null) + { + LastValidTrigger = value; + } + + _trigger = value; + } + } + + public InteractionTrigger LastValidTrigger { get; set; } + + [Signal] + public delegate void TriggerHitEventHandler(InteractionTrigger trigger); + + public override void _Ready() + { + + } + + public override void _PhysicsProcess(double delta) + { + if (IsColliding()) + { + var obj = GetCollider(); + // if obj is an InteractionTrigger then we signal hit + if (obj is InteractionTrigger trigger) + { + Trigger = trigger; + } + } + else + { + Trigger = null; + } + } +} diff --git a/BoundingBoxes/InteractionReceiver.cs b/BoundingBoxes/InteractionReceiver.cs index c5aba49..a568339 100644 --- a/BoundingBoxes/InteractionReceiver.cs +++ b/BoundingBoxes/InteractionReceiver.cs @@ -5,66 +5,4 @@ namespace SupaLidlGame.BoundingBoxes; public partial class InteractionReceiver : Area2D { - [Signal] - public delegate void TriggerEventHandler( - InteractionTrigger trigger, - InteractionTrigger closestTrigger); - - [Signal] - public delegate void ClosestTriggerEventHandler(InteractionTrigger trigger); - - private InteractionTrigger _closestTrigger; - - private HashSet _triggers; - - public InteractionReceiver() - { - _triggers = new HashSet(); - } - - private void UpdateClosestTrigger() - { - float minDist = float.MaxValue; - InteractionTrigger best = null; - - foreach (var trigger in _triggers) - { - float dist = trigger.GlobalPosition - .DistanceSquaredTo(GlobalPosition); - - if (dist <= minDist) - { - best = trigger; - minDist = dist; - } - } - - if (_closestTrigger != best) - { - EmitSignal(SignalName.ClosestTrigger, best); - _closestTrigger = best; - } - } - - public void _on_area_entered(Area2D area) - { - if (area is InteractionTrigger trigger) - { - EmitSignal(SignalName.Trigger, _closestTrigger); - } - } - - public void _on_area_exited(Area2D area) - { - // update closest trigger - if (area is InteractionTrigger trigger) - { - if (_triggers.Contains(trigger)) - { - _triggers.Remove(trigger); - } - UpdateClosestTrigger(); - } - GD.PushWarning("Area entered is not an InteractionTrigger."); - } } diff --git a/BoundingBoxes/InteractionTrigger.cs b/BoundingBoxes/InteractionTrigger.cs index 9c45016..1e7b830 100644 --- a/BoundingBoxes/InteractionTrigger.cs +++ b/BoundingBoxes/InteractionTrigger.cs @@ -1,7 +1,24 @@ using Godot; +using SupaLidlGame.Characters; namespace SupaLidlGame.BoundingBoxes; public partial class InteractionTrigger : Area2D { + [Signal] + public delegate void InteractionEventHandler(); + + [Signal] + public delegate void TargetEventHandler(); + + [Signal] + public delegate void UntargetEventHandler(); + + /// + /// Invokes or triggers an interaction to occur. + /// + public void InvokeInteraction() + { + EmitSignal(SignalName.Interaction); + } } diff --git a/Characters/Character.cs b/Characters/Character.cs index da2d29d..9bb77e6 100644 --- a/Characters/Character.cs +++ b/Characters/Character.cs @@ -73,9 +73,17 @@ public partial class Character : CharacterBody2D, IFaction [Export] public CharacterStateMachine StateMachine { get; set; } + [Export] + public BoundingBoxes.Hurtbox Hurtbox { get; set; } + [Export] public ushort Faction { get; set; } + public override void _Ready() + { + Hurtbox.ReceivedDamage += OnReceivedDamage; + } + public override void _Process(double delta) { if (StateMachine != null) @@ -133,7 +141,7 @@ public partial class Character : CharacterBody2D, IFaction StunTime += time; } - protected void DrawTarget() + protected virtual void DrawTarget() { Vector2 target = Target; float angle = Mathf.Atan2(target.Y, Mathf.Abs(target.X)); @@ -173,13 +181,14 @@ public partial class Character : CharacterBody2D, IFaction } } - public virtual void _on_hurtbox_received_damage( + public virtual void OnReceivedDamage( float damage, Character inflictor, float knockback, Vector2 knockbackOrigin = default, Vector2 knockbackVector = default) { + float oldHealth = Health; Health -= damage; // create damage text @@ -225,5 +234,19 @@ public partial class Character : CharacterBody2D, IFaction // very small pitch deviation sound.At(GlobalPosition).WithPitchDeviation(0.125f).Play(); } + + Events.HealthChangedArgs args = new Events.HealthChangedArgs + { + Attacker = inflictor, + OldHealth = oldHealth, + NewHealth = Health, + Damage = damage, + }; + EmitSignal(SignalName.Hurt, args); + + if (Health <= 0) + { + EmitSignal(SignalName.Death, args); + } } } diff --git a/Characters/ExampleEnemy.tscn b/Characters/ExampleEnemy.tscn index cbf1c2e..88734cd 100644 --- a/Characters/ExampleEnemy.tscn +++ b/Characters/ExampleEnemy.tscn @@ -130,7 +130,7 @@ _data = { "RESET": SubResource("Animation_k6l16") } -[node name="ExampleEnemy" type="CharacterBody2D" node_paths=PackedStringArray("Sprite", "Inventory", "StateMachine")] +[node name="ExampleEnemy" type="CharacterBody2D" node_paths=PackedStringArray("Sprite", "Inventory", "StateMachine", "Hurtbox")] y_sort_enabled = true texture_filter = 3 material = SubResource("ShaderMaterial_ms3xg") @@ -141,6 +141,7 @@ Health = 50.0 Sprite = NodePath("Sprite") Inventory = NodePath("Inventory") StateMachine = NodePath("StateMachine") +Hurtbox = NodePath("Hurtbox") Faction = 2 [node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState", "Character")] @@ -191,6 +192,4 @@ libraries = { [node name="HurtSound" type="AudioStreamPlayer2D" parent="."] stream = ExtResource("10_n1e64") -[connection signal="ReceivedDamage" from="Hurtbox" to="." method="_on_hurtbox_received_damage"] - [editable path="Hurtbox"] diff --git a/Characters/Player.cs b/Characters/Player.cs index 755fbab..6ba86b5 100644 --- a/Characters/Player.cs +++ b/Characters/Player.cs @@ -1,9 +1,12 @@ using Godot; +using GodotUtilities; using SupaLidlGame.Utils; +using SupaLidlGame.BoundingBoxes; namespace SupaLidlGame.Characters; -public partial class Player : Character +[Scene] +public sealed partial class Player : Character { private AnimatedSprite2D _sprite; private string _spriteAnim; @@ -11,6 +14,11 @@ public partial class Player : Character [Export] public PlayerCamera Camera { get; set; } + [Export] + public Marker2D DirectionMarker { get; private set; } + + public InteractionRay InteractionRay { get; private set; } + public string Animation { get => _sprite.Animation; @@ -32,11 +40,13 @@ public partial class Player : Character public override void _Ready() { + InteractionRay = GetNode("Direction2D/InteractionRay"); _sprite = GetNode("Sprite"); if (_spriteAnim != default) { _sprite.Animation = _spriteAnim; } + base._Ready(); } public override void ModifyVelocity() @@ -61,4 +71,12 @@ public partial class Player : Character GD.Print("died"); //base.Die(); } + + protected override void DrawTarget() + { + base.DrawTarget(); + DirectionMarker.GlobalRotation = DirectionMarker.GlobalPosition + .DirectionTo(GetGlobalMousePosition()) + .Angle(); + } } diff --git a/Characters/Player.tscn b/Characters/Player.tscn index 59650ff..e4f67b6 100644 --- a/Characters/Player.tscn +++ b/Characters/Player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=29 format=3 uid="uid://b2254pup8k161"] +[gd_scene load_steps=30 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"] @@ -12,6 +12,7 @@ [ext_resource type="Script" path="res://State/Character/PlayerRollState.cs" id="8_fy0v5"] [ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="9_avyu4"] [ext_resource type="AudioStream" uid="uid://njun3e6v4854" path="res://Assets/Sounds/hurt.wav" id="12_h0x0g"] +[ext_resource type="Script" path="res://BoundingBoxes/InteractionRay.cs" id="13_hs3u1"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"] shader = ExtResource("2_ngsgt") @@ -133,19 +134,21 @@ _data = { "RESET": SubResource("Animation_k6l16") } -[node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("Camera", "Sprite", "Inventory", "StateMachine")] +[node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("Camera", "DirectionMarker", "Sprite", "Inventory", "StateMachine", "Hurtbox")] y_sort_enabled = true texture_filter = 3 material = SubResource("ShaderMaterial_h78y7") -position = Vector2(0, -12) +position = Vector2(1, -12) collision_layer = 6 collision_mask = 17 script = ExtResource("1_flygr") Camera = NodePath("Camera2D") +DirectionMarker = NodePath("Direction2D") Speed = 64.0 Sprite = NodePath("Sprite") Inventory = NodePath("Inventory") StateMachine = NodePath("StateMachine") +Hurtbox = NodePath("Hurtbox") Faction = 1 [node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState", "Character")] @@ -231,6 +234,13 @@ max_distance = 64.0 [node name="AudioListener2D" type="AudioListener2D" parent="."] current = true -[connection signal="ReceivedDamage" from="Hurtbox" to="." method="_on_hurtbox_received_damage"] +[node name="Direction2D" type="Marker2D" parent="."] +position = Vector2(0, 6) + +[node name="InteractionRay" type="RayCast2D" parent="Direction2D"] +target_position = Vector2(16, 0) +collision_mask = 64 +collide_with_areas = true +script = ExtResource("13_hs3u1") [editable path="Hurtbox"] diff --git a/Entities/Campfire.cs b/Entities/Campfire.cs index 5572dbb..3e22de4 100644 --- a/Entities/Campfire.cs +++ b/Entities/Campfire.cs @@ -1,23 +1,35 @@ using Godot; -using System; +using GodotUtilities; +using SupaLidlGame.BoundingBoxes; namespace SupaLidlGame.Entities; -public partial class Campfire : StaticBody2D +[Scene] +public partial class Campfire : StaticBody2D, Utils.IInteractive { private PointLight2D _light; + public InteractionTrigger InteractionTrigger { get; set; } + [Signal] - public delegate void OnCampfireUseEventHandler(); + public delegate void UseEventHandler(); public override void _Ready() { + InteractionTrigger = GetNode("InteractionTrigger"); _light = GetNode("PointLight2D"); + InteractionTrigger.Interaction += () => + { + // save the player's spawn position to be their position on interaction + EmitSignal(SignalName.Use); + + this.GetAncestor().SetSpawn(GlobalPosition); + }; } public override void _Process(double delta) { _light.Energy += (GD.Randf() - 0.5f) * 8 * (float)delta; - _light.Energy = Math.Clamp(_light.Energy, 1.2f, 2.0f); + _light.Energy = Mathf.Clamp(_light.Energy, 1.8f, 2f); } } diff --git a/Entities/Campfire.tscn b/Entities/Campfire.tscn index d5c10ce..b42c4c8 100644 --- a/Entities/Campfire.tscn +++ b/Entities/Campfire.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=11 format=3 uid="uid://dhl071rj5wyvx"] +[gd_scene load_steps=13 format=3 uid="uid://dhl071rj5wyvx"] [ext_resource type="Texture2D" uid="uid://yqet0b22i70d" path="res://Assets/Sprites/campfire.png" id="1_7eor7"] [ext_resource type="Script" path="res://Entities/Campfire.cs" id="1_w4gfp"] [ext_resource type="Texture2D" uid="uid://coarr28adgo1u" path="res://Assets/Sprites/Particles/point-light.png" id="3_lm3vq"] +[ext_resource type="Script" path="res://BoundingBoxes/InteractionTrigger.cs" id="4_h1bqe"] [sub_resource type="AtlasTexture" id="AtlasTexture_68qj1"] atlas = ExtResource("1_7eor7") @@ -55,6 +56,9 @@ animations = [{ [sub_resource type="RectangleShape2D" id="RectangleShape2D_ubam4"] size = Vector2(16, 4) +[sub_resource type="RectangleShape2D" id="RectangleShape2D_dfj3a"] +size = Vector2(20, 10) + [node name="Campfire" type="StaticBody2D"] texture_filter = 3 position = Vector2(0, -8) @@ -74,3 +78,12 @@ texture_scale = 0.25 [node name="CollisionShape2D" type="CollisionShape2D" parent="."] position = Vector2(0, 6) shape = SubResource("RectangleShape2D_ubam4") + +[node name="InteractionTrigger" type="Area2D" parent="."] +collision_layer = 64 +collision_mask = 0 +script = ExtResource("4_h1bqe") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="InteractionTrigger"] +position = Vector2(0, 5) +shape = SubResource("RectangleShape2D_dfj3a") diff --git a/Scenes/Map.cs b/Scenes/Map.cs index a51bcdb..f64f2eb 100644 --- a/Scenes/Map.cs +++ b/Scenes/Map.cs @@ -1,5 +1,4 @@ using Godot; -using System; namespace SupaLidlGame.Scenes; diff --git a/Scenes/Maps/Hills.tscn b/Scenes/Maps/Hills.tscn index f1a84a6..0a34a83 100644 --- a/Scenes/Maps/Hills.tscn +++ b/Scenes/Maps/Hills.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=14 format=3 uid="uid://bxtpv6jqodj4v"] +[gd_scene load_steps=15 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="Shader" path="res://Shaders/Flash.gdshader" id="4_mwgaq"] [ext_resource type="PackedScene" uid="uid://5nvn1tw56m8e" path="res://Utils/Spawner.tscn" id="4_pi4df"] +[ext_resource type="PackedScene" uid="uid://dhl071rj5wyvx" path="res://Entities/Campfire.tscn" id="6_r6kxn"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_dvbe3"] texture = ExtResource("2_ote21") @@ -211,31 +212,31 @@ physics_layer_0/collision_mask = 16 physics_layer_1/collision_layer = 1 sources/0 = SubResource("TileSetAtlasSource_dvbe3") -[sub_resource type="ShaderMaterial" id="ShaderMaterial_kq7i3"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_qliqj"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_ck37u"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_xpy5p"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_3i2mi"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_jlmdb"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_trolh"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_pd2a6"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_vuv4g"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_th2v6"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) @@ -251,26 +252,32 @@ layer_4/tile_data = PackedInt32Array(1114105, 196608, 3, 1114106, 262144, 3, 111 layer_5/tile_data = PackedInt32Array(786438, 262144, 3, 720899, 262144, 3, 851971, 458752, 3, 196611, 458752, 3, 1835019, 262144, 3, 1835034, 458752, 3) [node name="ExampleEnemy" parent="Entities" index="0" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_kq7i3") +material = SubResource("ShaderMaterial_qliqj") position = Vector2(169, 115) [node name="ExampleEnemy2" parent="Entities" index="1" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_ck37u") +material = SubResource("ShaderMaterial_xpy5p") position = Vector2(75, 130) [node name="ExampleEnemy3" parent="Entities" index="2" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_3i2mi") +material = SubResource("ShaderMaterial_jlmdb") position = Vector2(140, 177) [node name="ExampleEnemy4" parent="Entities" index="3" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_trolh") +material = SubResource("ShaderMaterial_pd2a6") position = Vector2(14, 159) [node name="ExampleEnemy5" parent="Entities" index="4" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_vuv4g") +material = SubResource("ShaderMaterial_th2v6") position = Vector2(10, 22) Faction = 1 +[node name="Campfire" parent="Entities" index="5" instance=ExtResource("6_r6kxn")] +position = Vector2(155, -27) + +[node name="PointLight2D" parent="Entities/Campfire" index="1"] +color = Color(0.996078, 0.780392, 0.501961, 1) + [node name="Spawner" parent="Spawners" index="0" instance=ExtResource("4_pi4df")] position = Vector2(250, 512) Character = ExtResource("3_hwof6") @@ -279,4 +286,5 @@ SpawnTime = 5.0 [node name="CollisionShape2D" parent="Spawners/Spawner/Area2D" index="0"] shape = SubResource("RectangleShape2D_oods2") +[editable path="Entities/Campfire"] [editable path="Spawners/Spawner"] diff --git a/State/Character/PlayerState.cs b/State/Character/PlayerState.cs index 8476929..ed57644 100644 --- a/State/Character/PlayerState.cs +++ b/State/Character/PlayerState.cs @@ -13,9 +13,10 @@ public abstract partial class PlayerState : CharacterState public override CharacterState Input(InputEvent @event) { var inventory = Character.Inventory; + var player = _player; if (this is PlayerIdleState or PlayerMoveState && - !_player.Inventory.IsUsingItem) + !player.Inventory.IsUsingItem) { if (@event.IsActionPressed("equip_1")) { @@ -25,6 +26,13 @@ public abstract partial class PlayerState : CharacterState { inventory.SelectedItem = inventory.GetItemByMap("equip_2"); } + + if (@event.IsActionPressed("interact")) + { + // if looking at a trigger then interact with it + GD.Print("interacting"); + player.InteractionRay.Trigger?.InvokeInteraction(); + } } return base.Input(@event); diff --git a/SupaLidlGame.csproj b/SupaLidlGame.csproj index c9adce8..e7f1627 100644 --- a/SupaLidlGame.csproj +++ b/SupaLidlGame.csproj @@ -3,4 +3,7 @@ net6.0 true + + + \ No newline at end of file diff --git a/SupaLidlGame.sln b/SupaLidlGame.sln index d222077..f6135a2 100644 --- a/SupaLidlGame.sln +++ b/SupaLidlGame.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SupaLidlGame", "SupaLidlGame.csproj", "{AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SupaLidlGame", "SupaLidlGame.csproj", "{BC071CA6-9462-4CEC-AA20-B0CA618321E5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -9,11 +9,11 @@ Global ExportRelease|Any CPU = ExportRelease|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU - {AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU - {AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU - {AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU + {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU + {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU + {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU + {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU EndGlobalSection EndGlobal diff --git a/Utils/IInteractive.cs b/Utils/IInteractive.cs new file mode 100644 index 0000000..d094081 --- /dev/null +++ b/Utils/IInteractive.cs @@ -0,0 +1,6 @@ +namespace SupaLidlGame.Utils; + +public interface IInteractive +{ + public BoundingBoxes.InteractionTrigger InteractionTrigger { get; set; } +} diff --git a/Utils/World.cs b/Utils/World.cs index aa7eb4d..68c61c0 100644 --- a/Utils/World.cs +++ b/Utils/World.cs @@ -23,7 +23,9 @@ public partial class World : Node2D private string _currentMapResourcePath; - private Entities.Campfire _lastCampfire = null; + //private Entities.Campfire _lastCampfire = null; + public Vector2 SaveLocation { get; set; } + public string SaveMapKey { get; set; } private const string PLAYER_PATH = "res://Characters/Player.tscn"; private PackedScene _playerScene; @@ -47,25 +49,15 @@ public partial class World : Node2D CurrentPlayer.Death += (Events.HealthChangedArgs args) => { // TODO: respawn the player at the last campfire. + SpawnPlayer(); }; base._Ready(); } - public void LoadScene(PackedScene scene) + private void LoadMap(Map map) { - GD.Print("Loading map " + scene.ResourcePath); - - Map map; - if (_maps.ContainsKey(scene.ResourcePath)) - { - map = _maps[scene.ResourcePath]; - } - else - { - map = scene.Instantiate(); - _maps.Add(scene.ResourcePath, map); - } + GD.Print("Loading map " + map.Name); if (CurrentMap is not null) { @@ -86,6 +78,39 @@ public partial class World : Node2D } } + public void LoadScene(PackedScene scene) + { + Map map; + if (_maps.ContainsKey(scene.ResourcePath)) + { + map = _maps[scene.ResourcePath]; + } + else + { + map = scene.Instantiate(); + _maps.Add(scene.ResourcePath, map); + } + + LoadMap(map); + } + + public void LoadScene(string path) + { + Map map; + if (_maps.ContainsKey(path)) + { + map = _maps[path]; + } + else + { + var scene = ResourceLoader.Load(path); + map = scene.Instantiate(); + _maps.Add(scene.ResourcePath, map); + } + + LoadMap(map); + } + public void CreatePlayer() { CurrentPlayer = _playerScene.Instantiate(); @@ -117,7 +142,7 @@ public partial class World : Node2D } return false; }) as BoundingBoxes.ConnectorBox; - + CurrentPlayer.GlobalPosition = connector.GlobalPosition; } @@ -152,4 +177,34 @@ public partial class World : Node2D { throw new System.NotImplementedException(); } + + /// + /// Sets the player's saved spawn position. + /// + /// The position to save and spawn the player in + /// + /// The map to spawn the player in. If , use the + /// World's CurrentMap + /// + public void SetSpawn(Vector2 position, string mapKey = null) + { + GD.Print("Set spawn"); + if (mapKey is null) + { + mapKey = CurrentMap.SceneFilePath; + SaveLocation = position; + SaveMapKey = mapKey; + } + } + + public void SpawnPlayer() + { + // TODO: add max health property + CurrentPlayer.Health = 100; + CurrentPlayer.GlobalPosition = SaveLocation; + if (CurrentMap.SceneFilePath != SaveMapKey) + { + LoadScene(SaveMapKey); + } + } } From 19b8bf362d1f0f0cc1d79ac65554d726643ace7f Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Sun, 11 Jun 2023 15:15:52 -0700 Subject: [PATCH 03/12] roll animation --- Characters/Player.tscn | 50 ++++++++++++++++++++++++++++-- State/Character/PlayerRollState.cs | 17 ++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/Characters/Player.tscn b/Characters/Player.tscn index e4f67b6..519fd5e 100644 --- a/Characters/Player.tscn +++ b/Characters/Player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=30 format=3 uid="uid://b2254pup8k161"] +[gd_scene load_steps=33 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"] @@ -134,6 +134,44 @@ _data = { "RESET": SubResource("Animation_k6l16") } +[sub_resource type="Animation" id="Animation_rx2pj"] +resource_name = "roll" +length = 0.5 +step = 0.05 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.25, 0.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [0.0, 3.14159, 6.28319] +} + +[sub_resource type="Animation" id="Animation_yejx2"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_jai06"] +_data = { +"RESET": SubResource("Animation_yejx2"), +"roll": SubResource("Animation_rx2pj") +} + [node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("Camera", "DirectionMarker", "Sprite", "Inventory", "StateMachine", "Hurtbox")] y_sort_enabled = true texture_filter = 3 @@ -178,8 +216,10 @@ position_smoothing_speed = 8.0 [node name="Sprite" type="AnimatedSprite2D" parent="."] use_parent_material = true +position = Vector2(0, 4) sprite_frames = SubResource("SpriteFrames_2h7cf") animation = &"idle" +offset = Vector2(0, -4) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] position = Vector2(0, 8) @@ -202,10 +242,11 @@ horizontal_alignment = 1 [node name="Node" type="Node" parent="."] -[node name="Inventory" type="Node2D" parent="."] +[node name="Inventory" type="Node2D" parent="." node_paths=PackedStringArray("Items")] y_sort_enabled = true position = Vector2(0, 4) script = ExtResource("7_xyenu") +Items = [] InventoryMap = { "equip_1": 0, "equip_2": 1 @@ -227,6 +268,11 @@ libraries = { "": SubResource("AnimationLibrary_xe5eq") } +[node name="RollAnimation" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_jai06") +} + [node name="HurtSound" type="AudioStreamPlayer2D" parent="."] stream = ExtResource("12_h0x0g") max_distance = 64.0 diff --git a/State/Character/PlayerRollState.cs b/State/Character/PlayerRollState.cs index 57b6c87..d5a3acd 100644 --- a/State/Character/PlayerRollState.cs +++ b/State/Character/PlayerRollState.cs @@ -8,12 +8,28 @@ public partial class PlayerRollState : PlayerState private Vector2 _rollDirection = Vector2.Zero; + private AnimationPlayer _rollAnimation; + + public override void _Ready() + { + _rollAnimation = _player.GetNode("RollAnimation"); + base._Ready(); + } + public override IState Enter(IState previousState) { _timeLeftToRoll = 0.5; // roll the direction we were previously moving in _rollDirection = Character.Direction; Character.Target = Character.Direction; + if (Character.Direction.X >= 0) + { + _rollAnimation.Play("roll"); + } + else + { + _rollAnimation.PlayBackwards("roll"); + } return base.Enter(previousState); } @@ -23,6 +39,7 @@ public partial class PlayerRollState : PlayerState // this state (e.g. from death) _timeLeftToRoll = 0; _rollDirection = Character.Direction; + _rollAnimation.Stop(); base.Exit(nextState); } From 2833e761758fbdb08c236730e7d048cf6c91878d Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Tue, 13 Jun 2023 02:55:30 -0700 Subject: [PATCH 04/12] supa wip --- BoundingBoxes/InteractionTrigger.tscn | 14 +++++++ Characters/Character.cs | 20 +++++----- Characters/NPC.cs | 7 +++- Characters/Player.cs | 18 +++++++++ Characters/Player.tscn | 34 +++++++++++++++- Entities/Campfire.tscn | 57 ++++++++++++++++++++++----- Extensions/AudioStreamPlayer2D.cs | 12 +++++- Extensions/Node.cs | 3 +- Extensions/Node2DExtensions.cs | 29 ++++++++++++++ Extensions/Particles2D.cs | 14 +++++++ Items/Weapons/Railgun.cs | 2 +- Items/Weapons/Sword.cs | 3 +- Scenes/Maps/Hills.tscn | 42 ++++++++++++++------ State/Character/CharacterState.cs | 7 ++++ State/Character/PlayerRollState.cs | 2 +- SupaLidlGame.csproj | 2 +- Utils/Spawner.cs | 1 + Utils/World.cs | 11 ++++-- project.godot | 4 +- 19 files changed, 239 insertions(+), 43 deletions(-) create mode 100644 BoundingBoxes/InteractionTrigger.tscn create mode 100644 Extensions/Particles2D.cs diff --git a/BoundingBoxes/InteractionTrigger.tscn b/BoundingBoxes/InteractionTrigger.tscn new file mode 100644 index 0000000..48e8d89 --- /dev/null +++ b/BoundingBoxes/InteractionTrigger.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=3 format=3 uid="uid://dldnp8eunxj3q"] + +[ext_resource type="Script" path="res://BoundingBoxes/InteractionTrigger.cs" id="1_uoemj"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_dfj3a"] + +[node name="InteractionTrigger" type="Area2D"] +collision_layer = 64 +collision_mask = 0 +script = ExtResource("1_uoemj") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_dfj3a") +debug_color = Color(0.905882, 0, 0.745098, 0.419608) diff --git a/Characters/Character.cs b/Characters/Character.cs index 9bb77e6..12f58e7 100644 --- a/Characters/Character.cs +++ b/Characters/Character.cs @@ -1,4 +1,5 @@ using Godot; +using GodotUtilities; using SupaLidlGame.Extensions; using SupaLidlGame.Items; using SupaLidlGame.Utils; @@ -95,14 +96,6 @@ public partial class Character : CharacterBody2D, IFaction DrawTarget(); } - public override void _Input(InputEvent @event) - { - if (StateMachine != null) - { - StateMachine.Input(@event); - } - } - public override void _PhysicsProcess(double delta) { if (StateMachine != null) @@ -188,6 +181,11 @@ public partial class Character : CharacterBody2D, IFaction Vector2 knockbackOrigin = default, Vector2 knockbackVector = default) { + if (Health <= 0) + { + return; + } + float oldHealth = Health; Health -= damage; @@ -232,7 +230,7 @@ public partial class Character : CharacterBody2D, IFaction if (this.GetNode("HurtSound") is AudioStreamPlayer2D sound) { // very small pitch deviation - sound.At(GlobalPosition).WithPitchDeviation(0.125f).Play(); + sound.At(GlobalPosition).WithPitchDeviation(0.125f).PlayOneShot(); } Events.HealthChangedArgs args = new Events.HealthChangedArgs @@ -242,11 +240,15 @@ public partial class Character : CharacterBody2D, IFaction NewHealth = Health, Damage = damage, }; + EmitSignal(SignalName.Hurt, args); if (Health <= 0) { EmitSignal(SignalName.Death, args); + GetNode("DeathParticles") + .CloneOnWorld() + .EmitOneShot(); } } } diff --git a/Characters/NPC.cs b/Characters/NPC.cs index 1e34d27..96ecb65 100644 --- a/Characters/NPC.cs +++ b/Characters/NPC.cs @@ -92,8 +92,13 @@ public partial class NPC : Character Character bestChar = null; foreach (Node node in GetParent().GetChildren()) { - if (node is Character character && character.Faction != Faction) + if (node is Character character) { + if (character.Faction == Faction || character.Health <= 0) + { + continue; + } + float dist = Position.DistanceTo(character.Position); if (dist < bestDist) { diff --git a/Characters/Player.cs b/Characters/Player.cs index 6ba86b5..1891a2f 100644 --- a/Characters/Player.cs +++ b/Characters/Player.cs @@ -47,6 +47,24 @@ public sealed partial class Player : Character _sprite.Animation = _spriteAnim; } base._Ready(); + Death += (Events.HealthChangedArgs args) => + { + Visible = false; + }; + } + + public override void _Input(InputEvent @event) + { + if (StateMachine != null) + { + StateMachine.Input(@event); + } + } + + public void Spawn() + { + Health = 100; + Visible = true; } public override void ModifyVelocity() diff --git a/Characters/Player.tscn b/Characters/Player.tscn index 519fd5e..b18c399 100644 --- a/Characters/Player.tscn +++ b/Characters/Player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=33 format=3 uid="uid://b2254pup8k161"] +[gd_scene load_steps=37 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"] @@ -172,6 +172,30 @@ _data = { "roll": SubResource("Animation_rx2pj") } +[sub_resource type="Gradient" id="Gradient_3tax5"] +offsets = PackedFloat32Array(0.533333, 1) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_pjeh8"] +gradient = SubResource("Gradient_3tax5") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_humq0"] +emission_shape = 1 +emission_sphere_radius = 1.0 +particle_flag_disable_z = true +direction = Vector3(0, 0, 0) +spread = 180.0 +gravity = Vector3(0, 0, 0) +initial_velocity_min = 32.0 +initial_velocity_max = 32.0 +orbit_velocity_min = 0.0 +orbit_velocity_max = 0.1 +tangential_accel_min = 64.0 +tangential_accel_max = 64.0 +color_ramp = SubResource("GradientTexture1D_pjeh8") + +[sub_resource type="CanvasTexture" id="CanvasTexture_pited"] + [node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("Camera", "DirectionMarker", "Sprite", "Inventory", "StateMachine", "Hurtbox")] y_sort_enabled = true texture_filter = 3 @@ -289,4 +313,12 @@ collision_mask = 64 collide_with_areas = true script = ExtResource("13_hs3u1") +[node name="DeathParticles" type="GPUParticles2D" parent="."] +emitting = false +amount = 16 +process_material = SubResource("ParticleProcessMaterial_humq0") +texture = SubResource("CanvasTexture_pited") +one_shot = true +explosiveness = 0.9 + [editable path="Hurtbox"] diff --git a/Entities/Campfire.tscn b/Entities/Campfire.tscn index b42c4c8..03bf26c 100644 --- a/Entities/Campfire.tscn +++ b/Entities/Campfire.tscn @@ -1,9 +1,9 @@ -[gd_scene load_steps=13 format=3 uid="uid://dhl071rj5wyvx"] +[gd_scene load_steps=18 format=3 uid="uid://dhl071rj5wyvx"] [ext_resource type="Texture2D" uid="uid://yqet0b22i70d" path="res://Assets/Sprites/campfire.png" id="1_7eor7"] [ext_resource type="Script" path="res://Entities/Campfire.cs" id="1_w4gfp"] [ext_resource type="Texture2D" uid="uid://coarr28adgo1u" path="res://Assets/Sprites/Particles/point-light.png" id="3_lm3vq"] -[ext_resource type="Script" path="res://BoundingBoxes/InteractionTrigger.cs" id="4_h1bqe"] +[ext_resource type="PackedScene" uid="uid://dldnp8eunxj3q" path="res://BoundingBoxes/InteractionTrigger.tscn" id="4_yoo3p"] [sub_resource type="AtlasTexture" id="AtlasTexture_68qj1"] atlas = ExtResource("1_7eor7") @@ -56,9 +56,41 @@ animations = [{ [sub_resource type="RectangleShape2D" id="RectangleShape2D_ubam4"] size = Vector2(16, 4) -[sub_resource type="RectangleShape2D" id="RectangleShape2D_dfj3a"] +[sub_resource type="RectangleShape2D" id="RectangleShape2D_p0hsm"] size = Vector2(20, 10) +[sub_resource type="Gradient" id="Gradient_cr0xb"] +offsets = PackedFloat32Array(0, 0.644444, 1) +colors = PackedColorArray(2, 1.6, 0.8, 1, 0.863171, 0.393552, 0.380535, 1, 0.304405, 0.24341, 0.229614, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_pjqf7"] +gradient = SubResource("Gradient_cr0xb") + +[sub_resource type="Curve" id="Curve_jm83f"] +_data = [Vector2(0.144578, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.4), 0.0, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="CurveTexture" id="CurveTexture_jpefi"] +curve = SubResource("Curve_jm83f") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_xtx2m"] +emission_shape = 1 +emission_sphere_radius = 5.0 +particle_flag_disable_z = true +direction = Vector3(0, -1, 0) +spread = 0.0 +gravity = Vector3(0, -16, 0) +initial_velocity_min = 16.0 +initial_velocity_max = 16.0 +orbit_velocity_min = 0.0 +orbit_velocity_max = 0.0 +radial_accel_min = -40.0 +radial_accel_max = -20.0 +scale_min = 2.0 +scale_max = 4.0 +scale_curve = SubResource("CurveTexture_jpefi") +color_ramp = SubResource("GradientTexture1D_pjqf7") + [node name="Campfire" type="StaticBody2D"] texture_filter = 3 position = Vector2(0, -8) @@ -66,12 +98,14 @@ script = ExtResource("1_w4gfp") [node name="Sprite2D" type="AnimatedSprite2D" parent="."] sprite_frames = SubResource("SpriteFrames_o6lfi") -frame_progress = 0.387757 +animation = &"active" +frame_progress = 0.343741 [node name="PointLight2D" type="PointLight2D" parent="."] color = Color(0.996078, 0.780392, 0.615686, 1) energy = 2.0 blend_mode = 2 +shadow_enabled = true texture = ExtResource("3_lm3vq") texture_scale = 0.25 @@ -79,11 +113,14 @@ texture_scale = 0.25 position = Vector2(0, 6) shape = SubResource("RectangleShape2D_ubam4") -[node name="InteractionTrigger" type="Area2D" parent="."] -collision_layer = 64 -collision_mask = 0 -script = ExtResource("4_h1bqe") +[node name="InteractionTrigger" parent="." instance=ExtResource("4_yoo3p")] -[node name="CollisionShape2D" type="CollisionShape2D" parent="InteractionTrigger"] +[node name="CollisionShape2D" parent="InteractionTrigger" index="0"] position = Vector2(0, 5) -shape = SubResource("RectangleShape2D_dfj3a") +shape = SubResource("RectangleShape2D_p0hsm") + +[node name="GPUParticles2D" type="GPUParticles2D" parent="."] +amount = 40 +process_material = SubResource("ParticleProcessMaterial_xtx2m") + +[editable path="InteractionTrigger"] diff --git a/Extensions/AudioStreamPlayer2D.cs b/Extensions/AudioStreamPlayer2D.cs index 20bdb4d..0258eb3 100644 --- a/Extensions/AudioStreamPlayer2D.cs +++ b/Extensions/AudioStreamPlayer2D.cs @@ -1,4 +1,5 @@ using Godot; +using GodotUtilities; using System; namespace SupaLidlGame.Extensions; @@ -43,7 +44,7 @@ public static class AudioStreamPlayer2DExtensions this AudioStreamPlayer2D audio, Vector2 globalPosition) { - var world = audio.GetTree().Root.GetNode("World/TileMap"); + var world = audio.GetAncestor(); if (world is null) { throw new NullReferenceException("World does not exist"); @@ -61,6 +62,15 @@ public static class AudioStreamPlayer2DExtensions return clone; } + public static AudioStreamPlayer2D PlayOneShot( + this AudioStreamPlayer2D audio, + float fromPosition = 0) + { + audio.Finished += () => audio.QueueFree(); + audio.Play(fromPosition); + return audio; + } + public static AudioStreamPlayer2D WithPitchDeviation( this AudioStreamPlayer2D audio, float deviation) diff --git a/Extensions/Node.cs b/Extensions/Node.cs index ee52e80..cf7191c 100644 --- a/Extensions/Node.cs +++ b/Extensions/Node.cs @@ -8,7 +8,8 @@ public static class NodeExtensions /// Iterates through each ancestor until it finds an ancestor of type /// T /// - public static T GetAncestor(this Node node) where T : Node + [System.Obsolete] + public static T GetAncestorDeprecated(this Node node) where T : Node { Node parent; diff --git a/Extensions/Node2DExtensions.cs b/Extensions/Node2DExtensions.cs index 694fb45..ab70549 100644 --- a/Extensions/Node2DExtensions.cs +++ b/Extensions/Node2DExtensions.cs @@ -1,4 +1,5 @@ using Godot; +using GodotUtilities; namespace SupaLidlGame.Extensions; @@ -9,4 +10,32 @@ public static class Node2DExtensions //var spaceState = node.GetWorld2d().DirectSpaceState; //var result = spaceState.IntersectRay(); } + + public static Node CloneOnWorld(this Node2D node) + { + return CloneOnWorld(node); + } + + public static T CloneOnWorld(this Node2D node) where T : Node2D + { + var world = node.GetAncestor(); + if (world is null) + { + throw new System.NullReferenceException("World does not exist"); + } + + //var parent = new Node2D(); + //world.AddChild(parent); + //parent.GlobalPosition = node.GlobalPosition; + var clone = node.Duplicate() as T; + world.AddChild(clone); + clone.GlobalPosition = node.GlobalPosition; + return clone; + } + + public static Node AtPosition(this Node2D node, Vector2 position) + { + node.GlobalPosition = position; + return node; + } } diff --git a/Extensions/Particles2D.cs b/Extensions/Particles2D.cs new file mode 100644 index 0000000..fb76d57 --- /dev/null +++ b/Extensions/Particles2D.cs @@ -0,0 +1,14 @@ +using Godot; + +namespace SupaLidlGame.Extensions; + +public static class Particles2D +{ + public static void EmitOneShot(this GpuParticles2D particles) + { + particles.GetTree().CreateTimer(particles.Lifetime).Timeout += () => + { + particles.QueueFree(); + }; + } +} diff --git a/Items/Weapons/Railgun.cs b/Items/Weapons/Railgun.cs index 4ebed2a..d6f93d0 100644 --- a/Items/Weapons/Railgun.cs +++ b/Items/Weapons/Railgun.cs @@ -1,5 +1,5 @@ using Godot; -using SupaLidlGame.Extensions; +using GodotUtilities; namespace SupaLidlGame.Items.Weapons; diff --git a/Items/Weapons/Sword.cs b/Items/Weapons/Sword.cs index 826116a..12a719d 100644 --- a/Items/Weapons/Sword.cs +++ b/Items/Weapons/Sword.cs @@ -1,4 +1,5 @@ using Godot; +using GodotUtilities; using SupaLidlGame.BoundingBoxes; using SupaLidlGame.Characters; using SupaLidlGame.Extensions; @@ -197,7 +198,7 @@ public partial class Sword : Weapon, IParryable IsParried = true; AnimationPlayer.SpeedScale = 0.25f; Character.Stun(1.5f); - GetNode("ParrySound").OnWorld().Play(); + GetNode("ParrySound").OnWorld().PlayOneShot(); } public override void _on_hitbox_hit(BoundingBox box) diff --git a/Scenes/Maps/Hills.tscn b/Scenes/Maps/Hills.tscn index 0a34a83..4fe0066 100644 --- a/Scenes/Maps/Hills.tscn +++ b/Scenes/Maps/Hills.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=15 format=3 uid="uid://bxtpv6jqodj4v"] +[gd_scene load_steps=18 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"] @@ -212,31 +212,31 @@ physics_layer_0/collision_mask = 16 physics_layer_1/collision_layer = 1 sources/0 = SubResource("TileSetAtlasSource_dvbe3") -[sub_resource type="ShaderMaterial" id="ShaderMaterial_qliqj"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_3sxqg"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_xpy5p"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_r3w8l"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_jlmdb"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_2oi7o"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_pd2a6"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_65pfr"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_th2v6"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_5a7w6"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) @@ -245,6 +245,22 @@ shader_parameter/intensity = 0.0 [sub_resource type="RectangleShape2D" id="RectangleShape2D_oods2"] size = Vector2(128, 64) +[sub_resource type="Gradient" id="Gradient_rg6hp"] +colors = PackedColorArray(0.941579, 6.06447e-06, 0.603405, 1, 1, 1, 1, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_pdu88"] +gradient = SubResource("Gradient_rg6hp") + +[sub_resource type="Environment" id="Environment_c0b2h"] +background_mode = 3 +glow_enabled = true +glow_intensity = 1.2 +glow_strength = 0.8 +glow_bloom = 0.1 +glow_blend_mode = 0 +adjustment_enabled = true +adjustment_color_correction = SubResource("GradientTexture1D_pdu88") + [node name="TileMap" instance=ExtResource("1_vly6f")] tile_set = SubResource("TileSet_7f7fo") layer_3/tile_data = PackedInt32Array(786426, 262144, 1, 851962, 262144, 1, 917498, 262144, 1, 983034, 262144, 1, 786427, 262144, 1, 851963, 262144, 1, 917499, 262144, 1, 983035, 262144, 1, 786428, 262144, 1, 851964, 262144, 1, 917500, 262144, 1, 983036, 262144, 1, 786429, 262144, 1, 851965, 262144, 1, 917501, 262144, 1, 983037, 262144, 1, 786430, 262144, 1, 851966, 262144, 1, 917502, 262144, 1, 983038, 262144, 1, 786431, 262144, 1, 851967, 262144, 1, 917503, 262144, 1, 983039, 262144, 1, 720896, 262144, 1, 786432, 262144, 1, 851968, 262144, 1, 917504, 262144, 1, 1048573, 262144, 1, 1048574, 262144, 1, 1048575, 262144, 1, 983040, 262144, 1, 1048576, 262144, 1, 1114112, 262144, 1, 1179647, 262144, 1, 1179646, 262144, 1, 1179645, 262144, 1, 1114109, 262144, 1, 1114110, 262144, 1, 1114111, 262144, 1, 1245183, 262144, 1, 1310719, 262144, 1, 1376255, 262144, 1, 1310720, 131072, 3, 1376256, 262144, 1, 1441791, 262144, 1, 1245184, 131072, 3, 1179648, 131072, 3, 1179649, 131072, 3, 1179650, 131072, 3, 1179651, 131072, 3, 1114115, 262144, 1, 1114114, 262144, 1, 1114113, 262144, 1, 1114116, 262144, 1, 1114117, 262144, 1, 1114118, 262144, 1, 1114119, 262144, 1, 1114120, 262144, 1, 1114121, 262144, 1, 1114122, 262144, 1, 1114123, 262144, 1, 1179659, 262144, 1, 1245195, 262144, 1, 1310731, 262144, 1, 1376266, 262144, 1, 1376265, 262144, 1, 1376264, 262144, 1, 1376263, 262144, 1, 1376262, 262144, 1, 1376261, 262144, 1, 1376260, 262144, 1, 1376259, 131072, 3, 1376258, 131072, 3, 1376257, 262144, 1, 1310721, 131072, 3, 1245185, 131072, 4, 1245186, 131072, 4, 1310722, 131072, 3, 1245187, 131072, 3, 1179652, 262144, 1, 1179653, 262144, 1, 1179654, 262144, 1, 1179655, 262144, 1, 1179656, 262144, 1, 1179657, 262144, 1, 1179658, 262144, 1, 1376267, 262144, 1, 1310728, 262144, 1, 1310727, 262144, 1, 1310726, 262144, 1, 1310725, 131072, 3, 1310724, 131072, 3, 1310723, 131072, 3, 1245188, 131072, 3, 1245189, 131072, 3, 1245190, 262144, 1, 1245191, 262144, 1, 1245192, 262144, 1, 1245193, 262144, 1, 1245194, 262144, 1, 1310730, 262144, 1, 1310729, 262144, 1, 524285, 262144, 1, 589821, 262144, 1, 655357, 262144, 1, 720893, 262144, 1, 720894, 262144, 1, 655358, 131072, 3, 589822, 262144, 1, 524286, 262144, 1, 524287, 262144, 1, 458752, 262144, 1, 458753, 262144, 1, 458754, 262144, 1, 458755, 262144, 1, 458756, 262144, 1, 458757, 262144, 1, 458758, 262144, 1, 458759, 262144, 1, 458760, 262144, 1, 458764, 262144, 1, 524300, 262144, 1, 589836, 262144, 1, 655372, 262144, 1, 720908, 262144, 1, 786444, 131072, 3, 851980, 131072, 4, 851981, 131072, 4, 851982, 262144, 1, 786446, 262144, 1, 720910, 262144, 1, 720909, 262144, 1, 786445, 262144, 1, 851979, 131072, 4, 851978, 262144, 1, 851977, 262144, 1, 851976, 262144, 1, 851975, 262144, 1, 786439, 262144, 1, 786440, 262144, 1, 786441, 262144, 1, 786442, 131072, 3, 786443, 131072, 3, 720907, 262144, 1, 655371, 262144, 1, 589834, 131072, 3, 524298, 262144, 1, 524297, 131072, 3, 524294, 262144, 1, 524293, 262144, 1, 524292, 262144, 1, 524291, 262144, 1, 524290, 262144, 1, 524289, 131072, 3, 524288, 131072, 3, 589824, 131072, 3, 655359, 131072, 4, 720895, 131072, 3, 589823, 131072, 3, 655360, 131072, 3, 655361, 131072, 3, 655362, 131072, 3, 655363, 262144, 1, 655364, 262144, 1, 655366, 262144, 1, 655367, 131072, 3, 655368, 131072, 3, 655369, 131072, 3, 655370, 131072, 3, 720906, 262144, 1, 720905, 262144, 1, 720904, 262144, 1, 720903, 262144, 1, 720902, 262144, 1, 720901, 262144, 1, 720900, 262144, 1, 589828, 262144, 1, 589827, 262144, 1, 589826, 262144, 1, 589825, 131072, 3, 589829, 262144, 1, 589832, 131072, 4, 589833, 131072, 4, 589835, 131072, 3, 524299, 262144, 1, 393220, 262144, 1, 393221, 262144, 1, 393222, 262144, 1, 393223, 262144, 1, 393224, 262144, 1, 393225, 262144, 1, 393226, 262144, 1, 393227, 262144, 1, 393229, 262144, 1, 393230, 262144, 1, 327694, 262144, 1, 327692, 262144, 1, 327691, 262144, 1, 262155, 262144, 1, 262156, 262144, 1, 196621, 131072, 4, 196622, 262144, 1, 262157, 262144, 1, -131063, 262144, 1, -65527, 262144, 1, -65526, 262144, 1, 9, 262144, 1, -131062, 262144, 1, -131061, 262144, 1, -65525, 262144, 1, 10, 262144, 1, 11, 131072, 3, 65547, 262144, 1, 131083, 262144, 1, 196619, 262144, 1, 196620, 262144, 1, 131084, 131072, 3, 131085, 131072, 4, 65549, 131072, 4, 13, 131072, 3, 12, 131072, 3, -65524, 131072, 3, -131060, 262144, 1, -131059, 262144, 1, -131058, 262144, 1, -65522, 262144, 1, 14, 262144, 1, 65550, 262144, 1, 131086, 262144, 1, -65523, 262144, 1, 65548, 131072, 3, 8, 262144, 1, 7, 262144, 1, 6, 262144, 1, 5, 262144, 1, 4, 262144, 1, 3, 131072, 3, 2, 131072, 3, 1, 131072, 3, 0, 131072, 3, 65535, 262144, 1, 65534, 262144, 1, 65533, 262144, 1, -3, 262144, 1, -2, 262144, 1, -1, 262144, 1, -65536, 262144, 1, -65535, 262144, 1, -65534, 262144, 1, 65538, 262144, 1, 65537, 131072, 3, 65536, 131072, 3, 131071, 262144, 1, 131070, 262144, 1, 131069, 262144, 1, 720889, 196608, 0, 786425, 196608, 1, 851961, 196608, 1, 917497, 196608, 1, 983033, 196608, 1, 1048569, 196608, 2, 720890, 262144, 0, 1048570, 262144, 2, 720891, 262144, 0, 1048571, 262144, 2, -65540, 196608, 0, -4, 196608, 1, 65532, 196608, 1, 131068, 196608, 1, 196604, 196608, 2, 458748, 196608, 0, 524284, 196608, 1, 589820, 196608, 1, 655356, 196608, 1, 720892, 65536, 4, 1048572, 65536, 3, 1114108, 196608, 1, 1179644, 196608, 1, 1245180, 196608, 2, -65539, 262144, 0, 196605, 262144, 2, 458749, 262144, 0, 1245181, 262144, 2, -65538, 262144, 0, 196606, 262144, 2, 458750, 262144, 0, 1245182, 65536, 3, 1310718, 196608, 1, 1376254, 196608, 1, 1441790, 196608, 1, 1507326, 196608, 2, -65537, 262144, 0, 196607, 262144, 2, 458751, 262144, 0, 1507327, 262144, 2, -131072, 262144, 0, 131072, 262144, 2, 393216, 262144, 0, 1441792, 262144, 2, -131071, 262144, 0, 131073, 262144, 2, 393217, 262144, 0, 720897, 0, 3, 786433, 327680, 1, 851969, 327680, 1, 917505, 327680, 1, 983041, 327680, 1, 1048577, 0, 4, 1441793, 262144, 2, -131070, 262144, 0, 131074, 262144, 2, 393218, 262144, 0, 720898, 262144, 2, 1048578, 262144, 0, 1441794, 262144, 2, -131069, 327680, 0, -65533, 0, 4, 65539, 0, 3, 131075, 327680, 2, 327683, 196608, 0, 393219, 65536, 4, 720899, 65536, 3, 786435, 196608, 2, 1048579, 262144, 0, 1441795, 262144, 2, -65532, 262144, 0, 65540, 262144, 2, 327684, 262144, 0, 786436, 262144, 2, 1048580, 262144, 0, 1441796, 262144, 2, -65531, 262144, 0, 65541, 262144, 2, 327685, 262144, 0, 786437, 262144, 2, 1048581, 262144, 0, 1441797, 262144, 2, -65530, 262144, 0, 65542, 262144, 2, 327686, 262144, 0, 786438, 65536, 3, 851974, 196608, 1, 917510, 196608, 2, 1048582, 262144, 0, 1441798, 262144, 2, -65529, 262144, 0, 65543, 262144, 2, 327687, 262144, 0, 917511, 262144, 2, 1048583, 262144, 0, 1441799, 65536, 3, -196600, 196608, 0, -131064, 196608, 1, -65528, 65536, 4, 65544, 262144, 2, 327688, 262144, 0, 917512, 262144, 2, 1048584, 262144, 0, 1441800, 262144, 1, -196599, 262144, 0, 65545, 262144, 2, 327689, 262144, 0, 917513, 262144, 2, 1048585, 262144, 0, 1441801, 262144, 1, -196598, 262144, 0, 65546, 65536, 3, 131082, 196608, 1, 196618, 196608, 1, 262154, 196608, 1, 327690, 65536, 4, 917514, 262144, 2, 1048586, 262144, 0, 1441802, 262144, 1, -196597, 262144, 0, 917515, 262144, 2, 1048587, 262144, 0, 1441803, 262144, 1, -196596, 262144, 0, 917516, 262144, 2, 1048588, 327680, 0, 1114124, 327680, 1, 1179660, 327680, 1, 1245196, 327680, 1, 1310732, 327680, 1, 1376268, 0, 4, 1441804, 262144, 1, -196595, 262144, 0, 458765, 0, 3, 524301, 327680, 1, 589837, 327680, 1, 655373, 0, 4, 917517, 262144, 2, -196594, 262144, 0, 458766, 262144, 2, 655374, 262144, 0, 917518, 262144, 2, -196593, 327680, 0, -131057, 327680, 1, -65521, 327680, 1, 15, 0, 4, 65551, 262144, 1, 131087, 262144, 1, 196623, 262144, 1, 327695, 262144, 1, 393231, 0, 3, 458767, 327680, 2, 655375, 327680, 0, 720911, 327680, 1, 786447, 327680, 1, 851983, 327680, 1, 917519, 327680, 2, 262159, 262144, 1, 262158, 262144, 1, 327693, 262144, 1, 393228, 262144, 1, 458763, 262144, 1, 458762, 262144, 1, 458761, 262144, 1, 524296, 131072, 3, 524295, 131072, 3, 589831, 131072, 3, 589830, 131072, 3, 655365, 262144, 1, 851989, 262144, 1, 917525, 262144, 1, 983061, 262144, 1, 1048597, 262144, 1, 1114133, 262144, 1, 1179669, 262144, 1, 1245205, 262144, 1, 1310741, 262144, 1, 1376277, 262144, 1, 1441813, 262144, 1, 1507349, 262144, 1, 1572885, 262144, 1, 1638421, 262144, 1, 851990, 262144, 1, 917526, 262144, 1, 983062, 262144, 1, 1048598, 262144, 1, 1114134, 262144, 1, 1179670, 262144, 1, 1245206, 262144, 1, 1310742, 262144, 1, 1376278, 262144, 1, 1441814, 262144, 1, 1507350, 262144, 1, 1572886, 262144, 1, 1638422, 262144, 1, 851991, 262144, 1, 917527, 262144, 1, 983063, 262144, 1, 1048599, 262144, 1, 1114135, 262144, 1, 1179671, 262144, 1, 1245207, 262144, 1, 1310743, 262144, 1, 1376279, 262144, 1, 1441815, 262144, 1, 1507351, 262144, 1, 1572887, 262144, 1, 1638423, 262144, 1, 851992, 262144, 1, 917528, 262144, 1, 983064, 262144, 1, 1048600, 262144, 1, 1114136, 262144, 1, 1179672, 262144, 1, 1245208, 262144, 1, 1310744, 262144, 1, 1376280, 262144, 1, 1441816, 262144, 1, 1507352, 262144, 1, 1572888, 262144, 1, 1638424, 262144, 1, 851993, 262144, 1, 917529, 262144, 1, 983065, 262144, 1, 1048601, 262144, 1, 1114137, 262144, 1, 1179673, 262144, 1, 1245209, 262144, 1, 1310745, 262144, 1, 1376281, 262144, 1, 1441817, 262144, 1, 1507353, 262144, 1, 1572889, 262144, 1, 1638425, 262144, 1, 851994, 262144, 1, 917530, 262144, 1, 983066, 262144, 1, 1048602, 262144, 1, 1114138, 262144, 1, 1179674, 262144, 1, 1245210, 262144, 1, 1310746, 262144, 1, 1376282, 262144, 1, 1441818, 262144, 1, 1507354, 262144, 1, 1572890, 262144, 1, 1638426, 262144, 1, 851995, 262144, 1, 917531, 262144, 1, 983067, 262144, 1, 1048603, 262144, 1, 1114139, 262144, 1, 1179675, 262144, 1, 1245211, 262144, 1, 1310747, 262144, 1, 1376283, 262144, 1, 1441819, 262144, 1, 1507355, 262144, 1, 1572891, 262144, 1, 1638427, 262144, 1, 851996, 262144, 1, 917532, 262144, 1, 983068, 262144, 1, 1048604, 262144, 1, 1114140, 262144, 1, 1179676, 262144, 1, 1245212, 262144, 1, 1310748, 262144, 1, 1376284, 262144, 1, 1441820, 262144, 1, 1507356, 262144, 1, 1572892, 262144, 1, 1638428, 262144, 1, 65555, 262144, 1, 131091, 262144, 1, 196627, 262144, 1, 262163, 262144, 1, 327699, 262144, 1, 65556, 262144, 1, 131092, 262144, 1, 196628, 262144, 1, 262164, 262144, 1, 327700, 262144, 1, 65557, 262144, 1, 131093, 262144, 1, 196629, 262144, 1, 262165, 262144, 1, 327701, 262144, 1, 65558, 262144, 1, 131094, 262144, 1, 196630, 262144, 1, 262166, 262144, 1, 327702, 262144, 1, 65559, 262144, 1, 131095, 262144, 1, 196631, 262144, 1, 262167, 262144, 1, 327703, 262144, 1, 65560, 262144, 1, 131096, 262144, 1, 196632, 262144, 1, 262168, 262144, 1, 327704, 262144, 1, 65561, 262144, 1, 131097, 262144, 1, 196633, 262144, 1, 262169, 262144, 1, 327705, 262144, 1, 393237, 262144, 1, 458773, 262144, 1, 524309, 262144, 1, 589845, 262144, 1, 655381, 262144, 1, 720917, 262144, 1, 786453, 262144, 1, 393238, 262144, 1, 458774, 262144, 1, 524310, 262144, 1, 589846, 262144, 1, 655382, 262144, 1, 720918, 262144, 1, 786454, 262144, 1, 393239, 262144, 1, 458775, 262144, 1, 524311, 262144, 1, 589847, 262144, 1, 655383, 262144, 1, 720919, 262144, 1, 786455, 262144, 1, 393240, 262144, 1, 458776, 262144, 1, 524312, 262144, 1, 589848, 262144, 1, 655384, 262144, 1, 720920, 262144, 1, 786456, 262144, 1, 393241, 262144, 1, 458777, 262144, 1, 524313, 262144, 1, 589849, 262144, 1, 655385, 262144, 1, 720921, 262144, 1, 786457, 262144, 1, 65552, 262144, 1, 131088, 262144, 1, 196624, 262144, 1, 262160, 262144, 1, 327696, 262144, 1, 65553, 262144, 1, 131089, 262144, 1, 196625, 262144, 1, 262161, 262144, 1, 327697, 262144, 1, 65554, 262144, 1, 131090, 262144, 1, 196626, 262144, 1, 262162, 262144, 1, 327698, 262144, 1, 1507336, 262144, 1, 1572872, 262144, 1, 1638408, 262144, 1, 1507337, 262144, 1, 1572873, 262144, 1, 1638409, 262144, 1, 1507338, 262144, 1, 1572874, 262144, 1, 1638410, 262144, 1, 1507339, 262144, 1, 1572875, 262144, 1, 1638411, 262144, 1, 1507340, 262144, 1, 1572876, 262144, 1, 1638412, 262144, 1, 1441805, 262144, 1, 1507341, 262144, 1, 1572877, 262144, 1, 1638413, 262144, 1, 1441806, 262144, 1, 1507342, 262144, 1, 1572878, 262144, 1, 1638414, 262144, 1, 1441807, 262144, 1, 1507343, 262144, 1, 1572879, 262144, 1, 1638415, 262144, 1, 1441808, 262144, 1, 1507344, 262144, 1, 1572880, 262144, 1, 1638416, 262144, 1, 1441809, 262144, 1, 1507345, 262144, 1, 1572881, 262144, 1, 1638417, 262144, 1, 1441810, 262144, 1, 1507346, 262144, 1, 1572882, 262144, 1, 1638418, 262144, 1, 1441811, 262144, 1, 1507347, 262144, 1, 1572883, 262144, 1, 1638419, 262144, 1, 1441812, 262144, 1, 1507348, 262144, 1, 1572884, 262144, 1, 1638420, 262144, 1, 1507335, 196608, 1, 1572871, 196608, 1, 1638407, 196608, 1, 1703944, 262144, 2, 1703945, 262144, 2, 1703946, 65536, 3, 1703947, 262144, 1, 1703948, 262144, 1, 1703949, 262144, 1, 1703950, 262144, 1, 1703951, 262144, 1, 1703952, 262144, 1, 1703953, 262144, 1, 1703954, 262144, 1, 1703955, 262144, 1, 1703956, 262144, 1, 1703957, 262144, 1, 1703958, 262144, 1, 1703959, 262144, 1, 1703960, 262144, 1, 1703961, 262144, 1, 1703962, 0, 3, 1703963, 262144, 2, 1703964, 262144, 2, 1703965, 327680, 2, 1114141, 327680, 1, 1179677, 327680, 1, 1245213, 327680, 1, 1310749, 327680, 1, 1376285, 327680, 1, 1441821, 327680, 1, 1507357, 327680, 1, 1572893, 327680, 1, 1638429, 327680, 1, 851997, 327680, 1, 917533, 327680, 1, 983069, 327680, 1, 1048605, 327680, 1, 65562, 327680, 1, 131098, 327680, 1, 196634, 327680, 1, 262170, 327680, 1, 327706, 327680, 1, 393242, 327680, 1, 458778, 327680, 1, 524314, 327680, 1, 589850, 327680, 1, 655386, 327680, 1, 720922, 327680, 1, 786458, 0, 4, 786459, 262144, 0, 786460, 262144, 0, 786461, 327680, 0, 16, 262144, 0, 17, 262144, 0, 18, 262144, 0, 19, 262144, 0, 20, 262144, 0, 21, 262144, 0, 22, 262144, 0, 23, 262144, 0, 24, 262144, 0, 25, 262144, 0, 26, 327680, 0, 393236, 65536, 3, 393232, 262144, 2, 393233, 262144, 2, 393234, 262144, 2, 393235, 262144, 2, 458772, 196608, 1, 524308, 196608, 1, 589844, 196608, 1, 655380, 196608, 1, 720916, 196608, 1, 786452, 196608, 1, 851988, 196608, 1, 917524, 196608, 1, 983060, 196608, 1, 1048596, 196608, 1, 1114132, 196608, 1, 1179668, 196608, 1, 1245204, 196608, 1, 1310740, 196608, 1, 1376276, 65536, 4, 1376269, 262144, 0, 1376270, 262144, 0, 1376271, 262144, 0, 1376272, 262144, 0, 1376273, 262144, 0, 1376274, 262144, 0, 1376275, 262144, 0, 1769484, 262144, 1, 1769485, 262144, 1, 1769486, 262144, 1, 1769487, 262144, 1, 1769488, 262144, 1, 1769489, 262144, 1, 1769490, 262144, 1, 1769491, 262144, 1, 1769492, 262144, 1, 1769493, 262144, 1, 1769494, 262144, 1, 1835022, 262144, 1, 1835023, 262144, 1, 1835024, 262144, 1, 1835025, 262144, 1, 1769483, 65536, 3, 1835021, 65536, 3, 1835026, 0, 3, 1769495, 0, 3, 1900562, 262144, 1, 1835031, 327680, 2, 1900557, 262144, 1, 1835019, 196608, 2, 1769482, 196608, 2, 1835020, 262144, 2, 1900560, 262144, 1, 1900561, 262144, 1, 1835027, 262144, 2, 1835028, 262144, 2, 1835029, 262144, 2, 1835030, 262144, 2, 1769496, 262144, 2, 1769497, 262144, 2, 1769498, 327680, 2, 1835016, 262144, 0, 1835017, 262144, 0, 1835018, 262144, 0, 1900552, 262144, 1, 1900553, 262144, 1, 1900554, 262144, 1, 1900555, 262144, 1, 1900556, 262144, 1, 1966088, 262144, 1, 1966089, 262144, 1, 1966090, 262144, 1, 1966091, 262144, 1, 1966092, 262144, 1, 1966093, 262144, 1, 1966094, 262144, 1, 1966095, 262144, 1, 1966096, 262144, 1, 1966097, 262144, 1, 1966098, 262144, 1, 1966099, 262144, 1, 1966100, 262144, 1, 1966101, 262144, 1, 1900563, 262144, 1, 1900564, 262144, 1, 1900565, 262144, 1, 1900566, 262144, 1, 1900567, 262144, 1, 1966102, 262144, 1, 1966103, 262144, 1, 1835032, 262144, 1, 1900568, 262144, 1, 1966104, 262144, 1, 2031626, 262144, 1, 2031627, 262144, 1, 2031628, 262144, 1, 2031629, 262144, 1, 2031630, 262144, 1, 2031631, 262144, 1, 2031632, 262144, 1, 2031633, 262144, 1, 2031634, 262144, 1, 2031635, 262144, 1, 2031636, 262144, 1, 2097172, 262144, 1, 2097171, 262144, 1, 2097170, 262144, 1, 2097169, 262144, 1, 2097168, 262144, 1, 2097167, 262144, 1, 2097166, 262144, 1, 2097165, 262144, 1, 2097164, 262144, 1, 2097163, 262144, 1, 2097162, 262144, 1, 2031637, 262144, 1, 2097173, 262144, 1, 2097174, 262144, 1, 2031638, 262144, 1, 2031639, 262144, 1, 2097175, 262144, 1, 2097176, 262144, 1, 2031640, 262144, 1, 2162699, 262144, 1, 2162700, 262144, 1, 2162701, 262144, 1, 2162702, 262144, 1, 2162703, 262144, 1, 2162704, 262144, 1, 2162705, 262144, 1, 2162709, 262144, 1, 2162710, 262144, 1, 2162711, 262144, 1, 2162708, 262144, 1, 2162707, 262144, 1, 2162706, 262144, 1, 2162698, 262144, 1, 2228234, 262144, 1, 2228235, 262144, 1, 2228236, 262144, 1, 2228237, 262144, 1, 2228238, 262144, 1, 2228239, 262144, 1, 2228240, 262144, 1, 2228241, 262144, 1, 2228242, 262144, 1, 2228243, 262144, 1, 2228244, 262144, 1, 2228245, 262144, 1, 2228246, 262144, 1, 2228247, 262144, 1, 2293769, 196608, 2, 2031623, 196608, 2, 2293784, 327680, 2, 2162713, 327680, 2, 1835033, 327680, 1, 1900569, 327680, 1, 1966105, 327680, 1, 2031641, 327680, 1, 2097177, 327680, 1, 2162712, 0, 3, 2031625, 65536, 3, 2031624, 262144, 2, 2097161, 196608, 1, 2162697, 196608, 1, 2228233, 196608, 1, 2293770, 262144, 2, 2293771, 262144, 2, 2293772, 262144, 2, 2293773, 262144, 2, 2293774, 262144, 2, 2293775, 262144, 2, 2293776, 262144, 2, 2293777, 262144, 2, 2293778, 262144, 2, 2293779, 262144, 2, 2293780, 262144, 2, 2293781, 262144, 2, 2293782, 262144, 2, 2293783, 262144, 2, 2228248, 327680, 1, 1966087, 196608, 1, 1900551, 196608, 1, 1835015, 196608, 0, 1703943, 196608, 2, 1900559, 262144, 1, 1900558, 262144, 1) @@ -252,23 +268,23 @@ layer_4/tile_data = PackedInt32Array(1114105, 196608, 3, 1114106, 262144, 3, 111 layer_5/tile_data = PackedInt32Array(786438, 262144, 3, 720899, 262144, 3, 851971, 458752, 3, 196611, 458752, 3, 1835019, 262144, 3, 1835034, 458752, 3) [node name="ExampleEnemy" parent="Entities" index="0" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_qliqj") +material = SubResource("ShaderMaterial_3sxqg") position = Vector2(169, 115) [node name="ExampleEnemy2" parent="Entities" index="1" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_xpy5p") +material = SubResource("ShaderMaterial_r3w8l") position = Vector2(75, 130) [node name="ExampleEnemy3" parent="Entities" index="2" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_jlmdb") +material = SubResource("ShaderMaterial_2oi7o") position = Vector2(140, 177) [node name="ExampleEnemy4" parent="Entities" index="3" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_pd2a6") +material = SubResource("ShaderMaterial_65pfr") position = Vector2(14, 159) [node name="ExampleEnemy5" parent="Entities" index="4" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_th2v6") +material = SubResource("ShaderMaterial_5a7w6") position = Vector2(10, 22) Faction = 1 @@ -286,5 +302,9 @@ SpawnTime = 5.0 [node name="CollisionShape2D" parent="Spawners/Spawner/Area2D" index="0"] shape = SubResource("RectangleShape2D_oods2") +[node name="WorldEnvironment" parent="." index="5"] +environment = SubResource("Environment_c0b2h") + [editable path="Entities/Campfire"] +[editable path="Entities/Campfire/InteractionTrigger"] [editable path="Spawners/Spawner"] diff --git a/State/Character/CharacterState.cs b/State/Character/CharacterState.cs index 08fc94e..7632a4a 100644 --- a/State/Character/CharacterState.cs +++ b/State/Character/CharacterState.cs @@ -46,6 +46,13 @@ public abstract partial class CharacterState : Node, IState public virtual CharacterState PhysicsProcess(double delta) { + if (Character.Health < 0) + { + Character.Velocity = Vector2.Zero; + Character.MoveAndSlide(); + return null; + } + Character.Velocity = Character.NetImpulse; if (Character.NetImpulse.LengthSquared() < Mathf.Pow(Character.Speed, 2)) diff --git a/State/Character/PlayerRollState.cs b/State/Character/PlayerRollState.cs index d5a3acd..4c0ddbc 100644 --- a/State/Character/PlayerRollState.cs +++ b/State/Character/PlayerRollState.cs @@ -46,7 +46,7 @@ public partial class PlayerRollState : PlayerState public override CharacterState Process(double delta) { Character.Direction = _rollDirection; - if ((_timeLeftToRoll -= delta) <= 0) + if ((_timeLeftToRoll -= delta) <= 0 || _player.Health <= 0) { return IdleState; } diff --git a/SupaLidlGame.csproj b/SupaLidlGame.csproj index e7f1627..44aa4a6 100644 --- a/SupaLidlGame.csproj +++ b/SupaLidlGame.csproj @@ -1,4 +1,4 @@ - + net6.0 true diff --git a/Utils/Spawner.cs b/Utils/Spawner.cs index 0d642ca..07a5351 100644 --- a/Utils/Spawner.cs +++ b/Utils/Spawner.cs @@ -1,5 +1,6 @@ using Godot; using Godot.Collections; +using GodotUtilities; using SupaLidlGame.Extensions; namespace SupaLidlGame.Utils; diff --git a/Utils/World.cs b/Utils/World.cs index 68c61c0..8e426d7 100644 --- a/Utils/World.cs +++ b/Utils/World.cs @@ -49,7 +49,10 @@ public partial class World : Node2D CurrentPlayer.Death += (Events.HealthChangedArgs args) => { // TODO: respawn the player at the last campfire. - SpawnPlayer(); + GetTree().CreateTimer(1).Timeout += () => + { + SpawnPlayer(); + }; }; base._Ready(); @@ -200,11 +203,13 @@ public partial class World : Node2D public void SpawnPlayer() { // TODO: add max health property - CurrentPlayer.Health = 100; - CurrentPlayer.GlobalPosition = SaveLocation; + //CurrentPlayer.Health = 100; + //CurrentPlayer.Sprite.Visible = true; if (CurrentMap.SceneFilePath != SaveMapKey) { LoadScene(SaveMapKey); } + CurrentPlayer.GlobalPosition = SaveLocation; + CurrentPlayer.Spawn(); } } diff --git a/project.godot b/project.godot index 8bdfda5..e28b7f9 100644 --- a/project.godot +++ b/project.godot @@ -47,13 +47,13 @@ ui_down={ } roll={ "deadzone": 0.5, -"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":3,"pressed":false,"double_click":false,"script":null) +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":3,"canceled":false,"pressed":false,"double_click":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":0,"echo":false,"script":null) ] } attack1={ "deadzone": 0.5, -"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"pressed":false,"double_click":false,"script":null) +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null) ] } equip={ From 12e62da20add8fe19b81ee1df6a7c844c380720a Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Tue, 27 Jun 2023 20:28:37 -0700 Subject: [PATCH 05/12] doc sprite --- Assets/Sprites/Characters/doc.ase | Bin 0 -> 2360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Assets/Sprites/Characters/doc.ase diff --git a/Assets/Sprites/Characters/doc.ase b/Assets/Sprites/Characters/doc.ase new file mode 100644 index 0000000000000000000000000000000000000000..cbcf4a580c653e5f50c5254c2510da1b952cd320 GIT binary patch literal 2360 zcmc(fZ%7ky7{{M^O*c)m`KMW%9;q0pQ!`9OY?ok`N}Aw|K(?F`BT6*!Z{R9Sa;BxE zpcF|Xp$t(Z@`WfujVNZA8HzPXs8B&)804GvJ+rwj3W?N>eYkCR_xpaH=lNZ{n8;!j zkrZ#11Vp68XZ@vEKirffvkTG6lB;c11tJ8nzgCTOSaS~>ZzT#%%m@8Vrby1VeKbVCt2FVA;bIu=`~mI5u?)%nav$uS(;A-Py-YI_E3j6q+twQxIz?`P=p`kUB>bq-;X^5{iv<)8jbE7WMyah8xJ5|M%taa{b)JPs@mKnHtqw<+Ct5UkJLt5YH`Kcw?EmkS$laj)e z>QRMjg{*+w$ldN%?)X;GS)i^ZpMYg6`*{D2VK$kOSY{>qhTw6Nj?<03=5m=XPNy!? zFE01wL`P@HGt8$Lrc-)ao)(oMEAlrq%`3Fk%`t=0zQjv$8J-a}z2BLTn@_xgh}s7_ z7ACOr%94w1oHs?vV~eFGouo2X%lq%0a*ZWHVvwBZTO(JxeZ8_cY2~hIxzTQi0`mh{ zpjNB%ejmc~%`(P!_^tk&cBfB@>bhs}qfuj>%y1!)ktqG$=zah3%j1F-f&vF}h+wdlKCr+0N$u?~Udks}`6_=v|?` z)K+h_H%=Wpw$?F`!$gWmxWPxFKSP$%BVp?!xYdutDJP*Un~?noZul90RpZLCA-i%$ MYlTE@)7xqG1ARBkb^rhX literal 0 HcmV?d00001 From a2764247492823c3ad76ab0bee38b38cfc1cbc7d Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Tue, 27 Jun 2023 20:29:04 -0700 Subject: [PATCH 06/12] fix weapon breaking when hitting dead enemy --- BoundingBoxes/Hurtbox.cs | 15 +++++++++------ SupaLidlGame.csproj | 2 +- project.godot | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/BoundingBoxes/Hurtbox.cs b/BoundingBoxes/Hurtbox.cs index ca36c51..f9e6c4f 100644 --- a/BoundingBoxes/Hurtbox.cs +++ b/BoundingBoxes/Hurtbox.cs @@ -29,11 +29,14 @@ public partial class Hurtbox : BoundingBox, IFaction Vector2 knockbackOrigin = default, Vector2 knockbackVector = default) { - EmitSignal( - SignalName.ReceivedDamage, - damage, - inflictor, - knockback, - knockbackOrigin, knockbackVector); + if (inflictor is not null) + { + EmitSignal( + SignalName.ReceivedDamage, + damage, + inflictor, + knockback, + knockbackOrigin, knockbackVector); + } } } diff --git a/SupaLidlGame.csproj b/SupaLidlGame.csproj index 44aa4a6..e7f1627 100644 --- a/SupaLidlGame.csproj +++ b/SupaLidlGame.csproj @@ -1,4 +1,4 @@ - + net6.0 true diff --git a/project.godot b/project.godot index e28b7f9..8bdfda5 100644 --- a/project.godot +++ b/project.godot @@ -47,13 +47,13 @@ ui_down={ } roll={ "deadzone": 0.5, -"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":3,"canceled":false,"pressed":false,"double_click":false,"script":null) +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":3,"pressed":false,"double_click":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":0,"echo":false,"script":null) ] } attack1={ "deadzone": 0.5, -"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null) +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"pressed":false,"double_click":false,"script":null) ] } equip={ From 97c2b243c7a85a313a35b98d1089db3681eb4dac Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Thu, 13 Jul 2023 23:46:58 -0700 Subject: [PATCH 07/12] doc boss (wip) --- Assets/Sounds/splat-player.ogg | Bin 0 -> 82603 bytes Assets/Sounds/splat-player.ogg.import | 19 ++ Assets/Sounds/splat.ogg | Bin 0 -> 48161 bytes Assets/Sounds/splat.ogg.import | 19 ++ Assets/Sprites/Characters/doc.ase | Bin 2360 -> 2360 bytes Assets/Sprites/Characters/doc.png | Bin 0 -> 536 bytes Assets/Sprites/Characters/doc.png.import | 34 ++ Assets/Sprites/arena-tileset-normal.png | Bin 0 -> 1383 bytes .../Sprites/arena-tileset-normal.png.import | 34 ++ Assets/Sprites/arena-tileset.ase | Bin 0 -> 3811 bytes Assets/Sprites/arena-tileset.png | Bin 0 -> 3297 bytes Assets/Sprites/arena-tileset.png.import | 34 ++ BoundingBoxes/Hurtbox.cs | 15 +- Characters/Character.cs | 9 +- Characters/Doc.cs | 15 + Characters/Doc.tscn | 296 ++++++++++++++++++ Characters/Enemy.cs | 6 - Characters/Player.tscn | 51 +-- Entities/Projectile.cs | 21 +- Entities/RailBeam.tscn | 2 - Items/Weapons/Sword.tscn | 4 +- Scenes/Level.tscn | 4 +- Scenes/Map.cs | 14 +- Scenes/Maps/Arena.tscn | 274 ++++++++++++++++ Scenes/Maps/Hills.tscn | 20 +- State/NPC/Doc/DocAttackState.cs | 86 +++++ State/NPC/Doc/DocExitState.cs | 38 +++ State/NPC/Doc/DocTelegraphState.cs | 41 +++ State/NPC/NPCState.cs | 18 ++ State/NPC/NPCStateMachine.cs | 18 ++ State/NPC/TelegraphState.cs | 19 ++ project.godot | 4 + 32 files changed, 1037 insertions(+), 58 deletions(-) create mode 100644 Assets/Sounds/splat-player.ogg create mode 100644 Assets/Sounds/splat-player.ogg.import create mode 100644 Assets/Sounds/splat.ogg create mode 100644 Assets/Sounds/splat.ogg.import create mode 100644 Assets/Sprites/Characters/doc.png create mode 100644 Assets/Sprites/Characters/doc.png.import create mode 100644 Assets/Sprites/arena-tileset-normal.png create mode 100644 Assets/Sprites/arena-tileset-normal.png.import create mode 100644 Assets/Sprites/arena-tileset.ase create mode 100644 Assets/Sprites/arena-tileset.png create mode 100644 Assets/Sprites/arena-tileset.png.import create mode 100644 Characters/Doc.cs create mode 100644 Characters/Doc.tscn create mode 100644 Scenes/Maps/Arena.tscn create mode 100644 State/NPC/Doc/DocAttackState.cs create mode 100644 State/NPC/Doc/DocExitState.cs create mode 100644 State/NPC/Doc/DocTelegraphState.cs create mode 100644 State/NPC/NPCState.cs create mode 100644 State/NPC/NPCStateMachine.cs create mode 100644 State/NPC/TelegraphState.cs diff --git a/Assets/Sounds/splat-player.ogg b/Assets/Sounds/splat-player.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9dfeb197f1bfc551d28fb0bc15b534d45927358b GIT binary patch literal 82603 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 literal 0 HcmV?d00001 diff --git a/Assets/Sounds/splat-player.ogg.import b/Assets/Sounds/splat-player.ogg.import new file mode 100644 index 0000000..4207ee0 --- /dev/null +++ b/Assets/Sounds/splat-player.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://bkeyg8weaqnuu" +path="res://.godot/imported/splat-player.ogg-b9195de7bb7ca34678fd41a9159d6c3d.oggvorbisstr" + +[deps] + +source_file="res://Assets/Sounds/splat-player.ogg" +dest_files=["res://.godot/imported/splat-player.ogg-b9195de7bb7ca34678fd41a9159d6c3d.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/Assets/Sounds/splat.ogg b/Assets/Sounds/splat.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c98143674635c15ef2a55bd5556196257c960c28 GIT binary patch literal 48161 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 literal 0 HcmV?d00001 diff --git a/Assets/Sounds/splat.ogg.import b/Assets/Sounds/splat.ogg.import new file mode 100644 index 0000000..7d694e9 --- /dev/null +++ b/Assets/Sounds/splat.ogg.import @@ -0,0 +1,19 @@ +[remap] + +importer="oggvorbisstr" +type="AudioStreamOggVorbis" +uid="uid://k6kpdj1kv0jg" +path="res://.godot/imported/splat.ogg-3afac4e48ba675494c2bad9f16c4bde8.oggvorbisstr" + +[deps] + +source_file="res://Assets/Sounds/splat.ogg" +dest_files=["res://.godot/imported/splat.ogg-3afac4e48ba675494c2bad9f16c4bde8.oggvorbisstr"] + +[params] + +loop=false +loop_offset=0 +bpm=0 +beat_count=0 +bar_beats=4 diff --git a/Assets/Sprites/Characters/doc.ase b/Assets/Sprites/Characters/doc.ase index cbcf4a580c653e5f50c5254c2510da1b952cd320..2fd3a93307baf82037c0193fed0a8a88aaa0e7d2 100644 GIT binary patch delta 184 zcmdlXv_pv7f|G&a!BP$e9tMGp-0e)vOblF;?O9AG&u129W@KQR{D7$)O^g{RmOojA zMFJ}B1yz?n`8QCEk%4ov7;7+)W(2Fd%?c9Zn*5D50ICjQ9tS(f4v2ZZ>>%?vC$C_4 UfvU@&9LE8(!({SW4oR3e0L_~zasU7T delta 184 zcmdlXv_pv7f|G&a!BP$e2?mLc-0e)v91KE}?O9AG&u129W@q4<{D7$)O^h2TmOojA zMFJ}B1yz?n`8QCEok4K27;7+)<^-#|%?c6|n*5D50ICjQ9tS(f4v2ZZ>>%?5C$C_4 UfvU@&9LE8(!({SW4oR3e03^mLW&i*H diff --git a/Assets/Sprites/Characters/doc.png b/Assets/Sprites/Characters/doc.png new file mode 100644 index 0000000000000000000000000000000000000000..cd4c2813353130dc65b76d1649e07212ddb1ef2b GIT binary patch literal 536 zcmV+z0_XjSP)AHIP0005sNklf6YPxkO(`iz+kq+iPInl) z_XG4g3D3W)=9uJPl}`t42d3yd-C;cL4w z&3SqI$nmE6SLJQKgTrNk#S#y|=ZWT{OTvhODf(P{?mE~`mpOj!I$*xM%_RR6-U5=P z$OD%Z^Ml46O4aB5dNoN;fVW@(kp6xT&uN#M>R*Mo#f{#Al?ER72iTm#bWH6~ioUpX zy#-4;M(CRLYJ#Ys>rC-a;cXp(o9c_jJGE-Lo8q6sODmx5z^eK{(uLmZ4BO9{beRw@ zOHK84_*doc_<#o%VLnz3Ty#CXR)0HPN*}JVKgf@LrukRpb1NV##{2-whf!%@YKN-m z?+-f*?o-V7Q>tzM{7)6DNMF^D4O|yk#ZVLdDvtSq^q8o_KRXU%Rj(93(#u8_C_WRn z&DXKnIV!wP{}jITCaklv=Fg|l5(CtooGh=yqYAI$sW4bkXH}iyro4{IzR}jPz~B0- aJN^$LSn8;9{J7-+00008n`5Xb*Kusg6&7brl06a;adgaCemAb|J=p{}_nI3Vof#J!C36S$JxUbV#O5d<8} zR>#7fTM6(3@CtJIrR9<$De-H5mBrnqDbH}`zq4cI_J{AIA~v>I;Y-!!u(8Fx^%4H3 z7XX0r@5g9taX8?!bHuk*JU=_mJ|9o6bF2-pUcJD!fqUz8oZrLweNy@P8^O}+tyk(T zSL-crfQ=5t4*v+7`0@lEfFl$;a4>(h1vYwWd}&XxUcIEQ$9MpMdwfaVH_0TNGiH8i z`vJk+_TZH3p@0KNh6QGHx?e?CWfC*C5Ch1MN_@8S8r-Hzh>L!W8g0k|mP`+o7BJ{W(GBkY`geVO&yajFB51{gi$03(MS zVC0Ykj2v=+fiPhQFt#h4w_rOQ*dh9?+-m<+KMuBm)v9>jrPen=>ve#Jj)S@J&4c`S zdoc-&@0dZ+NJXvFv@Pncml=Rf4uxMxM&0#SVN-J}x)eK5^1Cl42RJ!@2TB1Wha6z! zjM@R%m20+EO_JqgMhuOyoMZLK1C0Fj0Oa?O z<*YJ%f2gr%NLrx}zV`hWiHl_BK>`@nF|TJW)y6C{{vfcu8XF{F-E*8%!Y z%MPFdfIBrY3*T1vEgUgS%%_3z3M0Wu1jvsHM7M}UU=#riGiAKOx4$Gj9T453{5Ehe zFks2Id_FbF0XjK>H$WI$SpVA2U9!g>IV z_|mzC<^pgoNex6hL?VzIG-=p8UEoelV9(-;A4e1ak|+fj>Fcvs2DjqdMKnWH2^7I2 zf^gh0k*)ZpL|~aRFwr_{(>dGaZ+fU1<`m{T&E@(5$nd>DS_+QBzo-lhWJV3!F}fFTI;XY>PPBft;~LPI4Mfrg2h2I>bG8PpFja<1ABAatU; z@()WikD3&G7w-oU3C<-&hBi@SV_c^npl<~teFOMjwOWOz1F)KXo~EIGfC4P5dY#~@ z!RNRX(td#GA3NTFRD>8&Kfut5Bfy@)HNv7!LKldRab?v*5xD}eXX#*w#3Im0^aDf& z&(Q^;n0wZcZt{@z0|<;=xet+OjJOggAnN2fvmYS%nfd|xfZB8zPWBT%qPa>UaTzYw p4?tqDA4p5VQTV=KKLF7#{{xttCIfS))B*qi002ovPDHLkV1liojY$9i literal 0 HcmV?d00001 diff --git a/Assets/Sprites/arena-tileset-normal.png.import b/Assets/Sprites/arena-tileset-normal.png.import new file mode 100644 index 0000000..64e9064 --- /dev/null +++ b/Assets/Sprites/arena-tileset-normal.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://5k0o7d7j65a4" +path="res://.godot/imported/arena-tileset-normal.png-9466546ce6c631f7ed3196f7d2a888b3.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/arena-tileset-normal.png" +dest_files=["res://.godot/imported/arena-tileset-normal.png-9466546ce6c631f7ed3196f7d2a888b3.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Sprites/arena-tileset.ase b/Assets/Sprites/arena-tileset.ase new file mode 100644 index 0000000000000000000000000000000000000000..7a34fb516dee7c0c3b941d1f5658d6b5d66bc48a GIT binary patch literal 3811 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 Q>fQ;Oh@PTHI|+XO0`HK#LjV8( literal 0 HcmV?d00001 diff --git a/Assets/Sprites/arena-tileset.png b/Assets/Sprites/arena-tileset.png new file mode 100644 index 0000000000000000000000000000000000000000..37205f55f134192a5723f3185f43815c874bde73 GIT binary patch literal 3297 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 literal 0 HcmV?d00001 diff --git a/Assets/Sprites/arena-tileset.png.import b/Assets/Sprites/arena-tileset.png.import new file mode 100644 index 0000000..d6c9bc5 --- /dev/null +++ b/Assets/Sprites/arena-tileset.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b0yiy7w8nxmas" +path="res://.godot/imported/arena-tileset.png-a3c9cd5d13a16cc6a35727d6d51ff6f7.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/arena-tileset.png" +dest_files=["res://.godot/imported/arena-tileset.png-a3c9cd5d13a16cc6a35727d6d51ff6f7.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/Hurtbox.cs b/BoundingBoxes/Hurtbox.cs index f9e6c4f..ca36c51 100644 --- a/BoundingBoxes/Hurtbox.cs +++ b/BoundingBoxes/Hurtbox.cs @@ -29,14 +29,11 @@ public partial class Hurtbox : BoundingBox, IFaction Vector2 knockbackOrigin = default, Vector2 knockbackVector = default) { - if (inflictor is not null) - { - EmitSignal( - SignalName.ReceivedDamage, - damage, - inflictor, - knockback, - knockbackOrigin, knockbackVector); - } + EmitSignal( + SignalName.ReceivedDamage, + damage, + inflictor, + knockback, + knockbackOrigin, knockbackVector); } } diff --git a/Characters/Character.cs b/Characters/Character.cs index 12f58e7..e986353 100644 --- a/Characters/Character.cs +++ b/Characters/Character.cs @@ -202,7 +202,14 @@ public partial class Character : CharacterBody2D, IFaction { if (knockbackOrigin == default) { - knockbackOrigin = inflictor.GlobalPosition; + if (inflictor is null) + { + knockbackOrigin = GlobalPosition + Vector2.Down; + } + else + { + knockbackOrigin = inflictor.GlobalPosition; + } } knockbackDir = knockbackOrigin.DirectionTo(GlobalPosition); diff --git a/Characters/Doc.cs b/Characters/Doc.cs new file mode 100644 index 0000000..6accedc --- /dev/null +++ b/Characters/Doc.cs @@ -0,0 +1,15 @@ +using Godot; + +namespace SupaLidlGame.Characters; + +public partial class Doc : Enemy +{ + [Export] + public State.NPC.NPCStateMachine BossStateMachine { get; set; } + + public override void _Process(double delta) + { + BossStateMachine.Process(delta); + base._Process(delta); + } +} diff --git a/Characters/Doc.tscn b/Characters/Doc.tscn new file mode 100644 index 0000000..5378697 --- /dev/null +++ b/Characters/Doc.tscn @@ -0,0 +1,296 @@ +[gd_scene load_steps=33 format=3 uid="uid://bt6s40u515jvo"] + +[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="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="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/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/DocAttackState.cs" id="8_r4l3q"] +[ext_resource type="Script" path="res://Items/Inventory.cs" id="8_r8ejq"] +[ext_resource type="Script" path="res://State/NPC/Doc/DocExitState.cs" id="9_6com1"] +[ext_resource type="PackedScene" uid="uid://bqvseo3sbs1aj" path="res://Entities/RailBeam.tscn" id="9_fcrmd"] +[ext_resource type="AudioStream" uid="uid://k6kpdj1kv0jg" path="res://Assets/Sounds/splat.ogg" id="9_stm0e"] + +[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 + +[sub_resource type="Animation" id="Animation_7oukw"] +resource_name = "enter_in" +length = 0.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprite:scale") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.4), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(2, 0.5), Vector2(1, 1)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("../Sprite:modulate") +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)] +} + +[sub_resource type="Animation" id="Animation_j3s0y"] +resource_name = "exit_out" +length = 0.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("../Sprite:scale") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.4), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(1, 1), Vector2(2, 0.5)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("../Sprite:modulate") +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)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_rpply"] +_data = { +"enter_in": SubResource("Animation_7oukw"), +"exit_out": SubResource("Animation_j3s0y") +} + +[sub_resource type="AtlasTexture" id="AtlasTexture_dib6t"] +atlas = ExtResource("3_rs44f") +region = Rect2(0, 0, 12, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_cwqre"] +atlas = ExtResource("3_rs44f") +region = Rect2(12, 0, 12, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_r8xjl"] +atlas = ExtResource("3_rs44f") +region = Rect2(24, 0, 12, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_7hkj4"] +atlas = ExtResource("3_rs44f") +region = Rect2(36, 0, 12, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_w04w0"] +atlas = ExtResource("3_rs44f") +region = Rect2(48, 0, 12, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ym6tg"] +atlas = ExtResource("3_rs44f") +region = Rect2(60, 0, 12, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_3rbas"] +atlas = ExtResource("3_rs44f") +region = Rect2(72, 0, 12, 16) + +[sub_resource type="AtlasTexture" id="AtlasTexture_63wkp"] +atlas = ExtResource("3_rs44f") +region = Rect2(84, 0, 12, 16) + +[sub_resource type="SpriteFrames" id="SpriteFrames_kb0pl"] +resource_local_to_scene = true +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_dib6t") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_cwqre") +}], +"loop": true, +"name": &"idle", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_r8xjl") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_7hkj4") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_w04w0") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ym6tg") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_3rbas") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_63wkp") +}], +"loop": true, +"name": &"move", +"speed": 12.0 +}] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_uict5"] +size = Vector2(16, 8) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_8lxmf"] +size = Vector2(16, 18) + +[sub_resource type="Animation" id="Animation_dxevc"] +resource_name = "Hurt" +length = 0.6 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:material:shader_parameter/intensity") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6), +"transitions": PackedFloat32Array(4, 4, 4, 4, 4, 4, 4), +"update": 0, +"values": [0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0] +} + +[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="Doc" type="CharacterBody2D" node_paths=PackedStringArray("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") +BossStateMachine = NodePath("BossStateMachine") +Health = 50.0 +Sprite = NodePath("Sprite") +Inventory = NodePath("Inventory") +StateMachine = NodePath("StateMachine") +Hurtbox = NodePath("Hurtbox") +Faction = 2 + +[node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState", "Character")] +script = ExtResource("3_t5jjc") +InitialState = NodePath("Idle") +Character = NodePath("..") + +[node name="Idle" type="Node" parent="StateMachine" node_paths=PackedStringArray("MoveState", "Character")] +script = ExtResource("4_b35px") +MoveState = NodePath("../Move") +Character = NodePath("../..") + +[node name="Move" type="Node" parent="StateMachine" node_paths=PackedStringArray("IdleState", "Character")] +script = ExtResource("5_pejsd") +IdleState = NodePath("../Idle") +Character = NodePath("../..") + +[node name="BossStateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState")] +script = ExtResource("6_kjpug") +InitialState = NodePath("Telegraph") + +[node name="Telegraph" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("TelegraphAnimationPlayer", "AttackState", "NPC")] +script = ExtResource("7_tfwbh") +TelegraphAnimationPlayer = NodePath("../../Animations/Telegraph") +AttackState = NodePath("../Attack") +NPC = NodePath("../..") + +[node name="Attack" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("ExitState", "NPC")] +script = ExtResource("8_r4l3q") +Duration = 8.0 +AttackDuration = 1.0 +Projectile = ExtResource("9_fcrmd") +ExitState = NodePath("../Exit") +NPC = NodePath("../..") + +[node name="Exit" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("TelegraphAnimationPlayer", "TelegraphState", "NPC")] +script = ExtResource("9_6com1") +TelegraphAnimationPlayer = NodePath("../../Animations/Telegraph") +TelegraphState = NodePath("../Telegraph") +NPC = NodePath("../..") + +[node name="Animations" type="Node" parent="."] + +[node name="Telegraph" type="AnimationPlayer" parent="Animations"] +libraries = { +"": SubResource("AnimationLibrary_rpply") +} + +[node name="Sprite" type="AnimatedSprite2D" parent="."] +modulate = Color(1, 1, 1, 0.5) +use_parent_material = true +position = Vector2(0, -4) +sprite_frames = SubResource("SpriteFrames_kb0pl") +animation = &"move" +frame_progress = 0.563144 +offset = Vector2(0, 4) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +visible = false +position = Vector2(0, 4) +shape = SubResource("RectangleShape2D_uict5") + +[node name="Hurtbox" parent="." instance=ExtResource("7_tnve0")] +visible = false +position = Vector2(0, -4) +Faction = 2 + +[node name="CollisionShape2D" parent="Hurtbox" index="0"] +position = Vector2(0, 4) +shape = SubResource("RectangleShape2D_8lxmf") + +[node name="Inventory" type="Node2D" parent="."] +y_sort_enabled = true +script = ExtResource("8_r8ejq") +Items = Array[Node2D]([]) + +[node name="FlashAnimation" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_xe5eq") +} + +[node name="HurtSound" type="AudioStreamPlayer2D" parent="."] +stream = ExtResource("9_stm0e") + +[editable path="Hurtbox"] diff --git a/Characters/Enemy.cs b/Characters/Enemy.cs index 4d5b335..a508679 100644 --- a/Characters/Enemy.cs +++ b/Characters/Enemy.cs @@ -5,12 +5,6 @@ namespace SupaLidlGame.Characters; public partial class Enemy : NPC { - public override void _Ready() - { - Inventory.SelectedItem = Inventory.GetNode("Sword"); - base._Ready(); - } - public override void Die() { base.Die(); diff --git a/Characters/Player.tscn b/Characters/Player.tscn index b18c399..f54a756 100644 --- a/Characters/Player.tscn +++ b/Characters/Player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=37 format=3 uid="uid://b2254pup8k161"] +[gd_scene load_steps=38 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,8 +11,9 @@ [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="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="9_avyu4"] -[ext_resource type="AudioStream" uid="uid://njun3e6v4854" path="res://Assets/Sounds/hurt.wav" id="12_h0x0g"] +[ext_resource type="AudioStream" uid="uid://bkeyg8weaqnuu" path="res://Assets/Sounds/splat-player.ogg" id="12_vvem5"] [ext_resource type="Script" path="res://BoundingBoxes/InteractionRay.cs" id="13_hs3u1"] +[ext_resource type="Texture2D" uid="uid://coarr28adgo1u" path="res://Assets/Sprites/Particles/point-light.png" id="14_l4ekh"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"] shader = ExtResource("2_ngsgt") @@ -89,7 +90,7 @@ animations = [{ }] [sub_resource type="RectangleShape2D" id="RectangleShape2D_bfqew"] -size = Vector2(16, 8) +size = Vector2(12, 8) [sub_resource type="LabelSettings" id="LabelSettings_q5h1n"] font_size = 24 @@ -134,6 +135,21 @@ _data = { "RESET": SubResource("Animation_k6l16") } +[sub_resource type="Animation" id="Animation_yejx2"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} + [sub_resource type="Animation" id="Animation_rx2pj"] resource_name = "roll" length = 0.5 @@ -151,21 +167,6 @@ tracks/0/keys = { "values": [0.0, 3.14159, 6.28319] } -[sub_resource type="Animation" id="Animation_yejx2"] -length = 0.001 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Sprite:rotation") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [0.0] -} - [sub_resource type="AnimationLibrary" id="AnimationLibrary_jai06"] _data = { "RESET": SubResource("Animation_yejx2"), @@ -266,11 +267,9 @@ horizontal_alignment = 1 [node name="Node" type="Node" parent="."] -[node name="Inventory" type="Node2D" parent="." node_paths=PackedStringArray("Items")] -y_sort_enabled = true +[node name="Inventory" type="Node2D" parent="."] position = Vector2(0, 4) script = ExtResource("7_xyenu") -Items = [] InventoryMap = { "equip_1": 0, "equip_2": 1 @@ -298,7 +297,7 @@ libraries = { } [node name="HurtSound" type="AudioStreamPlayer2D" parent="."] -stream = ExtResource("12_h0x0g") +stream = ExtResource("12_vvem5") max_distance = 64.0 [node name="AudioListener2D" type="AudioListener2D" parent="."] @@ -321,4 +320,12 @@ texture = SubResource("CanvasTexture_pited") one_shot = true explosiveness = 0.9 +[node name="PointLight2D" type="PointLight2D" parent="."] +blend_mode = 2 +shadow_enabled = true +shadow_filter = 2 +shadow_filter_smooth = 3.0 +texture = ExtResource("14_l4ekh") +texture_scale = 0.5 + [editable path="Hurtbox"] diff --git a/Entities/Projectile.cs b/Entities/Projectile.cs index 06c1f71..731fbfa 100644 --- a/Entities/Projectile.cs +++ b/Entities/Projectile.cs @@ -20,10 +20,22 @@ public partial class Projectile : RigidBody2D [Export] public double Lifetime { get; set; } = 10; + [Export] + public double Delay { get; set; } = 0; + public Character Character { get; set; } + public override void _Ready() + { + Hitbox.Hit += OnHit; + } + public override void _Process(double delta) { + if (Delay > 0) + { + Delay -= delta; + } if ((Lifetime -= delta) <= 0) { QueueFree(); @@ -32,11 +44,14 @@ public partial class Projectile : RigidBody2D public override void _PhysicsProcess(double delta) { - Vector2 velocity = Velocity; - MoveAndCollide(velocity * (float)delta); + if (Delay <= 0) + { + Vector2 velocity = Velocity; + MoveAndCollide(velocity * (float)delta); + } } - public void _on_hitbox_hit(BoundingBox box) + public void OnHit(BoundingBox box) { if (box is Hurtbox hurtbox) { diff --git a/Entities/RailBeam.tscn b/Entities/RailBeam.tscn index 1a41828..49eeafb 100644 --- a/Entities/RailBeam.tscn +++ b/Entities/RailBeam.tscn @@ -27,6 +27,4 @@ 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/Weapons/Sword.tscn b/Items/Weapons/Sword.tscn index b200c38..69f13b2 100644 --- a/Items/Weapons/Sword.tscn +++ b/Items/Weapons/Sword.tscn @@ -340,13 +340,13 @@ Hitbox = NodePath("Hitbox") AnimationPlayer = NodePath("AnimationPlayer") AnimationTree = NodePath("AnimationTree") AttackTime = 0.2 -AttackAnimationDuration = 1.0 +AttackAnimationDuration = 0.75 ParryParticles = NodePath("Anchor/Node2D/Sprite2D/ParryParticles") NPCAnticipateTime = 0.3 StateMachine = NodePath("State") Anchor = NodePath("Anchor") Damage = 20.0 -UseTime = 0.8 +UseTime = 0.55 Knockback = 64.0 ShouldHideIdle = true diff --git a/Scenes/Level.tscn b/Scenes/Level.tscn index efb08ee..910e672 100644 --- a/Scenes/Level.tscn +++ b/Scenes/Level.tscn @@ -1,8 +1,8 @@ [gd_scene load_steps=3 format=3 uid="uid://1pb3mpmrl7lc"] [ext_resource type="Script" path="res://Utils/World.cs" id="1_1k6ew"] -[ext_resource type="PackedScene" uid="uid://bxtpv6jqodj4v" path="res://Scenes/Maps/Hills.tscn" id="2_juio7"] +[ext_resource type="PackedScene" uid="uid://b2x17su05ou5w" path="res://Scenes/Maps/Arena.tscn" id="2_avsrq"] [node name="World" type="Node2D"] script = ExtResource("1_1k6ew") -StartingArea = ExtResource("2_juio7") +StartingArea = ExtResource("2_avsrq") diff --git a/Scenes/Map.cs b/Scenes/Map.cs index f64f2eb..3432ec2 100644 --- a/Scenes/Map.cs +++ b/Scenes/Map.cs @@ -29,7 +29,7 @@ public partial class Map : TileMap } set { - _active = Visible = value; + _active = Visible = value; SetProcess(value); } } @@ -43,4 +43,16 @@ public partial class Map : TileMap { base._Process(delta); } + + public Node SpawnEntity(PackedScene scene) + { + var instance = scene.Instantiate(); + Entities.AddChild(instance); + return instance; + } + + public T SpawnEntity(PackedScene scene) where T : Node + { + return SpawnEntity(scene) as T; + } } diff --git a/Scenes/Maps/Arena.tscn b/Scenes/Maps/Arena.tscn new file mode 100644 index 0000000..d7b6104 --- /dev/null +++ b/Scenes/Maps/Arena.tscn @@ -0,0 +1,274 @@ +[gd_scene load_steps=13 format=3 uid="uid://b2x17su05ou5w"] + +[ext_resource type="PackedScene" uid="uid://clwv2owvk6abe" path="res://Scenes/BaseMap.tscn" id="1_ifiic"] +[ext_resource type="Texture2D" uid="uid://b0yiy7w8nxmas" path="res://Assets/Sprites/arena-tileset.png" id="2_wnjm0"] +[ext_resource type="Texture2D" uid="uid://5k0o7d7j65a4" path="res://Assets/Sprites/arena-tileset-normal.png" id="3_iitgk"] +[ext_resource type="PackedScene" uid="uid://bt6s40u515jvo" path="res://Characters/Doc.tscn" id="4_c0csw"] +[ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="5_aevwf"] + +[sub_resource type="OccluderPolygon2D" id="OccluderPolygon2D_8jil2"] +polygon = PackedVector2Array(-8, -4, -6, -5, -6, -18, 6, -18, 6, -5, 8, -4, 8, 4, 4, 8, -4, 8, -8, 3.5) + +[sub_resource type="CanvasTexture" id="CanvasTexture_dnsyd"] +diffuse_texture = ExtResource("2_wnjm0") +normal_texture = ExtResource("3_iitgk") + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_fcd6d"] +texture = SubResource("CanvasTexture_dnsyd") +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +1:0/0 = 0 +1:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:0/0/physics_layer_0/angular_velocity = 0.0 +2:0/0 = 0 +2:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:0/0/physics_layer_0/angular_velocity = 0.0 +3:0/0 = 0 +3:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:0/0/physics_layer_0/angular_velocity = 0.0 +4:0/0 = 0 +4:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:0/0/physics_layer_0/angular_velocity = 0.0 +4:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +5:0/0 = 0 +5:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:0/0/physics_layer_0/angular_velocity = 0.0 +5:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +6:0/0 = 0 +6:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:0/0/physics_layer_0/angular_velocity = 0.0 +7:0/size_in_atlas = Vector2i(1, 2) +7:0/0 = 0 +7:0/0/texture_origin = Vector2i(0, 8) +7:0/0/occlusion_layer_0/polygon = SubResource("OccluderPolygon2D_8jil2") +7:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:0/0/physics_layer_0/angular_velocity = 0.0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -4, 8, -4, 8, 3.5, 4.5, 8, -4, 8, -8, 4) +0:1/0 = 0 +0:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:1/0/physics_layer_0/angular_velocity = 0.0 +1:1/0 = 0 +1:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:1/0/physics_layer_0/angular_velocity = 0.0 +2:1/0 = 0 +2:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:1/0/physics_layer_0/angular_velocity = 0.0 +2:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:1/0 = 0 +3:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:1/0/physics_layer_0/angular_velocity = 0.0 +3:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +4:1/0 = 0 +4:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:1/0/physics_layer_0/angular_velocity = 0.0 +4:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +5:1/0 = 0 +5:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:1/0/physics_layer_0/angular_velocity = 0.0 +5:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +6:1/0 = 0 +6:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:1/0/physics_layer_0/angular_velocity = 0.0 +6:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:2/0 = 0 +0:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:2/0/physics_layer_0/angular_velocity = 0.0 +0:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +1:2/0 = 0 +1:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:2/0/physics_layer_0/angular_velocity = 0.0 +1:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +2:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:2/0/physics_layer_0/angular_velocity = 0.0 +3:2/0 = 0 +3:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:2/0/physics_layer_0/angular_velocity = 0.0 +3:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +4:2/0 = 0 +4:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:2/0/physics_layer_0/angular_velocity = 0.0 +5:2/0 = 0 +5:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:2/0/physics_layer_0/angular_velocity = 0.0 +6:2/0 = 0 +6:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:2/0/physics_layer_0/angular_velocity = 0.0 +7:2/0 = 0 +7:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:2/0/physics_layer_0/angular_velocity = 0.0 +0:3/0 = 0 +0:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:3/0/physics_layer_0/angular_velocity = 0.0 +0:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +1:3/0 = 0 +1:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:3/0/physics_layer_0/angular_velocity = 0.0 +1:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:3/0 = 0 +2:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:3/0/physics_layer_0/angular_velocity = 0.0 +2:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:3/0 = 0 +3:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:3/0/physics_layer_0/angular_velocity = 0.0 +3:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +4:3/0 = 0 +4:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:3/0/physics_layer_0/angular_velocity = 0.0 +5:3/0 = 0 +5:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:3/0/physics_layer_0/angular_velocity = 0.0 +6:3/0 = 0 +6:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:3/0/physics_layer_0/angular_velocity = 0.0 +7:3/0 = 0 +7:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:3/0/physics_layer_0/angular_velocity = 0.0 + +[sub_resource type="OccluderPolygon2D" id="OccluderPolygon2D_kbvre"] +polygon = PackedVector2Array(-4, 8, -8, 4, -8, -4, -6, -4, -6, -20, 6, -20, 6, -4, 8, -4, 8, 4, 4, 8) + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_5yxvt"] +texture = ExtResource("2_wnjm0") +0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 +1:0/0 = 0 +1:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:0/0/physics_layer_0/angular_velocity = 0.0 +2:0/0 = 0 +2:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:0/0/physics_layer_0/angular_velocity = 0.0 +3:0/0 = 0 +3:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:0/0/physics_layer_0/angular_velocity = 0.0 +4:0/0 = 0 +4:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:0/0/physics_layer_0/angular_velocity = 0.0 +4:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +5:0/0 = 0 +5:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:0/0/physics_layer_0/angular_velocity = 0.0 +5:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +6:0/0 = 0 +6:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:0/0/physics_layer_0/angular_velocity = 0.0 +0:1/0 = 0 +0:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:1/0/physics_layer_0/angular_velocity = 0.0 +1:1/0 = 0 +1:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:1/0/physics_layer_0/angular_velocity = 0.0 +2:1/0 = 0 +2:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:1/0/physics_layer_0/angular_velocity = 0.0 +2:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +3:1/0 = 0 +3:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:1/0/physics_layer_0/angular_velocity = 0.0 +3:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +4:1/0 = 0 +4:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:1/0/physics_layer_0/angular_velocity = 0.0 +4:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +5:1/0 = 0 +5:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:1/0/physics_layer_0/angular_velocity = 0.0 +5:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +6:1/0 = 0 +6:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:1/0/physics_layer_0/angular_velocity = 0.0 +6:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +0:2/0 = 0 +0:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:2/0/physics_layer_0/angular_velocity = 0.0 +0:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +1:2/0 = 0 +1:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:2/0/physics_layer_0/angular_velocity = 0.0 +1:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:2/0 = 0 +2:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:2/0/physics_layer_0/angular_velocity = 0.0 +3:2/0 = 0 +3:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:2/0/physics_layer_0/angular_velocity = 0.0 +3:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 0, -8, 0) +4:2/0 = 0 +4:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:2/0/physics_layer_0/angular_velocity = 0.0 +5:2/0 = 0 +5:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:2/0/physics_layer_0/angular_velocity = 0.0 +6:2/0 = 0 +6:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:2/0/physics_layer_0/angular_velocity = 0.0 +7:2/0 = 0 +7:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:2/0/physics_layer_0/angular_velocity = 0.0 +0:3/0 = 0 +0:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:3/0/physics_layer_0/angular_velocity = 0.0 +0:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +1:3/0 = 0 +1:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:3/0/physics_layer_0/angular_velocity = 0.0 +1:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) +2:3/0 = 0 +2:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:3/0/physics_layer_0/angular_velocity = 0.0 +2:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -8, 0, 8, -8, 8) +3:3/0 = 0 +3:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:3/0/physics_layer_0/angular_velocity = 0.0 +3:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(0, -8, 8, -8, 8, 8, 0, 8) +4:3/0 = 0 +4:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:3/0/physics_layer_0/angular_velocity = 0.0 +4:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(0, -8, 8, -8, 8, 0, 0, 0) +5:3/0 = 0 +5:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:3/0/physics_layer_0/angular_velocity = 0.0 +5:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -8, 0, 0, -8, 0) +6:3/0 = 0 +6:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:3/0/physics_layer_0/angular_velocity = 0.0 +7:3/0 = 0 +7:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:3/0/physics_layer_0/angular_velocity = 0.0 +7:0/size_in_atlas = Vector2i(1, 2) +7:0/0 = 0 +7:0/0/texture_origin = Vector2i(0, 8) +7:0/0/occlusion_layer_0/polygon = SubResource("OccluderPolygon2D_kbvre") +7:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:0/0/physics_layer_0/angular_velocity = 0.0 +7:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8) + +[sub_resource type="TileSet" id="TileSet_k1u48"] +occlusion_layer_0/light_mask = 1 +physics_layer_0/collision_layer = 1 +sources/2 = SubResource("TileSetAtlasSource_5yxvt") +sources/0 = SubResource("TileSetAtlasSource_fcd6d") + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_wurwd"] +resource_local_to_scene = true +shader = ExtResource("5_aevwf") +shader_parameter/color = Quaternion(1, 1, 1, 1) +shader_parameter/intensity = 0.0 + +[node name="TileMap" instance=ExtResource("1_ifiic")] +tile_set = SubResource("TileSet_k1u48") +layer_0/tile_data = PackedInt32Array(-524281, 458752, 0, -524284, 458752, 0, -262152, 458752, 0, -327673, 458752, 0, -131065, 458752, 0, -65544, 458752, 0, 131064, 458752, 0, 65543, 458752, 0, 262151, 458752, 0, 327672, 458752, 0, 524280, 458752, 0, 524283, 458752, 0, 524286, 458752, 0, 458753, 458752, 0, 458756, 458752, 0, 458759, 458752, 0, -458760, 458752, 0, -458757, 458752, 0, -524287, 458752, 0, -458754, 458752, 0, -524292, 458752, 3, -589821, 458752, 2, -589822, 393216, 3, -524291, 393216, 2, -589817, 393216, 0) +layer_3/tile_data = PackedInt32Array(-196612, 65536, 1, -131076, 65536, 1, -65540, 196608, 0, -4, 131072, 0, -196611, 65536, 1, -131075, 65536, 0, -65539, 131072, 0, -3, 196608, 0, -196610, 65536, 0, -131074, 65536, 1, -65538, 0, 0, -2, 65536, 0, -196609, 65536, 1, -131073, 65536, 1, -65537, 65536, 0, -1, 65536, 1, -458760, 0, 0, -393224, 196608, 0, -327688, 196608, 0, -262152, 0, 0, -196616, 65536, 0, -131080, 131072, 0, -65544, 196608, 0, -8, 131072, 0, 65528, 131072, 0, 131064, 196608, 0, 196600, 131072, 0, 262136, 65536, 0, 327672, 65536, 0, 393208, 65536, 0, 458744, 0, 0, 524280, 65536, 0, -458759, 0, 1, -393223, 131072, 0, -327687, 131072, 0, -262151, 65536, 0, -196615, 65536, 1, -131079, 131072, 0, -65543, 131072, 0, -7, 196608, 0, 65529, 196608, 0, 131065, 196608, 0, 196601, 131072, 0, 262137, 65536, 1, 327673, 0, 0, 393209, 65536, 1, 458745, 65536, 0, 524281, 65536, 1, -458758, 0, 0, -393222, 65536, 0, -327686, 0, 0, -262150, 65536, 0, -196614, 0, 0, -131078, 0, 1, -65542, 196608, 0, -6, 196608, 0, 65530, 65536, 1, 131066, 65536, 1, 196602, 65536, 1, 262138, 0, 0, 327674, 65536, 1, 393210, 65536, 0, 458746, 131072, 0, 524282, 131072, 0, -458757, 65536, 0, -393221, 65536, 1, -327685, 65536, 0, -262149, 65536, 0, -196613, 0, 1, -131077, 0, 1, -65541, 131072, 0, -5, 131072, 0, 65531, 65536, 0, 131067, 0, 1, 196603, 0, 0, 262139, 0, 1, 327675, 0, 0, 393211, 65536, 0, 458747, 131072, 0, 524283, 196608, 0, -458756, 0, 0, -393220, 0, 1, -327684, 0, 0, -262148, 0, 0, 65532, 65536, 0, 131068, 65536, 0, 196604, 65536, 1, 262140, 0, 1, 327676, 131072, 0, 393212, 196608, 0, 458748, 196608, 0, 524284, 196608, 0, -458755, 0, 1, -393219, 0, 1, -327683, 0, 1, -262147, 0, 0, 65533, 65536, 0, 131069, 65536, 1, 196605, 65536, 1, 262141, 0, 1, 327677, 196608, 0, 393213, 131072, 0, 458749, 196608, 0, 524285, 131072, 0, -458754, 65536, 1, -393218, 65536, 1, -327682, 131072, 0, -262146, 196608, 0, 65534, 0, 1, 131070, 65536, 0, 196606, 196608, 0, 262142, 131072, 0, 327678, 196608, 0, 393214, 131072, 0, 458750, 65536, 0, 524286, 0, 0, -458753, 0, 1, -393217, 0, 1, -327681, 196608, 0, -262145, 131072, 0, 65535, 0, 1, 131071, 65536, 1, 196607, 131072, 0, 262143, 196608, 0, 327679, 131072, 0, 393215, 131072, 0, 458751, 65536, 1, 524287, 0, 0, -524288, 65536, 1, -458752, 65536, 1, -393216, 196608, 0, -327680, 196608, 0, -262144, 65536, 0, -196608, 0, 1, -131072, 65536, 0, -65536, 65536, 0, 0, 65536, 0, 65536, 65536, 1, 131072, 65536, 0, 196608, 65536, 1, 262144, 65536, 0, 327680, 0, 1, 393216, 0, 0, 458752, 0, 1, -524287, 65536, 1, -458751, 0, 0, -393215, 196608, 0, -327679, 196608, 0, -262143, 0, 0, -196607, 65536, 1, -131071, 0, 1, -65535, 65536, 1, 1, 0, 0, 65537, 65536, 1, 131073, 65536, 0, 196609, 65536, 0, 262145, 65536, 1, 327681, 65536, 1, 393217, 0, 1, 458753, 65536, 1, -524286, 65536, 0, -458750, 65536, 0, -393214, 131072, 0, -327678, 196608, 0, -262142, 0, 0, -196606, 65536, 0, -131070, 196608, 0, -65534, 131072, 0, 2, 131072, 0, 65538, 196608, 0, 131074, 65536, 0, 196610, 0, 0, 262146, 0, 1, 327682, 65536, 0, 393218, 131072, 0, 458754, 131072, 0, -524285, 65536, 0, -458749, 65536, 0, -393213, 131072, 0, -327677, 196608, 0, -262141, 0, 0, -196605, 65536, 0, -131069, 131072, 0, -65533, 131072, 0, 3, 196608, 0, 65539, 196608, 0, 131075, 0, 0, 196611, 0, 1, 262147, 65536, 1, 327683, 65536, 1, 393219, 196608, 0, 458755, 196608, 0, -524284, 0, 1, -458748, 65536, 0, -393212, 65536, 0, -327676, 0, 0, -262140, 65536, 1, -196604, 0, 1, -131068, 0, 1, -65532, 0, 1, 4, 0, 0, 65540, 65536, 1, 131076, 0, 0, 196612, 65536, 0, 262148, 131072, 0, 327684, 196608, 0, 393220, 196608, 0, 458756, 196608, 0, -524283, 65536, 1, -458747, 65536, 0, -393211, 65536, 1, -327675, 0, 0, -262139, 0, 1, -196603, 0, 1, -131067, 0, 1, -65531, 65536, 1, 5, 65536, 0, 65541, 65536, 0, 131077, 65536, 0, 196613, 0, 0, 262149, 196608, 0, 327685, 196608, 0, 393221, 131072, 0, 458757, 131072, 0, -524282, 0, 1, -458746, 0, 1, -393210, 0, 0, -327674, 65536, 0, -262138, 0, 0, -196602, 0, 1, -131066, 131072, 0, -65530, 196608, 0, 6, 65536, 0, 65542, 65536, 0, 131078, 0, 0, 196614, 0, 1, 262150, 65536, 0, 327686, 65536, 1, 393222, 0, 1, 458758, 0, 1, -524281, 65536, 0, -458745, 65536, 0, -393209, 196608, 0, -327673, 196608, 0, -262137, 196608, 0, -196601, 131072, 0, -131065, 196608, 0, -65529, 131072, 0, 7, 0, 1, 65543, 65536, 1, 131079, 0, 1, 196615, 0, 0, 262151, 0, 0, 327687, 0, 1, 393223, 65536, 0, 458759, 0, 1) +layer_4/tile_data = PackedInt32Array(-524296, 327680, 0, -589818, 262144, 0, -589817, 262144, 1, -589819, 327680, 0, -589820, 196608, 1, -589821, 327680, 1, -589822, 131072, 1, -589823, 262144, 1, -589824, 327680, 0, -524289, 131072, 1, -524290, 327680, 0, -524291, 327680, 1, -524292, 327680, 1, -524293, 327680, 0, -524294, 131072, 1, -524295, 262144, 1, -589832, 131072, 2, -589831, 131072, 2, -589830, 131072, 2, -589829, 131072, 2, -589828, 131072, 2, -589827, 131072, 2, -589826, 131072, 2, -589825, 131072, 2, -655360, 131072, 2, -655359, 131072, 2, -655358, 131072, 2, -655357, 131072, 2, -655356, 131072, 2, -655355, 131072, 2, -655354, 131072, 2, -655353, 131072, 2, -655352, 327680, 2, -589833, 262144, 2, -524297, 196608, 3, -458761, 196608, 3, -393225, 196608, 3, -327689, 196608, 3, -262153, 196608, 3, -196617, 196608, 3, -131081, 196608, 3, -65545, 196608, 3, -9, 196608, 3, 65527, 196608, 3, 131063, 196608, 3, 196599, 196608, 3, 262135, 196608, 3, 327671, 196608, 3, 393207, 196608, 3, 458743, 196608, 3, 524279, 196608, 3, 262152, 131072, 3, 327688, 131072, 3, 393224, 131072, 3, 458760, 131072, 3, 196616, 131072, 3, 131080, 131072, 3, 65544, 131072, 3, 8, 131072, 3, -65528, 131072, 3, -131064, 131072, 3, -196600, 131072, 3, -262136, 131072, 3, -589816, 131072, 3, -524280, 131072, 3, -458744, 131072, 3, -393208, 131072, 3, -327672, 131072, 3, 589816, 196608, 2, 589817, 196608, 2, 589818, 196608, 2, 589819, 196608, 2, 589820, 196608, 2, 589821, 196608, 2, 589822, 196608, 2, 589823, 196608, 2, 524288, 196608, 2, 524289, 196608, 2, 524290, 196608, 2, 524291, 196608, 2, 524292, 196608, 2, 524293, 196608, 2, 524294, 196608, 2, 524295, 196608, 2, 524296, 327680, 3, 589815, 262144, 3) + +[node name="CanvasModulate" parent="." index="0"] +color = Color(0.753984, 0.753984, 0.753984, 1) + +[node name="Doc" parent="Entities" index="0" instance=ExtResource("4_c0csw")] +material = SubResource("ShaderMaterial_wurwd") +PreferredWeightDistance = 256.0 +MaxWeightDistance = 32.0 +Health = 1000.0 diff --git a/Scenes/Maps/Hills.tscn b/Scenes/Maps/Hills.tscn index 4fe0066..3abe54d 100644 --- a/Scenes/Maps/Hills.tscn +++ b/Scenes/Maps/Hills.tscn @@ -212,31 +212,31 @@ physics_layer_0/collision_mask = 16 physics_layer_1/collision_layer = 1 sources/0 = SubResource("TileSetAtlasSource_dvbe3") -[sub_resource type="ShaderMaterial" id="ShaderMaterial_3sxqg"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_lhxal"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_r3w8l"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_ypbiq"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_2oi7o"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_rl34k"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_65pfr"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_txxdc"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_5a7w6"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_rqx80"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) @@ -268,23 +268,23 @@ layer_4/tile_data = PackedInt32Array(1114105, 196608, 3, 1114106, 262144, 3, 111 layer_5/tile_data = PackedInt32Array(786438, 262144, 3, 720899, 262144, 3, 851971, 458752, 3, 196611, 458752, 3, 1835019, 262144, 3, 1835034, 458752, 3) [node name="ExampleEnemy" parent="Entities" index="0" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_3sxqg") +material = SubResource("ShaderMaterial_lhxal") position = Vector2(169, 115) [node name="ExampleEnemy2" parent="Entities" index="1" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_r3w8l") +material = SubResource("ShaderMaterial_ypbiq") position = Vector2(75, 130) [node name="ExampleEnemy3" parent="Entities" index="2" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_2oi7o") +material = SubResource("ShaderMaterial_rl34k") position = Vector2(140, 177) [node name="ExampleEnemy4" parent="Entities" index="3" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_65pfr") +material = SubResource("ShaderMaterial_txxdc") position = Vector2(14, 159) [node name="ExampleEnemy5" parent="Entities" index="4" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_5a7w6") +material = SubResource("ShaderMaterial_rqx80") position = Vector2(10, 22) Faction = 1 diff --git a/State/NPC/Doc/DocAttackState.cs b/State/NPC/Doc/DocAttackState.cs new file mode 100644 index 0000000..bf37294 --- /dev/null +++ b/State/NPC/Doc/DocAttackState.cs @@ -0,0 +1,86 @@ +using Godot; +using GodotUtilities; + +namespace SupaLidlGame.State.NPC.Doc; + +public partial class DocAttackState : NPCState +{ + private Scenes.Map _map; + private Utils.World _world; + + private double _currentDuration = 0; + private double _currentAttackDuration = 0; + + [Export] + public double Duration { get; set; } + + [Export] + public double AttackDuration { get; set; } + + [Export] + public PackedScene Projectile { get; set; } + + [Export] + public DocExitState ExitState { get; set; } + + private float _intensity = 1; + + public override NPCState Enter(IState previousState) + { + _map = this.GetAncestor(); + _world = this.GetAncestor(); + _currentDuration = Duration; + _currentAttackDuration = AttackDuration; + return null; + } + + public override void Exit(IState nextState) + { + + } + + private void SpawnProjectile(Vector2 position, Vector2 direction) + { + var projectile = _map.SpawnEntity(Projectile); + projectile.Hitbox.Faction = NPC.Faction; + // global position is (from npc to player) * 2 = (2 * npc) - player + //projectile.GlobalPosition = 2 * NPC.GlobalPosition - playerPos; + projectile.GlobalPosition = position; + projectile.Direction = direction; + projectile.GlobalRotation = direction.Angle(); + projectile.Delay = 1 / _intensity; + } + + public override NPCState Process(double delta) + { + if ((_currentDuration -= delta) <= 0) + { + return ExitState; + } + + if (NPC.Health < 500) + { + _intensity = 2; + } + + if (NPC.Health < 250) + { + _intensity = 3; + } + + if ((_currentAttackDuration -= delta) <= 0) + { + var player = _world.CurrentPlayer; + var playerPos = player.GlobalPosition; + Vector2 position1 = 2 * NPC.GlobalPosition - playerPos; + Vector2 position2 = 2 * playerPos - NPC.GlobalPosition; + Vector2 direction1 = position1.DirectionTo(playerPos); + Vector2 direction2 = -direction1; + SpawnProjectile(position1, direction1); + SpawnProjectile(position2, direction2); + _currentAttackDuration = AttackDuration / _intensity; + } + + return null; + } +} diff --git a/State/NPC/Doc/DocExitState.cs b/State/NPC/Doc/DocExitState.cs new file mode 100644 index 0000000..b924cc1 --- /dev/null +++ b/State/NPC/Doc/DocExitState.cs @@ -0,0 +1,38 @@ +using Godot; + +namespace SupaLidlGame.State.NPC.Doc; + +public partial class DocExitState : NPCState +{ + [Export] + public AnimationPlayer TelegraphAnimationPlayer { get; set; } + + [Export] + public DocTelegraphState TelegraphState { get; set; } + + [Export] + public double Duration { get; set; } = 1; + + private double _currentDuration = 0; + + public override NPCState Enter(IState previousState) + { + _currentDuration = Duration; + TelegraphAnimationPlayer.Play("exit_out"); + return null; + } + + public override void Exit(IState nextState) + { + + } + + public override NPCState Process(double delta) + { + if ((_currentDuration -= delta) <= 0) + { + return TelegraphState; + } + return null; + } +} diff --git a/State/NPC/Doc/DocTelegraphState.cs b/State/NPC/Doc/DocTelegraphState.cs new file mode 100644 index 0000000..c19cdcd --- /dev/null +++ b/State/NPC/Doc/DocTelegraphState.cs @@ -0,0 +1,41 @@ +using Godot; + +namespace SupaLidlGame.State.NPC.Doc; + +public partial class DocTelegraphState : NPCState +{ + [Export] + public AnimationPlayer TelegraphAnimationPlayer { get; set; } + + [Export] + public DocAttackState AttackState { get; set; } + + [Export] + public double Duration { get; set; } = 1; + + private double _currentDuration = 1; + + public override NPCState Enter(IState previousState) + { + _currentDuration = Duration; + TelegraphAnimationPlayer.Play("enter_in"); + float randX = GD.RandRange(-128, 128); + float randY = GD.RandRange(-128, 128); + NPC.GlobalPosition = new Vector2(randX, randY); + return null; + } + + public override void Exit(IState nextState) + { + + } + + public override NPCState Process(double delta) + { + if ((_currentDuration -= delta) <= 0) + { + return AttackState; + } + return null; + } +} diff --git a/State/NPC/NPCState.cs b/State/NPC/NPCState.cs new file mode 100644 index 0000000..44564a8 --- /dev/null +++ b/State/NPC/NPCState.cs @@ -0,0 +1,18 @@ +using Godot; + +namespace SupaLidlGame.State.NPC; + +public abstract partial class NPCState : Node, IState +{ + [Export] + public SupaLidlGame.Characters.NPC NPC { get; set; } + + public abstract IState Enter(IState previousState); + + public virtual void Exit(IState nextState) + { + + } + + public virtual IState Process(double delta) => null; +} diff --git a/State/NPC/NPCStateMachine.cs b/State/NPC/NPCStateMachine.cs new file mode 100644 index 0000000..8905a58 --- /dev/null +++ b/State/NPC/NPCStateMachine.cs @@ -0,0 +1,18 @@ +using Godot; + +namespace SupaLidlGame.State.NPC; + +public partial class NPCStateMachine : StateMachine +{ + [Export] + public override NPCState InitialState { get; set; } + + public void Process(double delta) + { + var state = CurrentState.Process(delta); + if (state is NPCState s) + { + ChangeState(s); + } + } +} diff --git a/State/NPC/TelegraphState.cs b/State/NPC/TelegraphState.cs new file mode 100644 index 0000000..ee35116 --- /dev/null +++ b/State/NPC/TelegraphState.cs @@ -0,0 +1,19 @@ +using Godot; + +namespace SupaLidlGame.State.NPC; + +public partial class NPCTelegraphState : NPCState +{ + [Export] + public double Duration { get; set; } + + public override NPCState Enter(IState previousState) + { + return null; + } + + public override void Exit(IState nextState) + { + + } +} diff --git a/project.godot b/project.godot index 8bdfda5..e50529c 100644 --- a/project.godot +++ b/project.godot @@ -95,3 +95,7 @@ equip_3={ [physics] 2d/default_gravity=0.0 + +[rendering] + +environment/defaults/default_clear_color=Color(0.301961, 0.301961, 0.301961, 1) From 54c2bef86bec1805f4d810cb9e44362922315cff Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Mon, 17 Jul 2023 09:30:49 -0700 Subject: [PATCH 08/12] sprites for doc attack state --- Assets/Sprites/Misc/mini-shungite.ase | Bin 0 -> 680 bytes Assets/Sprites/Misc/mini-shungite.png | Bin 0 -> 296 bytes Assets/Sprites/Misc/shungite.ase | Bin 0 -> 6044 bytes Assets/Sprites/Misc/shungite.png | Bin 0 -> 414 bytes Assets/Sprites/Misc/shungite.png.import | 34 +++ Characters/Doc.cs | 6 + Characters/Doc.tscn | 6 +- Characters/Player.tscn | 6 +- Entities/Projectile.cs | 7 +- Entities/ShungiteSpike.cs | 13 + Entities/ShungiteSpike.tscn | 307 ++++++++++++++++++++++++ Scenes/Maps/Arena.tscn | 5 +- State/NPC/Doc/DocAttackState.cs | 10 +- Utils/DamageTime.cs | 41 ++++ 14 files changed, 418 insertions(+), 17 deletions(-) create mode 100644 Assets/Sprites/Misc/mini-shungite.ase create mode 100644 Assets/Sprites/Misc/mini-shungite.png create mode 100644 Assets/Sprites/Misc/shungite.ase create mode 100644 Assets/Sprites/Misc/shungite.png create mode 100644 Assets/Sprites/Misc/shungite.png.import create mode 100644 Entities/ShungiteSpike.cs create mode 100644 Entities/ShungiteSpike.tscn create mode 100644 Utils/DamageTime.cs diff --git a/Assets/Sprites/Misc/mini-shungite.ase b/Assets/Sprites/Misc/mini-shungite.ase new file mode 100644 index 0000000000000000000000000000000000000000..cc704c96a656d09cbc05ed58c27c2cd4eca3d3b9 GIT binary patch literal 680 zcmcJNyGue*0Edrh^q`?32_f?iicxyWjLZ^Af`}fZL)j!oxj024mQ6}TP!N&i5)F~$ z(o(cEL@fmo7(@g{kF6paT3hV9NLhbC2hPX2FV64#otrHa;whsNl|sW*2_dGKr6HG= z|FUXg|IZK2&#p2Nbkg^()<1jJOPvKFOkDx!3M|8s)gu@=zJ@#ZcTi`yLerQG`;u)i zy4wr07vu0MzXpd}l>70158R9S;Ylh2Zx2)O`Q`w&H<)42Vu4G8E$}#|@L@~&>g9AA z8nwzh9=#1ljY_smYb(t8T`<4shK+hB>@oXbykj12yI0_uFAX0TGO((;4%XHgpjO`m zCD{R;177H#iNQpA17;8R;d$;7zP-N|QuL!yPEDp8ilG%Mp%2QS32LAN3cwz9yphHj zU0e~x5=H!w!wfB)5W)r(JdnVE_+%$IsfkQp!jhDjWF#Qzh(<0#8I(+t`q#-3R#b?g wiMh~>WOHy)E)|~^IQ-&Je!tnxNw3d0AKwsjdK@5La;p3stK)o49WO{$0iU zE-$%zThdrpHB8T~$*6R>^NLdu7j8}T)i$c~a9mp+eqc)R^{rE$U)^jXqn@Cn)8VbX zuUz}yJjWLY3sgka9c2wmRVX>R8>dfOv31k&^JiYaeJRZustt6NUP+K&FvEXRK+yCLAP>rWx;Tb# z%uG%Q2n?d9XjF`HQ7Z~Xl_(MQp*U2AvQQHWLNzD_b)X1T0DQ0m9MnJtFJM6mOfUiv zbU*_apmI2qh_*&Q085i-Y3R7y2qAh6B7T(# z+EwP^2PUe29f{tHKg3)1duwWHs=OpfB}2Bp>&LS~tyh|1{#Wd|eB~_ukmGXEvr-~w zks!a2N%lXed!cfidO++r_3DM^!)Yj|)zu&VYySFYe(f1?T!)F8=@@(i*$sM|RXtLB89Kh)oE`)+2Vl+O+i9|&cUzm2Ui z7nGyMywX6)3eX;l{XCsB1gf;G_^qDw-r=*Z>`HR&uMds z5l1!9&ho*s*%JA$G4K1PU_Pqc-9r57i}@MFw8~;#&_TjF+HB0ww6y~tHA+%OMfR?0 z_wLKI-Nx$8F*Hw?)S?+`k!7L)EjNt$$fb2+>f*tjL1)ND+e=tOzbS@li=NMtn4uab zM#TgxSvslPSleNz!r7Ⓢ?AuO`*(B%^r z^-lT0;V*iMDNxBan%irAM31Kd%S!m$K(FsY*=I_xXGMCgPl;QTbp2i8)zn!*yUCeG@4m%ajF4fEd_Hxp( zQ$iVeHf}dF;$a?35*Y)dcb{xraA2x_#Fs zQ9NlR&3S_siN{V1_9Q{WO_D4jcKR2x)#l_R{oZS!urv}oml}v4s;T__pHqpQK*hE& t!d97s`WONd6D@f8IyTa|G2W|$TIs>+wps_#tPib!CQP3(+)=M9{{e#f*@XZA literal 0 HcmV?d00001 diff --git a/Assets/Sprites/Misc/shungite.png b/Assets/Sprites/Misc/shungite.png new file mode 100644 index 0000000000000000000000000000000000000000..491c22a93264bb254428e5dfea62f5aae7c15b9d GIT binary patch literal 414 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5I5?Prq+-X#ULe&K;1l91u3({R6=xII?ccwv zc;DqEcW+A?>#Bz7xiuM;E_YsWD&oSeiN4xKRUVFO%fk;$DZajS%JZw6O=Q#)baXnr zwfB{4-<#+7;$VS_sJf%9VX2D6QUinY;WoG0?BrxE9n=G>%&HgJ^&AVFe!pcYCzptT zh`gw*hJv2CrB^_BQF-I^X)CsFI)47l>$fkZIYYI9uF@+B@(X78PYMW{{sHJghN+$| zjv*eMM=vE%O=!Q_3Fy@l1VC_&tDvOR-GCW@#W?@~ literal 0 HcmV?d00001 diff --git a/Assets/Sprites/Misc/shungite.png.import b/Assets/Sprites/Misc/shungite.png.import new file mode 100644 index 0000000..1830fc6 --- /dev/null +++ b/Assets/Sprites/Misc/shungite.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dmeqjcc3uu4xi" +path="res://.godot/imported/shungite.png-b3a7d7db0635944f7318920460aea95b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Misc/shungite.png" +dest_files=["res://.godot/imported/shungite.png-b3a7d7db0635944f7318920460aea95b.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/Characters/Doc.cs b/Characters/Doc.cs index 6accedc..65562d6 100644 --- a/Characters/Doc.cs +++ b/Characters/Doc.cs @@ -6,6 +6,12 @@ public partial class Doc : Enemy { [Export] public State.NPC.NPCStateMachine BossStateMachine { get; set; } + + public override void _Ready() + { + GD.Print(Health); + base._Ready(); + } public override void _Process(double delta) { diff --git a/Characters/Doc.tscn b/Characters/Doc.tscn index 5378697..8545cf9 100644 --- a/Characters/Doc.tscn +++ b/Characters/Doc.tscn @@ -12,7 +12,7 @@ [ext_resource type="Script" path="res://State/NPC/Doc/DocAttackState.cs" id="8_r4l3q"] [ext_resource type="Script" path="res://Items/Inventory.cs" id="8_r8ejq"] [ext_resource type="Script" path="res://State/NPC/Doc/DocExitState.cs" id="9_6com1"] -[ext_resource type="PackedScene" uid="uid://bqvseo3sbs1aj" path="res://Entities/RailBeam.tscn" id="9_fcrmd"] +[ext_resource type="PackedScene" uid="uid://doiwdphocqlpo" path="res://Entities/ShungiteSpike.tscn" id="9_7kavk"] [ext_resource type="AudioStream" uid="uid://k6kpdj1kv0jg" path="res://Assets/Sounds/splat.ogg" id="9_stm0e"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_7n7iy"] @@ -204,7 +204,7 @@ collision_layer = 10 collision_mask = 17 script = ExtResource("2_3elet") BossStateMachine = NodePath("BossStateMachine") -Health = 50.0 +Health = 1000.0 Sprite = NodePath("Sprite") Inventory = NodePath("Inventory") StateMachine = NodePath("StateMachine") @@ -240,7 +240,7 @@ NPC = NodePath("../..") script = ExtResource("8_r4l3q") Duration = 8.0 AttackDuration = 1.0 -Projectile = ExtResource("9_fcrmd") +Projectile = ExtResource("9_7kavk") ExitState = NodePath("../Exit") NPC = NodePath("../..") diff --git a/Characters/Player.tscn b/Characters/Player.tscn index f54a756..b3a2f7e 100644 --- a/Characters/Player.tscn +++ b/Characters/Player.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=38 format=3 uid="uid://b2254pup8k161"] +[gd_scene load_steps=39 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"] @@ -14,6 +14,7 @@ [ext_resource type="AudioStream" uid="uid://bkeyg8weaqnuu" path="res://Assets/Sounds/splat-player.ogg" id="12_vvem5"] [ext_resource type="Script" path="res://BoundingBoxes/InteractionRay.cs" id="13_hs3u1"] [ext_resource type="Texture2D" uid="uid://coarr28adgo1u" path="res://Assets/Sprites/Particles/point-light.png" id="14_l4ekh"] +[ext_resource type="Script" path="res://Utils/DamageTime.cs" id="15_4xl06"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"] shader = ExtResource("2_ngsgt") @@ -328,4 +329,7 @@ shadow_filter_smooth = 3.0 texture = ExtResource("14_l4ekh") texture_scale = 0.5 +[node name="DamageTime" type="Node" parent="."] +script = ExtResource("15_4xl06") + [editable path="Hurtbox"] diff --git a/Entities/Projectile.cs b/Entities/Projectile.cs index 731fbfa..3e1a40c 100644 --- a/Entities/Projectile.cs +++ b/Entities/Projectile.cs @@ -44,11 +44,8 @@ public partial class Projectile : RigidBody2D public override void _PhysicsProcess(double delta) { - if (Delay <= 0) - { - Vector2 velocity = Velocity; - MoveAndCollide(velocity * (float)delta); - } + Vector2 velocity = Delay <= 0 ? Velocity : Vector2.Zero; + MoveAndCollide(velocity * (float)delta); } public void OnHit(BoundingBox box) diff --git a/Entities/ShungiteSpike.cs b/Entities/ShungiteSpike.cs new file mode 100644 index 0000000..63bc6ef --- /dev/null +++ b/Entities/ShungiteSpike.cs @@ -0,0 +1,13 @@ +using Godot; +namespace SupaLidlGame.Entities; + +public partial class ShungiteSpike : Projectile +{ + public override void _Ready() + { + var player = GetNode("AnimationPlayer"); + player.Play("spin"); + player.SpeedScale = (float)(1 / Delay); + base._Ready(); + } +} diff --git a/Entities/ShungiteSpike.tscn b/Entities/ShungiteSpike.tscn new file mode 100644 index 0000000..d7c8121 --- /dev/null +++ b/Entities/ShungiteSpike.tscn @@ -0,0 +1,307 @@ +[gd_scene load_steps=42 format=3 uid="uid://doiwdphocqlpo"] + +[ext_resource type="Script" path="res://Entities/ShungiteSpike.cs" id="1_pclpe"] +[ext_resource type="Texture2D" uid="uid://dmeqjcc3uu4xi" path="res://Assets/Sprites/Misc/shungite.png" id="2_gyvna"] +[ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="3_kojrj"] +[ext_resource type="Script" path="res://Utils/ProjectileTweeners/DelaySpin.cs" id="4_wy5kh"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_xmjp8"] +atlas = ExtResource("2_gyvna") +region = Rect2(0, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8i61s"] +atlas = ExtResource("2_gyvna") +region = Rect2(8, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_q000r"] +atlas = ExtResource("2_gyvna") +region = Rect2(16, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_0f7fg"] +atlas = ExtResource("2_gyvna") +region = Rect2(24, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_d34ii"] +atlas = ExtResource("2_gyvna") +region = Rect2(32, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_iybvf"] +atlas = ExtResource("2_gyvna") +region = Rect2(40, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_rninu"] +atlas = ExtResource("2_gyvna") +region = Rect2(48, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8vok2"] +atlas = ExtResource("2_gyvna") +region = Rect2(56, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_7tcc7"] +atlas = ExtResource("2_gyvna") +region = Rect2(64, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_sfa0w"] +atlas = ExtResource("2_gyvna") +region = Rect2(72, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_21chc"] +atlas = ExtResource("2_gyvna") +region = Rect2(80, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_iroma"] +atlas = ExtResource("2_gyvna") +region = Rect2(88, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_hbl5e"] +atlas = ExtResource("2_gyvna") +region = Rect2(96, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qlpso"] +atlas = ExtResource("2_gyvna") +region = Rect2(104, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_v65pa"] +atlas = ExtResource("2_gyvna") +region = Rect2(112, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_jotwh"] +atlas = ExtResource("2_gyvna") +region = Rect2(120, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_lu113"] +atlas = ExtResource("2_gyvna") +region = Rect2(128, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_w332l"] +atlas = ExtResource("2_gyvna") +region = Rect2(136, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_mg73k"] +atlas = ExtResource("2_gyvna") +region = Rect2(144, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_m0ogr"] +atlas = ExtResource("2_gyvna") +region = Rect2(152, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_py1jk"] +atlas = ExtResource("2_gyvna") +region = Rect2(160, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_0a8wd"] +atlas = ExtResource("2_gyvna") +region = Rect2(168, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8ut6e"] +atlas = ExtResource("2_gyvna") +region = Rect2(176, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_x5ucf"] +atlas = ExtResource("2_gyvna") +region = Rect2(184, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_13nfm"] +atlas = ExtResource("2_gyvna") +region = Rect2(192, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_uhjdb"] +atlas = ExtResource("2_gyvna") +region = Rect2(200, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_4vrn8"] +atlas = ExtResource("2_gyvna") +region = Rect2(208, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_4aa2t"] +atlas = ExtResource("2_gyvna") +region = Rect2(216, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_tn6f5"] +atlas = ExtResource("2_gyvna") +region = Rect2(224, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_60mwy"] +atlas = ExtResource("2_gyvna") +region = Rect2(232, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_d0xqb"] +atlas = ExtResource("2_gyvna") +region = Rect2(240, 0, 8, 8) + +[sub_resource type="AtlasTexture" id="AtlasTexture_j2hu2"] +atlas = ExtResource("2_gyvna") +region = Rect2(248, 0, 8, 8) + +[sub_resource type="SpriteFrames" id="SpriteFrames_6a2jq"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_xmjp8") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8i61s") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_q000r") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_0f7fg") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_d34ii") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_iybvf") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_rninu") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8vok2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_7tcc7") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_sfa0w") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_21chc") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_iroma") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_hbl5e") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_qlpso") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_v65pa") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_jotwh") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_lu113") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_w332l") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_mg73k") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_m0ogr") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_py1jk") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_0a8wd") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8ut6e") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_x5ucf") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_13nfm") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_uhjdb") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_4vrn8") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_4aa2t") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_tn6f5") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_60mwy") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_d0xqb") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_j2hu2") +}], +"loop": true, +"name": &"default", +"speed": 5.0 +}] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_fa7yf"] +size = Vector2(8, 4) + +[sub_resource type="Animation" id="Animation_tgj7f"] +resource_name = "spin" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [-4.71239, 1.5708] +} + +[sub_resource type="Animation" id="Animation_tcdo0"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [1.5708] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_pehte"] +_data = { +"RESET": SubResource("Animation_tcdo0"), +"spin": SubResource("Animation_tgj7f") +} + +[node name="ShungiteSpike" type="RigidBody2D" node_paths=PackedStringArray("Hitbox")] +script = ExtResource("1_pclpe") +Speed = 256.0 +Hitbox = NodePath("Hitbox") +Delay = 1.0 + +[node name="Sprite2D" type="AnimatedSprite2D" parent="."] +texture_filter = 1 +rotation = 1.5708 +sprite_frames = SubResource("SpriteFrames_6a2jq") +frame_progress = 0.227702 +speed_scale = 4.0 + +[node name="Hitbox" parent="." instance=ExtResource("3_kojrj")] +Damage = 25.0 +Knockback = 128.0 + +[node name="CollisionShape2D" parent="Hitbox" index="0"] +shape = SubResource("RectangleShape2D_fa7yf") + +[node name="DelaySpinTweener" type="Node" parent="."] +script = ExtResource("4_wy5kh") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_pehte") +} + +[editable path="Hitbox"] diff --git a/Scenes/Maps/Arena.tscn b/Scenes/Maps/Arena.tscn index d7b6104..56cbf2d 100644 --- a/Scenes/Maps/Arena.tscn +++ b/Scenes/Maps/Arena.tscn @@ -252,7 +252,7 @@ physics_layer_0/collision_layer = 1 sources/2 = SubResource("TileSetAtlasSource_5yxvt") sources/0 = SubResource("TileSetAtlasSource_fcd6d") -[sub_resource type="ShaderMaterial" id="ShaderMaterial_wurwd"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_hn0x7"] resource_local_to_scene = true shader = ExtResource("5_aevwf") shader_parameter/color = Quaternion(1, 1, 1, 1) @@ -268,7 +268,6 @@ layer_4/tile_data = PackedInt32Array(-524296, 327680, 0, -589818, 262144, 0, -58 color = Color(0.753984, 0.753984, 0.753984, 1) [node name="Doc" parent="Entities" index="0" instance=ExtResource("4_c0csw")] -material = SubResource("ShaderMaterial_wurwd") +material = SubResource("ShaderMaterial_hn0x7") PreferredWeightDistance = 256.0 MaxWeightDistance = 32.0 -Health = 1000.0 diff --git a/State/NPC/Doc/DocAttackState.cs b/State/NPC/Doc/DocAttackState.cs index bf37294..d4ee473 100644 --- a/State/NPC/Doc/DocAttackState.cs +++ b/State/NPC/Doc/DocAttackState.cs @@ -5,11 +5,11 @@ namespace SupaLidlGame.State.NPC.Doc; public partial class DocAttackState : NPCState { - private Scenes.Map _map; - private Utils.World _world; + protected Scenes.Map _map; + protected Utils.World _world; - private double _currentDuration = 0; - private double _currentAttackDuration = 0; + protected double _currentDuration = 0; + protected double _currentAttackDuration = 0; [Export] public double Duration { get; set; } @@ -39,7 +39,7 @@ public partial class DocAttackState : NPCState } - private void SpawnProjectile(Vector2 position, Vector2 direction) + protected virtual void SpawnProjectile(Vector2 position, Vector2 direction) { var projectile = _map.SpawnEntity(Projectile); projectile.Hitbox.Faction = NPC.Faction; diff --git a/Utils/DamageTime.cs b/Utils/DamageTime.cs new file mode 100644 index 0000000..ff213bf --- /dev/null +++ b/Utils/DamageTime.cs @@ -0,0 +1,41 @@ +using Godot; + +namespace SupaLidlGame.Utils; + +public partial class DamageTime : Node +{ + private double _duration = 0.1; + + private double _currentDuration = 0; + + private double _startValue = 0; + + public override void _Ready() + { + if (GetParent() is Characters.Player player) + { + player.Hurt += PlayerHurt; + } + } + + private void PlayerHurt(Events.HealthChangedArgs args) + { + if (args.Damage > 10) + { + // temp + //float strength = 0.8f; + //_startValue = 1 - strength; + //_currentDuration = 0; + _currentDuration = _duration; + Engine.TimeScale = 0.1; + } + } + + public override void _Process(double delta) + { + if ((_currentDuration -= delta) < 0) + { + Engine.TimeScale = 1; + } + } +} From ecfeb2f7641c7d94326957d7d7b6489d76986a30 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Mon, 17 Jul 2023 20:03:38 -0700 Subject: [PATCH 09/12] shungite spike state --- Assets/Sprites/Misc/mini-shungite.png.import | 34 +++++++++++++++++ Assets/Sprites/Misc/shungite-spike.ase | Bin 0 -> 838 bytes Assets/Sprites/Misc/shungite-spike.png | Bin 0 -> 458 bytes Assets/Sprites/Misc/shungite-spike.png.import | 34 +++++++++++++++++ State/NPC/Doc/DocAttackState.cs | 31 +++++++++------ State/NPC/Doc/DocShungiteSpikeState.cs | 36 ++++++++++++++++++ 6 files changed, 124 insertions(+), 11 deletions(-) create mode 100644 Assets/Sprites/Misc/mini-shungite.png.import create mode 100644 Assets/Sprites/Misc/shungite-spike.ase create mode 100644 Assets/Sprites/Misc/shungite-spike.png create mode 100644 Assets/Sprites/Misc/shungite-spike.png.import create mode 100644 State/NPC/Doc/DocShungiteSpikeState.cs diff --git a/Assets/Sprites/Misc/mini-shungite.png.import b/Assets/Sprites/Misc/mini-shungite.png.import new file mode 100644 index 0000000..6aeb4a9 --- /dev/null +++ b/Assets/Sprites/Misc/mini-shungite.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://debqunpkdemj2" +path="res://.godot/imported/mini-shungite.png-01bdbec41fe54ed8fc826d4314ec257e.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Misc/mini-shungite.png" +dest_files=["res://.godot/imported/mini-shungite.png-01bdbec41fe54ed8fc826d4314ec257e.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/Assets/Sprites/Misc/shungite-spike.ase b/Assets/Sprites/Misc/shungite-spike.ase new file mode 100644 index 0000000000000000000000000000000000000000..2d0291901d2e4ad1f3ee17b8ac9e8bb8f48f61a4 GIT binary patch literal 838 zcmcJN?MqWp0Edq@QTt$i&{Rmh#>7Y++N5bMX;>z1HaDWJB5{%VNim15te}O&(nX}E zP*GSdC)Jli=*>}N77}UZOIVuV2dyxQ1Y0HRxkXBUK<9EF&b{2r`8~gL@|OrP;RzBF zSC|MALhR*U9ID0Xf0^|J3-SGnVqsMk5#pr3tET_6W{i{_5F&Y93DlM}K;!9q(C&K$ zua3Qeaq4uKyj=zJkFS9>?Rn7KYlZ!zXJApP{Jyq82X8to@L{tZj&wG|siE62Yefny zO-q9=eJb=hWR72y|C)YO1(nhAH@f&tSfiA)c``C!pG6BtPvpXc_#C(~#RO~D9)_25 z-LS{h3g6XvVEED~7#WoaqvKaWNu_}~g~iZP?SRhK7U=D~1)ugkhaYF&2b$?eA@7=s zZYYLUsDwT!gC?kf4k!S7)bU0dV{~yv6iXEGLk=^va6$+hRPaCo1LBjN;G`xpc?nBW zVv>=7q$3)+2$d*jk~mfigRml07;J~is-?^!9zrDX`=|xj{68as<9G1F*~T3ailnej zIff^L^TzDnm9A?|9hW|Rwia$vZuXno9;nr`$AT+e4K_>U^oHf0i1M~sg?0Zx_(bg1 z@*}!$RTTwSitFq4nC^7vUKh4@ebRvHS&Qj_!rh@sx6jYLHNO^XI}g$Y}#Gl=v#equCy#>U-#tB*IwnR Z7;Dk}t}dt6tns^kI%|fPg^cL(egUtx3(Eii literal 0 HcmV?d00001 diff --git a/Assets/Sprites/Misc/shungite-spike.png b/Assets/Sprites/Misc/shungite-spike.png new file mode 100644 index 0000000000000000000000000000000000000000..7b0591a8779c9f6f279a99b50ce9a2648f6c6e22 GIT binary patch literal 458 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyT>(BJuHp(7s#b9}aozs?yNdT+ zUUK)gq_M7Qn4VjcQR#B$6{jLD+?wdCZB*sqxVAj}z?9!#!9&%A#7QkpYV8|W&%k|4iehX161py?k#9z5vj;uvDl zJ9SbZ-w_247t1qCX8xXEAQ}*mG3)8_-p>t;q9+}HcCc({eZ1v5>m4gAN$Y+Ng)ZNQ ztQK{L^aNEV14h3Cjf%dqi7wig88jN4#f2Xzew%5T$gCQ2e)6lEtaGJV<_WHM`1D|Z zYP+VK!rL!b)%BO~P1<$C=eXG^j&(0({AC}WkQG_&seRft!%OkWJyrd?+y&JqShhvx zE116d6_O*S`C2rx$i2Yx-AaLfc46O(;!lfTI%t`0c$N2)dZKUrlzvBNk-SiIpl297 MUHx3vIVCg!04dhY0RR91 literal 0 HcmV?d00001 diff --git a/Assets/Sprites/Misc/shungite-spike.png.import b/Assets/Sprites/Misc/shungite-spike.png.import new file mode 100644 index 0000000..2fd120b --- /dev/null +++ b/Assets/Sprites/Misc/shungite-spike.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dvx2b0y6dup53" +path="res://.godot/imported/shungite-spike.png-3c88db04670aa56f0aed81fe7332990b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Assets/Sprites/Misc/shungite-spike.png" +dest_files=["res://.godot/imported/shungite-spike.png-3c88db04670aa56f0aed81fe7332990b.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/State/NPC/Doc/DocAttackState.cs b/State/NPC/Doc/DocAttackState.cs index d4ee473..fdae8a3 100644 --- a/State/NPC/Doc/DocAttackState.cs +++ b/State/NPC/Doc/DocAttackState.cs @@ -1,5 +1,6 @@ using Godot; using GodotUtilities; +using SupaLidlGame.Entities; namespace SupaLidlGame.State.NPC.Doc; @@ -39,9 +40,11 @@ public partial class DocAttackState : NPCState } - protected virtual void SpawnProjectile(Vector2 position, Vector2 direction) + protected virtual Projectile SpawnProjectile( + Vector2 position, + Vector2 direction) { - var projectile = _map.SpawnEntity(Projectile); + var projectile = _map.SpawnEntity(Projectile); projectile.Hitbox.Faction = NPC.Faction; // global position is (from npc to player) * 2 = (2 * npc) - player //projectile.GlobalPosition = 2 * NPC.GlobalPosition - playerPos; @@ -49,6 +52,20 @@ public partial class DocAttackState : NPCState projectile.Direction = direction; projectile.GlobalRotation = direction.Angle(); projectile.Delay = 1 / _intensity; + return projectile; + } + + protected virtual void Attack() + { + var player = _world.CurrentPlayer; + var playerPos = player.GlobalPosition; + Vector2 position1 = 2 * NPC.GlobalPosition - playerPos; + Vector2 position2 = 2 * playerPos - NPC.GlobalPosition; + Vector2 direction1 = position1.DirectionTo(playerPos); + Vector2 direction2 = -direction1; + SpawnProjectile(position1, direction1); + SpawnProjectile(position2, direction2); + _currentAttackDuration = AttackDuration / _intensity; } public override NPCState Process(double delta) @@ -70,15 +87,7 @@ public partial class DocAttackState : NPCState if ((_currentAttackDuration -= delta) <= 0) { - var player = _world.CurrentPlayer; - var playerPos = player.GlobalPosition; - Vector2 position1 = 2 * NPC.GlobalPosition - playerPos; - Vector2 position2 = 2 * playerPos - NPC.GlobalPosition; - Vector2 direction1 = position1.DirectionTo(playerPos); - Vector2 direction2 = -direction1; - SpawnProjectile(position1, direction1); - SpawnProjectile(position2, direction2); - _currentAttackDuration = AttackDuration / _intensity; + Attack(); } return null; diff --git a/State/NPC/Doc/DocShungiteSpikeState.cs b/State/NPC/Doc/DocShungiteSpikeState.cs new file mode 100644 index 0000000..2b23149 --- /dev/null +++ b/State/NPC/Doc/DocShungiteSpikeState.cs @@ -0,0 +1,36 @@ +using Godot; +using GodotUtilities; +using SupaLidlGame.Entities; + +namespace SupaLidlGame.State.NPC.Doc; + +public partial class DocShungiteSpikeState : DocAttackState +{ + private float _intensity = 1; + + protected override Projectile SpawnProjectile( + Vector2 position, + Vector2 direction) + { + var projectile = base.SpawnProjectile(position, direction); + projectile.Delay = 4; + return projectile; + } + + protected override void Attack() + { + var player = _world.CurrentPlayer; + var playerPos = player.GlobalPosition; + Vector2 left = playerPos + Vector2.Left * 64; + Vector2 right = playerPos + Vector2.Right * 64; + Vector2 up = playerPos + Vector2.Up * 64; + Vector2 down = playerPos + Vector2.Down * 64; + SpawnProjectile(left, Vector2.Zero); + SpawnProjectile(right, Vector2.Zero); + SpawnProjectile(up, Vector2.Zero); + SpawnProjectile(down, Vector2.Zero); + + // only attack once and stop (but keep in this state for 8 seconds) + _currentAttackDuration = float.PositiveInfinity; + } +} From df3799910ce9a739266cbe5eaadae545f6d30730 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Mon, 17 Jul 2023 20:18:42 -0700 Subject: [PATCH 10/12] attack -> shungite dart, new abstract attack state --- Characters/Doc.tscn | 6 +- State/NPC/Doc/DocAttackState.cs | 91 ++---------------------- State/NPC/Doc/DocShungiteDartState.cs | 95 ++++++++++++++++++++++++++ State/NPC/Doc/DocShungiteSpikeState.cs | 3 +- 4 files changed, 105 insertions(+), 90 deletions(-) create mode 100644 State/NPC/Doc/DocShungiteDartState.cs diff --git a/Characters/Doc.tscn b/Characters/Doc.tscn index 8545cf9..cbd6f0e 100644 --- a/Characters/Doc.tscn +++ b/Characters/Doc.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=33 format=3 uid="uid://bt6s40u515jvo"] +[gd_scene load_steps=33 format=3 uid="uid://dsr5kkbthpwpl"] [ext_resource type="Script" path="res://Characters/Doc.cs" id="2_3elet"] [ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="2_5jxom"] @@ -9,7 +9,7 @@ [ext_resource type="Script" path="res://State/NPC/NPCStateMachine.cs" id="6_kjpug"] [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/DocAttackState.cs" id="8_r4l3q"] +[ext_resource type="Script" path="res://State/NPC/Doc/DocShungiteDartState.cs" id="8_1hoax"] [ext_resource type="Script" path="res://Items/Inventory.cs" id="8_r8ejq"] [ext_resource type="Script" path="res://State/NPC/Doc/DocExitState.cs" id="9_6com1"] [ext_resource type="PackedScene" uid="uid://doiwdphocqlpo" path="res://Entities/ShungiteSpike.tscn" id="9_7kavk"] @@ -237,7 +237,7 @@ AttackState = NodePath("../Attack") NPC = NodePath("../..") [node name="Attack" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("ExitState", "NPC")] -script = ExtResource("8_r4l3q") +script = ExtResource("8_1hoax") Duration = 8.0 AttackDuration = 1.0 Projectile = ExtResource("9_7kavk") diff --git a/State/NPC/Doc/DocAttackState.cs b/State/NPC/Doc/DocAttackState.cs index fdae8a3..aaeac51 100644 --- a/State/NPC/Doc/DocAttackState.cs +++ b/State/NPC/Doc/DocAttackState.cs @@ -1,95 +1,16 @@ using Godot; -using GodotUtilities; -using SupaLidlGame.Entities; namespace SupaLidlGame.State.NPC.Doc; -public partial class DocAttackState : NPCState +public abstract partial class DocAttackState : NPCState { - protected Scenes.Map _map; - protected Utils.World _world; + public abstract double Duration { get; set; } - protected double _currentDuration = 0; - protected double _currentAttackDuration = 0; + public abstract double AttackDuration { get; set; } - [Export] - public double Duration { get; set; } + public abstract PackedScene Projectile { get; set; } - [Export] - public double AttackDuration { get; set; } + public abstract DocExitState ExitState { get; set; } - [Export] - public PackedScene Projectile { get; set; } - - [Export] - public DocExitState ExitState { get; set; } - - private float _intensity = 1; - - public override NPCState Enter(IState previousState) - { - _map = this.GetAncestor(); - _world = this.GetAncestor(); - _currentDuration = Duration; - _currentAttackDuration = AttackDuration; - return null; - } - - public override void Exit(IState nextState) - { - - } - - protected virtual Projectile SpawnProjectile( - Vector2 position, - Vector2 direction) - { - var projectile = _map.SpawnEntity(Projectile); - projectile.Hitbox.Faction = NPC.Faction; - // global position is (from npc to player) * 2 = (2 * npc) - player - //projectile.GlobalPosition = 2 * NPC.GlobalPosition - playerPos; - projectile.GlobalPosition = position; - projectile.Direction = direction; - projectile.GlobalRotation = direction.Angle(); - projectile.Delay = 1 / _intensity; - return projectile; - } - - protected virtual void Attack() - { - var player = _world.CurrentPlayer; - var playerPos = player.GlobalPosition; - Vector2 position1 = 2 * NPC.GlobalPosition - playerPos; - Vector2 position2 = 2 * playerPos - NPC.GlobalPosition; - Vector2 direction1 = position1.DirectionTo(playerPos); - Vector2 direction2 = -direction1; - SpawnProjectile(position1, direction1); - SpawnProjectile(position2, direction2); - _currentAttackDuration = AttackDuration / _intensity; - } - - public override NPCState Process(double delta) - { - if ((_currentDuration -= delta) <= 0) - { - return ExitState; - } - - if (NPC.Health < 500) - { - _intensity = 2; - } - - if (NPC.Health < 250) - { - _intensity = 3; - } - - if ((_currentAttackDuration -= delta) <= 0) - { - Attack(); - } - - return null; - } + protected abstract void Attack(); } diff --git a/State/NPC/Doc/DocShungiteDartState.cs b/State/NPC/Doc/DocShungiteDartState.cs new file mode 100644 index 0000000..5a19af9 --- /dev/null +++ b/State/NPC/Doc/DocShungiteDartState.cs @@ -0,0 +1,95 @@ +using Godot; +using GodotUtilities; +using SupaLidlGame.Entities; + +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; } + + [Export] + public override double AttackDuration { get; set; } + + [Export] + public override PackedScene Projectile { get; set; } + + [Export] + public override DocExitState ExitState { get; set; } + + private float _intensity = 1; + + public override NPCState Enter(IState previousState) + { + _map = this.GetAncestor(); + _world = this.GetAncestor(); + _currentDuration = Duration; + _currentAttackDuration = AttackDuration; + return null; + } + + public override void Exit(IState nextState) + { + + } + + protected virtual Projectile SpawnProjectile( + Vector2 position, + Vector2 direction) + { + var projectile = _map.SpawnEntity(Projectile); + projectile.Hitbox.Faction = NPC.Faction; + // global position is (from npc to player) * 2 = (2 * npc) - player + //projectile.GlobalPosition = 2 * NPC.GlobalPosition - playerPos; + projectile.GlobalPosition = position; + projectile.Direction = direction; + projectile.GlobalRotation = direction.Angle(); + projectile.Delay = 1 / _intensity; + return projectile; + } + + protected override void Attack() + { + var player = _world.CurrentPlayer; + var playerPos = player.GlobalPosition; + Vector2 position1 = 2 * NPC.GlobalPosition - playerPos; + Vector2 position2 = 2 * playerPos - NPC.GlobalPosition; + Vector2 direction1 = position1.DirectionTo(playerPos); + Vector2 direction2 = -direction1; + SpawnProjectile(position1, direction1); + SpawnProjectile(position2, direction2); + _currentAttackDuration = AttackDuration / _intensity; + } + + public override NPCState Process(double delta) + { + if ((_currentDuration -= delta) <= 0) + { + return ExitState; + } + + if (NPC.Health < 500) + { + _intensity = 2; + } + + if (NPC.Health < 250) + { + _intensity = 3; + } + + if ((_currentAttackDuration -= delta) <= 0) + { + Attack(); + } + + return null; + } +} diff --git a/State/NPC/Doc/DocShungiteSpikeState.cs b/State/NPC/Doc/DocShungiteSpikeState.cs index 2b23149..b8968bd 100644 --- a/State/NPC/Doc/DocShungiteSpikeState.cs +++ b/State/NPC/Doc/DocShungiteSpikeState.cs @@ -1,10 +1,9 @@ using Godot; -using GodotUtilities; using SupaLidlGame.Entities; namespace SupaLidlGame.State.NPC.Doc; -public partial class DocShungiteSpikeState : DocAttackState +public partial class DocShungiteSpikeState : DocShungiteDartState { private float _intensity = 1; From 65fe4cf03d5f523ef81d2dc4ef7fd0c8318697b2 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Mon, 17 Jul 2023 23:54:07 -0700 Subject: [PATCH 11/12] rename shungite spike to shungite dart --- Characters/Doc.tscn | 6 +- .../{ShungiteSpike.cs => ShungiteDart.cs} | 2 +- .../{ShungiteSpike.tscn => ShungiteDart.tscn} | 112 +++++++++--------- Scenes/Maps/Arena.tscn | 6 +- 4 files changed, 61 insertions(+), 65 deletions(-) rename Entities/{ShungiteSpike.cs => ShungiteDart.cs} (84%) rename Entities/{ShungiteSpike.tscn => ShungiteDart.tscn} (80%) diff --git a/Characters/Doc.tscn b/Characters/Doc.tscn index cbd6f0e..6cedbb9 100644 --- a/Characters/Doc.tscn +++ b/Characters/Doc.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=33 format=3 uid="uid://dsr5kkbthpwpl"] +[gd_scene load_steps=33 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"] @@ -12,7 +12,7 @@ [ext_resource type="Script" path="res://State/NPC/Doc/DocShungiteDartState.cs" id="8_1hoax"] [ext_resource type="Script" path="res://Items/Inventory.cs" id="8_r8ejq"] [ext_resource type="Script" path="res://State/NPC/Doc/DocExitState.cs" id="9_6com1"] -[ext_resource type="PackedScene" uid="uid://doiwdphocqlpo" path="res://Entities/ShungiteSpike.tscn" id="9_7kavk"] +[ext_resource type="PackedScene" uid="uid://djaljmco3xo4g" path="res://Entities/ShungiteDart.tscn" id="9_kthpr"] [ext_resource type="AudioStream" uid="uid://k6kpdj1kv0jg" path="res://Assets/Sounds/splat.ogg" id="9_stm0e"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_7n7iy"] @@ -240,7 +240,7 @@ NPC = NodePath("../..") script = ExtResource("8_1hoax") Duration = 8.0 AttackDuration = 1.0 -Projectile = ExtResource("9_7kavk") +Projectile = ExtResource("9_kthpr") ExitState = NodePath("../Exit") NPC = NodePath("../..") diff --git a/Entities/ShungiteSpike.cs b/Entities/ShungiteDart.cs similarity index 84% rename from Entities/ShungiteSpike.cs rename to Entities/ShungiteDart.cs index 63bc6ef..f6d0a29 100644 --- a/Entities/ShungiteSpike.cs +++ b/Entities/ShungiteDart.cs @@ -1,7 +1,7 @@ using Godot; namespace SupaLidlGame.Entities; -public partial class ShungiteSpike : Projectile +public partial class ShungiteDart : Projectile { public override void _Ready() { diff --git a/Entities/ShungiteSpike.tscn b/Entities/ShungiteDart.tscn similarity index 80% rename from Entities/ShungiteSpike.tscn rename to Entities/ShungiteDart.tscn index d7c8121..302dd9e 100644 --- a/Entities/ShungiteSpike.tscn +++ b/Entities/ShungiteDart.tscn @@ -1,136 +1,135 @@ -[gd_scene load_steps=42 format=3 uid="uid://doiwdphocqlpo"] +[gd_scene load_steps=41 format=3 uid="uid://djaljmco3xo4g"] -[ext_resource type="Script" path="res://Entities/ShungiteSpike.cs" id="1_pclpe"] -[ext_resource type="Texture2D" uid="uid://dmeqjcc3uu4xi" path="res://Assets/Sprites/Misc/shungite.png" id="2_gyvna"] -[ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="3_kojrj"] -[ext_resource type="Script" path="res://Utils/ProjectileTweeners/DelaySpin.cs" id="4_wy5kh"] +[ext_resource type="Script" path="res://Entities/ShungiteDart.cs" id="1_jbgb8"] +[ext_resource type="Texture2D" uid="uid://dmeqjcc3uu4xi" path="res://Assets/Sprites/Misc/shungite.png" id="2_eh4e1"] +[ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="3_gdyk8"] [sub_resource type="AtlasTexture" id="AtlasTexture_xmjp8"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(0, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_8i61s"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(8, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_q000r"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(16, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_0f7fg"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(24, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_d34ii"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(32, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_iybvf"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(40, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_rninu"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(48, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_8vok2"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(56, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_7tcc7"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(64, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_sfa0w"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(72, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_21chc"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(80, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_iroma"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(88, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_hbl5e"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(96, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_qlpso"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(104, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_v65pa"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(112, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_jotwh"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(120, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_lu113"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(128, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_w332l"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(136, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_mg73k"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(144, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_m0ogr"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(152, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_py1jk"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(160, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_0a8wd"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(168, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_8ut6e"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(176, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_x5ucf"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(184, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_13nfm"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(192, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_uhjdb"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(200, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_4vrn8"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(208, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_4aa2t"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(216, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_tn6f5"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(224, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_60mwy"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(232, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_d0xqb"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(240, 0, 8, 8) [sub_resource type="AtlasTexture" id="AtlasTexture_j2hu2"] -atlas = ExtResource("2_gyvna") +atlas = ExtResource("2_eh4e1") region = Rect2(248, 0, 8, 8) [sub_resource type="SpriteFrames" id="SpriteFrames_6a2jq"] @@ -240,21 +239,6 @@ animations = [{ [sub_resource type="RectangleShape2D" id="RectangleShape2D_fa7yf"] size = Vector2(8, 4) -[sub_resource type="Animation" id="Animation_tgj7f"] -resource_name = "spin" -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Sprite2D:rotation") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0, 0.5), -"transitions": PackedFloat32Array(1, 1), -"update": 0, -"values": [-4.71239, 1.5708] -} - [sub_resource type="Animation" id="Animation_tcdo0"] length = 0.001 tracks/0/type = "value" @@ -270,14 +254,29 @@ tracks/0/keys = { "values": [1.5708] } +[sub_resource type="Animation" id="Animation_tgj7f"] +resource_name = "spin" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [-4.71239, 1.5708] +} + [sub_resource type="AnimationLibrary" id="AnimationLibrary_pehte"] _data = { "RESET": SubResource("Animation_tcdo0"), "spin": SubResource("Animation_tgj7f") } -[node name="ShungiteSpike" type="RigidBody2D" node_paths=PackedStringArray("Hitbox")] -script = ExtResource("1_pclpe") +[node name="ShungiteDart" type="RigidBody2D" node_paths=PackedStringArray("Hitbox")] +script = ExtResource("1_jbgb8") Speed = 256.0 Hitbox = NodePath("Hitbox") Delay = 1.0 @@ -289,16 +288,13 @@ sprite_frames = SubResource("SpriteFrames_6a2jq") frame_progress = 0.227702 speed_scale = 4.0 -[node name="Hitbox" parent="." instance=ExtResource("3_kojrj")] +[node name="Hitbox" parent="." instance=ExtResource("3_gdyk8")] Damage = 25.0 Knockback = 128.0 [node name="CollisionShape2D" parent="Hitbox" index="0"] shape = SubResource("RectangleShape2D_fa7yf") -[node name="DelaySpinTweener" type="Node" parent="."] -script = ExtResource("4_wy5kh") - [node name="AnimationPlayer" type="AnimationPlayer" parent="."] libraries = { "": SubResource("AnimationLibrary_pehte") diff --git a/Scenes/Maps/Arena.tscn b/Scenes/Maps/Arena.tscn index 56cbf2d..c5db8f1 100644 --- a/Scenes/Maps/Arena.tscn +++ b/Scenes/Maps/Arena.tscn @@ -3,7 +3,7 @@ [ext_resource type="PackedScene" uid="uid://clwv2owvk6abe" path="res://Scenes/BaseMap.tscn" id="1_ifiic"] [ext_resource type="Texture2D" uid="uid://b0yiy7w8nxmas" path="res://Assets/Sprites/arena-tileset.png" id="2_wnjm0"] [ext_resource type="Texture2D" uid="uid://5k0o7d7j65a4" path="res://Assets/Sprites/arena-tileset-normal.png" id="3_iitgk"] -[ext_resource type="PackedScene" uid="uid://bt6s40u515jvo" path="res://Characters/Doc.tscn" id="4_c0csw"] +[ext_resource type="PackedScene" uid="uid://dsr5kkbthpwpl" path="res://Characters/Doc.tscn" id="4_c0csw"] [ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="5_aevwf"] [sub_resource type="OccluderPolygon2D" id="OccluderPolygon2D_8jil2"] @@ -252,7 +252,7 @@ physics_layer_0/collision_layer = 1 sources/2 = SubResource("TileSetAtlasSource_5yxvt") sources/0 = SubResource("TileSetAtlasSource_fcd6d") -[sub_resource type="ShaderMaterial" id="ShaderMaterial_hn0x7"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_4g4ap"] resource_local_to_scene = true shader = ExtResource("5_aevwf") shader_parameter/color = Quaternion(1, 1, 1, 1) @@ -268,6 +268,6 @@ layer_4/tile_data = PackedInt32Array(-524296, 327680, 0, -589818, 262144, 0, -58 color = Color(0.753984, 0.753984, 0.753984, 1) [node name="Doc" parent="Entities" index="0" instance=ExtResource("4_c0csw")] -material = SubResource("ShaderMaterial_hn0x7") +material = SubResource("ShaderMaterial_4g4ap") PreferredWeightDistance = 256.0 MaxWeightDistance = 32.0 From 9dd4525fcd41727e41ab9845a48a9c15cba81834 Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Tue, 18 Jul 2023 00:57:28 -0700 Subject: [PATCH 12/12] new attack --- Characters/Doc.cs | 16 +++++ Characters/Doc.tscn | 26 +++++++- Entities/ShungiteDart.cs | 8 ++- Entities/ShungiteSpike.cs | 72 +++++++++++++++++++++ Entities/ShungiteSpike.tscn | 87 ++++++++++++++++++++++++++ Scenes/Maps/Hills.tscn | 20 +++--- State/NPC/Doc/DocAttackState.cs | 2 +- State/NPC/Doc/DocChooseAttackState.cs | 51 +++++++++++++++ State/NPC/Doc/DocShungiteDartState.cs | 21 ++----- State/NPC/Doc/DocShungiteSpikeState.cs | 32 +++++++++- State/NPC/Doc/DocTelegraphState.cs | 2 +- 11 files changed, 302 insertions(+), 35 deletions(-) create mode 100644 Entities/ShungiteSpike.cs create mode 100644 Entities/ShungiteSpike.tscn create mode 100644 State/NPC/Doc/DocChooseAttackState.cs diff --git a/Characters/Doc.cs b/Characters/Doc.cs index 65562d6..67d9a2b 100644 --- a/Characters/Doc.cs +++ b/Characters/Doc.cs @@ -7,6 +7,22 @@ public partial class Doc : Enemy [Export] public State.NPC.NPCStateMachine BossStateMachine { get; set; } + public int Intensity + { + get + { + switch (Health) + { + case < 250: + return 3; + case < 500: + return 2; + default: + return 1; + } + } + } + public override void _Ready() { GD.Print(Health); diff --git a/Characters/Doc.tscn b/Characters/Doc.tscn index 6cedbb9..fef7ca4 100644 --- a/Characters/Doc.tscn +++ b/Characters/Doc.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=33 format=3 uid="uid://d2skjvvx6fal0"] +[gd_scene load_steps=36 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"] @@ -12,8 +12,11 @@ [ext_resource type="Script" path="res://State/NPC/Doc/DocShungiteDartState.cs" id="8_1hoax"] [ext_resource type="Script" path="res://Items/Inventory.cs" id="8_r8ejq"] [ext_resource type="Script" path="res://State/NPC/Doc/DocExitState.cs" id="9_6com1"] +[ext_resource type="PackedScene" uid="uid://1tiswf3gtyvv" path="res://Entities/ShungiteSpike.tscn" id="9_7kavk"] [ext_resource type="PackedScene" uid="uid://djaljmco3xo4g" path="res://Entities/ShungiteDart.tscn" id="9_kthpr"] [ext_resource type="AudioStream" uid="uid://k6kpdj1kv0jg" path="res://Assets/Sounds/splat.ogg" id="9_stm0e"] +[ext_resource type="Script" path="res://State/NPC/Doc/DocShungiteSpikeState.cs" id="10_bgs6o"] +[ext_resource type="Script" path="res://State/NPC/Doc/DocChooseAttackState.cs" id="12_45x13"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_7n7iy"] resource_local_to_scene = true @@ -233,14 +236,31 @@ InitialState = NodePath("Telegraph") [node name="Telegraph" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("TelegraphAnimationPlayer", "AttackState", "NPC")] script = ExtResource("7_tfwbh") TelegraphAnimationPlayer = NodePath("../../Animations/Telegraph") -AttackState = NodePath("../Attack") +AttackState = NodePath("../ChooseAttack") NPC = NodePath("../..") -[node name="Attack" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("ExitState", "NPC")] +[node name="Dart" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("ChooseAttackState", "Doc", "NPC")] script = ExtResource("8_1hoax") Duration = 8.0 AttackDuration = 1.0 Projectile = ExtResource("9_kthpr") +ChooseAttackState = NodePath("../ChooseAttack") +Doc = NodePath("../..") +NPC = NodePath("../..") + +[node name="Spike" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("ChooseAttackState", "Doc", "NPC")] +script = ExtResource("10_bgs6o") +Duration = 8.0 +AttackDuration = 1.0 +Projectile = ExtResource("9_7kavk") +ChooseAttackState = NodePath("../ChooseAttack") +Doc = NodePath("../..") +NPC = NodePath("../..") + +[node name="ChooseAttack" type="Node" parent="BossStateMachine" node_paths=PackedStringArray("DartState", "SpikeState", "ExitState", "NPC")] +script = ExtResource("12_45x13") +DartState = NodePath("../Dart") +SpikeState = NodePath("../Spike") ExitState = NodePath("../Exit") NPC = NodePath("../..") diff --git a/Entities/ShungiteDart.cs b/Entities/ShungiteDart.cs index f6d0a29..302c3db 100644 --- a/Entities/ShungiteDart.cs +++ b/Entities/ShungiteDart.cs @@ -1,4 +1,5 @@ using Godot; + namespace SupaLidlGame.Entities; public partial class ShungiteDart : Projectile @@ -6,8 +7,11 @@ public partial class ShungiteDart : Projectile public override void _Ready() { var player = GetNode("AnimationPlayer"); - player.Play("spin"); - player.SpeedScale = (float)(1 / Delay); + if (Delay > 0) + { + player.Play("spin"); + player.SpeedScale = (float)(1 / Delay); + } base._Ready(); } } diff --git a/Entities/ShungiteSpike.cs b/Entities/ShungiteSpike.cs new file mode 100644 index 0000000..c2d8d90 --- /dev/null +++ b/Entities/ShungiteSpike.cs @@ -0,0 +1,72 @@ +using Godot; +using GodotUtilities; +using SupaLidlGame.Extensions; + +namespace SupaLidlGame.Entities; + +public partial class ShungiteSpike : Projectile +{ + [Export] + public PackedScene Dart { get; set; } + + [Export] + public double ExplodeTime { get; set; } = 6; + + [Export] + public BoundingBoxes.Hurtbox Hurtbox { get; set; } + + [Export] + public AudioStreamPlayer2D HitSound { get; set; } + + [Export] + public AnimationPlayer AnimationPlayer { get; set; } + + private double _currentExplodeTime; + + private Scenes.Map _map; + + public override void _Ready() + { + _currentExplodeTime = ExplodeTime; + _map = this.GetAncestor(); + + Hurtbox.ReceivedDamage += OnReceivedDamage; + AnimationPlayer.Play("spin"); + + base._Ready(); + } + + private void OnReceivedDamage( + float damage, + Characters.Character inflictor, + float knockback, + Vector2 knockbackOrigin = default, + Vector2 knockbackVector = default) + { + HitSound.At(GlobalPosition).PlayOneShot(); + QueueFree(); + } + + + private Entities.ShungiteDart CreateDart(Vector2 direction) + { + var dart = _map.SpawnEntity(Dart); + dart.Direction = direction; + dart.Hitbox.Faction = Hitbox.Faction; + dart.GlobalPosition = GlobalPosition; + dart.Delay = 0; + return dart; + } + + public override void _Process(double delta) + { + if ((_currentExplodeTime -= delta) <= 0) + { + CreateDart(Vector2.Up); + CreateDart(Vector2.Down); + CreateDart(Vector2.Left); + CreateDart(Vector2.Right); + QueueFree(); + } + } +} diff --git a/Entities/ShungiteSpike.tscn b/Entities/ShungiteSpike.tscn new file mode 100644 index 0000000..9393476 --- /dev/null +++ b/Entities/ShungiteSpike.tscn @@ -0,0 +1,87 @@ +[gd_scene load_steps=12 format=3 uid="uid://1tiswf3gtyvv"] + +[ext_resource type="Script" path="res://Entities/ShungiteSpike.cs" id="1_pclpe"] +[ext_resource type="PackedScene" uid="uid://djaljmco3xo4g" path="res://Entities/ShungiteDart.tscn" id="2_hinxt"] +[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"] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_konb7"] + +[sub_resource type="CircleShape2D" id="CircleShape2D_kumrg"] +radius = 20.0 + +[sub_resource type="Animation" id="Animation_dlpaa"] +resource_name = "spin" +length = 0.5 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:rotation") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 6.28319] +} + +[sub_resource type="Animation" id="Animation_0vfvo"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:rotation") +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_jj1qe"] +_data = { +"RESET": SubResource("Animation_0vfvo"), +"spin": SubResource("Animation_dlpaa") +} + +[node name="ShungiteSpike" type="RigidBody2D" node_paths=PackedStringArray("Hurtbox", "HitSound", "Hitbox")] +script = ExtResource("1_pclpe") +Dart = ExtResource("2_hinxt") +Hurtbox = NodePath("Hurtbox") +HitSound = NodePath("AudioStreamPlayer2D") +Hitbox = NodePath("Hitbox") + +[node name="Sprite2D" type="Sprite2D" parent="."] +modulate = Color(1.4, 0, 1.2, 1) +self_modulate = Color(2, 2, 2, 1) +texture_filter = 1 +texture = ExtResource("2_klp8v") + +[node name="Hitbox" parent="." instance=ExtResource("3_kojrj")] +Damage = 10.0 +Knockback = 256.0 + +[node name="CollisionShape2D" parent="Hitbox" index="0"] +shape = SubResource("RectangleShape2D_konb7") + +[node name="Hurtbox" parent="." instance=ExtResource("4_d8dl4")] + +[node name="CollisionShape2D" parent="Hurtbox" index="0"] +shape = SubResource("CircleShape2D_kumrg") + +[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."] +stream = ExtResource("6_fepye") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_jj1qe") +} + +[editable path="Hitbox"] +[editable path="Hurtbox"] diff --git a/Scenes/Maps/Hills.tscn b/Scenes/Maps/Hills.tscn index 3abe54d..896b900 100644 --- a/Scenes/Maps/Hills.tscn +++ b/Scenes/Maps/Hills.tscn @@ -212,31 +212,31 @@ physics_layer_0/collision_mask = 16 physics_layer_1/collision_layer = 1 sources/0 = SubResource("TileSetAtlasSource_dvbe3") -[sub_resource type="ShaderMaterial" id="ShaderMaterial_lhxal"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_5ho8d"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_ypbiq"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_tic7i"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_rl34k"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_oh7dr"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_txxdc"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_x6kxt"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/intensity = 0.0 -[sub_resource type="ShaderMaterial" id="ShaderMaterial_rqx80"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_uuq2q"] resource_local_to_scene = true shader = ExtResource("4_mwgaq") shader_parameter/color = Quaternion(1, 1, 1, 1) @@ -268,23 +268,23 @@ layer_4/tile_data = PackedInt32Array(1114105, 196608, 3, 1114106, 262144, 3, 111 layer_5/tile_data = PackedInt32Array(786438, 262144, 3, 720899, 262144, 3, 851971, 458752, 3, 196611, 458752, 3, 1835019, 262144, 3, 1835034, 458752, 3) [node name="ExampleEnemy" parent="Entities" index="0" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_lhxal") +material = SubResource("ShaderMaterial_5ho8d") position = Vector2(169, 115) [node name="ExampleEnemy2" parent="Entities" index="1" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_ypbiq") +material = SubResource("ShaderMaterial_tic7i") position = Vector2(75, 130) [node name="ExampleEnemy3" parent="Entities" index="2" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_rl34k") +material = SubResource("ShaderMaterial_oh7dr") position = Vector2(140, 177) [node name="ExampleEnemy4" parent="Entities" index="3" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_txxdc") +material = SubResource("ShaderMaterial_x6kxt") position = Vector2(14, 159) [node name="ExampleEnemy5" parent="Entities" index="4" instance=ExtResource("3_hwof6")] -material = SubResource("ShaderMaterial_rqx80") +material = SubResource("ShaderMaterial_uuq2q") position = Vector2(10, 22) Faction = 1 diff --git a/State/NPC/Doc/DocAttackState.cs b/State/NPC/Doc/DocAttackState.cs index aaeac51..2caf1ec 100644 --- a/State/NPC/Doc/DocAttackState.cs +++ b/State/NPC/Doc/DocAttackState.cs @@ -10,7 +10,7 @@ public abstract partial class DocAttackState : NPCState public abstract PackedScene Projectile { get; set; } - public abstract DocExitState ExitState { get; set; } + public abstract DocChooseAttackState ChooseAttackState { get; set; } protected abstract void Attack(); } diff --git a/State/NPC/Doc/DocChooseAttackState.cs b/State/NPC/Doc/DocChooseAttackState.cs new file mode 100644 index 0000000..6959bd7 --- /dev/null +++ b/State/NPC/Doc/DocChooseAttackState.cs @@ -0,0 +1,51 @@ +using Godot; +using System.Collections.Generic; + +namespace SupaLidlGame.State.NPC.Doc; + +public partial class DocChooseAttackState : NPCState +{ + [Export] + public DocShungiteDartState DartState { get; set; } + + [Export] + public DocShungiteSpikeState SpikeState { get; set; } + + [Export] + public DocExitState ExitState { get; set; } + + public Characters.Doc Doc => NPC as Characters.Doc; + + private List _states = new List(); + + private int _consecutiveAttacks = 0; + + public override void _Ready() + { + _states.Add(DartState); + _states.Add(SpikeState); + base._Ready(); + } + + public override NPCState Enter(IState previous) + { + if (previous is not DocTelegraphState) + { + _consecutiveAttacks++; + } + else + { + _consecutiveAttacks = 0; + } + + if (_consecutiveAttacks > Doc.Intensity) + { + _consecutiveAttacks = 0; + return ExitState; + } + + // choose random attack + var random = new System.Random(); + return _states[random.Next(_states.Count)]; + } +} diff --git a/State/NPC/Doc/DocShungiteDartState.cs b/State/NPC/Doc/DocShungiteDartState.cs index 5a19af9..f2b2601 100644 --- a/State/NPC/Doc/DocShungiteDartState.cs +++ b/State/NPC/Doc/DocShungiteDartState.cs @@ -22,9 +22,10 @@ public partial class DocShungiteDartState : DocAttackState public override PackedScene Projectile { get; set; } [Export] - public override DocExitState ExitState { get; set; } + public override DocChooseAttackState ChooseAttackState { get; set; } - private float _intensity = 1; + [Export] + public Characters.Doc Doc { get; set; } public override NPCState Enter(IState previousState) { @@ -51,7 +52,7 @@ public partial class DocShungiteDartState : DocAttackState projectile.GlobalPosition = position; projectile.Direction = direction; projectile.GlobalRotation = direction.Angle(); - projectile.Delay = 1 / _intensity; + projectile.Delay = 1.0 / Doc.Intensity; return projectile; } @@ -65,24 +66,14 @@ public partial class DocShungiteDartState : DocAttackState Vector2 direction2 = -direction1; SpawnProjectile(position1, direction1); SpawnProjectile(position2, direction2); - _currentAttackDuration = AttackDuration / _intensity; + _currentAttackDuration = AttackDuration / Doc.Intensity; } public override NPCState Process(double delta) { if ((_currentDuration -= delta) <= 0) { - return ExitState; - } - - if (NPC.Health < 500) - { - _intensity = 2; - } - - if (NPC.Health < 250) - { - _intensity = 3; + return ChooseAttackState; } if ((_currentAttackDuration -= delta) <= 0) diff --git a/State/NPC/Doc/DocShungiteSpikeState.cs b/State/NPC/Doc/DocShungiteSpikeState.cs index b8968bd..6f76bcb 100644 --- a/State/NPC/Doc/DocShungiteSpikeState.cs +++ b/State/NPC/Doc/DocShungiteSpikeState.cs @@ -7,12 +7,23 @@ public partial class DocShungiteSpikeState : DocShungiteDartState { private float _intensity = 1; + public override NPCState Enter(IState previous) + { + // subtract from total state time by intensity + Duration = _currentDuration = 9 - 2 * Doc.Intensity; + return base.Enter(previous); + } + protected override Projectile SpawnProjectile( Vector2 position, Vector2 direction) { - var projectile = base.SpawnProjectile(position, direction); - projectile.Delay = 4; + var projectile = base.SpawnProjectile(position, direction) + as ShungiteSpike; + projectile.GlobalRotation = 0; + projectile.Delay = 0; + projectile.ExplodeTime = 6 - 2 * Doc.Intensity; + projectile.Hitbox.Faction = projectile.Hurtbox.Faction = Doc.Faction; return projectile; } @@ -30,6 +41,21 @@ public partial class DocShungiteSpikeState : DocShungiteDartState SpawnProjectile(down, Vector2.Zero); // only attack once and stop (but keep in this state for 8 seconds) - _currentAttackDuration = float.PositiveInfinity; + _currentAttackDuration += 8; + } + + public override NPCState Process(double delta) + { + if ((_currentDuration -= delta) <= 0) + { + return ChooseAttackState; + } + + if ((_currentAttackDuration -= delta) <= 0) + { + Attack(); + } + + return null; } } diff --git a/State/NPC/Doc/DocTelegraphState.cs b/State/NPC/Doc/DocTelegraphState.cs index c19cdcd..33649af 100644 --- a/State/NPC/Doc/DocTelegraphState.cs +++ b/State/NPC/Doc/DocTelegraphState.cs @@ -8,7 +8,7 @@ public partial class DocTelegraphState : NPCState public AnimationPlayer TelegraphAnimationPlayer { get; set; } [Export] - public DocAttackState AttackState { get; set; } + public DocChooseAttackState AttackState { get; set; } [Export] public double Duration { get; set; } = 1;