From 85e1085ce0e74b03b1b99360e7097584a0277c77 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Tue, 20 Feb 2018 19:58:44 +1030 Subject: [PATCH 01/23] updated build --- .gradle/4.5/fileChanges/last-build.bin | Bin 0 -> 1 bytes .../4.5/fileContent/annotation-processors.bin | Bin 0 -> 18587 bytes .gradle/4.5/fileContent/fileContent.lock | Bin 0 -> 17 bytes .gradle/4.5/fileHashes/fileHashes.bin | Bin 0 -> 22447 bytes .gradle/4.5/fileHashes/fileHashes.lock | Bin 0 -> 17 bytes .gradle/4.5/fileHashes/resourceHashesCache.bin | Bin 0 -> 19483 bytes .gradle/4.5/taskHistory/taskHistory.bin | Bin 0 -> 53398 bytes .gradle/4.5/taskHistory/taskHistory.lock | Bin 0 -> 17 bytes .../buildOutputCleanup/buildOutputCleanup.lock | Bin 0 -> 17 bytes .gradle/buildOutputCleanup/cache.properties | 2 ++ .gradle/buildOutputCleanup/outputFiles.bin | Bin 0 -> 18965 bytes .gradle/vcsWorkingDirs/gc.properties | 0 build.gradle | 7 ++++--- 13 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .gradle/4.5/fileChanges/last-build.bin create mode 100644 .gradle/4.5/fileContent/annotation-processors.bin create mode 100644 .gradle/4.5/fileContent/fileContent.lock create mode 100644 .gradle/4.5/fileHashes/fileHashes.bin create mode 100644 .gradle/4.5/fileHashes/fileHashes.lock create mode 100644 .gradle/4.5/fileHashes/resourceHashesCache.bin create mode 100644 .gradle/4.5/taskHistory/taskHistory.bin create mode 100644 .gradle/4.5/taskHistory/taskHistory.lock create mode 100644 .gradle/buildOutputCleanup/buildOutputCleanup.lock create mode 100644 .gradle/buildOutputCleanup/cache.properties create mode 100644 .gradle/buildOutputCleanup/outputFiles.bin create mode 100644 .gradle/vcsWorkingDirs/gc.properties diff --git a/.gradle/4.5/fileChanges/last-build.bin b/.gradle/4.5/fileChanges/last-build.bin new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/.gradle/4.5/fileContent/annotation-processors.bin b/.gradle/4.5/fileContent/annotation-processors.bin new file mode 100644 index 0000000000000000000000000000000000000000..ef882423f1eb38b3b3049801bc68d547f9dc6192 GIT binary patch literal 18587 zcmeI%u}VTw9KhkD;GmYa1iI$x5H&eQMXez%PAxuzTi|Hq)C&aSgaw0|ama03dS$%>V!Z literal 0 HcmV?d00001 diff --git a/.gradle/4.5/fileHashes/fileHashes.bin b/.gradle/4.5/fileHashes/fileHashes.bin new file mode 100644 index 0000000000000000000000000000000000000000..4bdf63ad0e087ae2e01e7b5f88d816b2ca84b515 GIT binary patch literal 22447 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 literal 0 HcmV?d00001 diff --git a/.gradle/4.5/fileHashes/fileHashes.lock b/.gradle/4.5/fileHashes/fileHashes.lock new file mode 100644 index 0000000000000000000000000000000000000000..d3cb235941bfd15f1c94e4258c46170c0eb12cb4 GIT binary patch literal 17 UcmZQRpXWUJUeKS<3=r@e06-H4F#rGn literal 0 HcmV?d00001 diff --git a/.gradle/4.5/fileHashes/resourceHashesCache.bin b/.gradle/4.5/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000000000000000000000000000000000000..6bcc6cf304f6044033d266078fdb7d97bb016313 GIT binary patch literal 19483 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 literal 0 HcmV?d00001 diff --git a/.gradle/4.5/taskHistory/taskHistory.lock b/.gradle/4.5/taskHistory/taskHistory.lock new file mode 100644 index 0000000000000000000000000000000000000000..8719aa828ddfbbc1942c49eb3639e5639e494ea7 GIT binary patch literal 17 TcmZS9l0U=3T%%~q00Hs<85aT> literal 0 HcmV?d00001 diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000000000000000000000000000000000000..0eff39b43b3afb801c3d113dd042273bae41bcc9 GIT binary patch literal 17 UcmZSHa5nIXLR-5a0|eLs05qrsG5`Po literal 0 HcmV?d00001 diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..39be704 --- /dev/null +++ b/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Tue Feb 20 18:34:42 ACDT 2018 +gradle.version=4.5 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000000000000000000000000000000000000..572c7c35963e60a8f13b5c735f7f745574446918 GIT binary patch literal 18965 zcmeI%Z%7ki9Ki8Q4OxjR>5tWmKztFbpb(5`VTIwXe+y+nMv;*Sg@jC46uk)9Kr%=& ziUNrUp`cM2OWKQ|h!iwgv<4%Mm@iyOQ4|Heuv_>0DRFOB?~3oi-5$R8+&%Yv-mca# z$`?$_Vay(jXNQasKmY**5I_I{1Q0*~0R#|0009ILKmY**5J2F65eQftnP+dNe04!? z;0_ta+7fH9yvH2LZ2SE9gMHh)s{bEcs|=>=IJFgiT;T6o7x{lUlxx>!#CtTA?*XNHXikUNj1p)H`2EXN_iS)=%lx?Z$vZo% zBdwPk?QU+-J{7xHc*~oul-{g;dP!h#(Z_Gk)tO-%lroI?vC^O+Zuz{ zr6;skBv-fwTdMVYinXuz296&YKC9nzTYGKvP%0T}j?21!?Yo})yPm#Is#{RIKj9lK zD~S!ux{tK)z1wwccgs*xdPaL&Hl7%m=$$Y9tM>N(!<*Y*tf`Q7muWxUny4v?)DKDD zq+Ndvqu`8vk1GNQAb \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,31 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -90,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -114,6 +113,7 @@ fi if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -154,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat old mode 100755 new mode 100644 index aec9973..e95643d --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line From 69dfcae5bde9bba0c1a003cd9f4ac7b893ad71c0 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 25 Feb 2018 11:20:14 +1030 Subject: [PATCH 03/23] Added rolls with bounds --- .gradle/4.5/fileHashes/fileHashes.bin | Bin 22447 -> 22647 bytes .gradle/4.5/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .../4.5/fileHashes/resourceHashesCache.bin | Bin 19483 -> 19653 bytes .gradle/4.5/taskHistory/taskHistory.bin | Bin 53398 -> 82866 bytes .gradle/4.5/taskHistory/taskHistory.lock | Bin 17 -> 17 bytes .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .../common/expression/ExpressionParser.java | 16 ++++++ .../expression/function/DiceHelper.java | 11 ++++ .../expression/function/RollWithBounds.java | 49 ++++++++++++++++++ 9 files changed, 76 insertions(+) create mode 100644 src/main/java/net/rptools/common/expression/function/RollWithBounds.java diff --git a/.gradle/4.5/fileHashes/fileHashes.bin b/.gradle/4.5/fileHashes/fileHashes.bin index 4bdf63ad0e087ae2e01e7b5f88d816b2ca84b515..6a4f3901c6c53a34b3fff14fc3b03bd6838e67d4 100644 GIT binary patch delta 1603 zcmZ3#p7Hwz#tkMCjKP~tB`g{FEspyxXmk0&00t4ln^Pqt7zOTZa|`$Sp&B?{dxW6?~-5Q(i}tYN7q)wFfcGCZnij80nsYIXtKGdI`iho9Fr40r4-m1 z%;P~Y-0Uug+Q@g|@oM6uA!$+Mw~k9z8ZHGPND`TkOqoxMcCV$og@xn3x} zA4-3O(#qZt`A{gmJ6LM+LT`xPolvpYP+HapqShZuH~Q$?!rjAp0_ZM1V<4dk#EKv+ z;I_^{yXc+m?G5WV)|bvp*a`9OEeW6`NdENXw?1lin=N1htc!r6Xhy7OSI}s%=>1gF zd)o2CaeW6=BLojm4)j%H0U0s5+E)+4SPNs^hcN{Gpi<5-Mk$Q39LA{jm74t7PXuBF zw?9;aEsT*5V=RO*F2fkC0Z_%}Fh*v8kHXooMkNt0#v8AmYIB@=p_+i|@Z^P)uLg93 zV<Qt6H03b=`(MsPM91ErTd}uK`8whN~;FzF>kiGH#sa=-xNp#gAxo> zfFxR&I?S_Lr||4C{sV?ouy`5aRR+X9K@vlcCTy;I?seEdfXH6$IGK-KKu zFtr5!TKxS$_zH_>ObV6{|Fm+s#`gv;l{o}Pyman^SUii@fNk=_UHPulBG+w9G=%0#wW*jH!dw^2+tER+Vp7ZhU!4?p!J#st(2rm^wOl z=I6P-ireF*uD?G@l{NY-sum_|Of7ZMJ!_`_TXbq!W}`@b{HtwH9g}Z`U9Cqg9rRcN zPE>rKyThwy%{PG-EpL!YMES-B^bmTSCY{ghjQ`Vn)-3&-==1MMOc1kS#Ro?irjCxz znb*~(Bgmv+LUp;XZ&-Cpt4n3$|4AHR( LT4?c$fOG%=W{%hp delta 1325 zcmeyqfpPtM#tkMCjQ*QVB`g^?w@LalPJS!3V)I(*o6M8v$!9TEZdCjszR_TTz+^`c zWoGBc8k5sKHYg-^tlWR%GIM15HRn@19M<1tU|>w#WIOc%0~pBgPd4{dX9n^oCwfXL zxbYkiJM_s%ZTf99*EcVjOi>jJE}ELvDz_-Up2cQ!luNVsB-j_eKMjDAKp-zX`K^zd-6psI>mr~ini13QtWaFE z_EXogkC~_EbN^b6YJ|X|$$`FVEFdE$SNrNg7;9mS`!I%}A5_X2#wdj`mctm;zEYDv z`-wn|;P!`Vu!S-5VT^?^#$_0TH2|vE9LC5D@KLzGQz*>*SN6Qd%bwPsb{6!ZIy_c+ z^3{NDa112}LPB*als*one?n>PAbn=vzY>#Up>#i#J_w~hLuu7uJ?2e*jFZEH^-X~^ zIEaCS3TBx8*uRVW>1y>|qMpHvoexxf1Un6=b62o*{n55^hUi15HBa5(zt2)w-vyO} znkFz2(=?9#PoA4wUb4ToOyjTvpXYK^9h}cFb?oTk^7Ws2|AeqfmY2xtkhMrUSb?h9 zzfNWh5)Rz3AZ5k$kY1x($8*AYLgbJX0o8DXU>X~LByx#f_seF3!|}U{^)>;MA~1u& z1A@bB^4^d#1u^~)>s;+QM0K*cr4A(oEkRYpConlU)TRFM>b*>VCuF=F-ckIyhcq>e#U-#)~V4<5^#F-m|d3JAew{uB``h zxUg8V*Ms5TYULOitrKgQ1yr2BAZY>WU=hZ&WWT(nVn*|cKb@ZX>|w%gkPHY962=Rd zI$SqI__)pwSX;F*vch0PSCc5JB}_J$TFTeimkS-5`KD@1|2ON#l|oP*lW&Dx1po;D Bkc9vM diff --git a/.gradle/4.5/fileHashes/fileHashes.lock b/.gradle/4.5/fileHashes/fileHashes.lock index d3cb235941bfd15f1c94e4258c46170c0eb12cb4..0e693fbb8cb74fb6c9920b016a77bfb6b58b3f5a 100644 GIT binary patch literal 17 VcmZQRpXWUJUeKS<3}C>-1^_=I1wH@( literal 17 UcmZQRpXWUJUeKS<3=r@e06-H4F#rGn diff --git a/.gradle/4.5/fileHashes/resourceHashesCache.bin b/.gradle/4.5/fileHashes/resourceHashesCache.bin index 6bcc6cf304f6044033d266078fdb7d97bb016313..ac73ced8f4aab8bdab1b8dcc48467991934f4815 100644 GIT binary patch delta 222 zcmbO|gYoE0#tkMCj!NyV9}SIWwy$RZ1CQkYP|$U%atoi)#cqhWk2FkteuuAva>hR{ zsJQKBSBVHlfq%y*ZC-TOKNl*xc=J?A4Mu@1osuV>ma_t&qVbcrN?E8>T9-QgsxkL~ z3O2$FhS3ZR%#Irse~521xFNFH(c>2L)lX3P8#tkMCg0k(c9}SIWwy$RZ1CQj*r4kX0o1aQ5Fiw`0HsJXW1q=*KCpRko P5Z`DJAiCMn;}$ajU4a`7 diff --git a/.gradle/4.5/taskHistory/taskHistory.bin b/.gradle/4.5/taskHistory/taskHistory.bin index c68fa14a331356d048f66e23f70caa3b23272760..044a9e49f38e6f51b087d92dcbd2956d0ad125a6 100644 GIT binary patch delta 1439 zcmbQXka<%(>jV)^W(F|GjAURC_Jpu&7BMi$WiHGg{k>fY01fX$(a@ArDnOgDQSgfxe((RxS6|)^7BiA3sRF+3>g_DuTI`L$9Hl; zB**6WnI{+p+}0Ur7rnE+yyopG~enFf=<*|0_>5iZ6XubygioO+>}u(`0pfQ9k-? z&y5Y_Ulk<(W+j#-G7IRj1e~b&K6i&#&6;llEn42pd50!{EV0`BKV&@`U^oFskTaeII-z+o&sv$yuE|1d zj!HhjfRtkbro&$#%s9KmBqJ{~(WuHaE2AhcxvV5JB`K{SrzkZ)5t3RM{aCxeW)~!u zWH2yDZhlzvj!D3`?XPdYXEwtG11}?y$*a$AzF&_s6vVC&8*pi&%DI1v?88=McctCse<{f^F0xRdn+;H^` z2=mNe+P~l9x6Ne1T{8v3eHA&X7Mbhbxb*#>q}DQ)$%?T~lLK~2O-|S&Kl$%|&dGMW zg$39aNGzYVXxZzX3diK*KU%0wPTW0NAn@1X?+3zHSUh7=uskTeWYOe;M3_!P0pYc) zdVim(_*ZlPZToB2{+7)P_bg`=l6}VdXcdP;0HeUN_yp4ps*Ip~?f|q-c=OtQ@r*+E z+hYC*A6MBR9nWV_I>+D_<3E`EfXtso7Ww1 zWD-F4`Q-nHCJJ1V`gv;l{o}Pyman^SUii^q@`A%t1b-d9d1!0wZ?9E%U+rOuXqm-0 zIkCxcvi}aD$yP^ofZpX5s{mQUYI)`QSF6f5D>uG8C3h~Bj}aKLFlAOkojddMUd8S4 zQrF)frOFz8mhs4B#>1tP>-X@8f_2wL_pF)zZ_%k`nT;a#@vpW`F09ai+l4@iN*SCitG#witLlu*C;a@Y(9P=gNadMv%%%pjKYZ> zEBBwc%p941&H2<0hxIp^Q{PQye2_Nzfe**#Iag&F1>ATJh#mUmqc;7vnd_UEOs11B z-YS~x|CDpH%XL?_%?kIbn3yClPCocKaP!*-GE9@b77H*kPTuHMwRy^81IEegmkLa7 a-0w7bgHPn<{HJr+CM(?I->jFMkqZDU7G<*l diff --git a/.gradle/4.5/taskHistory/taskHistory.lock b/.gradle/4.5/taskHistory/taskHistory.lock index 8719aa828ddfbbc1942c49eb3639e5639e494ea7..e790a15857bbcb288751d813c5c00436af805f7b 100644 GIT binary patch literal 17 TcmZS9l0U=3T%%~q00E`|87%@Y literal 17 TcmZS9l0U=3T%%~q00Hs<85aT> diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 0eff39b43b3afb801c3d113dd042273bae41bcc9..588577ab74c7363ab7df5abe4761067ecd8ed996 100644 GIT binary patch literal 17 UcmZSHa5nIXLR-5a0|dkX05rw~Pyhe` literal 17 UcmZSHa5nIXLR-5a0|eLs05qrsG5`Po diff --git a/src/main/java/net/rptools/common/expression/ExpressionParser.java b/src/main/java/net/rptools/common/expression/ExpressionParser.java index e3a95fe..3286092 100755 --- a/src/main/java/net/rptools/common/expression/ExpressionParser.java +++ b/src/main/java/net/rptools/common/expression/ExpressionParser.java @@ -112,6 +112,22 @@ public class ExpressionParser { new String[] { "\\b(\\d+)[sS][rR]4[gG](\\d+)\\b", "sr4($1, $2)" }, new String[] { "\\b(\\d+)[sS][rR]4\\b", "sr4($1)" }, + // Subtract X with minimum of Y + new String[] { "\\b(\\d+)[dD](\\d+)[sS](\\d+)[lL](\\d+)\\b", "rollSubWithLower($1, $2, $3, $4)" }, + new String[] { "\\b[dD](\\d+)[sS](\\d+)[lL](\\d+)\\b", "rollSubWithLower(1, $1, $2, $3)" }, + + // Add X with maximum of Y + new String[] { "\\b(\\d+)[dD](\\d+)[aA](\\d+)[uU](\\d+)\\b", "rollAddWithUpper($1, $2, $3, $4)" }, + new String[] { "\\b[dD](\\d+)[aA](\\d+)[uU](\\d+)\\b", "rollAddWithUpper(1, $1, $2, $3)" }, + + // Roll with a minimum value per roll (e.g. treat 1s as 2s) + new String[] { "\\b(\\d+)[dD](\\d+)[lL](\\d+)\\b", "rollWithLower($1, $2, $3)" }, + new String[] { "\\b[dD](\\d+)[lL](\\d+)\\b", "rollWithLower(1, $1, $2)" }, + + // Roll with a maximum value per roll (e.g. treat 6s as 5s) + new String[] { "\\b(\\d+)[dD](\\d+)[uU](\\d+)\\b", "rollWithUpper($1, $2, $3)" }, + new String[] { "\\b[dD](\\d+)[uU](\\d+)\\b", "rollWithUpper(1, $1, $2)" }, + }; private final Parser parser; diff --git a/src/main/java/net/rptools/common/expression/function/DiceHelper.java b/src/main/java/net/rptools/common/expression/function/DiceHelper.java index 47e2ac9..1ed0e86 100755 --- a/src/main/java/net/rptools/common/expression/function/DiceHelper.java +++ b/src/main/java/net/rptools/common/expression/function/DiceHelper.java @@ -180,4 +180,15 @@ public static String countShadowRun4(int times, int gremlins, boolean explode) { return result; } + + public static int rollModWithBounds(int times, int sides, int sub, int lower, int upper) { + int result = 0; + + for (int i = 0; i < times; i++) { + result += Math.min(Math.max(rollDice(1, sides) - sub, lower), upper); + } + + return result; + } + } diff --git a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java new file mode 100644 index 0000000..88f5e0d --- /dev/null +++ b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java @@ -0,0 +1,49 @@ +package net.rptools.common.expression.function; + +import net.rptools.parser.Parser; +import net.rptools.parser.ParserException; +import net.rptools.parser.function.AbstractNumberFunction; + +import java.math.BigDecimal; +import java.util.List; + +public class RollWithBounds extends AbstractNumberFunction { + + public RollWithBounds() { + super(3, 4, false, "rollSubWithLower", "rollWithLower", "rollAddWithUpper", "rollWithUpper"); + } + + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) throws ParserException { + int times = 0; + int sides = 0; + int mod = 0; + int lower = Integer.MIN_VALUE; + int upper = Integer.MAX_VALUE; + + switch (functionName) { + case "rollSubWithLower": + times = ((BigDecimal) parameters.get(0)).intValue(); + sides = ((BigDecimal) parameters.get(1)).intValue(); + mod = -((BigDecimal) parameters.get(2)).intValue(); + lower = ((BigDecimal) parameters.get(3)).intValue(); + break; + case "rollWithLower": + times = ((BigDecimal) parameters.get(0)).intValue(); + sides = ((BigDecimal) parameters.get(1)).intValue(); + lower = ((BigDecimal) parameters.get(2)).intValue(); + break; + case "rollAddWithUpper": + times = ((BigDecimal) parameters.get(0)).intValue(); + sides = ((BigDecimal) parameters.get(1)).intValue(); + mod = ((BigDecimal) parameters.get(2)).intValue(); + upper = ((BigDecimal) parameters.get(3)).intValue(); + break; + case "rollWithUpper": + times = ((BigDecimal) parameters.get(0)).intValue(); + sides = ((BigDecimal) parameters.get(1)).intValue(); + upper = ((BigDecimal) parameters.get(2)).intValue(); + } + return DiceHelper.rollModWithBounds(times, sides, mod, lower, upper); + } +} From a834802be12d86d856b93d631ffcece9f971693a Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 25 Feb 2018 11:37:39 +1030 Subject: [PATCH 04/23] Fixed git wrapper --- .gitignore | 14 +++++++++++++- .gradle/4.5/fileChanges/last-build.bin | Bin 1 -> 0 bytes .../4.5/fileContent/annotation-processors.bin | Bin 18587 -> 0 bytes .gradle/4.5/fileContent/fileContent.lock | Bin 17 -> 0 bytes .gradle/4.5/fileHashes/fileHashes.bin | Bin 22647 -> 0 bytes .gradle/4.5/fileHashes/fileHashes.lock | Bin 17 -> 0 bytes .gradle/4.5/fileHashes/resourceHashesCache.bin | Bin 19653 -> 0 bytes .gradle/4.5/taskHistory/taskHistory.bin | Bin 82866 -> 0 bytes .gradle/4.5/taskHistory/taskHistory.lock | Bin 17 -> 0 bytes .../buildOutputCleanup/buildOutputCleanup.lock | Bin 17 -> 0 bytes .gradle/buildOutputCleanup/cache.properties | 2 -- .gradle/buildOutputCleanup/outputFiles.bin | Bin 18965 -> 0 bytes .gradle/vcsWorkingDirs/gc.properties | 0 build.gradle | 2 +- 14 files changed, 14 insertions(+), 4 deletions(-) delete mode 100644 .gradle/4.5/fileChanges/last-build.bin delete mode 100644 .gradle/4.5/fileContent/annotation-processors.bin delete mode 100644 .gradle/4.5/fileContent/fileContent.lock delete mode 100644 .gradle/4.5/fileHashes/fileHashes.bin delete mode 100644 .gradle/4.5/fileHashes/fileHashes.lock delete mode 100644 .gradle/4.5/fileHashes/resourceHashesCache.bin delete mode 100644 .gradle/4.5/taskHistory/taskHistory.bin delete mode 100644 .gradle/4.5/taskHistory/taskHistory.lock delete mode 100644 .gradle/buildOutputCleanup/buildOutputCleanup.lock delete mode 100644 .gradle/buildOutputCleanup/cache.properties delete mode 100644 .gradle/buildOutputCleanup/outputFiles.bin delete mode 100644 .gradle/vcsWorkingDirs/gc.properties diff --git a/.gitignore b/.gitignore index 9cfdb66..42969ce 100755 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -build/ maven-repo/ # OS generated files @@ -32,3 +31,16 @@ out/ .settings/ .classpath .history + + +# Gradle Wrapper +.gradle +!gradle-wrapper.jar +# Ignore Gradle GUI config +gradle-app.setting + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties \ No newline at end of file diff --git a/.gradle/4.5/fileChanges/last-build.bin b/.gradle/4.5/fileChanges/last-build.bin deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/.gradle/4.5/fileContent/annotation-processors.bin b/.gradle/4.5/fileContent/annotation-processors.bin deleted file mode 100644 index ef882423f1eb38b3b3049801bc68d547f9dc6192..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18587 zcmeI%u}VTw9KhkD;GmYa1iI$x5H&eQMXez%PAxuzTi|Hq)C&aSgaw0|ama03dS$%>V!Z diff --git a/.gradle/4.5/fileHashes/fileHashes.bin b/.gradle/4.5/fileHashes/fileHashes.bin deleted file mode 100644 index 6a4f3901c6c53a34b3fff14fc3b03bd6838e67d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22647 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 diff --git a/.gradle/4.5/fileHashes/fileHashes.lock b/.gradle/4.5/fileHashes/fileHashes.lock deleted file mode 100644 index 0e693fbb8cb74fb6c9920b016a77bfb6b58b3f5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 VcmZQRpXWUJUeKS<3}C>-1^_=I1wH@( diff --git a/.gradle/4.5/fileHashes/resourceHashesCache.bin b/.gradle/4.5/fileHashes/resourceHashesCache.bin deleted file mode 100644 index ac73ced8f4aab8bdab1b8dcc48467991934f4815..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19653 zcmeI(e=yW}9LMpMB9SC6KRYLkF0zzxOOBk@?poWWtjkqcKSMfPBsYFWZDITzUDw8@ zQ&y||=*O{#9Vc8XDZ0>d*D%hHMx{CDM`!2z{hZ0yO#j^9lrF@cruw7*ADnHAt5&t@? zrTp86R_mTm_@*7-=cE3Vt#@&DPWw9EXHf5rIv8Knc}@fCbaT|D@f|!4Dd-v2siUY5 z46{32`R9G{eJ<+5Ap<+R`sKgJ&;JeeiI6Ex!(^j!tkXtNf1AkR@^3I2@N=e7|7&V5 zqq$n~7T%AeK6A~teACRO8~8absL!|LRF(95gkzn-M}4KFo|PvQF|qCzh5G7pCSP<( z#RfmW26dI6hdbxDq?zOU+o)?i&K!7j#6A@3v{KY9y7D!VJQa6L^u+UaCgA8KU0uSMN& zeKSR&qA3aM^d8g$xQva`moLuZ-2?Sdv*;IYb{AM!XB)Z-{I&VQe>q2lKxp^mm(*Uk zub17`zH*)1kPyCdMWy%J%)!{q`wMZ?`wQdnE4*{}5+~-LGf!$|49pT2W>1T29}Ka? zv7<32m-mQe@48=d1~YZv@!k^okl3i*m7+ZEGFORA+c{TN+|v zi{R)XY6RIF_8OH=R{kSC^$kT%5kX zuD6Y1ziVq4W5_zd!-TkqqeLo6_J5l${H$LPQ!B|LE~M#qk9}O@+*s*6E2pWHu#vd< zeL}QBS+~F{Hi*q2D-Jgh7Y!#TZ1yt0 zA6s_JrHrSR@GEE>zSR6{KjInPqO0oP4XSe=8rK^6HHp=Ui@NQBrC*xa({;DTCl(sI zcoG*PON*%#`UBINI$g6vf~Fke;=_M)?x*M6v)qo7vdJ_njok7M;u+nBKg7>_8ia_I SB*R0j;AMWcAHK?Ri+=#xo$HwZ diff --git a/.gradle/4.5/taskHistory/taskHistory.bin b/.gradle/4.5/taskHistory/taskHistory.bin deleted file mode 100644 index 044a9e49f38e6f51b087d92dcbd2956d0ad125a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82866 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 diff --git a/.gradle/4.5/taskHistory/taskHistory.lock b/.gradle/4.5/taskHistory/taskHistory.lock deleted file mode 100644 index e790a15857bbcb288751d813c5c00436af805f7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 TcmZS9l0U=3T%%~q00E`|87%@Y diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock deleted file mode 100644 index 588577ab74c7363ab7df5abe4761067ecd8ed996..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17 UcmZSHa5nIXLR-5a0|dkX05rw~Pyhe` diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index 39be704..0000000 --- a/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Tue Feb 20 18:34:42 ACDT 2018 -gradle.version=4.5 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin deleted file mode 100644 index 572c7c35963e60a8f13b5c735f7f745574446918..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18965 zcmeI%Z%7ki9Ki8Q4OxjR>5tWmKztFbpb(5`VTIwXe+y+nMv;*Sg@jC46uk)9Kr%=& ziUNrUp`cM2OWKQ|h!iwgv<4%Mm@iyOQ4|Heuv_>0DRFOB?~3oi-5$R8+&%Yv-mca# z$`?$_Vay(jXNQasKmY**5I_I{1Q0*~0R#|0009ILKmY**5J2F65eQftnP+dNe04!? z;0_ta+7fH9yvH2LZ2SE9gMHh)s{bEcs|=>=IJFgiT;T6o7x{lUlxx>!#CtTA?*XNHXikUNj1p)H`2EXN_iS)=%lx?Z$vZo% zBdwPk?QU+-J{7xHc*~oul-{g;dP!h#(Z_Gk)tO-%lroI?vC^O+Zuz{ zr6;skBv-fwTdMVYinXuz296&YKC9nzTYGKvP%0T}j?21!?Yo})yPm#Is#{RIKj9lK zD~S!ux{tK)z1wwccgs*xdPaL&Hl7%m=$$Y9tM>N(!<*Y*tf`Q7muWxUny4v?)DKDD zq+Ndvqu`8vk1GNQAb Date: Mon, 26 Feb 2018 00:33:00 +1030 Subject: [PATCH 05/23] Added DragonQuest roll --- .../net/rptools/common/expression/ExpressionParser.java | 6 ++++++ .../rptools/common/expression/function/RollWithBounds.java | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/net/rptools/common/expression/ExpressionParser.java b/src/main/java/net/rptools/common/expression/ExpressionParser.java index 3286092..fba3fb7 100755 --- a/src/main/java/net/rptools/common/expression/ExpressionParser.java +++ b/src/main/java/net/rptools/common/expression/ExpressionParser.java @@ -128,6 +128,12 @@ public class ExpressionParser { new String[] { "\\b(\\d+)[dD](\\d+)[uU](\\d+)\\b", "rollWithUpper($1, $2, $3)" }, new String[] { "\\b[dD](\\d+)[uU](\\d+)\\b", "rollWithUpper(1, $1, $2)" }, + // Dragon Quest + new String[] { "\\b(\\d+)[dD](\\d+)q:([+-]?\\d+)\\b", "rollAddWithLower($1, $2, $3, 1)" }, + new String[] { "\\b[dD](\\d+)q:([+-]?\\d+)\\b", "rollAddWithLower(1, $1, $2, 1)" }, + new String[] { "\\b(\\d+)[dD](\\d+)q\\b", "rollAddWithLower($1, $2, 0, 1)" }, + new String[] { "\\b[dD](\\d+)q\\b", "rollAddWithLower(1, $1, 0, 1)" } + }; private final Parser parser; diff --git a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java index 88f5e0d..937b918 100644 --- a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java +++ b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java @@ -43,6 +43,13 @@ public Object childEvaluate(Parser parser, String functionName, List par times = ((BigDecimal) parameters.get(0)).intValue(); sides = ((BigDecimal) parameters.get(1)).intValue(); upper = ((BigDecimal) parameters.get(2)).intValue(); + break; + case "rollAddWithLower": + times = ((BigDecimal) parameters.get(0)).intValue(); + sides = ((BigDecimal) parameters.get(1)).intValue(); + mod = ((BigDecimal) parameters.get(2)).intValue(); + lower = ((BigDecimal) parameters.get(3)).intValue(); + break; } return DiceHelper.rollModWithBounds(times, sides, mod, lower, upper); } From 84739416f5aa41c3623ea0897491f569a8c11b0f Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sat, 30 Mar 2019 22:23:51 +1030 Subject: [PATCH 06/23] Upgradle gradle wrapper to 5.3 --- .gitignore | 33 ++++++++++++------------ gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 42969ce..94690a6 100755 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ -maven-repo/ - # OS generated files ################################################################################ .DS_Store @@ -14,11 +12,21 @@ Thumbs.db # Others ################################################################################ -*.log -*~ -target/ +.gradle build/ +/bin/ +target/ out/ +/releases/ +*.log +*~ +\${sys:appHome}/ + + +# Automatically Generated +################################################################################ +package/windows/MapTool.iss +src/main/resources/sentry.properties # IDEs @@ -31,16 +39,7 @@ out/ .settings/ .classpath .history +workbench.xmi - -# Gradle Wrapper -.gradle -!gradle-wrapper.jar -# Ignore Gradle GUI config -gradle-app.setting - -# Cache of project -.gradletasknamecache - -# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 -# gradle/wrapper/gradle-wrapper.properties \ No newline at end of file +# Keystore +build-resources/rptools-keystore \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 288472a..fd98198 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,4 +1,4 @@ -distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.3-bin.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists From 59887918b34e9e8c96221670309b1e62604d2b8d Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sat, 30 Mar 2019 22:44:42 +1030 Subject: [PATCH 07/23] Gradle and gradle build updates --- build.gradle | 94 ++++------ gradle/wrapper/gradle-wrapper.properties | 8 + gradlew | 172 ------------------ gradlew.bat | 84 --------- settings.gradle | 10 + .../common/expression/ExpressionParser.java | 8 + .../expression/function/DiceHelper.java | 18 ++ 7 files changed, 78 insertions(+), 316 deletions(-) delete mode 100755 gradlew delete mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/build.gradle b/build.gradle index 9f9b30a..af49bee 100755 --- a/build.gradle +++ b/build.gradle @@ -1,24 +1,47 @@ -import org.apache.tools.ant.filters.ReplaceTokens import java.text.SimpleDateFormat -import org.ajoberstar.grgit.* +buildscript { + dependencies { + classpath "com.diffplug.spotless:spotless-plugin-gradle:3.13.0" + } + + repositories { + mavenCentral() + } +} + +// Access Git info from build script +plugins { + id "org.ajoberstar.grgit" version "3.0.0" +} -apply plugin: 'java' +apply plugin: 'java-library' apply plugin: 'findbugs' -apply plugin: 'pmd' -apply plugin: 'maven' apply plugin: 'com.diffplug.gradle.spotless' -sourceCompatibility = 1.7 -targetCompatibility = 1.7 +sourceCompatibility = 10 +targetCompatibility = 10 -if (version == 'unspecified') { - version = getVersionName() -} +// Custom properties +ext { + // Get tag and commit info from Git to use for version numbering + def repo = org.ajoberstar.grgit.Grgit.open(currentDir: file('.')) + def head = repo.head() + def tags = repo.tag.list().find { + it.commit == head + } + + if (tags) { + tagVersion = tags.getName() + } + + revision = head.abbreviatedId + revisionFull = head.id -ext.repo = Grgit.open(project.file('.')) +// println 'Configuring for ' + project.name + " " + tagVersion + " by " + vendor +} spotless { @@ -33,44 +56,6 @@ configurations { } -task wrapper(type: Wrapper) { - gradleVersion='4.5' -} - -install { - repositories.mavenInstaller { - pom.version = project.version; - pom.artifactId = 'dicelib'; - pom.groupId = 'net.rptools.dicelib'; - } -} - - -uploadArchives { - repositories.mavenDeployer { - pom.version = project.version; - pom.artifactId = 'dicelib'; - pom.groupId = 'net.rptools.dicelib'; - configuration = configurations.deployerJars; - repository url: 'file://' + projectDir + '/../maven-repo' - } -} - -buildscript { - repositories { - mavenCentral() - jcenter() - maven { - url 'https://plugins.gradle.org/m2/' - } - } - dependencies { - classpath 'org.ajoberstar:gradle-git:0.11.2' - classpath 'com.diffplug.gradle.spotless:spotless:1.3.0-SNAPSHOT' - } -} - - dependencies { compile 'rhino:js:1.6R5' compile 'antlr:antlr:2.7.6' @@ -115,18 +100,7 @@ findbugs { sourceSets = [] // Empty source set so it wont run during build/check } -pmd { - ignoreFailures = true - sourceSets = [] // Empty source set so it wont run during tebuild/check -} - - -task showBuildVersion() { - doLast { - println 'Build Version Number = ' + project.version - } -} jar { manifest { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fd98198..fa98088 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,13 @@ +<<<<<<< Updated upstream distributionUrl=https\://services.gradle.org/distributions/gradle-5.3-bin.zip +======= +#Sat Mar 30 21:21:43 ACDT 2019 +>>>>>>> Stashed changes distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists +<<<<<<< Updated upstream zipStoreBase=GRADLE_USER_HOME +======= +distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip +>>>>>>> Stashed changes diff --git a/gradlew b/gradlew deleted file mode 100755 index cccdd3d..0000000 --- a/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index e95643d..0000000 --- a/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..4719553 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/5.2.1/userguide/multi_project_builds.html + */ + +rootProject.name = 'dicelib' diff --git a/src/main/java/net/rptools/common/expression/ExpressionParser.java b/src/main/java/net/rptools/common/expression/ExpressionParser.java index fba3fb7..47cd15c 100755 --- a/src/main/java/net/rptools/common/expression/ExpressionParser.java +++ b/src/main/java/net/rptools/common/expression/ExpressionParser.java @@ -34,10 +34,18 @@ public class ExpressionParser { new String[] { "\\b(\\d+)[dD](\\d+)[dD](\\d+)\\b", "drop($1, $2, $3)" }, new String[] { "\\b[dD](\\d+)[dD](\\d+)\\b", "drop(1, $1, $2)" }, + // drop highest + new String[] { "\\b(\\d+)[dD](\\d+)[dD](\\d+)\\b", "dropHighest($1, $2, $3)" }, + new String[] { "\\b[dD](\\d+)[dD](\\d+)\\b", "dropHighest(1, $1, $2)" }, + // keep new String[] { "\\b(\\d+)[dD](\\d+)[kK](\\d+)\\b", "keep($1, $2, $3)" }, new String[] { "\\b[dD](\\d+)[kK](\\d+)\\b", "keep(1, $1, $2)" }, + // keep lowest + new String[] { "\\b(\\d+)[dD](\\d+)[kK][lL](\\d+)\\b", "keepLowest($1, $2, $3)" }, + new String[] { "\\b[dD](\\d+)[kK][lL](\\d+)\\b", "keepLowest(1, $1, $2)" }, + // re-roll new String[] { "\\b(\\d+)[dD](\\d+)[rR](\\d+)\\b", "reroll($1, $2, $3)" }, new String[] { "\\b[dD](\\d+)[rR](\\d+)\\b", "reroll(1, $1, $2)" }, diff --git a/src/main/java/net/rptools/common/expression/function/DiceHelper.java b/src/main/java/net/rptools/common/expression/function/DiceHelper.java index 1ed0e86..683bb58 100755 --- a/src/main/java/net/rptools/common/expression/function/DiceHelper.java +++ b/src/main/java/net/rptools/common/expression/function/DiceHelper.java @@ -87,6 +87,24 @@ public static int dropDice(int times, int sides, int drop) throws EvaluationExce return result; } + public static int dropDiceLowest(int times, int sides, int drop) throws EvaluationException { + if (times - drop <= 0) + throw new EvaluationException("You cannot drop more dice than you roll"); + + RunData runData = RunData.getCurrent(); + + int[] values = runData.randomInts(times, sides); + + Arrays.sort(values); + + int result = 0; + for (int i = drop; i < times; i++) { + result += values[i]; + } + + return result; + } + public static int rerollDice(int times, int sides, int lowerBound) throws EvaluationException { RunData runData = RunData.getCurrent(); From 38803c2e4e39d9d95901d45368bba674c6dfbcd8 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sat, 30 Mar 2019 23:05:24 +1030 Subject: [PATCH 08/23] Add drop highest and keep lowest roll types --- .../common/expression/ExpressionParser.java | 8 ++-- .../expression/function/DiceHelper.java | 11 ++++-- .../expression/function/DropHighestRoll.java | 38 +++++++++++++++++++ .../expression/function/KeepLowestRoll.java | 38 +++++++++++++++++++ 4 files changed, 88 insertions(+), 7 deletions(-) create mode 100755 src/main/java/net/rptools/common/expression/function/DropHighestRoll.java create mode 100755 src/main/java/net/rptools/common/expression/function/KeepLowestRoll.java diff --git a/src/main/java/net/rptools/common/expression/ExpressionParser.java b/src/main/java/net/rptools/common/expression/ExpressionParser.java index 47cd15c..67e8b8b 100755 --- a/src/main/java/net/rptools/common/expression/ExpressionParser.java +++ b/src/main/java/net/rptools/common/expression/ExpressionParser.java @@ -137,10 +137,10 @@ public class ExpressionParser { new String[] { "\\b[dD](\\d+)[uU](\\d+)\\b", "rollWithUpper(1, $1, $2)" }, // Dragon Quest - new String[] { "\\b(\\d+)[dD](\\d+)q:([+-]?\\d+)\\b", "rollAddWithLower($1, $2, $3, 1)" }, - new String[] { "\\b[dD](\\d+)q:([+-]?\\d+)\\b", "rollAddWithLower(1, $1, $2, 1)" }, - new String[] { "\\b(\\d+)[dD](\\d+)q\\b", "rollAddWithLower($1, $2, 0, 1)" }, - new String[] { "\\b[dD](\\d+)q\\b", "rollAddWithLower(1, $1, 0, 1)" } + new String[] { "\\b(\\d+)[dD](\\d+)[qQ]:([+-]?\\d+)\\b", "rollAddWithLower($1, $2, $3, 1)" }, + new String[] { "\\b[dD](\\d+)[qQ]:([+-]?\\d+)\\b", "rollAddWithLower(1, $1, $2, 1)" }, + new String[] { "\\b(\\d+)[dD](\\d+)[qQ]\\b", "rollAddWithLower($1, $2, 0, 1)" }, + new String[] { "\\b[dD](\\d+)[qQ]\\b", "rollAddWithLower(1, $1, 0, 1)" } }; diff --git a/src/main/java/net/rptools/common/expression/function/DiceHelper.java b/src/main/java/net/rptools/common/expression/function/DiceHelper.java index 683bb58..7fc4f58 100755 --- a/src/main/java/net/rptools/common/expression/function/DiceHelper.java +++ b/src/main/java/net/rptools/common/expression/function/DiceHelper.java @@ -15,6 +15,7 @@ import java.util.Arrays; +import java.util.Comparator; import net.rptools.common.expression.RunData; import net.rptools.parser.function.*; @@ -69,6 +70,10 @@ public static int keepDice(int times, int sides, int keep) throws EvaluationExce return dropDice(times, sides, times - keep); } + public static int keepLowestDice(int times, int sides, int keep) throws EvaluationException { + return dropDiceHighest(times, sides, times - keep); + } + public static int dropDice(int times, int sides, int drop) throws EvaluationException { if (times - drop <= 0) throw new EvaluationException("You cannot drop more dice than you roll"); @@ -87,7 +92,7 @@ public static int dropDice(int times, int sides, int drop) throws EvaluationExce return result; } - public static int dropDiceLowest(int times, int sides, int drop) throws EvaluationException { + public static int dropDiceHighest(int times, int sides, int drop) throws EvaluationException { if (times - drop <= 0) throw new EvaluationException("You cannot drop more dice than you roll"); @@ -95,11 +100,11 @@ public static int dropDiceLowest(int times, int sides, int drop) throws Evaluati int[] values = runData.randomInts(times, sides); - Arrays.sort(values); + int[] descValues = Arrays.stream(values).boxed().sorted(Comparator.reverseOrder()).mapToInt(Integer::intValue).toArray(); int result = 0; for (int i = drop; i < times; i++) { - result += values[i]; + result += descValues[i]; } return result; diff --git a/src/main/java/net/rptools/common/expression/function/DropHighestRoll.java b/src/main/java/net/rptools/common/expression/function/DropHighestRoll.java new file mode 100755 index 0000000..a34c5a8 --- /dev/null +++ b/src/main/java/net/rptools/common/expression/function/DropHighestRoll.java @@ -0,0 +1,38 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package net.rptools.common.expression.function; + +import java.math.BigDecimal; +import java.util.List; +import net.rptools.parser.Parser; +import net.rptools.parser.function.AbstractNumberFunction; +import net.rptools.parser.function.EvaluationException; + +public class DropHighestRoll extends AbstractNumberFunction { + + public DropHighestRoll() { + super(3, 3, false, "dropHighest"); + } + + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + int drop = ((BigDecimal) parameters.get(n++)).intValue(); + + return new BigDecimal(DiceHelper.dropDiceHighest(times, sides, drop)); + } + +} diff --git a/src/main/java/net/rptools/common/expression/function/KeepLowestRoll.java b/src/main/java/net/rptools/common/expression/function/KeepLowestRoll.java new file mode 100755 index 0000000..4f3ce53 --- /dev/null +++ b/src/main/java/net/rptools/common/expression/function/KeepLowestRoll.java @@ -0,0 +1,38 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package net.rptools.common.expression.function; + +import java.math.BigDecimal; +import java.util.List; +import net.rptools.parser.Parser; +import net.rptools.parser.function.AbstractNumberFunction; +import net.rptools.parser.function.EvaluationException; + +public class KeepLowestRoll extends AbstractNumberFunction { + + public KeepLowestRoll() { + super(3, 3, false, "keepLowest"); + } + + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + int keep = ((BigDecimal) parameters.get(n++)).intValue(); + + return new BigDecimal(DiceHelper.keepLowestDice(times, sides, keep)); + } + +} From 9f8e76c3a77130a57871a557d00c234267d66bda Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 31 Mar 2019 01:19:02 +1030 Subject: [PATCH 09/23] Spotless reformat --- build.gradle | 96 ++-- gradle/wrapper/gradle-wrapper.properties | 9 - spotless.license.java | 14 + .../common/expression/ExpressionParser.java | 399 ++++++++-------- .../net/rptools/common/expression/Result.java | 107 ++--- .../rptools/common/expression/RunData.java | 172 ++++--- .../expression/function/CountSuccessDice.java | 44 +- .../expression/function/DiceHelper.java | 300 ++++++------ .../expression/function/DropHighestRoll.java | 43 +- .../common/expression/function/DropRoll.java | 44 +- .../expression/function/ExplodeDice.java | 42 +- .../function/ExplodingSuccessDice.java | 44 +- .../common/expression/function/FudgeRoll.java | 55 ++- .../expression/function/HeroKillingRoll.java | 160 ++++--- .../common/expression/function/HeroRoll.java | 191 ++++---- .../common/expression/function/If.java | 39 +- .../expression/function/KeepLowestRoll.java | 43 +- .../common/expression/function/KeepRoll.java | 44 +- .../expression/function/OpenTestDice.java | 42 +- .../expression/function/RerollDice.java | 44 +- .../common/expression/function/Roll.java | 57 ++- .../expression/function/RollWithBounds.java | 104 +++-- .../expression/function/ShadowRun4Dice.java | 45 +- .../function/ShadowRun4ExplodeDice.java | 45 +- .../expression/function/UbiquityRoll.java | 55 ++- .../expression/ExpressionParserTest.java | 442 +++++++++--------- .../common/expression/RunDataTest.java | 47 +- .../expression/function/DiceHelperTest.java | 90 ++-- .../expression/function/DropRollTest.java | 49 +- .../common/expression/function/RollTest.java | 95 ++-- 30 files changed, 1490 insertions(+), 1471 deletions(-) create mode 100644 spotless.license.java diff --git a/build.gradle b/build.gradle index af49bee..cb60955 100755 --- a/build.gradle +++ b/build.gradle @@ -17,13 +17,31 @@ plugins { apply plugin: 'java-library' -apply plugin: 'findbugs' apply plugin: 'com.diffplug.gradle.spotless' +apply plugin: 'maven' + sourceCompatibility = 10 targetCompatibility = 10 + +// In this section you declare where to find the dependencies of your project +repositories { + mavenCentral() + mavenLocal() + maven { url = 'http://maptool.craigs-stuff.net/repo/' } +} + + + +dependencies { + compile 'rhino:js:1.6R5' + compile 'antlr:antlr:2.7.6' + compile 'net.rptools.parser:parser:1.1.b24' + testCompile group: 'junit', name: 'junit', version: '4.11' +} + // Custom properties ext { // Get tag and commit info from Git to use for version numbering @@ -35,6 +53,7 @@ ext { if (tags) { tagVersion = tags.getName() + project.version = tagVersion } revision = head.abbreviatedId @@ -42,65 +61,56 @@ ext { // println 'Configuring for ' + project.name + " " + tagVersion + " by " + vendor } - +group = "net.rptools.dicelib" spotless { java { - eclipseFormatFile 'build-resources/eclipse.prefs.formatter.xml' + licenseHeaderFile 'spotless.license.java' + // Now using the Google Java style guide + //eclipse().configFile('build-resources/eclipse.prefs.formatter.xml') + googleJavaFormat() + // If you get exceptions thrown by spotlessApply, this might + // help. Enable it here if the problem is with a Java file, and + // below if it is not. Don't leave it enabled, as nothing will + // actually be updated if you do. + // https://github.com/diffplug/spotless/blob/master/PADDEDCELL.md + //paddedCell() } -} + format 'misc', { + target '**/*.gradle', '**/.gitignore' -configurations { - deployerJars + // spotless has built-in rules for most basic formatting tasks + trimTrailingWhitespace() + // or spaces. Takes an integer argument if you don't like 4 + indentWithSpaces(4) + //paddedCell() + } } - -dependencies { - compile 'rhino:js:1.6R5' - compile 'antlr:antlr:2.7.6' - compile 'net.rptools.parser:parser:1.1.b24' - testCompile group: 'junit', name: 'junit', version: '4.11' - deployerJars 'org.apache.maven.wagon:wagon-ssh:2.2' +configurations { + deployerJars } -ext.compileDate = new Date(); -ext.yyyymmdd = (new SimpleDateFormat('yyyyMMDD')).format(ext.compileDate); - - -repositories { - mavenCentral() - mavenLocal() - maven { - url = 'http://maptool.craigs-stuff.net/repo/' +install { + repositories.mavenInstaller { + pom.version = project.version; + pom.artifactId = 'dicelib'; + pom.groupId = 'net.rptools.dicelib'; } } -/* - * Gets the version name from the latest Git tag - */ - -def getVersionName() { - - - if (project.hasProperty('buildVersion')) { - return buildVersion - } else { - String vtxtVersionNo = new File('build-resources/version.txt').text.trim() - - return vtxtVersionNo +uploadArchives { + repositories.mavenDeployer { + pom.version = project.version; + pom.artifactId = 'dicelib'; + pom.groupId = 'net.rptools.dicelib'; + configuration = configurations.deployerJars; + repository url: 'file://' + projectDir + '/../maven-repo' } } -findbugs { - ignoreFailures = true - toolVersion = '3.0.0' - effort = 'max' - sourceSets = [] // Empty source set so it wont run during build/check -} - - jar { manifest { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fa98088..f45ffd6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,13 +1,4 @@ -<<<<<<< Updated upstream -distributionUrl=https\://services.gradle.org/distributions/gradle-5.3-bin.zip -======= -#Sat Mar 30 21:21:43 ACDT 2019 ->>>>>>> Stashed changes distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists -<<<<<<< Updated upstream -zipStoreBase=GRADLE_USER_HOME -======= distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip ->>>>>>> Stashed changes diff --git a/spotless.license.java b/spotless.license.java new file mode 100644 index 0000000..25bfe7b --- /dev/null +++ b/spotless.license.java @@ -0,0 +1,14 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ diff --git a/src/main/java/net/rptools/common/expression/ExpressionParser.java b/src/main/java/net/rptools/common/expression/ExpressionParser.java index 67e8b8b..c0cefe7 100755 --- a/src/main/java/net/rptools/common/expression/ExpressionParser.java +++ b/src/main/java/net/rptools/common/expression/ExpressionParser.java @@ -1,15 +1,16 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression; @@ -22,189 +23,199 @@ import net.rptools.parser.transform.StringLiteralTransformer; public class ExpressionParser { - private static String[][] DICE_PATTERNS = new String[][] { - // Comments - new String[] { "//.*", "" }, - - // Color hex strings #FFF or #FFFFFF or #FFFFFFFF (with alpha) - new String[] { "(? and specifically the Affero license + * text at . */ package net.rptools.common.expression; @@ -17,61 +18,61 @@ import java.util.Map; public class Result { - private final String expression; - private String detailExpression; - private Object value; - private String description; + private final String expression; + private String detailExpression; + private Object value; + private String description; - private final Map properties = new HashMap(); + private final Map properties = new HashMap(); - public Result(String expression) { - this.expression = expression; - } + public Result(String expression) { + this.expression = expression; + } - public String getExpression() { - return expression; - } + public String getExpression() { + return expression; + } - public String getDetailExpression() { - return detailExpression; - } + public String getDetailExpression() { + return detailExpression; + } - public void setDetailExpression(String detailExpression) { - this.detailExpression = detailExpression; - } + public void setDetailExpression(String detailExpression) { + this.detailExpression = detailExpression; + } - public String getDescription() { - return description; - } + public String getDescription() { + return description; + } - public void setDescription(String description) { - this.description = description; - } + public void setDescription(String description) { + this.description = description; + } - public Object getValue() { - return value; - } + public Object getValue() { + return value; + } - public void setValue(Object value) { - this.value = value; - } + public void setValue(Object value) { + this.value = value; + } - public Map getProperties() { - return this.properties; - } + public Map getProperties() { + return this.properties; + } - public String format() { - StringBuilder sb = new StringBuilder(64); - sb.append(expression).append(" = "); + public String format() { + StringBuilder sb = new StringBuilder(64); + sb.append(expression).append(" = "); - if (detailExpression != null && !detailExpression.equals(value.toString())) { - sb.append("(").append(detailExpression).append(") = "); - } + if (detailExpression != null && !detailExpression.equals(value.toString())) { + sb.append("(").append(detailExpression).append(") = "); + } - sb.append(value); - if (description != null) { - sb.append(" // ").append(description); - } - return sb.toString(); - } + sb.append(value); + if (description != null) { + sb.append(" // ").append(description); + } + return sb.toString(); + } } diff --git a/src/main/java/net/rptools/common/expression/RunData.java b/src/main/java/net/rptools/common/expression/RunData.java index f112246..ddd99c1 100755 --- a/src/main/java/net/rptools/common/expression/RunData.java +++ b/src/main/java/net/rptools/common/expression/RunData.java @@ -1,15 +1,16 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression; @@ -17,84 +18,77 @@ import java.util.Random; public class RunData { - private static ThreadLocal current = new ThreadLocal(); - public static Random RANDOM = new SecureRandom(); - - private final Result result; - - private long randomValue; - private long randomMax; - private long randomMin; - - public RunData(Result result) { - this.result = result; - } - - /** - * Returns a random integer between 1 and maxValue - */ - public int randomInt(int maxValue) { - return randomInt(1, maxValue); - } - - /** - * Returns a list of random integers between 1 and maxValue - */ - public int[] randomInts(int num, int maxValue) { - int[] ret = new int[num]; - for (int i = 0; i < num; i++) - ret[i] = randomInt(maxValue); - return ret; - } - - /** - * Returns a random integer between minValue and maxValue - */ - public int randomInt(int minValue, int maxValue) { - randomMin += minValue; - randomMax += maxValue; - - int result = RANDOM.nextInt(maxValue - minValue + 1) + minValue; - - randomValue += result; - - return result; - } - - /** - * Returns a list of random integers between minValue and maxValue - * @return - */ - public int[] randomInts(int num, int minValue, int maxValue) { - int[] ret = new int[num]; - for (int i = 0; i < num; i++) - ret[i] = randomInt(minValue, maxValue); - return ret; - } - - public Result getResult() { - return result; - } - - public static boolean hasCurrent() { - return current.get() != null; - } - - public static RunData getCurrent() { - RunData data = current.get(); - if (data == null) { - throw new NullPointerException("data cannot be null"); - } - return data; - } - - public static void setCurrent(RunData data) { - current.set(data); - } - - // If a seed is set we need to switch from SecureRandom to - // random. - public static void setSeed(long seed) { - RANDOM = new Random(seed); - } + private static ThreadLocal current = new ThreadLocal(); + public static Random RANDOM = new SecureRandom(); + + private final Result result; + + private long randomValue; + private long randomMax; + private long randomMin; + + public RunData(Result result) { + this.result = result; + } + + /** Returns a random integer between 1 and maxValue */ + public int randomInt(int maxValue) { + return randomInt(1, maxValue); + } + + /** Returns a list of random integers between 1 and maxValue */ + public int[] randomInts(int num, int maxValue) { + int[] ret = new int[num]; + for (int i = 0; i < num; i++) ret[i] = randomInt(maxValue); + return ret; + } + + /** Returns a random integer between minValue and maxValue */ + public int randomInt(int minValue, int maxValue) { + randomMin += minValue; + randomMax += maxValue; + + int result = RANDOM.nextInt(maxValue - minValue + 1) + minValue; + + randomValue += result; + + return result; + } + + /** + * Returns a list of random integers between minValue and maxValue + * + * @return + */ + public int[] randomInts(int num, int minValue, int maxValue) { + int[] ret = new int[num]; + for (int i = 0; i < num; i++) ret[i] = randomInt(minValue, maxValue); + return ret; + } + + public Result getResult() { + return result; + } + + public static boolean hasCurrent() { + return current.get() != null; + } + + public static RunData getCurrent() { + RunData data = current.get(); + if (data == null) { + throw new NullPointerException("data cannot be null"); + } + return data; + } + + public static void setCurrent(RunData data) { + current.set(data); + } + + // If a seed is set we need to switch from SecureRandom to + // random. + public static void setSeed(long seed) { + RANDOM = new Random(seed); + } } diff --git a/src/main/java/net/rptools/common/expression/function/CountSuccessDice.java b/src/main/java/net/rptools/common/expression/function/CountSuccessDice.java index ac741d7..7d194d5 100755 --- a/src/main/java/net/rptools/common/expression/function/CountSuccessDice.java +++ b/src/main/java/net/rptools/common/expression/function/CountSuccessDice.java @@ -1,39 +1,39 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; import net.rptools.parser.function.EvaluationException; public class CountSuccessDice extends AbstractNumberFunction { - public CountSuccessDice() { - super(3, 3, false, "countsuccess", "success"); - } - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { - int n = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); - int success = ((BigDecimal) parameters.get(n++)).intValue(); + public CountSuccessDice() { + super(3, 3, false, "countsuccess", "success"); + } - return new BigDecimal(DiceHelper.countSuccessDice(times, sides, success)); - } + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + int success = ((BigDecimal) parameters.get(n++)).intValue(); + return new BigDecimal(DiceHelper.countSuccessDice(times, sides, success)); + } } diff --git a/src/main/java/net/rptools/common/expression/function/DiceHelper.java b/src/main/java/net/rptools/common/expression/function/DiceHelper.java index 7fc4f58..985fbbb 100755 --- a/src/main/java/net/rptools/common/expression/function/DiceHelper.java +++ b/src/main/java/net/rptools/common/expression/function/DiceHelper.java @@ -1,217 +1,211 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.util.Arrays; - import java.util.Comparator; import net.rptools.common.expression.RunData; import net.rptools.parser.function.*; public class DiceHelper { - public static int rollDice(int times, int sides) { - int result = 0; - - RunData runData = RunData.getCurrent(); + public static int rollDice(int times, int sides) { + int result = 0; - for (int i = 0; i < times; i++) { - result += runData.randomInt(sides); - } + RunData runData = RunData.getCurrent(); - return result; - } + for (int i = 0; i < times; i++) { + result += runData.randomInt(sides); + } - public static String explodingSuccessDice(int times, int sides, int target) throws EvaluationException { - String rolls = "Dice: "; - int successes = 0; + return result; + } - for (int i = 0; i < times; i++) { - int currentRoll = explodeDice(1, sides); - rolls += currentRoll + ", "; - if (currentRoll >= target) - successes++; - } - return rolls + "Successes: " + successes; - } + public static String explodingSuccessDice(int times, int sides, int target) + throws EvaluationException { + String rolls = "Dice: "; + int successes = 0; - public static String openTestDice(int times, int sides) throws EvaluationException { - String rolls = "Dice: "; - int max = 0; + for (int i = 0; i < times; i++) { + int currentRoll = explodeDice(1, sides); + rolls += currentRoll + ", "; + if (currentRoll >= target) successes++; + } + return rolls + "Successes: " + successes; + } - for (int i = 0; i < times; i++) { - int currentRoll = explodeDice(1, sides); - rolls += currentRoll + ", "; - if (currentRoll > max) - max = currentRoll; - } - return rolls + "Maximum: " + max; - } + public static String openTestDice(int times, int sides) throws EvaluationException { + String rolls = "Dice: "; + int max = 0; - public static int fudgeDice(int times) { - return rollDice(times, 3) - (2 * times); - } + for (int i = 0; i < times; i++) { + int currentRoll = explodeDice(1, sides); + rolls += currentRoll + ", "; + if (currentRoll > max) max = currentRoll; + } + return rolls + "Maximum: " + max; + } - public static int ubiquityDice(int times) { - return rollDice(times, 2) - times; - } + public static int fudgeDice(int times) { + return rollDice(times, 3) - (2 * times); + } - public static int keepDice(int times, int sides, int keep) throws EvaluationException { - return dropDice(times, sides, times - keep); - } + public static int ubiquityDice(int times) { + return rollDice(times, 2) - times; + } - public static int keepLowestDice(int times, int sides, int keep) throws EvaluationException { - return dropDiceHighest(times, sides, times - keep); - } + public static int keepDice(int times, int sides, int keep) throws EvaluationException { + return dropDice(times, sides, times - keep); + } - public static int dropDice(int times, int sides, int drop) throws EvaluationException { - if (times - drop <= 0) - throw new EvaluationException("You cannot drop more dice than you roll"); + public static int keepLowestDice(int times, int sides, int keep) throws EvaluationException { + return dropDiceHighest(times, sides, times - keep); + } - RunData runData = RunData.getCurrent(); + public static int dropDice(int times, int sides, int drop) throws EvaluationException { + if (times - drop <= 0) throw new EvaluationException("You cannot drop more dice than you roll"); - int[] values = runData.randomInts(times, sides); + RunData runData = RunData.getCurrent(); - Arrays.sort(values); + int[] values = runData.randomInts(times, sides); - int result = 0; - for (int i = drop; i < times; i++) { - result += values[i]; - } + Arrays.sort(values); - return result; - } + int result = 0; + for (int i = drop; i < times; i++) { + result += values[i]; + } - public static int dropDiceHighest(int times, int sides, int drop) throws EvaluationException { - if (times - drop <= 0) - throw new EvaluationException("You cannot drop more dice than you roll"); + return result; + } - RunData runData = RunData.getCurrent(); + public static int dropDiceHighest(int times, int sides, int drop) throws EvaluationException { + if (times - drop <= 0) throw new EvaluationException("You cannot drop more dice than you roll"); - int[] values = runData.randomInts(times, sides); + RunData runData = RunData.getCurrent(); - int[] descValues = Arrays.stream(values).boxed().sorted(Comparator.reverseOrder()).mapToInt(Integer::intValue).toArray(); + int[] values = runData.randomInts(times, sides); - int result = 0; - for (int i = drop; i < times; i++) { - result += descValues[i]; - } + int[] descValues = + Arrays.stream(values) + .boxed() + .sorted(Comparator.reverseOrder()) + .mapToInt(Integer::intValue) + .toArray(); - return result; - } + int result = 0; + for (int i = drop; i < times; i++) { + result += descValues[i]; + } - public static int rerollDice(int times, int sides, int lowerBound) throws EvaluationException { - RunData runData = RunData.getCurrent(); + return result; + } - if (lowerBound > sides) - throw new EvaluationException( - "When rerolling, the lowerbound must be smaller than the number of sides on the rolling dice."); + public static int rerollDice(int times, int sides, int lowerBound) throws EvaluationException { + RunData runData = RunData.getCurrent(); - int[] values = new int[times]; + if (lowerBound > sides) + throw new EvaluationException( + "When rerolling, the lowerbound must be smaller than the number of sides on the rolling dice."); - for (int i = 0; i < values.length; i++) { - int roll; - while ((roll = runData.randomInt(sides)) < lowerBound) - ; + int[] values = new int[times]; - values[i] = roll; - } + for (int i = 0; i < values.length; i++) { + int roll; + while ((roll = runData.randomInt(sides)) < lowerBound) ; - int result = 0; - for (int i = 0; i < values.length; i++) { - result += values[i]; - } + values[i] = roll; + } - return result; - } + int result = 0; + for (int i = 0; i < values.length; i++) { + result += values[i]; + } - public static int explodeDice(int times, int sides) throws EvaluationException { - int result = 0; + return result; + } - if (sides == 0 || sides == 1) - throw new EvaluationException("Number of sides must be > 1"); + public static int explodeDice(int times, int sides) throws EvaluationException { + int result = 0; - RunData runData = RunData.getCurrent(); + if (sides == 0 || sides == 1) throw new EvaluationException("Number of sides must be > 1"); - for (int i = 0; i < times; i++) { - int roll = runData.randomInt(sides); - if (roll == sides) - times++; - result += roll; - } + RunData runData = RunData.getCurrent(); - return result; - } + for (int i = 0; i < times; i++) { + int roll = runData.randomInt(sides); + if (roll == sides) times++; + result += roll; + } - public static int countSuccessDice(int times, int sides, int success) { - RunData runData = RunData.getCurrent(); + return result; + } - int result = 0; - for (int value : runData.randomInts(times, sides)) { - if (value >= success) - result++; - } + public static int countSuccessDice(int times, int sides, int success) { + RunData runData = RunData.getCurrent(); - return result; - } + int result = 0; + for (int value : runData.randomInts(times, sides)) { + if (value >= success) result++; + } - public static String countShadowRun4(int times, int gremlins, boolean explode) { - RunData runData = RunData.getCurrent(); + return result; + } - int hitCount = 0; - int oneCount = 0; - int sides = 6; - int success = 5; - String actual = ""; - String glitch = ""; + public static String countShadowRun4(int times, int gremlins, boolean explode) { + RunData runData = RunData.getCurrent(); - for (int i = 0; i < times; i++) { - int value = runData.randomInt(sides); + int hitCount = 0; + int oneCount = 0; + int sides = 6; + int success = 5; + String actual = ""; + String glitch = ""; - if (value >= success) - hitCount++; + for (int i = 0; i < times; i++) { + int value = runData.randomInt(sides); - if (value == 1) - oneCount++; + if (value >= success) hitCount++; - if (value == 6 && explode) - times++; + if (value == 1) oneCount++; - actual = actual + value + " "; - } + if (value == 6 && explode) times++; - // Check for Glitchs - if (oneCount != 0) { - if ((hitCount == 0) && ((double) times / 2 - gremlins) <= (double) oneCount) { - glitch = " *Critical Glitch*"; - } else if ((double) (times / 2 - gremlins) <= (double) oneCount) { - glitch = " *Glitch*"; - } - } + actual = actual + value + " "; + } - String result = "Hits: " + hitCount + " Ones: " + oneCount + glitch + " Results: " + actual; + // Check for Glitchs + if (oneCount != 0) { + if ((hitCount == 0) && ((double) times / 2 - gremlins) <= (double) oneCount) { + glitch = " *Critical Glitch*"; + } else if ((double) (times / 2 - gremlins) <= (double) oneCount) { + glitch = " *Glitch*"; + } + } - return result; - } + String result = "Hits: " + hitCount + " Ones: " + oneCount + glitch + " Results: " + actual; - public static int rollModWithBounds(int times, int sides, int sub, int lower, int upper) { - int result = 0; + return result; + } - for (int i = 0; i < times; i++) { - result += Math.min(Math.max(rollDice(1, sides) - sub, lower), upper); - } + public static int rollModWithBounds(int times, int sides, int sub, int lower, int upper) { + int result = 0; - return result; - } + for (int i = 0; i < times; i++) { + result += Math.min(Math.max(rollDice(1, sides) - sub, lower), upper); + } + return result; + } } diff --git a/src/main/java/net/rptools/common/expression/function/DropHighestRoll.java b/src/main/java/net/rptools/common/expression/function/DropHighestRoll.java index a34c5a8..2838cd5 100755 --- a/src/main/java/net/rptools/common/expression/function/DropHighestRoll.java +++ b/src/main/java/net/rptools/common/expression/function/DropHighestRoll.java @@ -1,15 +1,16 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; @@ -21,18 +22,18 @@ public class DropHighestRoll extends AbstractNumberFunction { - public DropHighestRoll() { - super(3, 3, false, "dropHighest"); - } + public DropHighestRoll() { + super(3, 3, false, "dropHighest"); + } - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { - int n = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); - int drop = ((BigDecimal) parameters.get(n++)).intValue(); - - return new BigDecimal(DiceHelper.dropDiceHighest(times, sides, drop)); - } + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + int drop = ((BigDecimal) parameters.get(n++)).intValue(); + return new BigDecimal(DiceHelper.dropDiceHighest(times, sides, drop)); + } } diff --git a/src/main/java/net/rptools/common/expression/function/DropRoll.java b/src/main/java/net/rptools/common/expression/function/DropRoll.java index aaddeff..507e1f8 100755 --- a/src/main/java/net/rptools/common/expression/function/DropRoll.java +++ b/src/main/java/net/rptools/common/expression/function/DropRoll.java @@ -1,39 +1,39 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; import net.rptools.parser.function.EvaluationException; public class DropRoll extends AbstractNumberFunction { - public DropRoll() { - super(3, 3, false, "drop"); - } - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { - int n = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); - int drop = ((BigDecimal) parameters.get(n++)).intValue(); + public DropRoll() { + super(3, 3, false, "drop"); + } - return new BigDecimal(DiceHelper.dropDice(times, sides, drop)); - } + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + int drop = ((BigDecimal) parameters.get(n++)).intValue(); + return new BigDecimal(DiceHelper.dropDice(times, sides, drop)); + } } diff --git a/src/main/java/net/rptools/common/expression/function/ExplodeDice.java b/src/main/java/net/rptools/common/expression/function/ExplodeDice.java index 318a8c3..9f7dfad 100755 --- a/src/main/java/net/rptools/common/expression/function/ExplodeDice.java +++ b/src/main/java/net/rptools/common/expression/function/ExplodeDice.java @@ -1,38 +1,38 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; import net.rptools.parser.function.EvaluationException; public class ExplodeDice extends AbstractNumberFunction { - public ExplodeDice() { - super(2, 2, false, "explode"); - } - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { - int n = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); + public ExplodeDice() { + super(2, 2, false, "explode"); + } - return new BigDecimal(DiceHelper.explodeDice(times, sides)); - } + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + return new BigDecimal(DiceHelper.explodeDice(times, sides)); + } } diff --git a/src/main/java/net/rptools/common/expression/function/ExplodingSuccessDice.java b/src/main/java/net/rptools/common/expression/function/ExplodingSuccessDice.java index b8b3239..b7d03c0 100755 --- a/src/main/java/net/rptools/common/expression/function/ExplodingSuccessDice.java +++ b/src/main/java/net/rptools/common/expression/function/ExplodingSuccessDice.java @@ -1,39 +1,39 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; import net.rptools.parser.function.EvaluationException; public class ExplodingSuccessDice extends AbstractNumberFunction { - public ExplodingSuccessDice() { - super(3, 3, true, "explodingSuccess"); - } - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { - int n = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); - int target = ((BigDecimal) parameters.get(n++)).intValue(); + public ExplodingSuccessDice() { + super(3, 3, true, "explodingSuccess"); + } - return DiceHelper.explodingSuccessDice(times, sides, target); - } + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + int target = ((BigDecimal) parameters.get(n++)).intValue(); + return DiceHelper.explodingSuccessDice(times, sides, target); + } } diff --git a/src/main/java/net/rptools/common/expression/function/FudgeRoll.java b/src/main/java/net/rptools/common/expression/function/FudgeRoll.java index dfe19de..a2f9ea1 100755 --- a/src/main/java/net/rptools/common/expression/function/FudgeRoll.java +++ b/src/main/java/net/rptools/common/expression/function/FudgeRoll.java @@ -1,46 +1,45 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; -/** fudge(range) - * - * Generate a random number form 1 to sides, times - * number of times. If times is not supplied it defaults to 1. - * - * Example: - * fudge(4) = 4dF (-4..4) +/** + * fudge(range) + * + *

