diff --git a/enemies/boss/boss.gd b/enemies/boss/boss.gd index b013b8e..a0472f7 100644 --- a/enemies/boss/boss.gd +++ b/enemies/boss/boss.gd @@ -5,18 +5,24 @@ var moves = ["slam", "wave", "water_rise", "splash"] @export var big_blob : PackedScene @onready var water : Water = get_tree().get_root().get_node("main/Water") +# How often water has been risen. var risen = 0 + +# Managing idle behavior between attacks. var attack_ready = true var idle_dir : Vector2 = Vector2.ZERO var idle_dir_remaining = 0 var idle_move = true var target_pos = Vector2.ZERO + + var damage = 1 var dead = false signal grounded signal slam_step_finished func choose_next_move() -> String: + # Water rises at 75% and 50% of remaining HP. if $EnemyHurtbox.hp <= 3 * $EnemyHurtbox.max_hp / 4 and risen == 0: risen += 1 return "water_rise" @@ -25,10 +31,15 @@ func choose_next_move() -> String: return "water_rise" var pool = ["splash"] - if not (position.length() - water.radius < 300 and randf()<0.75): + + # Heavily decrease slam probability if boss height is low. + if not (position.length() - water.radius < 450 and randf()<0.75): pool.append("slam") + + # Heavily decrease wave probability if player is very high up. if not (player.position.length() > water.radius + 900 and randf()<0.75): pool.append("wave") + return ["slam", "wave", "splash"].pick_random() func _process(_delta: float) -> void: @@ -48,6 +59,7 @@ func _physics_process(delta: float) -> void: move_and_slide() func move_idle(delta : float): + # Pick a random target roughly above the player's head every 0.5 seconds. idle_dir_remaining -= delta if(idle_dir_remaining <= 0): target_pos = player.position + player.earth_aligner.global_from_local(Vector2.UP) * 400 @@ -57,6 +69,8 @@ func move_idle(delta : float): velocity = idle_dir func slam(): + # Move up, Slam Down, Repeat. Afterwards, linger for a moment. + # The slam destroys buildings. idle_move = false velocity = up_direction * 500 await get_tree().create_timer(0.6).timeout @@ -71,6 +85,8 @@ func slam(): attack_ready = true func slam_step(): + # End a downslam after ground is reached or 1.5 seconds have passed. + # Then destroy buildings hit. damage = 2 velocity = up_direction * -1500 grounded.connect(func(): slam_step_finished.emit()) @@ -86,21 +102,24 @@ func destroy_below(): if(body.has_method("destroy")): body.destroy() func wave(): - var angle = atan2(player.position.y, player.position.x) + # Raise a wave from the water at the boundary of the screen and move it towards the center. + var angle = player.position.angle var dir = randi_range(0, 1) * 2 - 1 - var speed = 3000/water.radius_base - water.create_tsunami(angle - speed * dir*TAU/30, dir, speed) + var speed = 3000 / water.radius_base + water.create_tsunami(angle - speed * dir * TAU/30, dir, speed) await get_tree().create_timer(0.5).timeout $Wave.play() await get_tree().create_timer(3.5).timeout attack_ready = true func water_rise(): + # Increase the water level by 1 room height. water.rise_water() await get_tree().create_timer(5).timeout attack_ready = true func splash(): + # Form four small blobs around the player which merge into one. var blob_instance = big_blob.instantiate() get_tree().get_root().get_node("main").add_child(blob_instance) blob_instance.position = player.position @@ -110,13 +129,14 @@ func splash(): func die(): + # Clear everything else, then wait for Audio Players to make sure sounds are not cut off. dead = true for child in get_children(): if not child is AudioStreamPlayer2D: child.queue_free() $DeathSound.play() await $DeathSound.finished - await get_tree().create_timer(3).timeout + await get_tree().create_timer(1).timeout get_tree().change_scene_to_file("res://ui/victory_screen/victory_screen.tscn") queue_free()