extends Node enum Role { TANK, DAMAGE, HEALER } # Basis (aus Resource geladen) var base: PlayerStats var speed := 5.0 var jump_velocity := 4.5 var target_range := 20.0 var combat_timeout := 3.0 var respawn_time := 3.0 var gcd_time := 0.5 var aa_cooldown := 0.5 # Laufzeit var health := 100.0 var max_health := 100.0 var health_regen := 0.0 var shield := 0.0 var max_shield := 0.0 var shield_regen_delay := 3.0 var shield_regen_time := 5.0 var shield_regen_timer := 0.0 var alive := true # Buffs var buff_damage := 1.0 var buff_heal := 1.0 var buff_shield := 1.0 # Level / XP const XP_PER_LEVEL: int = 50 var level: int = 1 var xp: int = 0 var xp_to_next: int = XP_PER_LEVEL var level_scale: float = 1.0 # Rolle var current_role: int = Role.DAMAGE var ability_set: AbilitySet = null # Kampf var target: Node3D = null var in_combat := false var combat_timer := 0.0 # Cooldowns var cooldowns: Array[float] = [] var max_cooldowns: Array[float] = [] var gcd := 0.0 var aa_timer := 0.0 # Szenenwechsel var portal_position := Vector3.ZERO var returning_from_dungeon := false var dungeon_cleared := false # Cache für Szenenwechsel var _cache: Dictionary = {} func init_from_resource(res: PlayerStats) -> void: base = res speed = res.speed jump_velocity = res.jump_velocity target_range = res.target_range combat_timeout = res.combat_timeout respawn_time = res.respawn_time gcd_time = res.gcd_time aa_cooldown = res.aa_cooldown if _cache.is_empty(): max_health = res.max_health * level_scale health = max_health health_regen = res.health_regen * level_scale max_shield = res.max_shield * level_scale shield = max_shield shield_regen_delay = res.shield_regen_delay shield_regen_time = res.shield_regen_time shield_regen_timer = 0.0 alive = true buff_damage = 1.0 buff_heal = 1.0 buff_shield = 1.0 else: _restore_cache() cooldowns.resize(5) cooldowns.fill(0.0) max_cooldowns.resize(5) max_cooldowns.fill(0.0) gcd = 0.0 aa_timer = 0.0 func set_health(value: float) -> void: health = value EventBus.health_changed.emit(self, health, max_health) if health <= 0 and alive: alive = false EventBus.entity_died.emit(self) func set_shield(value: float) -> void: shield = value EventBus.shield_changed.emit(self, shield, max_shield) func set_role(role: int) -> void: current_role = role EventBus.role_changed.emit(self, current_role) func set_target(new_target: Node3D) -> void: target = new_target EventBus.target_changed.emit(self, target) func respawn() -> void: health = max_health shield = max_shield alive = true EventBus.health_changed.emit(self, health, max_health) EventBus.shield_changed.emit(self, shield, max_shield) EventBus.player_respawned.emit(self) func save_cache() -> void: _cache = { "health": health, "max_health": max_health, "health_regen": health_regen, "shield": shield, "max_shield": max_shield, "shield_regen_delay": shield_regen_delay, "shield_regen_time": shield_regen_time, "alive": alive, "buff_damage": buff_damage, "buff_heal": buff_heal, "buff_shield": buff_shield, } func clear_cache() -> void: _cache.clear() portal_position = Vector3.ZERO returning_from_dungeon = false dungeon_cleared = false func reset_run() -> void: clear_cache() level = 1 xp = 0 xp_to_next = XP_PER_LEVEL level_scale = 1.0 func add_xp(amount: int) -> void: xp += amount EventBus.xp_gained.emit(self, amount) while xp >= xp_to_next: xp -= xp_to_next level_up() func level_up() -> void: level += 1 level_scale = float(_fibonacci(level)) xp_to_next = XP_PER_LEVEL * _fibonacci(level) if base: max_health = base.max_health * level_scale max_shield = base.max_shield * level_scale else: max_health = 100.0 * level_scale max_shield = 50.0 * level_scale health = max_health shield = max_shield EventBus.health_changed.emit(self, health, max_health) EventBus.shield_changed.emit(self, shield, max_shield) EventBus.level_up.emit(self, level) func _fibonacci(n: int) -> int: if n <= 1: return 1 if n == 2: return 2 var a := 1 var b := 2 for i in range(3, n + 1): var c := a + b a = b b = c return b func _restore_cache() -> void: health = _cache.get("health", max_health) max_health = _cache.get("max_health", max_health) health_regen = _cache.get("health_regen", 0.0) shield = _cache.get("shield", 0.0) max_shield = _cache.get("max_shield", 0.0) shield_regen_delay = _cache.get("shield_regen_delay", 3.0) shield_regen_time = _cache.get("shield_regen_time", 5.0) alive = _cache.get("alive", true) buff_damage = _cache.get("buff_damage", 1.0) buff_heal = _cache.get("buff_heal", 1.0) buff_shield = _cache.get("buff_shield", 1.0) _cache.clear()