summaryrefslogtreecommitdiff
path: root/Scripts
diff options
context:
space:
mode:
authoraltaf-creator <dev@altafcreator.com>2025-10-20 01:43:48 +0800
committeraltaf-creator <dev@altafcreator.com>2025-10-20 01:43:48 +0800
commit466bec0b724632f6dd2e1555a7bd58ffc1dd0458 (patch)
treed6645ea11914edeec645299fa497a9e542dbaec7 /Scripts
Jam version.
Diffstat (limited to 'Scripts')
-rw-r--r--Scripts/CheckpointArea.gd15
-rw-r--r--Scripts/CheckpointArea.gd.uid1
-rw-r--r--Scripts/Enemy AI/JungleAI.gd48
-rw-r--r--Scripts/Enemy AI/JungleAI.gd.uid1
-rw-r--r--Scripts/Enemy AI/ShoreAI.gd68
-rw-r--r--Scripts/Enemy AI/ShoreAI.gd.uid1
-rw-r--r--Scripts/Entity.gd56
-rw-r--r--Scripts/Entity.gd.uid1
-rw-r--r--Scripts/GameLoop.gd34
-rw-r--r--Scripts/GameLoop.gd.uid1
-rw-r--r--Scripts/Level Specific/0MachetteGive.gd8
-rw-r--r--Scripts/Level Specific/0MachetteGive.gd.uid1
-rw-r--r--Scripts/Level Specific/1FruitSrhubs.gd14
-rw-r--r--Scripts/Level Specific/1FruitSrhubs.gd.uid1
-rw-r--r--Scripts/Level Specific/1Mud.gd11
-rw-r--r--Scripts/Level Specific/1Mud.gd.uid1
-rw-r--r--Scripts/Level Specific/1SpikyShrubs.gd27
-rw-r--r--Scripts/Level Specific/1SpikyShrubs.gd.uid1
-rw-r--r--Scripts/Level Specific/2CameraControls.gd21
-rw-r--r--Scripts/Level Specific/2CameraControls.gd.uid1
-rw-r--r--Scripts/Level Specific/AnimationArea.gd9
-rw-r--r--Scripts/Level Specific/AnimationArea.gd.uid1
-rw-r--r--Scripts/Level Specific/DeathZone.gd20
-rw-r--r--Scripts/Level Specific/DeathZone.gd.uid1
-rw-r--r--Scripts/Level Specific/DisableJump.gd6
-rw-r--r--Scripts/Level Specific/DisableJump.gd.uid1
-rw-r--r--Scripts/Level Specific/Grappleable.gd10
-rw-r--r--Scripts/Level Specific/Grappleable.gd.uid1
-rw-r--r--Scripts/Mask/GrappleMask.gd78
-rw-r--r--Scripts/Mask/GrappleMask.gd.uid1
-rw-r--r--Scripts/Mask/SpeedMask.gd36
-rw-r--r--Scripts/Mask/SpeedMask.gd.uid1
-rw-r--r--Scripts/MaskChest.gd30
-rw-r--r--Scripts/MaskChest.gd.uid1
-rw-r--r--Scripts/Player/PlayerAction.gd46
-rw-r--r--Scripts/Player/PlayerAction.gd.uid1
-rw-r--r--Scripts/Player/PlayerDeath.gd8
-rw-r--r--Scripts/Player/PlayerDeath.gd.uid1
-rw-r--r--Scripts/Player/PlayerInventory.gd89
-rw-r--r--Scripts/Player/PlayerInventory.gd.uid1
-rw-r--r--Scripts/Player/PlayerMovement.gd146
-rw-r--r--Scripts/Player/PlayerMovement.gd.uid1
-rw-r--r--Scripts/SpawnZone.gd41
-rw-r--r--Scripts/SpawnZone.gd.uid1
-rw-r--r--Scripts/Spawner.gd57
-rw-r--r--Scripts/Spawner.gd.uid1
-rw-r--r--Scripts/UI/MaskButton.gd13
-rw-r--r--Scripts/UI/MaskButton.gd.uid1
-rw-r--r--Scripts/UI/UI.gd156
-rw-r--r--Scripts/UI/UI.gd.uid1
-rw-r--r--Scripts/UI/UIConnector.gd32
-rw-r--r--Scripts/UI/UIConnector.gd.uid1
-rw-r--r--Scripts/Weapons/Bow.gd22
-rw-r--r--Scripts/Weapons/Bow.gd.uid1
-rw-r--r--Scripts/Weapons/Melee.gd35
-rw-r--r--Scripts/Weapons/Melee.gd.uid1
-rw-r--r--Scripts/Weapons/Projectile.gd19
-rw-r--r--Scripts/Weapons/Projectile.gd.uid1
58 files changed, 1184 insertions, 0 deletions
diff --git a/Scripts/CheckpointArea.gd b/Scripts/CheckpointArea.gd
new file mode 100644
index 0000000..41ea2ff
--- /dev/null
+++ b/Scripts/CheckpointArea.gd
@@ -0,0 +1,15 @@
+extends Area2D
+
+@export var level_id : int
+
+func _on_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ body.health = body.max_health
+ UIConnector.next_level(level_id)
+ get_tree().get_root().get_node("Node2D").lvl = level_id
+ get_tree().get_root().get_node("Node2D").spawn_pos = global_position
+ get_tree().get_root().get_node("Node2D").inv_at_start = body.get_node("PlayerInventory").mask_inventory
+ get_tree().get_root().get_node("Node2D").has_machette = body.get_node("PlayerInventory").has_machette
+ UIConnector.display_health(body.health)
+ queue_free()
diff --git a/Scripts/CheckpointArea.gd.uid b/Scripts/CheckpointArea.gd.uid
new file mode 100644
index 0000000..0d8b33d
--- /dev/null
+++ b/Scripts/CheckpointArea.gd.uid
@@ -0,0 +1 @@
+uid://kyrqivposqhu
diff --git a/Scripts/Enemy AI/JungleAI.gd b/Scripts/Enemy AI/JungleAI.gd
new file mode 100644
index 0000000..cedb028
--- /dev/null
+++ b/Scripts/Enemy AI/JungleAI.gd
@@ -0,0 +1,48 @@
+extends Node
+
+var player : Entity = null
+
+@export var weapon : Node2D
+@export var pivot : Node2D
+@export var sprite : Node2D
+
+var delta_pos : Vector2
+
+var can_attack : bool = true
+
+func _on_detect_area_body_entered(body:Node2D) -> void:
+ print(body)
+ if body is Entity:
+ if body.is_player:
+ player = body
+
+var parent : Entity
+
+func _process(_delta: float) -> void:
+ parent = get_node("..")
+
+ if !player:
+ return
+
+ delta_pos = player.global_position - parent.global_position
+
+ var angle = rad_to_deg(atan2(delta_pos.y, delta_pos.x)) - 90
+ pivot.rotation_degrees = angle
+
+ if delta_pos.x < 0:
+ if pivot.position.x > 0: pivot.position.x *= -1
+ if pivot.scale.x > 0: pivot.scale.x *= -1
+ if sprite.scale.x > 0: sprite.scale.x *= -1
+ else:
+ if pivot.position.x < 0: pivot.position.x *= -1
+ if pivot.scale.x < 0: pivot.scale.x *= -1
+ if sprite.scale.x < 0: sprite.scale.x *= -1
+
+ if can_attack:
+ weapon.action()
+ $"AttackCooldown".start()
+ can_attack = false
+
+
+func _on_attack_cooldown_timeout() -> void:
+ can_attack = true
diff --git a/Scripts/Enemy AI/JungleAI.gd.uid b/Scripts/Enemy AI/JungleAI.gd.uid
new file mode 100644
index 0000000..dc5e0f4
--- /dev/null
+++ b/Scripts/Enemy AI/JungleAI.gd.uid
@@ -0,0 +1 @@
+uid://cahhmhibcdjcd
diff --git a/Scripts/Enemy AI/ShoreAI.gd b/Scripts/Enemy AI/ShoreAI.gd
new file mode 100644
index 0000000..16a3e04
--- /dev/null
+++ b/Scripts/Enemy AI/ShoreAI.gd
@@ -0,0 +1,68 @@
+extends Node
+
+var player : Entity = null
+var parent : Entity
+
+@export var weapon : Node2D
+@export var sprite : Node2D
+@export var animator : AnimationPlayer
+@export var walk_speed : float = 200
+
+var in_range : bool = false
+var can_attack : bool = true
+
+func _ready() -> void:
+ parent = get_node("..")
+ walk_speed = randf_range(walk_speed - 50, walk_speed + 50)
+
+var delta_pos : Vector2
+
+func _process(delta: float) -> void:
+ if !player:
+ return
+
+ delta_pos = player.global_position - parent.global_position
+
+ if delta_pos.x < 0:
+ if weapon.position.x > 0: weapon.position.x = -weapon.position.x
+ if weapon.scale.x > 0: weapon.scale.x = -1
+ if sprite.scale.x > 0: sprite.scale.x = -1
+ else:
+ if weapon.position.x < 0: weapon.position.x = -weapon.position.x
+ if weapon.scale.x < 0: weapon.scale.x = 1
+ if sprite.scale.x < 0: sprite.scale.x = 1
+
+ if in_range && can_attack:
+ weapon.action()
+ parent.linear_velocity.y = 2000
+ can_attack = false
+
+func _physics_process(delta: float) -> void:
+ if !in_range && parent.linear_velocity.y == 0 && player:
+ if delta_pos.x < 0:
+ parent.linear_velocity.x = -walk_speed
+ else:
+ parent.linear_velocity.x = walk_speed
+ animator.play("walk")
+ elif in_range:
+ animator.stop()
+
+func _on_area_2d_body_entered(body:Node2D) -> void:
+ print(body)
+ if body is Entity:
+ if body.is_player:
+ player = body
+ $"AttackCooldown".start()
+
+func _on_attack_area_body_entered(body: Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ in_range = true
+
+func _on_attack_area_body_exited(body: Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ in_range = false
+
+func _on_attack_cooldown_timeout() -> void:
+ can_attack = true
diff --git a/Scripts/Enemy AI/ShoreAI.gd.uid b/Scripts/Enemy AI/ShoreAI.gd.uid
new file mode 100644
index 0000000..2f42db4
--- /dev/null
+++ b/Scripts/Enemy AI/ShoreAI.gd.uid
@@ -0,0 +1 @@
+uid://n2vodoxhopnr
diff --git a/Scripts/Entity.gd b/Scripts/Entity.gd
new file mode 100644
index 0000000..33a1e98
--- /dev/null
+++ b/Scripts/Entity.gd
@@ -0,0 +1,56 @@
+extends PhysicsBody2D
+class_name Entity
+
+@export var is_player : bool = false
+@export var is_player_dead : bool = false
+@export var max_health : int = 10
+var health : int = 1
+
+var timer : Timer
+
+var knockback : Vector2
+
+func _ready() -> void:
+ timer = Timer.new()
+ add_child(timer)
+ timer.wait_time = 0.15
+ timer.one_shot = true
+ timer.timeout.connect(_on_dmg_visual_timer_timeout)
+ health = max_health
+
+signal entity_death
+
+func _process(_delta: float) -> void:
+ if health <= 0:
+ entity_death.emit()
+ if !is_player:
+ queue_free()
+ else:
+ is_player_dead = true
+
+func _physics_process(_delta: float) -> void:
+ if is_player && knockback != Vector2.ZERO:
+ $"PlayerMovement".knockback = knockback
+ knockback = Vector2.ZERO
+
+func damage(n : int):
+ health -= n
+ modulate = Color.RED
+ timer.start()
+
+ if is_player: UIConnector.display_health(health)
+
+func _on_dmg_visual_timer_timeout() -> void:
+ modulate = Color.WHITE
+
+# this is bad
+
+func make_tools_invisible():
+ $"HandPivot".visible = false
+
+func make_mask_invisible():
+ $"MaskNode".visible = false
+
+func make_invisisble():
+ $"Player".visible = false
+ $"Sprite2D".visible = false
diff --git a/Scripts/Entity.gd.uid b/Scripts/Entity.gd.uid
new file mode 100644
index 0000000..3fbc6b5
--- /dev/null
+++ b/Scripts/Entity.gd.uid
@@ -0,0 +1 @@
+uid://c5warxls18mds
diff --git a/Scripts/GameLoop.gd b/Scripts/GameLoop.gd
new file mode 100644
index 0000000..353f1be
--- /dev/null
+++ b/Scripts/GameLoop.gd
@@ -0,0 +1,34 @@
+extends Node2D
+
+var spawn_pos : Vector2 = Vector2(640, 372)
+
+var inv_at_start : Array[int] = [-1, -1, -1, -1, -1, -1]
+var has_machette : bool = false
+
+var player : Entity
+
+@export var lvl : int = 0
+
+@export var level_nodes : Array[Node2D]
+@export var level_packs : Array[PackedScene]
+
+func _ready() -> void:
+ player = get_tree().get_root().get_node("Node2D/Player")
+ Engine.time_scale = 1
+
+func restart() -> void:
+ var new = level_packs[lvl].instantiate()
+
+ new.global_position = level_nodes[lvl].global_position
+ get_tree().get_root().get_node("Node2D").add_child(new)
+ level_nodes[lvl].queue_free()
+ level_nodes[lvl] = new
+
+ player.health = player.max_health
+ UIConnector.display_health(player.health)
+ player.position = spawn_pos
+ player.visible = true
+ player.process_mode = Node.PROCESS_MODE_PAUSABLE
+ player.get_node("PlayerInventory").mask_inventory = inv_at_start
+ if !has_machette: player.get_node("PlayerInventory").ungive_machette()
+ UIConnector.update_masks(player.get_node("PlayerInventory").mask_inventory)
diff --git a/Scripts/GameLoop.gd.uid b/Scripts/GameLoop.gd.uid
new file mode 100644
index 0000000..652213d
--- /dev/null
+++ b/Scripts/GameLoop.gd.uid
@@ -0,0 +1 @@
+uid://cde31fpchqoxt
diff --git a/Scripts/Level Specific/0MachetteGive.gd b/Scripts/Level Specific/0MachetteGive.gd
new file mode 100644
index 0000000..9754741
--- /dev/null
+++ b/Scripts/Level Specific/0MachetteGive.gd
@@ -0,0 +1,8 @@
+extends Node2D
+
+
+func _on_area_2d_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ body.get_node("PlayerInventory").give_machette()
+ queue_free()
diff --git a/Scripts/Level Specific/0MachetteGive.gd.uid b/Scripts/Level Specific/0MachetteGive.gd.uid
new file mode 100644
index 0000000..8b41468
--- /dev/null
+++ b/Scripts/Level Specific/0MachetteGive.gd.uid
@@ -0,0 +1 @@
+uid://c4st16y5gx2yh
diff --git a/Scripts/Level Specific/1FruitSrhubs.gd b/Scripts/Level Specific/1FruitSrhubs.gd
new file mode 100644
index 0000000..ee38b61
--- /dev/null
+++ b/Scripts/Level Specific/1FruitSrhubs.gd
@@ -0,0 +1,14 @@
+extends Node2D
+
+@export var area : Area2D
+@export var fruites : Node2D
+@export var health = 3
+
+func _on_area_2d_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ body.health += health
+ body.health = min(body.health, body.max_health)
+ UIConnector.display_health(body.health)
+ area.queue_free()
+ fruites.queue_free()
diff --git a/Scripts/Level Specific/1FruitSrhubs.gd.uid b/Scripts/Level Specific/1FruitSrhubs.gd.uid
new file mode 100644
index 0000000..1cfc179
--- /dev/null
+++ b/Scripts/Level Specific/1FruitSrhubs.gd.uid
@@ -0,0 +1 @@
+uid://cl2xrq3y86cer
diff --git a/Scripts/Level Specific/1Mud.gd b/Scripts/Level Specific/1Mud.gd
new file mode 100644
index 0000000..eaa64d5
--- /dev/null
+++ b/Scripts/Level Specific/1Mud.gd
@@ -0,0 +1,11 @@
+extends Area2D
+
+func _on_body_exited(body:Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ body.get_node("PlayerMovement").speed *= 4
+
+func _on_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ body.get_node("PlayerMovement").speed /= 4
diff --git a/Scripts/Level Specific/1Mud.gd.uid b/Scripts/Level Specific/1Mud.gd.uid
new file mode 100644
index 0000000..00af3c2
--- /dev/null
+++ b/Scripts/Level Specific/1Mud.gd.uid
@@ -0,0 +1 @@
+uid://bkw5wrlcs14pa
diff --git a/Scripts/Level Specific/1SpikyShrubs.gd b/Scripts/Level Specific/1SpikyShrubs.gd
new file mode 100644
index 0000000..99747a2
--- /dev/null
+++ b/Scripts/Level Specific/1SpikyShrubs.gd
@@ -0,0 +1,27 @@
+extends Node2D
+
+@export var health = 1
+
+var can_hurt = true
+
+var pler : Entity = null
+
+func _process(_delta: float) -> void:
+ if pler && can_hurt:
+ pler.damage(health)
+ can_hurt = false
+ $"Timer".start()
+
+func _on_area_2d_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ if body.is_player && can_hurt:
+ pler = body
+ pler.get_node("PlayerMovement").speed /= 2
+
+func _on_timer_timeout() -> void:
+ can_hurt = true
+
+func _on_area_2d_body_exited(_body:Node2D) -> void:
+ if pler:
+ pler.get_node("PlayerMovement").speed *= 2
+ pler = null
diff --git a/Scripts/Level Specific/1SpikyShrubs.gd.uid b/Scripts/Level Specific/1SpikyShrubs.gd.uid
new file mode 100644
index 0000000..1c9977b
--- /dev/null
+++ b/Scripts/Level Specific/1SpikyShrubs.gd.uid
@@ -0,0 +1 @@
+uid://d311iyn5wpy1q
diff --git a/Scripts/Level Specific/2CameraControls.gd b/Scripts/Level Specific/2CameraControls.gd
new file mode 100644
index 0000000..f207aca
--- /dev/null
+++ b/Scripts/Level Specific/2CameraControls.gd
@@ -0,0 +1,21 @@
+extends Area2D
+
+@export_range(-1, 1, 0.01) var horizontal_offset : float = 0
+@export var x_delta : float
+@export var y_delta : float
+@export var once : bool = false
+@export var set : bool = false
+
+func _on_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ var cam : Camera2D = body.get_node("Node2D/Camera2D")
+
+ cam.drag_horizontal_offset = horizontal_offset
+ if !set:
+ cam.position.x += x_delta
+ cam.position.y += y_delta
+ else:
+ cam.position.x = x_delta
+ cam.position.y = y_delta
+ if once: queue_free()
diff --git a/Scripts/Level Specific/2CameraControls.gd.uid b/Scripts/Level Specific/2CameraControls.gd.uid
new file mode 100644
index 0000000..1c3c871
--- /dev/null
+++ b/Scripts/Level Specific/2CameraControls.gd.uid
@@ -0,0 +1 @@
+uid://b5td7htthnvrn
diff --git a/Scripts/Level Specific/AnimationArea.gd b/Scripts/Level Specific/AnimationArea.gd
new file mode 100644
index 0000000..70d5e85
--- /dev/null
+++ b/Scripts/Level Specific/AnimationArea.gd
@@ -0,0 +1,9 @@
+extends Area2D
+
+@export var anim : AnimationPlayer
+@export var aname : String
+
+func _on_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ anim.play(aname)
diff --git a/Scripts/Level Specific/AnimationArea.gd.uid b/Scripts/Level Specific/AnimationArea.gd.uid
new file mode 100644
index 0000000..e55799d
--- /dev/null
+++ b/Scripts/Level Specific/AnimationArea.gd.uid
@@ -0,0 +1 @@
+uid://dfgrs1b8urejr
diff --git a/Scripts/Level Specific/DeathZone.gd b/Scripts/Level Specific/DeathZone.gd
new file mode 100644
index 0000000..0648c27
--- /dev/null
+++ b/Scripts/Level Specific/DeathZone.gd
@@ -0,0 +1,20 @@
+extends Area2D
+
+var timer : Timer
+
+func _ready() -> void:
+ monitoring = false
+ timer = Timer.new()
+ timer.wait_time = 1
+ timer.timeout.connect(_enable)
+ add_child(timer)
+ timer.one_shot = true
+ timer.start()
+
+func _on_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ body.damage(1000000)
+ monitoring = false
+
+func _enable():
+ monitoring = true
diff --git a/Scripts/Level Specific/DeathZone.gd.uid b/Scripts/Level Specific/DeathZone.gd.uid
new file mode 100644
index 0000000..dfed3a0
--- /dev/null
+++ b/Scripts/Level Specific/DeathZone.gd.uid
@@ -0,0 +1 @@
+uid://c6a1wljfwd8jm
diff --git a/Scripts/Level Specific/DisableJump.gd b/Scripts/Level Specific/DisableJump.gd
new file mode 100644
index 0000000..ac4ec38
--- /dev/null
+++ b/Scripts/Level Specific/DisableJump.gd
@@ -0,0 +1,6 @@
+extends Area2D
+
+func _on_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ body.get_node("PlayerMovement").jump_vel = 0
diff --git a/Scripts/Level Specific/DisableJump.gd.uid b/Scripts/Level Specific/DisableJump.gd.uid
new file mode 100644
index 0000000..8f61bfa
--- /dev/null
+++ b/Scripts/Level Specific/DisableJump.gd.uid
@@ -0,0 +1 @@
+uid://cswiai0otl7jn
diff --git a/Scripts/Level Specific/Grappleable.gd b/Scripts/Level Specific/Grappleable.gd
new file mode 100644
index 0000000..43dcbd4
--- /dev/null
+++ b/Scripts/Level Specific/Grappleable.gd
@@ -0,0 +1,10 @@
+extends StaticBody2D
+class_name Grappleable
+
+@export var highlighter : Sprite2D
+
+func highlight():
+ highlighter.visible = true
+
+func dehighlight():
+ highlighter.visible = false
diff --git a/Scripts/Level Specific/Grappleable.gd.uid b/Scripts/Level Specific/Grappleable.gd.uid
new file mode 100644
index 0000000..e735572
--- /dev/null
+++ b/Scripts/Level Specific/Grappleable.gd.uid
@@ -0,0 +1 @@
+uid://c8n5trpan30g0
diff --git a/Scripts/Mask/GrappleMask.gd b/Scripts/Mask/GrappleMask.gd
new file mode 100644
index 0000000..35df89a
--- /dev/null
+++ b/Scripts/Mask/GrappleMask.gd
@@ -0,0 +1,78 @@
+extends Node2D
+
+@export var area : Area2D
+@export var area_detect : Area2D
+@export var line : Line2D
+@export var grapple_speed : float
+
+var thing : Node2D = null
+
+var player_movement : PlayerMovement
+
+var just_released : bool = false
+
+func _ready() -> void:
+ player_movement = get_node("../../PlayerMovement")
+
+func _input(event: InputEvent) -> void:
+ if event is InputEventMouseMotion:
+ var delta_pos = event.position - get_global_transform_with_canvas().origin
+ area_detect.rotation = atan2(delta_pos.y, delta_pos.x)
+ if Input.is_action_just_pressed("action_secondary") && event is InputEventMouseButton:
+ var delta_pos = event.position - get_global_transform_with_canvas().origin
+ area.rotation = atan2(delta_pos.y, delta_pos.x)
+ area.monitoring = true
+ if Input.is_action_just_released("action_secondary"):
+ print("hi")
+ area.monitoring = false
+ thing = null
+
+var init_delta : Vector2
+var x_vel
+
+func _process(_delta: float) -> void:
+ if !thing:
+ if just_released:
+ player_movement.grapple_x_vel_aft = player_movement.speed
+ player_movement.grapple_velocity = Vector2.ZERO
+ line.points[1] = Vector2.ZERO
+ x_vel = null
+ just_released = false
+ return
+
+ area.monitoring = false
+
+ var delta_pos = thing.global_position - global_position
+ print(delta_pos.length(), " ", delta_pos.y, " ", delta_pos.x)
+
+ line.points[1] = delta_pos
+
+ var normalised = delta_pos.normalized()
+
+ if !x_vel: x_vel = normalised.x
+
+ if x_vel > 0.3:
+ x_vel = .9
+ elif x_vel < -0.3:
+ x_vel = -.9
+
+ if delta_pos.length() < 100 || ((x_vel > 0 && delta_pos.x < 0) || (x_vel < 0 && delta_pos.x > 0)):
+ just_released = true
+ thing = null
+
+ player_movement.grapple_velocity = Vector2(x_vel, normalised.y * 1.1) * grapple_speed
+
+func _on_area_2d_body_entered(body: Node2D) -> void:
+ print("grapple", body)
+ thing = body
+ area.monitoring = false
+ init_delta = thing.global_position - global_position
+
+func _on_detect_area_2d_body_exited(body:Node2D) -> void:
+ if body is Grappleable:
+ body.dehighlight()
+
+func _on_detect_area_2d_body_entered(body:Node2D) -> void:
+ if body is Grappleable:
+ body.highlight()
+
diff --git a/Scripts/Mask/GrappleMask.gd.uid b/Scripts/Mask/GrappleMask.gd.uid
new file mode 100644
index 0000000..908aafb
--- /dev/null
+++ b/Scripts/Mask/GrappleMask.gd.uid
@@ -0,0 +1 @@
+uid://cxy2ovjxwgtco
diff --git a/Scripts/Mask/SpeedMask.gd b/Scripts/Mask/SpeedMask.gd
new file mode 100644
index 0000000..682785a
--- /dev/null
+++ b/Scripts/Mask/SpeedMask.gd
@@ -0,0 +1,36 @@
+extends Node2D
+
+var player_movement : PlayerMovement
+
+var timer : Timer
+
+var just_clicked : bool = false
+
+var can_dash : bool = true
+
+func _ready() -> void:
+ player_movement = get_node("../../PlayerMovement")
+ timer = Timer.new()
+ timer.wait_time = .5
+ timer.one_shot = true
+ timer.timeout.connect(_timeout)
+ add_child(timer)
+
+func _input(_event: InputEvent) -> void:
+# if Input.is_action_just_pressed("left") || Input.is_action_just_pressed("right"):
+# if !just_clicked:
+# just_clicked = true
+# timer.start()
+# else:
+# just_clicked = false
+ if Input.is_action_just_pressed("dash"):
+ if can_dash:
+ player_movement.dash(Input.get_axis("left", "right"))
+ can_dash = false
+ $"Cooldown".start()
+
+func _timeout() -> void:
+ just_clicked = false
+
+func _on_cooldown_timeout() -> void:
+ can_dash = true
diff --git a/Scripts/Mask/SpeedMask.gd.uid b/Scripts/Mask/SpeedMask.gd.uid
new file mode 100644
index 0000000..4e64967
--- /dev/null
+++ b/Scripts/Mask/SpeedMask.gd.uid
@@ -0,0 +1 @@
+uid://dpjuboxc5u855
diff --git a/Scripts/MaskChest.gd b/Scripts/MaskChest.gd
new file mode 100644
index 0000000..76d1ecf
--- /dev/null
+++ b/Scripts/MaskChest.gd
@@ -0,0 +1,30 @@
+extends Node2D
+class_name MaskChest
+
+enum MaskType {
+ Dash = 0,
+ Grapple = 1,
+ Freeze = 3,
+ Minions = 2,
+}
+
+@export var mask : MaskType
+
+@export var masks : Array[Node2D]
+@export var tutorial_to_be_visible : Array[Sprite2D]
+
+@export var animator : AnimationPlayer
+
+@export var area : Area2D
+
+func _on_area_2d_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ if body.is_player:
+ masks[mask].visible = true
+ animator.play("mask_reveal")
+ body.get_node("PlayerInventory").add_mask(mask)
+
+ for sprite in tutorial_to_be_visible:
+ sprite.visible = true
+
+ area.queue_free()
diff --git a/Scripts/MaskChest.gd.uid b/Scripts/MaskChest.gd.uid
new file mode 100644
index 0000000..5ea26cd
--- /dev/null
+++ b/Scripts/MaskChest.gd.uid
@@ -0,0 +1 @@
+uid://buli338mi1oqs
diff --git a/Scripts/Player/PlayerAction.gd b/Scripts/Player/PlayerAction.gd
new file mode 100644
index 0000000..989823a
--- /dev/null
+++ b/Scripts/Player/PlayerAction.gd
@@ -0,0 +1,46 @@
+extends Node
+class_name PlayerAction
+
+@export var plr_sprite : Sprite2D
+@export var hand_pivot : Node2D
+@export var curr_weapon : Node2D
+@export var machette_pivot : Node2D
+@export var machette : Node2D
+
+var can_attack : bool = true
+
+var delta_pos : Vector2
+
+func _process(_delta: float) -> void:
+ if UIConnector.is_inv_open:
+ return
+
+ var hpos : Vector2 = hand_pivot.get_global_transform_with_canvas().get_origin()
+ var mouse_position : Vector2 = get_viewport().get_mouse_position()
+ delta_pos = mouse_position - hpos
+
+ var angle = rad_to_deg(atan2(delta_pos.y, delta_pos.x)) - 90
+ hand_pivot.rotation_degrees = angle
+ if angle <= 0 && angle >= -180:
+ if machette_pivot.rotation_degrees < 0: machette_pivot.rotation_degrees *= -1
+ if machette.scale.x < 0: machette.scale.x *= -1
+ elif (angle <= -180 && angle >= -270) || (angle >= 0 && angle <= 90):
+ if machette_pivot.rotation_degrees > 0: machette_pivot.rotation_degrees *= -1
+ if machette.scale.x > 0: machette.scale.x *= -1
+
+func _input(_event: InputEvent) -> void:
+ if UIConnector.is_inv_open:
+ return
+
+ if Input.is_action_just_pressed("action") && can_attack:
+ if delta_pos.x < 0 && !plr_sprite.flip_h:
+ $"../PlayerMovement".look_left(true)
+ elif delta_pos.x > 0 && plr_sprite.flip_h:
+ $"../PlayerMovement".look_right(true)
+
+ curr_weapon.action()
+ can_attack = false
+ $"Cooldown".start()
+
+func _on_cooldown_timeout() -> void:
+ can_attack = true
diff --git a/Scripts/Player/PlayerAction.gd.uid b/Scripts/Player/PlayerAction.gd.uid
new file mode 100644
index 0000000..00777f8
--- /dev/null
+++ b/Scripts/Player/PlayerAction.gd.uid
@@ -0,0 +1 @@
+uid://f4kopug5xiuj
diff --git a/Scripts/Player/PlayerDeath.gd b/Scripts/Player/PlayerDeath.gd
new file mode 100644
index 0000000..5df4fbf
--- /dev/null
+++ b/Scripts/Player/PlayerDeath.gd
@@ -0,0 +1,8 @@
+extends Node
+
+@export var player : CharacterBody2D
+
+func _on_player_entity_death() -> void:
+ player.visible = false
+ player.process_mode = Node.PROCESS_MODE_DISABLED
+ UIConnector.death()
diff --git a/Scripts/Player/PlayerDeath.gd.uid b/Scripts/Player/PlayerDeath.gd.uid
new file mode 100644
index 0000000..1d6d4b1
--- /dev/null
+++ b/Scripts/Player/PlayerDeath.gd.uid
@@ -0,0 +1 @@
+uid://dovejm1jxwfrp
diff --git a/Scripts/Player/PlayerInventory.gd b/Scripts/Player/PlayerInventory.gd
new file mode 100644
index 0000000..76ad2ec
--- /dev/null
+++ b/Scripts/Player/PlayerInventory.gd
@@ -0,0 +1,89 @@
+extends Node
+class_name PlayerInventory
+
+@export var action : PlayerAction
+@export var machette_pivot : Node2D
+
+@export var bow : Node2D
+@export var bow_cooldown : float = 0.35
+@export var machette : Node2D
+@export var machette_cooldown : float = 0.2
+
+@export var masks : Array[Node2D]
+
+
+enum MaskType {
+ Dash = 0,
+ Grapple = 1,
+ Freeze = 3,
+ Minions = 2,
+}
+
+var prev_inv : Array[int] = [-1, -1, -1, -1, -1, -1]
+
+@export var mask_inventory : Array[int] = [-1, -1, -1, -1, -1, -1]
+
+var has_machette : bool = false
+var using_bow : bool = true
+
+func _ready():
+ UIConnector.update_masks(mask_inventory)
+
+func _input(_event: InputEvent) -> void:
+ if Input.is_action_just_pressed("switch_tool") && has_machette:
+ UIConnector.switch_tool()
+
+ if using_bow:
+ action.curr_weapon = machette
+ machette_pivot.visible = true
+ bow.visible = false
+ machette.process_mode = Node.PROCESS_MODE_INHERIT
+ bow.process_mode = Node.PROCESS_MODE_DISABLED
+ action.get_node("Cooldown").wait_time = machette_cooldown
+ else:
+ action.curr_weapon = bow
+ machette_pivot.visible = false
+ bow.visible = true
+ machette.process_mode = Node.PROCESS_MODE_DISABLED
+ bow.process_mode = Node.PROCESS_MODE_INHERIT
+ action.get_node("Cooldown").wait_time = bow_cooldown
+
+ using_bow = !using_bow
+
+ if Input.is_action_just_pressed("switch_mask"):
+ var curr_mask = mask_inventory[0]
+ mask_inventory[0] = mask_inventory[1]
+ mask_inventory[1] = curr_mask
+ UIConnector.update_masks(mask_inventory)
+ $"../PlayerMovement".grapple_velocity = Vector2.ZERO
+
+func _process(_delta: float) -> void:
+ if prev_inv.hash() != mask_inventory.hash():
+ print("changed")
+ for mask in masks:
+ mask.visible = false
+ mask.process_mode = Node.PROCESS_MODE_DISABLED
+ if mask_inventory[0] != -1:
+ print("YEAH")
+ masks[mask_inventory[0]].visible = true
+ masks[mask_inventory[0]].process_mode = Node.PROCESS_MODE_INHERIT
+
+ prev_inv = mask_inventory.duplicate()
+
+func give_machette() -> void:
+ has_machette = true
+ UIConnector.add_machette()
+
+func ungive_machette() -> void:
+ has_machette = false
+ UIConnector.remove_machette()
+
+func add_mask(mask : MaskType):
+ print("the mask is ", mask)
+ if !(mask in mask_inventory):
+ for i in range(2, 6):
+ if mask_inventory[i] == -1:
+ mask_inventory[i] = mask
+ break
+ UIConnector.update_masks(mask_inventory)
+ UIConnector.show_mask_bubble()
diff --git a/Scripts/Player/PlayerInventory.gd.uid b/Scripts/Player/PlayerInventory.gd.uid
new file mode 100644
index 0000000..e1d5bbd
--- /dev/null
+++ b/Scripts/Player/PlayerInventory.gd.uid
@@ -0,0 +1 @@
+uid://bmx4fy618slwb
diff --git a/Scripts/Player/PlayerMovement.gd b/Scripts/Player/PlayerMovement.gd
new file mode 100644
index 0000000..648a5e6
--- /dev/null
+++ b/Scripts/Player/PlayerMovement.gd
@@ -0,0 +1,146 @@
+extends Node
+class_name PlayerMovement
+
+@export var character : CharacterBody2D
+
+@export var speed = 300.0
+@export var jump_vel = -400.0
+
+@export var plr_sprite : Sprite2D
+@export var mask_node : Node2D
+@export var hand_pivot : Node2D
+
+@export var cape : Sprite2D
+@export var skew_min : float
+@export var skew_max : float
+@export var skew_maxmax : float
+@export var lerp_step_on : float
+@export var lerp_step_off : float
+
+var target_skew = 0.0
+var curr_step = 0.0
+
+@export var min_knock = 100
+@export var knockback_decay = 1.3
+var knockback : Vector2
+
+var dir_manipulated : bool = false
+
+var dash_timer : Timer
+var dashing : bool = false
+var dash_dir : int = 0
+@export var dash_time : float = 0.2
+@export var dash_speed : float = 1500
+
+var grapple_velocity : Vector2 = Vector2.ZERO
+var grapple_x_vel_aft : float = 0
+
+func _ready() -> void:
+ dash_timer = Timer.new()
+ dash_timer.wait_time = dash_time
+ dash_timer.one_shot = true
+ dash_timer.timeout.connect(_on_dash_end)
+ add_child(dash_timer)
+
+ manipulate_timer = Timer.new()
+ add_child(manipulate_timer)
+ manipulate_timer.wait_time = 0.5
+ manipulate_timer.one_shot = true
+ manipulate_timer.timeout.connect(_on_manipulate_end)
+
+
+func _physics_process(delta: float) -> void:
+ if knockback.length_squared() > min_knock**2:
+ knockback /= knockback_decay
+ character.velocity = knockback
+ character.move_and_slide()
+ return
+
+ if grapple_velocity != Vector2.ZERO:
+ character.velocity = grapple_velocity
+ character.move_and_slide()
+ return
+
+ # Add the gravity.
+ if not character.is_on_floor():
+ character.velocity += character.get_gravity() * delta
+
+ if dashing:
+ character.velocity.x = 1000 * dash_dir
+ character.move_and_slide()
+ return
+
+ # Handle jump.
+ if Input.is_action_just_pressed("jump") and character.is_on_floor():
+ character.velocity.y = jump_vel
+
+ # Get the input direction and handle the movement/deceleration.
+ # As good practice, you should replace UI actions with custom gameplay actions.
+ var direction := Input.get_axis("left", "right")
+ if direction:
+ grapple_x_vel_aft = 0
+ character.velocity.x = direction * speed
+ if character.velocity.y < 0:
+ target_skew = skew_min
+ elif character.is_on_floor():
+ target_skew = skew_max
+ curr_step = lerp_step_on
+ else:
+ if grapple_x_vel_aft != 0:
+ grapple_x_vel_aft = move_toward(character.velocity.x, 0, speed * delta)
+ character.velocity.x = grapple_x_vel_aft
+ else:
+ character.velocity.x = move_toward(character.velocity.x, 0, speed)
+ target_skew = skew_min
+ curr_step = lerp_step_off
+
+ if character.velocity.y > 0:
+ target_skew = skew_maxmax
+ curr_step = lerp_step_off
+
+ cape.skew = lerp_angle(cape.skew, deg_to_rad(target_skew), curr_step)
+
+ if direction == -1 && !dir_manipulated: look_left()
+ elif direction == 1 && !dir_manipulated: look_right()
+
+ character.move_and_slide()
+
+var manipulate_timer : Timer
+
+func look_left(manipulate : bool = false) -> void:
+ if manipulate:
+ dir_manipulated = true
+ manipulate_timer.start()
+
+ if cape.skew > 0: cape.skew = -cape.skew
+ if skew_min > 0: skew_min = -skew_min
+ if skew_max > 0: skew_max = -skew_max
+ if skew_maxmax > 0: skew_maxmax = -skew_maxmax
+ if mask_node.position.x > 0: mask_node.position.x *= -1
+ if hand_pivot.position.x > 0: hand_pivot.position.x *= -1
+ plr_sprite.flip_h = true
+
+
+func look_right(manipulate : bool = false) -> void:
+ if manipulate:
+ dir_manipulated = true
+ manipulate_timer.start()
+
+ if cape.skew < 0: cape.skew = -cape.skew
+ if skew_min < 0: skew_min = -skew_min
+ if skew_max < 0: skew_max = -skew_max
+ if skew_maxmax < 0: skew_maxmax = -skew_maxmax
+ if mask_node.position.x < 0: mask_node.position.x *= -1
+ if hand_pivot.position.x < 0: hand_pivot.position.x *= -1
+ plr_sprite.flip_h = false
+
+func dash(dir):
+ dashing = true
+ dash_dir = dir
+ dash_timer.start()
+
+func _on_manipulate_end() -> void:
+ dir_manipulated = false
+
+func _on_dash_end() -> void:
+ dashing = false
diff --git a/Scripts/Player/PlayerMovement.gd.uid b/Scripts/Player/PlayerMovement.gd.uid
new file mode 100644
index 0000000..8636702
--- /dev/null
+++ b/Scripts/Player/PlayerMovement.gd.uid
@@ -0,0 +1 @@
+uid://d1e1dfcab58lk
diff --git a/Scripts/SpawnZone.gd b/Scripts/SpawnZone.gd
new file mode 100644
index 0000000..fdcb10a
--- /dev/null
+++ b/Scripts/SpawnZone.gd
@@ -0,0 +1,41 @@
+extends Area2D
+class_name SpawnZone
+
+var spawned : bool = false
+
+@export var anim_to_play : Array[AnimationPlayer]
+@export var spawn_to_enable : Array[Spawner]
+
+func _ready() -> void:
+ var timer = Timer.new()
+ add_child(timer)
+ timer.wait_time = .5
+ timer.timeout.connect(_timeout)
+ timer.start()
+
+func _on_body_entered(body:Node2D) -> void:
+ if spawned:
+ return
+
+ if body is Entity:
+ if body.is_player:
+ for anim in anim_to_play:
+ anim.play("close")
+
+ for spawner in spawn_to_enable:
+ spawner.all_spawned_dead.connect(_a_spawner_finished)
+ spawner.start()
+
+ spawned = true
+
+var finished_counter = 0
+
+func _a_spawner_finished() -> void:
+ if finished_counter >= len(spawn_to_enable) - 1:
+ for anim in anim_to_play:
+ anim.play("open")
+ else:
+ finished_counter += 1
+
+func _timeout() -> void:
+ monitoring = true
diff --git a/Scripts/SpawnZone.gd.uid b/Scripts/SpawnZone.gd.uid
new file mode 100644
index 0000000..de83a2d
--- /dev/null
+++ b/Scripts/SpawnZone.gd.uid
@@ -0,0 +1 @@
+uid://c5vuv87l6mm6w
diff --git a/Scripts/Spawner.gd b/Scripts/Spawner.gd
new file mode 100644
index 0000000..c2c60c5
--- /dev/null
+++ b/Scripts/Spawner.gd
@@ -0,0 +1,57 @@
+extends Node2D
+class_name Spawner
+
+@export var enemy : PackedScene
+@export var interval_seconds : float = 10
+@export var count : int = 5
+@export var initial_delay : float = 3
+@export var curr_lvl : Node2D
+
+var init_timer : Timer
+var timer : Timer
+
+var counter : int = 0
+
+func _ready() -> void:
+ timer = Timer.new()
+ add_child(timer)
+ timer.wait_time = interval_seconds
+ timer.one_shot = false
+ timer.timeout.connect(_on_timeout)
+
+
+ init_timer = Timer.new()
+ add_child(init_timer)
+ init_timer.wait_time = initial_delay
+ init_timer.one_shot = true
+ init_timer.timeout.connect(_actual_start)
+
+func start():
+ init_timer.start()
+
+func _actual_start():
+ _on_timeout()
+ timer.start()
+
+func _on_timeout() -> void:
+ if counter >= count:
+ timer.stop()
+ return
+
+ var new : Entity = enemy.instantiate()
+ new.position = position
+ curr_lvl.add_child(new)
+ new.entity_death.connect(_upon_spawned_death)
+
+ counter += 1
+
+var dead_counter = 0
+
+signal all_spawned_dead
+
+func _upon_spawned_death() -> void:
+ if dead_counter >= count - 1:
+ print("ALL SPAWNED DEAD")
+ all_spawned_dead.emit()
+ else:
+ dead_counter += 1
diff --git a/Scripts/Spawner.gd.uid b/Scripts/Spawner.gd.uid
new file mode 100644
index 0000000..527bf47
--- /dev/null
+++ b/Scripts/Spawner.gd.uid
@@ -0,0 +1 @@
+uid://df037bypj74at
diff --git a/Scripts/UI/MaskButton.gd b/Scripts/UI/MaskButton.gd
new file mode 100644
index 0000000..b9ce505
--- /dev/null
+++ b/Scripts/UI/MaskButton.gd
@@ -0,0 +1,13 @@
+extends Button
+
+@export var mask_type : int = -1
+@export var index : int = 0
+
+func _ready() -> void:
+ pressed.connect(_on_pressed)
+
+signal i_was_pressed(mask : int, index : int, btn : Button)
+
+func _on_pressed() -> void:
+ print("pressed here")
+ i_was_pressed.emit(mask_type, index, self)
diff --git a/Scripts/UI/MaskButton.gd.uid b/Scripts/UI/MaskButton.gd.uid
new file mode 100644
index 0000000..d9bf37f
--- /dev/null
+++ b/Scripts/UI/MaskButton.gd.uid
@@ -0,0 +1 @@
+uid://bbf1up6i5tkg2
diff --git a/Scripts/UI/UI.gd b/Scripts/UI/UI.gd
new file mode 100644
index 0000000..a86d69d
--- /dev/null
+++ b/Scripts/UI/UI.gd
@@ -0,0 +1,156 @@
+extends CanvasLayer
+class_name UI
+
+@export var health_label : Label
+@export var machette_sprite : TextureRect
+
+@export var main_hud : Control
+@export var inventory_panel : Control
+
+@export var tool_slot_1 : PanelContainer
+@export var tool_slot_2 : PanelContainer
+
+@export var mask_slot_1 : PanelContainer
+@export var mask_slot_2 : PanelContainer
+
+@export var inventory_equip : Control
+@export var inventory_secondary : Control
+@export var inventory_1 : Control
+@export var inventory_2 : Control
+@export var inventory_3 : Control
+@export var inventory_4 : Control
+
+@export var bubble_machette_anim : AnimationPlayer
+@export var bubble_mask_anim : AnimationPlayer
+
+@export var death_animator : AnimationPlayer
+
+@export var level_animator : AnimationPlayer
+@export var level_label : Label
+@export var level_label_id : Label
+
+@export var level_names : Array[String]
+
+var curr_tool : bool = false # false is 1, true is 2
+
+var is_inv_open : bool = false
+
+func _ready() -> void:
+ # absolutely disgusting.
+ inventory_equip.i_was_pressed.connect(_on_inventorybtn_pressed)
+ inventory_secondary.i_was_pressed.connect(_on_inventorybtn_pressed)
+ inventory_1.i_was_pressed.connect(_on_inventorybtn_pressed)
+ inventory_2.i_was_pressed.connect(_on_inventorybtn_pressed)
+ inventory_3.i_was_pressed.connect(_on_inventorybtn_pressed)
+ inventory_4.i_was_pressed.connect(_on_inventorybtn_pressed)
+
+func _input(_event: InputEvent) -> void:
+ if Input.is_action_just_pressed("open_bag"):
+ if !is_inv_open:
+ main_hud.visible = false
+ main_hud.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ inventory_panel.visible = true
+ main_hud.mouse_filter = Control.MOUSE_FILTER_STOP
+ else:
+ main_hud.visible = true
+ main_hud.mouse_filter = Control.MOUSE_FILTER_STOP
+ inventory_panel.visible = false
+ main_hud.mouse_filter = Control.MOUSE_FILTER_IGNORE
+ is_inv_open = !is_inv_open
+ UIConnector.is_inv_open = is_inv_open
+
+func display_health(n : int) -> void:
+ health_label.text = "♥".repeat(n)
+
+func add_machette() -> void:
+ machette_sprite.visible = true
+ bubble_machette_anim.play("toast")
+
+func remove_machette() -> void:
+ machette_sprite.visible = false
+
+func switch_tool() -> void:
+ if curr_tool:
+ tool_slot_1.theme_type_variation = "SlotSelected"
+ tool_slot_2.theme_type_variation = "SlotDeselected"
+ else:
+ tool_slot_2.theme_type_variation = "SlotSelected"
+ tool_slot_1.theme_type_variation = "SlotDeselected"
+
+ curr_tool = !curr_tool
+
+var names = ["Dash", "Grapple", "Minions", "Freeze"]
+
+func update_masks(masks : Array[int]) -> void:
+ # are you disgusted?
+ for mname in names:
+ inventory_equip.get_node(mname).visible = false
+ inventory_secondary.get_node(mname).visible = false
+ mask_slot_1.get_node(mname).visible = false
+ mask_slot_2.get_node(mname).visible = false
+ inventory_1.get_node(mname).visible = false
+ inventory_2.get_node(mname).visible = false
+ inventory_3.get_node(mname).visible = false
+ inventory_4.get_node(mname).visible = false
+ if masks[0] != -1:
+ inventory_equip.get_node(names[masks[0]]).visible = true
+ mask_slot_1.get_node(names[masks[0]]).visible = true
+ mask_slot_1.theme_type_variation = "SlotSelected"
+ if masks[1] != -1:
+ inventory_secondary.get_node(names[masks[1]]).visible = true
+ mask_slot_2.get_node(names[masks[1]]).visible = true
+ for mname in names:
+ inventory_1.get_node(mname).visible = false
+ if masks[2] != -1:
+ inventory_1.get_node(names[masks[2]]).visible = true
+ inventory_1.mask_type = masks[2]
+ if masks[3] != -1:
+ inventory_2.get_node(names[masks[3]]).visible = true
+ inventory_2.mask_type = masks[3]
+ if masks[4] != -1:
+ inventory_3.get_node(names[masks[4]]).visible = true
+ inventory_3.mask_type = masks[4]
+ if masks[5] != -1:
+ inventory_4.get_node(names[masks[5]]).visible = true
+ inventory_4.mask_type = masks[5]
+
+func death() -> void:
+ death_animator.play("death")
+
+func death_finished() -> void:
+ get_tree().get_root().get_node("Node2D").restart()
+
+var was_selecting : bool = false
+var prev_selecting_mask : int = -1
+var prev_selecting_index : int = -1
+var prev_selecting_btn : Button
+
+func _on_inventorybtn_pressed(mask : int, index : int, btn : Button) -> void:
+ print("pressed there")
+ # i'm sorry.
+ var player_inventory : PlayerInventory = get_tree().get_root().get_node("Node2D/Player/PlayerInventory")
+
+ if !was_selecting:
+ was_selecting = true
+ prev_selecting_mask = mask
+ prev_selecting_index = index
+ prev_selecting_btn = btn
+ print(prev_selecting_mask, " ", prev_selecting_index)
+ else:
+ was_selecting = false
+ player_inventory.mask_inventory[index] = prev_selecting_mask
+ player_inventory.mask_inventory[prev_selecting_index] = mask
+ btn.mask_type = prev_selecting_mask
+ prev_selecting_btn.mask_type = mask
+ update_masks(player_inventory.mask_inventory)
+ prev_selecting_mask = -1
+ prev_selecting_index = -1
+ prev_selecting_btn = null
+
+func next_level(level : int) -> void:
+ level_animator.play("enter")
+ level_label.text = level_names[level]
+ level_label_id.text = "Level " + str(level)
+
+func show_mask_bubble() -> void:
+ bubble_mask_anim.play("toast")
diff --git a/Scripts/UI/UI.gd.uid b/Scripts/UI/UI.gd.uid
new file mode 100644
index 0000000..e8fd98f
--- /dev/null
+++ b/Scripts/UI/UI.gd.uid
@@ -0,0 +1 @@
+uid://mauaa0rjx7lo
diff --git a/Scripts/UI/UIConnector.gd b/Scripts/UI/UIConnector.gd
new file mode 100644
index 0000000..b41e241
--- /dev/null
+++ b/Scripts/UI/UIConnector.gd
@@ -0,0 +1,32 @@
+extends Node
+
+var hud : UI
+
+var is_inv_open : bool = false
+
+func _ready() -> void:
+ hud = get_tree().get_root().get_node("Node2D/HUD")
+
+func display_health(n : int) -> void:
+ hud.display_health(n)
+
+func add_machette() -> void:
+ hud.add_machette()
+
+func remove_machette() -> void:
+ hud.remove_machette()
+
+func switch_tool() -> void:
+ hud.switch_tool()
+
+func update_masks(masks : Array[int]) -> void:
+ hud.update_masks(masks)
+
+func show_mask_bubble() -> void:
+ hud.show_mask_bubble()
+
+func death() -> void:
+ hud.death()
+
+func next_level(level : int) -> void:
+ hud.next_level(level)
diff --git a/Scripts/UI/UIConnector.gd.uid b/Scripts/UI/UIConnector.gd.uid
new file mode 100644
index 0000000..f5527a1
--- /dev/null
+++ b/Scripts/UI/UIConnector.gd.uid
@@ -0,0 +1 @@
+uid://brryfq1vrcok3
diff --git a/Scripts/Weapons/Bow.gd b/Scripts/Weapons/Bow.gd
new file mode 100644
index 0000000..09ffa3c
--- /dev/null
+++ b/Scripts/Weapons/Bow.gd
@@ -0,0 +1,22 @@
+extends Node2D
+
+@export var arrow : PackedScene
+@export var speed : float
+
+# Called when the node enters the scene tree for the first time.
+func _ready() -> void:
+ pass # Replace with function body.
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta: float) -> void:
+ pass
+
+func action() -> void:
+ var pivot = get_node("../../")
+ var new = arrow.instantiate()
+ new.init_vel = Vector2.DOWN.rotated(pivot.rotation) * speed
+ new.global_position = global_position
+ var normalised = new.init_vel.normalized()
+ new.sprite.rotation = atan2(normalised.y, normalised.x)
+ get_tree().get_root().get_node("Node2D").add_child(new)
diff --git a/Scripts/Weapons/Bow.gd.uid b/Scripts/Weapons/Bow.gd.uid
new file mode 100644
index 0000000..07daad8
--- /dev/null
+++ b/Scripts/Weapons/Bow.gd.uid
@@ -0,0 +1 @@
+uid://bfmc8st4ss7om
diff --git a/Scripts/Weapons/Melee.gd b/Scripts/Weapons/Melee.gd
new file mode 100644
index 0000000..33f2807
--- /dev/null
+++ b/Scripts/Weapons/Melee.gd
@@ -0,0 +1,35 @@
+extends Node2D
+
+@export var animator : AnimationPlayer
+@export var atk : int
+@export var area : Area2D
+@export var knock : Vector2 = Vector2(700, -300)
+@export_flags_2d_physics var mask
+@export var disable_aft_atk : bool = false
+
+func _ready() -> void:
+ area.collision_mask = mask
+
+#func _process(_delta: float) -> void:
+# if area.monitoring:
+# modulate = Color.GREEN
+# else:
+# modulate = Color.WHITE
+
+func action() -> void:
+ if animator.is_playing():
+ return
+
+ area.monitoring = true
+
+ if scale.x < 0:
+ animator.play("swing_flip")
+ else:
+ animator.play("swing")
+
+func _on_area_2d_body_entered(body:Node2D) -> void:
+ if body is Entity:
+ body.damage(atk)
+ if disable_aft_atk: area.set_deferred("monitoring", false)
+ if scale.x < 0: body.knockback = Vector2(-knock.x, knock.y)
+ else: body.knockback = knock
diff --git a/Scripts/Weapons/Melee.gd.uid b/Scripts/Weapons/Melee.gd.uid
new file mode 100644
index 0000000..7b405a9
--- /dev/null
+++ b/Scripts/Weapons/Melee.gd.uid
@@ -0,0 +1 @@
+uid://ckd00ra2lp1xo
diff --git a/Scripts/Weapons/Projectile.gd b/Scripts/Weapons/Projectile.gd
new file mode 100644
index 0000000..fa13c70
--- /dev/null
+++ b/Scripts/Weapons/Projectile.gd
@@ -0,0 +1,19 @@
+extends RigidBody2D
+
+@export var init_vel : Vector2
+@export var sprite : Node2D
+@export var atk : int
+
+func _ready() -> void:
+ linear_velocity = init_vel
+ print(linear_velocity.normalized())
+
+func _process(delta: float) -> void:
+ var normalised = linear_velocity.normalized()
+ sprite.rotation = atan2(normalised.y, normalised.x)
+
+func _on_area_2d_body_entered(body:Node2D) -> void:
+ print(body)
+ if body is Entity:
+ body.damage(atk)
+ queue_free()
diff --git a/Scripts/Weapons/Projectile.gd.uid b/Scripts/Weapons/Projectile.gd.uid
new file mode 100644
index 0000000..9bc33ba
--- /dev/null
+++ b/Scripts/Weapons/Projectile.gd.uid
@@ -0,0 +1 @@
+uid://i4wpiugtk5qi