This commit is contained in:
Marek Lenczewski
2026-04-04 00:00:15 +02:00
parent 3488856b91
commit f1d34ebf1d
104 changed files with 1912 additions and 1789 deletions

View File

@@ -1,5 +0,0 @@
extends "res://scenes/enemy/enemy.gd"
func _ready() -> void:
super._ready()
add_to_group("boss")

View File

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

View File

@@ -1,108 +0,0 @@
[gd_scene load_steps=6 format=3]
[ext_resource type="Script" path="res://scenes/enemy/boss.gd" id="1"]
[ext_resource type="Script" path="res://scenes/healthbar.gd" id="4"]
[ext_resource type="Script" path="res://scenes/enemy/enemy_movement.gd" id="5"]
[ext_resource type="Resource" path="res://scenes/enemy/boss_stats.tres" id="8"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1"]
radius = 0.6
height = 2.0
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_2"]
radius = 0.6
height = 2.0
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_health_bg"]
bg_color = Color(0.3, 0.1, 0.1, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_health_fill"]
bg_color = Color(0.2, 0.8, 0.2, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_shield_bg"]
bg_color = Color(0.1, 0.1, 0.3, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_shield_fill"]
bg_color = Color(0.2, 0.5, 0.9, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.6, 0.1, 0.6, 1)
[sub_resource type="SphereMesh" id="SphereMesh_1"]
radius = 0.75
height = 1.5
material = SubResource("StandardMaterial3D_1")
[sub_resource type="SphereShape3D" id="SphereShape3D_1"]
radius = 8.0
[node name="Boss" type="CharacterBody3D"]
script = ExtResource("1")
stats = ExtResource("8")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
shape = SubResource("CapsuleShape3D_1")
[node name="Mesh" type="MeshInstance3D" parent="."]
transform = Transform3D(1.5, 0, 0, 0, 1.5, 0, 0, 0, 1.5, 0, 0, 0)
mesh = SubResource("SphereMesh_1")
[node name="HitArea" type="Area3D" parent="."]
collision_layer = 4
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="HitArea"]
shape = SubResource("CapsuleShape3D_2")
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."]
[node name="EnemyMovement" type="Node" parent="."]
script = ExtResource("5")
[node name="DetectionArea" type="Area3D" parent="."]
collision_layer = 0
collision_mask = 1
monitoring = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="DetectionArea"]
shape = SubResource("SphereShape3D_1")
[node name="Healthbar" type="Sprite3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.0, 0)
billboard = 1
pixel_size = 0.01
script = ExtResource("4")
[node name="SubViewport" type="SubViewport" parent="Healthbar"]
transparent_bg = true
size = Vector2i(104, 29)
[node name="Border" type="ColorRect" parent="Healthbar/SubViewport"]
offset_right = 104.0
offset_bottom = 29.0
color = Color(1, 0.9, 0.2, 1)
[node name="HealthBar" type="ProgressBar" parent="Healthbar/SubViewport"]
offset_left = 2.0
offset_top = 2.0
offset_right = 102.0
offset_bottom = 12.0
theme_override_styles/background = SubResource("StyleBoxFlat_health_bg")
theme_override_styles/fill = SubResource("StyleBoxFlat_health_fill")
max_value = 500.0
value = 500.0
show_percentage = false
[node name="ShieldBar" type="ProgressBar" parent="Healthbar/SubViewport"]
offset_left = 2.0
offset_top = 15.0
offset_right = 102.0
offset_bottom = 27.0
theme_override_styles/background = SubResource("StyleBoxFlat_shield_bg")
theme_override_styles/fill = SubResource("StyleBoxFlat_shield_fill")
max_value = 100.0
value = 100.0
show_percentage = false
[connection signal="body_entered" from="DetectionArea" to="." method="_on_detection_area_body_entered"]
[connection signal="body_exited" from="DetectionArea" to="." method="_on_detection_area_body_exited"]

View File

@@ -1 +1 @@
uid://bio01w2gd5e7q
uid://dlawq281oesnf

11
scenes/enemy/detection.gd Normal file
View File

@@ -0,0 +1,11 @@
extends Node
@onready var entity: CharacterBody3D = get_parent()
func _on_detection_area_body_entered(body: Node3D) -> void:
if body is CharacterBody3D and body.name == "Player":
EventBus.enemy_detected.emit(entity, body)
func _on_detection_area_body_exited(body: Node3D) -> void:
if body is CharacterBody3D and body.name == "Player":
EventBus.enemy_lost.emit(entity, body)

View File

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

View File

@@ -1,37 +0,0 @@
extends CharacterBody3D
enum State { IDLE, CHASE, ATTACK, RETURN }
@export var stats: BaseStats
var state: int = State.IDLE
var target: Node3D = null
var spawn_position: Vector3
var portal: Node3D = null
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
func _ready() -> void:
spawn_position = global_position
add_to_group("enemies")
Stats.register(self, stats)
EventBus.entity_died.connect(_on_entity_died)
func _exit_tree() -> void:
Stats.deregister(self)
func _on_entity_died(entity: Node) -> void:
if entity == self:
queue_free()
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":
EventBus.enemy_detected.emit(self, body)
func _on_detection_area_body_exited(body: Node3D) -> void:
if body is CharacterBody3D and body.name == "Player":
EventBus.enemy_lost.emit(self, body)

View File

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

View File

@@ -1,18 +1,26 @@
[gd_scene load_steps=6 format=3]
[gd_scene format=3 uid="uid://db8pa55ev4l4a"]
[ext_resource type="Script" path="res://scenes/enemy/enemy.gd" id="1"]
[ext_resource type="Script" path="res://scenes/healthbar.gd" id="4"]
[ext_resource type="Script" path="res://scenes/enemy/enemy_movement.gd" id="5"]
[ext_resource type="Resource" path="res://scenes/enemy/enemy_stats.tres" id="8"]
[ext_resource type="Script" uid="uid://vy6hyqok0p8b" path="res://scenes/enemy/init.gd" id="1"]
[ext_resource type="Script" uid="uid://b07aajhufqvb3" path="res://scenes/enemy/detection.gd" id="2"]
[ext_resource type="Resource" uid="uid://cj1shmjwf0xeo" path="res://scenes/enemy/enemy_stats.tres" id="8"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1"]
radius = 0.4
height = 1.5
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.8, 0.1, 0.1, 1)
[sub_resource type="SphereMesh" id="SphereMesh_1"]
material = SubResource("StandardMaterial3D_1")
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_2"]
radius = 0.4
height = 1.5
[sub_resource type="SphereShape3D" id="SphereShape3D_1"]
radius = 10.0
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_health_bg"]
bg_color = Color(0.3, 0.1, 0.1, 1)
@@ -25,74 +33,58 @@ bg_color = Color(0.1, 0.1, 0.3, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_shield_fill"]
bg_color = Color(0.2, 0.5, 0.9, 1)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1"]
albedo_color = Color(0.8, 0.1, 0.1, 1)
[sub_resource type="SphereMesh" id="SphereMesh_1"]
radius = 0.5
height = 1.0
material = SubResource("StandardMaterial3D_1")
[sub_resource type="SphereShape3D" id="SphereShape3D_1"]
radius = 10.0
[node name="Enemy" type="CharacterBody3D"]
[node name="Enemy" type="CharacterBody3D" unique_id=1724620529]
script = ExtResource("1")
stats = ExtResource("8")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1011138038]
shape = SubResource("CapsuleShape3D_1")
[node name="Mesh" type="MeshInstance3D" parent="."]
[node name="Mesh" type="MeshInstance3D" parent="." unique_id=1598094615]
mesh = SubResource("SphereMesh_1")
[node name="HitArea" type="Area3D" parent="."]
[node name="HitArea" type="Area3D" parent="." unique_id=893463784]
collision_layer = 4
collision_mask = 0
[node name="CollisionShape3D" type="CollisionShape3D" parent="HitArea"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="HitArea" unique_id=984781962]
shape = SubResource("CapsuleShape3D_2")
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."]
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="." unique_id=440641945]
[node name="EnemyMovement" type="Node" parent="."]
script = ExtResource("5")
[node name="Detection" type="Node" parent="." unique_id=534240144]
script = ExtResource("2")
[node name="DetectionArea" type="Area3D" parent="."]
[node name="DetectionArea" type="Area3D" parent="." unique_id=1955178598]
collision_layer = 0
collision_mask = 1
monitoring = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="DetectionArea"]
[node name="CollisionShape3D" type="CollisionShape3D" parent="DetectionArea" unique_id=557461347]
shape = SubResource("SphereShape3D_1")
[node name="Healthbar" type="Sprite3D" parent="."]
[node name="Healthbar" type="Sprite3D" parent="." unique_id=1008728031]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
billboard = 1
pixel_size = 0.01
script = ExtResource("4")
[node name="SubViewport" type="SubViewport" parent="Healthbar"]
[node name="SubViewport" type="SubViewport" parent="Healthbar" unique_id=1219060718]
transparent_bg = true
size = Vector2i(104, 29)
[node name="Border" type="ColorRect" parent="Healthbar/SubViewport"]
[node name="Border" type="ColorRect" parent="Healthbar/SubViewport" unique_id=848146848]
offset_right = 104.0
offset_bottom = 29.0
color = Color(1, 0.9, 0.2, 1)
[node name="HealthBar" type="ProgressBar" parent="Healthbar/SubViewport"]
[node name="HealthBar" type="ProgressBar" parent="Healthbar/SubViewport" unique_id=1206434403]
offset_left = 2.0
offset_top = 2.0
offset_right = 102.0
offset_bottom = 12.0
theme_override_styles/background = SubResource("StyleBoxFlat_health_bg")
theme_override_styles/fill = SubResource("StyleBoxFlat_health_fill")
max_value = 100.0
value = 100.0
show_percentage = false
[node name="ShieldBar" type="ProgressBar" parent="Healthbar/SubViewport"]
[node name="ShieldBar" type="ProgressBar" parent="Healthbar/SubViewport" unique_id=1891108036]
offset_left = 2.0
offset_top = 15.0
offset_right = 102.0
@@ -103,5 +95,5 @@ max_value = 50.0
value = 50.0
show_percentage = false
[connection signal="body_entered" from="DetectionArea" to="." method="_on_detection_area_body_entered"]
[connection signal="body_exited" from="DetectionArea" to="." method="_on_detection_area_body_exited"]
[connection signal="body_entered" from="DetectionArea" to="Detection" method="_on_detection_area_body_entered"]
[connection signal="body_exited" from="DetectionArea" to="Detection" method="_on_detection_area_body_exited"]

View File

@@ -1,62 +0,0 @@
extends Node
const SPEED := 3.0
const ATTACK_RANGE := 2.0
const REGEN_FAST := 0.10
const REGEN_SLOW := 0.01
@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(delta)
func _chase() -> void:
if not is_instance_valid(enemy.target):
enemy.state = enemy.State.RETURN
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(delta: float) -> 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
_regenerate(delta)
func _regenerate(delta: float) -> void:
var health: float = Stats.get_stat(enemy, "health")
var max_health: float = Stats.get_stat(enemy, "max_health")
if health == null or max_health == null:
return
if health < max_health:
var rate: float = REGEN_FAST
if health >= max_health * 0.99:
rate = REGEN_SLOW
health = min(health + max_health * rate * delta, max_health)
Stats.set_stat(enemy, "health", health)
EventBus.health_changed.emit(enemy, health, max_health)

View File

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

30
scenes/enemy/init.gd Normal file
View File

@@ -0,0 +1,30 @@
extends CharacterBody3D
@export var stats: EnemyStats
var gravity: float = ProjectSettings.get_setting("physics/3d/default_gravity")
func _ready() -> void:
add_to_group("enemies")
if is_in_group("boss"):
BossData.register(self, stats)
BossData.set_stat(self, "spawn_position", global_position)
else:
EnemyData.register(self, stats)
EnemyData.set_stat(self, "spawn_position", global_position)
EventBus.entity_died.connect(_on_entity_died)
func _exit_tree() -> void:
if is_in_group("boss"):
BossData.deregister(self)
else:
EnemyData.deregister(self)
func _on_entity_died(entity: Node) -> void:
if entity == self:
queue_free()
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity.y -= gravity * delta
move_and_slide()

1
scenes/enemy/init.gd.uid Normal file
View File

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