Hero system die roller in python

import random

def roll_d6(n=1):
    return [random.randint(1, 6) for _ in range(n)]

def knockback_roll(modifier=0):
    knockback = sum(roll_d6(2)) – modifier
    knockback = max(knockback, 0)
    print(f”Knockback Roll (2d6 – {modifier}): {knockback} = {knockback * 2} meters\n”)
    return knockback

def normal_damage_dice(n, show_knockback=False):
    rolls = roll_d6(n)
    stun = sum(rolls)
    body = sum(1 if r == 1 else 2 if r in [2, 3, 4, 5] else 3 for r in rolls)
    print(f”[Normal Damage] Rolled: {rolls}”)
    print(f”STUN: {stun} | BODY: {body}”)
    if show_knockback:
        knockback_roll()
    print()
    return rolls, stun, body

def killing_damage_dice(n, show_knockback=False):
    rolls = roll_d6(n)
    body = sum(rolls)

    hit_location_roll = roll_d6(3)
    total = sum(hit_location_roll)
    if total <= 3:
        multiplier = 1
    elif total <= 6:
        multiplier = 2
    elif total <= 8:
        multiplier = 3
    elif total <= 11:
        multiplier = 4
    else:
        multiplier = 5

    stun = body * multiplier
    print(f”[Killing Damage] Rolled: {rolls}”)
    print(f”BODY: {body} | Hit Location Roll: {hit_location_roll} (x{multiplier}) | STUN: {stun}”)
    if show_knockback:
        knockback_roll()
    print()
    return rolls, body, stun

def skill_roll(target_number):
    roll = sum(roll_d6(3))
    success = roll <= target_number
    print(f”\n[Skill Roll] Roll: {roll} vs Target: {target_number} –> {‘Success!’ if success else ‘Failure.’}\n”)
    return roll, success

def main():
    print(“=== HERO SYSTEM DICE ROLLER ===”)
    while True:
        print(“\nChoose a roll type:”)
        print(“1. Normal Damage”)
        print(“2. Killing Damage”)
        print(“3. Skill Roll”)
        print(“4. Quit”)

        choice = input(“Enter your choice (1-4): “).strip()

        if choice in [‘1’, ‘2’]:
            num_dice = int(input(“How many dice per roll? “))
            num_sets = int(input(“How many sets to roll? “))
            use_knockback = input(“Include knockback? (y/n): “).strip().lower() == ‘y’
            kb_mod = 0
            if use_knockback:
                try:
                    kb_mod = int(input(“Knockback modifier (usually 0): “))
                except:
                    print(“Invalid modifier, defaulting to 0.”)

            for i in range(num_sets):
                print(f”\n— Set {i+1} —“)
                if choice == ‘1’:
                    normal_damage_dice(num_dice, show_knockback=use_knockback)
                else:
                    killing_damage_dice(num_dice, show_knockback=use_knockback)

        elif choice == ‘3’:
            target = int(input(“Enter skill roll target number: “))
            skill_roll(target)

        elif choice == ‘4’:
            print(“Goodbye!”)
            break
        else:
            print(“Invalid option. Please choose 1-4.”)

if __name__ == “__main__”:
    main()

Leave a Reply