Demo: Add demon BT
This commit is contained in:
parent
2fd15f04d6
commit
39d1440b96
|
@ -10,6 +10,12 @@
|
|||
[ext_resource type="Script" path="res://demo/agents/scripts/hitbox.gd" id="5_taq6b"]
|
||||
[ext_resource type="Script" path="res://demo/agents/scripts/hurtbox.gd" id="6_jnvxm"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_2k81i"]
|
||||
size = Vector2(130, 35)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_26abe"]
|
||||
size = Vector2(80, 35)
|
||||
|
||||
[sub_resource type="Curve" id="Curve_noh01"]
|
||||
_data = [Vector2(0, 0.010989), 0.0, 0.0, 0, 0, Vector2(0.151111, 1), 1.3559, 1.3559, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 3
|
||||
|
@ -37,12 +43,6 @@ scale_min = 0.8
|
|||
scale_max = 1.2
|
||||
scale_curve = SubResource("CurveTexture_sb0wp")
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_2k81i"]
|
||||
size = Vector2(130, 35)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_26abe"]
|
||||
size = Vector2(80, 35)
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_0c228"]
|
||||
|
||||
[sub_resource type="Animation" id="Animation_nvm4d"]
|
||||
|
@ -266,7 +266,7 @@ tracks/17/keys = {
|
|||
tracks/18/type = "value"
|
||||
tracks/18/imported = false
|
||||
tracks/18/enabled = true
|
||||
tracks/18/path = NodePath("Root/FX/Cloud:visible")
|
||||
tracks/18/path = NodePath("FX/Cloud:visible")
|
||||
tracks/18/interp = 1
|
||||
tracks/18/loop_wrap = true
|
||||
tracks/18/keys = {
|
||||
|
@ -338,7 +338,7 @@ tracks/23/keys = {
|
|||
tracks/24/type = "value"
|
||||
tracks/24/imported = false
|
||||
tracks/24/enabled = true
|
||||
tracks/24/path = NodePath("Root/FX/Death:emitting")
|
||||
tracks/24/path = NodePath("FX/Death:emitting")
|
||||
tracks/24/interp = 1
|
||||
tracks/24/loop_wrap = true
|
||||
tracks/24/keys = {
|
||||
|
@ -1133,7 +1133,7 @@ tracks/17/keys = {
|
|||
tracks/18/type = "value"
|
||||
tracks/18/imported = false
|
||||
tracks/18/enabled = true
|
||||
tracks/18/path = NodePath("Root/FX/Cloud:visible")
|
||||
tracks/18/path = NodePath("FX/Cloud:visible")
|
||||
tracks/18/interp = 1
|
||||
tracks/18/loop_wrap = true
|
||||
tracks/18/keys = {
|
||||
|
@ -1424,6 +1424,30 @@ tracks/20/keys = {
|
|||
"update": 0,
|
||||
"values": [Vector2(1, 1)]
|
||||
}
|
||||
tracks/21/type = "value"
|
||||
tracks/21/imported = false
|
||||
tracks/21/enabled = true
|
||||
tracks/21/path = NodePath("Root/Hitbox/CollisionShape2D:disabled")
|
||||
tracks/21/interp = 1
|
||||
tracks/21/loop_wrap = true
|
||||
tracks/21/keys = {
|
||||
"times": PackedFloat32Array(0, 0.2),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 1,
|
||||
"values": [false, false]
|
||||
}
|
||||
tracks/22/type = "value"
|
||||
tracks/22/imported = false
|
||||
tracks/22/enabled = true
|
||||
tracks/22/path = NodePath("Root/Hitbox:knockback_enabled")
|
||||
tracks/22/interp = 1
|
||||
tracks/22/loop_wrap = true
|
||||
tracks/22/keys = {
|
||||
"times": PackedFloat32Array(0, 0.2),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 1,
|
||||
"values": [true, true]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_sva81"]
|
||||
resource_name = "charge_prepare"
|
||||
|
@ -2161,7 +2185,7 @@ tracks/17/keys = {
|
|||
tracks/18/type = "value"
|
||||
tracks/18/imported = false
|
||||
tracks/18/enabled = false
|
||||
tracks/18/path = NodePath("Root/FX/Cloud:visible")
|
||||
tracks/18/path = NodePath("FX/Cloud:visible")
|
||||
tracks/18/interp = 1
|
||||
tracks/18/loop_wrap = true
|
||||
tracks/18/keys = {
|
||||
|
@ -2221,7 +2245,7 @@ tracks/22/keys = {
|
|||
tracks/23/type = "value"
|
||||
tracks/23/imported = false
|
||||
tracks/23/enabled = true
|
||||
tracks/23/path = NodePath("Root/FX/Death:emitting")
|
||||
tracks/23/path = NodePath("FX/Death:emitting")
|
||||
tracks/23/interp = 1
|
||||
tracks/23/loop_wrap = true
|
||||
tracks/23/keys = {
|
||||
|
@ -2454,7 +2478,7 @@ tracks/17/keys = {
|
|||
tracks/18/type = "value"
|
||||
tracks/18/imported = false
|
||||
tracks/18/enabled = true
|
||||
tracks/18/path = NodePath("Root/FX/Cloud:visible")
|
||||
tracks/18/path = NodePath("FX/Cloud:visible")
|
||||
tracks/18/interp = 1
|
||||
tracks/18/loop_wrap = true
|
||||
tracks/18/keys = {
|
||||
|
@ -2735,7 +2759,7 @@ tracks/17/keys = {
|
|||
tracks/18/type = "value"
|
||||
tracks/18/imported = false
|
||||
tracks/18/enabled = true
|
||||
tracks/18/path = NodePath("Root/FX/Cloud:visible")
|
||||
tracks/18/path = NodePath("FX/Cloud:visible")
|
||||
tracks/18/interp = 1
|
||||
tracks/18/loop_wrap = true
|
||||
tracks/18/keys = {
|
||||
|
@ -4203,7 +4227,7 @@ tracks/17/keys = {
|
|||
tracks/18/type = "value"
|
||||
tracks/18/imported = false
|
||||
tracks/18/enabled = true
|
||||
tracks/18/path = NodePath("Root/FX/Cloud:visible")
|
||||
tracks/18/path = NodePath("FX/Cloud:visible")
|
||||
tracks/18/interp = 1
|
||||
tracks/18/loop_wrap = true
|
||||
tracks/18/keys = {
|
||||
|
@ -4295,35 +4319,12 @@ texture = ExtResource("1_1u51b")
|
|||
region_enabled = true
|
||||
region_rect = Rect2(111, 34, 26.9272, 26.6298)
|
||||
|
||||
[node name="FX" type="Node2D" parent="Root"]
|
||||
position = Vector2(0, -68)
|
||||
metadata/_edit_lock_ = true
|
||||
|
||||
[node name="Cloud" type="Sprite2D" parent="Root/FX"]
|
||||
visible = false
|
||||
scale = Vector2(0.5, 0.5)
|
||||
texture = ExtResource("2_lv102")
|
||||
region_enabled = true
|
||||
region_rect = Rect2(300, 0, 100, 70)
|
||||
|
||||
[node name="Death" type="GPUParticles2D" parent="Root/FX"]
|
||||
position = Vector2(0, 52)
|
||||
emitting = false
|
||||
amount = 16
|
||||
process_material = SubResource("ParticleProcessMaterial_f5i1x")
|
||||
texture = ExtResource("4_mnb6v")
|
||||
lifetime = 0.7
|
||||
one_shot = true
|
||||
explosiveness = 0.7
|
||||
fixed_fps = 60
|
||||
|
||||
[node name="WeaponNinjaStar" type="Sprite2D" parent="Root"]
|
||||
visible = false
|
||||
position = Vector2(-55, -76)
|
||||
texture = ExtResource("4_1c5xq")
|
||||
|
||||
[node name="Hitbox" type="Area2D" parent="Root"]
|
||||
visible = false
|
||||
position = Vector2(50, 0)
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
|
@ -4337,7 +4338,6 @@ debug_color = Color(0.933131, 0.0801983, 0.605982, 0.42)
|
|||
metadata/_edit_lock_ = true
|
||||
|
||||
[node name="Hurtbox" type="Area2D" parent="Root" node_paths=PackedStringArray("health")]
|
||||
visible = false
|
||||
collision_layer = 8
|
||||
collision_mask = 0
|
||||
script = ExtResource("6_jnvxm")
|
||||
|
@ -4348,6 +4348,28 @@ shape = SubResource("RectangleShape2D_26abe")
|
|||
debug_color = Color(0.466325, 0.590206, 0.107862, 0.42)
|
||||
metadata/_edit_lock_ = true
|
||||
|
||||
[node name="FX" type="Node2D" parent="."]
|
||||
position = Vector2(0, -68)
|
||||
metadata/_edit_lock_ = true
|
||||
|
||||
[node name="Cloud" type="Sprite2D" parent="FX"]
|
||||
visible = false
|
||||
scale = Vector2(0.5, 0.5)
|
||||
texture = ExtResource("2_lv102")
|
||||
region_enabled = true
|
||||
region_rect = Rect2(300, 0, 100, 70)
|
||||
|
||||
[node name="Death" type="GPUParticles2D" parent="FX"]
|
||||
position = Vector2(0, 52)
|
||||
emitting = false
|
||||
amount = 16
|
||||
process_material = SubResource("ParticleProcessMaterial_f5i1x")
|
||||
texture = ExtResource("4_mnb6v")
|
||||
lifetime = 0.7
|
||||
one_shot = true
|
||||
explosiveness = 0.7
|
||||
fixed_fps = 60
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
visible = false
|
||||
position = Vector2(-1, -7)
|
||||
|
|
|
@ -1,17 +1,30 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://g1pnvanyxcpa"]
|
||||
[gd_scene load_steps=5 format=3 uid="uid://g1pnvanyxcpa"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_n83hi"]
|
||||
[ext_resource type="Texture2D" uid="uid://ce16nc0wy2s8" path="res://demo/assets/agent_charger.png" id="2_y7pic"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://ylife72ym5et" path="res://demo/ai/trees/enemy_charger.tres" id="3_nacc3"]
|
||||
|
||||
[node name="Bobby" instance=ExtResource("1_n83hi")]
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_b4r3u"]
|
||||
var/speed/name = "speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
var/charge_speed/name = "charge_speed"
|
||||
var/charge_speed/type = 3
|
||||
var/charge_speed/value = 800.0
|
||||
var/charge_speed/hint = 1
|
||||
var/charge_speed/hint_string = "10,1000,10"
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="0"]
|
||||
[node name="AgentCharger" instance=ExtResource("1_n83hi")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_y7pic")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="1"]
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_y7pic")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="2"]
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_y7pic")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
|
@ -22,3 +35,7 @@ texture = ExtResource("2_y7pic")
|
|||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_y7pic")
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="4"]
|
||||
behavior_tree = ExtResource("3_nacc3")
|
||||
blackboard_plan = SubResource("BlackboardPlan_b4r3u")
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://jb504ogmwmjk"]
|
||||
[gd_scene load_steps=5 format=3 uid="uid://jb504ogmwmjk"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ooigbfhfy4wa" path="res://demo/agents/agent_base.tscn" id="1_115kp"]
|
||||
[ext_resource type="Texture2D" uid="uid://d1tx7u8ho0r4v" path="res://demo/assets/agent_demon.png" id="2_cb5f2"]
|
||||
[ext_resource type="BehaviorTree" uid="uid://cpcnbi81jqge4" path="res://demo/ai/trees/enemy_demon.tres" id="3_ebd57"]
|
||||
|
||||
[node name="Bobby" instance=ExtResource("1_115kp")]
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_ju1qf"]
|
||||
var/speed/name = "speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="0"]
|
||||
[node name="AgentDemon" instance=ExtResource("1_115kp")]
|
||||
|
||||
[node name="LegL" parent="Root/Rig" index="1"]
|
||||
texture = ExtResource("2_cb5f2")
|
||||
|
||||
[node name="LegR" parent="Root/Rig" index="1"]
|
||||
[node name="LegR" parent="Root/Rig" index="2"]
|
||||
texture = ExtResource("2_cb5f2")
|
||||
|
||||
[node name="Body" parent="Root/Rig" index="2"]
|
||||
[node name="Body" parent="Root/Rig" index="3"]
|
||||
texture = ExtResource("2_cb5f2")
|
||||
|
||||
[node name="Hat" parent="Root/Rig/Body" index="0"]
|
||||
|
@ -22,3 +30,7 @@ texture = ExtResource("2_cb5f2")
|
|||
|
||||
[node name="HandR" parent="Root/Rig/Body" index="2"]
|
||||
texture = ExtResource("2_cb5f2")
|
||||
|
||||
[node name="BTPlayer" type="BTPlayer" parent="." index="5"]
|
||||
behavior_tree = ExtResource("3_ebd57")
|
||||
blackboard_plan = SubResource("BlackboardPlan_ju1qf")
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
#*
|
||||
#* fireball.gd
|
||||
#* =============================================================================
|
||||
#* Copyright 2021-2024 Serhii Snitsaruk
|
||||
#*
|
||||
#* Use of this source code is governed by an MIT-style
|
||||
#* license that can be found in the LICENSE file or at
|
||||
#* https://opensource.org/licenses/MIT.
|
||||
#* =============================================================================
|
||||
#*
|
||||
extends Node2D
|
||||
## Fireball
|
||||
|
||||
const SPEED := 800.0
|
||||
const DEAD_SPEED := 400.0
|
||||
|
||||
@export var dir: float = 1.0
|
||||
|
||||
var _is_dead: bool = false
|
||||
|
||||
@onready var fireball_sprite: Sprite2D = $Root/Fireball
|
||||
@onready var death: GPUParticles2D = $FX/Death
|
||||
@onready var collision_shape_2d: CollisionShape2D = $Hitbox/CollisionShape2D
|
||||
@onready var root: Node2D = $Root
|
||||
@onready var trail: GPUParticles2D = $FX/Trail
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
var tween := create_tween().set_loops()
|
||||
tween.tween_property(fireball_sprite, ^"rotation", PI * signf(dir), 1.0).as_relative()
|
||||
|
||||
var tween2 := create_tween().set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN)
|
||||
tween2.tween_property(fireball_sprite, "position:y", -10.0, 0.5).as_relative().set_ease(Tween.EASE_OUT)
|
||||
tween2.tween_property(fireball_sprite, "position:y", 0.0, 1.0)
|
||||
tween2.tween_callback(_die)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var speed: float = SPEED if not _is_dead else DEAD_SPEED
|
||||
position += Vector2.RIGHT * speed * dir * delta
|
||||
|
||||
|
||||
func _die() -> void:
|
||||
_is_dead = true
|
||||
trail.emitting = false
|
||||
root.hide()
|
||||
collision_shape_2d.set_deferred(&"disabled", true)
|
||||
death.emitting = true
|
||||
await death.finished
|
||||
queue_free()
|
||||
|
||||
|
||||
func _on_hitbox_area_entered(_area: Area2D) -> void:
|
||||
_die()
|
|
@ -0,0 +1,169 @@
|
|||
[gd_scene load_steps=18 format=3 uid="uid://wdauoepicegb"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/agents/fireball/fireball.gd" id="1_ituf4"]
|
||||
[ext_resource type="Texture2D" uid="uid://dwhhxj5557qrb" path="res://demo/assets/shadow.png" id="2_6n8mx"]
|
||||
[ext_resource type="Texture2D" uid="uid://235liwnxn1n5" path="res://demo/assets/fireball.png" id="3_1an0e"]
|
||||
[ext_resource type="Script" path="res://demo/agents/scripts/hitbox.gd" id="4_rjhgc"]
|
||||
[ext_resource type="Texture2D" uid="uid://bdusy0qqtw0th" path="res://demo/assets/smoke.png" id="5_dcbp6"]
|
||||
|
||||
[sub_resource type="Curve" id="Curve_mukra"]
|
||||
_data = [Vector2(0, 0), 0.0, 4.81319, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 2
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_56342"]
|
||||
curve = SubResource("Curve_mukra")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_gbya7"]
|
||||
lifetime_randomness = 0.5
|
||||
particle_flag_disable_z = true
|
||||
direction = Vector3(0, -1, 0)
|
||||
spread = 90.0
|
||||
initial_velocity_min = 150.0
|
||||
initial_velocity_max = 250.0
|
||||
angular_velocity_min = -90.0
|
||||
angular_velocity_max = 90.0
|
||||
gravity = Vector3(0, 0, 0)
|
||||
radial_accel_min = -90.0
|
||||
radial_accel_max = 90.0
|
||||
damping_min = 200.0
|
||||
damping_max = 200.0
|
||||
scale_min = 0.8
|
||||
scale_max = 1.2
|
||||
scale_curve = SubResource("CurveTexture_56342")
|
||||
color = Color(0.552941, 0.552941, 0.552941, 1)
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_c08h3"]
|
||||
offsets = PackedFloat32Array(0, 0.549738, 1)
|
||||
colors = PackedColorArray(0.980453, 0.717632, 0.282353, 1, 0.960906, 0.211521, 0.0390784, 1, 0.201527, 0.201527, 0.201527, 1)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_fhxvw"]
|
||||
gradient = SubResource("Gradient_c08h3")
|
||||
|
||||
[sub_resource type="Curve" id="Curve_ugmtv"]
|
||||
_data = [Vector2(0, 0.010989), 0.0, 0.0, 0, 0, Vector2(0.151111, 1), 1.3559, 1.3559, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 3
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_1f5jp"]
|
||||
curve = SubResource("Curve_ugmtv")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_gilhy"]
|
||||
lifetime_randomness = 0.5
|
||||
particle_flag_disable_z = true
|
||||
emission_shape = 3
|
||||
emission_box_extents = Vector3(40, 1, 1)
|
||||
direction = Vector3(0, -1, 0)
|
||||
spread = 90.0
|
||||
initial_velocity_min = 150.0
|
||||
initial_velocity_max = 250.0
|
||||
angular_velocity_min = -90.0
|
||||
angular_velocity_max = 90.0
|
||||
gravity = Vector3(0, 0, 0)
|
||||
radial_accel_min = -90.0
|
||||
radial_accel_max = 90.0
|
||||
damping_min = 200.0
|
||||
damping_max = 200.0
|
||||
scale_min = 0.8
|
||||
scale_max = 1.2
|
||||
scale_curve = SubResource("CurveTexture_1f5jp")
|
||||
color_ramp = SubResource("GradientTexture1D_fhxvw")
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_7uc1b"]
|
||||
radius = 25.13
|
||||
|
||||
[sub_resource type="Animation" id="Animation_ey8it"]
|
||||
resource_name = "default"
|
||||
length = 0.3
|
||||
loop_mode = 1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Root/Fireball:frame")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1),
|
||||
"update": 1,
|
||||
"values": [0, 1, 2, 0]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_wr7y0"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Root/Fireball:frame")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [0]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_cphpk"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_wr7y0"),
|
||||
"default": SubResource("Animation_ey8it")
|
||||
}
|
||||
|
||||
[node name="Fireball" type="Node2D"]
|
||||
script = ExtResource("1_ituf4")
|
||||
|
||||
[node name="FX" type="Node2D" parent="."]
|
||||
position = Vector2(0, -92)
|
||||
|
||||
[node name="Trail" type="GPUParticles2D" parent="FX"]
|
||||
show_behind_parent = true
|
||||
amount = 6
|
||||
process_material = SubResource("ParticleProcessMaterial_gbya7")
|
||||
texture = ExtResource("5_dcbp6")
|
||||
lifetime = 0.4
|
||||
fixed_fps = 60
|
||||
|
||||
[node name="Death" type="GPUParticles2D" parent="FX"]
|
||||
emitting = false
|
||||
amount = 6
|
||||
process_material = SubResource("ParticleProcessMaterial_gilhy")
|
||||
texture = ExtResource("5_dcbp6")
|
||||
lifetime = 0.7
|
||||
one_shot = true
|
||||
explosiveness = 0.7
|
||||
fixed_fps = 60
|
||||
local_coords = true
|
||||
|
||||
[node name="Root" type="Node2D" parent="."]
|
||||
|
||||
[node name="Shadow" type="Sprite2D" parent="Root"]
|
||||
modulate = Color(1, 1, 1, 0.686275)
|
||||
position = Vector2(0, -1)
|
||||
scale = Vector2(0.382, 0.297)
|
||||
texture = ExtResource("2_6n8mx")
|
||||
|
||||
[node name="Fireball" type="Sprite2D" parent="Root"]
|
||||
position = Vector2(0, -92)
|
||||
texture = ExtResource("3_1an0e")
|
||||
hframes = 3
|
||||
|
||||
[node name="RemoteTransform2D" type="RemoteTransform2D" parent="Root/Fireball"]
|
||||
remote_path = NodePath("../../../FX")
|
||||
update_rotation = false
|
||||
update_scale = false
|
||||
|
||||
[node name="Hitbox" type="Area2D" parent="."]
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
script = ExtResource("4_rjhgc")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"]
|
||||
shape = SubResource("CircleShape2D_7uc1b")
|
||||
debug_color = Color(0.839216, 0.192157, 0.815686, 0.419608)
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_cphpk")
|
||||
}
|
||||
autoplay = "default"
|
||||
|
||||
[connection signal="area_entered" from="Hitbox" to="." method="_on_hitbox_area_entered"]
|
|
@ -13,6 +13,7 @@ extends CharacterBody2D
|
|||
## Base agent script.
|
||||
|
||||
const NinjaStar := preload("res://demo/agents/ninja_star/ninja_star.tscn")
|
||||
const Fireball := preload("res://demo/agents/fireball/fireball.tscn")
|
||||
|
||||
@onready var animation_player: AnimationPlayer = $AnimationPlayer
|
||||
@onready var health: Health = $Health
|
||||
|
@ -54,6 +55,13 @@ func throw_ninja_star() -> void:
|
|||
ninja_star.global_position = global_position + Vector2.RIGHT * 100.0 * get_facing()
|
||||
|
||||
|
||||
func spit_fire() -> void:
|
||||
var fireball := Fireball.instantiate()
|
||||
fireball.dir = get_facing()
|
||||
get_parent().add_child(fireball)
|
||||
fireball.global_position = global_position + Vector2.RIGHT * 100.0 * get_facing()
|
||||
|
||||
|
||||
func _damaged(_amount: float, knockback: Vector2) -> void:
|
||||
apply_knockback(knockback)
|
||||
animation_player.play(&"hurt")
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=27 format=3 uid="uid://ylife72ym5et"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_flanking_pos.gd" id="1_3ovx6"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_g3c1d"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="2_l3434"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="4_km0bx"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/leap_forward.gd" id="5_socam"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_qd806"]
|
||||
var/speed/name = "speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
var/charge_speed/name = "charge_speed"
|
||||
var/charge_speed/type = 3
|
||||
var/charge_speed/value = 800.0
|
||||
var/charge_speed/hint = 1
|
||||
var/charge_speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_yrurg"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ha2ag"]
|
||||
animation_player = SubResource("BBNode_yrurg")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_cedqr"]
|
||||
min_duration = 2.0
|
||||
max_duration = 5.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_l3v31"]
|
||||
custom_name = "Short break"
|
||||
children = [SubResource("BTPlayAnimation_ha2ag"), SubResource("BTRandomWait_cedqr")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_pp23y"]
|
||||
script = ExtResource("1_g3c1d")
|
||||
group = &"player"
|
||||
output_var = "target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_pmvd0"]
|
||||
script = ExtResource("1_3ovx6")
|
||||
target_var = "target"
|
||||
closest_side = false
|
||||
flank_side = 0
|
||||
range_min = 500
|
||||
range_max = 600
|
||||
position_var = "flank_pos"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_xh3wr"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_h0poo"]
|
||||
animation_player = SubResource("BBNode_xh3wr")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_87mi0"]
|
||||
script = ExtResource("2_l3434")
|
||||
target_position_var = "flank_pos"
|
||||
speed_var = "speed"
|
||||
tolerance = 50.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_p6pgg"]
|
||||
custom_name = "Flank target"
|
||||
children = [SubResource("BTAction_pp23y"), SubResource("BTAction_pmvd0"), SubResource("BTPlayAnimation_h0poo"), SubResource("BTAction_87mi0")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_q5g4a"]
|
||||
script = ExtResource("4_km0bx")
|
||||
target_var = "target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_bfijg"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_4okoy"]
|
||||
await_completion = 2.0
|
||||
animation_player = SubResource("BBNode_bfijg")
|
||||
animation_name = &"charge_prepare"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_ovu3r"]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_mde2g"]
|
||||
custom_name = "Anticipation"
|
||||
children = [SubResource("BTAction_q5g4a"), SubResource("BTPlayAnimation_4okoy"), SubResource("BTWait_ovu3r")]
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_kpp70"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_8s1wq"]
|
||||
animation_player = SubResource("BBNode_kpp70")
|
||||
animation_name = &"charge"
|
||||
blend = 0.05
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_o18uk"]
|
||||
script = ExtResource("5_socam")
|
||||
force = 1000.0
|
||||
duration = 2.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_8lur1"]
|
||||
custom_name = "Charge!"
|
||||
children = [SubResource("BTPlayAnimation_8s1wq"), SubResource("BTAction_o18uk")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_pjuov"]
|
||||
custom_name = "Charge Attack"
|
||||
children = [SubResource("BTSequence_l3v31"), SubResource("BTSequence_p6pgg"), SubResource("BTSequence_mde2g"), SubResource("BTSequence_8lur1")]
|
||||
|
||||
[resource]
|
||||
blackboard_plan = SubResource("BlackboardPlan_qd806")
|
||||
root_task = SubResource("BTSequence_pjuov")
|
|
@ -0,0 +1,197 @@
|
|||
[gd_resource type="BehaviorTree" load_steps=49 format=3 uid="uid://cpcnbi81jqge4"]
|
||||
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/get_first_in_group.gd" id="1_84v18"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/face_target.gd" id="2_ff2n7"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/in_range.gd" id="3_ealyw"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/back_away.gd" id="4_iaxsb"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/select_flanking_pos.gd" id="5_u6msy"]
|
||||
[ext_resource type="Script" path="res://demo/ai/tasks/arrive_pos.gd" id="6_jl5ks"]
|
||||
|
||||
[sub_resource type="BlackboardPlan" id="BlackboardPlan_8ay3j"]
|
||||
var/speed/name = "speed"
|
||||
var/speed/type = 3
|
||||
var/speed/value = 400.0
|
||||
var/speed/hint = 1
|
||||
var/speed/hint_string = "10,1000,10"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_lpri5"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_p3e7a"]
|
||||
animation_player = SubResource("BBNode_lpri5")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_j6cjm"]
|
||||
max_duration = 3.0
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_5thv4"]
|
||||
custom_name = "Chill"
|
||||
children = [SubResource("BTPlayAnimation_p3e7a"), SubResource("BTRandomWait_j6cjm")]
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_oms7a"]
|
||||
children = [SubResource("BTSequence_5thv4")]
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_ohfp7"]
|
||||
script = ExtResource("1_84v18")
|
||||
group = &"player"
|
||||
output_var = "target"
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_7a5nv"]
|
||||
script = ExtResource("3_ealyw")
|
||||
distance_min = 50.0
|
||||
distance_max = 150.0
|
||||
target_var = "target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_ddvrs"]
|
||||
script = ExtResource("2_ff2n7")
|
||||
target_var = "target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_c4nfu"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_yytkn"]
|
||||
await_completion = 3.0
|
||||
animation_player = SubResource("BBNode_c4nfu")
|
||||
animation_name = &"attack_3"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTCooldown" id="BTCooldown_ejg6q"]
|
||||
duration = 3.0
|
||||
children = [SubResource("BTPlayAnimation_yytkn")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_eikr4"]
|
||||
custom_name = "Melee"
|
||||
children = [SubResource("BTAction_ohfp7"), SubResource("BTCondition_7a5nv"), SubResource("BTAction_ddvrs"), SubResource("BTCooldown_ejg6q")]
|
||||
|
||||
[sub_resource type="BTCondition" id="BTCondition_h75v8"]
|
||||
script = ExtResource("3_ealyw")
|
||||
distance_min = 0.0
|
||||
distance_max = 300.0
|
||||
target_var = "target"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_wpt7j"]
|
||||
script = ExtResource("2_ff2n7")
|
||||
target_var = "target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_iv62h"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_wnaul"]
|
||||
animation_player = SubResource("BBNode_iv62h")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
speed = -1.0
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_h2efl"]
|
||||
script = ExtResource("4_iaxsb")
|
||||
speed_var = "speed"
|
||||
max_angle_deviation = 0.7
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_wm5g2"]
|
||||
time_limit = 1.0
|
||||
children = [SubResource("BTAction_h2efl")]
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_wh4dl"]
|
||||
custom_name = "Back away"
|
||||
children = [SubResource("BTCondition_h75v8"), SubResource("BTAction_wpt7j"), SubResource("BTPlayAnimation_wnaul"), SubResource("BTTimeLimit_wm5g2")]
|
||||
|
||||
[sub_resource type="BTComment" id="BTComment_mqte5"]
|
||||
custom_name = "Get into position"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_edmui"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_vjtpq"]
|
||||
animation_player = SubResource("BBNode_edmui")
|
||||
animation_name = &"walk"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_4mmh0"]
|
||||
script = ExtResource("5_u6msy")
|
||||
target_var = "target"
|
||||
closest_side = false
|
||||
flank_side = 0
|
||||
range_min = 300
|
||||
range_max = 700
|
||||
position_var = "pos"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_vb5c3"]
|
||||
script = ExtResource("6_jl5ks")
|
||||
target_position_var = "pos"
|
||||
speed_var = "speed"
|
||||
tolerance = 50.0
|
||||
|
||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_jyks2"]
|
||||
children = [SubResource("BTAction_vb5c3")]
|
||||
|
||||
[sub_resource type="BTComment" id="BTComment_ym6nj"]
|
||||
custom_name = "Short break before action"
|
||||
|
||||
[sub_resource type="BTAction" id="BTAction_fkevy"]
|
||||
script = ExtResource("2_ff2n7")
|
||||
target_var = "target"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_lh25u"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_vcjeq"]
|
||||
animation_player = SubResource("BBNode_lh25u")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTWait" id="BTWait_42smh"]
|
||||
duration = 0.2
|
||||
|
||||
[sub_resource type="BTComment" id="BTComment_nbp2b"]
|
||||
custom_name = "Spit fire!"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_cqw71"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_214yn"]
|
||||
await_completion = 3.0
|
||||
animation_player = SubResource("BBNode_cqw71")
|
||||
animation_name = &"spit"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_dv5b5"]
|
||||
saved_value = NodePath(".")
|
||||
resource_name = "."
|
||||
|
||||
[sub_resource type="BTCallMethod" id="BTCallMethod_lk7i6"]
|
||||
node = SubResource("BBNode_dv5b5")
|
||||
method = &"spit_fire"
|
||||
|
||||
[sub_resource type="BTComment" id="BTComment_fndxk"]
|
||||
custom_name = "Short break after"
|
||||
|
||||
[sub_resource type="BBNode" id="BBNode_m68ui"]
|
||||
saved_value = NodePath("AnimationPlayer")
|
||||
resource_name = "AnimationPlayer"
|
||||
|
||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_m7gyp"]
|
||||
animation_player = SubResource("BBNode_m68ui")
|
||||
animation_name = &"idle"
|
||||
blend = 0.1
|
||||
|
||||
[sub_resource type="BTRandomWait" id="BTRandomWait_v0el8"]
|
||||
min_duration = 0.5
|
||||
max_duration = 1.5
|
||||
|
||||
[sub_resource type="BTSequence" id="BTSequence_djtph"]
|
||||
custom_name = "Spit fire"
|
||||
children = [SubResource("BTComment_mqte5"), SubResource("BTPlayAnimation_vjtpq"), SubResource("BTAction_4mmh0"), SubResource("BTTimeLimit_jyks2"), SubResource("BTComment_ym6nj"), SubResource("BTAction_fkevy"), SubResource("BTPlayAnimation_vcjeq"), SubResource("BTWait_42smh"), SubResource("BTComment_nbp2b"), SubResource("BTPlayAnimation_214yn"), SubResource("BTCallMethod_lk7i6"), SubResource("BTComment_fndxk"), SubResource("BTPlayAnimation_m7gyp"), SubResource("BTRandomWait_v0el8")]
|
||||
|
||||
[sub_resource type="BTSelector" id="BTSelector_feba6"]
|
||||
children = [SubResource("BTCooldown_oms7a"), SubResource("BTSequence_eikr4"), SubResource("BTSequence_wh4dl"), SubResource("BTSequence_djtph")]
|
||||
|
||||
[resource]
|
||||
blackboard_plan = SubResource("BlackboardPlan_8ay3j")
|
||||
root_task = SubResource("BTSelector_feba6")
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=13 format=3 uid="uid://bsig1usigbbuy"]
|
||||
[gd_scene load_steps=16 format=3 uid="uid://bsig1usigbbuy"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://b3g14elmg0m36" path="res://demo/assets/env_rocks.png" id="1_145kx"]
|
||||
[ext_resource type="PackedScene" uid="uid://dt2jlrqffpyw" path="res://demo/scenes/clouds.tscn" id="1_gsxmp"]
|
||||
|
@ -8,7 +8,10 @@
|
|||
[ext_resource type="PackedScene" uid="uid://d07ag5dcje13i" path="res://demo/agents/player/player.tscn" id="5_cmgoj"]
|
||||
[ext_resource type="PackedScene" uid="uid://ci3x5esepbu5v" path="res://demo/agents/agent_ranged.tscn" id="6_76icr"]
|
||||
[ext_resource type="PackedScene" uid="uid://blxmw2w1h2s0s" path="res://demo/agents/agent_melee_combo.tscn" id="7_jlgir"]
|
||||
[ext_resource type="PackedScene" uid="uid://co6yeafaljbq0" path="res://demo/agents/agent_skirmisher.tscn" id="8_a0psq"]
|
||||
[ext_resource type="PackedScene" uid="uid://2e4ohaqjaawb" path="res://demo/agents/agent_melee_nuanced.tscn" id="8_ovfbp"]
|
||||
[ext_resource type="PackedScene" uid="uid://g1pnvanyxcpa" path="res://demo/agents/agent_charger.tscn" id="9_k8jcc"]
|
||||
[ext_resource type="PackedScene" uid="uid://jb504ogmwmjk" path="res://demo/agents/agent_demon.tscn" id="10_nds64"]
|
||||
|
||||
[sub_resource type="Animation" id="Animation_gwtgs"]
|
||||
length = 0.001
|
||||
|
@ -2874,16 +2877,14 @@ metadata/_edit_lock_ = true
|
|||
y_sort_enabled = true
|
||||
metadata/_edit_lock_ = true
|
||||
|
||||
[node name="AgentMeleeNuanced" parent="YSort/Agents" instance=ExtResource("8_ovfbp")]
|
||||
position = Vector2(1513, 262)
|
||||
|
||||
[node name="AgentMeleeNuanced3" parent="YSort/Agents" instance=ExtResource("8_ovfbp")]
|
||||
position = Vector2(1125, 748)
|
||||
|
||||
[node name="AgentMeleeNuanced4" parent="YSort/Agents" instance=ExtResource("8_ovfbp")]
|
||||
position = Vector2(227, 231)
|
||||
process_mode = 4
|
||||
visible = false
|
||||
position = Vector2(350, 657)
|
||||
|
||||
[node name="AgentMeleeNuanced5" parent="YSort/Agents" instance=ExtResource("8_ovfbp")]
|
||||
process_mode = 4
|
||||
visible = false
|
||||
position = Vector2(592, -163)
|
||||
|
||||
[node name="Player" parent="YSort/Agents" instance=ExtResource("5_cmgoj")]
|
||||
|
@ -2900,11 +2901,31 @@ drag_top_margin = 0.1
|
|||
drag_bottom_margin = 0.1
|
||||
|
||||
[node name="AgentRanged" parent="YSort/Agents" instance=ExtResource("6_76icr")]
|
||||
process_mode = 4
|
||||
visible = false
|
||||
position = Vector2(2067, 543)
|
||||
|
||||
[node name="AgentMeleeCombo" parent="YSort/Agents" instance=ExtResource("7_jlgir")]
|
||||
process_mode = 4
|
||||
visible = false
|
||||
position = Vector2(1778, 22)
|
||||
|
||||
[node name="AgentSkirmisher" parent="YSort/Agents" instance=ExtResource("8_a0psq")]
|
||||
process_mode = 4
|
||||
visible = false
|
||||
position = Vector2(-162, 498)
|
||||
|
||||
[node name="AgentCharger" parent="YSort/Agents" instance=ExtResource("9_k8jcc")]
|
||||
process_mode = 4
|
||||
visible = false
|
||||
position = Vector2(1400, 382)
|
||||
|
||||
[node name="AgentDemon" parent="YSort/Agents" instance=ExtResource("10_nds64")]
|
||||
position = Vector2(1417, 503)
|
||||
|
||||
[node name="AgentDemon2" parent="YSort/Agents" instance=ExtResource("10_nds64")]
|
||||
position = Vector2(70, 537)
|
||||
|
||||
[node name="Props" type="Node2D" parent="YSort"]
|
||||
y_sort_enabled = true
|
||||
metadata/_edit_lock_ = true
|
||||
|
|
Loading…
Reference in New Issue