Modulares Python-Textadventure mit Kampfsystem (Stagger, Bullet Time, Glory Kills, Hacking-Skill-Checks), Hub-Raum-Navigation, prozeduralen Encountern, 3 Charakterklassen, mehreren Enden und Story-Elementen (weißer Hase, Orakel, schwarze-Katze-Deja-vu-Glitch).
68 lines
2.2 KiB
Python
68 lines
2.2 KiB
Python
#!/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
|