a game about throwing hammers made for the github game off
add first enemy
also i got carried away with doccing my classes
bendn 2022-11-22
parent bd046ec · commit 98da2a7
-rw-r--r--Main.gd2
-rw-r--r--Main.tscn22
-rw-r--r--assets/enemys/bird.pngbin0 -> 551 bytes
-rw-r--r--assets/enemys/bird.png.import34
-rw-r--r--assets/enemys/worm.pngbin0 -> 222 bytes
-rw-r--r--assets/enemys/worm.png.import34
-rw-r--r--assets/enemys/wrencher.pngbin0 -> 502 bytes
-rw-r--r--assets/enemys/wrencher.png.import34
-rw-r--r--assets/hammers/hammer01.pngbin0 -> 127 bytes
-rw-r--r--assets/hammers/hammer01.png.import34
-rw-r--r--assets/hammers/hammer02.pngbin0 -> 131 bytes
-rw-r--r--assets/hammers/hammer02.png.import34
-rw-r--r--assets/hammers/hammer03.pngbin0 -> 122 bytes
-rw-r--r--assets/hammers/hammer03.png.import34
-rw-r--r--autoloads/Globals.gd3
-rw-r--r--autoloads/Utils.gd30
-rw-r--r--colliders/hitbox.gd12
-rw-r--r--colliders/hitbox.tscn10
-rw-r--r--colliders/hittable.gd6
-rw-r--r--colliders/hurtbox.gd5
-rw-r--r--colliders/hurtbox.tscn10
-rw-r--r--enemys/Enemy.gd23
-rw-r--r--enemys/Enemy.tscn23
-rw-r--r--enemys/wrencher.gd83
-rw-r--r--enemys/wrencher.tscn129
-rw-r--r--enemys/wrencher_collision.tres4
-rw-r--r--fx/dust.gd2
-rw-r--r--fx/enemy_death.gd14
-rw-r--r--fx/enemy_death.tscn6
-rw-r--r--fx/trail.gd85
-rw-r--r--fx/trail2d_icon.svg3
-rw-r--r--fx/trail2d_icon.svg.import37
-rw-r--r--hammers/8x14.tres4
-rw-r--r--hammers/hammer.gd52
-rw-r--r--hammers/hammer_01.tscn11
-rw-r--r--hammers/hammer_02.tscn17
-rw-r--r--hammers/hammer_03.tscn26
-rw-r--r--hammers/hammer_base.tscn41
-rw-r--r--hammers/trail_color.tres5
-rw-r--r--hammers/trail_width.tres6
-rw-r--r--levels/BaseTemplate.gd79
-rw-r--r--levels/Level.gd84
-rw-r--r--levels/Level.tscn (renamed from levels/BaseTemplate.tscn)6
-rw-r--r--levels/LevelManager.gd6
-rw-r--r--levels/Start.tscn4
-rw-r--r--levels/level_icon.svg3
-rw-r--r--levels/level_icon.svg.import37
-rw-r--r--levels/rand/01.tscn4
-rw-r--r--levels/rand/02.tscn4
-rw-r--r--levels/rand/03.tscn4
-rw-r--r--levels/rand/04.tscn4
-rw-r--r--levels/rand/05.tscn4
-rw-r--r--levels/rand/06.tscn4
-rw-r--r--levels/rand/07.tscn4
-rw-r--r--levels/rand/08.tscn4
-rw-r--r--levels/rand/09.tscn4
-rw-r--r--levels/rand/10.tscn4
-rw-r--r--levels/rand/11.tscn4
-rw-r--r--levels/rand/12.tscn4
-rw-r--r--levels/rand/13.tscn4
-rw-r--r--levels/rand/14.tscn4
-rw-r--r--levels/rand/15.tscn4
-rw-r--r--levels/rand/16.tscn4
-rw-r--r--levels/rand/17.tscn4
-rw-r--r--levels/rand/18.tscn4
-rw-r--r--player/player.gd9
-rw-r--r--player/player.tscn36
-rw-r--r--player/player_collision.tres5
-rw-r--r--project.godot41
-rw-r--r--world/door/block_door.gd23
-rw-r--r--world/door/door.gd4
71 files changed, 1117 insertions, 167 deletions
diff --git a/Main.gd b/Main.gd
index 0469154..802459b 100644
--- a/Main.gd
+++ b/Main.gd
@@ -4,4 +4,4 @@ var maze: Maze
func _on_level_manager_world_generated(p_maze: Maze) -> void:
- maze = p_maze
+ maze = p_maze
diff --git a/Main.tscn b/Main.tscn
index f9ecbcd..12e0b08 100644
--- a/Main.tscn
+++ b/Main.tscn
@@ -1,4 +1,4 @@
-[gd_scene load_steps=23 format=3 uid="uid://b4g41v2qctg7f"]
+[gd_scene load_steps=25 format=3 uid="uid://b4g41v2qctg7f"]
[ext_resource type="Script" path="res://Main.gd" id="1_l4fqe"]
[ext_resource type="PackedScene" uid="uid://c1fgxkkh72npw" path="res://player/player.tscn" id="1_ug1uc"]
@@ -22,6 +22,9 @@
[ext_resource type="PackedScene" uid="uid://d4dwvcp6764bx" path="res://levels/rand/16.tscn" id="19_ko67h"]
[ext_resource type="PackedScene" uid="uid://duo0cbnh5u3qt" path="res://levels/rand/17.tscn" id="20_f85eu"]
[ext_resource type="PackedScene" uid="uid://cy3kc27btbipt" path="res://levels/rand/18.tscn" id="21_rvdjm"]
+[ext_resource type="PackedScene" uid="uid://f7wqdmugs712" path="res://enemys/wrencher.tscn" id="23_p2dy5"]
+
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_htk2i"]
[node name="Main" type="Node2D"]
texture_filter = 1
@@ -45,4 +48,21 @@ offset = Vector2(128, 128)
current = true
zoom = Vector2(1.25, 1.25)
+[node name="RigidBody2D" type="RigidBody2D" parent="."]
+position = Vector2(164, 82)
+collision_layer = 8
+collision_mask = 11
+mass = 5.0
+
+[node name="CollisionShape2D" type="CollisionShape2D" parent="RigidBody2D"]
+shape = SubResource("RectangleShape2D_htk2i")
+
+[node name="Polygon2D" type="Polygon2D" parent="RigidBody2D"]
+polygon = PackedVector2Array(-10, -10, -10, -10, 10, -10, 10, 10, -10, 10)
+
+[node name="Wrencher" parent="." instance=ExtResource("23_p2dy5")]
+position = Vector2(16, 163)
+rotation = 1.57079
+
[connection signal="world_generated" from="LevelManager" to="." method="_on_level_manager_world_generated"]
+[connection signal="died" from="Wrencher" to="Wrencher" method="die"]
diff --git a/assets/enemys/bird.png b/assets/enemys/bird.png
new file mode 100644
index 0000000..40ea703
--- /dev/null
+++ b/assets/enemys/bird.png
Binary files differ
diff --git a/assets/enemys/bird.png.import b/assets/enemys/bird.png.import
new file mode 100644
index 0000000..98cbd33
--- /dev/null
+++ b/assets/enemys/bird.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dmsbm3rfeyn3v"
+path="res://.godot/imported/bird.png-67494895ecaae32bb4d352e8e04faba3.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/enemys/bird.png"
+dest_files=["res://.godot/imported/bird.png-67494895ecaae32bb4d352e8e04faba3.ctex"]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/bptc_ldr=0
+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
diff --git a/assets/enemys/worm.png b/assets/enemys/worm.png
new file mode 100644
index 0000000..6a2a1b6
--- /dev/null
+++ b/assets/enemys/worm.png
Binary files differ
diff --git a/assets/enemys/worm.png.import b/assets/enemys/worm.png.import
new file mode 100644
index 0000000..8b07710
--- /dev/null
+++ b/assets/enemys/worm.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://wouxdtpy13s3"
+path="res://.godot/imported/worm.png-80645eec2d7a6a8d4331df1cdaf183b6.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/enemys/worm.png"
+dest_files=["res://.godot/imported/worm.png-80645eec2d7a6a8d4331df1cdaf183b6.ctex"]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/bptc_ldr=0
+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
diff --git a/assets/enemys/wrencher.png b/assets/enemys/wrencher.png
new file mode 100644
index 0000000..63d5da5
--- /dev/null
+++ b/assets/enemys/wrencher.png
Binary files differ
diff --git a/assets/enemys/wrencher.png.import b/assets/enemys/wrencher.png.import
new file mode 100644
index 0000000..1a5bef7
--- /dev/null
+++ b/assets/enemys/wrencher.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bbp683dgbfu76"
+path="res://.godot/imported/wrencher.png-ce39ce010949597f777cf8f28a8a0d75.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/enemys/wrencher.png"
+dest_files=["res://.godot/imported/wrencher.png-ce39ce010949597f777cf8f28a8a0d75.ctex"]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/bptc_ldr=0
+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
diff --git a/assets/hammers/hammer01.png b/assets/hammers/hammer01.png
new file mode 100644
index 0000000..a988b9d
--- /dev/null
+++ b/assets/hammers/hammer01.png
Binary files differ
diff --git a/assets/hammers/hammer01.png.import b/assets/hammers/hammer01.png.import
new file mode 100644
index 0000000..56e605a
--- /dev/null
+++ b/assets/hammers/hammer01.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dcf5es758pw1n"
+path="res://.godot/imported/hammer01.png-5e086a4b5f808836c38d44299bce41b2.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/hammers/hammer01.png"
+dest_files=["res://.godot/imported/hammer01.png-5e086a4b5f808836c38d44299bce41b2.ctex"]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/bptc_ldr=0
+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
diff --git a/assets/hammers/hammer02.png b/assets/hammers/hammer02.png
new file mode 100644
index 0000000..edae92d
--- /dev/null
+++ b/assets/hammers/hammer02.png
Binary files differ
diff --git a/assets/hammers/hammer02.png.import b/assets/hammers/hammer02.png.import
new file mode 100644
index 0000000..e3ce64a
--- /dev/null
+++ b/assets/hammers/hammer02.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bcpy0wbrlmqsq"
+path="res://.godot/imported/hammer02.png-f372d77aafa92e6ad72ccbb6fa6dd264.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/hammers/hammer02.png"
+dest_files=["res://.godot/imported/hammer02.png-f372d77aafa92e6ad72ccbb6fa6dd264.ctex"]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/bptc_ldr=0
+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
diff --git a/assets/hammers/hammer03.png b/assets/hammers/hammer03.png
new file mode 100644
index 0000000..840a1c2
--- /dev/null
+++ b/assets/hammers/hammer03.png
Binary files differ
diff --git a/assets/hammers/hammer03.png.import b/assets/hammers/hammer03.png.import
new file mode 100644
index 0000000..f3272f6
--- /dev/null
+++ b/assets/hammers/hammer03.png.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://blx67dnlqysnc"
+path="res://.godot/imported/hammer03.png-16829620ed9d85fffb33ca735666bb13.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/hammers/hammer03.png"
+dest_files=["res://.godot/imported/hammer03.png-16829620ed9d85fffb33ca735666bb13.ctex"]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/bptc_ldr=0
+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
diff --git a/autoloads/Globals.gd b/autoloads/Globals.gd
new file mode 100644
index 0000000..d371dc3
--- /dev/null
+++ b/autoloads/Globals.gd
@@ -0,0 +1,3 @@
+extends Node
+
+var player: Player = null \ No newline at end of file
diff --git a/autoloads/Utils.gd b/autoloads/Utils.gd
index a005032..0a07436 100644
--- a/autoloads/Utils.gd
+++ b/autoloads/Utils.gd
@@ -3,20 +3,32 @@ class_name Util
func instance_scene_on_main(scene: PackedScene, position: Vector2) -> Node:
- var main = get_tree().current_scene
- var instance = scene.instantiate()
- main.add_child(instance)
- instance.global_position = position
- return instance
+ var main := get_tree().current_scene
+ var instance := scene.instantiate() as Node2D
+ main.add_child(instance)
+ instance.global_position = position
+ return instance
static func str_vec(vec: Vector2) -> String:
- var map := {Vector2.UP: "up", Vector2.DOWN: "down", Vector2.LEFT: "left", Vector2.RIGHT: "right"}
- return map.get(vec, str(vec))
+ var map := {Vector2.UP: "up", Vector2.DOWN: "down", Vector2.LEFT: "left", Vector2.RIGHT: "right"}
+ return map.get(vec, str(vec))
static func sub(a: Array, b: Array) -> Array:
- return a.filter(func(item) -> bool: return not item in b)
+ return a.filter(func(item) -> bool: return not item in b)
+
static func out_of_bounds(v: Vector2i, rect: Vector2i) -> bool:
- return v.x > rect.x or v.y > rect.y or v.x < 0 or v.y < 0 \ No newline at end of file
+ return v.x > rect.x or v.y > rect.y or v.x < 0 or v.y < 0
+
+
+const hammer_path_fmt := "res://hammers/hammer_%s.tscn"
+const hammers: Array[PackedScene] = [
+ preload(hammer_path_fmt % "01"),
+ preload(hammer_path_fmt % "02"),
+ preload(hammer_path_fmt % "03"),
+]
+
+func get_hammer() -> PackedScene:
+ return hammers[randi() % len(hammers)]
diff --git a/colliders/hitbox.gd b/colliders/hitbox.gd
new file mode 100644
index 0000000..9bcc233
--- /dev/null
+++ b/colliders/hitbox.gd
@@ -0,0 +1,12 @@
+extends Area2D
+
+@export var damage: int = 1
+
+signal hit_enemy
+
+func _on_area_entered(hurtbox: Hurtbox) -> void:
+ (hurtbox.owner as Hittable).hit(damage)
+ hit_enemy.emit()
+
+func _ready() -> void:
+ area_entered.connect(_on_area_entered)
diff --git a/colliders/hitbox.tscn b/colliders/hitbox.tscn
new file mode 100644
index 0000000..75cacc3
--- /dev/null
+++ b/colliders/hitbox.tscn
@@ -0,0 +1,10 @@
+[gd_scene load_steps=2 format=3 uid="uid://cdpkxaateaqdf"]
+
+[ext_resource type="Script" path="res://colliders/hitbox.gd" id="1_3seao"]
+
+[node name="Hitbox" type="Area2D"]
+collision_layer = 0
+monitorable = false
+script = ExtResource("1_3seao")
+
+[node name="Collision" type="CollisionShape2D" parent="."]
diff --git a/colliders/hittable.gd b/colliders/hittable.gd
new file mode 100644
index 0000000..89090eb
--- /dev/null
+++ b/colliders/hittable.gd
@@ -0,0 +1,6 @@
+extends CharacterBody2D
+class_name Hittable
+
+# @virtual
+func hit(_damage: int) -> void:
+ pass \ No newline at end of file
diff --git a/colliders/hurtbox.gd b/colliders/hurtbox.gd
new file mode 100644
index 0000000..df92234
--- /dev/null
+++ b/colliders/hurtbox.gd
@@ -0,0 +1,5 @@
+extends Area2D
+class_name Hurtbox
+
+func _ready() -> void:
+ assert(owner is Hittable) \ No newline at end of file
diff --git a/colliders/hurtbox.tscn b/colliders/hurtbox.tscn
new file mode 100644
index 0000000..67be79b
--- /dev/null
+++ b/colliders/hurtbox.tscn
@@ -0,0 +1,10 @@
+[gd_scene load_steps=2 format=3 uid="uid://qliv2erkwokh"]
+
+[ext_resource type="Script" path="res://colliders/hurtbox.gd" id="1_4me7n"]
+
+[node name="Hurtbox" type="Area2D"]
+collision_mask = 0
+monitoring = false
+script = ExtResource("1_4me7n")
+
+[node name="Collision" type="CollisionShape2D" parent="."]
diff --git a/enemys/Enemy.gd b/enemys/Enemy.gd
new file mode 100644
index 0000000..55ce199
--- /dev/null
+++ b/enemys/Enemy.gd
@@ -0,0 +1,23 @@
+## A enemy! Kill it!
+extends Hittable
+class_name Enemy
+
+signal died
+
+## Maximum health
+@export var max_health: int = 1
+
+## Current health
+@onready var health := max_health:
+ set(value):
+ health = clamp(value, 0, max_health)
+ if health == 0:
+ died.emit() # voodoo magic makes this signal connect to die()
+ # die()
+
+func hit(damage: int) -> void:
+ health -= damage
+
+func die() -> void:
+ Utils.instance_scene_on_main(preload("res://fx/enemy_death.tscn"), global_position)
+ queue_free()
diff --git a/enemys/Enemy.tscn b/enemys/Enemy.tscn
new file mode 100644
index 0000000..8016a44
--- /dev/null
+++ b/enemys/Enemy.tscn
@@ -0,0 +1,23 @@
+[gd_scene load_steps=4 format=3 uid="uid://baefo17xlk1n1"]
+
+[ext_resource type="Script" path="res://enemys/Enemy.gd" id="1_rvxwt"]
+[ext_resource type="PackedScene" uid="uid://qliv2erkwokh" path="res://colliders/hurtbox.tscn" id="2_c7rvc"]
+[ext_resource type="PackedScene" uid="uid://cdpkxaateaqdf" path="res://colliders/hitbox.tscn" id="3_cav1d"]
+
+[node name="Enemy" type="CharacterBody2D"]
+texture_filter = 1
+collision_layer = 16
+script = ExtResource("1_rvxwt")
+
+[node name="Sprite" type="Sprite2D" parent="."]
+
+[node name="Collision" type="CollisionShape2D" parent="."]
+
+[node name="Hurtbox" parent="." instance=ExtResource("2_c7rvc")]
+collision_layer = 8
+
+[node name="Hitbox" parent="." instance=ExtResource("3_cav1d")]
+collision_mask = 4
+
+[editable path="Hurtbox"]
+[editable path="Hitbox"]
diff --git a/enemys/wrencher.gd b/enemys/wrencher.gd
new file mode 100644
index 0000000..cfa44ca
--- /dev/null
+++ b/enemys/wrencher.gd
@@ -0,0 +1,83 @@
+extends Enemy
+
+@export var ACCELERATION := 3
+@export var MAX_SPEED := 32
+@export var FRICTION := .8
+@export var SHOT_COOLDOWN := 1
+@onready @export var muzzle: Node2D
+@onready @export var floorcast: RayCast2D
+@onready @export var animator: AnimationPlayer
+@onready @export var player_cast: ShapeCast2D
+
+var axis := 0
+var current_dir := 0
+enum States {MOVE, FIRE}
+var state := States.MOVE
+var bullet_timer: SceneTreeTimer = null
+
+func _ready() -> void:
+ up_direction = global_position.direction_to(muzzle.global_position).round()
+ axis = 1 if up_direction.x != 0 else 0
+ current_dir = -1 if randi() % 2 == 0 else 1
+
+
+func _physics_process(_delta: float) -> void:
+ match state:
+ States.MOVE:
+ var dir := brain()
+ animator.play(&"normal")
+
+ velocity[axis] += dir * ACCELERATION
+ velocity[axis] = clampf(velocity[axis], -MAX_SPEED, MAX_SPEED)
+ if (dir == 0):
+ velocity[axis] = lerpf(velocity[axis], 0, FRICTION)
+ floorcast.position.x = 0 + (dir * 10)
+ move_and_slide()
+ States.FIRE:
+ animator.play(&"fire")
+ await animator.animation_finished
+ state = States.MOVE
+
+
+func fire() -> void:
+ var hammer: Hammer = Utils.instance_scene_on_main(Utils.get_hammer(), muzzle.global_position)
+ hammer.steer_force = 0.01 # cheat
+ hammer.target = Globals.player
+ hammer.direction = up_direction
+ bullet_timer = get_tree().create_timer(SHOT_COOLDOWN)
+ player_cast.enabled = false
+
+func brain() -> float:
+ var dir := 0.0
+ if bullet_timer == null or bullet_timer.time_left < 0:
+ if not player_cast.enabled:
+ bullet_timer = null
+ player_cast.force_shapecast_update()
+ player_cast.enabled = true
+ for i in player_cast.get_collision_count():
+ if player_cast.get_collider(i) is Player:
+ if player_cast.get_collision_count() != 1:
+ player_cast.target_position.y = -((global_position.y-Globals.player.global_position.y) + 30)
+ player_cast.force_shapecast_update()
+ player_cast.target_position.y = -170
+ if player_cast.get_collision_count() == 1:
+ state = States.FIRE
+ break
+ if not state == States.FIRE:
+ if is_on_wall():
+ dir = -get_wall_axis()
+ elif not floorcast.is_colliding():
+ dir = -current_dir
+ else:
+ dir = current_dir
+ current_dir = roundi(dir)
+ return dir
+
+func get_wall_axis() -> int:
+ var left := up_direction
+ left[axis] = -1
+ var right := up_direction
+ right[axis] = 1
+ var is_right_wall := test_move(transform, left)
+ var is_left_wall := test_move(transform, right)
+ return int(is_left_wall) - int(is_right_wall)
diff --git a/enemys/wrencher.tscn b/enemys/wrencher.tscn
new file mode 100644
index 0000000..70b7e28
--- /dev/null
+++ b/enemys/wrencher.tscn
@@ -0,0 +1,129 @@
+[gd_scene load_steps=10 format=3 uid="uid://f7wqdmugs712"]
+
+[ext_resource type="PackedScene" uid="uid://baefo17xlk1n1" path="res://enemys/Enemy.tscn" id="1_7mo8u"]
+[ext_resource type="Texture2D" uid="uid://bbp683dgbfu76" path="res://assets/enemys/wrencher.png" id="2_0jx2r"]
+[ext_resource type="Script" path="res://enemys/wrencher.gd" id="2_ydgi0"]
+[ext_resource type="Shape2D" uid="uid://5mpwir3ab0ff" path="res://enemys/wrencher_collision.tres" id="3_fsg5e"]
+
+[sub_resource type="Animation" id="Animation_ghcxr"]
+length = 0.001
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("Sprite:frame")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0),
+"transitions": PackedFloat32Array(1),
+"update": 1,
+"values": [4]
+}
+
+[sub_resource type="Animation" id="Animation_3sxm5"]
+resource_name = "fire"
+length = 1.2
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("Sprite:frame")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0, 0.2, 0.4, 0.7, 0.8, 1, 1.1),
+"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1),
+"update": 1,
+"values": [4, 5, 6, 7, 6, 8, 4]
+}
+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.7),
+"transitions": PackedFloat32Array(1),
+"values": [{
+"args": [],
+"method": &"fire"
+}]
+}
+
+[sub_resource type="Animation" id="Animation_kjtpb"]
+resource_name = "normal"
+loop_mode = 1
+tracks/0/type = "value"
+tracks/0/imported = false
+tracks/0/enabled = true
+tracks/0/path = NodePath("Sprite:frame")
+tracks/0/interp = 1
+tracks/0/loop_wrap = true
+tracks/0/keys = {
+"times": PackedFloat32Array(0, 0.2, 0.4, 0.6, 0.8),
+"transitions": PackedFloat32Array(1, 1, 1, 1, 1),
+"update": 1,
+"values": [0, 1, 2, 3, 4]
+}
+
+[sub_resource type="AnimationLibrary" id="AnimationLibrary_bv8p0"]
+_data = {
+"RESET": SubResource("Animation_ghcxr"),
+"fire": SubResource("Animation_3sxm5"),
+"normal": SubResource("Animation_kjtpb")
+}
+
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_j3gtw"]
+size = Vector2(20, 50)
+
+[node name="Wrencher" node_paths=PackedStringArray("muzzle", "floorcast", "animator", "player_cast") instance=ExtResource("1_7mo8u")]
+script = ExtResource("2_ydgi0")
+ACCELERATION = 3
+MAX_SPEED = 32
+FRICTION = 0.8
+SHOT_COOLDOWN = 1
+muzzle = NodePath("Muzzle")
+floorcast = NodePath("FloorCast")
+animator = NodePath("AnimationPlayer")
+player_cast = NodePath("PlayerCast")
+
+[node name="Sprite" parent="." index="0"]
+position = Vector2(0, -8)
+texture = ExtResource("2_0jx2r")
+hframes = 9
+frame = 4
+
+[node name="Collision" parent="." index="1"]
+position = Vector2(0, -5)
+shape = ExtResource("3_fsg5e")
+
+[node name="Collision" parent="Hurtbox" index="0"]
+visible = false
+position = Vector2(0, -5)
+shape = ExtResource("3_fsg5e")
+
+[node name="Collision" parent="Hitbox" index="0"]
+visible = false
+position = Vector2(0, -5)
+shape = ExtResource("3_fsg5e")
+
+[node name="AnimationPlayer" type="AnimationPlayer" parent="." index="4"]
+libraries = {
+"": SubResource("AnimationLibrary_bv8p0")
+}
+
+[node name="Muzzle" type="Node2D" parent="." index="5"]
+position = Vector2(0, -6)
+
+[node name="FloorCast" type="RayCast2D" parent="." index="6"]
+position = Vector2(0, -3)
+target_position = Vector2(0, 5)
+
+[node name="PlayerCast" type="ShapeCast2D" parent="." index="7"]
+position = Vector2(0, -25)
+shape = SubResource("RectangleShape2D_j3gtw")
+target_position = Vector2(0, -170)
+collision_mask = 3
+
+[editable path="Hurtbox"]
+[editable path="Hitbox"]
diff --git a/enemys/wrencher_collision.tres b/enemys/wrencher_collision.tres
new file mode 100644
index 0000000..1816089
--- /dev/null
+++ b/enemys/wrencher_collision.tres
@@ -0,0 +1,4 @@
+[gd_resource type="RectangleShape2D" format=3 uid="uid://5mpwir3ab0ff"]
+
+[resource]
+size = Vector2(16, 10)
diff --git a/fx/dust.gd b/fx/dust.gd
index 6bc9386..2974472 100644
--- a/fx/dust.gd
+++ b/fx/dust.gd
@@ -4,4 +4,4 @@ var motion := Vector2(randf_range(-20, 20), randf_range(-10, 10))
func _process(delta: float) -> void:
- position += motion * delta
+ position += motion * delta
diff --git a/fx/enemy_death.gd b/fx/enemy_death.gd
new file mode 100644
index 0000000..0d5638a
--- /dev/null
+++ b/fx/enemy_death.gd
@@ -0,0 +1,14 @@
+extends Node2D
+
+const DustFx := preload("./dust.tscn")
+
+func _ready() -> void:
+ # print(global_position)
+ randomize()
+ # print_stack()
+ # get_tree().paused = true
+ var randv := func randv(): return Vector2(randf_range(-10, 10), randf_range(-10, 10))
+ for i in range(10):
+ var inst := Utils.instance_scene_on_main(DustFx, global_position + randv.call())
+ if i == 9:
+ inst.tree_exited.connect(queue_free)
diff --git a/fx/enemy_death.tscn b/fx/enemy_death.tscn
new file mode 100644
index 0000000..9dd9c1f
--- /dev/null
+++ b/fx/enemy_death.tscn
@@ -0,0 +1,6 @@
+[gd_scene load_steps=2 format=3 uid="uid://b10daeo07yvlv"]
+
+[ext_resource type="Script" path="res://fx/enemy_death.gd" id="1_pgtt6"]
+
+[node name="EnemyDeathEffect" type="Node2D"]
+script = ExtResource("1_pgtt6")
diff --git a/fx/trail.gd b/fx/trail.gd
new file mode 100644
index 0000000..dd8f064
--- /dev/null
+++ b/fx/trail.gd
@@ -0,0 +1,85 @@
+## Draws a 2D trail using a [Line2D].
+class_name Trail2D
+extends Line2D
+
+@icon("./trail2d_icon.svg")
+
+## Enable or disable the trail
+@export var is_emitting := false:
+ set(emitting):
+ is_emitting = emitting
+ if not is_inside_tree():
+ await ready
+
+ if is_emitting:
+ clear_points()
+ _points_creation_time.clear()
+ _last_point = to_local(target.global_position)
+
+## Resolution. Smaller = more points
+@export var resolution := 2.0
+
+## The lifetime for each point
+@export var lifetime := 0.5
+
+## Maximum number of points
+@export var max_points := 100
+
+## Optional path to the target node to follow. If not set, the instance follows its parent.
+@onready @export var target: Node2D
+
+var _points_creation_time := []
+var _last_point := Vector2.ZERO
+var _clock := 0.0
+
+func _ready() -> void:
+ if not target:
+ target = get_parent() as Node2D
+
+ joint_mode = Line2D.LINE_JOINT_BEVEL
+ top_level = true
+ clear_points()
+ position = Vector2.ZERO
+ _last_point = to_local(target.global_position)
+
+
+func _process(delta: float) -> void:
+ _clock += delta
+ remove_older()
+
+ if not is_emitting:
+ return
+
+ # Adding new points if necessary.
+ var desired_point := (target.global_position)
+ var distance: float = _last_point.distance_to(desired_point)
+ if distance > resolution:
+ add_timed_point(desired_point, _clock)
+
+
+## Creates a new point and stores its creation time.
+func add_timed_point(point: Vector2, time: float) -> void:
+ add_point(point)
+ _points_creation_time.append(time)
+ _last_point = point
+ if get_point_count() > max_points:
+ remove_first_point()
+
+
+## Removes the first point in the line and the corresponding time.
+func remove_first_point() -> void:
+ if get_point_count() > 1:
+ remove_point(0)
+ _points_creation_time.pop_front()
+
+
+## Remove points older than [code]lifetime[/code].
+func remove_older() -> void:
+ for creation_time in _points_creation_time:
+ var delta = _clock - creation_time
+ if delta > lifetime:
+ remove_first_point()
+ # Points in `_points_creation_time` are ordered from oldest to newest so as soon as a point
+ # isn't older than `lifetime`, we know all remaining points should stay as well.
+ else:
+ break
diff --git a/fx/trail2d_icon.svg b/fx/trail2d_icon.svg
new file mode 100644
index 0000000..903ba96
--- /dev/null
+++ b/fx/trail2d_icon.svg
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4.233 4.233" height="16" width="16" source="https://github.com/OBKF/Godot-Trail-System">
+ <path d="M2.38 293.033a2.106 2.106 0 0 0-1.112.269 1.96 1.96 0 0 0-.926 2.045c.17.76.804 1.3 1.495 1.38.692.072 1.342-.327 1.594-.885-.357.498-1.02.695-1.523.529-.505-.158-.857-.672-.846-1.119-.006-.445.334-.88.688-.973a.766.766 0 0 1 .32-.03 1.145 1.145 0 0 1-.015-.183 1.145 1.145 0 0 1 .595-1.001 2.085 2.085 0 0 0-.27-.032zm1.547 1.033a.727.727 0 0 1-.727.727.727.727 0 0 1-.727-.727.727.727 0 0 1 .727-.727.727.727 0 0 1 .727.727z" style="vector-effect:none;fill:#a5b7f3;fill-opacity:1;stroke:none;stroke-width:.26499999;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" transform="translate(0 -292.767)"/>
+</svg>
diff --git a/fx/trail2d_icon.svg.import b/fx/trail2d_icon.svg.import
new file mode 100644
index 0000000..1630a1d
--- /dev/null
+++ b/fx/trail2d_icon.svg.import
@@ -0,0 +1,37 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://cvnsmgthpro2g"
+path="res://.godot/imported/trail2d_icon.svg-c8fbbbb5c3d8b9d54e76a3e6a2dc876c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://fx/trail2d_icon.svg"
+dest_files=["res://.godot/imported/trail2d_icon.svg-c8fbbbb5c3d8b9d54e76a3e6a2dc876c.ctex"]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/bptc_ldr=0
+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
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/hammers/8x14.tres b/hammers/8x14.tres
new file mode 100644
index 0000000..0d53234
--- /dev/null
+++ b/hammers/8x14.tres
@@ -0,0 +1,4 @@
+[gd_resource type="RectangleShape2D" format=3 uid="uid://bg3mq5wg3xtiy"]
+
+[resource]
+size = Vector2(6, 12)
diff --git a/hammers/hammer.gd b/hammers/hammer.gd
new file mode 100644
index 0000000..9be86af
--- /dev/null
+++ b/hammers/hammer.gd
@@ -0,0 +1,52 @@
+## A hammer.
+extends Area2D
+class_name Hammer
+
+@icon("res://assets/hammers/hammer01.png")
+
+## The current velocity
+var velocity := Vector2.ZERO
+
+## The direction to go in
+var direction := Vector2.ZERO
+
+## Acceleration
+@export var acceleration := 100
+
+## Maximum speed
+@export var top_speed := 200
+
+## The amount it can turn towards its target in radians
+@export var steer_force = 0.05
+
+## The target
+var target: Node2D = null
+
+## To hit the player
+var hit_player := true
+
+## To hit the enemys
+var hit_enemys := false
+
+@onready var trail: Trail2D = $Trail2D
+
+func _ready() -> void:
+ set_collision_mask_value(3, hit_player)
+ set_collision_mask_value(4, hit_enemys)
+
+func seek() -> void:
+ if target:
+ direction = direction + (global_position.direction_to(target.global_position) - direction) * steer_force
+
+
+func _physics_process(delta: float) -> void:
+ seek()
+ velocity = (direction * acceleration * delta).limit_length(top_speed)
+ print(velocity)
+ rotation = velocity.angle() + PI/2 # face forward
+ global_position += velocity
+
+func _on_body_entered(_body: Node2D) -> void:
+ trail.clear_points()
+ global_position += velocity # go into the wall a little
+ set_physics_process(false)
diff --git a/hammers/hammer_01.tscn b/hammers/hammer_01.tscn
new file mode 100644
index 0000000..1ba90e4
--- /dev/null
+++ b/hammers/hammer_01.tscn
@@ -0,0 +1,11 @@
+[gd_scene load_steps=3 format=3 uid="uid://bjux3r57ffv8e"]
+
+[ext_resource type="PackedScene" uid="uid://bciufe82lwiaw" path="res://hammers/hammer_base.tscn" id="1_350hj"]
+[ext_resource type="Texture2D" uid="uid://dcf5es758pw1n" path="res://assets/hammers/hammer01.png" id="2_sdlv5"]
+
+[node name="Hammer01" instance=ExtResource("1_350hj")]
+
+[node name="Sprite" parent="." index="1"]
+texture = ExtResource("2_sdlv5")
+
+[editable path="Hitbox"]
diff --git a/hammers/hammer_02.tscn b/hammers/hammer_02.tscn
new file mode 100644
index 0000000..bcd1390
--- /dev/null
+++ b/hammers/hammer_02.tscn
@@ -0,0 +1,17 @@
+[gd_scene load_steps=3 format=3 uid="uid://cd85psvumxs8"]
+
+[ext_resource type="PackedScene" uid="uid://bciufe82lwiaw" path="res://hammers/hammer_base.tscn" id="1_vy2k1"]
+[ext_resource type="Texture2D" uid="uid://bcpy0wbrlmqsq" path="res://assets/hammers/hammer02.png" id="2_dmvhv"]
+
+[node name="Hammer02" instance=ExtResource("1_vy2k1")]
+
+[node name="Trail2D" parent="." index="0"]
+z_index = -1
+
+[node name="Sprite" parent="." index="1"]
+texture = ExtResource("2_dmvhv")
+
+[node name="Hitbox" parent="." index="3"]
+damage = 2
+
+[editable path="Hitbox"]
diff --git a/hammers/hammer_03.tscn b/hammers/hammer_03.tscn
new file mode 100644
index 0000000..bdb8ad8
--- /dev/null
+++ b/hammers/hammer_03.tscn
@@ -0,0 +1,26 @@
+[gd_scene load_steps=5 format=3 uid="uid://lsx00k2cigtf"]
+
+[ext_resource type="PackedScene" uid="uid://bciufe82lwiaw" path="res://hammers/hammer_base.tscn" id="1_wc0io"]
+[ext_resource type="Texture2D" uid="uid://blx67dnlqysnc" path="res://assets/hammers/hammer03.png" id="2_0uj7a"]
+
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_06tn2"]
+size = Vector2(8, 12)
+
+[sub_resource type="RectangleShape2D" id="RectangleShape2D_k0ws5"]
+size = Vector2(8, 12)
+
+[node name="Hammer03" instance=ExtResource("1_wc0io")]
+
+[node name="Sprite" parent="." index="0"]
+texture = ExtResource("2_0uj7a")
+
+[node name="Collision" parent="." index="1"]
+shape = SubResource("RectangleShape2D_06tn2")
+
+[node name="Hitbox" parent="." index="2"]
+damage = 3
+
+[node name="Collision" parent="Hitbox" index="0"]
+shape = SubResource("RectangleShape2D_k0ws5")
+
+[editable path="Hitbox"]
diff --git a/hammers/hammer_base.tscn b/hammers/hammer_base.tscn
new file mode 100644
index 0000000..6efe682
--- /dev/null
+++ b/hammers/hammer_base.tscn
@@ -0,0 +1,41 @@
+[gd_scene load_steps=7 format=3 uid="uid://bciufe82lwiaw"]
+
+[ext_resource type="PackedScene" uid="uid://cdpkxaateaqdf" path="res://colliders/hitbox.tscn" id="1_kdx5x"]
+[ext_resource type="Script" path="res://hammers/hammer.gd" id="1_xp22t"]
+[ext_resource type="Shape2D" uid="uid://bg3mq5wg3xtiy" path="res://hammers/8x14.tres" id="2_tgkvf"]
+[ext_resource type="Script" path="res://fx/trail.gd" id="4_boru3"]
+[ext_resource type="Curve" uid="uid://bud8anghktv2f" path="res://hammers/trail_width.tres" id="4_yvshk"]
+[ext_resource type="Gradient" uid="uid://bi35r2i1ue6ub" path="res://hammers/trail_color.tres" id="5_8dqv1"]
+
+[node name="Hammer" type="Area2D"]
+texture_filter = 1
+collision_layer = 0
+script = ExtResource("1_xp22t")
+
+[node name="Trail2D" type="Line2D" parent="."]
+position = Vector2(0, -6)
+z_index = -1
+points = PackedVector2Array(0, 0)
+width = 3.0
+width_curve = ExtResource("4_yvshk")
+gradient = ExtResource("5_8dqv1")
+round_precision = 4
+antialiased = true
+script = ExtResource("4_boru3")
+is_emitting = true
+lifetime = 2.0
+
+[node name="Sprite" type="Sprite2D" parent="."]
+
+[node name="Collision" type="CollisionShape2D" parent="."]
+shape = ExtResource("2_tgkvf")
+
+[node name="Hitbox" parent="." instance=ExtResource("1_kdx5x")]
+
+[node name="Collision" parent="Hitbox" index="0"]
+visible = false
+shape = ExtResource("2_tgkvf")
+
+[connection signal="body_entered" from="." to="." method="_on_body_entered"]
+
+[editable path="Hitbox"]
diff --git a/hammers/trail_color.tres b/hammers/trail_color.tres
new file mode 100644
index 0000000..3a06925
--- /dev/null
+++ b/hammers/trail_color.tres
@@ -0,0 +1,5 @@
+[gd_resource type="Gradient" format=3 uid="uid://bi35r2i1ue6ub"]
+
+[resource]
+offsets = PackedFloat32Array(0.0795756, 0.331565, 0.901857)
+colors = PackedColorArray(1, 1, 1, 0.247059, 1, 1, 1, 1, 1, 1, 1, 1)
diff --git a/hammers/trail_width.tres b/hammers/trail_width.tres
new file mode 100644
index 0000000..fd6f48e
--- /dev/null
+++ b/hammers/trail_width.tres
@@ -0,0 +1,6 @@
+[gd_resource type="Curve" format=3 uid="uid://bud8anghktv2f"]
+
+[resource]
+bake_resolution = 20
+_data = [Vector2(0, 0.00943398), 0.0, 6.15849, 0, 0, Vector2(0.406863, 1), 0.0343667, 0.0343667, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0]
+point_count = 3
diff --git a/levels/BaseTemplate.gd b/levels/BaseTemplate.gd
deleted file mode 100644
index 6679cde..0000000
--- a/levels/BaseTemplate.gd
+++ /dev/null
@@ -1,79 +0,0 @@
-extends TileMap
-class_name Level
-
-const BlockDoor_scn := preload("res://world/door/block_door.tscn")
-const Door_scn := preload("res://world/door/door.tscn")
-const OneWayPlatform_scn := preload("res://world/one_way_platform.tscn")
-
-const ALL_DOORS := [Vector2i.UP, Vector2i.DOWN, Vector2i.LEFT, Vector2i.RIGHT]
-
-@export_range(0, 15) var enabled_walls := 0 # https://kidscancode.org/blog/img/cells_4bit.png
-
-const rot_map := {Vector2i.LEFT: PI, Vector2i.RIGHT: 0, Vector2i.DOWN: PI / 2, Vector2i.UP: -PI / 2} # 180 # 90 # -90
-
-@onready var enemys := $Enemys.get_children()
-@onready var enemyqty := $Enemys.get_child_count()
-@onready var has_enemys := enemyqty != 0
-
-@onready var blockdoors: Node2D
-@onready var doors: Node2D = create_node(&"doors")
-
-
-func create_node(p_name: StringName) -> Node2D:
- var n := Node2D.new()
- n.position = Vector2.ZERO
- n.name = p_name
- add_child(n)
- return n
-
-
-func _ready():
- var wall_array := Maze.tile_4b_to_wall_array(enabled_walls)
-
- if len(wall_array) != 4:
- var door_array := Util.sub(ALL_DOORS, wall_array)
- if Vector2i.DOWN in door_array:
- var p: OneWayPlatform = OneWayPlatform_scn.instantiate()
- p.position = Vector2(128, 243)
- call_deferred(&"add_child", p)
-
- if has_enemys:
- blockdoors = create_node(&"block_doors")
-
- for door_p in door_array:
- var door := add_door(door_p)
- if has_enemys:
- add_block_door(door)
-
- for enemy in enemys:
- enemy.connect(&"died", _on_enemy_died)
-
-
-func add_door(dir: Vector2i) -> Door:
- var d := Door_scn.instantiate()
- var v := Vector2i(128, 128) # center
- d.rotation = rot_map[dir]
- d.position = Vector2(v + (v * dir)).move_toward(v, 16)
- d.dir = dir
- doors.add_child(d)
- return d
-
-
-func add_block_door(door: Door) -> BlockDoor:
- var d := BlockDoor_scn.instantiate()
- d.rotation = door.rotation
- d.position = door.position.move_toward(Vector2(128, 128), -8)
- blockdoors.add_child(d)
- return d
-
-
-func _on_enemy_died() -> void:
- enemyqty -= 1
- if enemyqty == 0:
- open_doors()
-
-
-func open_doors() -> void:
- var block_doors := blockdoors.get_children()
- for bloc_door in block_doors:
- bloc_door.open()
diff --git a/levels/Level.gd b/levels/Level.gd
new file mode 100644
index 0000000..70afe3e
--- /dev/null
+++ b/levels/Level.gd
@@ -0,0 +1,84 @@
+## A Level.
+extends TileMap
+class_name Level
+
+@icon("./level_icon.svg")
+
+const BlockDoor_scn := preload("res://world/door/block_door.tscn")
+const Door_scn := preload("res://world/door/door.tscn")
+const OneWayPlatform_scn := preload("res://world/one_way_platform.tscn")
+
+const ALL_DOORS := [Vector2i.UP, Vector2i.DOWN, Vector2i.LEFT, Vector2i.RIGHT]
+
+## The enabled walls. [url=https://kidscancode.org/blog/img/cells_4bit.png]4bit[/url]
+@export_range(0, 15) var enabled_walls := 0
+
+const rot_map := {Vector2i.LEFT: PI, Vector2i.RIGHT: 0, Vector2i.DOWN: PI / 2, Vector2i.UP: -PI / 2} # 180 # 90 # -90
+
+@onready var enemys := $Enemys.get_children()
+@onready var enemyqty := $Enemys.get_child_count()
+@onready var has_enemys := enemyqty != 0
+
+@onready var blockdoors: Node2D
+@onready var doors: Node2D = create_node(&"doors")
+
+## Utility fuction to create a [Node2D]
+func create_node(p_name: StringName) -> Node2D:
+ var n := Node2D.new()
+ n.position = Vector2.ZERO
+ n.name = p_name
+ add_child(n)
+ return n
+
+
+func _ready():
+ var wall_array := Maze.tile_4b_to_wall_array(enabled_walls)
+
+ if len(wall_array) != 4:
+ var door_array := Util.sub(ALL_DOORS, wall_array)
+ if Vector2i.DOWN in door_array:
+ var p: OneWayPlatform = OneWayPlatform_scn.instantiate()
+ p.position = Vector2(128, 243)
+ call_deferred(&"add_child", p)
+
+ if has_enemys:
+ blockdoors = create_node(&"block_doors")
+
+ for door_p in door_array:
+ var door := add_door(door_p)
+ if has_enemys:
+ add_block_door(door)
+
+ for enemy in enemys:
+ enemy.died.connect(_on_enemy_died)
+
+
+## Add a [Door] for given direction.
+func add_door(dir: Vector2i) -> Door:
+ var d := Door_scn.instantiate()
+ var v := Vector2i(128, 128) # center
+ d.rotation = rot_map[dir]
+ d.position = Vector2(v + (v * dir)).move_toward(v, 16)
+ d.dir = dir
+ doors.add_child(d)
+ return d
+
+## Add a [BlockDoor] on top of a [Door]
+func add_block_door(door: Door) -> BlockDoor:
+ var d := BlockDoor_scn.instantiate()
+ d.rotation = door.rotation
+ d.position = door.position.move_toward(Vector2(128, 128), -8)
+ blockdoors.add_child(d)
+ return d
+
+
+func _on_enemy_died() -> void:
+ enemyqty -= 1
+ if enemyqty == 0:
+ open_doors()
+
+## Opens all doors
+func open_doors() -> void:
+ var block_doors := blockdoors.get_children()
+ for bloc_door in block_doors:
+ bloc_door.open()
diff --git a/levels/BaseTemplate.tscn b/levels/Level.tscn
index 4674c6d..ad412ee 100644
--- a/levels/BaseTemplate.tscn
+++ b/levels/Level.tscn
@@ -1,9 +1,9 @@
-[gd_scene load_steps=3 format=3 uid="uid://h2yl2s2kudv8"]
+[gd_scene load_steps=3 format=3 uid="uid://cflva11kyp5ui"]
-[ext_resource type="Script" path="res://levels/BaseTemplate.gd" id="1_cubc7"]
+[ext_resource type="Script" path="res://levels/Level.gd" id="1_cubc7"]
[ext_resource type="TileSet" uid="uid://dsw8frlrcnbi8" path="res://world/tiles.tres" id="1_r867i"]
-[node name="BaseTemplate" type="TileMap"]
+[node name="Level" type="TileMap"]
texture_filter = 1
tile_set = ExtResource("1_r867i")
format = 2
diff --git a/levels/LevelManager.gd b/levels/LevelManager.gd
index 644cb98..d7c905c 100644
--- a/levels/LevelManager.gd
+++ b/levels/LevelManager.gd
@@ -14,7 +14,7 @@ const lvl_path_fmt := "res://levels/rand/%s.tscn"
var lvl_position := Vector2i(-1, -1)
var t: SceneTreeTimer
-var sorted := [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]] # Array[Array[PackedScene]] [[0..][1..]...[15..]]
+var sorted := [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]] # Array[PackedSceneArray] [[0..][1..]...[15..]]
func go(to: Vector2i) -> void:
@@ -51,7 +51,7 @@ func sort_levels():
func _ready() -> void:
gen_map()
lvl_position = size / 2
- Events.connect(&"change_level", go)
+ Events.change_level.connect(go)
print_map_pretty()
@@ -67,4 +67,4 @@ func gen_map() -> void:
map_row.append(sorted[i][randi() % len(sorted[i])])
map.append(map_row)
map[lvl_position.x][lvl_position.y] = preload("res://levels/Start.tscn")
- emit_signal(&"world_generated", maze)
+ world_generated.emit(maze)
diff --git a/levels/Start.tscn b/levels/Start.tscn
index 406a257..a85c053 100644
--- a/levels/Start.tscn
+++ b/levels/Start.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=3 format=3 uid="uid://c8hhhk21dtpe0"]
+[gd_scene load_steps=3 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_qw36g"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_qw36g"]
[ext_resource type="Script" path="res://levels/Start.gd" id="2_dhcq0"]
[node name="Start" instance=ExtResource("1_qw36g")]
diff --git a/levels/level_icon.svg b/levels/level_icon.svg
new file mode 100644
index 0000000..1adeb4a
--- /dev/null
+++ b/levels/level_icon.svg
@@ -0,0 +1,3 @@
+<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg" source="https://github.com/godotengine/godot/blob/dce1602edacd8ad96a70f29e4f524d7b7c231e3f/editor/icons/AtlasTexture.svg">
+ <path d="M6 1 1 3v12l5-2 4 2 5-2V1l-5 2zm0 2 4 2v8l-4-2z" fill="#e0e0e0"/>
+</svg>
diff --git a/levels/level_icon.svg.import b/levels/level_icon.svg.import
new file mode 100644
index 0000000..39bb20d
--- /dev/null
+++ b/levels/level_icon.svg.import
@@ -0,0 +1,37 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://qe2hj21r7fs5"
+path="res://.godot/imported/level_icon.svg-fdf28b9d131e093e07b143d6eebcf8c9.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://levels/level_icon.svg"
+dest_files=["res://.godot/imported/level_icon.svg-fdf28b9d131e093e07b143d6eebcf8c9.ctex"]
+
+[params]
+
+compress/mode=0
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/bptc_ldr=0
+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
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/levels/rand/01.tscn b/levels/rand/01.tscn
index 1aa70e2..9231178 100644
--- a/levels/rand/01.tscn
+++ b/levels/rand/01.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://txq8h42d4oqi"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_gxkva"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_gxkva"]
[node name="01" instance=ExtResource("1_gxkva")]
layer_0/tile_data = PackedInt32Array(131072, 0, 1, 196608, 0, 1, 262144, 262144, 1, 327680, 196608, 1, 393216, 196608, 2, 589824, 196608, 0, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 0, 983042, 65536, 3, 3, 65536, 0, 983043, 65536, 3, 4, 327680, 0, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 131072, 3, 983046, 131072, 3, 9, 0, 3, 983049, 0, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 393216, 0, 983052, 65536, 3, 13, 65536, 0, 983053, 65536, 3, 14, 65536, 0, 983054, 65536, 3, 15, 131072, 0, 65551, 131072, 1, 131087, 131072, 1, 196623, 131072, 1, 262159, 458752, 1, 327695, 196608, 1, 393231, 196608, 2, 589839, 196608, 0, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 0, 1, 0, 0, 0, 1, 65536, 0, 65537, 65536, 1, 131073, 65536, 1, 196609, 65536, 1, 262145, 65536, 2, 262146, 131072, 2, 196610, 131072, 1, 131074, 327680, 1, 65538, 65536, 1, 65539, 65536, 1, 131075, 65536, 2, 65540, 131072, 1, 131076, 458752, 1, 196612, 196608, 2, 65548, 0, 1, 131084, 0, 1, 196620, 262144, 1, 262156, 196608, 2, 131085, 65536, 1, 65549, 65536, 1, 65550, 65536, 1, 196621, 65536, 2, 196622, 393216, 1, 131086, 65536, 1, 262158, 0, 2, 524294, 65536, 1, 524295, 65536, 1, 524296, 65536, 1, 458760, 65536, 1, 458761, 65536, 1, 458762, 327680, 2, 458763, 131072, 0, 524298, 327680, 1, 589834, 131072, 2, 524297, 65536, 1, 458759, 65536, 1, 458758, 65536, 1, 589831, 65536, 2, 393223, 65536, 0, 393222, 65536, 0, 393221, 0, 0, 458757, 393216, 2, 524293, 393216, 1, 524292, 0, 2, 458756, 0, 0, 393226, 131072, 0, 393225, 65536, 0, 393224, 65536, 0, 589829, 0, 2, 589830, 65536, 2, 589832, 65536, 2, 589833, 65536, 2, 524299, 131072, 2, 917518, 327681, 0, 393220, 1, 0, 917516, 196609, 0, 917517, 262145, 0, 851982, 196609, 0)
diff --git a/levels/rand/02.tscn b/levels/rand/02.tscn
index f60876b..ab81e0d 100644
--- a/levels/rand/02.tscn
+++ b/levels/rand/02.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://gev80rx2b8vn"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_br7j7"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_br7j7"]
[node name="02" instance=ExtResource("1_br7j7")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 2, 589824, 196608, 0, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 131072, 3, 393222, 65536, 1, 524294, 65536, 1, 589830, 65536, 1, 983046, 131072, 3, 524295, 65536, 1, 589831, 65536, 1, 393224, 65536, 1, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 1, 9, 0, 3, 393225, 65536, 1, 458761, 65536, 1, 524297, 65536, 1, 589833, 65536, 1, 983049, 0, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 65536, 3, 983052, 65536, 3, 13, 65536, 3, 983053, 65536, 3, 14, 65536, 3, 983054, 65536, 3, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 2, 589839, 196608, 0, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 65536, 1, 393223, 65536, 1, 458759, 65536, 1, 786444, 131072, 2, 720908, 131072, 1, 655372, 131072, 1, 589836, 131072, 1, 524300, 131072, 1, 458764, 131072, 1, 393228, 131072, 1, 327692, 131072, 1, 262156, 131072, 1, 786443, 65536, 2, 720907, 65536, 1, 655371, 65536, 1, 589835, 65536, 1, 524299, 65536, 1, 458763, 65536, 1, 393227, 65536, 1, 327691, 65536, 1, 262155, 65536, 1, 786442, 65536, 2, 720906, 65536, 1, 655370, 65536, 1, 589834, 65536, 1, 524298, 65536, 1, 458762, 65536, 1, 393226, 65536, 1, 327690, 65536, 1, 262154, 65536, 1, 786441, 65536, 2, 720905, 65536, 1, 655369, 65536, 1, 327689, 65536, 1, 262153, 65536, 1, 786440, 65536, 2, 720904, 65536, 1, 655368, 65536, 1, 327688, 65536, 1, 262152, 65536, 1, 786439, 65536, 2, 720903, 65536, 1, 655367, 65536, 1, 327687, 65536, 1, 262151, 65536, 1, 786438, 65536, 2, 720902, 65536, 1, 655366, 65536, 1, 327686, 65536, 1, 262150, 65536, 1, 786437, 65536, 2, 720901, 65536, 1, 655365, 65536, 1, 589829, 65536, 1, 524293, 65536, 1, 458757, 65536, 1, 393221, 65536, 1, 327685, 65536, 1, 262149, 65536, 1, 786436, 65536, 2, 720900, 65536, 1, 655364, 65536, 1, 589828, 65536, 1, 524292, 65536, 1, 458756, 65536, 1, 393220, 65536, 1, 327684, 65536, 1, 262148, 65536, 1, 196620, 131072, 0, 196619, 65536, 0, 196618, 65536, 0, 196617, 65536, 0, 196616, 65536, 0, 196615, 65536, 0, 196614, 65536, 0, 196613, 65536, 0, 196612, 65536, 0, 786435, 0, 2, 720899, 0, 1, 655363, 0, 1, 589827, 0, 1, 524291, 0, 1, 458755, 0, 1, 393219, 0, 1, 327683, 0, 1, 262147, 0, 1, 196611, 0, 0)
diff --git a/levels/rand/03.tscn b/levels/rand/03.tscn
index e18805b..703e0cb 100644
--- a/levels/rand/03.tscn
+++ b/levels/rand/03.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://esupr5vkktt"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_tj6sj"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_tj6sj"]
[node name="03" instance=ExtResource("1_tj6sj")]
layer_0/tile_data = PackedInt32Array(131072, 0, 1, 196608, 0, 1, 262144, 0, 1, 327680, 262144, 1, 393216, 196608, 2, 589824, 196608, 0, 655360, 262144, 2, 720896, 0, 1, 786432, 0, 1, 851968, 0, 1, 917504, 0, 1, 983040, 0, 2, 983041, 65536, 2, 2, 65536, 0, 983042, 65536, 2, 3, 65536, 0, 983043, 65536, 2, 4, 65536, 0, 983044, 65536, 2, 5, 327680, 0, 983045, 65536, 2, 6, 131072, 3, 983046, 131072, 2, 9, 0, 0, 983049, 0, 2, 10, 65536, 0, 983050, 65536, 2, 11, 65536, 0, 983051, 65536, 2, 12, 65536, 0, 983052, 65536, 2, 13, 65536, 0, 983053, 65536, 2, 14, 65536, 0, 983054, 65536, 2, 15, 131072, 0, 65551, 131072, 1, 131087, 131072, 1, 196623, 131072, 1, 262159, 131072, 1, 327695, 458752, 1, 393231, 196608, 2, 589839, 131072, 0, 655375, 131072, 1, 720911, 131072, 1, 786447, 131072, 1, 851983, 131072, 1, 917519, 131072, 1, 983055, 131072, 2, 65536, 0, 1, 0, 0, 0, 1, 65536, 0, 917505, 65536, 1, 917506, 65536, 1, 917507, 65536, 1, 917508, 65536, 1, 917509, 65536, 1, 917510, 131072, 1, 851974, 131072, 0, 851973, 327680, 2, 851972, 65536, 1, 851971, 65536, 1, 851970, 65536, 1, 851969, 65536, 1, 786433, 65536, 1, 720897, 65536, 1, 655361, 65536, 0, 786434, 65536, 1, 720898, 65536, 1, 655362, 65536, 0, 786435, 65536, 1, 720899, 65536, 1, 655363, 65536, 0, 655364, 65536, 0, 655365, 131072, 0, 720901, 131072, 1, 720900, 65536, 1, 786436, 65536, 1, 786437, 131072, 1, 917513, 0, 0, 917514, 65536, 0, 917515, 65536, 0, 917516, 393216, 2, 851980, 0, 0, 917517, 65536, 1, 851981, 393216, 2, 851982, 65536, 1, 917518, 65536, 1, 786445, 0, 0, 786446, 393216, 2, 720910, 0, 1, 655374, 0, 1, 589838, 0, 0, 65546, 393216, 1, 131082, 0, 1, 131083, 65536, 1, 196619, 393216, 1, 196620, 65536, 1, 262156, 65536, 1, 327692, 393216, 1, 327693, 327680, 1, 327694, 65536, 2, 262158, 65536, 1, 196622, 65536, 1, 131086, 65536, 1, 65549, 65536, 1, 131085, 65536, 1, 131084, 65536, 1, 65548, 65536, 1, 196621, 65536, 1, 65547, 65536, 1, 262157, 65536, 1, 65550, 65536, 1, 393229, 131072, 2, 393228, 0, 2, 327691, 0, 2, 262155, 0, 1, 196618, 0, 2, 65545, 0, 2, 65538, 65536, 1, 131075, 65536, 1, 196611, 327680, 1, 196612, 131072, 2, 131076, 327680, 1, 65541, 131072, 1, 131077, 131072, 2, 196610, 65536, 1, 65537, 65536, 1, 131074, 65536, 1, 131073, 65536, 1, 196609, 65536, 1, 262145, 65536, 1, 65539, 65536, 1, 65540, 65536, 1, 262147, 131072, 2, 262146, 327680, 1, 327682, 131072, 2, 327681, 65536, 2, 393222, 393216, 4, 458758, 0, 2, 458759, 65536, 2, 458760, 458752, 1, 524296, 196608, 2, 393224, 131072, 0, 393223, 327680, 2, 393221, 0, 3, 327686, 0, 0, 327687, 131072, 0, 655370, 131072, 0, 720906, 131072, 2, 720905, 0, 2, 655369, 0, 0, 524299, 131072, 3, 524298, 0, 3, 196616, 131072, 3, 196615, 0, 3)
diff --git a/levels/rand/04.tscn b/levels/rand/04.tscn
index 6749d8c..c56032e 100644
--- a/levels/rand/04.tscn
+++ b/levels/rand/04.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://wgp3b5vk3qbs"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_twiom"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_twiom"]
[node name="04" instance=ExtResource("1_twiom")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 2, 589824, 196608, 0, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 262144, 2, 917504, 0, 1, 983040, 0, 2, 983041, 65536, 2, 2, 65536, 3, 983042, 65536, 2, 3, 393216, 0, 983043, 65536, 2, 4, 65536, 0, 983044, 327680, 3, 5, 65536, 0, 983045, 65536, 3, 6, 65536, 0, 393222, 0, 1, 524294, 393216, 1, 589830, 0, 2, 983046, 131072, 3, 524295, 65536, 1, 589831, 393216, 1, 393224, 65536, 1, 458760, 65536, 1, 524296, 65536, 1, 589832, 327680, 1, 9, 327680, 0, 393225, 65536, 1, 458761, 65536, 1, 524297, 65536, 1, 589833, 65536, 2, 983049, 0, 3, 10, 65536, 3, 983050, 65536, 3, 11, 393216, 0, 983051, 65536, 3, 12, 65536, 0, 983052, 65536, 3, 13, 65536, 0, 983053, 65536, 3, 14, 65536, 0, 983054, 65536, 3, 15, 131072, 0, 65551, 131072, 1, 131087, 131072, 1, 196623, 131072, 1, 262159, 458752, 1, 327695, 196608, 1, 393231, 196608, 2, 589839, 196608, 0, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 393216, 2, 393223, 65536, 1, 458759, 65536, 1, 8, 65536, 0, 7, 65536, 0, 65542, 65536, 1, 131078, 65536, 1, 196614, 393216, 1, 262150, 0, 1, 327686, 0, 1, 327687, 65536, 1, 327688, 65536, 1, 327689, 65536, 1, 262153, 327680, 2, 196617, 131072, 1, 131081, 131072, 1, 65545, 131072, 1, 65544, 65536, 1, 65543, 65536, 1, 131079, 65536, 1, 196615, 65536, 1, 262151, 65536, 1, 196616, 65536, 1, 131080, 65536, 1, 262152, 65536, 1, 65539, 0, 2, 65540, 393216, 1, 131076, 0, 2, 131077, 393216, 1, 196613, 0, 2, 65541, 65536, 1, 262158, 0, 2, 196622, 393216, 1, 196621, 0, 2, 131085, 393216, 1, 131084, 0, 2, 65548, 393216, 1, 65547, 0, 2, 65549, 65536, 1, 65550, 65536, 1, 131086, 65536, 1, 327690, 327680, 2, 327691, 131072, 0, 393227, 327680, 2, 458763, 65536, 1, 458764, 327680, 4, 393228, 131072, 0, 524300, 131072, 2, 524299, 327680, 1, 524298, 65536, 1, 589834, 65536, 2, 589835, 131072, 2, 458762, 65536, 1, 393226, 65536, 1, 458765, 131072, 3, 262154, 131072, 0, 458757, 0, 0, 524293, 0, 2, 655367, 0, 2, 655368, 131072, 2, 917516, 196609, 0, 917517, 262145, 0, 851982, 196609, 0, 917518, 327681, 0, 917505, 65536, 1, 917506, 327680, 2, 851969, 65536, 0, 851970, 131072, 0, 917507, 65536, 0, 917508, 131072, 0)
diff --git a/levels/rand/05.tscn b/levels/rand/05.tscn
index cd2c676..0f37385 100644
--- a/levels/rand/05.tscn
+++ b/levels/rand/05.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://lb0i4wxlcdo3"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_6wqlc"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_6wqlc"]
[node name="05" instance=ExtResource("1_6wqlc")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 2, 589824, 196608, 0, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 131072, 3, 393222, 589824, 0, 524294, 0, 1, 589830, 0, 2, 983046, 131072, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 0, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 327680, 2, 589833, 393216, 1, 983049, 0, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 393216, 3, 12, 65536, 3, 983052, 65536, 2, 13, 65536, 3, 983053, 65536, 2, 14, 65536, 3, 983054, 65536, 2, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 1, 589839, 196608, 1, 655375, 196608, 1, 720911, 196608, 1, 786447, 458752, 2, 851983, 131072, 1, 917519, 131072, 1, 983055, 131072, 2, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 458767, 196608, 1, 524303, 196608, 1, 917518, 65536, 1, 917517, 65536, 1, 851981, 393216, 2, 851982, 65536, 1, 786446, 65536, 0, 786445, 0, 0, 851980, 0, 0, 917516, 393216, 2, 917515, 0, 0, 131074, 0, 0, 196610, 0, 1, 262146, 0, 2, 262147, 393216, 1, 262148, 327680, 2, 196612, 131072, 1, 196611, 65536, 1, 131075, 65536, 0, 131076, 131072, 0, 262149, 65536, 0, 327685, 393216, 1, 327686, 131072, 1, 262150, 131072, 0, 393221, 0, 2, 327684, 65536, 2, 327683, 0, 2, 655369, 0, 1, 720905, 0, 2, 720906, 131072, 2, 655370, 131072, 1, 589834, 131072, 1, 524298, 131072, 0, 720900, 131072, 0, 720899, 0, 0, 786435, 0, 2, 786436, 131072, 2)
diff --git a/levels/rand/06.tscn b/levels/rand/06.tscn
index a1efe51..af989a6 100644
--- a/levels/rand/06.tscn
+++ b/levels/rand/06.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://cmex8m63vfpoj"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_m26rk"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_m26rk"]
[node name="06" instance=ExtResource("1_m26rk")]
layer_0/tile_data = PackedInt32Array(131072, 262144, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 2, 589824, 196608, 0, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 0, 983042, 65536, 3, 3, 65536, 0, 983043, 65536, 3, 4, 65536, 0, 983044, 65536, 3, 5, 65536, 0, 983045, 65536, 3, 6, 65536, 0, 393222, 393216, 1, 524294, 0, 1, 589830, 0, 2, 983046, 131072, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 1, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 65536, 0, 393225, 65536, 1, 458761, 65536, 1, 524297, 65536, 1, 589833, 65536, 2, 983049, 0, 3, 10, 65536, 0, 983050, 65536, 3, 11, 65536, 0, 983051, 65536, 3, 12, 65536, 0, 983052, 65536, 3, 13, 65536, 0, 983053, 65536, 3, 14, 65536, 0, 983054, 393216, 3, 15, 131072, 0, 65551, 131072, 1, 131087, 131072, 1, 196623, 131072, 1, 262159, 131072, 1, 327695, 131072, 1, 393231, 131072, 1, 589839, 131072, 1, 655375, 131072, 1, 720911, 131072, 1, 786447, 131072, 1, 851983, 131072, 1, 917519, 131072, 1, 983055, 131072, 2, 65536, 0, 1, 0, 0, 0, 1, 65536, 0, 458758, 0, 1, 393223, 65536, 1, 458759, 65536, 1, 327686, 65536, 1, 262149, 65536, 1, 196612, 65536, 1, 131075, 65536, 1, 65538, 65536, 1, 786446, 65536, 1, 720909, 65536, 1, 655372, 65536, 1, 589835, 65536, 1, 524298, 65536, 1, 196611, 393216, 1, 262148, 393216, 1, 327685, 393216, 1, 589834, 393216, 1, 655371, 393216, 1, 720908, 393216, 1, 786445, 393216, 1, 851982, 393216, 1, 131074, 393216, 1, 65537, 65536, 1, 196610, 0, 2, 262147, 0, 2, 327684, 0, 2, 393221, 0, 2, 655370, 0, 2, 720907, 0, 2, 786444, 0, 2, 851981, 0, 2, 917518, 0, 1, 131073, 65536, 2, 7, 65536, 0, 8, 65536, 0, 458767, 131072, 1, 524303, 131072, 1, 720910, 65536, 1, 655374, 65536, 1, 589838, 65536, 1, 524302, 65536, 1, 458766, 65536, 1, 393230, 65536, 1, 327694, 65536, 1, 262158, 65536, 1, 196622, 65536, 1, 131086, 65536, 1, 65550, 65536, 1, 655373, 65536, 1, 589837, 65536, 1, 524301, 65536, 1, 458765, 65536, 1, 393229, 65536, 1, 327693, 65536, 1, 262157, 65536, 1, 196621, 65536, 1, 131085, 65536, 1, 65549, 65536, 1, 589836, 65536, 1, 524300, 65536, 1, 458764, 65536, 1, 393228, 65536, 1, 327692, 65536, 1, 262156, 65536, 1, 196620, 65536, 1, 131084, 65536, 1, 65548, 65536, 1, 524299, 65536, 1, 458763, 65536, 1, 393227, 65536, 1, 327691, 65536, 1, 262155, 65536, 1, 196619, 65536, 1, 131083, 65536, 1, 65547, 65536, 1, 458762, 65536, 1, 393226, 65536, 1, 327690, 65536, 1, 262154, 65536, 1, 196618, 65536, 1, 131082, 65536, 1, 65546, 65536, 1, 327689, 65536, 1, 262153, 65536, 1, 196617, 65536, 1, 131081, 65536, 1, 65545, 65536, 1, 327688, 65536, 1, 262152, 65536, 1, 196616, 65536, 1, 131080, 65536, 1, 65544, 65536, 1, 327687, 65536, 1, 262151, 65536, 1, 196615, 65536, 1, 131079, 65536, 1, 65543, 65536, 1, 262150, 65536, 1, 196614, 65536, 1, 131078, 65536, 1, 65542, 65536, 1, 196613, 65536, 1, 131077, 65536, 1, 65541, 65536, 1, 131076, 65536, 1, 65540, 65536, 1, 65539, 65536, 1)
diff --git a/levels/rand/07.tscn b/levels/rand/07.tscn
index e4e6ba9..a6fc775 100644
--- a/levels/rand/07.tscn
+++ b/levels/rand/07.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://bh0o48w2ir4l2"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_3bnrf"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_3bnrf"]
[node name="07" instance=ExtResource("1_3bnrf")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 2, 589824, 196608, 0, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 131072, 3, 393222, 0, 0, 524294, 0, 1, 589830, 0, 2, 983046, 65536, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 0, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 131072, 1, 589833, 131072, 2, 983049, 65536, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 65536, 3, 983052, 65536, 3, 13, 65536, 3, 983053, 65536, 3, 14, 65536, 3, 983054, 65536, 3, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 2, 589839, 196608, 0, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 983047, 65536, 3, 983048, 65536, 3)
diff --git a/levels/rand/08.tscn b/levels/rand/08.tscn
index 9a85d13..4950d60 100644
--- a/levels/rand/08.tscn
+++ b/levels/rand/08.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://x3fddi5udbur"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_4ldoi"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_4ldoi"]
[node name="08" instance=ExtResource("1_4ldoi")]
layer_0/tile_data = PackedInt32Array(131072, 0, 1, 196608, 0, 1, 262144, 0, 1, 327680, 0, 1, 393216, 0, 2, 589824, 0, 0, 655360, 0, 1, 720896, 0, 1, 786432, 0, 1, 851968, 0, 1, 917504, 0, 1, 983040, 0, 2, 983041, 65536, 2, 2, 65536, 0, 983042, 65536, 2, 3, 65536, 0, 983043, 65536, 2, 4, 65536, 0, 983044, 65536, 2, 5, 65536, 0, 983045, 65536, 2, 6, 65536, 0, 524294, 0, 2, 983046, 65536, 2, 524295, 65536, 2, 458760, 65536, 0, 524296, 65536, 2, 9, 65536, 0, 458761, 131072, 0, 524297, 131072, 2, 983049, 65536, 2, 10, 65536, 0, 983050, 65536, 2, 11, 65536, 0, 983051, 65536, 2, 12, 65536, 0, 983052, 65536, 2, 13, 65536, 0, 983053, 65536, 2, 14, 65536, 0, 983054, 65536, 2, 15, 131072, 0, 65551, 131072, 1, 131087, 131072, 1, 196623, 131072, 1, 262159, 131072, 1, 327695, 131072, 1, 393231, 131072, 2, 589839, 131072, 0, 655375, 131072, 1, 720911, 131072, 1, 786447, 131072, 1, 851983, 131072, 1, 917519, 131072, 1, 983055, 131072, 2, 65536, 0, 1, 0, 0, 0, 1, 65536, 0, 458758, 0, 0, 458759, 65536, 0, 7, 65536, 0, 8, 65536, 0, 983047, 65536, 2, 983048, 65536, 2, 917518, 65536, 1, 851982, 65536, 1, 786446, 65536, 1, 720910, 65536, 1, 655374, 65536, 1, 589838, 65536, 0, 917517, 65536, 1, 851981, 65536, 1, 786445, 65536, 1, 720909, 65536, 1, 655373, 65536, 1, 589837, 65536, 0, 917516, 65536, 1, 851980, 65536, 1, 786444, 65536, 1, 720908, 65536, 1, 655372, 65536, 1, 589836, 65536, 0, 917515, 65536, 1, 851979, 65536, 1, 786443, 65536, 1, 720907, 393216, 2, 655371, 0, 1, 589835, 0, 0, 917514, 65536, 1, 851978, 65536, 1, 786442, 65536, 1, 720906, 65536, 0, 917513, 65536, 1, 851977, 65536, 1, 786441, 65536, 1, 720905, 65536, 0, 917512, 65536, 1, 851976, 65536, 1, 786440, 65536, 1, 720904, 65536, 0, 917511, 65536, 1, 851975, 65536, 1, 786439, 65536, 1, 720903, 65536, 0, 917510, 65536, 1, 851974, 65536, 1, 786438, 65536, 1, 720902, 65536, 0, 917509, 65536, 1, 851973, 65536, 1, 786437, 65536, 1, 720901, 65536, 0, 917508, 65536, 1, 851972, 65536, 1, 786436, 65536, 1, 720900, 327680, 2, 655364, 131072, 1, 589828, 131072, 0, 917507, 65536, 1, 851971, 65536, 1, 786435, 65536, 1, 720899, 65536, 1, 655363, 65536, 1, 589827, 65536, 0, 917506, 65536, 1, 851970, 65536, 1, 786434, 65536, 1, 720898, 65536, 1, 655362, 65536, 1, 589826, 65536, 0, 917505, 65536, 1, 851969, 65536, 1, 786433, 65536, 1, 720897, 65536, 1, 655361, 65536, 1, 589825, 65536, 0, 393230, 65536, 2, 327694, 65536, 1, 262158, 65536, 1, 196622, 65536, 1, 131086, 65536, 1, 65550, 65536, 1, 393229, 65536, 2, 327693, 65536, 1, 262157, 65536, 1, 196621, 65536, 1, 131085, 65536, 1, 65549, 65536, 1, 393228, 65536, 2, 327692, 65536, 1, 262156, 65536, 1, 196620, 65536, 1, 131084, 65536, 1, 65548, 65536, 1, 393227, 0, 2, 327691, 393216, 1, 262155, 65536, 1, 196619, 65536, 1, 131083, 65536, 1, 65547, 65536, 1, 327690, 65536, 2, 262154, 65536, 1, 196618, 65536, 1, 131082, 65536, 1, 65546, 65536, 1, 327689, 65536, 2, 262153, 65536, 1, 196617, 65536, 1, 131081, 65536, 1, 65545, 65536, 1, 327688, 65536, 2, 262152, 65536, 1, 196616, 65536, 1, 131080, 65536, 1, 65544, 65536, 1, 327687, 65536, 2, 262151, 65536, 1, 196615, 65536, 1, 131079, 65536, 1, 65543, 65536, 1, 327686, 65536, 2, 262150, 65536, 1, 196614, 65536, 1, 131078, 65536, 1, 65542, 65536, 1, 262149, 65536, 1, 196613, 65536, 1, 131077, 65536, 1, 65541, 65536, 1, 393220, 131072, 2, 327684, 327680, 1, 262148, 65536, 1, 196612, 65536, 1, 131076, 65536, 1, 65540, 65536, 1, 393219, 65536, 2, 327683, 65536, 1, 262147, 65536, 1, 196611, 65536, 1, 131075, 65536, 1, 65539, 65536, 1, 393218, 65536, 2, 327682, 65536, 1, 262146, 65536, 1, 196610, 65536, 1, 131074, 65536, 1, 65538, 65536, 1, 393217, 65536, 2, 327681, 65536, 1, 262145, 65536, 1, 196609, 65536, 1, 131073, 65536, 1, 65537, 65536, 1, 327685, 65536, 2)
diff --git a/levels/rand/09.tscn b/levels/rand/09.tscn
index c5d9f87..5f25fdc 100644
--- a/levels/rand/09.tscn
+++ b/levels/rand/09.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://b7w7ns27n53rh"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_ix63m"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_ix63m"]
[node name="09" instance=ExtResource("1_ix63m")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 2, 589824, 196608, 0, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 131072, 3, 393222, 0, 0, 524294, 0, 1, 589830, 0, 2, 983046, 65536, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 0, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 131072, 1, 589833, 131072, 2, 983049, 65536, 3, 10, 65536, 3, 983050, 393216, 3, 11, 65536, 3, 983051, 65536, 2, 12, 65536, 3, 983052, 65536, 2, 13, 65536, 3, 983053, 65536, 2, 14, 65536, 3, 983054, 65536, 2, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 1, 589839, 131072, 1, 655375, 131072, 1, 720911, 131072, 1, 786447, 131072, 1, 851983, 131072, 1, 917519, 131072, 1, 983055, 131072, 2, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 983047, 65536, 3, 983048, 65536, 3, 917514, 0, 0, 917515, 65536, 0, 917516, 393216, 2, 851981, 65536, 1, 851982, 65536, 1, 786446, 65536, 1, 720910, 393216, 2, 524303, 458752, 2, 458767, 196608, 1, 524302, 0, 0, 589838, 0, 1, 655374, 0, 1, 917517, 65536, 1, 917518, 65536, 1, 786445, 393216, 2, 720909, 0, 0, 786444, 0, 0, 851980, 0, 1)
diff --git a/levels/rand/10.tscn b/levels/rand/10.tscn
index 867f536..3d21abc 100644
--- a/levels/rand/10.tscn
+++ b/levels/rand/10.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://gyxkjwsih0s2"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_c2n3v"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_c2n3v"]
[node name="10" instance=ExtResource("1_c2n3v")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 2, 589824, 196608, 0, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 65536, 3, 393222, 0, 0, 524294, 0, 1, 589830, 0, 2, 983046, 65536, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 65536, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 131072, 1, 589833, 131072, 2, 983049, 65536, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 65536, 3, 983052, 65536, 3, 13, 65536, 3, 983053, 65536, 3, 14, 65536, 3, 983054, 65536, 3, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 1, 589839, 196608, 1, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 983047, 65536, 3, 983048, 65536, 3, 524303, 196608, 1, 458767, 196608, 1, 8, 65536, 3, 7, 65536, 3)
diff --git a/levels/rand/11.tscn b/levels/rand/11.tscn
index 5a7156b..b6719ef 100644
--- a/levels/rand/11.tscn
+++ b/levels/rand/11.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://bkywu3kc1xfep"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_pa3ds"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_pa3ds"]
[node name="11" instance=ExtResource("1_pa3ds")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 1, 589824, 196608, 1, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 131072, 3, 393222, 0, 0, 524294, 0, 1, 589830, 0, 2, 983046, 131072, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 0, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 131072, 1, 589833, 131072, 2, 983049, 0, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 65536, 3, 983052, 65536, 3, 13, 65536, 3, 983053, 65536, 3, 14, 65536, 3, 983054, 65536, 3, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 2, 589839, 196608, 0, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 524288, 196608, 1, 458752, 196608, 1)
diff --git a/levels/rand/12.tscn b/levels/rand/12.tscn
index 7e3b2de..957bf93 100644
--- a/levels/rand/12.tscn
+++ b/levels/rand/12.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://dnn448k214c42"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_x55go"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_x55go"]
[node name="12" instance=ExtResource("1_x55go")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 1, 589824, 196608, 1, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 65536, 3, 393222, 0, 0, 524294, 0, 1, 589830, 0, 2, 983046, 131072, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 65536, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 131072, 1, 589833, 131072, 2, 983049, 0, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 65536, 3, 983052, 65536, 3, 13, 65536, 3, 983053, 65536, 3, 14, 65536, 3, 983054, 65536, 3, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 2, 589839, 196608, 0, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 7, 65536, 3, 8, 65536, 3, 458752, 196608, 1, 524288, 196608, 1)
diff --git a/levels/rand/13.tscn b/levels/rand/13.tscn
index 8012be2..437bfff 100644
--- a/levels/rand/13.tscn
+++ b/levels/rand/13.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://dkci2hmtjgrvj"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_13npg"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_13npg"]
[node name="13" instance=ExtResource("1_13npg")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 1, 589824, 196608, 1, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 131072, 3, 393222, 0, 0, 524294, 0, 1, 589830, 0, 2, 983046, 131072, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 0, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 131072, 1, 589833, 131072, 2, 983049, 0, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 65536, 3, 983052, 65536, 3, 13, 65536, 3, 983053, 65536, 3, 14, 65536, 3, 983054, 65536, 3, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 1, 589839, 196608, 1, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 458767, 196608, 1, 524303, 196608, 1, 458752, 196608, 1, 524288, 196608, 1)
diff --git a/levels/rand/14.tscn b/levels/rand/14.tscn
index 913caaf..9ac75c0 100644
--- a/levels/rand/14.tscn
+++ b/levels/rand/14.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://bxokgsjhvo0ad"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_d7058"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_d7058"]
[node name="14" instance=ExtResource("1_d7058")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 1, 589824, 196608, 1, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 65536, 3, 393222, 0, 0, 524294, 0, 1, 589830, 0, 2, 983046, 131072, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 65536, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 131072, 1, 589833, 131072, 2, 983049, 0, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 65536, 3, 983052, 65536, 3, 13, 65536, 3, 983053, 65536, 3, 14, 65536, 3, 983054, 65536, 3, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 1, 589839, 196608, 1, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 458752, 196608, 1, 524288, 196608, 1, 8, 65536, 3, 7, 65536, 3, 524303, 196608, 1, 458767, 196608, 1)
diff --git a/levels/rand/15.tscn b/levels/rand/15.tscn
index 22d87cd..cfd2837 100644
--- a/levels/rand/15.tscn
+++ b/levels/rand/15.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://cnwifdbe2eqv8"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_40br1"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_40br1"]
[node name="15" instance=ExtResource("1_40br1")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 1, 589824, 196608, 1, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 131072, 3, 393222, 0, 0, 524294, 0, 1, 589830, 0, 2, 983046, 65536, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 0, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 131072, 1, 589833, 131072, 2, 983049, 65536, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 65536, 3, 983052, 65536, 3, 13, 65536, 3, 983053, 65536, 3, 14, 65536, 3, 983054, 65536, 3, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 2, 589839, 196608, 0, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 458752, 196608, 1, 524288, 196608, 1, 983047, 65536, 3, 983048, 65536, 3)
diff --git a/levels/rand/16.tscn b/levels/rand/16.tscn
index e33cf47..af4ec04 100644
--- a/levels/rand/16.tscn
+++ b/levels/rand/16.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://d4dwvcp6764bx"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_yds8y"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_yds8y"]
[node name="16" instance=ExtResource("1_yds8y")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 1, 589824, 196608, 1, 655360, 196608, 1, 720896, 196608, 1, 786432, 196608, 1, 851968, 196608, 1, 917504, 196608, 1, 983040, 262144, 3, 983041, 65536, 3, 2, 65536, 3, 983042, 65536, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 65536, 3, 393222, 0, 0, 524294, 0, 1, 589830, 0, 2, 983046, 65536, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 65536, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 131072, 1, 589833, 131072, 2, 983049, 65536, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 65536, 3, 983052, 65536, 3, 13, 65536, 3, 983053, 65536, 3, 14, 65536, 3, 983054, 65536, 3, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 2, 589839, 196608, 0, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 983048, 65536, 3, 983047, 65536, 3, 524288, 196608, 1, 458752, 196608, 1, 7, 65536, 3, 8, 65536, 3)
diff --git a/levels/rand/17.tscn b/levels/rand/17.tscn
index ce200e3..66307d2 100644
--- a/levels/rand/17.tscn
+++ b/levels/rand/17.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://duo0cbnh5u3qt"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_otvl3"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_otvl3"]
[node name="17" instance=ExtResource("1_otvl3")]
layer_0/tile_data = PackedInt32Array(131072, 196608, 1, 196608, 196608, 1, 262144, 196608, 1, 327680, 196608, 1, 393216, 196608, 1, 589824, 196608, 1, 655360, 196608, 1, 720896, 196608, 1, 786432, 262144, 2, 851968, 0, 1, 917504, 0, 1, 983040, 0, 2, 983041, 65536, 2, 2, 65536, 3, 983042, 327680, 3, 3, 65536, 3, 983043, 65536, 3, 4, 65536, 3, 983044, 65536, 3, 5, 65536, 3, 983045, 65536, 3, 6, 131072, 3, 393222, 0, 0, 524294, 0, 1, 589830, 0, 2, 983046, 65536, 3, 524295, 65536, 1, 589831, 65536, 2, 393224, 65536, 0, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 2, 9, 0, 3, 393225, 131072, 0, 458761, 131072, 1, 524297, 131072, 1, 589833, 131072, 2, 983049, 65536, 3, 10, 65536, 3, 983050, 65536, 3, 11, 65536, 3, 983051, 65536, 3, 12, 65536, 3, 983052, 65536, 3, 13, 65536, 3, 983053, 65536, 3, 14, 65536, 3, 983054, 65536, 3, 15, 458752, 0, 65551, 196608, 1, 131087, 196608, 1, 196623, 196608, 1, 262159, 196608, 1, 327695, 196608, 1, 393231, 196608, 1, 589839, 196608, 1, 655375, 196608, 1, 720911, 196608, 1, 786447, 196608, 1, 851983, 196608, 1, 917519, 196608, 1, 983055, 458752, 3, 65536, 196608, 1, 0, 262144, 0, 1, 65536, 3, 458758, 0, 1, 393223, 65536, 0, 458759, 65536, 1, 458752, 196608, 1, 524288, 196608, 1, 786433, 131072, 0, 917505, 327680, 2, 851969, 131072, 1, 917506, 131072, 0, 983047, 65536, 3, 983048, 65536, 3, 524303, 196608, 1, 458767, 196608, 1)
diff --git a/levels/rand/18.tscn b/levels/rand/18.tscn
index 3f22f31..fcaa73a 100644
--- a/levels/rand/18.tscn
+++ b/levels/rand/18.tscn
@@ -1,6 +1,6 @@
-[gd_scene load_steps=2 format=3 uid="uid://cy3kc27btbipt"]
+[gd_scene load_steps=2 format=3]
-[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/BaseTemplate.tscn" id="1_ucpni"]
+[ext_resource type="PackedScene" uid="uid://h2yl2s2kudv8" path="res://levels/Level.tscn" id="1_ucpni"]
[node name="18" instance=ExtResource("1_ucpni")]
layer_0/tile_data = PackedInt32Array(131072, 0, 1, 196608, 0, 1, 262144, 0, 1, 327680, 0, 1, 393216, 0, 1, 589824, 0, 1, 655360, 0, 1, 720896, 0, 1, 786432, 0, 1, 851968, 0, 1, 917504, 0, 1, 983040, 0, 2, 983041, 65536, 2, 2, 65536, 0, 983042, 65536, 2, 3, 65536, 0, 983043, 65536, 2, 4, 65536, 0, 983044, 65536, 2, 5, 65536, 0, 983045, 65536, 2, 6, 65536, 0, 393222, 65536, 1, 524294, 65536, 1, 589830, 65536, 1, 983046, 65536, 2, 524295, 65536, 1, 589831, 65536, 1, 393224, 65536, 1, 458760, 65536, 1, 524296, 65536, 1, 589832, 65536, 1, 9, 65536, 0, 393225, 65536, 1, 458761, 65536, 1, 524297, 65536, 1, 589833, 65536, 1, 983049, 65536, 2, 10, 65536, 0, 983050, 65536, 2, 11, 65536, 0, 983051, 65536, 2, 12, 65536, 0, 983052, 65536, 2, 13, 65536, 0, 983053, 65536, 2, 14, 65536, 0, 983054, 65536, 2, 15, 131072, 0, 65551, 131072, 1, 131087, 131072, 1, 196623, 131072, 1, 262159, 131072, 1, 327695, 131072, 1, 393231, 131072, 1, 589839, 131072, 1, 655375, 131072, 1, 720911, 131072, 1, 786447, 131072, 1, 851983, 131072, 1, 917519, 131072, 1, 983055, 131072, 2, 65536, 0, 1, 0, 0, 0, 1, 65536, 0, 458758, 65536, 1, 393223, 65536, 1, 458759, 65536, 1, 524303, 131072, 1, 458767, 131072, 1, 917518, 65536, 1, 851982, 65536, 1, 786446, 65536, 1, 720910, 65536, 1, 655374, 65536, 1, 589838, 65536, 1, 524302, 65536, 1, 458766, 65536, 1, 393230, 65536, 1, 327694, 65536, 1, 262158, 65536, 1, 196622, 65536, 1, 131086, 65536, 1, 65550, 65536, 1, 917517, 65536, 1, 851981, 65536, 1, 786445, 65536, 1, 720909, 65536, 1, 655373, 65536, 1, 589837, 65536, 1, 524301, 65536, 1, 458765, 65536, 1, 393229, 65536, 1, 327693, 65536, 1, 262157, 65536, 1, 196621, 65536, 1, 131085, 65536, 1, 65549, 65536, 1, 917516, 65536, 1, 851980, 65536, 1, 786444, 65536, 1, 720908, 65536, 1, 655372, 65536, 1, 589836, 65536, 1, 524300, 65536, 1, 458764, 65536, 1, 393228, 65536, 1, 327692, 65536, 1, 262156, 65536, 1, 196620, 65536, 1, 131084, 65536, 1, 65548, 65536, 1, 917515, 65536, 1, 851979, 65536, 1, 786443, 65536, 1, 720907, 65536, 1, 655371, 65536, 1, 589835, 65536, 1, 524299, 65536, 1, 458763, 65536, 1, 393227, 65536, 1, 327691, 65536, 1, 262155, 65536, 1, 196619, 65536, 1, 131083, 65536, 1, 65547, 65536, 1, 917514, 65536, 1, 851978, 65536, 1, 786442, 65536, 1, 720906, 65536, 1, 655370, 65536, 1, 589834, 65536, 1, 524298, 65536, 1, 458762, 65536, 1, 393226, 65536, 1, 327690, 65536, 1, 262154, 65536, 1, 196618, 65536, 1, 131082, 65536, 1, 65546, 65536, 1, 917513, 65536, 1, 851977, 65536, 1, 786441, 65536, 1, 720905, 65536, 1, 655369, 65536, 1, 327689, 65536, 1, 262153, 65536, 1, 196617, 65536, 1, 131081, 65536, 1, 65545, 65536, 1, 983048, 65536, 2, 917512, 65536, 1, 851976, 65536, 1, 786440, 65536, 1, 720904, 65536, 1, 655368, 65536, 1, 327688, 65536, 1, 262152, 65536, 1, 196616, 65536, 1, 131080, 65536, 1, 65544, 65536, 1, 8, 65536, 0, 983047, 65536, 2, 917511, 65536, 1, 851975, 65536, 1, 786439, 65536, 1, 720903, 65536, 1, 655367, 65536, 1, 327687, 65536, 1, 262151, 65536, 1, 196615, 65536, 1, 131079, 65536, 1, 65543, 65536, 1, 7, 65536, 0, 917510, 65536, 1, 851974, 65536, 1, 786438, 65536, 1, 720902, 65536, 1, 655366, 65536, 1, 327686, 65536, 1, 262150, 65536, 1, 196614, 65536, 1, 131078, 65536, 1, 65542, 65536, 1, 917509, 65536, 1, 851973, 65536, 1, 786437, 65536, 1, 720901, 65536, 1, 655365, 65536, 1, 589829, 65536, 1, 524293, 65536, 1, 458757, 65536, 1, 393221, 65536, 1, 327685, 65536, 1, 262149, 65536, 1, 196613, 65536, 1, 131077, 65536, 1, 65541, 65536, 1, 917508, 65536, 1, 851972, 65536, 1, 786436, 65536, 1, 720900, 65536, 1, 655364, 65536, 1, 589828, 65536, 1, 524292, 65536, 1, 458756, 65536, 1, 393220, 65536, 1, 327684, 65536, 1, 262148, 65536, 1, 196612, 65536, 1, 131076, 65536, 1, 65540, 65536, 1, 917507, 65536, 1, 851971, 65536, 1, 786435, 65536, 1, 720899, 65536, 1, 655363, 65536, 1, 589827, 65536, 1, 524291, 65536, 1, 458755, 65536, 1, 393219, 65536, 1, 327683, 65536, 1, 262147, 65536, 1, 196611, 65536, 1, 131075, 65536, 1, 65539, 65536, 1, 917506, 65536, 1, 851970, 65536, 1, 786434, 65536, 1, 720898, 65536, 1, 655362, 65536, 1, 589826, 65536, 1, 524290, 65536, 1, 458754, 65536, 1, 393218, 65536, 1, 327682, 65536, 1, 262146, 65536, 1, 196610, 65536, 1, 131074, 65536, 1, 65538, 65536, 1, 917505, 65536, 1, 851969, 65536, 1, 786433, 65536, 1, 720897, 65536, 1, 655361, 65536, 1, 589825, 65536, 1, 524289, 65536, 1, 458753, 65536, 1, 393217, 65536, 1, 327681, 65536, 1, 262145, 65536, 1, 196609, 65536, 1, 131073, 65536, 1, 65537, 65536, 1, 524288, 0, 1, 458752, 0, 1)
diff --git a/player/player.gd b/player/player.gd
index 9da6719..8034e2c 100644
--- a/player/player.gd
+++ b/player/player.gd
@@ -1,4 +1,4 @@
-extends CharacterBody2D
+extends Hittable
class_name Player
const DustEffect := preload("res://fx/dust.tscn")
@@ -21,12 +21,11 @@ const WallJumpEffect := preload("res://fx/wall_dust.tscn")
@onready var GRAVITY: float = ProjectSettings.get_setting(&"physics/2d/default_gravity")
-const FLOOR_MAX_ANGLE := deg_to_rad(46)
-
-
func _init() -> void:
- floor_max_angle = FLOOR_MAX_ANGLE
+ Globals.player = self
+func _exit_tree() -> void:
+ Globals.player = null
enum State { MOVE, WALL_SLIDE, STOP }
diff --git a/player/player.tscn b/player/player.tscn
index b5e9665..3c22ede 100644
--- a/player/player.tscn
+++ b/player/player.tscn
@@ -1,11 +1,10 @@
-[gd_scene load_steps=9 format=3 uid="uid://c1fgxkkh72npw"]
+[gd_scene load_steps=11 format=3 uid="uid://c1fgxkkh72npw"]
[ext_resource type="Script" path="res://player/player.gd" id="1_lnsyt"]
[ext_resource type="Texture2D" uid="uid://b36hv0jwfmb1u" path="res://assets/player/animations.png" id="2_dgplu"]
-
-[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_bxmud"]
-radius = 3.0
-height = 12.0
+[ext_resource type="Shape2D" uid="uid://f1oxba248m0l" path="res://player/player_collision.tres" id="3_uoann"]
+[ext_resource type="PackedScene" uid="uid://qliv2erkwokh" path="res://colliders/hurtbox.tscn" id="4_yd6uo"]
+[ext_resource type="PackedScene" uid="uid://cdpkxaateaqdf" path="res://colliders/hitbox.tscn" id="5_wpn72"]
[sub_resource type="Animation" id="Animation_sbyxw"]
resource_name = "idle"
@@ -102,6 +101,7 @@ _data = {
[node name="player" type="CharacterBody2D"]
collision_layer = 2
+floor_max_angle = 0.802851
script = ExtResource("1_lnsyt")
[node name="Sprite" type="Sprite2D" parent="."]
@@ -110,10 +110,9 @@ position = Vector2(0, -14)
texture = ExtResource("2_dgplu")
hframes = 30
-[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
-position = Vector2(0, -6)
-shape = SubResource("CapsuleShape2D_bxmud")
-debug_color = Color(0.811765, 0.360784, 0.529412, 0.419608)
+[node name="Collision" type="CollisionShape2D" parent="."]
+position = Vector2(0, -7)
+shape = ExtResource("3_uoann")
[node name="Player" type="AnimationPlayer" parent="."]
libraries = {
@@ -123,3 +122,22 @@ libraries = {
[node name="CoyoteJump" type="Timer" parent="."]
wait_time = 0.2
one_shot = true
+
+[node name="Hurtbox" parent="." instance=ExtResource("4_yd6uo")]
+collision_layer = 4
+
+[node name="Collision" parent="Hurtbox" index="0"]
+visible = false
+position = Vector2(0, -7)
+shape = ExtResource("3_uoann")
+
+[node name="Hitbox" parent="." instance=ExtResource("5_wpn72")]
+collision_mask = 8
+
+[node name="Collision" parent="Hitbox" index="0"]
+visible = false
+position = Vector2(0, -7)
+shape = ExtResource("3_uoann")
+
+[editable path="Hurtbox"]
+[editable path="Hitbox"]
diff --git a/player/player_collision.tres b/player/player_collision.tres
new file mode 100644
index 0000000..39ec48b
--- /dev/null
+++ b/player/player_collision.tres
@@ -0,0 +1,5 @@
+[gd_resource type="CapsuleShape2D" format=3 uid="uid://f1oxba248m0l"]
+
+[resource]
+radius = 3.0
+height = 14.0
diff --git a/project.godot b/project.godot
index c415d4a..79f6209 100644
--- a/project.godot
+++ b/project.godot
@@ -19,10 +19,30 @@ _global_script_classes=[{
"language": &"GDScript",
"path": "res://world/door/door.gd"
}, {
+"base": "Hittable",
+"class": &"Enemy",
+"language": &"GDScript",
+"path": "res://enemys/Enemy.gd"
+}, {
+"base": "Area2D",
+"class": &"Hammer",
+"language": &"GDScript",
+"path": "res://hammers/hammer.gd"
+}, {
+"base": "CharacterBody2D",
+"class": &"Hittable",
+"language": &"GDScript",
+"path": "res://colliders/hittable.gd"
+}, {
+"base": "Area2D",
+"class": &"Hurtbox",
+"language": &"GDScript",
+"path": "res://colliders/hurtbox.gd"
+}, {
"base": "TileMap",
"class": &"Level",
"language": &"GDScript",
-"path": "res://levels/BaseTemplate.gd"
+"path": "res://levels/Level.gd"
}, {
"base": "Node",
"class": &"LevelManager",
@@ -39,11 +59,16 @@ _global_script_classes=[{
"language": &"GDScript",
"path": "res://world/one_way_platform.gd"
}, {
-"base": "CharacterBody2D",
+"base": "Hittable",
"class": &"Player",
"language": &"GDScript",
"path": "res://player/player.gd"
}, {
+"base": "Line2D",
+"class": &"Trail2D",
+"language": &"GDScript",
+"path": "res://fx/trail.gd"
+}, {
"base": "Node",
"class": &"Util",
"language": &"GDScript",
@@ -52,11 +77,16 @@ _global_script_classes=[{
_global_script_class_icons={
"BlockDoor": "",
"Door": "",
-"Level": "",
+"Enemy": "",
+"Hammer": "res://assets/hammers/hammer01.png",
+"Hittable": "",
+"Hurtbox": "",
+"Level": "res://levels/level_icon.svg",
"LevelManager": "",
"Maze": "",
"OneWayPlatform": "",
"Player": "",
+"Trail2D": "res://fx/trail2d_icon.svg",
"Util": ""
}
@@ -72,6 +102,7 @@ config/features=PackedStringArray("4.0")
Utils="*res://autoloads/Utils.gd"
Events="*res://autoloads/Events.gd"
+Globals="*res://autoloads/Globals.gd"
[debug]
@@ -131,7 +162,9 @@ down={
2d_physics/layer_1="world"
2d_physics/layer_2="player"
-2d_physics/layer_3="enemy"
+2d_physics/layer_3="player_hurt"
+2d_physics/layer_4="enemy_hurt"
+2d_physics/layer_5="enemy"
[logging]
diff --git a/world/door/block_door.gd b/world/door/block_door.gd
index 26427ef..8c5ee6c 100644
--- a/world/door/block_door.gd
+++ b/world/door/block_door.gd
@@ -5,18 +5,17 @@ const DustEffect := preload("res://fx/wall_dust.tscn")
@onready @export var path_follower: PathFollow2D
-
func dust(mod: int) -> void:
- var i: Node2D = (
- Utils . instance_scene_on_main(DustEffect, global_position + Vector2(randi_range(3, 5), (16 + 7) * mod))
- )
- i.rotation = (PI / 2) * mod
-
+ var i: Node2D = (
+ Utils . instance_scene_on_main(DustEffect, global_position + Vector2(randi_range(3, 5), (16 + 7) * mod))
+ )
+ i.rotation = (PI / 2) * mod
+## Opens this door
func open() -> void:
- dust(1)
- dust(-1)
- var t := create_tween().set_ease(Tween.EASE_IN)
- t.tween_property(path_follower, "progress_ratio", 1, 2)
- await t.finished
- queue_free()
+ dust(1)
+ dust(-1)
+ var t := create_tween().set_ease(Tween.EASE_IN)
+ t.tween_property(path_follower, "progress_ratio", 1, 2)
+ await t.finished
+ queue_free()
diff --git a/world/door/door.gd b/world/door/door.gd
index bd5869f..dd9afb2 100644
--- a/world/door/door.gd
+++ b/world/door/door.gd
@@ -1,8 +1,8 @@
extends Area2D
class_name Door
+## The direction the player should go in when going through this door
var dir: Vector2i
-
func _on_body_entered(_p: Player) -> void:
- Events.emit_signal(&"change_level", dir)
+ Events.change_level.emit(dir)