04-27-2022, 09:14 PM
Code: (Select All)
SCREEN _NEWIMAGE(1024, 720, 32)
_SCREENMOVE _MIDDLE
CONST DiagRollEm = -1
'The next lines are only needed for manual testing
DIM DiceToRoll AS DiceRoller_Type
DIM SHARED Brief AS LONG
'Feel free to change options as wanted for your program
'DiceToRoll.NumberOfDice = 2
'DiceToRoll.DiceSides = 10
'DiceToRoll.DiceReroll = "=1"
'DiceToRoll.DiceOpenRoll = "=10"
'DiceToRoll.DiceMod = 2
'DiceToRoll.DiceKeepHigh = 1
'DiceToRoll.DiceKeepLow = 1
'DiceToRoll.Set = 10
'DiceToRoll.SetMod = 1
'DiceToRoll.SetReRoll = "<6"
'DiceToRoll.SetOpenRoll = ">10"
'DiceToRoll.TotalMod = 27
'DiceToRoll.SetKeepHigh = 9
PRINT RollEm$("10skh9r2;2d10o20;t2;b2")
PRINT
PRINT "PRESS <ANY KEY> TO CONTINUE"
SLEEP
PRINT
ClearDice
DiceToRoll.Set = 6
DiceToRoll.NumberOfDice = 4
DiceToRoll.DiceSides = 6
DiceToRoll.DiceKeepHigh = 3
Brief = 0
PRINT "NON-BRIEF OUTPUT:"
PRINT "'6s; 4d6 kh3' -- Roll 6 sets of 4 six-sided dice, keep the three highest"
PRINT DiceRoll$
PRINT
PRINT "PRESS <ANY KEY> TO CONTINUE"
SLEEP
PRINT
Brief = 1
PRINT "SEMI-BRIEF OUTPUT:"
PRINT "'6s; 4d6 kh3' -- Roll 6 sets of 4 six-sided dice, keep the three highest"
PRINT DiceRoll$
PRINT
PRINT "PRESS <ANY KEY> TO CONTINUE"
SLEEP
PRINT
Brief = 2
PRINT "MOST BRIEF OUTPUT:"
PRINT "'6s; 4d6 kh3' -- Roll 6 sets of 4 six-sided dice, keep the three highest"
PRINT DiceRoll$
PRINT
PRINT "PRESS <ANY KEY> TO CONTINUE"
SLEEP
PRINT
TYPE DiceRoller_Type
Set AS LONG
SetMod AS LONG
SetReRoll AS STRING * 100
SetOpenRoll AS STRING * 100
SetKeepHigh AS LONG
SetKeepLow AS LONG
SetDiscardHigh AS LONG
SetDiscardLow AS LONG
NumberOfDice AS LONG
DiceSides AS LONG
DiceMod AS LONG
DiceReroll AS STRING * 100
DiceOpenRoll AS STRING * 100
DiceKeepHigh AS LONG
DiceKeepLow AS LONG
DiceDiscardHigh AS LONG
DiceDiscardLow AS LONG
TotalMod AS LONG
END TYPE
SUB StripNumber (m$)
v = VAL(m$)
DO UNTIL v = 0
'PRINT "Stripping number"; m$
m$ = MID$(m$, 2)
v = VAL(m$)
LOOP
DO UNTIL LEFT$(m$, 1) <> "0" 'strip any zeros
m$ = MID$(m$, 2)
LOOP
END SUB
SUB ClearDice
SHARED DiceToRoll AS DiceRoller_Type
DiceToRoll.Set = 0
DiceToRoll.SetMod = 0
DiceToRoll.SetReRoll = ""
DiceToRoll.NumberOfDice = 0
DiceToRoll.DiceSides = 0
DiceToRoll.DiceMod = 0
DiceToRoll.DiceReroll = ""
DiceToRoll.DiceOpenRoll = ""
DiceToRoll.DiceKeepHigh = 0
DiceToRoll.DiceKeepLow = 0
DiceToRoll.DiceDiscardHigh = 0
DiceToRoll.DiceDiscardLow = 0
DiceToRoll.TotalMod = 0
END SUB
FUNCTION DiceRoll$
SHARED Brief AS LONG
SHARED DiceToRoll AS DiceRoller_Type
IF DiceToRoll.DiceKeepHigh OR DiceToRoll.DiceKeepLow THEN
IF DiceToRoll.DiceDiscardHigh OR DiceToRoll.DiceDiscardLow THEN DiceRoll$ = "Error - Can not keep and discard at the same time.": EXIT FUNCTION
END IF
IF DiceToRoll.NumberOfDice < 1 THEN DiceRoll$ = "Error - No dice to roll!": EXIT FUNCTION
RANDOMIZE TIMER
SHARED DiceToRoll AS DiceRoller_Type
REDIM rolls(0) AS LONG
REDIM SetRolls(0) AS LONG
SetCount = 0
IF Brief = 2 THEN out$ = "("
FOR j = 1 TO DiceToRoll.Set
ReRollSet:
SetTotal = 0
IF Brief = 0 THEN
out$ = out$ + "RAW: ("
ELSEIF Brief = 1 THEN
out$ = out$ + "("
END IF
rollcount = -1
FOR i = 1 TO DiceToRoll.NumberOfDice
ReRollDice:
roll = INT(RND(1) * DiceToRoll.DiceSides) + 1
IF ParseDiceOption(roll, DiceToRoll.DiceReroll) THEN
DiceOK = 0
IF Brief = 0 THEN out$ = out$ + "r" + _TRIM$(STR$(roll)) + ", "
GOTO ReRollDice
END IF
IF ParseDiceOption(roll, DiceToRoll.DiceOpenRoll) THEN
DiceOK = 0
DiceTotal = DiceTotal + roll + DiceToRoll.DiceMod
IF Brief = 0 THEN
out$ = out$ + _TRIM$(STR$(roll)) + "o"
IF DiceToRoll.DiceMod THEN out$ = out$ + " + " + _TRIM$(STR$(DiceToRoll.DiceMod))
out$ = out$ + ","
END IF
rollcount = rollcount + 1
REDIM _PRESERVE rolls(rollcount) AS LONG 'make certain we dont get out of bound errors for crazy reroll scenarios
rolls(rollcount) = roll + DiceToRoll.DiceMod
GOTO ReRollDice
END IF
rollcount = rollcount + 1
REDIM _PRESERVE rolls(rollcount) AS LONG 'make certain we dont get out of bound errors for crazy reroll scenarios
rolls(rollcount) = roll + DiceToRoll.DiceMod
DiceTotal = DiceTotal + roll + DiceToRoll.DiceMod
IF Brief = 0 THEN
out$ = out$ + _TRIM$(STR$(roll))
IF DiceToRoll.DiceMod THEN out$ = out$ + " + " + _TRIM$(STR$(DiceToRoll.DiceMod))
IF i < DiceToRoll.NumberOfDice THEN 'more dice to roll in this set
out$ = out$ + ", "
ELSE 'we're finished
out$ = out$ + ")"
END IF
END IF
NEXT
IF rollcount > 0 THEN Sort rolls() 'No need to try and sort only 1 dice.
IF Brief = 0 THEN
out$ = out$ + "; SORTED: ("
FOR i = 0 TO rollcount
out$ = out$ + _TRIM$(STR$(rolls(i)))
IF i < rollcount THEN out$ = out$ + ", " ELSE out$ = out$ + ")"
NEXT
END IF
REDIM keep(rollcount) AS LONG
IF DiceToRoll.DiceKeepHigh OR DiceToRoll.DiceKeepLow THEN
IF DiceToRoll.DiceKeepHigh THEN
FOR i = DiceToRoll.DiceKeepHigh - 1 TO 0 STEP -1
IF i < rollcount THEN keep(rollcount - i) = -1
NEXT
END IF
IF DiceToRoll.DiceKeepLow THEN
FOR i = 0 TO DiceToRoll.DiceKeepLow - 1
IF i < rollcount THEN keep(i) = -1
NEXT
END IF
ELSEIF DiceToRoll.DiceDiscardHigh OR DiceToRoll.DiceDiscardLow THEN
FOR i = 0 TO rollcount
keep(i) = -1
NEXT
IF DiceToRoll.DiceDiscardHigh THEN
FOR i = DiceToRoll.DiceDiscardHigh - 1 TO 0 STEP -1
IF i < rollcount THEN keep(rollcount - i) = 0
NEXT
END IF
IF DiceToRoll.DiceDiscardLow THEN
FOR i = 0 TO DiceToRoll.DiceDiscardLow - 1
IF i < rollcount THEN keep(i) = 0
NEXT
END IF
ELSE
FOR i = 0 TO rollcount
keep(i) = -1
NEXT
END IF
IF Brief = 0 THEN out$ = out$ + "; KEEP: ("
KeepTotal = 0
kept = 0
FOR i = 0 TO rollcount
IF keep(i) THEN
kept = kept + 1
IF Brief < 2 THEN
IF kept > 1 THEN out$ = out$ + ", "
out$ = out$ + _TRIM$(STR$(rolls(i)))
END IF
KeepTotal = KeepTotal + rolls(i)
END IF
NEXT
IF Brief < 2 THEN out$ = out$ + ") = " + _TRIM$(STR$(KeepTotal))
IF ParseDiceOption(KeepTotal, DiceToRoll.SetReRoll) THEN
IF Brief < 2 THEN out$ = out$ + "r" + CHR$(13)
GOTO ReRollSet
END IF
IF ParseDiceOption(KeepTotal, DiceToRoll.SetOpenRoll) THEN
SetTotal = SetTotal + KeepTotal + DiceToRoll.SetMod
SetCount = SetCount + 1
REDIM _PRESERVE SetRolls(SetCount) AS LONG
SetRolls(SetCount) = SetTotal
GrandTotal = GrandTotal + SetTotal
IF Brief = 2 THEN out$ = out$ + _TRIM$(STR$(SetTotal))
out$ = out$ + "o"
IF Brief < 2 THEN
IF DiceToRoll.SetMod THEN out$ = out$ + " + " + _TRIM$(STR$(DiceToRoll.SetMod))
out$ = out$ + " = " + _TRIM$(STR$(SetTotal))
out$ = out$ + CHR$(13)
ELSE
out$ = out$ + ", "
END IF
GOTO ReRollSet
END IF
SetTotal = SetTotal + KeepTotal + DiceToRoll.SetMod
SetCount = SetCount + 1
REDIM _PRESERVE SetRolls(SetCount) AS LONG
SetRolls(SetCount) = SetTotal
GrandTotal = GrandTotal + SetTotal
IF Brief < 2 THEN
IF DiceToRoll.SetMod THEN
out$ = out$ + " + " + _TRIM$(STR$(DiceToRoll.SetMod))
out$ = out$ + " = " + _TRIM$(STR$(SetTotal))
END IF
out$ = out$ + CHR$(13)
ELSE
out$ = out$ + _TRIM$(STR$(SetTotal))
IF j < DiceToRoll.Set THEN out$ = out$ + ", " ELSE out$ = out$ + ")"
END IF
NEXT
IF Brief < 2 THEN out$ = out$ + CHR$(13) + "GRAND TOTAL:"
IF DiceToRoll.TotalMod THEN
IF Brief < 2 THEN out$ = out$ + STR$(GrandTotal) + " +" + STR$(DiceToRoll.TotalMod)
END IF
GrandTotal = GrandTotal + DiceToRoll.TotalMod
out$ = out$ + " =" + STR$(GrandTotal)
Sort SetRolls()
IF Brief = 0 THEN
out$ = out$ + CHR$(13) + CHR$(13) + "Sorted Set: ("
FOR i = 1 TO SetCount
out$ = out$ + _TRIM$(STR$(SetRolls(i)))
IF i < SetCount THEN out$ = out$ + ", " ELSE out$ = out$ + ")"
NEXT
END IF
REDIM keep(SetCount) AS LONG
IF DiceToRoll.SetKeepHigh OR DiceToRoll.SetKeepLow THEN
IF DiceToRoll.SetKeepHigh THEN
FOR i = DiceToRoll.SetKeepHigh - 1 TO 0 STEP -1
IF i < SetCount THEN keep(SetCount - i) = -1
NEXT
END IF
IF DiceToRoll.SetKeepLow THEN
FOR i = 0 TO DiceToRoll.SetKeepLow - 1
IF i < SetCount THEN keep(i) = -1
NEXT
END IF
ELSEIF DiceToRoll.SetDiscardHigh OR DiceToRoll.SetDiscardLow THEN
FOR i = 0 TO SetCount
keep(i) = -1
NEXT
IF DiceToRoll.SetDiscardHigh THEN
FOR i = DiceToRoll.SetDiscardHigh - 1 TO 0 STEP -1
IF i < SetCount THEN keep(SetCount - i) = 0
NEXT
END IF
IF DiceToRoll.SetDiscardLow THEN
FOR i = 0 TO DiceToRoll.SetDiscardLow - 1
IF i < SetCount THEN keep(i) = 0
NEXT
END IF
ELSE
FOR i = 0 TO SetCount
keep(i) = -1
NEXT
END IF
out$ = out$ + CHR$(13) + "Set Kept: ("
IF Brief = 2 THEN out$ = "("
KeepTotal = 0
keep = 0
FOR i = 1 TO SetCount
IF keep(i) THEN
keep = keep + 1
IF keep > 1 THEN out$ = out$ + ", "
out$ = out$ + _TRIM$(STR$(SetRolls(i)))
KeepTotal = KeepTotal + SetRolls(i)
END IF
NEXT
KeepTotal = KeepTotal + DiceToRoll.TotalMod
out$ = out$ + ") = " + _TRIM$(STR$(KeepTotal))
DiceRoll$ = out$
END FUNCTION
FUNCTION ParseDiceOption (num, t_temp$)
SHARED DiceToRoll AS DiceRoller_Type
temp$ = _TRIM$(t_temp$)
IF temp$ = "" THEN EXIT FUNCTION
IF RIGHT$(temp$, 1) <> "," THEN temp$ = temp$ + ","
DO
f = INSTR(temp$, ",")
IF f THEN
o$ = LEFT$(temp$, f - 1)
temp$ = MID$(temp$, f + 1)
o = VAL(MID$(o$, 2))
o$ = LEFT$(o$, 1)
SELECT CASE o$
CASE "=": IF num = o THEN ParseDiceOption = -1: EXIT FUNCTION
CASE "<": IF num < o THEN ParseDiceOption = -1: EXIT FUNCTION
CASE ">": IF num > o THEN ParseDiceOption = -1: EXIT FUNCTION
END SELECT
END IF
LOOP UNTIL f = 0 OR temp$ = ""
END FUNCTION
SUB Sort (Array() AS LONG)
'The dice sorting routine, optimized to use _MEM and a comb sort algorithm.
'It's more than fast enough for our needs here I think. ;)
DIM m AS _MEM
DIM o AS _OFFSET, o1 AS _OFFSET
DIM t AS LONG, t1 AS LONG
m = _MEM(Array())
$CHECKING:OFF
gap = rollcount
DO
gap = 10 * gap \ 13
IF gap < 1 THEN gap = 1
i = 0
swapped = 0
DO
o = m.OFFSET + i * 4
o1 = m.OFFSET + (i + gap) * 4
IF _MEMGET(m, o, LONG) > _MEMGET(m, o1, LONG) THEN
_MEMGET m, o1, t1
_MEMGET m, o, t
_MEMPUT m, o1, t
_MEMPUT m, o, t1
swapped = -1
END IF
i = i + 1
LOOP UNTIL i + gap > UBOUND(Array)
LOOP UNTIL swapped = 0 AND gap = 1
$CHECKING:ON
_MEMFREE m
END SUB
FUNCTION RollEm$ (temp$)
SHARED DiceToRoll AS DiceRoller_Type
text1$ = UCASE$(temp$)
FOR i = 1 TO LEN(text1$) 'check for invalid characters
m$ = MID$(text1$, i, 1)
SELECT CASE m$
CASE "0" TO "9", "+", "-", "D", "K", "H", "L", "S", "T", ";", "=", "<", ">", ",", "R", "O", "B"
text$ = text$ + m$ 'add valid characters to make text$
CASE " " 'do nothing to a space
CASE ELSE
'invalid
END SELECT
NEXT
'IF DiagRollEM THEN PRINT "Verified: "; text$
IF text$ = "" THEN EXIT SUB 'can't do nothing with an empty string
ClearDice
DO
semicolon = INSTR(text$, ";")
IF semicolon THEN
l$ = LEFT$(text$, semicolon - 1)
text$ = MID$(text$, semicolon + 1)
ELSE
l$ = text$
END IF
'IF DiagRollEM THEN PRINT "PROCESSING: "; l$
found = 0
s = INSTR(l$, "S"): IF s THEN found = found + 1
d = INSTR(l$, "D"): IF d THEN found = found + 1
t = INSTR(l$, "T"): IF t THEN found = found + 1
b = INSTR(l$, "B"): IF b THEN found = found + 1
IF found <> 1 THEN EXIT SUB 'we should only find ONE element each pass, and there should always be one. IF not, somebody screwed up.
IF s THEN
DiceToRoll.Set = VAL(LEFT$(l$, s - 1))
IF DiagRollEm THEN PRINT "Number of Sets = "; DiceToRoll.Set
m$ = MID$(l$, s + 1)
pass = 0
DO UNTIL m$ = ""
pass = pass + 1
'IF DiagRollEM THEN PRINT "SUBPROC "; m$
n$ = LEFT$(m$, 1)
IF n$ = "K" OR n$ = "D" THEN n$ = LEFT$(m$, 2)
m$ = MID$(m$, LEN(n$) + 1)
v = VAL(m$)
SELECT CASE n$
CASE "+" '+ set mod
IF v > 0 THEN DiceToRoll.SetMod = v
IF DiagRollEm THEN PRINT "Set Mod"; v
CASE "-" ' - set mod
IF v > 0 THEN DiceToRoll.SetMod = -v
IF DiagRollEm THEN PRINT "Set Mod"; v
CASE "KH" 'keep high
IF v > 0 THEN DiceToRoll.SetKeepHigh = v
IF DiagRollEm THEN PRINT "Keep the Highest"; v; " Sets"
CASE "KL"
IF v > 0 THEN DiceToRoll.SetKeepLow = v
IF DiagRollEm THEN PRINT "Keep the Lowest"; v; " Sets"
CASE "DH"
IF v > 0 THEN DiceToRoll.SetDiscardHigh = v
IF DiagRollEm THEN PRINT "Discard the Highest"; v; " Sets"
CASE "DL"
IF v > 0 THEN DiceToRoll.SetDiscardLow = v
IF DiagRollEm THEN PRINT "Discard the Lowest"; v; " Sets"
CASE "R", "O" 'reroll or open roll
finished = 0: t$ = "": innerpass = 0
DO UNTIL finished
innerpass = innerpass + 1
v = VAL(m$)
IF v <> 0 THEN 'it's an o/r followed by a number
t$ = t$ + "=" + _TRIM$(STR$(v)) + ","
ELSE
n1$ = LEFT$(m$, 1)
SELECT CASE n1$
CASE "="
m$ = MID$(m$, 2)
v = VAL(m$)
t$ = t$ + "=" + _TRIM$(STR$(v)) + ","
CASE "<"
m$ = MID$(m$, 2)
v = VAL(m$)
t$ = t$ + "<" + _TRIM$(STR$(v)) + ","
CASE ">"
m$ = MID$(m$, 2)
v = VAL(m$)
t$ = t$ + ">" + _TRIM$(STR$(v)) + ","
CASE ","
m$ = MID$(m$, 2)
CASE ELSE 'a character not a number, or =<>,
finished = -1
END SELECT
END IF
StripNumber m$
IF n$ = "R" THEN
DiceToRoll.SetReRoll = t$
IF DiagRollEm THEN PRINT "Reroll Sets "; DiceToRoll.SetReRoll
ELSE
DiceToRoll.SetOpenRoll = t$
IF DiagRollEm THEN PRINT "Openroll Sets "; DiceToRoll.SetOpenRoll
END IF
IF m$ = "" THEN finished = -1
IF innerpass > 255 THEN IF DiagRollEm THEN PRINT "Error -- Too many loops processing Set ReRoll or OpenRoll": EXIT FUNCTION
LOOP
END SELECT
StripNumber m$
n$ = LEFT$(m$, 1)
SELECT CASE n$
CASE "K", "D", "R", "O", "+", "-" 'see if it's another command without a comma
CASE ELSE
comma = INSTR(m$, ",")
IF comma THEN m$ = MID$(m$, comma + 1)
END SELECT
IF pass > 100 THEN IF DiagRollEm THEN PRINT "Error - endless processing loop deciphering SET information": EXIT FUNCTION
LOOP
END IF
IF d THEN
v = VAL(LEFT$(l$, d))
IF v < 1 THEN DiceToRoll.NumberOfDice = 1 ELSE DiceToRoll.NumberOfDice = v
IF DiagRollEm THEN PRINT "Number of Dice To Roll = "; DiceToRoll.NumberOfDice
m$ = MID$(l$, d + 1)
v = VAL(m$)
IF v > 0 THEN DiceToRoll.DiceSides = v
StripNumber m$
IF DiagRollEm THEN PRINT "Dice Sides = "; DiceToRoll.DiceSides
pass = 0
DO UNTIL m$ = ""
pass = pass + 1
'IF DiagRollEM THEN PRINT "SUBPROC "; m$
n$ = LEFT$(m$, 1)
IF n$ = "K" OR n$ = "D" THEN n$ = LEFT$(m$, 2)
m$ = MID$(m$, LEN(n$) + 1)
v = VAL(m$)
SELECT CASE n$
CASE "+" '+ set mod
IF v > 0 THEN DiceToRoll.DiceMod = v
IF DiagRollEm THEN PRINT "DM"; v
CASE "-" ' - set mod
IF v > 0 THEN DiceToRoll.DiceMod = -v
IF DiagRollEm THEN PRINT "DM"; v
CASE "KH" 'keep high
IF v > 0 THEN DiceToRoll.DiceKeepHigh = v
IF DiagRollEm THEN PRINT "DKH"; v
CASE "KL"
IF v > 0 THEN DiceToRoll.DiceKeepLow = v
IF DiagRollEm THEN PRINT "DKL"; v
CASE "DH"
IF v > 0 THEN DiceToRollDiceDiscardHigh = v
IF DiagRollEm THEN PRINT "DDH"; v
CASE "DL"
IF v > 0 THEN DiceToRoll.DiceDiscardLow = v
IF DiagRollEm THEN PRINT "DDL"; v
CASE "R", "O" 'reroll or open roll
finished = 0: t$ = "": innerpass = 0
DO UNTIL finished
innerpass = innerpass + 1
v = VAL(m$)
IF v <> 0 THEN 'it's an o/r followed by a number
t$ = t$ + "=" + _TRIM$(STR$(v)) + ","
ELSE
n1$ = LEFT$(m$, 1)
SELECT CASE n1$
CASE "="
m$ = MID$(m$, 2)
v = VAL(m$)
t$ = t$ + "=" + _TRIM$(STR$(v)) + ","
CASE "<"
m$ = MID$(m$, 2)
v = VAL(m$)
t$ = t$ + "<" + _TRIM$(STR$(v)) + ","
CASE ">"
m$ = MID$(m$, 2)
v = VAL(m$)
t$ = t$ + ">" + _TRIM$(STR$(v)) + ","
CASE ","
m$ = MID$(m$, 2)
CASE ELSE 'a character not a number, or =<>,
finished = -1
END SELECT
END IF
StripNumber m$
IF n$ = "R" THEN
DiceToRoll.DiceReroll = t$
IF DiagRollEm THEN PRINT "DR: "; DiceToRoll.DiceReroll
ELSE
DiceToRoll.DiceOpenRoll = t$
IF DiagRollEm THEN PRINT "DO: "; DiceToRoll.DiceOpenRoll
END IF
IF m$ = "" THEN finished = -1
IF innerpass > 255 THEN IF DiagRollEm THEN PRINT "Error -- Too many loops processing Dice ReRoll or OpenRoll": EXIT FUNCTION
LOOP
END SELECT
StripNumber m$
n$ = LEFT$(m$, 1)
SELECT CASE n$
CASE "K", "D", "R", "O", "+", "-" 'see if it's another command without a comma
CASE ELSE
comma = INSTR(m$, ",")
IF comma THEN m$ = MID$(m$, comma + 1)
END SELECT
IF pass > 100 THEN IF DiagRollEm THEN PRINT "Error - endless processing loop deciphering SET information": EXIT FUNCTION
LOOP
END IF
IF t THEN
DiceToRoll.TotalMod = VAL(MID$(l$, 2))
IF DiagRollEm THEN PRINT "Dice Total Modifier = "; DiceToRoll.TotalMod
END IF
IF b THEN
Brief = VAL(MID$(l$, 2))
IF DiagRollEm THEN PRINT "Roll Information Displayed: ";
SELECT CASE Brief
CASE 0: IF DiagRollEm THEN PRINT "Full"
CASE 1: IF DiagRollEm THEN PRINT "Reduced"
CASE 2: IF DiagRollEm THEN PRINT "Final Results Only"
END SELECT
END IF
LOOP UNTIL l$ = text$
RollEm$ = DiceRoll$
END FUNCTION
If you want to make this a library for your own usage, just strip it out at line 70 or so, and save it as whatever library name you want. "DiceRoller.BM" works for me, but make it whatever you'd like...
At that point, usage is rather simple:
'$INCLUDE:'whatever_you_named_your_library.BM" would go at the bottom of your code, and then you can simply use:
result$ = RollEm$(whatever_to_roll$)
This little library is able to do just about anything you'd need it to do, as far as dice rolling for RPGs go, as long as you follow the basic syntax and send it a proper string.
[b]First Concept of Library:[/b] Our "dice rolling formula" is broken down into segments seperated by a semicolon.
[b]Our 4 basic segments are:[/b]
Sets
Dice
Total mod
Brief output
[b]For Sets, the syntax is:[/b]
##S -- the number of sets, followed by S
[b]For Dice, the syntax is:[/b]
##D## -- the number of dice, followed by D, followed by the sides on the dice. NOTE: the first set of numbers are optional, so you could simply use D6 to roll a single six sided dice.
[b]For Total modifed, the syntax is:[/b]
T## -- T followed by the total to add or subtract to the total dice roll
[b]For Brief output, the syntax is:[/b]
##B -- the number to represent how little output we want, followed by B
0 = full output
1 = reduced output
2 = minimal output (basically only the final results)
[b]Second Concept of Library:[/b] Our segments can be further limited by optional parameters
[b]+## (or -##)[/b] -- add (or subtract) number to segment
[b]KH## [/b]-- Keep the Highest number of "segment"
[b]KL## [/b]-- Keep the Lowest number of "segment"
[b]DH## [/b]-- Discard the Highest number of "segment"
[b]DL## [/b]-- Discard the Lowest number of "segment"
[b]R + [i]stuff[/i][/b] -- Reroll according to [i]stuff[/i]
[b]O + [i]stuff[/i][/b]-- Openroll according [i]to stuff[/i]
[i]stuff[/i] -- A string composed of numbers, operators, and commas, to represent what to reroll or openroll. It sounds complex, but its not.
R1 -- Reroll all 1's
R=2,=3 -- Reroll all rolls that are equal to 2 and equal to 3
R<4 -- Reroll all rolls that are less than 4
O1<2>3 -- (a silly rule set, but hey, it's an example)... Openroll all 1's, all numbers less than two, and all numbers greater than 3
[b]Putting it all together:[/b]
In the end, what we end up with is formulas which look like the following:
3S;2D10 -- Roll 3 sets; of 2 10-sided dice.
6S;4D6KH3 -- Roll 6 sets; of 4 6-sided dice, keeping the 3 highest rolls
10SKH1KL1;2D10+2 -- Roll 10 sets of dice and only keep the highest set and the lowest set; of 2 10-sided dice, and add 2 to each dice.
Depending on what you want, you can generate some rather impressive formulas and take all the bite out of the dice rolling process completely for your games.
NOTE: Spaces are optional, so if they help you understand your "dice rolling formulas" better, feel free to use them:
4S; 3D10 KH2 O20 R2 ; T1; B2 -- Roll 4 sets of; 3 10-sided dice, keeping the 2 highest dice, and openrolling if the dice total to 20, and rerolling if the dice total to 2; then add 1 to the final total; and all we want to see are the final results...