class_name Crawler extends Entity @onready var player = get_parent().get_parent().get_node("Player"); @onready var sprite = $AnimatedSprite2D @onready var main_collider = $CollisionShape2D @onready var whip = $WhipArea @onready var speed_mult = 0 @onready var is_dying = false @onready var explosion_sfx = $ExplosionSFX @onready var death_timer = $DeathTimer @onready var hurting = false @onready var hurt_timer = $HurtTimer @onready var attack_timer = $AttackTimer @onready var recharge_timer = $Recharge ## Crawl towards the player but stay within striking distance and not super close const HEALTH = 45 const SPEED_MULTIPLIER = 50 const ATTACK_DAMAGE = 20 var death_timer_started = false var attacking = true func _init() -> void: super._init(HEALTH, SPEED_MULTIPLIER, ATTACK_DAMAGE) func _ready() -> void: whip.visible = false func face_player(): var player_position = player.global_position var crawler_position = global_position if player_position.x > crawler_position.x and not sprite.flip_h: sprite.flip_h = true main_collider.position.x -= 62 position.x += 62 whip.position.x += 10 elif player_position.x < crawler_position.x and sprite.flip_h: sprite.flip_h = false main_collider.position.x += 62 position.x -= 62 whip.position.x -= 10 func _physics_process(delta: float) -> void: var distanceToPlayer = global_position.distance_to(player.global_position) var desiredDistance = 70 if health <= 0 and !death_timer_started: is_dying = true death_timer_started = true death_timer.start() if !is_dying: if !hurting: if sprite.flip_h: desiredDistance -= 69 face_player() if distanceToPlayer > desiredDistance: velocity.x = speed * speed_mult face_player() if not sprite.flip_h: velocity.x *= -1 sprite.play("walk") else: if recharge_timer.is_stopped(): attacking = true whip.visible = true whip.connect("body_entered", whip_hit) attack_timer.start() if attacking and !attack_timer.is_stopped(): velocity.x = 0 sprite.play("Whip") elif attacking and attack_timer.is_stopped(): recharge_timer.start() whip.visible = false whip.disconnect("body_entered", whip_hit) attacking = false if hurt_timer.is_stopped(): hurting = false else: sprite.play("jump back") move_and_slide() else: sprite.play("death") explosion_sfx.play() speed_mult = 0 if death_timer.is_stopped(): queue_free() func charge() -> void: speed_mult = 1 func hurt_anim(): hurting = true hurt_timer.start() func whip_hit(node: Node) -> void: if node is Player: node.health -= ATTACK_DAMAGE node.take_knockback(50) if node.has_method("hurt_anim"): node.call("hurt_anim")