| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 |
- #!/bin/bash
- # Defaults
- FEAT_COUNT=1
- SUCCESS_COUNT=0
- ROLL_MODE="" # adv, disadv, or empty
- BONUS_VALUE=0 # bonus/debuff value
- # Macro configuration
- MACRO_FILE="$HOME/.tor-roller-macros"
- # Help function
- show_help() {
- echo "Usage: $0 [FEAT_DICE] [SUCCESS_DICE] [OPTIONS]"
- echo ""
- echo "Arguments:"
- echo " FEAT_DICE Number of 1d12 Feat Dice to roll (default: 1)"
- echo " SUCCESS_DICE Number of 1d6 Success Dice to roll (default: 0)"
- echo ""
- echo "Options:"
- echo " -h, --help Show this help message"
- echo " macro Use a saved macro (see --macro-help)"
- echo ""
- echo "Examples:"
- echo " $0 # Rolls 1 Feat Die"
- echo " $0 1 3 # Rolls 1 Feat Die and 3 Success Dice"
- echo " $0 2 0 # Rolls 2 Feat Dice"
- echo ""
- echo "Macro Examples:"
- echo " $0 --macro-help # Show macro usage"
- echo " $0 --save-macro hero 1 3 # Save macro named 'hero' with 1d12+3d6"
- echo " $0 --save-macro attack 2 4 adv # Save with advantage"
- echo " $0 --save-macro spell 1 2 disadv # Save with disadvantage"
- echo " $0 --save-macro skill 1 2 +5 # Save with +5 bonus"
- echo " $0 --list-macros # List all saved macros"
- echo " $0 hero # Use saved macro"
- exit 0
- }
- # Show macro help
- show_macro_help() {
- echo "Macro Usage:"
- echo ""
- echo "Save Macros:"
- echo " --save-macro NAME FEAT_DICE SUCCESS_DICE [ADV|DISADV] [BONUS]"
- echo " NAME: Name for the macro"
- echo " FEAT_DICE: Number of d12 dice (1-99)"
- echo " SUCCESS_DICE: Number of d6 dice (0-99)"
- echo " ADV: Advantage (roll 2 sets, keep highest)"
- echo " DISADV: Disadvantage (roll 2 sets, drop highest)"
- echo " BONUS: Bonus/debuff value (+5, -3, etc.)"
- echo ""
- echo "Examples:"
- echo " $0 --save-macro hero 1 3"
- echo " $0 --save-macro attack 2 4 adv"
- echo " $0 --save-macro spell 1 2 disadv"
- echo " $0 --save-macro skill 1 2 +5"
- echo ""
- echo "Use Macros:"
- echo " $0 MACRO_NAME"
- echo ""
- echo "List Macros:"
- echo " $0 --list-macros"
- echo ""
- echo "Delete Macros:"
- echo " $0 --delete-macro MACRO_NAME"
- echo ""
- exit 0
- }
- # Save a macro
- save_macro() {
- local name="$1"
- local feat="$2"
- local success="$3"
- local mode="$4"
- local bonus="$5"
-
- # Validate inputs
- if [[ ! "$feat" =~ ^[0-9]+$ ]] || [ "$feat" -lt 1 ] || [ "$feat" -gt 99 ]; then
- echo "Error: FEAT_DICE must be a number between 1 and 99"
- exit 1
- fi
-
- if [[ ! "$success" =~ ^[0-9]+$ ]] || [ "$success" -gt 99 ]; then
- echo "Error: SUCCESS_DICE must be a number between 0 and 99"
- exit 1
- fi
-
- # Handle mode and bonus arguments
- if [[ "$mode" == "adv" ]] || [[ "$mode" == "ADV" ]]; then
- mode="adv"
- bonus="$5"
- elif [[ "$mode" == "disadv" ]] || [[ "$mode" == "DISADV" ]]; then
- mode="disadv"
- bonus="$5"
- elif [[ "$mode" =~ ^[+-]?[0-9]+$ ]]; then
- # This is a bonus, mode is empty
- mode=""
- bonus="$4" # bonus is in the mode position
- else
- mode=""
- bonus="$4" # bonus is in the mode position if provided
- fi
-
- # Validate bonus if provided
- if [[ "$bonus" != "" ]] && [[ "$bonus" != "0" ]] && [[ ! "$bonus" =~ ^[+-]?[0-9]+$ ]]; then
- echo "Error: BONUS must be a number with + or - (e.g., +5, -3)"
- exit 1
- fi
-
- # If bonus is empty or not a number, set to 0
- if [[ "$bonus" == "" ]] || [[ ! "$bonus" =~ ^[+-]?[0-9]+$ ]]; then
- bonus="0"
- fi
-
- # Create macro entry
- local entry="$name|$feat|$success|$mode|$bonus"
-
- # Create directory if it doesn't exist
- mkdir -p "$(dirname "$MACRO_FILE")"
-
- # Remove existing macro with same name
- if [ -f "$MACRO_FILE" ]; then
- grep -v "^$name|" "$MACRO_FILE" > "${MACRO_FILE}.tmp" 2>/dev/null || true
- mv "${MACRO_FILE}.tmp" "$MACRO_FILE"
- fi
-
- # Add new macro
- echo "$entry" >> "$MACRO_FILE"
- echo "Macro '$name' saved successfully!"
- echo " Feat Dice: $feat d12, Success Dice: $success d6"
- if [[ "$mode" == "adv" ]]; then
- echo " Mode: Advantage"
- elif [[ "$mode" == "disadv" ]]; then
- echo " Mode: Disadvantage"
- fi
- if [[ "$bonus" != "0" ]]; then
- echo " Bonus: $bonus"
- fi
- exit 0
- }
- # List all macros
- list_macros() {
- echo "Saved Macros:"
- echo ""
- if [ ! -f "$MACRO_FILE" ]; then
- echo "No macros saved yet."
- echo ""
- echo "Use --save-macro to create a macro, or --macro-help for examples."
- exit 0
- fi
-
- printf "%-20s %-10s %-12s %-12s %s\n" "NAME" "FEAT_DICE" "SUCCESS_DICE" "MODE" "BONUS"
- printf "%-20s %-10s %-12s %-12s %s\n" "----" "---------" "------------" "----" "-----"
-
- while IFS='|' read -r name feat success mode bonus; do
- local mode_display="${mode:-(none)}"
- local bonus_display="$bonus"
- if [[ "$bonus" == "0" ]]; then
- bonus_display="(none)"
- fi
- printf "%-20s %-10s %-12s %-12s %s\n" "$name" "${feat}d12" "${success}d6" "$mode_display" "$bonus_display"
- done < "$MACRO_FILE"
- exit 0
- }
- # Delete a macro
- delete_macro() {
- local name="$1"
-
- if [ ! -f "$MACRO_FILE" ]; then
- echo "No macros saved yet."
- exit 1
- fi
-
- if ! grep -q "^$name|" "$MACRO_FILE"; then
- echo "Macro '$name' not found."
- exit 1
- fi
-
- # Remove the macro
- grep -v "^$name|" "$MACRO_FILE" > "${MACRO_FILE}.tmp"
- mv "${MACRO_FILE}.tmp" "$MACRO_FILE"
- echo "Macro '$name' deleted successfully!"
- exit 0
- }
- # Load and execute a macro
- load_macro() {
- local name="$1"
-
- if [ ! -f "$MACRO_FILE" ]; then
- echo "No macros saved yet. Use --save-macro to create one."
- exit 1
- fi
-
- local macro_data=$(grep "^$name|" "$MACRO_FILE")
- if [ -z "$macro_data" ]; then
- echo "Macro '$name' not found. Use --list-macros to see available macros."
- exit 1
- fi
-
- # Parse macro data
- IFS='|' read -r macro_name feat success mode bonus <<< "$macro_data"
-
- echo "Using macro: $name"
- echo ""
-
- # Set global variables for rolling
- FEAT_COUNT=$feat
- SUCCESS_COUNT=$success
- ROLL_MODE=$mode
- BONUS_VALUE=$bonus
- }
- # Check for help flag
- if [[ "$1" == "-h" || "$1" == "--help" ]]; then
- show_help
- fi
- # Check for macro commands
- if [[ "$1" == "--macro-help" ]]; then
- show_macro_help
- elif [[ "$1" == "--save-macro" ]]; then
- if [ "$#" -lt 4 ]; then
- echo "Error: --save-macro requires NAME FEAT_DICE SUCCESS_DICE"
- echo "Use --macro-help for examples"
- exit 1
- fi
- save_macro "$2" "$3" "$4" "$5" "$6"
- elif [[ "$1" == "--list-macros" ]]; then
- list_macros
- elif [[ "$1" == "--delete-macro" ]]; then
- if [ "$#" -lt 2 ]; then
- echo "Error: --delete-macro requires MACRO_NAME"
- exit 1
- fi
- delete_macro "$2"
- fi
- # Check if using a saved macro
- if [ "$#" -eq 1 ] && [ "$1" != "" ]; then
- # Check if it's a macro name (not numeric)
- if ! [[ "$1" =~ ^[0-9]+$ ]]; then
- load_macro "$1"
- # Macro will set FEAT_COUNT, SUCCESS_COUNT, etc.
- else
- FEAT_COUNT=$1
- fi
- elif [[ "$1" =~ ^[0-9]+$ ]]; then
- FEAT_COUNT=$1
- if [[ "$2" =~ ^[0-9]+$ ]]; then
- SUCCESS_COUNT=$2
- fi
- fi
- # Colors and formatting
- BOLD='\033[1m'
- RED='\033[31m'
- GREEN='\033[32m'
- CYAN='\033[36m' # Using Cyan for Gandalf as it's bright/distinct
- RESET='\033[0m'
- # Function to generate a random number between 1 and max
- roll() {
- local max=$1
- # Read 2 bytes from /dev/urandom, convert to decimal, modulo max, add 1
- # This provides better randomness than $RANDOM
- val=$(od -An -N2 -tu2 /dev/urandom)
- echo $(( (val % max) + 1 ))
- }
- gum spin --spinner moon --title "🔮 Consulting Palantir..." -- sleep 1
- echo ""
- # Display macro name if using one
- if [ -n "$macro_name" ]; then
- if [[ "$ROLL_MODE" == "adv" ]]; then
- echo "Mode: Advantage (roll 2 sets, keep highest)"
- elif [[ "$ROLL_MODE" == "disadv" ]]; then
- echo "Mode: Disadvantage (roll 2 sets, drop highest)"
- fi
- if [[ "$BONUS_VALUE" != "0" ]]; then
- if [[ "$BONUS_VALUE" =~ ^- ]]; then
- echo "Effect: $BONUS_VALUE (debuff)"
- else
- echo "Effect: $BONUS_VALUE (bonus)"
- fi
- fi
- echo ""
- fi
- TOTAL=0
- # Roll Feat Dice (1d12)
- if [ "$FEAT_COUNT" -gt 0 ]; then
- echo -n -e "Feat Dice (${FEAT_COUNT}d12 ): "
-
- # Handle advantage/disadvantage for Feat Dice
- if [[ "$ROLL_MODE" == "adv" ]]; then
- echo -n "Set 1: "
- total_set1=0
- for ((i=0; i<FEAT_COUNT; i++)); do
- RESULT=$(roll 12)
- total_set1=$((total_set1 + RESULT))
-
- if [ "$RESULT" -eq 1 ]; then
- echo -n -e "[ ${BOLD}${RED}1 (EYE)${RESET} ] "
- elif [ "$RESULT" -eq 12 ]; then
- echo -n -e "[ ${BOLD}${CYAN}12 (GANDALF)${RESET} ] "
- else
- echo -n "[ $RESULT ] "
- fi
- done
-
- echo -n -e " | Set 2: "
- total_set2=0
- for ((i=0; i<FEAT_COUNT; i++)); do
- RESULT=$(roll 12)
- total_set2=$((total_set2 + RESULT))
-
- if [ "$RESULT" -eq 1 ]; then
- echo -n -e "[ ${BOLD}${RED}1 (EYE)${RESET} ] "
- elif [ "$RESULT" -eq 12 ]; then
- echo -n -e "[ ${BOLD}${CYAN}12 (GANDALF)${RESET} ] "
- else
- echo -n "[ $RESULT ] "
- fi
- done
-
- if [ $total_set1 -ge $total_set2 ]; then
- TOTAL=$((TOTAL + total_set1))
- echo -e " (Kept: $total_set1)"
- else
- TOTAL=$((TOTAL + total_set2))
- echo -e " (Kept: $total_set2)"
- fi
-
- elif [[ "$ROLL_MODE" == "disadv" ]]; then
- echo -n "Set 1: "
- total_set1=0
- for ((i=0; i<FEAT_COUNT; i++)); do
- RESULT=$(roll 12)
- total_set1=$((total_set1 + RESULT))
-
- if [ "$RESULT" -eq 1 ]; then
- echo -n -e "[ ${BOLD}${RED}1 (EYE)${RESET} ] "
- elif [ "$RESULT" -eq 12 ]; then
- echo -n -e "[ ${BOLD}${CYAN}12 (GANDALF)${RESET} ] "
- else
- echo -n "[ $RESULT ] "
- fi
- done
-
- echo -n -e " | Set 2: "
- total_set2=0
- for ((i=0; i<FEAT_COUNT; i++)); do
- RESULT=$(roll 12)
- total_set2=$((total_set2 + RESULT))
-
- if [ "$RESULT" -eq 1 ]; then
- echo -n -e "[ ${BOLD}${RED}1 (EYE)${RESET} ] "
- elif [ "$RESULT" -eq 12 ]; then
- echo -n -e "[ ${BOLD}${CYAN}12 (GANDALF)${RESET} ] "
- else
- echo -n "[ $RESULT ] "
- fi
- done
-
- if [ $total_set1 -le $total_set2 ]; then
- TOTAL=$((TOTAL + total_set1))
- echo -e " (Kept: $total_set1)"
- else
- TOTAL=$((TOTAL + total_set2))
- echo -e " (Kept: $total_set2)"
- fi
-
- else
- # Normal rolling
- for ((i=0; i<FEAT_COUNT; i++)); do
- RESULT=$(roll 12)
- ((TOTAL+=RESULT))
-
- if [ "$RESULT" -eq 1 ]; then
- # Eye of Mordor
- echo -n -e "[ ${BOLD}${RED}1 (EYE)${RESET} ] "
- elif [ "$RESULT" -eq 12 ]; then
- # Gandalf
- echo -n -e "[ ${BOLD}${CYAN}12 (GANDALF)${RESET} ] "
- else
- echo -n "[ $RESULT ] "
- fi
- done
- fi
- echo ""
- fi
- # Roll Success Dice (1d6)
- if [ "$SUCCESS_COUNT" -gt 0 ]; then
- echo -n -e "Success Dice (${SUCCESS_COUNT}d6 ): "
-
- # Handle advantage/disadvantage for Success Dice
- if [[ "$ROLL_MODE" == "adv" ]]; then
- echo -n "Set 1: "
- total_set1=0
- for ((i=0; i<SUCCESS_COUNT; i++)); do
- RESULT=$(roll 6)
- total_set1=$((total_set1 + RESULT))
-
- if [ "$RESULT" -eq 6 ]; then
- echo -n -e "[ ${BOLD}${GREEN}6 (MAGNIFICENT)${RESET} ] "
- else
- echo -n "[ $RESULT ] "
- fi
- done
-
- echo -n -e " | Set 2: "
- total_set2=0
- for ((i=0; i<SUCCESS_COUNT; i++)); do
- RESULT=$(roll 6)
- total_set2=$((total_set2 + RESULT))
-
- if [ "$RESULT" -eq 6 ]; then
- echo -n -e "[ ${BOLD}${GREEN}6 (MAGNIFICENT)${RESET} ] "
- else
- echo -n "[ $RESULT ] "
- fi
- done
-
- if [ $total_set1 -ge $total_set2 ]; then
- TOTAL=$((TOTAL + total_set1))
- echo -e " (Kept: $total_set1)"
- else
- TOTAL=$((TOTAL + total_set2))
- echo -e " (Kept: $total_set2)"
- fi
-
- elif [[ "$ROLL_MODE" == "disadv" ]]; then
- echo -n "Set 1: "
- total_set1=0
- for ((i=0; i<SUCCESS_COUNT; i++)); do
- RESULT=$(roll 6)
- total_set1=$((total_set1 + RESULT))
-
- if [ "$RESULT" -eq 6 ]; then
- echo -n -e "[ ${BOLD}${GREEN}6 (MAGNIFICENT)${RESET} ] "
- else
- echo -n "[ $RESULT ] "
- fi
- done
-
- echo -n -e " | Set 2: "
- total_set2=0
- for ((i=0; i<SUCCESS_COUNT; i++)); do
- RESULT=$(roll 6)
- total_set2=$((total_set2 + RESULT))
-
- if [ "$RESULT" -eq 6 ]; then
- echo -n -e "[ ${BOLD}${GREEN}6 (MAGNIFICENT)${RESET} ] "
- else
- echo -n "[ $RESULT ] "
- fi
- done
-
- if [ $total_set1 -le $total_set2 ]; then
- TOTAL=$((TOTAL + total_set1))
- echo -e " (Kept: $total_set1)"
- else
- TOTAL=$((TOTAL + total_set2))
- echo -e " (Kept: $total_set2)"
- fi
-
- else
- # Normal rolling
- for ((i=0; i<SUCCESS_COUNT; i++)); do
- RESULT=$(roll 6)
- ((TOTAL+=RESULT))
-
- if [ "$RESULT" -eq 6 ]; then
- # Magnificent Outcome
- echo -n -e "[ ${BOLD}${GREEN}6 (MAGNIFICENT)${RESET} ] "
- else
- echo -n "[ $RESULT ] "
- fi
- done
- fi
- echo ""
- fi
- # Apply bonus/debuff
- if [[ "$BONUS_VALUE" != "0" ]]; then
- if [[ "$BONUS_VALUE" =~ ^- ]]; then
- TOTAL=$((TOTAL + BONUS_VALUE)) # BONUS_VALUE is negative
- echo -e "\n${BOLD}Total Face Value (before debuff): $((TOTAL - BONUS_VALUE))${RESET}"
- echo -e "${BOLD}Final Total (after ${BONUS_VALUE} debuff): $TOTAL${RESET}"
- else
- TOTAL=$((TOTAL + BONUS_VALUE))
- echo -e "\n${BOLD}Total Face Value (before bonus): $((TOTAL - BONUS_VALUE))${RESET}"
- echo -e "${BOLD}Final Total (after ${BONUS_VALUE} bonus): $TOTAL${RESET}"
- fi
- else
- echo -e "\n${BOLD}Total Face Value: $TOTAL${RESET}"
- fi
|