Generate a random number form 1 to sides, times number of times. If + * times is not supplied it defaults to 1. + * + *

Example: fudge(4) = 4dF (-4..4) */ public class FudgeRoll extends AbstractNumberFunction { - public FudgeRoll() { - super(1, 1, false, "f", "fudge"); - } + public FudgeRoll() { + super(1, 1, false, "f", "fudge"); + } - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) { - int n = 0; + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) { + int n = 0; - int times = 1; - if (parameters.size() == 1) - times = ((BigDecimal) parameters.get(n++)).intValue(); + int times = 1; + if (parameters.size() == 1) times = ((BigDecimal) parameters.get(n++)).intValue(); - return new BigDecimal(DiceHelper.fudgeDice(times)); - } + return new BigDecimal(DiceHelper.fudgeDice(times)); + } } diff --git a/src/main/java/net/rptools/common/expression/function/HeroKillingRoll.java b/src/main/java/net/rptools/common/expression/function/HeroKillingRoll.java index b55d170..589cc51 100755 --- a/src/main/java/net/rptools/common/expression/function/HeroKillingRoll.java +++ b/src/main/java/net/rptools/common/expression/function/HeroKillingRoll.java @@ -1,21 +1,21 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.common.expression.RunData; import net.rptools.parser.Parser; import net.rptools.parser.ParserException; @@ -24,89 +24,87 @@ /* * Hero System Dice - * + * * Used to get both the stun & body of an attack roll. - * + * */ public class HeroKillingRoll extends AbstractNumberFunction { - public HeroKillingRoll() { - super(2, 3, false, "herokilling", "herokilling2", "killing", "heromultiplier", "multiplier"); - } + public HeroKillingRoll() { + super(2, 3, false, "herokilling", "herokilling2", "killing", "heromultiplier", "multiplier"); + } - // Use variable names with illegal character to minimize chances of variable overlap - private static String lastKillingBodyVar = "#Hero-LastKillingBodyVar"; + // Use variable names with illegal character to minimize chances of variable overlap + private static String lastKillingBodyVar = "#Hero-LastKillingBodyVar"; - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws ParserException { - int n = 0; + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws ParserException { + int n = 0; - double times = ((BigDecimal) parameters.get(n++)).doubleValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); - double half = times - Math.floor(times); - int extra = 0; - if (parameters.size() > 2) - extra = ((BigDecimal) parameters.get(n++)).intValue(); + double times = ((BigDecimal) parameters.get(n++)).doubleValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + double half = times - Math.floor(times); + int extra = 0; + if (parameters.size() > 2) extra = ((BigDecimal) parameters.get(n++)).intValue(); - VariableResolver vr = parser.getVariableResolver(); - RunData runData = RunData.getCurrent(); + VariableResolver vr = parser.getVariableResolver(); + RunData runData = RunData.getCurrent(); - if (functionName.equalsIgnoreCase("herokilling")) { + if (functionName.equalsIgnoreCase("herokilling")) { - int body = DiceHelper.rollDice((int) times, sides); - body = body + extra; - /* - * If value half or more roll a half die - */ - if (half >= 0.5) { - /* - * Roll a half dice. - */ - int die = runData.randomInt(sides); - body += (die + 1) / 2; - } else if (half >= 0.2) { - /* - * Add a single pip - */ - body++; - } + int body = DiceHelper.rollDice((int) times, sides); + body = body + extra; + /* + * If value half or more roll a half die + */ + if (half >= 0.5) { + /* + * Roll a half dice. + */ + int die = runData.randomInt(sides); + body += (die + 1) / 2; + } else if (half >= 0.2) { + /* + * Add a single pip + */ + body++; + } - parser.setVariable(lastKillingBodyVar, new BigDecimal(body)); - return new BigDecimal(body); - } else if (functionName.equalsIgnoreCase("herokilling2")) { + parser.setVariable(lastKillingBodyVar, new BigDecimal(body)); + return new BigDecimal(body); + } else if (functionName.equalsIgnoreCase("herokilling2")) { - int body = DiceHelper.rollDice((int) times, sides); - body = body + extra; - /* - * If value half or more roll a die -1. minimum value of 1. - */ - if (half >= 0.5) { - /* - * Roll a half dice. - */ - int die = runData.randomInt(sides); - if (die > 1) - die = die - 1; - body += die; - } else if (half >= 0.2) { - /* - * Add a single pip - */ - body++; - } + int body = DiceHelper.rollDice((int) times, sides); + body = body + extra; + /* + * If value half or more roll a die -1. minimum value of 1. + */ + if (half >= 0.5) { + /* + * Roll a half dice. + */ + int die = runData.randomInt(sides); + if (die > 1) die = die - 1; + body += die; + } else if (half >= 0.2) { + /* + * Add a single pip + */ + body++; + } - parser.setVariable(lastKillingBodyVar, new BigDecimal(body)); - return new BigDecimal(body); - } else { - int multi = DiceHelper.rollDice((int) times, sides); - multi = multi + extra; - if (multi < 1) - multi = 1; + parser.setVariable(lastKillingBodyVar, new BigDecimal(body)); + return new BigDecimal(body); + } else { + int multi = DiceHelper.rollDice((int) times, sides); + multi = multi + extra; + if (multi < 1) multi = 1; - int lastBody = 0; - if (vr.containsVariable(lastKillingBodyVar)) - lastBody = ((BigDecimal) vr.getVariable(lastKillingBodyVar)).intValue(); + int lastBody = 0; + if (vr.containsVariable(lastKillingBodyVar)) + lastBody = ((BigDecimal) vr.getVariable(lastKillingBodyVar)).intValue(); - return new BigDecimal(lastBody * multi); - } - } + return new BigDecimal(lastBody * multi); + } + } } diff --git a/src/main/java/net/rptools/common/expression/function/HeroRoll.java b/src/main/java/net/rptools/common/expression/function/HeroRoll.java index c42ee42..923262f 100755 --- a/src/main/java/net/rptools/common/expression/function/HeroRoll.java +++ b/src/main/java/net/rptools/common/expression/function/HeroRoll.java @@ -1,21 +1,21 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.common.expression.RunData; import net.rptools.parser.Parser; import net.rptools.parser.ParserException; @@ -24,94 +24,91 @@ /* * Hero System Dice - * + * * Used to get both the stun & body of an attack roll. - * + * */ public class HeroRoll extends AbstractNumberFunction { - public HeroRoll() { - super(2, 2, false, "hero", "herostun", "herobody"); - } - - // Use variable names with illegal character to minimize chances of variable overlap - private static String lastTimesVar = "#Hero-LastTimesVar"; - private static String lastSidesVar = "#Hero-LastSidesVar"; - private static String lastBodyVar = "#Hero-LastBodyVar"; - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws ParserException { - int n = 0; - - double times = ((BigDecimal) parameters.get(n++)).doubleValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); - - VariableResolver vr = parser.getVariableResolver(); - - if (functionName.equalsIgnoreCase("herobody")) { - double lastTimes = 0; - if (vr.containsVariable(lastTimesVar)) - lastTimes = ((BigDecimal) vr.getVariable(lastTimesVar)).doubleValue(); - - int lastSides = 0; - if (vr.containsVariable(lastSidesVar)) - lastSides = ((BigDecimal) vr.getVariable(lastSidesVar)).intValue(); - - int lastBody = 0; - if (vr.containsVariable(lastBodyVar)) - lastBody = ((BigDecimal) vr.getVariable(lastBodyVar)).intValue(); - - if (times == lastTimes && sides == lastSides) - return new BigDecimal(lastBody); - - return new BigDecimal(-1); // Should this be -1? Perhaps it should return null. - } else { - // assume stun - - double lastTimes = times; - int lastSides = sides; - int lastBody = 0; - - RunData runData = RunData.getCurrent(); - - int stun = 0; - double half = times - Math.floor(times); - for (int i = 0; i < Math.floor(times); i++) { - int die = runData.randomInt(sides); - /* - * Keep track of the body generated. In theory - * Hero System only uses 6-sided where a 1 is - * 0 body, 2-5 is 1 body and 6 is 2 body but I - * left the sides unbounded just in case. - */ - if (die > 1) - lastBody++; - if (die == sides) - lastBody++; - - stun += die; - } - - if (half >= 0.5) { - /* - * Roll a half dice. In theory Hero System - * only uses 6-sided and for half dice - * 1 & 2 = 1 Stun 0 body - * 3 = 2 stun 0 body - * 4 = 2 stun 1 body - * 5 & 6 = 3 stun 1 body - */ - int die = runData.randomInt(sides); - if (die * 2 > sides) - lastBody++; - - stun += (die + 1) / 2; - } - - parser.setVariable(lastTimesVar, new BigDecimal(lastTimes)); - parser.setVariable(lastSidesVar, new BigDecimal(lastSides)); - parser.setVariable(lastBodyVar, new BigDecimal(lastBody)); - - return new BigDecimal(stun); - } - } + public HeroRoll() { + super(2, 2, false, "hero", "herostun", "herobody"); + } + + // Use variable names with illegal character to minimize chances of variable overlap + private static String lastTimesVar = "#Hero-LastTimesVar"; + private static String lastSidesVar = "#Hero-LastSidesVar"; + private static String lastBodyVar = "#Hero-LastBodyVar"; + + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws ParserException { + int n = 0; + + double times = ((BigDecimal) parameters.get(n++)).doubleValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + + VariableResolver vr = parser.getVariableResolver(); + + if (functionName.equalsIgnoreCase("herobody")) { + double lastTimes = 0; + if (vr.containsVariable(lastTimesVar)) + lastTimes = ((BigDecimal) vr.getVariable(lastTimesVar)).doubleValue(); + + int lastSides = 0; + if (vr.containsVariable(lastSidesVar)) + lastSides = ((BigDecimal) vr.getVariable(lastSidesVar)).intValue(); + + int lastBody = 0; + if (vr.containsVariable(lastBodyVar)) + lastBody = ((BigDecimal) vr.getVariable(lastBodyVar)).intValue(); + + if (times == lastTimes && sides == lastSides) return new BigDecimal(lastBody); + + return new BigDecimal(-1); // Should this be -1? Perhaps it should return null. + } else { + // assume stun + + double lastTimes = times; + int lastSides = sides; + int lastBody = 0; + + RunData runData = RunData.getCurrent(); + + int stun = 0; + double half = times - Math.floor(times); + for (int i = 0; i < Math.floor(times); i++) { + int die = runData.randomInt(sides); + /* + * Keep track of the body generated. In theory + * Hero System only uses 6-sided where a 1 is + * 0 body, 2-5 is 1 body and 6 is 2 body but I + * left the sides unbounded just in case. + */ + if (die > 1) lastBody++; + if (die == sides) lastBody++; + + stun += die; + } + + if (half >= 0.5) { + /* + * Roll a half dice. In theory Hero System + * only uses 6-sided and for half dice + * 1 & 2 = 1 Stun 0 body + * 3 = 2 stun 0 body + * 4 = 2 stun 1 body + * 5 & 6 = 3 stun 1 body + */ + int die = runData.randomInt(sides); + if (die * 2 > sides) lastBody++; + + stun += (die + 1) / 2; + } + + parser.setVariable(lastTimesVar, new BigDecimal(lastTimes)); + parser.setVariable(lastSidesVar, new BigDecimal(lastSides)); + parser.setVariable(lastBodyVar, new BigDecimal(lastBody)); + + return new BigDecimal(stun); + } + } } diff --git a/src/main/java/net/rptools/common/expression/function/If.java b/src/main/java/net/rptools/common/expression/function/If.java index 30a2019..4405633 100755 --- a/src/main/java/net/rptools/common/expression/function/If.java +++ b/src/main/java/net/rptools/common/expression/function/If.java @@ -1,37 +1,36 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractFunction; import net.rptools.parser.function.EvaluationException; public class If extends AbstractFunction { - public If() { - super(3, 3, false, "if"); - } - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { - if (BigDecimal.ZERO.equals((BigDecimal) parameters.get(0))) - return parameters.get(2); + public If() { + super(3, 3, false, "if"); + } - return parameters.get(1); - } + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { + if (BigDecimal.ZERO.equals((BigDecimal) parameters.get(0))) return parameters.get(2); + return parameters.get(1); + } } diff --git a/src/main/java/net/rptools/common/expression/function/KeepLowestRoll.java b/src/main/java/net/rptools/common/expression/function/KeepLowestRoll.java index 4f3ce53..361db5f 100755 --- a/src/main/java/net/rptools/common/expression/function/KeepLowestRoll.java +++ b/src/main/java/net/rptools/common/expression/function/KeepLowestRoll.java @@ -1,15 +1,16 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; @@ -21,18 +22,18 @@ public class KeepLowestRoll extends AbstractNumberFunction { - public KeepLowestRoll() { - super(3, 3, false, "keepLowest"); - } + public KeepLowestRoll() { + super(3, 3, false, "keepLowest"); + } - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { - int n = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); - int keep = ((BigDecimal) parameters.get(n++)).intValue(); - - return new BigDecimal(DiceHelper.keepLowestDice(times, sides, keep)); - } + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + int keep = ((BigDecimal) parameters.get(n++)).intValue(); + return new BigDecimal(DiceHelper.keepLowestDice(times, sides, keep)); + } } diff --git a/src/main/java/net/rptools/common/expression/function/KeepRoll.java b/src/main/java/net/rptools/common/expression/function/KeepRoll.java index 9ad65ad..9a064f9 100755 --- a/src/main/java/net/rptools/common/expression/function/KeepRoll.java +++ b/src/main/java/net/rptools/common/expression/function/KeepRoll.java @@ -1,39 +1,39 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; import net.rptools.parser.function.EvaluationException; public class KeepRoll extends AbstractNumberFunction { - public KeepRoll() { - super(3, 3, false, "keep"); - } - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { - int n = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); - int keep = ((BigDecimal) parameters.get(n++)).intValue(); + public KeepRoll() { + super(3, 3, false, "keep"); + } - return new BigDecimal(DiceHelper.keepDice(times, sides, keep)); - } + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + int keep = ((BigDecimal) parameters.get(n++)).intValue(); + return new BigDecimal(DiceHelper.keepDice(times, sides, keep)); + } } diff --git a/src/main/java/net/rptools/common/expression/function/OpenTestDice.java b/src/main/java/net/rptools/common/expression/function/OpenTestDice.java index b832e8e..7e5b62a 100755 --- a/src/main/java/net/rptools/common/expression/function/OpenTestDice.java +++ b/src/main/java/net/rptools/common/expression/function/OpenTestDice.java @@ -1,38 +1,38 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; import net.rptools.parser.function.EvaluationException; public class OpenTestDice extends AbstractNumberFunction { - public OpenTestDice() { - super(2, 2, true, "openTest"); - } - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { - int n = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); + public OpenTestDice() { + super(2, 2, true, "openTest"); + } - return DiceHelper.openTestDice(times, sides); - } + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + return DiceHelper.openTestDice(times, sides); + } } diff --git a/src/main/java/net/rptools/common/expression/function/RerollDice.java b/src/main/java/net/rptools/common/expression/function/RerollDice.java index 4f07c70..4225471 100755 --- a/src/main/java/net/rptools/common/expression/function/RerollDice.java +++ b/src/main/java/net/rptools/common/expression/function/RerollDice.java @@ -1,39 +1,39 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; import net.rptools.parser.function.EvaluationException; public class RerollDice extends AbstractNumberFunction { - public RerollDice() { - super(3, 3, false, "reroll"); - } - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { - int n = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); - int lowerBound = ((BigDecimal) parameters.get(n++)).intValue(); + public RerollDice() { + super(3, 3, false, "reroll"); + } - return new BigDecimal(DiceHelper.rerollDice(times, sides, lowerBound)); - } + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { + int n = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); + int lowerBound = ((BigDecimal) parameters.get(n++)).intValue(); + return new BigDecimal(DiceHelper.rerollDice(times, sides, lowerBound)); + } } diff --git a/src/main/java/net/rptools/common/expression/function/Roll.java b/src/main/java/net/rptools/common/expression/function/Roll.java index fc2521b..bb3aaae 100755 --- a/src/main/java/net/rptools/common/expression/function/Roll.java +++ b/src/main/java/net/rptools/common/expression/function/Roll.java @@ -1,48 +1,47 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; -/** roll(range) or roll(times, range) - * - * Generate a random number form 1 to sides, times - * number of times. If times is not supplied it defaults to 1. - * - * Example: - * roll(4, 6) = 4d6 +/** + * roll(range) or roll(times, range) + * + *

Generate a random number form 1 to sides, times number of times. If + * times is not supplied it defaults to 1. + * + *

Example: roll(4, 6) = 4d6 */ public class Roll extends AbstractNumberFunction { - public Roll() { - super(1, 2, false, "d", "roll", "dice"); - } + public Roll() { + super(1, 2, false, "d", "roll", "dice"); + } - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) { - int n = 0; + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) { + int n = 0; - int times = 1; - if (parameters.size() == 2) - times = ((BigDecimal) parameters.get(n++)).intValue(); + int times = 1; + if (parameters.size() == 2) times = ((BigDecimal) parameters.get(n++)).intValue(); - int sides = ((BigDecimal) parameters.get(n++)).intValue(); + int sides = ((BigDecimal) parameters.get(n++)).intValue(); - return new BigDecimal(DiceHelper.rollDice(times, sides)); - } + return new BigDecimal(DiceHelper.rollDice(times, sides)); + } } diff --git a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java index 937b918..ca4c825 100644 --- a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java +++ b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java @@ -1,56 +1,70 @@ +/* + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. + * + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . + */ package net.rptools.common.expression.function; +import java.math.BigDecimal; +import java.util.List; import net.rptools.parser.Parser; import net.rptools.parser.ParserException; import net.rptools.parser.function.AbstractNumberFunction; -import java.math.BigDecimal; -import java.util.List; - public class RollWithBounds extends AbstractNumberFunction { - public RollWithBounds() { - super(3, 4, false, "rollSubWithLower", "rollWithLower", "rollAddWithUpper", "rollWithUpper"); - } + public RollWithBounds() { + super(3, 4, false, "rollSubWithLower", "rollWithLower", "rollAddWithUpper", "rollWithUpper"); + } - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws ParserException { - int times = 0; - int sides = 0; - int mod = 0; - int lower = Integer.MIN_VALUE; - int upper = Integer.MAX_VALUE; + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws ParserException { + int times = 0; + int sides = 0; + int mod = 0; + int lower = Integer.MIN_VALUE; + int upper = Integer.MAX_VALUE; - switch (functionName) { - case "rollSubWithLower": - times = ((BigDecimal) parameters.get(0)).intValue(); - sides = ((BigDecimal) parameters.get(1)).intValue(); - mod = -((BigDecimal) parameters.get(2)).intValue(); - lower = ((BigDecimal) parameters.get(3)).intValue(); - break; - case "rollWithLower": - times = ((BigDecimal) parameters.get(0)).intValue(); - sides = ((BigDecimal) parameters.get(1)).intValue(); - lower = ((BigDecimal) parameters.get(2)).intValue(); - break; - case "rollAddWithUpper": - times = ((BigDecimal) parameters.get(0)).intValue(); - sides = ((BigDecimal) parameters.get(1)).intValue(); - mod = ((BigDecimal) parameters.get(2)).intValue(); - upper = ((BigDecimal) parameters.get(3)).intValue(); - break; - case "rollWithUpper": - times = ((BigDecimal) parameters.get(0)).intValue(); - sides = ((BigDecimal) parameters.get(1)).intValue(); - upper = ((BigDecimal) parameters.get(2)).intValue(); - break; - case "rollAddWithLower": - times = ((BigDecimal) parameters.get(0)).intValue(); - sides = ((BigDecimal) parameters.get(1)).intValue(); - mod = ((BigDecimal) parameters.get(2)).intValue(); - lower = ((BigDecimal) parameters.get(3)).intValue(); - break; - } - return DiceHelper.rollModWithBounds(times, sides, mod, lower, upper); - } + switch (functionName) { + case "rollSubWithLower": + times = ((BigDecimal) parameters.get(0)).intValue(); + sides = ((BigDecimal) parameters.get(1)).intValue(); + mod = -((BigDecimal) parameters.get(2)).intValue(); + lower = ((BigDecimal) parameters.get(3)).intValue(); + break; + case "rollWithLower": + times = ((BigDecimal) parameters.get(0)).intValue(); + sides = ((BigDecimal) parameters.get(1)).intValue(); + lower = ((BigDecimal) parameters.get(2)).intValue(); + break; + case "rollAddWithUpper": + times = ((BigDecimal) parameters.get(0)).intValue(); + sides = ((BigDecimal) parameters.get(1)).intValue(); + mod = ((BigDecimal) parameters.get(2)).intValue(); + upper = ((BigDecimal) parameters.get(3)).intValue(); + break; + case "rollWithUpper": + times = ((BigDecimal) parameters.get(0)).intValue(); + sides = ((BigDecimal) parameters.get(1)).intValue(); + upper = ((BigDecimal) parameters.get(2)).intValue(); + break; + case "rollAddWithLower": + times = ((BigDecimal) parameters.get(0)).intValue(); + sides = ((BigDecimal) parameters.get(1)).intValue(); + mod = ((BigDecimal) parameters.get(2)).intValue(); + lower = ((BigDecimal) parameters.get(3)).intValue(); + break; + } + return DiceHelper.rollModWithBounds(times, sides, mod, lower, upper); + } } diff --git a/src/main/java/net/rptools/common/expression/function/ShadowRun4Dice.java b/src/main/java/net/rptools/common/expression/function/ShadowRun4Dice.java index 4ec012c..5595df4 100755 --- a/src/main/java/net/rptools/common/expression/function/ShadowRun4Dice.java +++ b/src/main/java/net/rptools/common/expression/function/ShadowRun4Dice.java @@ -1,41 +1,40 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; import net.rptools.parser.function.EvaluationException; public class ShadowRun4Dice extends AbstractNumberFunction { - public ShadowRun4Dice() { - super(1, 2, true, "sr4"); - } - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { + public ShadowRun4Dice() { + super(1, 2, true, "sr4"); + } - int n = 0; - int gremlins = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - if (parameters.size() == 2) - gremlins = ((BigDecimal) parameters.get(n++)).intValue(); + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { - return DiceHelper.countShadowRun4(times, gremlins, false); - } + int n = 0; + int gremlins = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + if (parameters.size() == 2) gremlins = ((BigDecimal) parameters.get(n++)).intValue(); + return DiceHelper.countShadowRun4(times, gremlins, false); + } } diff --git a/src/main/java/net/rptools/common/expression/function/ShadowRun4ExplodeDice.java b/src/main/java/net/rptools/common/expression/function/ShadowRun4ExplodeDice.java index 3ffb76c..b5c0811 100755 --- a/src/main/java/net/rptools/common/expression/function/ShadowRun4ExplodeDice.java +++ b/src/main/java/net/rptools/common/expression/function/ShadowRun4ExplodeDice.java @@ -1,41 +1,40 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; import net.rptools.parser.function.EvaluationException; public class ShadowRun4ExplodeDice extends AbstractNumberFunction { - public ShadowRun4ExplodeDice() { - super(1, 2, true, "sr4e"); - } - - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) throws EvaluationException { + public ShadowRun4ExplodeDice() { + super(1, 2, true, "sr4e"); + } - int n = 0; - int gremlins = 0; - int times = ((BigDecimal) parameters.get(n++)).intValue(); - if (parameters.size() == 2) - gremlins = ((BigDecimal) parameters.get(n++)).intValue(); + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) + throws EvaluationException { - return DiceHelper.countShadowRun4(times, gremlins, true); - } + int n = 0; + int gremlins = 0; + int times = ((BigDecimal) parameters.get(n++)).intValue(); + if (parameters.size() == 2) gremlins = ((BigDecimal) parameters.get(n++)).intValue(); + return DiceHelper.countShadowRun4(times, gremlins, true); + } } diff --git a/src/main/java/net/rptools/common/expression/function/UbiquityRoll.java b/src/main/java/net/rptools/common/expression/function/UbiquityRoll.java index 5a26355..2d21f31 100755 --- a/src/main/java/net/rptools/common/expression/function/UbiquityRoll.java +++ b/src/main/java/net/rptools/common/expression/function/UbiquityRoll.java @@ -1,46 +1,45 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; import java.util.List; - import net.rptools.parser.Parser; import net.rptools.parser.function.AbstractNumberFunction; -/** ubiquity(range) - * - * Generate a random number form 1 to sides, times - * number of times. If times is not supplied it defaults to 1. - * - * Example: - * ubiquity(4) = 4dU (0..4 successes) +/** + * ubiquity(range) + * + *

Generate a random number form 1 to sides, times number of times. If + * times is not supplied it defaults to 1. + * + *

Example: ubiquity(4) = 4dU (0..4 successes) */ public class UbiquityRoll extends AbstractNumberFunction { - public UbiquityRoll() { - super(1, 1, false, "u", "ubiquity"); - } + public UbiquityRoll() { + super(1, 1, false, "u", "ubiquity"); + } - @Override - public Object childEvaluate(Parser parser, String functionName, List parameters) { - int n = 0; + @Override + public Object childEvaluate(Parser parser, String functionName, List parameters) { + int n = 0; - int times = 1; - if (parameters.size() == 1) - times = ((BigDecimal) parameters.get(n++)).intValue(); + int times = 1; + if (parameters.size() == 1) times = ((BigDecimal) parameters.get(n++)).intValue(); - return new BigDecimal(DiceHelper.ubiquityDice(times)); - } + return new BigDecimal(DiceHelper.ubiquityDice(times)); + } } diff --git a/src/test/java/net/rptools/common/expression/ExpressionParserTest.java b/src/test/java/net/rptools/common/expression/ExpressionParserTest.java index 617be58..0c1ad05 100755 --- a/src/test/java/net/rptools/common/expression/ExpressionParserTest.java +++ b/src/test/java/net/rptools/common/expression/ExpressionParserTest.java @@ -1,15 +1,16 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression; @@ -17,236 +18,235 @@ import java.math.BigInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; - import junit.framework.TestCase; -import net.rptools.parser.Parser; import net.rptools.parser.ParserException; -import net.rptools.parser.function.EvaluationException; -import net.rptools.parser.function.ParameterException; public class ExpressionParserTest extends TestCase { - public void testEvaluate() throws ParserException { - Result result = new ExpressionParser().evaluate("100+4d1*10"); - - assertNotNull(result); - assertEquals("100+4d1*10", result.getExpression()); - assertEquals("100 + 4 * 10", result.getDetailExpression()); - assertEquals(new BigDecimal(140), (BigDecimal) result.getValue()); - } - - public void testEvaluate_Explode() throws ParserException { - RunData.setSeed(10423L); - Result result = new ExpressionParser().evaluate("100+10d6e+1"); - - assertEquals(new BigDecimal(164), result.getValue()); - } - - public void testEvaluate_Drop() throws ParserException { - RunData.setSeed(10423L); - Result result = new ExpressionParser().evaluate("100+10d6d2+1"); - - assertEquals(new BigDecimal(138), result.getValue()); - } - - public void testEvaluate_Keep() throws ParserException { - RunData.setSeed(10423L); - Result result = new ExpressionParser().evaluate("100+10d6k8+1"); - - assertEquals(new BigDecimal(138), result.getValue()); - } - - public void testEvaluate_CountSuccess() throws ParserException { - RunData.setSeed(10423L); - Result result = new ExpressionParser().evaluate("100+10d6s4+1"); - - assertEquals(new BigDecimal(109), result.getValue()); - } - - public void testEvaluate_ExplodingSuccess() throws ParserException { - RunData.setSeed(10423L); - Result result = new ExpressionParser().evaluate("10d4es6"); - assertEquals("10d4es6", result.getExpression()); - assertEquals("explodingSuccess(10, 4, 6)", result.getDetailExpression()); - assertEquals("Dice: 1, 2, 2, 1, 2, 7, 1, 7, 2, 3, Successes: 2", result.getValue()); - RunData.setSeed(10423L); - - result = new ExpressionParser().evaluate("10es9"); - assertEquals("10es9", result.getExpression()); - assertEquals("explodingSuccess(10, 6, 9)", result.getDetailExpression()); - assertEquals("Dice: 4, 4, 4, 3, 16, 5, 1, 4, 14, 8, Successes: 2", result.getValue()); - } - - public void testEvaluate_OpenTest() throws ParserException { - RunData.setSeed(10423L); - Result result = new ExpressionParser().evaluate("10d4o"); - assertEquals("10d4o", result.getExpression()); - assertEquals("openTest(10, 4)", result.getDetailExpression()); - assertEquals("Dice: 1, 2, 2, 1, 2, 7, 1, 7, 2, 3, Maximum: 7", result.getValue()); - - RunData.setSeed(10423L); - result = new ExpressionParser().evaluate("10o"); - assertEquals("10o", result.getExpression()); - assertEquals("openTest(10, 6)", result.getDetailExpression()); - assertEquals("Dice: 4, 4, 4, 3, 16, 5, 1, 4, 14, 8, Maximum: 16", result.getValue()); - } - - public void testEvaluate_SR4Success() throws ParserException { - RunData.setSeed(10523L); - Result result = new ExpressionParser().evaluate("5sr4"); - assertEquals("5sr4", result.getExpression()); - assertEquals("sr4(5)", result.getDetailExpression()); - assertEquals("Hits: 1 Ones: 1 Results: 3 1 4 6 3 ", result.getValue()); - } - - public void testEvaluate_SR4GremlinSuccess() throws ParserException { - RunData.setSeed(10523L); - Result result = new ExpressionParser().evaluate("5sr4g2"); - assertEquals("5sr4g2", result.getExpression()); - assertEquals("sr4(5, 2)", result.getDetailExpression()); - assertEquals("Hits: 1 Ones: 1 *Glitch* Results: 3 1 4 6 3 ", result.getValue()); - } - - public void testEvaluate_SR4ExplodingSuccess() throws ParserException { - RunData.setSeed(10523L); - Result result = new ExpressionParser().evaluate("5sr4e"); - assertEquals("5sr4e", result.getExpression()); - assertEquals("sr4e(5)", result.getDetailExpression()); - assertEquals("Hits: 1 Ones: 2 Results: 3 1 4 6 3 1 ", result.getValue()); - } - - public void testEvaluate_SR4ExplodingGremlinSuccess() throws ParserException { - RunData.setSeed(10523L); - Result result = new ExpressionParser().evaluate("5sr4eg2"); - assertEquals("5sr4eg2", result.getExpression()); - assertEquals("sr4e(5, 2)", result.getDetailExpression()); - assertEquals("Hits: 1 Ones: 2 *Glitch* Results: 3 1 4 6 3 1 ", result.getValue()); - } - - public void testEvaluate_HeroRoll() throws ParserException { - RunData.setSeed(10423L); - ExpressionParser parser = new ExpressionParser(); - - Result result = parser.evaluate("4.5d6h"); - assertEquals(new BigDecimal(18), result.getValue()); - - result = parser.evaluate("4.5d6b"); - assertEquals(new BigDecimal(5), result.getValue()); - - RunData.setSeed(10423L); - parser = new ExpressionParser(); - - result = parser.evaluate("4d6h"); - assertEquals(new BigDecimal(15), result.getValue()); - - result = parser.evaluate("4d6b"); - assertEquals(new BigDecimal(4), result.getValue()); - } - - public void testEvaluate_FudgeRoll() throws ParserException { - RunData.setSeed(10423L); - ExpressionParser parser = new ExpressionParser(); - - Result result = parser.evaluate("dF"); - assertEquals(new BigDecimal(-1), result.getValue()); - - result = parser.evaluate("4df"); - assertEquals(new BigDecimal(0), result.getValue()); - - // Don't parse df in the middle of things - parser.getParser().getVariableResolver().setVariable("asdfg", new BigDecimal(10)); - result = parser.evaluate("asdfg"); - assertEquals(new BigDecimal(10), result.getValue()); - } - - public void testEvaluate_UbiquityRoll() throws ParserException { - RunData.setSeed(10423L); - ExpressionParser parser = new ExpressionParser(); - - Result result = parser.evaluate("dU"); - assertEquals(new BigDecimal(0), result.getValue()); - - result = parser.evaluate("10du"); - assertEquals(new BigDecimal(4), result.getValue()); - - // Don't parse a uf in the middle of other things - parser.getParser().getVariableResolver().setVariable("asufg", new BigDecimal(10)); - result = parser.evaluate("asufg"); - assertEquals(new BigDecimal(10), result.getValue()); - } - - public void testEvaluate_ColorHex() throws ParserException { - RunData.setSeed(10423L); - ExpressionParser parser = new ExpressionParser(); - - Result result = parser.evaluate("#FF0000"); - assertEquals(new BigDecimal(new BigInteger("FF0000", 16)), result.getValue()); - - result = parser.evaluate("#00FF0000"); - assertEquals(new BigDecimal(new BigInteger("FF0000", 16)), result.getValue()); - - result = parser.evaluate("#FF0"); - assertEquals(new BigDecimal(new BigInteger("FFFF00", 16)), result.getValue()); - } - - public void testEvaluate_If() throws ParserException { - ExpressionParser parser = new ExpressionParser(); - - evaluateExpression(parser, "if(10 > 2, 10, 2)", new BigDecimal(10)); - evaluateExpression(parser, "if(10 < 2, 10, 2)", new BigDecimal(2)); - evaluateStringExpression(parser, "if(10 < 2, 's1', 's2')", "s2"); - evaluateStringExpression(parser, "if(10 > 2, 's1', 's2')", "s1"); - } + public void testEvaluate() throws ParserException { + Result result = new ExpressionParser().evaluate("100+4d1*10"); + + assertNotNull(result); + assertEquals("100+4d1*10", result.getExpression()); + assertEquals("100 + 4 * 10", result.getDetailExpression()); + assertEquals(new BigDecimal(140), (BigDecimal) result.getValue()); + } + + public void testEvaluate_Explode() throws ParserException { + RunData.setSeed(10423L); + Result result = new ExpressionParser().evaluate("100+10d6e+1"); + + assertEquals(new BigDecimal(164), result.getValue()); + } + + public void testEvaluate_Drop() throws ParserException { + RunData.setSeed(10423L); + Result result = new ExpressionParser().evaluate("100+10d6d2+1"); + + assertEquals(new BigDecimal(138), result.getValue()); + } + + public void testEvaluate_Keep() throws ParserException { + RunData.setSeed(10423L); + Result result = new ExpressionParser().evaluate("100+10d6k8+1"); + + assertEquals(new BigDecimal(138), result.getValue()); + } + + public void testEvaluate_CountSuccess() throws ParserException { + RunData.setSeed(10423L); + Result result = new ExpressionParser().evaluate("100+10d6s4+1"); + + assertEquals(new BigDecimal(109), result.getValue()); + } + + public void testEvaluate_ExplodingSuccess() throws ParserException { + RunData.setSeed(10423L); + Result result = new ExpressionParser().evaluate("10d4es6"); + assertEquals("10d4es6", result.getExpression()); + assertEquals("explodingSuccess(10, 4, 6)", result.getDetailExpression()); + assertEquals("Dice: 1, 2, 2, 1, 2, 7, 1, 7, 2, 3, Successes: 2", result.getValue()); + RunData.setSeed(10423L); + + result = new ExpressionParser().evaluate("10es9"); + assertEquals("10es9", result.getExpression()); + assertEquals("explodingSuccess(10, 6, 9)", result.getDetailExpression()); + assertEquals("Dice: 4, 4, 4, 3, 16, 5, 1, 4, 14, 8, Successes: 2", result.getValue()); + } + + public void testEvaluate_OpenTest() throws ParserException { + RunData.setSeed(10423L); + Result result = new ExpressionParser().evaluate("10d4o"); + assertEquals("10d4o", result.getExpression()); + assertEquals("openTest(10, 4)", result.getDetailExpression()); + assertEquals("Dice: 1, 2, 2, 1, 2, 7, 1, 7, 2, 3, Maximum: 7", result.getValue()); + + RunData.setSeed(10423L); + result = new ExpressionParser().evaluate("10o"); + assertEquals("10o", result.getExpression()); + assertEquals("openTest(10, 6)", result.getDetailExpression()); + assertEquals("Dice: 4, 4, 4, 3, 16, 5, 1, 4, 14, 8, Maximum: 16", result.getValue()); + } + + public void testEvaluate_SR4Success() throws ParserException { + RunData.setSeed(10523L); + Result result = new ExpressionParser().evaluate("5sr4"); + assertEquals("5sr4", result.getExpression()); + assertEquals("sr4(5)", result.getDetailExpression()); + assertEquals("Hits: 1 Ones: 1 Results: 3 1 4 6 3 ", result.getValue()); + } + + public void testEvaluate_SR4GremlinSuccess() throws ParserException { + RunData.setSeed(10523L); + Result result = new ExpressionParser().evaluate("5sr4g2"); + assertEquals("5sr4g2", result.getExpression()); + assertEquals("sr4(5, 2)", result.getDetailExpression()); + assertEquals("Hits: 1 Ones: 1 *Glitch* Results: 3 1 4 6 3 ", result.getValue()); + } + + public void testEvaluate_SR4ExplodingSuccess() throws ParserException { + RunData.setSeed(10523L); + Result result = new ExpressionParser().evaluate("5sr4e"); + assertEquals("5sr4e", result.getExpression()); + assertEquals("sr4e(5)", result.getDetailExpression()); + assertEquals("Hits: 1 Ones: 2 Results: 3 1 4 6 3 1 ", result.getValue()); + } + + public void testEvaluate_SR4ExplodingGremlinSuccess() throws ParserException { + RunData.setSeed(10523L); + Result result = new ExpressionParser().evaluate("5sr4eg2"); + assertEquals("5sr4eg2", result.getExpression()); + assertEquals("sr4e(5, 2)", result.getDetailExpression()); + assertEquals("Hits: 1 Ones: 2 *Glitch* Results: 3 1 4 6 3 1 ", result.getValue()); + } + + public void testEvaluate_HeroRoll() throws ParserException { + RunData.setSeed(10423L); + ExpressionParser parser = new ExpressionParser(); + + Result result = parser.evaluate("4.5d6h"); + assertEquals(new BigDecimal(18), result.getValue()); + + result = parser.evaluate("4.5d6b"); + assertEquals(new BigDecimal(5), result.getValue()); + + RunData.setSeed(10423L); + parser = new ExpressionParser(); + + result = parser.evaluate("4d6h"); + assertEquals(new BigDecimal(15), result.getValue()); + + result = parser.evaluate("4d6b"); + assertEquals(new BigDecimal(4), result.getValue()); + } + + public void testEvaluate_FudgeRoll() throws ParserException { + RunData.setSeed(10423L); + ExpressionParser parser = new ExpressionParser(); + + Result result = parser.evaluate("dF"); + assertEquals(new BigDecimal(-1), result.getValue()); + + result = parser.evaluate("4df"); + assertEquals(new BigDecimal(0), result.getValue()); + + // Don't parse df in the middle of things + parser.getParser().getVariableResolver().setVariable("asdfg", new BigDecimal(10)); + result = parser.evaluate("asdfg"); + assertEquals(new BigDecimal(10), result.getValue()); + } + + public void testEvaluate_UbiquityRoll() throws ParserException { + RunData.setSeed(10423L); + ExpressionParser parser = new ExpressionParser(); + + Result result = parser.evaluate("dU"); + assertEquals(new BigDecimal(0), result.getValue()); + + result = parser.evaluate("10du"); + assertEquals(new BigDecimal(4), result.getValue()); + + // Don't parse a uf in the middle of other things + parser.getParser().getVariableResolver().setVariable("asufg", new BigDecimal(10)); + result = parser.evaluate("asufg"); + assertEquals(new BigDecimal(10), result.getValue()); + } + + public void testEvaluate_ColorHex() throws ParserException { + RunData.setSeed(10423L); + ExpressionParser parser = new ExpressionParser(); + + Result result = parser.evaluate("#FF0000"); + assertEquals(new BigDecimal(new BigInteger("FF0000", 16)), result.getValue()); + + result = parser.evaluate("#00FF0000"); + assertEquals(new BigDecimal(new BigInteger("FF0000", 16)), result.getValue()); + + result = parser.evaluate("#FF0"); + assertEquals(new BigDecimal(new BigInteger("FFFF00", 16)), result.getValue()); + } + + public void testEvaluate_If() throws ParserException { + ExpressionParser parser = new ExpressionParser(); + + evaluateExpression(parser, "if(10 > 2, 10, 2)", new BigDecimal(10)); + evaluateExpression(parser, "if(10 < 2, 10, 2)", new BigDecimal(2)); + evaluateStringExpression(parser, "if(10 < 2, 's1', 's2')", "s2"); + evaluateStringExpression(parser, "if(10 > 2, 's1', 's2')", "s1"); + } - public void testEvaluate_Multiline() throws ParserException { - RunData.setSeed(10423L); - ExpressionParser parser = new ExpressionParser(); + public void testEvaluate_Multiline() throws ParserException { + RunData.setSeed(10423L); + ExpressionParser parser = new ExpressionParser(); - evaluateExpression(parser, "10 + \r\n d6 + \n 2", new BigDecimal(16)); + evaluateExpression(parser, "10 + \r\n d6 + \n 2", new BigDecimal(16)); - String s = "10 + // Constant expression\n" + - "2 + // Another bit\n" + - "d20 // The roll\n"; + String s = "10 + // Constant expression\n" + "2 + // Another bit\n" + "d20 // The roll\n"; - evaluateExpression(parser, s, new BigDecimal(26)); - } + evaluateExpression(parser, s, new BigDecimal(26)); + } - public void testMultilineRegex() { - String str1 = "one two three"; - String str2 = "one two\nthree"; + public void testMultilineRegex() { + String str1 = "one two three"; + String str2 = "one two\nthree"; - Pattern p1 = Pattern.compile("^one(.*)three$"); - Pattern p2 = Pattern.compile("one(.*)three", Pattern.MULTILINE); + Pattern p1 = Pattern.compile("^one(.*)three$"); + Pattern p2 = Pattern.compile("one(.*)three", Pattern.MULTILINE); - Matcher m1 = p1.matcher(str1); - Matcher m2 = p2.matcher(str2); + Matcher m1 = p1.matcher(str1); + Matcher m2 = p2.matcher(str2); - System.out.println(m1.matches()); - System.out.println(m2.matches()); - } + System.out.println(m1.matches()); + System.out.println(m2.matches()); + } - public void testNoTransformInStrings() throws ParserException { - ExpressionParser parser = new ExpressionParser(); + public void testNoTransformInStrings() throws ParserException { + ExpressionParser parser = new ExpressionParser(); - evaluateStringExpression(parser, "'10' + 'd10'", "10d10"); - } + evaluateStringExpression(parser, "'10' + 'd10'", "10d10"); + } - public void testVariableRegexOverlaps() throws ParserException { - ExpressionParser parser = new ExpressionParser(); - parser.getParser().setVariable("food10", new BigDecimal(10)); + public void testVariableRegexOverlaps() throws ParserException { + ExpressionParser parser = new ExpressionParser(); + parser.getParser().setVariable("food10", new BigDecimal(10)); - evaluateExpression(parser, "food10 + 10", new BigDecimal(20)); - } + evaluateExpression(parser, "food10 + 10", new BigDecimal(20)); + } - private void evaluateExpression(ExpressionParser p, String expression, BigDecimal answer) throws ParserException { - Result result = p.evaluate(expression); - assertTrue(String.format("%s evaluated incorrectly expected <%s> but was <%s>", expression, answer, result.getValue()), - answer.compareTo((BigDecimal) result.getValue()) == 0); - } + private void evaluateExpression(ExpressionParser p, String expression, BigDecimal answer) + throws ParserException { + Result result = p.evaluate(expression); + assertTrue( + String.format( + "%s evaluated incorrectly expected <%s> but was <%s>", + expression, answer, result.getValue()), + answer.compareTo((BigDecimal) result.getValue()) == 0); + } - private void evaluateStringExpression(ExpressionParser p, String expression, String answer) throws ParserException { - Result result = p.evaluate(expression); + private void evaluateStringExpression(ExpressionParser p, String expression, String answer) + throws ParserException { + Result result = p.evaluate(expression); - assertEquals(answer, result.getValue()); - } + assertEquals(answer, result.getValue()); + } } diff --git a/src/test/java/net/rptools/common/expression/RunDataTest.java b/src/test/java/net/rptools/common/expression/RunDataTest.java index b5d202d..d42d365 100755 --- a/src/test/java/net/rptools/common/expression/RunDataTest.java +++ b/src/test/java/net/rptools/common/expression/RunDataTest.java @@ -1,15 +1,16 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression; @@ -17,21 +18,21 @@ public class RunDataTest extends TestCase { - public void testRandomIntInt() { - RunData runData = new RunData(null); + public void testRandomIntInt() { + RunData runData = new RunData(null); - for (int i = 0; i < 10000; i++) { - int value = runData.randomInt(10); - assertTrue(1 <= value && value <= 10); - } - } + for (int i = 0; i < 10000; i++) { + int value = runData.randomInt(10); + assertTrue(1 <= value && value <= 10); + } + } - public void testRandomIntIntInt() { - RunData runData = new RunData(null); + public void testRandomIntIntInt() { + RunData runData = new RunData(null); - for (int i = 0; i < 10000; i++) { - int value = runData.randomInt(10, 20); - assertTrue(String.format("Value outside range: %s", value), 10 <= value && value <= 20); - } - } + for (int i = 0; i < 10000; i++) { + int value = runData.randomInt(10, 20); + assertTrue(String.format("Value outside range: %s", value), 10 <= value && value <= 20); + } + } } diff --git a/src/test/java/net/rptools/common/expression/function/DiceHelperTest.java b/src/test/java/net/rptools/common/expression/function/DiceHelperTest.java index 7dadc20..da10b2e 100755 --- a/src/test/java/net/rptools/common/expression/function/DiceHelperTest.java +++ b/src/test/java/net/rptools/common/expression/function/DiceHelperTest.java @@ -1,67 +1,67 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; +import junit.framework.TestCase; import net.rptools.common.expression.RunData; import net.rptools.parser.function.EvaluationException; -import junit.framework.TestCase; public class DiceHelperTest extends TestCase { - public void testRollDice() throws Exception { - RunData.setCurrent(new RunData(null)); - RunData.setSeed(102312L); - - assertEquals(42, DiceHelper.rollDice(10, 6)); - } + public void testRollDice() throws Exception { + RunData.setCurrent(new RunData(null)); + RunData.setSeed(102312L); - public void testKeepDice() throws Exception { - RunData.setCurrent(new RunData(null)); - RunData.setSeed(102312L); + assertEquals(42, DiceHelper.rollDice(10, 6)); + } - assertEquals(28, DiceHelper.keepDice(10, 6, 5)); - } + public void testKeepDice() throws Exception { + RunData.setCurrent(new RunData(null)); + RunData.setSeed(102312L); - public void testDropDice() throws Exception { - RunData.setCurrent(new RunData(null)); - RunData.setSeed(102312L); + assertEquals(28, DiceHelper.keepDice(10, 6, 5)); + } - assertEquals(28, DiceHelper.dropDice(10, 6, 5)); - } + public void testDropDice() throws Exception { + RunData.setCurrent(new RunData(null)); + RunData.setSeed(102312L); - public void testRerollDice() throws Exception { - RunData.setCurrent(new RunData(null)); - RunData.setSeed(102312L); + assertEquals(28, DiceHelper.dropDice(10, 6, 5)); + } - assertEquals(50, DiceHelper.rerollDice(10, 6, 2)); - } + public void testRerollDice() throws Exception { + RunData.setCurrent(new RunData(null)); + RunData.setSeed(102312L); - public void testExplodeDice() throws Exception { - RunData.setCurrent(new RunData(null)); - RunData.setSeed(102312L); + assertEquals(50, DiceHelper.rerollDice(10, 6, 2)); + } - assertEquals(23, DiceHelper.explodeDice(4, 6)); - } + public void testExplodeDice() throws Exception { + RunData.setCurrent(new RunData(null)); + RunData.setSeed(102312L); - public void testExplodeDice_Exception() throws Exception { - try { - RunData.setCurrent(new RunData(null)); - RunData.setSeed(102312L); + assertEquals(23, DiceHelper.explodeDice(4, 6)); + } - assertEquals(23, DiceHelper.explodeDice(4, 1)); - fail(); - } catch (EvaluationException e) { - } + public void testExplodeDice_Exception() throws Exception { + try { + RunData.setCurrent(new RunData(null)); + RunData.setSeed(102312L); - } + assertEquals(23, DiceHelper.explodeDice(4, 1)); + fail(); + } catch (EvaluationException e) { + } + } } diff --git a/src/test/java/net/rptools/common/expression/function/DropRollTest.java b/src/test/java/net/rptools/common/expression/function/DropRollTest.java index d99ba7f..7f4dc8a 100755 --- a/src/test/java/net/rptools/common/expression/function/DropRollTest.java +++ b/src/test/java/net/rptools/common/expression/function/DropRollTest.java @@ -1,46 +1,45 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; - +import junit.framework.TestCase; import net.rptools.common.expression.RunData; import net.rptools.parser.Expression; import net.rptools.parser.Parser; import net.rptools.parser.ParserException; import net.rptools.parser.function.EvaluationException; import net.rptools.parser.function.ParameterException; -import junit.framework.TestCase; public class DropRollTest extends TestCase { - public void testEvaluateRoll() throws ParserException, EvaluationException, - ParameterException { + public void testEvaluateRoll() throws ParserException, EvaluationException, ParameterException { - Parser p = new Parser(); - p.addFunction(new DropRoll()); + Parser p = new Parser(); + p.addFunction(new DropRoll()); - try { - RunData.setCurrent(new RunData(null)); - RunData.setSeed(10423L); + try { + RunData.setCurrent(new RunData(null)); + RunData.setSeed(10423L); - Expression xp = p.parseExpression("drop(4,6,1)"); + Expression xp = p.parseExpression("drop(4,6,1)"); - long result = ((BigDecimal) xp.evaluate()).longValueExact(); + long result = ((BigDecimal) xp.evaluate()).longValueExact(); - assertEquals(12L, result); - } finally { - RunData.setCurrent(null); - } - } + assertEquals(12L, result); + } finally { + RunData.setCurrent(null); + } + } } diff --git a/src/test/java/net/rptools/common/expression/function/RollTest.java b/src/test/java/net/rptools/common/expression/function/RollTest.java index 784aeb6..8e7cacc 100755 --- a/src/test/java/net/rptools/common/expression/function/RollTest.java +++ b/src/test/java/net/rptools/common/expression/function/RollTest.java @@ -1,63 +1,62 @@ /* - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at + * This software Copyright by the RPTools.net development team, and + * licensed under the Affero GPL Version 3 or, at your option, any later + * version. * - * http://www.apache.org/licenses/LICENSE-2.0 + * MapTool Source Code is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. + * You should have received a copy of the GNU Affero General Public + * License * along with this source Code. If not, please visit + * and specifically the Affero license + * text at . */ package net.rptools.common.expression.function; import java.math.BigDecimal; - +import junit.framework.TestCase; import net.rptools.common.expression.RunData; import net.rptools.parser.Expression; -import net.rptools.parser.ParserException; import net.rptools.parser.Parser; +import net.rptools.parser.ParserException; import net.rptools.parser.function.EvaluationException; import net.rptools.parser.function.ParameterException; -import junit.framework.TestCase; public class RollTest extends TestCase { - public void testEvaluateRoll() throws ParserException, EvaluationException, - ParameterException { - Parser p = new Parser(); - p.addFunction(new Roll()); - - try { - RunData.setCurrent(new RunData(null)); - - Expression xp = p.parseExpression("roll(6)"); - - for (int i = 0; i < 1000; i++) { - long result = ((BigDecimal) xp.evaluate()).longValueExact(); - - assertTrue(result >= 1 && result <= 6); - } - } finally { - RunData.setCurrent(null); - } - } - - public void testIsNonDeterministic() throws ParserException, - EvaluationException, ParameterException { - Parser p = new Parser(); - p.addFunction(new Roll()); - - try { - RunData.setCurrent(new RunData(null)); - - Expression xp = p.parseExpression("roll(10, 6) + 10"); - Expression dxp = xp.getDeterministicExpression(); - - assertTrue(dxp.format().matches("\\d+ \\+ 10")); - } finally { - RunData.setCurrent(null); - } - } + public void testEvaluateRoll() throws ParserException, EvaluationException, ParameterException { + Parser p = new Parser(); + p.addFunction(new Roll()); + + try { + RunData.setCurrent(new RunData(null)); + + Expression xp = p.parseExpression("roll(6)"); + + for (int i = 0; i < 1000; i++) { + long result = ((BigDecimal) xp.evaluate()).longValueExact(); + + assertTrue(result >= 1 && result <= 6); + } + } finally { + RunData.setCurrent(null); + } + } + + public void testIsNonDeterministic() + throws ParserException, EvaluationException, ParameterException { + Parser p = new Parser(); + p.addFunction(new Roll()); + + try { + RunData.setCurrent(new RunData(null)); + + Expression xp = p.parseExpression("roll(10, 6) + 10"); + Expression dxp = xp.getDeterministicExpression(); + + assertTrue(dxp.format().matches("\\d+ \\+ 10")); + } finally { + RunData.setCurrent(null); + } + } } From 0a9d816d818674a20d7ea8f583c52237f40d4a25 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 31 Mar 2019 01:30:01 +1030 Subject: [PATCH 10/23] Addded roll functions to parser --- .../java/net/rptools/common/expression/ExpressionParser.java | 4 ++++ .../rptools/common/expression/function/RollWithBounds.java | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/common/expression/ExpressionParser.java b/src/main/java/net/rptools/common/expression/ExpressionParser.java index c0cefe7..41c30df 100755 --- a/src/main/java/net/rptools/common/expression/ExpressionParser.java +++ b/src/main/java/net/rptools/common/expression/ExpressionParser.java @@ -186,6 +186,10 @@ public ExpressionParser(String[][] regexpTransforms, VariableResolver resolver) parser.addFunction(new Roll()); parser.addFunction(new ExplodingSuccessDice()); parser.addFunction(new OpenTestDice()); + parser.addFunction(new RollWithBounds()); + parser.addFunction(new DropHighestRoll()); + parser.addFunction(new KeepLowestRoll()); + parser.addFunction(new If()); diff --git a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java index ca4c825..bff079b 100644 --- a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java +++ b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java @@ -23,7 +23,7 @@ public class RollWithBounds extends AbstractNumberFunction { public RollWithBounds() { - super(3, 4, false, "rollSubWithLower", "rollWithLower", "rollAddWithUpper", "rollWithUpper"); + super(3, 4, false, "rollSubWithLower", "rollWithLower", "rollAddWithUpper", "rollWithUpper", "rollAddWithLower"); } @Override From 0f440996939c09116d003828b42f8e8fcde04015 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 31 Mar 2019 01:36:53 +1030 Subject: [PATCH 11/23] fix dice spec for dragon quest / drop highest --- .../net/rptools/common/expression/ExpressionParser.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/rptools/common/expression/ExpressionParser.java b/src/main/java/net/rptools/common/expression/ExpressionParser.java index 41c30df..1ae1cc5 100755 --- a/src/main/java/net/rptools/common/expression/ExpressionParser.java +++ b/src/main/java/net/rptools/common/expression/ExpressionParser.java @@ -42,8 +42,8 @@ public class ExpressionParser { new String[] {"\\b[dD](\\d+)[dD](\\d+)\\b", "drop(1, $1, $2)"}, // drop highest - new String[] {"\\b(\\d+)[dD](\\d+)[dD](\\d+)\\b", "dropHighest($1, $2, $3)"}, - new String[] {"\\b[dD](\\d+)[dD](\\d+)\\b", "dropHighest(1, $1, $2)"}, + new String[] {"\\b(\\d+)[dD](\\d+)[dD][hH](\\d+)\\b", "dropHighest($1, $2, $3)"}, + new String[] {"\\b[dD](\\d+)[dD][hH](\\d+)\\b", "dropHighest(1, $1, $2)"}, // keep new String[] {"\\b(\\d+)[dD](\\d+)[kK](\\d+)\\b", "keep($1, $2, $3)"}, @@ -149,8 +149,8 @@ public class ExpressionParser { new String[] {"\\b[dD](\\d+)[uU](\\d+)\\b", "rollWithUpper(1, $1, $2)"}, // Dragon Quest - new String[] {"\\b(\\d+)[dD](\\d+)[qQ]:([+-]?\\d+)\\b", "rollAddWithLower($1, $2, $3, 1)"}, - new String[] {"\\b[dD](\\d+)[qQ]:([+-]?\\d+)\\b", "rollAddWithLower(1, $1, $2, 1)"}, + new String[] {"\\b(\\d+)[dD](\\d+)[qQ]#([+-]?\\d+)\\b", "rollAddWithLower($1, $2, $3, 1)"}, + new String[] {"\\b[dD](\\d+)[qQ]#([+-]?\\d+)\\b", "rollAddWithLower(1, $1, $2, 1)"}, new String[] {"\\b(\\d+)[dD](\\d+)[qQ]\\b", "rollAddWithLower($1, $2, 0, 1)"}, new String[] {"\\b[dD](\\d+)[qQ]\\b", "rollAddWithLower(1, $1, 0, 1)"} }; From 2fc0b31f06d0d474333ef37f5ba5158d5f657529 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 31 Mar 2019 01:53:37 +1030 Subject: [PATCH 12/23] add debugging --- .../net/rptools/common/expression/function/RollWithBounds.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java index bff079b..2e3a5ff 100644 --- a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java +++ b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java @@ -65,6 +65,7 @@ public Object childEvaluate(Parser parser, String functionName, List par lower = ((BigDecimal) parameters.get(3)).intValue(); break; } + System.out.println("times = " + times + ", sides = " + sides + ", mod = " + mod + ", lower = " + lower); return DiceHelper.rollModWithBounds(times, sides, mod, lower, upper); } } From cbe6e346bb4663507a2761247d89f2f4421d1a79 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 31 Mar 2019 01:56:20 +1030 Subject: [PATCH 13/23] add debugging --- .../net/rptools/common/expression/function/DiceHelper.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/common/expression/function/DiceHelper.java b/src/main/java/net/rptools/common/expression/function/DiceHelper.java index 985fbbb..33680b0 100755 --- a/src/main/java/net/rptools/common/expression/function/DiceHelper.java +++ b/src/main/java/net/rptools/common/expression/function/DiceHelper.java @@ -203,7 +203,9 @@ public static int rollModWithBounds(int times, int sides, int sub, int lower, in int result = 0; for (int i = 0; i < times; i++) { - result += Math.min(Math.max(rollDice(1, sides) - sub, lower), upper); + int roll = Math.min(Math.max(rollDice(1, sides) - sub, lower), upper); + result += roll; + System.out.println("\t" + roll); } return result; From 6c0cd3205666b29e25b74facba82abb9af9dc48a Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 31 Mar 2019 01:59:53 +1030 Subject: [PATCH 14/23] add debugging --- .../rptools/common/expression/function/DiceHelper.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/rptools/common/expression/function/DiceHelper.java b/src/main/java/net/rptools/common/expression/function/DiceHelper.java index 33680b0..5b04fdd 100755 --- a/src/main/java/net/rptools/common/expression/function/DiceHelper.java +++ b/src/main/java/net/rptools/common/expression/function/DiceHelper.java @@ -203,9 +203,11 @@ public static int rollModWithBounds(int times, int sides, int sub, int lower, in int result = 0; for (int i = 0; i < times; i++) { - int roll = Math.min(Math.max(rollDice(1, sides) - sub, lower), upper); - result += roll; - System.out.println("\t" + roll); + int roll = rollDice(1, sides); + int val = Math.min(Math.min(roll - sub, lower), upper); + //int roll = Math.min(Math.max(rollDice(1, sides) - sub, lower), upper); + result += val; + System.out.println("\t" + roll + " - " + val); } return result; From cdf1e04156a359a7d646fab4ac71f8ecc87e7232 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 31 Mar 2019 02:01:08 +1030 Subject: [PATCH 15/23] add debugging --- .../java/net/rptools/common/expression/function/DiceHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/common/expression/function/DiceHelper.java b/src/main/java/net/rptools/common/expression/function/DiceHelper.java index 5b04fdd..dc1a4ca 100755 --- a/src/main/java/net/rptools/common/expression/function/DiceHelper.java +++ b/src/main/java/net/rptools/common/expression/function/DiceHelper.java @@ -204,7 +204,7 @@ public static int rollModWithBounds(int times, int sides, int sub, int lower, in for (int i = 0; i < times; i++) { int roll = rollDice(1, sides); - int val = Math.min(Math.min(roll - sub, lower), upper); + int val = Math.min(Math.max(roll - sub, lower), upper); //int roll = Math.min(Math.max(rollDice(1, sides) - sub, lower), upper); result += val; System.out.println("\t" + roll + " - " + val); From 2bfde43a6cdc3de84a42a7a7c3646f2561f91d2a Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 31 Mar 2019 02:02:30 +1030 Subject: [PATCH 16/23] add debugging --- .../java/net/rptools/common/expression/function/DiceHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/common/expression/function/DiceHelper.java b/src/main/java/net/rptools/common/expression/function/DiceHelper.java index dc1a4ca..9f8a3ab 100755 --- a/src/main/java/net/rptools/common/expression/function/DiceHelper.java +++ b/src/main/java/net/rptools/common/expression/function/DiceHelper.java @@ -204,7 +204,7 @@ public static int rollModWithBounds(int times, int sides, int sub, int lower, in for (int i = 0; i < times; i++) { int roll = rollDice(1, sides); - int val = Math.min(Math.max(roll - sub, lower), upper); + int val = Math.min(Math.max(roll + sub, lower), upper); //int roll = Math.min(Math.max(rollDice(1, sides) - sub, lower), upper); result += val; System.out.println("\t" + roll + " - " + val); From 2b07753c4bdd1721ff21ad1425e56626cb65e251 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 7 Apr 2019 19:32:44 +0930 Subject: [PATCH 17/23] new rolls and support for listing rolled dice --- .../common/expression/ExpressionParser.java | 5 +++-- .../java/net/rptools/common/expression/Result.java | 12 ++++++++++++ .../net/rptools/common/expression/RunData.java | 14 +++++++++++++- .../common/expression/function/DiceHelper.java | 2 -- .../common/expression/function/RollWithBounds.java | 11 +++++++++-- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/rptools/common/expression/ExpressionParser.java b/src/main/java/net/rptools/common/expression/ExpressionParser.java index 1ae1cc5..89aa69b 100755 --- a/src/main/java/net/rptools/common/expression/ExpressionParser.java +++ b/src/main/java/net/rptools/common/expression/ExpressionParser.java @@ -190,7 +190,6 @@ public ExpressionParser(String[][] regexpTransforms, VariableResolver resolver) parser.addFunction(new DropHighestRoll()); parser.addFunction(new KeepLowestRoll()); - parser.addFunction(new If()); StringLiteralTransformer slt = new StringLiteralTransformer(); @@ -208,13 +207,15 @@ public Result evaluate(String expression) throws ParserException { Result ret = new Result(expression); RunData oldData = RunData.hasCurrent() ? RunData.getCurrent() : null; try { - RunData.setCurrent(new RunData(ret)); + RunData newRunData = new RunData(ret); + RunData.setCurrent(newRunData); synchronized (parser) { Expression xp = parser.parseExpression(expression); Expression dxp = xp.getDeterministicExpression(); ret.setDetailExpression(dxp.format()); ret.setValue(dxp.evaluate()); + ret.setRolled(newRunData.getRolled()); } } finally { RunData.setCurrent(oldData); diff --git a/src/main/java/net/rptools/common/expression/Result.java b/src/main/java/net/rptools/common/expression/Result.java index 220fa9b..5beb3e3 100755 --- a/src/main/java/net/rptools/common/expression/Result.java +++ b/src/main/java/net/rptools/common/expression/Result.java @@ -14,7 +14,10 @@ */ package net.rptools.common.expression; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; public class Result { @@ -22,6 +25,7 @@ public class Result { private String detailExpression; private Object value; private String description; + private List rolled; private final Map properties = new HashMap(); @@ -61,6 +65,14 @@ public Map getProperties() { return this.properties; } + public void setRolled(List rolls) { + rolled = new ArrayList<>(rolls); + } + + public List getRolled() { + return Collections.unmodifiableList(rolled); + } + public String format() { StringBuilder sb = new StringBuilder(64); sb.append(expression).append(" = "); diff --git a/src/main/java/net/rptools/common/expression/RunData.java b/src/main/java/net/rptools/common/expression/RunData.java index ddd99c1..01db739 100755 --- a/src/main/java/net/rptools/common/expression/RunData.java +++ b/src/main/java/net/rptools/common/expression/RunData.java @@ -15,6 +15,9 @@ package net.rptools.common.expression; import java.security.SecureRandom; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import java.util.Random; public class RunData { @@ -27,6 +30,8 @@ public class RunData { private long randomMax; private long randomMin; + private List rolled = new LinkedList<>(); + public RunData(Result result) { this.result = result; } @@ -39,7 +44,10 @@ public int randomInt(int maxValue) { /** Returns a list of random integers between 1 and maxValue */ public int[] randomInts(int num, int maxValue) { int[] ret = new int[num]; - for (int i = 0; i < num; i++) ret[i] = randomInt(maxValue); + for (int i = 0; i < num; i++) { + ret[i] = randomInt(maxValue); + rolled.add(ret[i]); + } return ret; } @@ -91,4 +99,8 @@ public static void setCurrent(RunData data) { public static void setSeed(long seed) { RANDOM = new Random(seed); } + + public List getRolled() { + return Collections.unmodifiableList(rolled); + } } diff --git a/src/main/java/net/rptools/common/expression/function/DiceHelper.java b/src/main/java/net/rptools/common/expression/function/DiceHelper.java index 9f8a3ab..039cbfd 100755 --- a/src/main/java/net/rptools/common/expression/function/DiceHelper.java +++ b/src/main/java/net/rptools/common/expression/function/DiceHelper.java @@ -205,9 +205,7 @@ public static int rollModWithBounds(int times, int sides, int sub, int lower, in for (int i = 0; i < times; i++) { int roll = rollDice(1, sides); int val = Math.min(Math.max(roll + sub, lower), upper); - //int roll = Math.min(Math.max(rollDice(1, sides) - sub, lower), upper); result += val; - System.out.println("\t" + roll + " - " + val); } return result; diff --git a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java index 2e3a5ff..57ef212 100644 --- a/src/main/java/net/rptools/common/expression/function/RollWithBounds.java +++ b/src/main/java/net/rptools/common/expression/function/RollWithBounds.java @@ -23,7 +23,15 @@ public class RollWithBounds extends AbstractNumberFunction { public RollWithBounds() { - super(3, 4, false, "rollSubWithLower", "rollWithLower", "rollAddWithUpper", "rollWithUpper", "rollAddWithLower"); + super( + 3, + 4, + false, + "rollSubWithLower", + "rollWithLower", + "rollAddWithUpper", + "rollWithUpper", + "rollAddWithLower"); } @Override @@ -65,7 +73,6 @@ public Object childEvaluate(Parser parser, String functionName, List par lower = ((BigDecimal) parameters.get(3)).intValue(); break; } - System.out.println("times = " + times + ", sides = " + sides + ", mod = " + mod + ", lower = " + lower); return DiceHelper.rollModWithBounds(times, sides, mod, lower, upper); } } From 134bbf919117373abe46093607172f527c53c218 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sun, 7 Apr 2019 21:22:03 +0930 Subject: [PATCH 18/23] changed location that rolls are recorded --- src/main/java/net/rptools/common/expression/RunData.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/rptools/common/expression/RunData.java b/src/main/java/net/rptools/common/expression/RunData.java index 01db739..3a4b93e 100755 --- a/src/main/java/net/rptools/common/expression/RunData.java +++ b/src/main/java/net/rptools/common/expression/RunData.java @@ -46,7 +46,6 @@ public int[] randomInts(int num, int maxValue) { int[] ret = new int[num]; for (int i = 0; i < num; i++) { ret[i] = randomInt(maxValue); - rolled.add(ret[i]); } return ret; } @@ -58,6 +57,8 @@ public int randomInt(int minValue, int maxValue) { int result = RANDOM.nextInt(maxValue - minValue + 1) + minValue; + rolled.add(result); + randomValue += result; return result; From f7f2a891f7f9a95b26cd38a7726e09299496b3b0 Mon Sep 17 00:00:00 2001 From: Craig Wisniewski Date: Sat, 13 Apr 2019 01:16:46 +0930 Subject: [PATCH 19/23] update to gradle 5.3.1 --- gradle/wrapper/gradle-wrapper.jar | Bin 54329 -> 55190 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 172 +++++++++++++++++++++++ gradlew.bat | 84 +++++++++++ 4 files changed, 258 insertions(+), 1 deletion(-) create mode 100755 gradlew create mode 100644 gradlew.bat diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a5fe1cb94b9ee5ce57e6113458225bcba12d83e3..87b738cbd051603d91cc39de6cb000dd98fe6b02 100644 GIT binary patch literal 55190 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 z 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

<5G2M1WZP5 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..6d57edc --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From e3fb4d5ba5c9dffa130236af868d4c2cb260e281 Mon Sep 17 00:00:00 2001 From: Jamz Date: Fri, 12 Apr 2019 11:05:57 -0500 Subject: [PATCH 20/23] Create jitpack.yml --- jitpack.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 jitpack.yml diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..0bcc119 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,2 @@ +jdk: + - oraclejdk20 From 12b77a88ea36978e86a2e24cf3d63e91515c7293 Mon Sep 17 00:00:00 2001 From: Jamz Date: Fri, 12 Apr 2019 11:14:12 -0500 Subject: [PATCH 21/23] Update jitpack.yml fat fingers --- jitpack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jitpack.yml b/jitpack.yml index 0bcc119..246d32f 100644 --- a/jitpack.yml +++ b/jitpack.yml @@ -1,2 +1,2 @@ jdk: - - oraclejdk20 + - oraclejdk10 From 601cc2e461a3fca64cf5b6b873d8d50a38e96812 Mon Sep 17 00:00:00 2001 From: Jamz Date: Fri, 12 Apr 2019 11:22:30 -0500 Subject: [PATCH 22/23] Update README.md jitpack.io badge added for status check. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e70536e..199cbd8 100755 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![](https://jitpack.io/v/RPTools/dicelib.svg)](https://jitpack.io/#RPTools/dicelib) + # dicelib Dice Roll Library used by RPTools programs. From d55821bb74b4a577d76a0755544edea864448f77 Mon Sep 17 00:00:00 2001 From: Phergus <34379254+Phergus@users.noreply.github.com> Date: Sat, 28 Sep 2019 14:52:12 -0600 Subject: [PATCH 23/23] Update build.gradle to use parser 1.5.5 Add jitpack.io to repos. Callout parser 1.5.5 in dependencies. --- build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index cb60955..6b4d2c9 100755 --- a/build.gradle +++ b/build.gradle @@ -31,6 +31,7 @@ repositories { mavenCentral() mavenLocal() maven { url = 'http://maptool.craigs-stuff.net/repo/' } + maven { url = 'https://jitpack.io' } } @@ -38,7 +39,8 @@ repositories { dependencies { compile 'rhino:js:1.6R5' compile 'antlr:antlr:2.7.6' - compile 'net.rptools.parser:parser:1.1.b24' +// compile 'net.rptools.parser:parser:1.1.b24' + implementation 'com.github.RPTools:parser:1.5.5' testCompile group: 'junit', name: 'junit', version: '4.11' }