#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Enemy-Klasse: datengetriebene Gegner mit Stagger-System.""" import json import os _DATA_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), "data", "enemies.json") _ENEMY_TEMPLATES = None def _load_templates(): global _ENEMY_TEMPLATES if _ENEMY_TEMPLATES is None: with open(_DATA_PATH, "r", encoding="utf-8") as f: data = json.load(f) _ENEMY_TEMPLATES = {d["id"]: d for d in data} return _ENEMY_TEMPLATES class Enemy: def __init__(self, template): self.enemy_id = template["id"] self.name = template["name"] self.type = template["type"] # demon, program, hybrid self.max_hp = template["hp"] self.hp = template["hp"] self.stagger_max = template["stagger_max"] self.stagger = 0 self.attack_range = tuple(template["attack_range"]) self.firewall = template.get("firewall", 5) self.description = template.get("description", "") self.is_boss = template.get("boss", False) self.max_phases = template.get("phases", 1) self.phase = 1 self.staggered = False @classmethod def create(cls, enemy_id): templates = _load_templates() return cls(templates[enemy_id]) @property def is_alive(self): return self.hp > 0 def apply_damage(self, amount): self.hp = max(0, self.hp - amount) if not self.staggered: self.stagger = min(self.stagger_max, self.stagger + amount) if self.stagger >= self.stagger_max: self.staggered = True def clear_stagger(self): self.staggered = False self.stagger = 0 def maybe_advance_phase(self): """Bosse verlieren pro Phase einen Teil ihres HP-Schwellenwerts und werden staerker.""" if not self.is_boss or self.phase >= self.max_phases: return False threshold = self.max_hp * (1 - self.phase / self.max_phases) if self.hp <= threshold and self.hp > 0: self.phase += 1 self.attack_range = (self.attack_range[0] + 4, self.attack_range[1] + 6) return True return False