sword rework
parent
6349b5b8b2
commit
7dfd061c16
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 325 B |
|
@ -35,16 +35,10 @@ namespace SupaLidlGame.Items
|
||||||
[Export]
|
[Export]
|
||||||
public float InitialVelocity { get; set; } = 0;
|
public float InitialVelocity { get; set; } = 0;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether or not the weapon can parry other weapons and is
|
|
||||||
/// parryable by other weapons.
|
|
||||||
/// </summary>
|
|
||||||
public virtual bool IsParryable { get; protected set; } = false;
|
public virtual bool IsParryable { get; protected set; } = false;
|
||||||
|
|
||||||
public bool IsParried { get; set; }
|
public bool IsParried { get; set; }
|
||||||
|
|
||||||
public ulong ParryTimeOrigin { get; protected set; }
|
|
||||||
|
|
||||||
public Character Character { get; set; }
|
public Character Character { get; set; }
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
|
@ -53,6 +47,9 @@ namespace SupaLidlGame.Items
|
||||||
[Export]
|
[Export]
|
||||||
public float MaxDistanceHint { get; set; }
|
public float MaxDistanceHint { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Node2D Anchor { get; set; }
|
||||||
|
|
||||||
public override bool StacksWith(Item item) => false;
|
public override bool StacksWith(Item item) => false;
|
||||||
|
|
||||||
public override void Equip(Character character)
|
public override void Equip(Character character)
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace SupaLidlGame.Items.Weapons
|
||||||
|
{
|
||||||
|
public interface IParryable
|
||||||
|
{
|
||||||
|
public bool IsParryable { get; }
|
||||||
|
public bool IsParried { get; }
|
||||||
|
public ulong ParryTimeOrigin { get; }
|
||||||
|
public void Stun();
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,19 +2,26 @@ using Godot;
|
||||||
using SupaLidlGame.BoundingBoxes;
|
using SupaLidlGame.BoundingBoxes;
|
||||||
using SupaLidlGame.Characters;
|
using SupaLidlGame.Characters;
|
||||||
using SupaLidlGame.Extensions;
|
using SupaLidlGame.Extensions;
|
||||||
|
using SupaLidlGame.State.Sword;
|
||||||
|
|
||||||
namespace SupaLidlGame.Items.Weapons
|
namespace SupaLidlGame.Items.Weapons
|
||||||
{
|
{
|
||||||
public partial class Sword : Weapon
|
public partial class Sword : Weapon, IParryable
|
||||||
{
|
{
|
||||||
public bool IsAttacking { get; protected set; }
|
public bool IsAttacking { get; protected set; }
|
||||||
|
|
||||||
|
public override bool IsUsing => StateMachine.CurrentState
|
||||||
|
is SwordAttackState;
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public Hitbox Hitbox { get; set; }
|
public Hitbox Hitbox { get; set; }
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public AnimationPlayer AnimationPlayer { get; set; }
|
public AnimationPlayer AnimationPlayer { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public AnimationTree AnimationTree { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The time frame in seconds for which the weapon will deal damage.
|
/// The time frame in seconds for which the weapon will deal damage.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -25,29 +32,25 @@ namespace SupaLidlGame.Items.Weapons
|
||||||
[Export]
|
[Export]
|
||||||
public double AttackTime { get; set; } = 0;
|
public double AttackTime { get; set; } = 0;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public double AttackAnimationDuration { get; set; }
|
||||||
|
|
||||||
[Export]
|
[Export]
|
||||||
public CpuParticles2D ParryParticles { get; set; }
|
public CpuParticles2D ParryParticles { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public double NPCAnticipateTime { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public SwordStateMachine StateMachine { get; set; }
|
||||||
|
|
||||||
public override bool IsParryable { get; protected set; }
|
public override bool IsParryable { get; protected set; }
|
||||||
|
|
||||||
[Export]
|
public ulong ParryTimeOrigin { get; protected set; }
|
||||||
public float AnticipationAngle { get; set; }
|
|
||||||
|
|
||||||
[Export]
|
private Tween _currentTween;
|
||||||
public float OvershootAngle { get; set; }
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public float RecoveryAngle { get; set; }
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public float AnticipationDuration { get; set; }
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public float OvershootDuration { get; set; }
|
|
||||||
|
|
||||||
[Export]
|
|
||||||
public float RecoveryDuration { get; set; }
|
|
||||||
|
|
||||||
|
private AnimationNodeStateMachinePlayback _playback;
|
||||||
|
|
||||||
public override void Equip(Character character)
|
public override void Equip(Character character)
|
||||||
{
|
{
|
||||||
|
@ -67,17 +70,22 @@ namespace SupaLidlGame.Items.Weapons
|
||||||
// we can't use if we're still using the weapon
|
// we can't use if we're still using the weapon
|
||||||
if (RemainingUseTime > 0)
|
if (RemainingUseTime > 0)
|
||||||
{
|
{
|
||||||
return;
|
//return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StateMachine.Use();
|
||||||
|
|
||||||
|
/*
|
||||||
// reset state of the weapon
|
// reset state of the weapon
|
||||||
IsParried = false;
|
IsParried = false;
|
||||||
IsParryable = true;
|
IsParryable = true;
|
||||||
ParryTimeOrigin = Time.GetTicksMsec();
|
ParryTimeOrigin = Time.GetTicksMsec();
|
||||||
|
|
||||||
AnimationPlayer.Stop();
|
_playback.Travel("use");
|
||||||
|
*/
|
||||||
|
|
||||||
// play animation depending on rotation of weapon
|
// play animation depending on rotation of weapon
|
||||||
|
/*
|
||||||
string anim = "use";
|
string anim = "use";
|
||||||
|
|
||||||
if (GetNode<Node2D>("Anchor").Rotation > Mathf.DegToRad(50))
|
if (GetNode<Node2D>("Anchor").Rotation > Mathf.DegToRad(50))
|
||||||
|
@ -92,10 +100,24 @@ namespace SupaLidlGame.Items.Weapons
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimationPlayer.Play(anim);
|
AnimationPlayer.Play(anim);
|
||||||
|
*/
|
||||||
|
|
||||||
base.Use();
|
base.Use();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void EnableParry()
|
||||||
|
{
|
||||||
|
IsParried = false;
|
||||||
|
IsParryable = true;
|
||||||
|
ParryTimeOrigin = Time.GetTicksMsec();
|
||||||
|
GD.Print(Character.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DisableParry()
|
||||||
|
{
|
||||||
|
IsParryable = false;
|
||||||
|
}
|
||||||
|
|
||||||
public override void Deuse()
|
public override void Deuse()
|
||||||
{
|
{
|
||||||
//AnimationPlayer.Stop();
|
//AnimationPlayer.Stop();
|
||||||
|
@ -113,7 +135,7 @@ namespace SupaLidlGame.Items.Weapons
|
||||||
public void Deattack()
|
public void Deattack()
|
||||||
{
|
{
|
||||||
IsAttacking = false;
|
IsAttacking = false;
|
||||||
IsParryable = false;
|
DisableParry();
|
||||||
Hitbox.IsDisabled = true;
|
Hitbox.IsDisabled = true;
|
||||||
ProcessHits();
|
ProcessHits();
|
||||||
Hitbox.ResetIgnoreList();
|
Hitbox.ResetIgnoreList();
|
||||||
|
@ -123,10 +145,13 @@ namespace SupaLidlGame.Items.Weapons
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
Hitbox.Damage = Damage;
|
Hitbox.Damage = Damage;
|
||||||
|
_playback = (AnimationNodeStateMachinePlayback)AnimationTree
|
||||||
|
.Get("parameters/playback");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
|
StateMachine.Process(delta);
|
||||||
base._Process(delta);
|
base._Process(delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,23 +174,31 @@ namespace SupaLidlGame.Items.Weapons
|
||||||
|
|
||||||
public void AttemptParry(Weapon otherWeapon)
|
public void AttemptParry(Weapon otherWeapon)
|
||||||
{
|
{
|
||||||
if (IsParryable && otherWeapon.IsParryable)
|
//if (IsParryable && otherWeapon.IsParryable)
|
||||||
|
if (otherWeapon.IsParryable &&
|
||||||
|
otherWeapon is IParryable otherParryable)
|
||||||
{
|
{
|
||||||
ParryParticles.Emitting = true;
|
ParryParticles.Emitting = true;
|
||||||
if (ParryTimeOrigin < otherWeapon.ParryTimeOrigin)
|
if (ParryTimeOrigin < otherParryable.ParryTimeOrigin)
|
||||||
{
|
{
|
||||||
// our character was parried
|
// our character was parried
|
||||||
IsParried = true;
|
}
|
||||||
AnimationPlayer.SpeedScale = 0.25f;
|
else
|
||||||
Character.Stun(1.5f);
|
{
|
||||||
GD.Print(ParryTimeOrigin);
|
otherParryable.Stun();
|
||||||
GD.Print(otherWeapon.ParryTimeOrigin);
|
|
||||||
GetNode<AudioStreamPlayer2D>("ParrySound").OnWorld().Play();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//this.GetAncestor<TileMap>().AddChild(instance);
|
//this.GetAncestor<TileMap>().AddChild(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Stun()
|
||||||
|
{
|
||||||
|
IsParried = true;
|
||||||
|
AnimationPlayer.SpeedScale = 0.25f;
|
||||||
|
Character.Stun(1.5f);
|
||||||
|
GetNode<AudioStreamPlayer2D>("ParrySound").OnWorld().Play();
|
||||||
|
}
|
||||||
|
|
||||||
public override void _on_hitbox_hit(BoundingBox box)
|
public override void _on_hitbox_hit(BoundingBox box)
|
||||||
{
|
{
|
||||||
if (IsParried)
|
if (IsParried)
|
||||||
|
@ -194,5 +227,10 @@ namespace SupaLidlGame.Items.Weapons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void SetAnimationCondition(string condition, bool value)
|
||||||
|
{
|
||||||
|
AnimationTree.Set("parameters/conditions/" + condition, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,21 @@
|
||||||
[gd_scene load_steps=20 format=3 uid="uid://d72ehtv1ks0e"]
|
[gd_scene load_steps=35 format=3 uid="uid://d72ehtv1ks0e"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://Items/Weapons/Sword.cs" id="1_mlo73"]
|
[ext_resource type="Script" path="res://Items/Weapons/Sword.cs" id="1_mlo73"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dt6u8p4h6g7le" path="res://Assets/Sprites/knife.png" id="2_rnfo4"]
|
[ext_resource type="Script" path="res://State/Sword/SwordStateMachine.cs" id="2_rje2m"]
|
||||||
|
[ext_resource type="Script" path="res://State/Sword/SwordIdleState.cs" id="3_qh2cs"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dp7osg05ip5oo" path="res://Assets/Sprites/sword.png" id="3_r75ni"]
|
||||||
[ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="3_up3ob"]
|
[ext_resource type="PackedScene" uid="uid://du5vhccg75nrq" path="res://BoundingBoxes/Hitbox.tscn" id="3_up3ob"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cojxmcin13ihm" path="res://Utils/Trail.tscn" id="4_pt6lq"]
|
[ext_resource type="PackedScene" uid="uid://cojxmcin13ihm" path="res://Utils/Trail.tscn" id="4_pt6lq"]
|
||||||
|
[ext_resource type="Script" path="res://State/Sword/SwordAnticipateState.cs" id="4_ycuhw"]
|
||||||
|
[ext_resource type="Script" path="res://State/Sword/SwordAttackState.cs" id="5_30003"]
|
||||||
[ext_resource type="Texture2D" uid="uid://do1bui3bblkk7" path="res://Assets/Sprites/sword-swing.png" id="5_pywek"]
|
[ext_resource type="Texture2D" uid="uid://do1bui3bblkk7" path="res://Assets/Sprites/sword-swing.png" id="5_pywek"]
|
||||||
[ext_resource type="AudioStream" uid="uid://c4n7ioxpukdwi" path="res://Assets/Sounds/parry.wav" id="6_8nxjm"]
|
[ext_resource type="AudioStream" uid="uid://c4n7ioxpukdwi" path="res://Assets/Sounds/parry.wav" id="6_8nxjm"]
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_72txp"]
|
||||||
|
background_mode = 3
|
||||||
|
glow_enabled = true
|
||||||
|
glow_hdr_threshold = 1.42
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_4cxtp"]
|
[sub_resource type="Curve" id="Curve_4cxtp"]
|
||||||
_data = [Vector2(0.00687286, 1), 0.0, 0.0, 0, 0, Vector2(0.879725, 0.190909), -2.93145, -2.93145, 0, 0, Vector2(1, 0.0454545), 0.0483926, 0.0, 0, 0]
|
_data = [Vector2(0.00687286, 1), 0.0, 0.0, 0, 0, Vector2(0.879725, 0.190909), -2.93145, -2.93145, 0, 0, Vector2(1, 0.0454545), 0.0483926, 0.0, 0, 0]
|
||||||
point_count = 3
|
point_count = 3
|
||||||
|
@ -30,8 +39,8 @@ tracks/0/loop_wrap = true
|
||||||
tracks/0/keys = {
|
tracks/0/keys = {
|
||||||
"times": PackedFloat32Array(0),
|
"times": PackedFloat32Array(0),
|
||||||
"transitions": PackedFloat32Array(1),
|
"transitions": PackedFloat32Array(1),
|
||||||
"update": 0,
|
"update": 1,
|
||||||
"values": [-0.610865]
|
"values": [-1.5708]
|
||||||
}
|
}
|
||||||
tracks/1/type = "value"
|
tracks/1/type = "value"
|
||||||
tracks/1/imported = false
|
tracks/1/imported = false
|
||||||
|
@ -45,151 +54,94 @@ tracks/1/keys = {
|
||||||
"update": 1,
|
"update": 1,
|
||||||
"values": [0]
|
"values": [0]
|
||||||
}
|
}
|
||||||
|
tracks/2/type = "value"
|
||||||
|
tracks/2/imported = false
|
||||||
|
tracks/2/enabled = true
|
||||||
|
tracks/2/path = NodePath("Anchor:position")
|
||||||
|
tracks/2/interp = 1
|
||||||
|
tracks/2/loop_wrap = true
|
||||||
|
tracks/2/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 1,
|
||||||
|
"values": [Vector2(0, 0)]
|
||||||
|
}
|
||||||
|
tracks/3/type = "value"
|
||||||
|
tracks/3/imported = false
|
||||||
|
tracks/3/enabled = true
|
||||||
|
tracks/3/path = NodePath("Anchor/Node2D:rotation")
|
||||||
|
tracks/3/interp = 1
|
||||||
|
tracks/3/loop_wrap = true
|
||||||
|
tracks/3/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 0.0001, 0.0002),
|
||||||
|
"transitions": PackedFloat32Array(1, 1, 1),
|
||||||
|
"update": 1,
|
||||||
|
"values": [0.0, 0.0, 0.0]
|
||||||
|
}
|
||||||
|
tracks/4/type = "method"
|
||||||
|
tracks/4/imported = false
|
||||||
|
tracks/4/enabled = true
|
||||||
|
tracks/4/path = NodePath(".")
|
||||||
|
tracks/4/interp = 1
|
||||||
|
tracks/4/loop_wrap = true
|
||||||
|
tracks/4/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"values": [{
|
||||||
|
"args": ["is_alternate", false],
|
||||||
|
"method": &"SetAnimationCondition"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_r58x0"]
|
[sub_resource type="Animation" id="Animation_ameas"]
|
||||||
|
resource_name = "anticipate"
|
||||||
|
length = 0.1
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("Anchor:rotation")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(0.933033),
|
||||||
|
"update": 1,
|
||||||
|
"values": [-2.35619]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_bj2ky"]
|
||||||
|
resource_name = "anticipate_alternate"
|
||||||
|
length = 0.1
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("Anchor:rotation")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 1,
|
||||||
|
"values": [2.35619]
|
||||||
|
}
|
||||||
|
tracks/1/type = "value"
|
||||||
|
tracks/1/imported = false
|
||||||
|
tracks/1/enabled = true
|
||||||
|
tracks/1/path = NodePath("Anchor/Node2D:rotation")
|
||||||
|
tracks/1/interp = 1
|
||||||
|
tracks/1/loop_wrap = true
|
||||||
|
tracks/1/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [3.14159]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_b8r8j"]
|
||||||
|
resource_name = "anticipate_bot"
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_6jphj"]
|
||||||
resource_name = "attack"
|
resource_name = "attack"
|
||||||
length = 1.5
|
|
||||||
step = 0.05
|
|
||||||
tracks/0/type = "value"
|
|
||||||
tracks/0/imported = false
|
|
||||||
tracks/0/enabled = true
|
|
||||||
tracks/0/path = NodePath("Anchor:rotation")
|
|
||||||
tracks/0/interp = 1
|
|
||||||
tracks/0/loop_wrap = false
|
|
||||||
tracks/0/keys = {
|
|
||||||
"times": PackedFloat32Array(0.05, 0.1, 0.2, 0.25, 0.75, 1.5),
|
|
||||||
"transitions": PackedFloat32Array(1, 4, 1, 2, 4, 1),
|
|
||||||
"update": 3,
|
|
||||||
"values": [-0.610865, -0.959931, 3.92699, 3.92699, 3.75246, -0.785398]
|
|
||||||
}
|
|
||||||
tracks/1/type = "method"
|
|
||||||
tracks/1/imported = false
|
|
||||||
tracks/1/enabled = true
|
|
||||||
tracks/1/path = NodePath(".")
|
|
||||||
tracks/1/interp = 1
|
|
||||||
tracks/1/loop_wrap = true
|
|
||||||
tracks/1/keys = {
|
|
||||||
"times": PackedFloat32Array(0.1, 0.25),
|
|
||||||
"transitions": PackedFloat32Array(1, 1),
|
|
||||||
"values": [{
|
|
||||||
"args": [],
|
|
||||||
"method": &"Attack"
|
|
||||||
}, {
|
|
||||||
"args": [],
|
|
||||||
"method": &"Deattack"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
tracks/2/type = "value"
|
|
||||||
tracks/2/imported = false
|
|
||||||
tracks/2/enabled = true
|
|
||||||
tracks/2/path = NodePath("SwingSprite:frame")
|
|
||||||
tracks/2/interp = 1
|
|
||||||
tracks/2/loop_wrap = true
|
|
||||||
tracks/2/keys = {
|
|
||||||
"times": PackedFloat32Array(0, 0.2, 0.3, 0.4),
|
|
||||||
"transitions": PackedFloat32Array(1, 1, 1, 1),
|
|
||||||
"update": 1,
|
|
||||||
"values": [0, 1, 2, 0]
|
|
||||||
}
|
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_mv7y2"]
|
|
||||||
resource_name = "idle"
|
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_orc8t"]
|
|
||||||
resource_name = "use"
|
|
||||||
length = 1.5
|
|
||||||
step = 0.05
|
|
||||||
tracks/0/type = "value"
|
|
||||||
tracks/0/imported = false
|
|
||||||
tracks/0/enabled = true
|
|
||||||
tracks/0/path = NodePath("Anchor:rotation")
|
|
||||||
tracks/0/interp = 1
|
|
||||||
tracks/0/loop_wrap = false
|
|
||||||
tracks/0/keys = {
|
|
||||||
"times": PackedFloat32Array(0.05, 0.1, 0.2, 0.25, 0.75, 1.5),
|
|
||||||
"transitions": PackedFloat32Array(1, 4, 1, 2, 4, 1),
|
|
||||||
"update": 3,
|
|
||||||
"values": [-0.610865, -0.959931, 3.92699, 3.92699, 3.75246, -0.785398]
|
|
||||||
}
|
|
||||||
tracks/1/type = "method"
|
|
||||||
tracks/1/imported = false
|
|
||||||
tracks/1/enabled = true
|
|
||||||
tracks/1/path = NodePath(".")
|
|
||||||
tracks/1/interp = 1
|
|
||||||
tracks/1/loop_wrap = true
|
|
||||||
tracks/1/keys = {
|
|
||||||
"times": PackedFloat32Array(0.1, 0.25),
|
|
||||||
"transitions": PackedFloat32Array(1, 1),
|
|
||||||
"values": [{
|
|
||||||
"args": [],
|
|
||||||
"method": &"Attack"
|
|
||||||
}, {
|
|
||||||
"args": [],
|
|
||||||
"method": &"Deattack"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
tracks/2/type = "value"
|
|
||||||
tracks/2/imported = false
|
|
||||||
tracks/2/enabled = true
|
|
||||||
tracks/2/path = NodePath("SwingSprite:frame")
|
|
||||||
tracks/2/interp = 1
|
|
||||||
tracks/2/loop_wrap = true
|
|
||||||
tracks/2/keys = {
|
|
||||||
"times": PackedFloat32Array(0, 0.2, 0.3, 0.4),
|
|
||||||
"transitions": PackedFloat32Array(1, 1, 1, 1),
|
|
||||||
"update": 1,
|
|
||||||
"values": [0, 1, 2, 0]
|
|
||||||
}
|
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_nivo8"]
|
|
||||||
resource_name = "use-npc"
|
|
||||||
length = 1.5
|
|
||||||
step = 0.05
|
|
||||||
tracks/0/type = "value"
|
|
||||||
tracks/0/imported = false
|
|
||||||
tracks/0/enabled = true
|
|
||||||
tracks/0/path = NodePath("Anchor:rotation")
|
|
||||||
tracks/0/interp = 1
|
|
||||||
tracks/0/loop_wrap = false
|
|
||||||
tracks/0/keys = {
|
|
||||||
"times": PackedFloat32Array(0.05, 0.3, 0.4, 0.45, 0.75, 1.5),
|
|
||||||
"transitions": PackedFloat32Array(1, 4, 1, 2, 4, 1),
|
|
||||||
"update": 3,
|
|
||||||
"values": [-0.610865, -1.309, 3.92699, 3.92699, 3.75246, -0.785398]
|
|
||||||
}
|
|
||||||
tracks/1/type = "method"
|
|
||||||
tracks/1/imported = false
|
|
||||||
tracks/1/enabled = true
|
|
||||||
tracks/1/path = NodePath(".")
|
|
||||||
tracks/1/interp = 1
|
|
||||||
tracks/1/loop_wrap = true
|
|
||||||
tracks/1/keys = {
|
|
||||||
"times": PackedFloat32Array(0.3, 0.45),
|
|
||||||
"transitions": PackedFloat32Array(1, 1),
|
|
||||||
"values": [{
|
|
||||||
"args": [],
|
|
||||||
"method": &"Attack"
|
|
||||||
}, {
|
|
||||||
"args": [],
|
|
||||||
"method": &"Deattack"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
tracks/2/type = "value"
|
|
||||||
tracks/2/imported = false
|
|
||||||
tracks/2/enabled = true
|
|
||||||
tracks/2/path = NodePath("SwingSprite:frame")
|
|
||||||
tracks/2/interp = 1
|
|
||||||
tracks/2/loop_wrap = true
|
|
||||||
tracks/2/keys = {
|
|
||||||
"times": PackedFloat32Array(0, 0.4, 0.5, 0.6),
|
|
||||||
"transitions": PackedFloat32Array(1, 1, 1, 1),
|
|
||||||
"update": 1,
|
|
||||||
"values": [0, 1, 2, 0]
|
|
||||||
}
|
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_y4mj3"]
|
|
||||||
resource_name = "use2"
|
|
||||||
length = 0.75
|
|
||||||
step = 0.05
|
step = 0.05
|
||||||
tracks/0/type = "value"
|
tracks/0/type = "value"
|
||||||
tracks/0/imported = false
|
tracks/0/imported = false
|
||||||
|
@ -198,44 +150,61 @@ tracks/0/path = NodePath("Anchor:rotation")
|
||||||
tracks/0/interp = 1
|
tracks/0/interp = 1
|
||||||
tracks/0/loop_wrap = true
|
tracks/0/loop_wrap = true
|
||||||
tracks/0/keys = {
|
tracks/0/keys = {
|
||||||
"times": PackedFloat32Array(0.05, 0.1, 0.2, 0.25, 0.75),
|
"times": PackedFloat32Array(0, 0.15, 0.35),
|
||||||
"transitions": PackedFloat32Array(1, 4, 1, 2, 1),
|
"transitions": PackedFloat32Array(1, 1, 1),
|
||||||
"update": 3,
|
"update": 1,
|
||||||
"values": [3.75246, 4.10152, -0.785398, -0.785398, -0.610865]
|
"values": [-1.5708, 1.5708, 1.5708]
|
||||||
}
|
}
|
||||||
tracks/1/type = "method"
|
tracks/1/type = "value"
|
||||||
tracks/1/imported = false
|
tracks/1/imported = false
|
||||||
tracks/1/enabled = true
|
tracks/1/enabled = true
|
||||||
tracks/1/path = NodePath(".")
|
tracks/1/path = NodePath("SwingSprite:frame")
|
||||||
tracks/1/interp = 1
|
tracks/1/interp = 1
|
||||||
tracks/1/loop_wrap = true
|
tracks/1/loop_wrap = true
|
||||||
tracks/1/keys = {
|
tracks/1/keys = {
|
||||||
"times": PackedFloat32Array(0.1, 0.25),
|
"times": PackedFloat32Array(0.1, 0.2, 0.4),
|
||||||
"transitions": PackedFloat32Array(1, 1),
|
"transitions": PackedFloat32Array(1, 1, 1),
|
||||||
"values": [{
|
"update": 1,
|
||||||
"args": [],
|
"values": [1, 2, 0]
|
||||||
"method": &"Attack"
|
|
||||||
}, {
|
|
||||||
"args": [],
|
|
||||||
"method": &"Deattack"
|
|
||||||
}]
|
|
||||||
}
|
}
|
||||||
tracks/2/type = "value"
|
tracks/2/type = "value"
|
||||||
tracks/2/imported = false
|
tracks/2/imported = false
|
||||||
tracks/2/enabled = true
|
tracks/2/enabled = false
|
||||||
tracks/2/path = NodePath("SwingSprite:frame")
|
tracks/2/path = NodePath("Anchor:position")
|
||||||
tracks/2/interp = 1
|
tracks/2/interp = 1
|
||||||
tracks/2/loop_wrap = true
|
tracks/2/loop_wrap = true
|
||||||
tracks/2/keys = {
|
tracks/2/keys = {
|
||||||
"times": PackedFloat32Array(0, 0.2, 0.3, 0.4),
|
"times": PackedFloat32Array(0, 0.1, 0.35),
|
||||||
"transitions": PackedFloat32Array(1, 1, 1, 1),
|
"transitions": PackedFloat32Array(1, 1, 1),
|
||||||
"update": 1,
|
"update": 1,
|
||||||
"values": [0, 1, 3, 0]
|
"values": [Vector2(0, 0), Vector2(0, -4), Vector2(0, 0)]
|
||||||
|
}
|
||||||
|
tracks/3/type = "value"
|
||||||
|
tracks/3/imported = false
|
||||||
|
tracks/3/enabled = true
|
||||||
|
tracks/3/path = NodePath("Anchor/Node2D:rotation")
|
||||||
|
tracks/3/interp = 1
|
||||||
|
tracks/3/loop_wrap = true
|
||||||
|
tracks/3/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 0.15),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 1,
|
||||||
|
"values": [0.0, 2.35619]
|
||||||
|
}
|
||||||
|
tracks/4/type = "method"
|
||||||
|
tracks/4/imported = false
|
||||||
|
tracks/4/enabled = true
|
||||||
|
tracks/4/path = NodePath(".")
|
||||||
|
tracks/4/interp = 1
|
||||||
|
tracks/4/loop_wrap = true
|
||||||
|
tracks/4/keys = {
|
||||||
|
"times": PackedFloat32Array(),
|
||||||
|
"transitions": PackedFloat32Array(),
|
||||||
|
"values": []
|
||||||
}
|
}
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_2k2er"]
|
[sub_resource type="Animation" id="Animation_pclfs"]
|
||||||
resource_name = "use2-npc"
|
resource_name = "attack_alternate"
|
||||||
length = 0.75
|
|
||||||
step = 0.05
|
step = 0.05
|
||||||
tracks/0/type = "value"
|
tracks/0/type = "value"
|
||||||
tracks/0/imported = false
|
tracks/0/imported = false
|
||||||
|
@ -244,71 +213,168 @@ tracks/0/path = NodePath("Anchor:rotation")
|
||||||
tracks/0/interp = 1
|
tracks/0/interp = 1
|
||||||
tracks/0/loop_wrap = true
|
tracks/0/loop_wrap = true
|
||||||
tracks/0/keys = {
|
tracks/0/keys = {
|
||||||
"times": PackedFloat32Array(0.05, 0.3, 0.4, 0.45, 0.75),
|
"times": PackedFloat32Array(0, 0.15, 0.35),
|
||||||
"transitions": PackedFloat32Array(1, 4, 1, 2, 1),
|
"transitions": PackedFloat32Array(1, 1, 1),
|
||||||
"update": 3,
|
"update": 1,
|
||||||
"values": [3.75246, 4.45059, -0.785398, -0.785398, -0.610865]
|
"values": [1.5708, -1.5708, -1.5708]
|
||||||
}
|
}
|
||||||
tracks/1/type = "method"
|
tracks/1/type = "value"
|
||||||
tracks/1/imported = false
|
tracks/1/imported = false
|
||||||
tracks/1/enabled = true
|
tracks/1/enabled = true
|
||||||
tracks/1/path = NodePath(".")
|
tracks/1/path = NodePath("SwingSprite:frame")
|
||||||
tracks/1/interp = 1
|
tracks/1/interp = 1
|
||||||
tracks/1/loop_wrap = true
|
tracks/1/loop_wrap = true
|
||||||
tracks/1/keys = {
|
tracks/1/keys = {
|
||||||
"times": PackedFloat32Array(0.3, 0.45),
|
"times": PackedFloat32Array(0.1, 0.2, 0.4),
|
||||||
"transitions": PackedFloat32Array(1, 1),
|
"transitions": PackedFloat32Array(1, 1, 1),
|
||||||
"values": [{
|
"update": 1,
|
||||||
"args": [],
|
"values": [1, 3, 0]
|
||||||
"method": &"Attack"
|
|
||||||
}, {
|
|
||||||
"args": [],
|
|
||||||
"method": &"Deattack"
|
|
||||||
}]
|
|
||||||
}
|
}
|
||||||
tracks/2/type = "value"
|
tracks/2/type = "value"
|
||||||
tracks/2/imported = false
|
tracks/2/imported = false
|
||||||
tracks/2/enabled = true
|
tracks/2/enabled = false
|
||||||
tracks/2/path = NodePath("SwingSprite:frame")
|
tracks/2/path = NodePath("Anchor:position")
|
||||||
tracks/2/interp = 1
|
tracks/2/interp = 1
|
||||||
tracks/2/loop_wrap = true
|
tracks/2/loop_wrap = true
|
||||||
tracks/2/keys = {
|
tracks/2/keys = {
|
||||||
"times": PackedFloat32Array(0, 0.4, 0.5, 0.6),
|
"times": PackedFloat32Array(0, 0.1, 0.35),
|
||||||
"transitions": PackedFloat32Array(1, 1, 1, 1),
|
"transitions": PackedFloat32Array(1, 1, 1),
|
||||||
"update": 1,
|
"update": 1,
|
||||||
"values": [0, 1, 3, 0]
|
"values": [Vector2(0, 0), Vector2(0, -4), Vector2(0, 0)]
|
||||||
|
}
|
||||||
|
tracks/3/type = "value"
|
||||||
|
tracks/3/imported = false
|
||||||
|
tracks/3/enabled = true
|
||||||
|
tracks/3/path = NodePath("Anchor/Node2D:rotation")
|
||||||
|
tracks/3/interp = 1
|
||||||
|
tracks/3/loop_wrap = true
|
||||||
|
tracks/3/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 0.15),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 1,
|
||||||
|
"values": [3.14159, 0.785398]
|
||||||
|
}
|
||||||
|
tracks/4/type = "method"
|
||||||
|
tracks/4/imported = false
|
||||||
|
tracks/4/enabled = true
|
||||||
|
tracks/4/path = NodePath(".")
|
||||||
|
tracks/4/interp = 1
|
||||||
|
tracks/4/loop_wrap = true
|
||||||
|
tracks/4/keys = {
|
||||||
|
"times": PackedFloat32Array(0.2),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"values": [{
|
||||||
|
"args": ["is_alternate", false],
|
||||||
|
"method": &"SetAnimationCondition"
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_tao4k"]
|
[sub_resource type="AnimationLibrary" id="AnimationLibrary_tao4k"]
|
||||||
_data = {
|
_data = {
|
||||||
"RESET": SubResource("Animation_b7327"),
|
"RESET": SubResource("Animation_b7327"),
|
||||||
"attack": SubResource("Animation_r58x0"),
|
"anticipate": SubResource("Animation_ameas"),
|
||||||
"idle": SubResource("Animation_mv7y2"),
|
"anticipate_alternate": SubResource("Animation_bj2ky"),
|
||||||
"use": SubResource("Animation_orc8t"),
|
"anticipate_bot": SubResource("Animation_b8r8j"),
|
||||||
"use-npc": SubResource("Animation_nivo8"),
|
"attack": SubResource("Animation_6jphj"),
|
||||||
"use2": SubResource("Animation_y4mj3"),
|
"attack_alternate": SubResource("Animation_pclfs")
|
||||||
"use2-npc": SubResource("Animation_2k2er")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_1lid1"]
|
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_7lqgd"]
|
||||||
|
animation = &"RESET"
|
||||||
|
|
||||||
[sub_resource type="ConvexPolygonShape2D" id="ConvexPolygonShape2D_tv0o2"]
|
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_0in44"]
|
||||||
points = PackedVector2Array(-14.142, -14.142, 0, -20, 14.142, -14.142, 20, 0, 14.142, 14.142, 0, 20, -14.142, 14.142, 0, 0)
|
animation = &"anticipate"
|
||||||
|
|
||||||
[node name="Sword" type="Node2D" node_paths=PackedStringArray("Hitbox", "AnimationPlayer", "ParryParticles")]
|
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_2wqg6"]
|
||||||
|
animation = &"anticipate_bot"
|
||||||
|
|
||||||
|
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_2ei3g"]
|
||||||
|
animation = &"use"
|
||||||
|
|
||||||
|
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_esyoj"]
|
||||||
|
|
||||||
|
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_kg3rd"]
|
||||||
|
switch_mode = 2
|
||||||
|
advance_mode = 2
|
||||||
|
|
||||||
|
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_twtoe"]
|
||||||
|
|
||||||
|
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_73wvy"]
|
||||||
|
switch_mode = 2
|
||||||
|
advance_mode = 2
|
||||||
|
|
||||||
|
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_4wst0"]
|
||||||
|
switch_mode = 2
|
||||||
|
advance_mode = 2
|
||||||
|
|
||||||
|
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_2lfol"]
|
||||||
|
switch_mode = 2
|
||||||
|
advance_mode = 2
|
||||||
|
advance_condition = &"is_player"
|
||||||
|
|
||||||
|
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_q4hbp"]
|
||||||
|
states/End/position = Vector2(717, 75)
|
||||||
|
states/RESET/node = SubResource("AnimationNodeAnimation_7lqgd")
|
||||||
|
states/RESET/position = Vector2(275, 190)
|
||||||
|
states/Start/position = Vector2(109, 75)
|
||||||
|
states/anticipate/node = SubResource("AnimationNodeAnimation_0in44")
|
||||||
|
states/anticipate/position = Vector2(275, 75)
|
||||||
|
states/anticipate_bot/node = SubResource("AnimationNodeAnimation_2wqg6")
|
||||||
|
states/anticipate_bot/position = Vector2(456, 18)
|
||||||
|
states/use/node = SubResource("AnimationNodeAnimation_2ei3g")
|
||||||
|
states/use/position = Vector2(609, 75)
|
||||||
|
transitions = ["Start", "anticipate", SubResource("AnimationNodeStateMachineTransition_esyoj"), "use", "RESET", SubResource("AnimationNodeStateMachineTransition_kg3rd"), "RESET", "anticipate", SubResource("AnimationNodeStateMachineTransition_twtoe"), "anticipate", "anticipate_bot", SubResource("AnimationNodeStateMachineTransition_73wvy"), "anticipate_bot", "use", SubResource("AnimationNodeStateMachineTransition_4wst0"), "anticipate", "use", SubResource("AnimationNodeStateMachineTransition_2lfol")]
|
||||||
|
graph_offset = Vector2(0, -104.073)
|
||||||
|
|
||||||
|
[sub_resource type="AnimationNodeStateMachinePlayback" id="AnimationNodeStateMachinePlayback_o5g2u"]
|
||||||
|
|
||||||
|
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_ic623"]
|
||||||
|
radius = 20.0
|
||||||
|
height = 48.0
|
||||||
|
|
||||||
|
[node name="Node2D" type="Node2D" node_paths=PackedStringArray("Hitbox", "AnimationPlayer", "AnimationTree", "ParryParticles", "StateMachine", "Anchor")]
|
||||||
y_sort_enabled = true
|
y_sort_enabled = true
|
||||||
texture_filter = 3
|
texture_filter = 3
|
||||||
script = ExtResource("1_mlo73")
|
script = ExtResource("1_mlo73")
|
||||||
Hitbox = NodePath("Hitbox")
|
Hitbox = NodePath("Hitbox")
|
||||||
AnimationPlayer = NodePath("AnimationPlayer")
|
AnimationPlayer = NodePath("AnimationPlayer")
|
||||||
|
AnimationTree = NodePath("AnimationTree")
|
||||||
|
AttackTime = 0.2
|
||||||
|
AttackAnimationDuration = 1.0
|
||||||
ParryParticles = NodePath("Anchor/Node2D/Sprite2D/ParryParticles")
|
ParryParticles = NodePath("Anchor/Node2D/Sprite2D/ParryParticles")
|
||||||
|
NPCAnticipateTime = 0.4
|
||||||
|
StateMachine = NodePath("State")
|
||||||
Damage = 20.0
|
Damage = 20.0
|
||||||
UseTime = 0.5
|
UseTime = 0.4
|
||||||
Knockback = 20.0
|
Knockback = 20.0
|
||||||
|
Anchor = NodePath("Anchor")
|
||||||
|
|
||||||
|
[node name="State" type="Node" parent="." node_paths=PackedStringArray("InitialState")]
|
||||||
|
script = ExtResource("2_rje2m")
|
||||||
|
InitialState = NodePath("Idle")
|
||||||
|
|
||||||
|
[node name="Idle" type="Node" parent="State" node_paths=PackedStringArray("AnticipateState", "Sword")]
|
||||||
|
script = ExtResource("3_qh2cs")
|
||||||
|
AnticipateState = NodePath("../Anticipate")
|
||||||
|
Sword = NodePath("../..")
|
||||||
|
|
||||||
|
[node name="Anticipate" type="Node" parent="State" node_paths=PackedStringArray("Sword", "AttackState")]
|
||||||
|
script = ExtResource("4_ycuhw")
|
||||||
|
Sword = NodePath("../..")
|
||||||
|
AttackState = NodePath("../Attack")
|
||||||
|
|
||||||
|
[node name="Attack" type="Node" parent="State" node_paths=PackedStringArray("Sword", "AnticipateState", "IdleState")]
|
||||||
|
script = ExtResource("5_30003")
|
||||||
|
Sword = NodePath("../..")
|
||||||
|
AnticipateState = NodePath("../Anticipate")
|
||||||
|
IdleState = NodePath("../Idle")
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_72txp")
|
||||||
|
|
||||||
[node name="Anchor" type="Node2D" parent="."]
|
[node name="Anchor" type="Node2D" parent="."]
|
||||||
y_sort_enabled = true
|
y_sort_enabled = true
|
||||||
rotation = -0.610865
|
rotation = -1.5708
|
||||||
|
|
||||||
[node name="Trail" parent="Anchor" node_paths=PackedStringArray("Tracking") instance=ExtResource("4_pt6lq")]
|
[node name="Trail" parent="Anchor" node_paths=PackedStringArray("Tracking") instance=ExtResource("4_pt6lq")]
|
||||||
position = Vector2(2.40734, -0.55655)
|
position = Vector2(2.40734, -0.55655)
|
||||||
|
@ -318,12 +384,12 @@ gradient = SubResource("Gradient_2ablm")
|
||||||
Tracking = NodePath("../Node2D/Sprite2D")
|
Tracking = NodePath("../Node2D/Sprite2D")
|
||||||
|
|
||||||
[node name="Node2D" type="Node2D" parent="Anchor"]
|
[node name="Node2D" type="Node2D" parent="Anchor"]
|
||||||
rotation = -0.846485
|
position = Vector2(8, 0)
|
||||||
|
|
||||||
[node name="Sprite2D" type="Sprite2D" parent="Anchor/Node2D"]
|
[node name="Sprite2D" type="Sprite2D" parent="Anchor/Node2D"]
|
||||||
y_sort_enabled = true
|
y_sort_enabled = true
|
||||||
position = Vector2(0, -12)
|
position = Vector2(0, -8)
|
||||||
texture = ExtResource("2_rnfo4")
|
texture = ExtResource("3_r75ni")
|
||||||
|
|
||||||
[node name="ParryParticles" type="CPUParticles2D" parent="Anchor/Node2D/Sprite2D"]
|
[node name="ParryParticles" type="CPUParticles2D" parent="Anchor/Node2D/Sprite2D"]
|
||||||
position = Vector2(-0.221825, -3.12132)
|
position = Vector2(-0.221825, -3.12132)
|
||||||
|
@ -348,19 +414,25 @@ libraries = {
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="AnimationTree" type="AnimationTree" parent="."]
|
[node name="AnimationTree" type="AnimationTree" parent="."]
|
||||||
tree_root = SubResource("AnimationNodeAnimation_1lid1")
|
tree_root = SubResource("AnimationNodeStateMachine_q4hbp")
|
||||||
anim_player = NodePath("../AnimationPlayer")
|
anim_player = NodePath("../AnimationPlayer")
|
||||||
active = true
|
active = true
|
||||||
|
parameters/playback = SubResource("AnimationNodeStateMachinePlayback_o5g2u")
|
||||||
|
parameters/conditions/is_player = false
|
||||||
|
|
||||||
[node name="Hitbox" parent="." instance=ExtResource("3_up3ob")]
|
[node name="Hitbox" parent="." instance=ExtResource("3_up3ob")]
|
||||||
IsDisabled = true
|
IsDisabled = true
|
||||||
|
|
||||||
[node name="CollisionShape2D" parent="Hitbox" index="0"]
|
[node name="CollisionShape2D" parent="Hitbox" index="0"]
|
||||||
shape = SubResource("ConvexPolygonShape2D_tv0o2")
|
position = Vector2(4, 0)
|
||||||
|
rotation = 1.5708
|
||||||
|
shape = SubResource("CapsuleShape2D_ic623")
|
||||||
disabled = true
|
disabled = true
|
||||||
|
|
||||||
[node name="SwingSprite" type="Sprite2D" parent="."]
|
[node name="SwingSprite" type="Sprite2D" parent="."]
|
||||||
|
modulate = Color(2, 2, 2, 1)
|
||||||
texture = ExtResource("5_pywek")
|
texture = ExtResource("5_pywek")
|
||||||
|
offset = Vector2(4, 0)
|
||||||
hframes = 4
|
hframes = 4
|
||||||
|
|
||||||
[node name="SwingSound" type="AudioStreamPlayer2D" parent="."]
|
[node name="SwingSound" type="AudioStreamPlayer2D" parent="."]
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
namespace SupaLidlGame.State
|
||||||
|
{
|
||||||
|
public interface IState<T> where T : IState<T>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Called when this state is entered
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This returns a <c>IState</c> in case a state is being
|
||||||
|
/// transitioned to but wants to transition to another state. For
|
||||||
|
/// example, an attack state can return to an idle state, but that idle
|
||||||
|
/// state can override it to the move state immediately when necessary.
|
||||||
|
/// </remarks>
|
||||||
|
public IState<T> Enter(IState<T> previousState) => null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the <c>Character</c> exits this <c>CharacterState</c>.
|
||||||
|
/// </summary>
|
||||||
|
public void Exit(IState<T> nextState)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public IState<T> Process(double delta) => null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SupaLidlGame.Characters.State
|
||||||
|
{
|
||||||
|
public partial class Machine : Node
|
||||||
|
{
|
||||||
|
protected Character _character;
|
||||||
|
|
||||||
|
public CharacterState State { get; protected set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public CharacterState InitialState { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public Character Character { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public int DebugLevel { get; set; }
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
ChangeState(InitialState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeState(CharacterState nextState, bool isProxied = false)
|
||||||
|
{
|
||||||
|
if (nextState is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (DebugLevel >= 2)
|
||||||
|
{
|
||||||
|
if (State is not null)
|
||||||
|
{
|
||||||
|
string proxyNote = isProxied ? " (proxied)" : "";
|
||||||
|
GD.Print($"Transition{proxyNote} {State.Name} -> {nextState.Name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DebugLevel >= 1)
|
||||||
|
{
|
||||||
|
if (GetNode<Label>("../Debug/State") is Label label)
|
||||||
|
{
|
||||||
|
label.Text = nextState.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextState.Character = Character;
|
||||||
|
if (State != null)
|
||||||
|
{
|
||||||
|
State.Exit(nextState);
|
||||||
|
}
|
||||||
|
|
||||||
|
var nextNextState = nextState.Enter(State);
|
||||||
|
|
||||||
|
State = nextState;
|
||||||
|
|
||||||
|
if (nextNextState is not null)
|
||||||
|
{
|
||||||
|
ChangeState(nextNextState, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Process(double delta)
|
||||||
|
{
|
||||||
|
CharacterState nextState = State.Process(delta);
|
||||||
|
if (nextState is not null)
|
||||||
|
{
|
||||||
|
ChangeState(nextState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PhysicsProcess(double delta)
|
||||||
|
{
|
||||||
|
CharacterState nextState = State.PhysicsProcess(delta);
|
||||||
|
if (nextState is not null)
|
||||||
|
{
|
||||||
|
ChangeState(nextState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Input(InputEvent @event)
|
||||||
|
{
|
||||||
|
CharacterState nextState = State.Input(@event);
|
||||||
|
if (nextState is not null)
|
||||||
|
{
|
||||||
|
ChangeState(nextState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SupaLidlGame.State
|
||||||
|
{
|
||||||
|
public abstract partial class StateMachine<T> : Node where T : IState<T>
|
||||||
|
{
|
||||||
|
public T CurrentState { get; protected set; }
|
||||||
|
|
||||||
|
public abstract T InitialState { get; set; }
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
ChangeState(InitialState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool ChangeState(T nextState, bool isProxied = false)
|
||||||
|
{
|
||||||
|
if (nextState is null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CurrentState != null)
|
||||||
|
{
|
||||||
|
CurrentState.Exit(nextState);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentState = nextState;
|
||||||
|
|
||||||
|
// if the next state decides it should enter a different state,
|
||||||
|
// then we enter that different state instead
|
||||||
|
var nextNextState = nextState.Enter(CurrentState);
|
||||||
|
if (nextNextState is T t)
|
||||||
|
{
|
||||||
|
return ChangeState(t, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SupaLidlGame.State.Sword
|
||||||
|
{
|
||||||
|
public partial class SwordAnticipateState : SwordState
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public SupaLidlGame.Items.Weapons.Sword Sword { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public SwordAttackState AttackState { get; set; }
|
||||||
|
|
||||||
|
private double _anticipateTime;
|
||||||
|
|
||||||
|
public override SwordState Enter(IState<SwordState> prevState)
|
||||||
|
{
|
||||||
|
Sword.EnableParry();
|
||||||
|
|
||||||
|
if (Sword.Character is SupaLidlGame.Characters.Player)
|
||||||
|
{
|
||||||
|
return AttackState;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Sword.Anchor.Rotation > Mathf.DegToRad(50))
|
||||||
|
{
|
||||||
|
Sword.AnimationPlayer.Play("anticipate_alternate");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Sword.AnimationPlayer.Play("anticipate");
|
||||||
|
}
|
||||||
|
_anticipateTime = Sword.NPCAnticipateTime;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SwordState Process(double delta)
|
||||||
|
{
|
||||||
|
// go into attack state if anticipation time is delta
|
||||||
|
if ((_anticipateTime -= delta) <= 0)
|
||||||
|
{
|
||||||
|
return AttackState;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SupaLidlGame.State.Sword
|
||||||
|
{
|
||||||
|
public partial class SwordAttackState : SwordState
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public SupaLidlGame.Items.Weapons.Sword Sword { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public SwordAnticipateState AnticipateState { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public SwordIdleState IdleState { get; set; }
|
||||||
|
|
||||||
|
private double _attackDuration = 0;
|
||||||
|
|
||||||
|
private double _useDuration = 0;
|
||||||
|
|
||||||
|
private double _attackAnimDuration = 0;
|
||||||
|
|
||||||
|
private bool _isAlternate = false;
|
||||||
|
|
||||||
|
public override SwordState Enter(IState<SwordState> prevState)
|
||||||
|
{
|
||||||
|
//Sword.AnimationPlayer.Stop();
|
||||||
|
Sword.Attack();
|
||||||
|
|
||||||
|
if (_isAlternate)
|
||||||
|
{
|
||||||
|
Sword.AnimationPlayer.Play("attack_alternate");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Sword.AnimationPlayer.Play("attack");
|
||||||
|
}
|
||||||
|
|
||||||
|
_attackDuration = Sword.AttackTime;
|
||||||
|
_useDuration = Sword.UseTime;
|
||||||
|
_attackAnimDuration = Sword.AttackAnimationDuration;
|
||||||
|
|
||||||
|
GD.Print(_attackDuration);
|
||||||
|
GD.Print(_useDuration);
|
||||||
|
GD.Print(_attackAnimDuration);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Exit(IState<SwordState> nextState)
|
||||||
|
{
|
||||||
|
Sword.Deattack();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SwordState Use()
|
||||||
|
{
|
||||||
|
if (_useDuration <= 0)
|
||||||
|
{
|
||||||
|
// if we are still playing the current attack animation, we should alternate
|
||||||
|
if (_attackAnimDuration > 0)
|
||||||
|
{
|
||||||
|
_isAlternate = !_isAlternate;
|
||||||
|
}
|
||||||
|
return AnticipateState;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SwordState Process(double delta)
|
||||||
|
{
|
||||||
|
if (_attackDuration > 0)
|
||||||
|
{
|
||||||
|
if ((_attackDuration -= delta) <= 0)
|
||||||
|
{
|
||||||
|
Sword.Deattack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_attackAnimDuration -= delta) <= 0)
|
||||||
|
{
|
||||||
|
Sword.AnimationPlayer.Play("RESET");
|
||||||
|
_isAlternate = false;
|
||||||
|
return IdleState;
|
||||||
|
}
|
||||||
|
|
||||||
|
_useDuration -= delta;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SupaLidlGame.State.Sword
|
||||||
|
{
|
||||||
|
public partial class SwordIdleState : SwordState
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public SwordAnticipateState AnticipateState { get; set; }
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public SupaLidlGame.Items.Weapons.Sword Sword { get; set; }
|
||||||
|
|
||||||
|
private double _attackCooldown;
|
||||||
|
|
||||||
|
public override SwordState Enter(IState<SwordState> prevState)
|
||||||
|
{
|
||||||
|
if (prevState is SwordAttackState)
|
||||||
|
{
|
||||||
|
_attackCooldown = Sword.UseTime - Sword.AttackTime;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SwordState Use()
|
||||||
|
{
|
||||||
|
if (_attackCooldown <= 0)
|
||||||
|
{
|
||||||
|
return AnticipateState;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AnticipateState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SwordState Process(double delta)
|
||||||
|
{
|
||||||
|
if (_attackCooldown > 0)
|
||||||
|
{
|
||||||
|
_attackCooldown -= delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SupaLidlGame.State.Sword
|
||||||
|
{
|
||||||
|
public abstract partial class SwordState : Node, IState<SwordState>
|
||||||
|
{
|
||||||
|
public virtual SwordState Use() => null;
|
||||||
|
|
||||||
|
public abstract IState<SwordState> Enter(IState<SwordState> previousState);
|
||||||
|
|
||||||
|
public virtual void Exit(IState<SwordState> previousState)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IState<SwordState> Process(double delta) => null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SupaLidlGame.State.Sword
|
||||||
|
{
|
||||||
|
public partial class SwordStateMachine : StateMachine<SwordState>
|
||||||
|
{
|
||||||
|
[Export]
|
||||||
|
public override SwordState InitialState { get; set; }
|
||||||
|
|
||||||
|
public void Use()
|
||||||
|
{
|
||||||
|
var state = CurrentState.Use();
|
||||||
|
if (state is not null)
|
||||||
|
{
|
||||||
|
ChangeState(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Process(double delta)
|
||||||
|
{
|
||||||
|
var state = CurrentState.Process(delta);
|
||||||
|
if (state is SwordState s)
|
||||||
|
{
|
||||||
|
ChangeState(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue