dnd5-scripts/generate_encounter/get_creature.py
2026-06-17 22:32:48 +03:00

97 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
get_creature.py — выбор случайного существа/группы из таблиц биома.
Вынесено из encounter_generator.py.
Экспортирует:
get_creature(env, level) -> str
Возвращает строку из таблицы монстров для биома и уровня.
"""
import random
from monsters_data import DATA
# ──────────────────────────────────────────────────────────────────────────────
# Внутренние функции
# ──────────────────────────────────────────────────────────────────────────────
def _resolve_level_key(env: str, level: int) -> str:
"""
Определяет ключ диапазона уровней для данного биома.
Разные биомы имеют разные диапазоны в таблицах DMG.
"""
if env == "grassland":
if level <= 5: return "1-5"
if level <= 10: return "6-10"
if level <= 16: return "11-16"
return "17-20"
if env in ("swamp", "underwater"):
if level <= 4: return "1-4"
if level <= 10: return "5-10"
return "11-20"
# Все остальные биомы
if level <= 4: return "1-4"
if level <= 10: return "5-10"
if level <= 16: return "11-16"
return "17-20"
def _roll_on_table(table: list[tuple[int, int, str]]) -> str:
"""
Бросает d100 и возвращает результат из таблицы.
Таблица: список кортежей (min, max, text).
"""
die_roll = random.randint(1, 100)
for start, end, text in table:
if start <= die_roll <= end:
return f"(d100: {die_roll}) — {text}"
return f"(d100: {die_roll}) — результат не найден в таблице."
# ──────────────────────────────────────────────────────────────────────────────
# Публичная функция
# ──────────────────────────────────────────────────────────────────────────────
def get_creature(env: str, level: int) -> str:
"""
Возвращает случайное существо/группу из таблицы биома и уровня.
Args:
env: Биом (arctic, coastal, desert, forest, ...).
level: Средний уровень группы (120).
Returns:
Строка вида "(d100: 42) — 2d6 bandits" или сообщение об ошибке.
"""
env = env.lower().strip()
if env not in DATA:
return f"[get_creature] Биом '{env}' не найден в таблицах."
key = _resolve_level_key(env, level)
table = DATA.get(env, {}).get(key)
if not table:
return f"[get_creature] Таблица для биома '{env}', уровни '{key}' не найдена."
return _roll_on_table(table)
# ──────────────────────────────────────────────────────────────────────────────
# Быстрый тест
# ──────────────────────────────────────────────────────────────────────────────
if __name__ == "__main__":
tests = [
("forest", 3),
("arctic", 1),
("urban", 10),
("grassland", 6),
("underwater", 15),
("unknown", 5),
]
for biome, lvl in tests:
print(f"[{biome:12} lvl {lvl:2}] {get_creature(biome, lvl)}")