#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Item-, Waffen- und Inventar-Klassen.""" class Item: def __init__(self, item_id, name, description, kind="misc", stackable=True, value=1): self.item_id = item_id self.name = name self.description = description self.kind = kind # misc, consumable, key, lore, fragment self.stackable = stackable self.value = value # z.B. Heilmenge bei consumables @classmethod def from_dict(cls, d): return cls( item_id=d["id"], name=d["name"], description=d.get("description", ""), kind=d.get("kind", "misc"), stackable=d.get("stackable", True), value=d.get("value", 1), ) class Weapon: def __init__(self, weapon_id, name, damage_range, ammo_type, ammo_cost, damage_type="ballistic", description=""): self.weapon_id = weapon_id self.name = name self.damage_range = tuple(damage_range) # (min, max) self.ammo_type = ammo_type # "melee" fuer unbegrenzt self.ammo_cost = ammo_cost self.damage_type = damage_type # ballistic, plasma, melee self.description = description @classmethod def from_dict(cls, d): return cls( weapon_id=d["id"], name=d["name"], damage_range=d["damage_range"], ammo_type=d.get("ammo_type", "melee"), ammo_cost=d.get("ammo_cost", 0), damage_type=d.get("damage_type", "ballistic"), description=d.get("description", ""), ) def __repr__(self): return self.name # Waffen-Dreieck: Schaden-Multiplikator (Waffentyp -> Gegnertyp) TYPE_ADVANTAGE = { ("ballistic", "demon"): 1.3, ("ballistic", "program"): 0.8, ("ballistic", "hybrid"): 1.0, ("plasma", "program"): 1.3, ("plasma", "hybrid"): 1.15, ("plasma", "demon"): 0.85, ("melee", "demon"): 1.0, ("melee", "program"): 1.0, ("melee", "hybrid"): 1.1, } def type_multiplier(damage_type, enemy_type): return TYPE_ADVANTAGE.get((damage_type, enemy_type), 1.0) class Inventory: def __init__(self): self.items = {} # item_id -> (Item, count) self.keycards = set() # "red", "blue", "yellow" self.crucible_fragments = 0 self.has_backup_pill = False def add(self, item, count=1): if item.kind == "key": self.keycards.add(item.item_id) return if item.kind == "fragment": self.crucible_fragments += count return if item.item_id == "backup_pill": self.has_backup_pill = True return if item.item_id in self.items: existing_item, existing_count = self.items[item.item_id] self.items[item.item_id] = (existing_item, existing_count + count) else: self.items[item.item_id] = (item, count) def has(self, item_id): return item_id in self.items and self.items[item_id][1] > 0 def consume(self, item_id): if not self.has(item_id): return None item, count = self.items[item_id] count -= 1 if count <= 0: del self.items[item_id] else: self.items[item_id] = (item, count) return item def has_keycard(self, color): return color in self.keycards def list_display(self): lines = [] for item, count in self.items.values(): lines.append(f"{item.name} x{count}") if self.keycards: lines.append("Keycards: " + ", ".join(sorted(self.keycards))) if self.crucible_fragments: lines.append(f"Crucible-Fragmente: {self.crucible_fragments}/3") if self.has_backup_pill: lines.append("Backup-Pille (Auto-Revive bereit)") return lines def is_empty(self): return not self.items and not self.keycards and not self.crucible_fragments and not self.has_backup_pill