cave-of-dreams/scripts/enemies/slime.gd

112 lines
2.3 KiB
GDScript3
Raw Normal View History

2026-05-09 17:18:11 +00:00
extends CharacterBody3D
const SPEED = 2.5
const JUMP_VELOCITY = 4.5
2026-05-14 15:57:50 +00:00
var face_rotation = 0
2026-05-09 17:18:11 +00:00
var face_left = false
var health = 35
2026-05-09 17:18:11 +00:00
var mid_knockback = false
@onready var player = get_parent().get_node("Player")
enum {
STATE_IDLE,
STATE_JUMP,
STATE_LEAP,
STATE_HIT,
STATE_DEATH
2026-05-09 17:18:11 +00:00
}
var state = STATE_IDLE
var state_timer = 1
var iframes = 0
@onready var game = get_parent()
@onready var camera = game.get_node("PlayerCamera")
func on_knockback() -> void:
state_timer = 99999
state = STATE_HIT
$Body/Animator.play("leap")
func _ready() -> void:
$Body/Animator.play("idle")
func _physics_process(delta: float) -> void:
2026-05-14 15:57:50 +00:00
face_rotation = player.get_node("DreamerBody").global_rotation.y
if (health <= 0) and (state != STATE_DEATH):
state = STATE_DEATH
state_timer = 0.75
$Body/Animator.play("jump")
2026-05-09 17:18:11 +00:00
state_timer -= delta
if state_timer < 0:
if state == STATE_IDLE:
state = STATE_JUMP
state_timer = 0.6
$Body/Animator.play("jump")
elif state == STATE_JUMP:
state = STATE_LEAP
state_timer = 99999
$Body/Animator.play("leap")
velocity = global_position.direction_to(player.global_position) * 3
velocity.y = 3
elif state == STATE_DEATH:
queue_free()
2026-05-09 17:18:11 +00:00
elif (state == STATE_LEAP) and is_on_floor():
state = STATE_IDLE
state_timer = randf_range(0.8, 1.5)
$Body/Animator.play("idle")
elif (state == STATE_HIT) and is_on_floor():
state = STATE_IDLE
state_timer = 0.5
2026-05-09 17:18:11 +00:00
$Body/Animator.play("idle")
elif (state == STATE_DEATH):
pass
2026-05-09 17:18:11 +00:00
if iframes > 0:
iframes -= delta
$Body.modulate.a = 0.5
else:
$Body.modulate.a = 1
#wa$HealthLabel.text = str(health)
2026-05-09 17:18:11 +00:00
if not is_on_floor():
velocity += get_gravity() * delta
var viewport_half = (get_viewport().get_visible_rect().size / 2.0)
var player_position = camera.unproject_position(global_transform.origin)
if face_left:
$Body.rotation.y = face_rotation + deg_to_rad(180)
else:
$Body.rotation.y = face_rotation
if is_on_floor() and not mid_knockback:
velocity.x = move_toward(velocity.x, 0, delta * 16)
velocity.z = move_toward(velocity.z, 0, delta * 16)
2026-05-09 17:18:11 +00:00
move_and_slide()
if player in $HitCollision.get_overlapping_bodies():
if player.iframes <= 0:
player.health -= 20
player.on_hit(self)
2026-05-09 17:18:11 +00:00
if mid_knockback: mid_knockback = false
$Shadow.global_position.y = $Floorcast.get_collision_point().y + 0.01