Merge branch 'wip' into master (#42)

* Implement igniting bow arrows

* Add bow alt-fire ability
wip^2
HumanoidSandvichDispenser 2024-07-06 22:51:09 -07:00 committed by GitHub
parent f0ac72b919
commit 12767e3c70
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 368 additions and 13 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dj1vsctgh1scr"
path="res://.godot/imported/flame.png-e7b2d4c51e3e9c0041d6294e9c805c89.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Assets/Sprites/Misc/flame.png"
dest_files=["res://.godot/imported/flame.png-e7b2d4c51e3e9c0041d6294e9c805c89.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

View File

@ -8,19 +8,33 @@ public partial class Bow : ProjectileSpawner
protected Area2D _ignitionArea;
protected override void SpawnProjectile(Scenes.Map map,
protected override Entities.Projectile SpawnProjectile(Scenes.Map map,
Vector2 direction, float velocityModifier = 1)
{
base.SpawnProjectile(map, direction, velocityModifier);
var projectile = base.SpawnProjectile(map, direction, velocityModifier);
if (_isOnFire)
{
GetNode<AnimatedSprite2D>("%Flame").Visible = false;
// TODO: instead of doing 1.5x damage, create an "On Fire" debuff
projectile.Hitbox.Damage *= 1.5f;
_isOnFire = false;
}
return projectile;
}
public override void _Ready()
{
base._Ready();
_ignitionArea = GetNode<Area2D>("IgnitionArea");
_ignitionArea.AreaEntered += (Area2D area) =>
var onAreaEntered = (Area2D area) =>
{
_isOnFire = false;
GetNode<AnimatedSprite2D>("%Flame").Visible = true;
_isOnFire = true;
};
_ignitionArea.Connect(
Area2D.SignalName.AreaEntered,
Callable.From(onAreaEntered));
}
}

View File

@ -1,15 +1,74 @@
[gd_scene load_steps=17 format=3 uid="uid://cgg0sfm2qeiwn"]
[gd_scene load_steps=28 format=3 uid="uid://cgg0sfm2qeiwn"]
[ext_resource type="Texture2D" uid="uid://dam6aigkw8xs" path="res://Assets/Sprites/Items/bow-and-arrow.png" id="1_1ghvv"]
[ext_resource type="Script" path="res://Items/Weapons/ProjectileSpawner.cs" id="1_76bur"]
[ext_resource type="Script" path="res://Items/Weapons/Bow.cs" id="1_ikgu2"]
[ext_resource type="PackedScene" uid="uid://cjiftn2suskla" path="res://Entities/Arrow.tscn" id="2_mvw0j"]
[ext_resource type="Resource" uid="uid://cjsh0dcgbfn77" path="res://Items/Weapons/Bow.tres" id="3_j7q7r"]
[ext_resource type="Script" path="res://State/Weapon/WeaponStateMachine.cs" id="3_pg4gy"]
[ext_resource type="Script" path="res://State/Weapon/RangedIdleState.cs" id="3_uxif8"]
[ext_resource type="Script" path="res://State/Weapon/RangedFireState.cs" id="4_moo4d"]
[ext_resource type="Script" path="res://State/Weapon/RangedChargeState.cs" id="5_k8y6f"]
[ext_resource type="Script" path="res://State/Weapon/BowAltState.cs" id="7_l73rl"]
[ext_resource type="AudioStream" uid="uid://bkekgj4gu7fw4" path="res://Assets/Sounds/bow-draw.wav" id="7_t07v0"]
[ext_resource type="Texture2D" uid="uid://coarr28adgo1u" path="res://Assets/Sprites/Particles/point-light.png" id="9_tk6lc"]
[ext_resource type="AudioStream" uid="uid://cwy4giq8eod5g" path="res://Assets/Sounds/bow-release.wav" id="9_v051g"]
[ext_resource type="Texture2D" uid="uid://dj1vsctgh1scr" path="res://Assets/Sprites/Misc/flame.png" id="9_xwcvy"]
[sub_resource type="AtlasTexture" id="AtlasTexture_5af70"]
atlas = ExtResource("9_xwcvy")
region = Rect2(0, 0, 8, 8)
[sub_resource type="AtlasTexture" id="AtlasTexture_bct7o"]
atlas = ExtResource("9_xwcvy")
region = Rect2(8, 0, 8, 8)
[sub_resource type="AtlasTexture" id="AtlasTexture_fhtjn"]
atlas = ExtResource("9_xwcvy")
region = Rect2(16, 0, 8, 8)
[sub_resource type="AtlasTexture" id="AtlasTexture_si88l"]
atlas = ExtResource("9_xwcvy")
region = Rect2(24, 0, 8, 8)
[sub_resource type="AtlasTexture" id="AtlasTexture_ap5vw"]
atlas = ExtResource("9_xwcvy")
region = Rect2(32, 0, 8, 8)
[sub_resource type="AtlasTexture" id="AtlasTexture_uad0p"]
atlas = ExtResource("9_xwcvy")
region = Rect2(40, 0, 8, 8)
[sub_resource type="AtlasTexture" id="AtlasTexture_cxv2f"]
atlas = ExtResource("9_xwcvy")
region = Rect2(48, 0, 8, 8)
[sub_resource type="SpriteFrames" id="SpriteFrames_b2khh"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": SubResource("AtlasTexture_5af70")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_bct7o")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_fhtjn")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_si88l")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_ap5vw")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_uad0p")
}, {
"duration": 1.0,
"texture": SubResource("AtlasTexture_cxv2f")
}],
"loop": true,
"name": &"default",
"speed": 10.0
}]
[sub_resource type="Animation" id="Animation_h0fti"]
resource_name = "RESET"
@ -25,6 +84,101 @@ tracks/0/keys = {
"update": 1,
"values": [0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Anchor/Flame:position")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(15, -8)]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Anchor/Flame:visible")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="Animation" id="Animation_bejvb"]
resource_name = "alt_fire"
step = 0.05
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Anchor/Sprite2D:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [0, 5, 0, 5, 0, 5, 0, 5, 0]
}
tracks/1/type = "audio"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("AudioStreamPlayer2D")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.03,
"stream": ExtResource("9_v051g")
}, {
"end_offset": 0.0,
"start_offset": 0.03,
"stream": ExtResource("9_v051g")
}, {
"end_offset": 0.0,
"start_offset": 0.03,
"stream": ExtResource("9_v051g")
}, {
"end_offset": 0.0,
"start_offset": 0.03,
"stream": ExtResource("9_v051g")
}, {
"end_offset": 0.0,
"start_offset": 0.03,
"stream": ExtResource("9_v051g")
}],
"times": PackedFloat32Array(0, 0.1998, 0.3996, 0.5994, 0.7992)
}
tracks/1/use_blend = true
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Anchor/Flame:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(15, -8)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("Anchor/Flame:visible")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="Animation" id="Animation_8qr8x"]
resource_name = "charge"
@ -56,8 +210,20 @@ tracks/1/keys = {
"times": PackedFloat32Array(0)
}
tracks/1/use_blend = true
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Anchor/Flame:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
"update": 1,
"values": [Vector2(15, -8), Vector2(14, -8), Vector2(13, -8), Vector2(12, -8), Vector2(11, -8), Vector2(9, -8)]
}
[sub_resource type="Animation" id="Animation_bejvb"]
[sub_resource type="Animation" id="Animation_j5qtq"]
resource_name = "fire"
tracks/0/type = "value"
tracks/0/imported = false
@ -86,6 +252,30 @@ tracks/1/keys = {
"times": PackedFloat32Array(0)
}
tracks/1/use_blend = true
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Anchor/Flame:position")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Vector2(15, -8)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("Anchor/Flame:visible")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
[sub_resource type="Animation" id="Animation_riv7t"]
resource_name = "idle"
@ -105,8 +295,9 @@ tracks/0/keys = {
[sub_resource type="AnimationLibrary" id="AnimationLibrary_5vx8d"]
_data = {
"RESET": SubResource("Animation_h0fti"),
"alt_fire": SubResource("Animation_bejvb"),
"charge": SubResource("Animation_8qr8x"),
"fire": SubResource("Animation_bejvb"),
"fire": SubResource("Animation_j5qtq"),
"idle": SubResource("Animation_riv7t")
}
@ -114,27 +305,29 @@ _data = {
[node name="Bow" type="Node2D" node_paths=PackedStringArray("StateMachine")]
y_sort_enabled = true
script = ExtResource("1_76bur")
script = ExtResource("1_ikgu2")
Projectile = ExtResource("2_mvw0j")
ChargeTime = 0.5
StateMachine = NodePath("StateMachine")
Damage = 20.0
UseTime = 0.5
UseAltTime = 0.2
Knockback = 64.0
InitialVelocity = 200.0
ShouldFreezeAngleOnUse = false
PlayerLevelGain = 1.0
Metadata = ExtResource("3_j7q7r")
[node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState")]
script = ExtResource("3_pg4gy")
InitialState = NodePath("Idle")
UsedItemStates = Array[NodePath]([NodePath("Charge"), NodePath("Fire")])
UsedItemAltStates = Array[NodePath]([NodePath("AltFire")])
DeusedItemStates = Array[NodePath]([NodePath("Idle")])
[node name="Idle" type="Node" parent="StateMachine" node_paths=PackedStringArray("FireState", "Weapon", "AnimationPlayer")]
[node name="Idle" type="Node" parent="StateMachine" node_paths=PackedStringArray("FireState", "AltFireState", "Weapon", "AnimationPlayer")]
script = ExtResource("3_uxif8")
FireState = NodePath("../Charge")
AltFireState = NodePath("../AltFire")
Weapon = NodePath("../..")
AnimationPlayer = NodePath("../../AnimationPlayer")
AnimationKey = "idle"
@ -154,6 +347,14 @@ IdleState = NodePath("../Idle")
AnimationPlayer = NodePath("../../AnimationPlayer")
AnimationKey = "fire"
[node name="AltFire" type="Node" parent="StateMachine" node_paths=PackedStringArray("Bow", "IdleState", "AnimationPlayer")]
script = ExtResource("7_l73rl")
Bow = NodePath("../..")
IdleState = NodePath("../Idle")
AnimationPlayer = NodePath("../../AnimationPlayer")
AnimationKey = "alt_fire"
AngleDeviation = 30.0
[node name="Anchor" type="Node2D" parent="."]
y_sort_enabled = true
position = Vector2(0, 4)
@ -166,6 +367,18 @@ centered = false
offset = Vector2(-8, -16)
hframes = 8
[node name="Flame" type="AnimatedSprite2D" parent="Anchor"]
unique_name_in_owner = true
visible = false
position = Vector2(15, -8)
sprite_frames = SubResource("SpriteFrames_b2khh")
autoplay = "default"
[node name="PointLight2D" type="PointLight2D" parent="Anchor/Flame"]
color = Color(1, 0.8, 0.701961, 1)
texture = ExtResource("9_tk6lc")
texture_scale = 0.13
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
"": SubResource("AnimationLibrary_5vx8d")

View File

@ -33,7 +33,7 @@ public partial class ProjectileSpawner : Ranged
}
}
protected virtual void SpawnProjectile(Scenes.Map map,
protected virtual Entities.Projectile SpawnProjectile(Scenes.Map map,
Vector2 direction, float velocityModifier = 1)
{
var projectile = map.SpawnEntity<Entities.Projectile>(Projectile);
@ -70,6 +70,7 @@ public partial class ProjectileSpawner : Ranged
}
}
return projectile;
}
public override void Attack()
@ -85,6 +86,12 @@ public partial class ProjectileSpawner : Ranged
Vector2 target = Character.Target.Normalized();
if (AngleDeviation > 0)
{
float angle = (GD.Randf() - 0.5f) * AngleDeviation;
target = target.Rotated(Mathf.DegToRad(angle));
}
if (CharacterRecoil > 0)
{
Character.ApplyImpulse(-target * CharacterRecoil);

View File

@ -29,12 +29,24 @@ public abstract partial class Ranged : Weapon
base.Use();
}
public override void UseAlt()
{
StateMachine.UseAlt();
base.Use();
}
public override void Deuse()
{
StateMachine.Deuse();
base.Deuse();
}
public override void DeuseAlt()
{
StateMachine.DeuseAlt();
base.Deuse();
}
public override void _Process(double delta)
{
StateMachine.Process(delta);

View File

@ -0,0 +1,75 @@
using Godot;
using SupaLidlGame.Extensions;
namespace SupaLidlGame.State.Weapon;
public partial class BowAltState : WeaponState
{
[Export]
public Items.Weapons.Bow Bow { get; set; }
[Export]
public RangedIdleState IdleState { get; set; }
[Export]
public AnimationPlayer AnimationPlayer { get; set; }
[Export]
public string AnimationKey { get; set; }
[Export]
public int MaxCount { get; set; } = 5;
[Export]
public float AngleDeviation { get; set; }
public float VelocityModifier { get; set; } = 1;
private Timer _timer;
private int _count = 0;
private float _oldDeviation;
public override IState<WeaponState> Enter(IState<WeaponState> prev)
{
//_timer = GetTree().CreateTimer(Weapon.UseAltTime);
_timer = new Timer();
_count = 1;
_oldDeviation = Bow.ProjectileAngleDeviation;
Bow.AngleDeviation = AngleDeviation;
var timeout = () =>
{
Bow.Attack(VelocityModifier);
_count++;
};
Bow.Attack(VelocityModifier);
Bow.UseDirection = Bow.Character.Target;
AnimationPlayer?.TryPlay(AnimationKey);
_timer.Connect(Timer.SignalName.Timeout, Callable.From(timeout));
AddChild(_timer);
_timer.Start(Bow.UseAltTime);
GD.Print("Entered alt fire state");
return null;
}
public override WeaponState Process(double delta)
{
if (_count >= MaxCount)
{
return IdleState;
}
return null;
}
public override void Exit(IState<WeaponState> nextState)
{
_timer.QueueFree();
Bow.AngleDeviation = _oldDeviation;
}
}