new attack

pull/3/head
John Montagu, the 4th Earl of Sandvich 2023-07-18 00:57:28 -07:00
parent 65fe4cf03d
commit 9dd4525fcd
Signed by: sandvich
GPG Key ID: 9A39BE37E602B22D
11 changed files with 302 additions and 35 deletions

View File

@ -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);

View File

@ -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("../..")

View File

@ -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>("AnimationPlayer");
if (Delay > 0)
{
player.Play("spin");
player.SpeedScale = (float)(1 / Delay);
}
base._Ready();
}
}

View File

@ -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<Scenes.Map>();
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<Entities.ShungiteDart>(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();
}
}
}

View File

@ -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"]

View File

@ -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

View File

@ -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();
}

View File

@ -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<NPCState> _states = new List<NPCState>();
private int _consecutiveAttacks = 0;
public override void _Ready()
{
_states.Add(DartState);
_states.Add(SpikeState);
base._Ready();
}
public override NPCState Enter(IState<NPCState> 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)];
}
}

View File

@ -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<NPCState> 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)

View File

@ -7,12 +7,23 @@ public partial class DocShungiteSpikeState : DocShungiteDartState
{
private float _intensity = 1;
public override NPCState Enter(IState<NPCState> 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;
}
}

View File

@ -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;