Locked: rules/ (deck cards + mechanics), tools/ (draw, roll, run) Unlocked: session/ (character, world, tweaks, log) Entry: run.sh launches the Textual TUI
98 lines
2.7 KiB
Python
Executable File
98 lines
2.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
draw.py — Draw a card from The Chaos deck.
|
|
|
|
Usage:
|
|
python3 draw.py <deck> <table> [count]
|
|
|
|
Decks: souls, cook, creatures, curiosities
|
|
Tables: see the YAML files (e.g. traits, rumours, type, drink_or_drug)
|
|
|
|
Examples:
|
|
python3 draw.py souls thing
|
|
python3 draw.py cook rumours 3
|
|
python3 draw.py creatures type appearance
|
|
python3 draw.py curiosities creepy_vibe
|
|
"""
|
|
|
|
import sys
|
|
import yaml
|
|
import random
|
|
import os
|
|
|
|
DECK_DIR = os.path.join(os.path.dirname(__file__), '..', 'rules', 'deck')
|
|
|
|
DECKS = {
|
|
'souls': 'souls.yaml',
|
|
'cook': 'cook.yaml',
|
|
'creatures': 'creatures.yaml',
|
|
'curiosities': 'curiosities.yaml',
|
|
}
|
|
|
|
def load_deck(name):
|
|
path = os.path.join(DECK_DIR, DECKS[name])
|
|
with open(path) as f:
|
|
return yaml.safe_load(f)
|
|
|
|
def draw_from_table(data, table_name):
|
|
entry = data.get(table_name)
|
|
if not entry:
|
|
print(f"Table '{table_name}' not found in deck.")
|
|
sys.exit(1)
|
|
|
|
table = entry.get('table')
|
|
if table:
|
|
keys = sorted(table.keys(), key=int)
|
|
roll = random.randint(keys[0], keys[-1])
|
|
result = table[roll]
|
|
if isinstance(result, dict):
|
|
return result.get('name', str(result)), roll
|
|
return result, roll
|
|
|
|
one_to_six = entry.get('animal_table') or entry.get('trinket_table')
|
|
if one_to_six and entry.get('has_table'):
|
|
r1 = random.randint(1, 6)
|
|
r2 = random.randint(1, 6)
|
|
return f"{one_to_six[r1]} and has {entry['has_table'][r2]}", f"{r1},{r2}"
|
|
|
|
faction_keys = [k for k in entry if k.startswith('table_')]
|
|
if faction_keys:
|
|
key = random.choice(faction_keys)
|
|
items = entry[key]['factions']
|
|
return random.choice(items), key
|
|
|
|
return None, None
|
|
|
|
def main():
|
|
if len(sys.argv) < 3:
|
|
print(__doc__.strip())
|
|
sys.exit(1)
|
|
|
|
deck_name = sys.argv[1].lower()
|
|
table_name = sys.argv[2].lower()
|
|
count = int(sys.argv[3]) if len(sys.argv) > 3 else 1
|
|
|
|
if deck_name not in DECKS:
|
|
print(f"Unknown deck '{deck_name}'. Choose from: {', '.join(DECKS.keys())}")
|
|
sys.exit(1)
|
|
|
|
data = load_deck(deck_name)
|
|
|
|
print(f"── [{deck_name}] drawing from '{table_name}' ──")
|
|
for _ in range(count):
|
|
result, roll = draw_from_table(data, table_name)
|
|
if result:
|
|
if roll is not None:
|
|
print(f" [{roll}] → {result}")
|
|
else:
|
|
print(f" → {result}")
|
|
else:
|
|
# Try direct pick from top-level
|
|
if table_name == 'rules':
|
|
print(" (No card — consult mechanics.md)")
|
|
else:
|
|
print(f" No result for '{table_name}'")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|