v2.3 — Vollständige D&D 5e Status-Effekte
32 Status-Effekte (alle D&D 5e Conditions): Schaden über Zeit: Gift🐍, Brennen🔥, Blutung🩸, Verätzung⚗️, Nekrotisch💀 Debuffs: Schwäche💜, Erschöpfung😫, Furcht😱, Verlangsamt🐌, Geblendet🙈, Taub🔇, Gelähmt⚡, Betäubt💫, Gefesselt🔗, Niedergestreckt🤕, Versteinert🗿, Erschöpft🥵 Buffs: Regeneration💚, Gesegnet✨, Wutanfall😠, Glaubensschild🛡️, Beschleunigt⚡, Steinhaut🪨, Baumhaut🌳, Heldenmut🦸, Bewegungsfreiheit🕊️, Wahrer Streich🎯, Magische Rüstung🔮, Göttliche Gunst🙏, Vergrößert📈 Heilung: Verband🩹, Entgiftung🌿 Monster-Inflicts (nach Typ): - Spinne/Naga: Gift, Drache/Feuer: Brennen, Vampir/Bestie: Blutung - Hexe/Fluch: Schwäche, Geist/Phantom: Furcht - Schleim/Säure: Verätzung, Untot/Skelett: Nekrotisch - Medusa/Basilisk: Blenden, Oger/Troll: Betäubung - Eis/Frost: Verlangsamung, Wüste/Hitze: Erschöpfung Combat: - Gelähmt/Betäubt/Versteinert → kann nicht angreifen - Geblendet/Gefesselt/Niedergestreckt/Furcht → Attack Disadvantage - Effekte ticken jede Runde (Schaden/Heilung) Shop: - Verbände (15G): Stoppt Blutung/Brennen, heilt 1d4+2, gibt Regeneration - Gegengift (25G): Entfernt alle negativen Effekte - Trank-Anzeige: ❤️ ✨ 💖 🌿 🩹
This commit is contained in:
+106
-40
@@ -249,12 +249,61 @@ class DnDCharacter:
|
|||||||
self.spell_slots -= 1
|
self.spell_slots -= 1
|
||||||
|
|
||||||
# === Status Effects ===
|
# === Status Effects ===
|
||||||
def add_effect(self, effect_type: str, duration: int, power: int, name: str):
|
# Complete D&D 5e condition list adapted for auto-RPG
|
||||||
|
EFFECT_DEFINITIONS = {
|
||||||
|
# Damage over time
|
||||||
|
"poison": {"icon": "🐍", "tick": "damage", "desc": "Vergiftet"},
|
||||||
|
"burn": {"icon": "🔥", "tick": "damage", "desc": "Brennend"},
|
||||||
|
"bleed": {"icon": "🩸", "tick": "damage", "desc": "Blutung"},
|
||||||
|
"acid": {"icon": "⚗️", "tick": "damage", "desc": "Verätzt"},
|
||||||
|
"necrotic": {"icon": "💀", "tick": "damage", "desc": "Nekrotisch"},
|
||||||
|
# Debuffs
|
||||||
|
"curse_weakness":{"icon": "💜", "tick": "none", "desc": "Schwäche", "stat": "attack", "mod": -2},
|
||||||
|
"curse_fatigue": {"icon": "😫", "tick": "none", "desc": "Erschöpfung", "stat": "all", "mod": -1},
|
||||||
|
"fear": {"icon": "😱", "tick": "skip_chance", "desc": "Verängstigt", "skip_pct": 50},
|
||||||
|
"slow": {"icon": "🐌", "tick": "none", "desc": "Verlangsamt", "stat": "ac", "mod": -2},
|
||||||
|
"blinded": {"icon": "🙈", "tick": "disadvantage", "desc": "Geblendet"},
|
||||||
|
"deafened": {"icon": "🔇", "tick": "none", "desc": "Taub"},
|
||||||
|
"paralyzed": {"icon": "⚡", "tick": "skip_all", "desc": "Gelähmt"},
|
||||||
|
"stunned": {"icon": "💫", "tick": "skip_all", "desc": "Betäubt"},
|
||||||
|
"restrained": {"icon": "🔗", "tick": "disadvantage", "desc": "Gefesselt"},
|
||||||
|
"prone": {"icon": "🤕", "tick": "disadvantage", "desc": "Niedergestreckt"},
|
||||||
|
"petrified": {"icon": "🗿", "tick": "skip_all", "desc": "Versteinert"},
|
||||||
|
"exhaustion": {"icon": "🥵", "tick": "none", "desc": "Erschöpft", "stat": "all", "mod": -2},
|
||||||
|
# Buffs
|
||||||
|
"regen": {"icon": "💚", "tick": "heal", "desc": "Regeneration"},
|
||||||
|
"bless": {"icon": "✨", "tick": "none", "desc": "Gesegnet", "stat": "attack", "mod": 2},
|
||||||
|
"rage": {"icon": "😠", "tick": "none", "desc": "Wutanfall", "stat": "attack", "mod": 3},
|
||||||
|
"shield_of_faith":{"icon": "🛡️", "tick": "none", "desc": "Glaubensschild", "stat": "ac", "mod": 3},
|
||||||
|
"haste": {"icon": "⚡", "tick": "extra_attack", "desc": "Beschleunigt"},
|
||||||
|
"stoneskin": {"icon": "🪨", "tick": "none", "desc": "Steinhaut", "stat": "ac", "mod": 4},
|
||||||
|
"barkskin": {"icon": "🌳", "tick": "none", "desc": "Baumhaut", "stat": "ac", "mod": 2},
|
||||||
|
"heroism": {"icon": "🦸", "tick": "heal", "desc": "Heldenmut"},
|
||||||
|
"freedom": {"icon": "🕊️", "tick": "none", "desc": "Bewegungsfreiheit"},
|
||||||
|
"true_strike": {"icon": "🎯", "tick": "advantage", "desc": "Wahrer Streich"},
|
||||||
|
"mage_armor": {"icon": "🔮", "tick": "none", "desc": "Magische Rüstung", "stat": "ac", "mod": 3},
|
||||||
|
"divine_favor": {"icon": "🙏", "tick": "none", "desc": "Göttliche Gunst", "stat": "attack", "mod": 2},
|
||||||
|
"enlarge": {"icon": "📈", "tick": "none", "desc": "Vergrößert", "stat": "attack", "mod": 2},
|
||||||
|
# Bandages / healing items
|
||||||
|
"bandaged": {"icon": "🩹", "tick": "heal", "desc": "Verbunden"},
|
||||||
|
"antidote_effect":{"icon": "🌿", "tick": "cleanse_tick", "desc": "Entgiftet"},
|
||||||
|
}
|
||||||
|
|
||||||
|
NEGATIVE_EFFECTS = [
|
||||||
|
"poison", "burn", "bleed", "acid", "necrotic",
|
||||||
|
"curse_weakness", "curse_fatigue", "fear", "slow",
|
||||||
|
"blinded", "deafened", "paralyzed", "stunned",
|
||||||
|
"restrained", "prone", "petrified", "exhaustion",
|
||||||
|
]
|
||||||
|
|
||||||
|
def add_effect(self, effect_type: str, duration: int, power: int, name: str = ""):
|
||||||
"""Fügt einen Statuseffekt hinzu."""
|
"""Fügt einen Statuseffekt hinzu."""
|
||||||
# Remove existing effect of same type
|
|
||||||
self.status_effects = [e for e in self.status_effects if e["type"] != effect_type]
|
self.status_effects = [e for e in self.status_effects if e["type"] != effect_type]
|
||||||
|
definition = self.EFFECT_DEFINITIONS.get(effect_type, {"icon": "❓", "desc": name})
|
||||||
self.status_effects.append({
|
self.status_effects.append({
|
||||||
"type": effect_type, "duration": duration, "power": power, "name": name
|
"type": effect_type, "duration": duration, "power": power,
|
||||||
|
"name": name or definition.get("desc", effect_type),
|
||||||
|
"icon": definition.get("icon", "❓"),
|
||||||
})
|
})
|
||||||
|
|
||||||
def has_effect(self, effect_type: str) -> bool:
|
def has_effect(self, effect_type: str) -> bool:
|
||||||
@@ -267,65 +316,88 @@ class DnDCharacter:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def tick_effects(self) -> list:
|
def tick_effects(self) -> list:
|
||||||
"""Tickt alle Effekte, gibt Liste der abgelaufenen und gewirkten zurück."""
|
"""Tickt alle Effekte pro Runde, gibt Liste der Ereignisse zurück."""
|
||||||
results = []
|
results = []
|
||||||
for effect in self.status_effects[:]:
|
for effect in self.status_effects[:]:
|
||||||
effect["duration"] -= 1
|
effect["duration"] -= 1
|
||||||
|
etype = effect["type"]
|
||||||
|
power = effect["power"]
|
||||||
|
icon = effect.get("icon", "❓")
|
||||||
|
|
||||||
# Apply per-turn effects
|
# Apply per-turn effects
|
||||||
if effect["type"] == "poison":
|
if etype in ("poison", "burn", "bleed", "acid", "necrotic"):
|
||||||
dmg = effect["power"]
|
self.hp = max(0, self.hp - power)
|
||||||
self.hp = max(0, self.hp - dmg)
|
results.append(f"[{self._effect_color(etype)}]{icon} {effect['name']} schadet {power} HP (HP: {self.hp}/{self.max_hp})[/]")
|
||||||
results.append(f"[green]🐍 Gift schadet {dmg} HP (HP: {self.hp}/{self.max_hp})[/]")
|
elif etype == "regen" or etype == "heroism":
|
||||||
elif effect["type"] == "burn":
|
self.hp = min(self.max_hp, self.hp + power)
|
||||||
dmg = effect["power"]
|
results.append(f"[green]{icon} Regeneration heilt {power} HP (HP: {self.hp}/{self.max_hp})[/]")
|
||||||
self.hp = max(0, self.hp - dmg)
|
elif etype == "bandaged":
|
||||||
results.append(f"[red]🔥 Brennen schadet {dmg} HP[/]")
|
self.hp = min(self.max_hp, self.hp + power)
|
||||||
elif effect["type"] == "regen":
|
results.append(f"[green]{icon} Verband heilt {power} HP[/]")
|
||||||
heal = effect["power"]
|
elif etype == "antidote_effect":
|
||||||
self.hp = min(self.max_hp, self.hp + heal)
|
# Ticks: removes one negative effect per turn
|
||||||
results.append(f"[green]💚 Regeneration heilt {heal} HP[/]")
|
for neg in self.NEGATIVE_EFFECTS:
|
||||||
elif effect["type"] == "bleed":
|
if self.has_effect(neg) and neg != "antidote_effect":
|
||||||
dmg = effect["power"]
|
self.status_effects = [e for e in self.status_effects if e["type"] != neg]
|
||||||
self.hp = max(0, self.hp - dmg)
|
results.append(f"[green]{icon} Entgiftung entfernt {neg}[/]")
|
||||||
results.append(f"[red]🩸 Blutung schadet {dmg} HP[/]")
|
break
|
||||||
|
|
||||||
if effect["duration"] <= 0:
|
if effect["duration"] <= 0:
|
||||||
self.status_effects.remove(effect)
|
self.status_effects.remove(effect)
|
||||||
results.append(f"[dim]✨ {effect['name']} ist abgeklungen.[/]")
|
results.append(f"[dim]{icon} {effect['name']} ist abgeklungen.[/]")
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
def _effect_color(self, etype: str) -> str:
|
||||||
|
colors = {
|
||||||
|
"poison": "green", "burn": "red", "bleed": "red",
|
||||||
|
"acid": "yellow", "necrotic": "bold red",
|
||||||
|
}
|
||||||
|
return colors.get(etype, "red")
|
||||||
|
|
||||||
|
def is_immobilized(self) -> bool:
|
||||||
|
"""True wenn der Charakter nicht handeln kann."""
|
||||||
|
return self.has_effect("paralyzed") or self.has_effect("stunned") or self.has_effect("petrified")
|
||||||
|
|
||||||
|
def has_attack_disadvantage(self) -> bool:
|
||||||
|
return self.has_effect("blinded") or self.has_effect("restrained") or self.has_effect("prone") or self.has_effect("fear")
|
||||||
|
|
||||||
def cleanse(self) -> int:
|
def cleanse(self) -> int:
|
||||||
"""Entfernt alle negativen Effekte. Gibt Anzahl entfernter zurück."""
|
"""Entfernt alle negativen Effekte. Gibt Anzahl entfernter zurück."""
|
||||||
negative = ["poison", "burn", "bleed", "curse_weakness", "curse_fatigue", "fear", "slow"]
|
|
||||||
removed = 0
|
removed = 0
|
||||||
for neg in negative:
|
for neg in self.NEGATIVE_EFFECTS:
|
||||||
before = len(self.status_effects)
|
before = len(self.status_effects)
|
||||||
self.status_effects = [e for e in self.status_effects if e["type"] != neg]
|
self.status_effects = [e for e in self.status_effects if e["type"] != neg]
|
||||||
removed += before - len(self.status_effects)
|
removed += before - len(self.status_effects)
|
||||||
return removed
|
return removed
|
||||||
|
|
||||||
|
def apply_bandage(self) -> int:
|
||||||
|
"""Verband anwenden — heilt und fügt regen-Effekt hinzu."""
|
||||||
|
heal = roll(4, 1, 2)["total"] # 1d4+2
|
||||||
|
self.hp = min(self.max_hp, self.hp + heal)
|
||||||
|
self.add_effect("bandaged", 3, 2, "Verband")
|
||||||
|
return heal
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def effective_ac(self) -> int:
|
def effective_ac(self) -> int:
|
||||||
"""AC mit Buffs/Debuffs."""
|
"""AC mit Buffs/Debuffs."""
|
||||||
ac = self.ac
|
ac = self.ac
|
||||||
if self.has_effect("shield_of_faith"):
|
for effect in self.status_effects:
|
||||||
ac += self.get_effect("shield_of_faith")["power"]
|
definition = self.EFFECT_DEFINITIONS.get(effect["type"], {})
|
||||||
if self.has_effect("curse_weakness"):
|
if definition.get("stat") == "ac":
|
||||||
ac -= 2
|
ac += definition.get("mod", 0) + effect.get("power", 0)
|
||||||
return max(1, ac)
|
return max(1, ac)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def effective_attack(self) -> int:
|
def effective_attack(self) -> int:
|
||||||
"""Attack Bonus mit Buffs/Debuffs."""
|
"""Attack Bonus mit Buffs/Debuffs."""
|
||||||
bonus = self.attack_bonus
|
bonus = self.attack_bonus
|
||||||
if self.has_effect("bless"):
|
for effect in self.status_effects:
|
||||||
bonus += 2
|
definition = self.EFFECT_DEFINITIONS.get(effect["type"], {})
|
||||||
if self.has_effect("curse_weakness"):
|
if definition.get("stat") == "attack":
|
||||||
bonus -= 2
|
bonus += definition.get("mod", 0) + effect.get("power", 0)
|
||||||
if self.has_effect("rage"):
|
elif definition.get("stat") == "all":
|
||||||
bonus += self.get_effect("rage")["power"]
|
bonus += definition.get("mod", 0)
|
||||||
return max(0, bonus)
|
return max(0, bonus)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -333,15 +405,9 @@ class DnDCharacter:
|
|||||||
"""Kurze Zusammenfassung der aktiven Effekte für UI."""
|
"""Kurze Zusammenfassung der aktiven Effekte für UI."""
|
||||||
if not self.status_effects:
|
if not self.status_effects:
|
||||||
return "[dim]keine[/]"
|
return "[dim]keine[/]"
|
||||||
icons = {
|
|
||||||
"poison": "🐍", "burn": "🔥", "regen": "💚", "bleed": "🩸",
|
|
||||||
"bless": "✨", "rage": "😠", "shield_of_faith": "🛡️",
|
|
||||||
"curse_weakness": "💜", "curse_fatigue": "😫", "fear": "😱", "slow": "🐌",
|
|
||||||
"haste": "⚡", "strength": "💪",
|
|
||||||
}
|
|
||||||
parts = []
|
parts = []
|
||||||
for e in self.status_effects:
|
for e in self.status_effects:
|
||||||
icon = icons.get(e["type"], "❓")
|
icon = e.get("icon", "❓")
|
||||||
parts.append(f"{icon}{e['duration']}")
|
parts.append(f"{icon}{e['duration']}")
|
||||||
return " ".join(parts)
|
return " ".join(parts)
|
||||||
|
|
||||||
|
|||||||
+76
-24
@@ -67,18 +67,41 @@ class DnDMonster:
|
|||||||
|
|
||||||
# Status effects the monster can inflict (based on type)
|
# Status effects the monster can inflict (based on type)
|
||||||
self.inflicts = []
|
self.inflicts = []
|
||||||
monster_type = name.lower()
|
mt = name.lower()
|
||||||
if any(w in monster_type for w in ["spinne", "naga", "schlang", "skorpion", "gift"]):
|
# Poison
|
||||||
|
if any(w in mt for w in ["spinne", "naga", "schlang", "skorpion", "gift", "nattern"]):
|
||||||
self.inflicts.append({"type": "poison", "chance": 30, "duration": 3, "power": max(1, level // 2), "name": "Giftbiss"})
|
self.inflicts.append({"type": "poison", "chance": 30, "duration": 3, "power": max(1, level // 2), "name": "Giftbiss"})
|
||||||
if any(w in monster_type for w in ["drache", "feuer", "dämon", "phoenix", "flamme"]):
|
# Burn
|
||||||
|
if any(w in mt for w in ["drache", "feuer", "dämon", "phoenix", "flamme", "elementar"]):
|
||||||
self.inflicts.append({"type": "burn", "chance": 25, "duration": 2, "power": max(1, level // 2), "name": "Feueratem"})
|
self.inflicts.append({"type": "burn", "chance": 25, "duration": 2, "power": max(1, level // 2), "name": "Feueratem"})
|
||||||
if any(w in monster_type for w in ["vampir", "blut", "schnitter", "todes"]):
|
# Bleed
|
||||||
|
if any(w in mt for w in ["vampir", "blut", "schnitter", "todes", "werwolf", "bestie"]):
|
||||||
self.inflicts.append({"type": "bleed", "chance": 35, "duration": 3, "power": max(1, level // 3), "name": "Blutung"})
|
self.inflicts.append({"type": "bleed", "chance": 35, "duration": 3, "power": max(1, level // 3), "name": "Blutung"})
|
||||||
if any(w in monster_type for w in ["hexe", "fluch", "verflucht", "schatten", "dunkel"]):
|
# Curse
|
||||||
|
if any(w in mt for w in ["hexe", "fluch", "verflucht", "schatten", "dunkel", "necroman"]):
|
||||||
self.inflicts.append({"type": "curse_weakness", "chance": 20, "duration": 3, "power": 2, "name": "Schwächungsfluch"})
|
self.inflicts.append({"type": "curse_weakness", "chance": 20, "duration": 3, "power": 2, "name": "Schwächungsfluch"})
|
||||||
if any(w in monster_type for w in ["geist", "gespenst", "furcht", "schrecken"]):
|
# Fear
|
||||||
|
if any(w in mt for w in ["geist", "gespenst", "furcht", "schrecken", "phantom", "wraith"]):
|
||||||
self.inflicts.append({"type": "fear", "chance": 20, "duration": 2, "power": 2, "name": "Furcht"})
|
self.inflicts.append({"type": "fear", "chance": 20, "duration": 2, "power": 2, "name": "Furcht"})
|
||||||
# Sometimes random poison for variety
|
# Acid
|
||||||
|
if any(w in mt for w in ["schleim", "säure", "gallert", "ozy", "schlam"]):
|
||||||
|
self.inflicts.append({"type": "acid", "chance": 30, "duration": 3, "power": max(1, level // 2), "name": "Verätzung"})
|
||||||
|
# Necrotic
|
||||||
|
if any(w in mt for w in ["untot", "skelett", "wiederg", "ghoul", "leiche", "necro"]):
|
||||||
|
self.inflicts.append({"type": "necrotic", "chance": 20, "duration": 2, "power": max(1, level // 2), "name": "Nekrotische Aura"})
|
||||||
|
# Blinded
|
||||||
|
if any(w in mt for w in ["medusa", "basilisk", "blitz", "licht", "sonne"]):
|
||||||
|
self.inflicts.append({"type": "blinded", "chance": 25, "duration": 2, "power": 1, "name": "Blendender Blick"})
|
||||||
|
# Stunned
|
||||||
|
if any(w in mt for w in ["ogre", "ries", "troll", "donner", "schlag"]):
|
||||||
|
self.inflicts.append({"type": "stunned", "chance": 10, "duration": 1, "power": 1, "name": "Betäubender Schlag"})
|
||||||
|
# Slow
|
||||||
|
if any(w in mt for w in ["eis", "frost", "kälte", "winter"]):
|
||||||
|
self.inflicts.append({"type": "slow", "chance": 25, "duration": 3, "power": 2, "name": "Verlangsamende Kälte"})
|
||||||
|
# Exhaustion
|
||||||
|
if any(w in mt for w in ["wüste", "sand", "hitz", "phönix"]):
|
||||||
|
self.inflicts.append({"type": "exhaustion", "chance": 15, "duration": 3, "power": 2, "name": "Erschöpfung"})
|
||||||
|
# Random poison for variety
|
||||||
if not self.inflicts and random.randint(1, 4) == 1:
|
if not self.inflicts and random.randint(1, 4) == 1:
|
||||||
self.inflicts.append({"type": "poison", "chance": 15, "duration": 2, "power": 1, "name": "Gift"})
|
self.inflicts.append({"type": "poison", "chance": 15, "duration": 2, "power": 1, "name": "Gift"})
|
||||||
|
|
||||||
@@ -296,26 +319,25 @@ class GameEngine:
|
|||||||
self.dice_log.add(f"[bold red]💀 Status-Effekt tötet dich![/]")
|
self.dice_log.add(f"[bold red]💀 Status-Effekt tötet dich![/]")
|
||||||
return {"result": "death", "rounds": rounds, "monster": monster.name}
|
return {"result": "death", "rounds": rounds, "monster": monster.name}
|
||||||
|
|
||||||
# Use cleanse potion if badly afflicted
|
# Check immobilization
|
||||||
if self.character.has_effect("poison") and self.character.potions.get("healing", 0) > 0 and self.character.hp < self.character.max_hp * 0.5:
|
if self.character.is_immobilized():
|
||||||
# Use healing potion which also cleanses (simplified)
|
self.dice_log.add(f"[yellow]💫 Du bist gelähmt/betäubt — kannst nicht angreifen![/]")
|
||||||
pass # potion use happens in _use_potions_if_needed before combat
|
else:
|
||||||
|
# Caster tries spell first (50% chance per round)
|
||||||
# Caster tries spell first (50% chance per round)
|
if rounds == 1 and self.character.max_mp > 0 and random.random() < 0.5:
|
||||||
if rounds == 1 and self.character.max_mp > 0 and random.random() < 0.5:
|
if self._cast_spell_if_possible(monster):
|
||||||
if self._cast_spell_if_possible(monster):
|
if not monster.is_alive:
|
||||||
|
self.dice_log.add(f"[bold green]☠️ {monster.name} durch Zauber besiegt![/]")
|
||||||
|
break
|
||||||
|
|
||||||
|
# Player attacks
|
||||||
|
result = self._player_attack(monster)
|
||||||
|
if result["hit"]:
|
||||||
|
monster.hp = max(0, monster.hp - result["damage"])
|
||||||
if not monster.is_alive:
|
if not monster.is_alive:
|
||||||
self.dice_log.add(f"[bold green]☠️ {monster.name} durch Zauber besiegt![/]")
|
self.dice_log.add(f"[bold green]☠️ {monster.name} besiegt![/]")
|
||||||
break
|
break
|
||||||
|
|
||||||
# Player attacks
|
|
||||||
result = self._player_attack(monster)
|
|
||||||
if result["hit"]:
|
|
||||||
monster.hp = max(0, monster.hp - result["damage"])
|
|
||||||
if not monster.is_alive:
|
|
||||||
self.dice_log.add(f"[bold green]☠️ {monster.name} besiegt![/]")
|
|
||||||
break
|
|
||||||
|
|
||||||
# Monster attacks
|
# Monster attacks
|
||||||
if monster.is_alive:
|
if monster.is_alive:
|
||||||
m_result = monster.attack(self.character.effective_ac, self.dice_log.entries)
|
m_result = monster.attack(self.character.effective_ac, self.dice_log.entries)
|
||||||
@@ -518,6 +540,17 @@ class GameEngine:
|
|||||||
self._add_loot_log(f"[green]🧪 Kaufe Gegengift (-{antidote_price}G)[/]")
|
self._add_loot_log(f"[green]🧪 Kaufe Gegengift (-{antidote_price}G)[/]")
|
||||||
bought_something = True
|
bought_something = True
|
||||||
|
|
||||||
|
# 8. Bandages (Verbände) — heal + stop bleeding
|
||||||
|
bandage_price = 15
|
||||||
|
max_bandages = 5
|
||||||
|
while c.potions.get("bandage", 0) < max_bandages and c.gold - bandage_price >= gold_reserve:
|
||||||
|
c.gold -= bandage_price
|
||||||
|
c.potions["bandage"] = c.potions.get("bandage", 0) + 1
|
||||||
|
c.gold_spent += bandage_price
|
||||||
|
c.items_bought += 1
|
||||||
|
self._add_loot_log(f"[green]🩹 Kaufe Verband (-{bandage_price}G)[/]")
|
||||||
|
bought_something = True
|
||||||
|
|
||||||
if bought_something:
|
if bought_something:
|
||||||
self._add_log(f"[yellow]🏪 Shop besucht — Ausrüstung und Tränke gekauft[/]")
|
self._add_log(f"[yellow]🏪 Shop besucht — Ausrüstung und Tränke gekauft[/]")
|
||||||
self.dice_log.add(f"[yellow]🏪 Shop: {c.items_bought} Items, Rest-Gold: {c.gold}G[/]")
|
self.dice_log.add(f"[yellow]🏪 Shop: {c.items_bought} Items, Rest-Gold: {c.gold}G[/]")
|
||||||
@@ -534,6 +567,25 @@ class GameEngine:
|
|||||||
self.dice_log.add(f"[green]🧪 Gegengift benutzt! {removed} Effekte entfernt.[/]")
|
self.dice_log.add(f"[green]🧪 Gegengift benutzt! {removed} Effekte entfernt.[/]")
|
||||||
self._add_log(f"[green]🧪 Gegengift benutzt — Vergiftung geheilt![/]")
|
self._add_log(f"[green]🧪 Gegengift benutzt — Vergiftung geheilt![/]")
|
||||||
|
|
||||||
|
# Bandage if bleeding or burning
|
||||||
|
if c.has_effect("bleed") and c.potions.get("bandage", 0) > 0:
|
||||||
|
heal = c.apply_bandage()
|
||||||
|
c.potions["bandage"] -= 1
|
||||||
|
c.potions_used += 1
|
||||||
|
# Remove bleed
|
||||||
|
c.status_effects = [e for e in c.status_effects if e["type"] != "bleed"]
|
||||||
|
self.dice_log.add(f"[green]🩹 Verband benutzt! Blutung gestoppt, +{heal} HP[/]")
|
||||||
|
self._add_log(f"[green]🩹 Verband — Blutung gestoppt (+{heal} HP)[/]")
|
||||||
|
|
||||||
|
# Bandage also helps with burn (smother flames)
|
||||||
|
if c.has_effect("burn") and c.potions.get("bandage", 0) > 0 and not c.has_effect("bleed"):
|
||||||
|
heal = c.apply_bandage()
|
||||||
|
c.potions["bandage"] -= 1
|
||||||
|
c.potions_used += 1
|
||||||
|
c.status_effects = [e for e in c.status_effects if e["type"] != "burn"]
|
||||||
|
self.dice_log.add(f"[green]🩹 Verband löscht Feuer! +{heal} HP[/]")
|
||||||
|
self._add_log(f"[green]🩹 Verband — Brennen gelöscht (+{heal} HP)[/]")
|
||||||
|
|
||||||
# Antidote also removes curses if desperate
|
# Antidote also removes curses if desperate
|
||||||
if c.has_effect("curse_weakness") and c.potions.get("antidote", 0) > 0 and c.hp < c.max_hp * 0.3:
|
if c.has_effect("curse_weakness") and c.potions.get("antidote", 0) > 0 and c.hp < c.max_hp * 0.3:
|
||||||
removed = c.cleanse()
|
removed = c.cleanse()
|
||||||
|
|||||||
+3
-1
@@ -109,7 +109,9 @@ def render_game(engine: GameEngine) -> Layout:
|
|||||||
# Potions
|
# Potions
|
||||||
pot_str = f"❤️{c.potions.get('healing',0)} " \
|
pot_str = f"❤️{c.potions.get('healing',0)} " \
|
||||||
f"✨{c.potions.get('mana',0)} " \
|
f"✨{c.potions.get('mana',0)} " \
|
||||||
f"💖{c.potions.get('greater_healing',0)}"
|
f"💖{c.potions.get('greater_healing',0)} " \
|
||||||
|
f"🌿{c.potions.get('antidote',0)} " \
|
||||||
|
f"🩹{c.potions.get('bandage',0)}"
|
||||||
char_table.add_row("Tränke", pot_str)
|
char_table.add_row("Tränke", pot_str)
|
||||||
|
|
||||||
# Status effects
|
# Status effects
|
||||||
|
|||||||
Reference in New Issue
Block a user