new attack
parent
65fe4cf03d
commit
9dd4525fcd
|
@ -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);
|
||||
|
|
|
@ -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("../..")
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"]
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)];
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue