diff options
Diffstat (limited to 'npc/functions/main.txt')
-rw-r--r-- | npc/functions/main.txt | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/npc/functions/main.txt b/npc/functions/main.txt index b2a7a78..999d18c 100644 --- a/npc/functions/main.txt +++ b/npc/functions/main.txt @@ -299,6 +299,34 @@ function script any_of { return getelementofarray(getarg(0), getarrayindex(getarg(0)) + rand2(getarraysize(getarg(0)) - getarrayindex(getarg(0)))); } +// Miller Algorithm implementation for shuffling (PRIG) +// miller_rand( state, seed, array_size ) +function script miller_rand { + .@inx = getarg(0); + .@shuffleID = getarg(1); + .@listSize = getarg(2); + + .@shuffleID += 131 * (.@inx/.@listSize); // have inx overflow effect the mix + .@si = (.@inx + .@shuffleID) % .@listSize; // cut the deck + + .@topEven = .@listSize - (.@listSize & 1); // compute reference value + .@r1 = .@shuffleID % 0xFFF; // improved randomizing values + .@r2 = .@shuffleID % 0x3FFF ^ .@r1; + .@r3 = .@shuffleID / 881 + 3; + .@rx = (.@shuffleID / .@listSize) % .@listSize + 1; + + // NOTE: the next line operates only 1/3 the time, the following line 1/2 + if (.@si % 3 == 0) + .@si = (((.@si/3)*3343+.@r1) % ((.@listSize+2)/3)) * 3; // spin multiples of 3 + if (.@si&1) + .@si = (2 * .@r2 + .@topEven - .@si) % .@topEven; // reverse+rotate flow of odd #s + if ((.@si ^ .@rx) < .@listSize) + .@si ^= .@rx; // flip some bits with Xor + .@si = (.@si * 9973 + .@r3) % .@listSize; // turn more prime wheels + + return .@si; +} + function script die { if ($HARDCORE) { @grace=true; |