Wednesday, July 22, 2026

Foundry Arbitrary Pool Dice Roller

I roll a lot of arbitrary sets of dice and use Foundry, so I want a system that lets me roll a number of Hunger and non-Hunger dice that I choose. This macro just feeds into the Foundry World of Darkness 5e system I already have installed. To use it, just create a Macro and paste this as the code. This was mostly written by Gemini and tweaked a bit by me.

/**
 * V5 Prompted Roll Macro (Vampire: The Masquerade 5th Edition)
 *
 * This script displays a dialog box prompting the user for the number of
 * regular 'Vampire Dice' (dv) and 'Hunger Dice' (dg).
 * It then constructs the V5-specific roll formula (e.g., 4dv + 2dg) and
 * executes it by directly passing the command string to Foundry's chat processor,
 * ensuring the V5 system module correctly processes the roll result.
 */
(async () => {
    // --- 1. Define the HTML for the Dialog Form (Keeping accessibility improvements) ---
    const dialogContent = `
        <style>
            .v5-dialog-form .form-group {
                display: flex;
                flex-direction: column;
                margin-bottom: 10px;
            }
            .v5-dialog-form label {
                font-weight: bold;
                margin-bottom: 5px;
            }
            .v5-dialog-form input[type="number"] {
                padding: 5px;
                border: 1px solid #7a0000; /* V5 Theme Color */
                background: rgba(0,0,0,0.05);
                border-radius: 4px;
                text-align: center;
                /* Add a visual focus indicator for accessibility */
                transition: box-shadow 0.2s ease-in-out;
            }
            .v5-dialog-form input[type="number"]:focus {
                /* High-contrast focus ring for keyboard navigation */
                box-shadow: 0 0 0 2px #7a0000, 0 0 0 4px #ccc;
                outline: none;
            }
        </style>
        <form class="v5-dialog-form">
            <p>Enter the number of dice for your V5 roll:</p>
            <div class="form-group">
                <label for="vampire-dice">Vampire Dice (Normal Dice):</label>
                <input type="number" id="vampire-dice" name="vampire-dice" value="4" min="0" data-dtype="Number"
                       title="The number of standard dice (dv) for the roll." aria-label="Vampire Dice">
            </div>
            <div class="form-group">
                <label for="hunger-dice">Hunger Dice (Blood Dice):</label>
                <input type="number" id="hunger-dice" name="hunger-dice" value="2" min="0" data-dtype="Number"
                       title="The number of Hunger Dice (dg) for the roll." aria-label="Hunger Dice">
            </div>
        </form>
    `;

    // --- 2. Create and Render the Dialog ---
    new Dialog({
        title: "V5 Custom Roll Prompt",
        content: dialogContent,
        buttons: {
            roll: {
                icon: '<i class="fas fa-dice-d10"></i>',
                label: "Execute Roll",
                callback: (html) => {
                    // Extract values from the rendered dialog HTML
                    const vampireDice = parseInt(html.find('#vampire-dice').val()) || 0;
                    const hungerDice = parseInt(html.find('#hunger-dice').val()) || 0;

                    // Validation check
                    if ((vampireDice + hungerDice) <= 0) {
                        return ui.notifications.warn("Roll canceled: You must enter at least one die.");
                    }

                    // --- 3. Construct the Roll Formula ---
                    // The system uses 'dv' for Vampire Dice and 'dg' for Hunger Dice.
                    const formula = `${vampireDice}dv + ${hungerDice}dg`;
                    
                    // --- 4. Directly Execute the Roll Command via Chat UI Processor (The most reliable fix) ---
                    // This method is functionally equivalent to typing "/roll 4dv + 2dg" into the chat input
                    // and hitting enter, ensuring all necessary Foundry and V5 system hooks are triggered.
                    const commandString = `/roll ${formula} # V5 Custom Roll: ${vampireDice}V + ${hungerDice}H`;
                    
                    // ui.chat.processMessage is a dedicated method for executing chat commands.
                    ui.chat.processMessage(commandString);
                }
            },
            cancel: {
                icon: '<i class="fas fa-times"></i>',
                label: "Cancel"
            }
        },
        default: "roll"
    }).render(true);
})();

No comments:

Post a Comment