extends KinematicBody2D enum State {DEAD, STAND, FORWARD, BACK, DUCK, BEAM} const Bullet = preload("res://objects/enemy/2600_bullet.tscn") const SmallExplosion = preload("res://objects/enemy/boss/2600_small_explosion.tscn") export var hp: float = 100.0 export var shot_speed: float = 50.0 export var move_speed: float = 30.0 export var safe_from_breath: bool = false export var make_explosions: bool = false export var explosion_rect: Rect2 export var famira_path: NodePath var state: int = State.STAND var knockback: float = 0.0 onready var bullet_positions = $"%BulletPositions" onready var anims: AnimationPlayer = $"%AnimationPlayer" onready var head_sprite = $"%Head" func _physics_process(delta: float) -> void: match state: State.DEAD: return State.STAND: if Input.is_action_pressed("move_down"): state = State.DUCK anims.play("Duck") elif Input.is_action_pressed("move_right"): state = State.FORWARD anims.play("Walk") elif Input.is_action_pressed("move_left"): state = State.BACK anims.play("Walk", -1.0, -1.0, true) State.DUCK: if not Input.is_action_pressed("move_down") and anims.current_animation.empty(): anims.play("UnDuck") State.FORWARD: move_and_slide(Vector2(move_speed, 0.0)) State.BACK: move_and_slide(Vector2(-move_speed, 0.0)) move_and_slide(Vector2(-knockback, 0.0)) knockback *= pow(0.1, delta) func _input(event: InputEvent) -> void: if state == State.DEAD: return if event.is_action_pressed("shoot") and (state == State.STAND or state == State.FORWARD or state == State.BACK): shoot() if event.is_action_pressed("jump") and state == State.STAND: beam() func shoot() -> void: Audio.play_sound(Audio.a_bullet_barrage,Audio.ac_collectible) for pos in bullet_positions.get_children(): var bullet = Bullet.instance() bullet.global_position = pos.global_position bullet.direction = Vector2.LEFT.rotated(pos.rotation) bullet.speed = shot_speed get_parent().add_child(bullet) func beam() -> void: state = State.BEAM anims.play("Beam") func hurt(amount: float, can_duck: bool = false) -> void: if can_duck and state == State.DUCK: return hp -= amount if state != State.DEAD and hp <= 0.0: state = State.DEAD anims.play("die") func knock_back(amount: float, can_duck: bool = false) -> void: if can_duck and state == State.DUCK: return knockback += amount func _play_laser_sound(play: bool): var famira = get_node(famira_path) if play: if famira.has_method("start_push"): famira.start_push() Audio.play_sound(Audio.a_rainbow_laser,Audio.ac_collectible) else: if famira.has_method("stop_push"): famira.stop_push() Audio.ac_collectible.playing = false func _play_charge_sound(play: bool): if play: Audio.play_sound(Audio.a_2600_charge,Audio.ac_collectible) else: Audio.ac_collectible.playing = false func _spawn_explosions() -> void: while make_explosions: yield(get_tree().create_timer(randf() * 0.5, false), "timeout") var explosion = SmallExplosion.instance() explosion.position = Vector2( rand_range(explosion_rect.position.x, explosion_rect.end.x), rand_range(explosion_rect.position.y, explosion_rect.end.y) ) add_child(explosion) func _on_animation_finished(anim_name: String) -> void: match anim_name: "UnDuck": state = State.STAND "Walk": if state == State.FORWARD and Input.is_action_pressed("move_right"): anims.play("Walk") elif state == State.BACK and Input.is_action_pressed("move_left"): anims.play("Walk", -1.0, -1.0, true) else: state = State.STAND "Beam": state = State.STAND "die": pass