diff options
Diffstat (limited to 'Scripts')
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 |