"""Character-System: Rassen, Klassen, Stats, Leveling.""" import random import math RACES = [ "Kleinwüchsiger Goblin", "Waldelf", "Höhlentroll", "Stadtmensch", "Wüstenork", "Sumpfzwerg", "Eisbarbar", "Schattenkatze", "Steingolem", "Feuerechse", "Nachtalb", "Wolfsjäger", ] CLASSES = [ "Schlachtenbraten", "Kartoffelmagier", "Panzerschmied", "Bratpfannenpaladin", "Würstchenkrieger", "Kaffeepriester", "Bierbrauer-Mönch", "Käsekönigin", "Dosenöffner-Assassin", "Fahrradschurke", "Schneeballhexer", "Teppichkampfkünstler", ] # Class → stat weights (STR, DEX, INT, VIT, LCK) CLASS_STATS = { "Schlachtenbraten": (8, 3, 1, 7, 2), "Kartoffelmagier": (2, 3, 8, 3, 5), "Panzerschmied": (7, 2, 3, 8, 1), "Bratpfannenpaladin": (6, 4, 4, 6, 3), "Würstchenkrieger": (7, 5, 2, 5, 4), "Kaffeepriester": (3, 4, 7, 3, 6), "Bierbrauer-Mönch": (5, 3, 5, 7, 3), "Käsekönigin": (4, 5, 6, 4, 5), "Dosenöffner-Assassin": (4, 8, 3, 3, 7), "Fahrradschurke": (3, 7, 4, 4, 8), "Schneeballhexer": (2, 4, 8, 3, 5), "Teppichkampfkünstler": (5, 7, 3, 5, 4), } # XP curve: xp needed for next level = base * level^1.5 def xp_for_level(level: int) -> int: return int(50 * (level ** 1.5)) class Character: def __init__(self, name: str, race: str, char_class: str): self.name = name self.race = race self.char_class = char_class self.level = 1 self.xp = 0 self.gold = 10 stats = CLASS_STATS.get(char_class, (5, 5, 5, 5, 5)) self.str = stats[0] + random.randint(0, 2) self.dex = stats[1] + random.randint(0, 2) self.int = stats[2] + random.randint(0, 2) self.vit = stats[3] + random.randint(0, 2) self.lck = stats[4] + random.randint(0, 2) self.hp = self.max_hp self.mp = self.max_mp self.inventory = [] self.equipped = {"weapon": None, "armor": None, "helmet": None, "boots": None, "accessory": None} self.kills = 0 self.deaths = 0 self.quests_done = 0 self.steps = 0 @property def max_hp(self) -> int: return 20 + self.vit * 5 + self.level * 3 @property def max_mp(self) -> int: return 10 + self.int * 3 + self.level * 2 @property def attack(self) -> int: weapon_bonus = self.equipped["weapon"].power if self.equipped["weapon"] else 0 return self.str * 2 + self.level + weapon_bonus @property def defense(self) -> int: armor_bonus = sum(e.power for e in self.equipped.values() if e) return self.vit + armor_bonus @property def xp_to_next(self) -> int: return xp_for_level(self.level) def gain_xp(self, amount: int) -> bool: """Gibt XP. Return True bei Level-Up.""" self.xp += amount if self.xp >= self.xp_to_next: self.xp -= self.xp_to_next self.level += 1 self.hp = self.max_hp self.mp = self.max_mp # Stat growth self.str += random.randint(0, 1) self.dex += random.randint(0, 1) self.int += random.randint(0, 1) self.vit += random.randint(0, 1) self.lck += random.randint(0, 1) return True return False def take_damage(self, dmg: int): actual = max(1, dmg - self.defense) self.hp -= actual return actual def heal(self): self.hp = self.max_hp self.mp = self.max_mp def is_alive(self) -> bool: return self.hp > 0 def to_dict(self) -> dict: return { "name": self.name, "race": self.race, "char_class": self.char_class, "level": self.level, "xp": self.xp, "gold": self.gold, "str": self.str, "dex": self.dex, "int": self.int, "vit": self.vit, "lck": self.lck, "hp": self.hp, "mp": self.mp, "kills": self.kills, "deaths": self.deaths, "quests_done": self.quests_done, "steps": self.steps, "inventory": [i.to_dict() for i in self.inventory], "equipped": {k: v.to_dict() if v else None for k, v in self.equipped.items()}, } @classmethod def from_dict(cls, d: dict) -> "Character": c = cls(d["name"], d["race"], d["char_class"]) c.level = d["level"]; c.xp = d["xp"]; c.gold = d["gold"] c.str = d["str"]; c.dex = d["dex"]; c.int = d["int"]; c.vit = d["vit"]; c.lck = d["lck"] c.hp = d["hp"]; c.mp = d["mp"] c.kills = d["kills"]; c.deaths = d["deaths"]; c.quests_done = d["quests_done"]; c.steps = d["steps"] c.inventory = [Item.from_dict(i) for i in d.get("inventory", [])] c.equipped = { k: Item.from_dict(v) if v else None for k, v in d.get("equipped", {}).items() } return c class Item: def __init__(self, name: str, item_type: str, power: int, value: int, rarity: str = "gewöhnlich"): self.name = name self.item_type = item_type # weapon, armor, helmet, boots, accessory, junk, potion self.power = power self.value = value self.rarity = rarity def to_dict(self) -> dict: return {"name": self.name, "item_type": self.item_type, "power": self.power, "value": self.value, "rarity": self.rarity} @classmethod def from_dict(cls, d: dict) -> "Item": return cls(d["name"], d["item_type"], d["power"], d["value"], d.get("rarity", "gewöhnlich")) def __str__(self): r = {"gewöhnlich": "", "selten": "[cyan]", "episch": "[magenta]", "legendär": "[bold yellow]"} color = r.get(self.rarity, "") prefix = f"{color}" if color else "" suffix = "[/]" if color else "" return f"{prefix}{self.name} (Stärke {self.power}, {self.value} Gold){suffix}"