last init

This commit is contained in:
Marek
2026-03-29 16:05:31 +02:00
commit aa2c182534
53 changed files with 1419 additions and 0 deletions

38
scripts/enemy/enemy.gd Normal file
View File

@@ -0,0 +1,38 @@
extends CharacterBody3D
enum State { IDLE, CHASE, ATTACK, RETURN }
var state: int = State.IDLE
var target: Node3D = null
var spawn_position: Vector3
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
@onready var health: Node = $Health
func _ready() -> void:
spawn_position = global_position
add_to_group("enemies")
EventBus.entity_died.connect(_on_entity_died)
func _on_entity_died(entity: Node) -> void:
if entity == self:
queue_free()
elif entity == target:
target = null
state = State.RETURN
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y -= gravity * delta
move_and_slide()
func _on_detection_area_body_entered(body: Node3D) -> void:
if body is CharacterBody3D and body.name == "Player":
target = body
state = State.CHASE
EventBus.enemy_engaged.emit(self, body)
func _on_detection_area_body_exited(body: Node3D) -> void:
if body == target and state == State.CHASE:
state = State.RETURN
target = null

View File

@@ -0,0 +1 @@
uid://bwi75jx0agktd

View File

@@ -0,0 +1,26 @@
extends Node
const ATTACK_RANGE := 2.0
const ATTACK_COOLDOWN := 1.5
const ATTACK_DAMAGE := 5.0
var attack_timer := 0.0
@onready var enemy: CharacterBody3D = get_parent()
func _physics_process(delta: float) -> void:
attack_timer -= delta
if enemy.state != enemy.State.ATTACK:
return
if not is_instance_valid(enemy.target):
enemy.state = enemy.State.RETURN
return
var dist := enemy.global_position.distance_to(enemy.target.global_position)
if dist > ATTACK_RANGE:
enemy.state = enemy.State.CHASE
return
if attack_timer <= 0:
attack_timer = ATTACK_COOLDOWN
EventBus.damage_requested.emit(enemy, enemy.target, ATTACK_DAMAGE)
enemy.velocity.x = 0
enemy.velocity.z = 0

View File

@@ -0,0 +1 @@
uid://ct4u62xalrjyo

View File

@@ -0,0 +1,22 @@
extends Sprite3D
@onready var viewport: SubViewport = $SubViewport
@onready var health_bar: ProgressBar = $SubViewport/HealthBar
@onready var shield_bar: ProgressBar = $SubViewport/ShieldBar
@onready var border: ColorRect = $SubViewport/Border
@onready var health: Node = get_parent().get_node("Health")
@onready var shield: Node = get_parent().get_node("Shield")
func _ready() -> void:
texture = viewport.get_texture()
health_bar.max_value = health.max_health
shield_bar.max_value = shield.max_shield
border.visible = false
EventBus.target_changed.connect(_on_target_changed)
func _process(_delta: float) -> void:
health_bar.value = health.current_health
shield_bar.value = shield.current_shield
func _on_target_changed(_player: Node, target: Node) -> void:
border.visible = (target == get_parent())

View File

@@ -0,0 +1 @@
uid://dwqx03nfypa7u

View File

@@ -0,0 +1,52 @@
extends Node
const SPEED := 3.0
const LEASH_RANGE := 15.0
const ATTACK_RANGE := 2.0
@onready var enemy: CharacterBody3D = get_parent()
@onready var nav_agent: NavigationAgent3D = get_parent().get_node("NavigationAgent3D")
func _physics_process(_delta: float) -> void:
match enemy.state:
enemy.State.IDLE:
enemy.velocity.x = 0
enemy.velocity.z = 0
enemy.State.CHASE:
_chase()
enemy.State.RETURN:
_return_to_spawn()
func _chase() -> void:
if not is_instance_valid(enemy.target):
enemy.state = enemy.State.RETURN
return
var dist_to_spawn := enemy.global_position.distance_to(enemy.spawn_position)
if dist_to_spawn > LEASH_RANGE:
enemy.state = enemy.State.RETURN
enemy.target = null
return
var dist_to_target := enemy.global_position.distance_to(enemy.target.global_position)
if dist_to_target <= ATTACK_RANGE:
enemy.state = enemy.State.ATTACK
return
nav_agent.target_position = enemy.target.global_position
var next_pos := nav_agent.get_next_path_position()
var direction := (next_pos - enemy.global_position).normalized()
direction.y = 0
enemy.velocity.x = direction.x * SPEED
enemy.velocity.z = direction.z * SPEED
func _return_to_spawn() -> void:
var dist := enemy.global_position.distance_to(enemy.spawn_position)
if dist < 1.0:
enemy.state = enemy.State.IDLE
enemy.velocity.x = 0
enemy.velocity.z = 0
return
nav_agent.target_position = enemy.spawn_position
var next_pos := nav_agent.get_next_path_position()
var direction := (next_pos - enemy.global_position).normalized()
direction.y = 0
enemy.velocity.x = direction.x * SPEED
enemy.velocity.z = direction.z * SPEED

View File

@@ -0,0 +1 @@
uid://tnx6rbnnngn