Refactored and documented boss code.
This commit is contained in:
parent
60e32002c1
commit
8c11ee3000
1 changed files with 25 additions and 5 deletions
|
|
@ -5,18 +5,24 @@ var moves = ["slam", "wave", "water_rise", "splash"]
|
||||||
@export var big_blob : PackedScene
|
@export var big_blob : PackedScene
|
||||||
@onready var water : Water = get_tree().get_root().get_node("main/Water")
|
@onready var water : Water = get_tree().get_root().get_node("main/Water")
|
||||||
|
|
||||||
|
# How often water has been risen.
|
||||||
var risen = 0
|
var risen = 0
|
||||||
|
|
||||||
|
# Managing idle behavior between attacks.
|
||||||
var attack_ready = true
|
var attack_ready = true
|
||||||
var idle_dir : Vector2 = Vector2.ZERO
|
var idle_dir : Vector2 = Vector2.ZERO
|
||||||
var idle_dir_remaining = 0
|
var idle_dir_remaining = 0
|
||||||
var idle_move = true
|
var idle_move = true
|
||||||
var target_pos = Vector2.ZERO
|
var target_pos = Vector2.ZERO
|
||||||
|
|
||||||
|
|
||||||
var damage = 1
|
var damage = 1
|
||||||
var dead = false
|
var dead = false
|
||||||
signal grounded
|
signal grounded
|
||||||
signal slam_step_finished
|
signal slam_step_finished
|
||||||
|
|
||||||
func choose_next_move() -> String:
|
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:
|
if $EnemyHurtbox.hp <= 3 * $EnemyHurtbox.max_hp / 4 and risen == 0:
|
||||||
risen += 1
|
risen += 1
|
||||||
return "water_rise"
|
return "water_rise"
|
||||||
|
|
@ -25,10 +31,15 @@ func choose_next_move() -> String:
|
||||||
return "water_rise"
|
return "water_rise"
|
||||||
|
|
||||||
var pool = ["splash"]
|
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")
|
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):
|
if not (player.position.length() > water.radius + 900 and randf()<0.75):
|
||||||
pool.append("wave")
|
pool.append("wave")
|
||||||
|
|
||||||
return ["slam", "wave", "splash"].pick_random()
|
return ["slam", "wave", "splash"].pick_random()
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
|
|
@ -48,6 +59,7 @@ func _physics_process(delta: float) -> void:
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
|
|
||||||
func move_idle(delta : float):
|
func move_idle(delta : float):
|
||||||
|
# Pick a random target roughly above the player's head every 0.5 seconds.
|
||||||
idle_dir_remaining -= delta
|
idle_dir_remaining -= delta
|
||||||
if(idle_dir_remaining <= 0):
|
if(idle_dir_remaining <= 0):
|
||||||
target_pos = player.position + player.earth_aligner.global_from_local(Vector2.UP) * 400
|
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
|
velocity = idle_dir
|
||||||
|
|
||||||
func slam():
|
func slam():
|
||||||
|
# Move up, Slam Down, Repeat. Afterwards, linger for a moment.
|
||||||
|
# The slam destroys buildings.
|
||||||
idle_move = false
|
idle_move = false
|
||||||
velocity = up_direction * 500
|
velocity = up_direction * 500
|
||||||
await get_tree().create_timer(0.6).timeout
|
await get_tree().create_timer(0.6).timeout
|
||||||
|
|
@ -71,6 +85,8 @@ func slam():
|
||||||
attack_ready = true
|
attack_ready = true
|
||||||
|
|
||||||
func slam_step():
|
func slam_step():
|
||||||
|
# End a downslam after ground is reached or 1.5 seconds have passed.
|
||||||
|
# Then destroy buildings hit.
|
||||||
damage = 2
|
damage = 2
|
||||||
velocity = up_direction * -1500
|
velocity = up_direction * -1500
|
||||||
grounded.connect(func(): slam_step_finished.emit())
|
grounded.connect(func(): slam_step_finished.emit())
|
||||||
|
|
@ -86,21 +102,24 @@ func destroy_below():
|
||||||
if(body.has_method("destroy")): body.destroy()
|
if(body.has_method("destroy")): body.destroy()
|
||||||
|
|
||||||
func wave():
|
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 dir = randi_range(0, 1) * 2 - 1
|
||||||
var speed = 3000/water.radius_base
|
var speed = 3000 / water.radius_base
|
||||||
water.create_tsunami(angle - speed * dir*TAU/30, dir, speed)
|
water.create_tsunami(angle - speed * dir * TAU/30, dir, speed)
|
||||||
await get_tree().create_timer(0.5).timeout
|
await get_tree().create_timer(0.5).timeout
|
||||||
$Wave.play()
|
$Wave.play()
|
||||||
await get_tree().create_timer(3.5).timeout
|
await get_tree().create_timer(3.5).timeout
|
||||||
attack_ready = true
|
attack_ready = true
|
||||||
|
|
||||||
func water_rise():
|
func water_rise():
|
||||||
|
# Increase the water level by 1 room height.
|
||||||
water.rise_water()
|
water.rise_water()
|
||||||
await get_tree().create_timer(5).timeout
|
await get_tree().create_timer(5).timeout
|
||||||
attack_ready = true
|
attack_ready = true
|
||||||
|
|
||||||
func splash():
|
func splash():
|
||||||
|
# Form four small blobs around the player which merge into one.
|
||||||
var blob_instance = big_blob.instantiate()
|
var blob_instance = big_blob.instantiate()
|
||||||
get_tree().get_root().get_node("main").add_child(blob_instance)
|
get_tree().get_root().get_node("main").add_child(blob_instance)
|
||||||
blob_instance.position = player.position
|
blob_instance.position = player.position
|
||||||
|
|
@ -110,13 +129,14 @@ func splash():
|
||||||
|
|
||||||
|
|
||||||
func die():
|
func die():
|
||||||
|
# Clear everything else, then wait for Audio Players to make sure sounds are not cut off.
|
||||||
dead = true
|
dead = true
|
||||||
for child in get_children():
|
for child in get_children():
|
||||||
if not child is AudioStreamPlayer2D:
|
if not child is AudioStreamPlayer2D:
|
||||||
child.queue_free()
|
child.queue_free()
|
||||||
$DeathSound.play()
|
$DeathSound.play()
|
||||||
await $DeathSound.finished
|
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")
|
get_tree().change_scene_to_file("res://ui/victory_screen/victory_screen.tscn")
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue