This commit is contained in:
Marek Lenczewski
2026-04-01 22:53:28 +02:00
parent b236cd52cb
commit e76c66eda6
70 changed files with 1016 additions and 732 deletions

View File

@@ -1,45 +0,0 @@
extends Node
@export var stats: EntityStats
var max_health: float
var health_regen: float
var current_health: float
func _ready() -> void:
max_health = stats.max_health
health_regen = stats.health_regen
current_health = max_health
EventBus.damage_requested.connect(_on_damage_requested)
EventBus.heal_requested.connect(_on_heal_requested)
func _process(delta: float) -> void:
if current_health > 0 and current_health < max_health and health_regen > 0:
current_health = min(current_health + health_regen * delta, max_health)
EventBus.health_changed.emit(get_parent(), current_health, max_health)
func _on_damage_requested(attacker: Node, target: Node, amount: float) -> void:
if target != get_parent():
return
var remaining: float = amount
var shield: Node = get_parent().get_node_or_null("Shield")
if shield:
remaining = shield.absorb(remaining)
EventBus.damage_dealt.emit(attacker, get_parent(), amount)
if remaining > 0:
take_damage(remaining, attacker)
func take_damage(amount: float, attacker: Node) -> void:
current_health -= amount
if current_health <= 0:
current_health = 0
EventBus.health_changed.emit(get_parent(), current_health, max_health)
if current_health <= 0:
EventBus.entity_died.emit(get_parent())
func heal(amount: float) -> void:
current_health = min(current_health + amount, max_health)
EventBus.health_changed.emit(get_parent(), current_health, max_health)
func _on_heal_requested(healer: Node, target: Node, amount: float) -> void:
if target == get_parent():
heal(amount)

View File

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

View File

@@ -3,38 +3,55 @@ extends Sprite3D
@onready var viewport: SubViewport = $SubViewport
@onready var health_bar: ProgressBar = $SubViewport/HealthBar
@onready var border: ColorRect = $SubViewport/Border
@onready var health: Node = get_parent().get_node("Health")
@onready var parent_node: Node = get_parent()
var shield: Node = null
var shield_bar: ProgressBar = null
var style_normal: StyleBoxFlat
var style_aggro: StyleBoxFlat
func _ready() -> void:
texture = viewport.get_texture()
health_bar.max_value = health.max_health
shield = get_parent().get_node_or_null("Shield")
shield_bar = $SubViewport.get_node_or_null("ShieldBar")
if shield and shield_bar:
shield_bar.max_value = shield.max_shield
elif shield_bar:
shield_bar.visible = false
border.visible = false
style_normal = health_bar.get_theme_stylebox("fill").duplicate()
style_aggro = style_normal.duplicate()
style_aggro.bg_color = Color(0.2, 0.4, 0.9, 1)
EventBus.target_changed.connect(_on_target_changed)
EventBus.health_changed.connect(_on_health_changed)
EventBus.shield_changed.connect(_on_shield_changed)
_init_bars()
func _init_bars() -> void:
var max_health: Variant = Stats.get_stat(parent_node, "max_health")
if max_health != null:
health_bar.max_value = max_health
health_bar.value = Stats.get_stat(parent_node, "health")
var max_shield: Variant = Stats.get_stat(parent_node, "max_shield")
if shield_bar:
if max_shield != null and max_shield > 0:
shield_bar.max_value = max_shield
shield_bar.value = Stats.get_stat(parent_node, "shield")
else:
shield_bar.visible = false
func _process(_delta: float) -> void:
health_bar.value = health.current_health
if shield and shield_bar:
shield_bar.value = shield.current_shield
var player: Node = get_tree().get_first_node_in_group("player")
if player and "target" in parent_node and parent_node.target == player:
health_bar.add_theme_stylebox_override("fill", style_aggro)
else:
health_bar.add_theme_stylebox_override("fill", style_normal)
func _on_health_changed(entity: Node, current: float, max_val: float) -> void:
if entity != parent_node:
return
health_bar.max_value = max_val
health_bar.value = current
func _on_shield_changed(entity: Node, current: float, max_val: float) -> void:
if entity != parent_node or shield_bar == null:
return
shield_bar.max_value = max_val
shield_bar.value = current
func _on_target_changed(_player: Node, target: Node) -> void:
border.visible = (target == get_parent())

View File

@@ -1,57 +0,0 @@
extends Node
@export var stats: EntityStats
var max_shield: float
var regen_delay: float
var regen_time: float
var current_shield: float
var regen_timer := 0.0
var base_max_shield: float
func _ready() -> void:
max_shield = stats.max_shield
base_max_shield = max_shield
regen_delay = stats.shield_regen_delay
regen_time = stats.shield_regen_time
current_shield = max_shield
EventBus.role_changed.connect(_on_role_changed)
func _process(delta: float) -> void:
if max_shield <= 0:
return
if current_shield < max_shield:
regen_timer += delta
if regen_timer >= regen_delay:
current_shield += (max_shield / regen_time) * delta
if current_shield >= max_shield:
current_shield = max_shield
EventBus.shield_regenerated.emit(get_parent())
EventBus.shield_changed.emit(get_parent(), current_shield, max_shield)
func _on_role_changed(_player: Node, _role_type: int) -> void:
if get_parent() != _player:
return
var role: Node = get_parent().get_node_or_null("Role")
if not role:
return
var ability_set: AbilitySet = role.get_ability_set()
if not ability_set:
return
max_shield = base_max_shield
for ability in ability_set.abilities:
if ability and ability.type == Ability.Type.PASSIVE and ability.passive_stat == "shield":
max_shield = base_max_shield * (1.0 + ability.damage / 100.0)
current_shield = min(current_shield, max_shield)
EventBus.shield_changed.emit(get_parent(), current_shield, max_shield)
func absorb(amount: float) -> float:
if current_shield <= 0:
return amount
regen_timer = 0.0
var absorbed: float = min(amount, current_shield)
current_shield -= absorbed
if current_shield <= 0:
EventBus.shield_broken.emit(get_parent())
EventBus.shield_changed.emit(get_parent(), current_shield, max_shield)
return amount - absorbed

View File

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

View File

@@ -1,44 +0,0 @@
extends Node
@export var spawn_scene: PackedScene
@export var spawn_count := 3
@export var thresholds: Array[float] = [0.85, 0.70, 0.55, 0.40, 0.25, 0.10]
var triggered: Array[bool] = []
@onready var parent: Node3D = get_parent()
@onready var health: Node = get_parent().get_node("Health")
func _ready() -> void:
triggered.resize(thresholds.size())
triggered.fill(false)
func _process(_delta: float) -> void:
if not spawn_scene or health.current_health <= 0:
return
var ratio: float = health.current_health / health.max_health
for i in range(thresholds.size()):
if not triggered[i] and ratio <= thresholds[i]:
triggered[i] = true
_spawn()
func _spawn() -> void:
var spawned: Array = []
for j in range(spawn_count):
var entity: Node = spawn_scene.instantiate()
var offset := Vector3(randf_range(-2, 2), 0, randf_range(-2, 2))
parent.get_parent().add_child(entity)
entity.global_position = parent.global_position + offset
if "spawn_position" in entity:
entity.spawn_position = parent.global_position
if "portal" in entity:
entity.portal = parent
spawned.append(entity)
var player: Node = get_tree().get_first_node_in_group("player")
if player:
var dist: float = parent.global_position.distance_to(player.global_position)
if dist <= 10.0:
for entity in spawned:
if entity.has_method("_engage"):
entity._engage(player)
EventBus.portal_spawn.emit(parent, spawned)

View File

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