Added win condition for level 1 and added boss fight for level 5
This commit is contained in:
@@ -16,9 +16,7 @@ height = 2.0
|
||||
[sub_resource type="CircleShape2D" id=3]
|
||||
radius = 50.0
|
||||
|
||||
[node name="Chasing Glowing Ghost" type="KinematicBody2D" groups=[
|
||||
"enemy",
|
||||
]]
|
||||
[node name="Chasing Glowing Ghost" type="KinematicBody2D" groups=["enemy"]]
|
||||
light_mask = 0
|
||||
collision_layer = 4
|
||||
collision_mask = 5
|
||||
@@ -36,9 +34,7 @@ light_mask = 0
|
||||
rotation = 1.5708
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="Hitbox" type="Area2D" parent="." groups=[
|
||||
"enemy_hitbox_1",
|
||||
]]
|
||||
[node name="Hitbox" type="Area2D" parent="." groups=["enemy_hitbox_1"]]
|
||||
light_mask = 0
|
||||
collision_layer = 4
|
||||
collision_mask = 2
|
||||
@@ -51,10 +47,10 @@ shape = SubResource( 2 )
|
||||
|
||||
[node name="Player Detector" type="Area2D" parent="."]
|
||||
light_mask = 0
|
||||
input_pickable = false
|
||||
monitorable = false
|
||||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
input_pickable = false
|
||||
monitorable = false
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Player Detector"]
|
||||
visible = false
|
||||
|
@@ -1,5 +1,6 @@
|
||||
extends KinematicBody2D
|
||||
|
||||
signal death
|
||||
# Declare member variables here. Examples:
|
||||
# var a = 2
|
||||
# var b = "text"
|
||||
@@ -55,7 +56,7 @@ func _on_Star_detect_body_entered(body_star):
|
||||
#print("timer start")
|
||||
|
||||
func _on_Star_detect_body_exited(_body):
|
||||
#if _body.name == 'Star':
|
||||
#if _body.name == 'Star':
|
||||
#print("obstacle exited")
|
||||
#if _body.name == 'Obstacle':
|
||||
#obstacle = null
|
||||
@@ -74,5 +75,6 @@ func _on_Hitbox_area_entered(area: Area2D):
|
||||
health -= 2
|
||||
|
||||
if health <= 0:
|
||||
emit_signal('death')
|
||||
call_deferred('queue_free')
|
||||
return
|
||||
|
78
Enemies/Eyeball Boss.gd
Normal file
78
Enemies/Eyeball Boss.gd
Normal file
@@ -0,0 +1,78 @@
|
||||
extends StaticBody2D
|
||||
|
||||
signal death
|
||||
|
||||
export var glowing_blue_fireball: PackedScene
|
||||
|
||||
var player: KinematicBody2D = null
|
||||
var health: int = 12
|
||||
var center: Vector2
|
||||
var center_x: float
|
||||
var shoot_y: int
|
||||
|
||||
var rng: RandomNumberGenerator = RandomNumberGenerator.new()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
center = $Sprite.global_position
|
||||
center_x = center.x
|
||||
shoot_y = int(center.y) + 1
|
||||
rng.randomize()
|
||||
return
|
||||
|
||||
|
||||
func _on_shoot_timeout() -> void:
|
||||
if player:
|
||||
var shoot_directions: Array = [
|
||||
Vector2(center_x + rng.randf_range(-1, 1), shoot_y),
|
||||
Vector2(center_x + rng.randf_range(-1, 1), shoot_y),
|
||||
Vector2(center_x + rng.randf_range(-1, 1), shoot_y),
|
||||
Vector2(center_x + rng.randf_range(-1, 1), shoot_y),
|
||||
Vector2(center_x + rng.randf_range(-1, 1), shoot_y)]
|
||||
|
||||
for itr in shoot_directions:
|
||||
var projectile: Node = glowing_blue_fireball.instance()
|
||||
projectile.init(center, itr)
|
||||
get_tree().get_current_scene().get_node('Projectiles').add_child(projectile)
|
||||
|
||||
$'Flash Timer'.start()
|
||||
$Flash.set_visible(true)
|
||||
return
|
||||
|
||||
|
||||
func _on_flash_timer_timeout() -> void:
|
||||
$Flash.set_visible(false)
|
||||
return
|
||||
|
||||
|
||||
func _on_hit_timeout() -> void:
|
||||
$Sprite.self_modulate = Color(1, 1, 1)
|
||||
return
|
||||
|
||||
|
||||
func _on_hitbox_area_entered(area: Area2D) -> void:
|
||||
if area.is_in_group('player_weapon_1'):
|
||||
health -= 1
|
||||
$Sprite.self_modulate = Color(1, 0, 0)
|
||||
$Hit.start()
|
||||
elif area.is_in_group('player_weapon_2'):
|
||||
health -= 2
|
||||
$Sprite.self_modulate = Color(1, 0, 0)
|
||||
$Hit.start()
|
||||
|
||||
if health <= 0:
|
||||
emit_signal('death')
|
||||
call_deferred('queue_free')
|
||||
return
|
||||
|
||||
|
||||
func _on_player_detector_body_entered(body: Node) -> void:
|
||||
if body.is_in_group('player'):
|
||||
player = body
|
||||
return
|
||||
|
||||
|
||||
func _on_player_detector_body_exited(body: Node) -> void:
|
||||
if body.is_in_group('player'):
|
||||
player = null
|
||||
return
|
127
Enemies/Eyeball Boss.tscn
Normal file
127
Enemies/Eyeball Boss.tscn
Normal file
@@ -0,0 +1,127 @@
|
||||
[gd_scene load_steps=17 format=2]
|
||||
|
||||
[ext_resource path="res://Sprites/Enemies/Eyeball_Boss_Spritesheet.png" type="Texture" id=1]
|
||||
[ext_resource path="res://Enemies/Eyeball Boss.gd" type="Script" id=2]
|
||||
[ext_resource path="res://Sprites/Assets/Light.png" type="Texture" id=3]
|
||||
[ext_resource path="res://Enemies/Projectiles/Glowing Blue Fireball.tscn" type="PackedScene" id=4]
|
||||
|
||||
[sub_resource type="AtlasTexture" id=1]
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 0, 0, 32, 32 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=2]
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 32, 0, 32, 32 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=3]
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 64, 0, 32, 32 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=4]
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 96, 0, 32, 32 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=5]
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 128, 0, 32, 32 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=6]
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 160, 0, 32, 32 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=7]
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 192, 0, 32, 32 )
|
||||
|
||||
[sub_resource type="AtlasTexture" id=8]
|
||||
atlas = ExtResource( 1 )
|
||||
region = Rect2( 224, 0, 32, 32 )
|
||||
|
||||
[sub_resource type="SpriteFrames" id=9]
|
||||
animations = [ {
|
||||
"frames": [ SubResource( 1 ), SubResource( 2 ), SubResource( 3 ), SubResource( 4 ), SubResource( 5 ), SubResource( 6 ), SubResource( 7 ), SubResource( 8 ) ],
|
||||
"loop": true,
|
||||
"name": "idle",
|
||||
"speed": 5.0
|
||||
} ]
|
||||
|
||||
[sub_resource type="CircleShape2D" id=10]
|
||||
radius = 15.0
|
||||
|
||||
[sub_resource type="CircleShape2D" id=12]
|
||||
radius = 17.0
|
||||
|
||||
[sub_resource type="CircleShape2D" id=11]
|
||||
radius = 200.0
|
||||
|
||||
[node name="Eyeball Boss" type="StaticBody2D"]
|
||||
light_mask = 0
|
||||
collision_mask = 0
|
||||
script = ExtResource( 2 )
|
||||
glowing_blue_fireball = ExtResource( 4 )
|
||||
|
||||
[node name="Sprite" type="AnimatedSprite" parent="."]
|
||||
self_modulate = Color( 0.705882, 0.705882, 0.705882, 1 )
|
||||
frames = SubResource( 9 )
|
||||
animation = "idle"
|
||||
frame = 2
|
||||
playing = true
|
||||
|
||||
[node name="Collision" type="CollisionShape2D" parent="."]
|
||||
visible = false
|
||||
light_mask = 0
|
||||
shape = SubResource( 10 )
|
||||
|
||||
[node name="Hitbox" type="Area2D" parent="." groups=["enemy_hitbox_2"]]
|
||||
light_mask = 0
|
||||
collision_layer = 4
|
||||
collision_mask = 2
|
||||
input_pickable = false
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"]
|
||||
visible = false
|
||||
light_mask = 0
|
||||
shape = SubResource( 12 )
|
||||
|
||||
[node name="Player Detector" type="Area2D" parent="."]
|
||||
light_mask = 0
|
||||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
input_pickable = false
|
||||
monitorable = false
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Player Detector"]
|
||||
visible = false
|
||||
light_mask = 0
|
||||
shape = SubResource( 11 )
|
||||
|
||||
[node name="Light" type="Light2D" parent="."]
|
||||
texture = ExtResource( 3 )
|
||||
texture_scale = 0.8
|
||||
|
||||
[node name="Flash" type="Light2D" parent="."]
|
||||
visible = false
|
||||
position = Vector2( 0, 8 )
|
||||
texture = ExtResource( 3 )
|
||||
texture_scale = 0.2
|
||||
color = Color( 0, 0.952941, 1, 1 )
|
||||
shadow_item_cull_mask = 0
|
||||
|
||||
[node name="Shoot" type="Timer" parent="."]
|
||||
wait_time = 1.5
|
||||
autostart = true
|
||||
|
||||
[node name="Flash Timer" type="Timer" parent="."]
|
||||
wait_time = 0.1
|
||||
one_shot = true
|
||||
|
||||
[node name="Hit" type="Timer" parent="."]
|
||||
wait_time = 0.1
|
||||
one_shot = true
|
||||
|
||||
[connection signal="area_entered" from="Hitbox" to="." method="_on_hitbox_area_entered"]
|
||||
[connection signal="body_entered" from="Player Detector" to="." method="_on_player_detector_body_entered"]
|
||||
[connection signal="body_exited" from="Player Detector" to="." method="_on_player_detector_body_exited"]
|
||||
[connection signal="timeout" from="Shoot" to="." method="_on_shoot_timeout"]
|
||||
[connection signal="timeout" from="Flash Timer" to="." method="_on_flash_timer_timeout"]
|
||||
[connection signal="timeout" from="Hit" to="." method="_on_hit_timeout"]
|
@@ -10,49 +10,49 @@ var counter: int = 0
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
velocity = Vector2.ZERO
|
||||
velocity = Vector2.ZERO
|
||||
|
||||
if player and position.distance_to(player.position) > 1:
|
||||
velocity = position.direction_to(player.position).normalized() * SPEED
|
||||
if player and position.distance_to(player.position) > 1:
|
||||
velocity = position.direction_to(player.position).normalized() * SPEED
|
||||
|
||||
|
||||
if hit == true:
|
||||
if counter < 15:
|
||||
if counter % 5 == 0:
|
||||
$AnimatedSprite.visible = false
|
||||
else:
|
||||
$AnimatedSprite.visible = true
|
||||
counter += 1
|
||||
velocity = Vector2.ZERO
|
||||
else:
|
||||
counter = 0
|
||||
hit = false
|
||||
if hit == true:
|
||||
if counter < 15:
|
||||
if counter % 5 == 0:
|
||||
$AnimatedSprite.visible = false
|
||||
else:
|
||||
$AnimatedSprite.visible = true
|
||||
counter += 1
|
||||
velocity = Vector2.ZERO
|
||||
else:
|
||||
counter = 0
|
||||
hit = false
|
||||
|
||||
|
||||
velocity = move_and_slide(velocity)
|
||||
return
|
||||
velocity = move_and_slide(velocity)
|
||||
return
|
||||
|
||||
|
||||
func _on_player_detector_body_entered(body: Node) -> void:
|
||||
if body.is_in_group('player'):
|
||||
player = body
|
||||
return
|
||||
if body.is_in_group('player'):
|
||||
player = body
|
||||
return
|
||||
|
||||
|
||||
func _on_player_detector_body_exited(body: Node) -> void:
|
||||
if body.is_in_group('player'):
|
||||
player = null
|
||||
return
|
||||
if body.is_in_group('player'):
|
||||
player = null
|
||||
return
|
||||
|
||||
|
||||
func _on_hitbox_area_entered(area: Area2D) -> void:
|
||||
if area.is_in_group('player_weapon_1'):
|
||||
health -= 1
|
||||
hit = true
|
||||
elif area.is_in_group('player_weapon_2'):
|
||||
health -= 2
|
||||
hit = true
|
||||
if area.is_in_group('player_weapon_1'):
|
||||
health -= 1
|
||||
hit = true
|
||||
elif area.is_in_group('player_weapon_2'):
|
||||
health -= 2
|
||||
hit = true
|
||||
|
||||
if health <= 0:
|
||||
call_deferred('queue_free')
|
||||
return
|
||||
if health <= 0:
|
||||
call_deferred('queue_free')
|
||||
return
|
||||
|
@@ -20,7 +20,7 @@ func _ready() -> void:
|
||||
|
||||
func _physics_process(delta):
|
||||
velocity = Vector2.ZERO
|
||||
|
||||
|
||||
if player and position.distance_to(player.position) > 1:
|
||||
velocity = position.direction_to(player.position).normalized() * SPEED
|
||||
velocity = move_and_slide(velocity)
|
||||
@@ -34,7 +34,7 @@ func _on_Area2D_body_entered(body):
|
||||
self.visible = true
|
||||
$AnimatedSprite.play("appear")
|
||||
counter = 1
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_AnimatedSprite_animation_finished():
|
||||
|
@@ -6,7 +6,7 @@
|
||||
[ext_resource path="res://Sprites/Assets/ghost-vanish.png" type="Texture" id=4]
|
||||
[ext_resource path="res://Enemies/Ghost_Enemy.gd" type="Script" id=5]
|
||||
[ext_resource path="res://Enemies/Projectiles/Fireball.tscn" type="PackedScene" id=6]
|
||||
[ext_resource path="res://Sprites/Assets/fire_column_medium_14.png" type="Texture" id=7]
|
||||
[ext_resource path="res://Sprites/Levels/Environment/Fire_Column_Medium_14.png" type="Texture" id=7]
|
||||
|
||||
[sub_resource type="AtlasTexture" id=1]
|
||||
atlas = ExtResource( 2 )
|
||||
|
@@ -10,65 +10,65 @@ var counter: int = 0
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
velocity = Vector2.ZERO
|
||||
velocity = Vector2.ZERO
|
||||
|
||||
if player and position.distance_to(player.position) > 1:
|
||||
velocity = position.direction_to(player.position).normalized() * SPEED
|
||||
var angle = position.angle_to_point(player.position)
|
||||
if abs(angle) > PI/2:
|
||||
$AnimatedSprite1.scale.x = -0.563
|
||||
else:
|
||||
$AnimatedSprite1.scale.x = 0.563
|
||||
if player and position.distance_to(player.position) > 1:
|
||||
velocity = position.direction_to(player.position).normalized() * SPEED
|
||||
var angle = position.angle_to_point(player.position)
|
||||
if abs(angle) > PI/2:
|
||||
$AnimatedSprite1.scale.x = -0.563
|
||||
else:
|
||||
$AnimatedSprite1.scale.x = 0.563
|
||||
|
||||
if hit == true:
|
||||
if counter < 15:
|
||||
if counter % 5 == 0:
|
||||
$AnimatedSprite1.visible = false
|
||||
else:
|
||||
$AnimatedSprite1.visible = true
|
||||
counter += 1
|
||||
velocity = Vector2.ZERO
|
||||
else:
|
||||
counter = 0
|
||||
hit = false
|
||||
if hit == true:
|
||||
if counter < 15:
|
||||
if counter % 5 == 0:
|
||||
$AnimatedSprite1.visible = false
|
||||
else:
|
||||
$AnimatedSprite1.visible = true
|
||||
counter += 1
|
||||
velocity = Vector2.ZERO
|
||||
else:
|
||||
counter = 0
|
||||
hit = false
|
||||
|
||||
velocity = move_and_slide(velocity)
|
||||
return
|
||||
velocity = move_and_slide(velocity)
|
||||
return
|
||||
|
||||
|
||||
func _on_player_detector_body_entered(body: Node) -> void:
|
||||
if body.is_in_group('player'):
|
||||
player = body
|
||||
$AnimatedSprite1.animation = 'Running'
|
||||
return
|
||||
if body.is_in_group('player'):
|
||||
player = body
|
||||
$AnimatedSprite1.animation = 'Running'
|
||||
return
|
||||
|
||||
|
||||
func _on_player_detector_body_exited(body: Node) -> void:
|
||||
if body.is_in_group('player'):
|
||||
player = null
|
||||
$AnimatedSprite1.animation = 'Idle'
|
||||
return
|
||||
if body.is_in_group('player'):
|
||||
player = null
|
||||
$AnimatedSprite1.animation = 'Idle'
|
||||
return
|
||||
|
||||
|
||||
func _on_hitbox_area_entered(area: Area2D) -> void:
|
||||
if area.is_in_group('player_weapon_1'):
|
||||
health -= 1
|
||||
hit = true
|
||||
elif area.is_in_group('player_weapon_2'):
|
||||
health -= 2
|
||||
hit = true
|
||||
if area.is_in_group('player_weapon_1'):
|
||||
health -= 1
|
||||
hit = true
|
||||
elif area.is_in_group('player_weapon_2'):
|
||||
health -= 2
|
||||
hit = true
|
||||
|
||||
if health <= 0:
|
||||
call_deferred('queue_free')
|
||||
return
|
||||
if health <= 0:
|
||||
call_deferred('queue_free')
|
||||
return
|
||||
|
||||
func _on_Player_Detector__Attack_body_entered(body: Node) -> void:
|
||||
if body.is_in_group('player'):
|
||||
player = body
|
||||
$AnimatedSprite1.animation = 'Jump'
|
||||
if body.is_in_group('player'):
|
||||
player = body
|
||||
$AnimatedSprite1.animation = 'Jump'
|
||||
|
||||
|
||||
func _on_Player_Detector__Attack_body_exited(body: Node) -> void:
|
||||
if body.is_in_group('player'):
|
||||
player = body
|
||||
$AnimatedSprite1.animation = 'Running'
|
||||
if body.is_in_group('player'):
|
||||
player = body
|
||||
$AnimatedSprite1.animation = 'Running'
|
||||
|
@@ -23,6 +23,6 @@ func _physics_process(delta: float) -> void:
|
||||
return
|
||||
|
||||
|
||||
func _on_tifetime_timeout() -> void:
|
||||
func _on_lifetime_timeout() -> void:
|
||||
call_deferred('queue_free')
|
||||
return
|
||||
|
@@ -7,15 +7,13 @@
|
||||
[sub_resource type="CircleShape2D" id=1]
|
||||
radius = 12.0
|
||||
|
||||
[node name="Creepy Hand" type="Area2D" groups=[
|
||||
"enemy_projectile_1",
|
||||
]]
|
||||
[node name="Creepy Hand" type="Area2D" groups=["enemy_projectile_1"]]
|
||||
light_mask = 0
|
||||
scale = Vector2( 0.5, 0.5 )
|
||||
input_pickable = false
|
||||
monitoring = false
|
||||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
input_pickable = false
|
||||
monitoring = false
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="."]
|
||||
@@ -40,4 +38,4 @@ wait_time = 2.0
|
||||
one_shot = true
|
||||
autostart = true
|
||||
|
||||
[connection signal="timeout" from="Lifetime" to="." method="_on_tifetime_timeout"]
|
||||
[connection signal="timeout" from="Lifetime" to="." method="_on_lifetime_timeout"]
|
||||
|
21
Enemies/Projectiles/Glowing Blue Fireball.gd
Normal file
21
Enemies/Projectiles/Glowing Blue Fireball.gd
Normal file
@@ -0,0 +1,21 @@
|
||||
extends Area2D
|
||||
|
||||
const SPEED: int = 60
|
||||
|
||||
var velocity: Vector2 = Vector2.ZERO
|
||||
|
||||
|
||||
func init(spawn_position: Vector2, shoot_position: Vector2) -> void:
|
||||
position = spawn_position
|
||||
velocity = position.direction_to(shoot_position).normalized() * SPEED
|
||||
return
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
position += velocity * delta
|
||||
return
|
||||
|
||||
|
||||
func _on_lifetime_timeout() -> void:
|
||||
call_deferred('queue_free')
|
||||
return
|
40
Enemies/Projectiles/Glowing Blue Fireball.tscn
Normal file
40
Enemies/Projectiles/Glowing Blue Fireball.tscn
Normal file
@@ -0,0 +1,40 @@
|
||||
[gd_scene load_steps=5 format=2]
|
||||
|
||||
[ext_resource path="res://Sprites/Assets/Light.png" type="Texture" id=1]
|
||||
[ext_resource path="res://Sprites/Enemies/Projectiles/Glowing_Blue_Fireball.png" type="Texture" id=2]
|
||||
[ext_resource path="res://Enemies/Projectiles/Glowing Blue Fireball.gd" type="Script" id=3]
|
||||
|
||||
[sub_resource type="CircleShape2D" id=1]
|
||||
radius = 12.0
|
||||
|
||||
[node name="Glowing Blue Fireball" type="Area2D" groups=["enemy_projectile_1"]]
|
||||
light_mask = 0
|
||||
scale = Vector2( 0.5, 0.5 )
|
||||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
input_pickable = false
|
||||
monitoring = false
|
||||
script = ExtResource( 3 )
|
||||
|
||||
[node name="Sprite" type="Sprite" parent="."]
|
||||
texture = ExtResource( 2 )
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
visible = false
|
||||
light_mask = 0
|
||||
shape = SubResource( 1 )
|
||||
|
||||
[node name="Light" type="Light2D" parent="."]
|
||||
texture = ExtResource( 1 )
|
||||
texture_scale = 0.3
|
||||
color = Color( 0.211765, 0.964706, 0.984314, 1 )
|
||||
energy = 1.5
|
||||
range_item_cull_mask = 15
|
||||
shadow_item_cull_mask = 0
|
||||
|
||||
[node name="Lifetime" type="Timer" parent="."]
|
||||
wait_time = 3.0
|
||||
one_shot = true
|
||||
autostart = true
|
||||
|
||||
[connection signal="timeout" from="Lifetime" to="." method="_on_lifetime_timeout"]
|
@@ -16,6 +16,6 @@ func _physics_process(delta: float) -> void:
|
||||
return
|
||||
|
||||
|
||||
func _on_tifetime_timeout() -> void:
|
||||
func _on_lifetime_timeout() -> void:
|
||||
call_deferred('queue_free')
|
||||
return
|
||||
|
@@ -37,4 +37,4 @@ wait_time = 1.5
|
||||
one_shot = true
|
||||
autostart = true
|
||||
|
||||
[connection signal="timeout" from="Lifetime" to="." method="_on_tifetime_timeout"]
|
||||
[connection signal="timeout" from="Lifetime" to="." method="_on_lifetime_timeout"]
|
||||
|
Reference in New Issue
Block a user