--XRNG - SRB2 Lua implementation of xoshiro128++ PRNG with multiple instance support, made by Nightwolf --The original xoshiro128++ code can be found here: https://prng.di.unimi.it/xoshiro128plusplus.c --XRNG Version: v1 --Main xoshiro128++ function, generates a random value based on the RNG state (s) and modifies the state --The name was changed from 'next' because a standard lua function uses that name local function generate(s) local x = s[1] + s[4] local result = ((x << 7) | (x >> 25)) + s[1] local t = s[2] << 9 s[3] = $ ^^ s[1] s[4] = $ ^^ s[2] s[2] = $ ^^ s[3] s[1] = $ ^^ s[4] s[3] = $ ^^ t s[4] = (s[4] << 11) | (s[4] >> 21) return result end --This function is equivalent to 2^64 calls to generate(). In XRNG it's used to initialize the RNG state after seeding it local function jump(s) local JUMP = { 0x8764000b, 0xf542d2d3, 0x6fa035c3, 0x77f2db5b } local s1 = 0 local s2 = 0 local s3 = 0 local s4 = 0 for i = 1,#JUMP do for b = 0,31 do if JUMP[i] & (1 << b) then s1 = $ ^^ s[1] s2 = $ ^^ s[2] s3 = $ ^^ s[3] s4 = $ ^^ s[4] end generate(s) end end s[1] = s1 s[2] = s2 s[3] = s3 s[4] = s4 end --XRNG interface functions start here --This function sets the RNG seed and returns it (as a number) local function xrng_setSeed(self,seed) seed = seed or 0 if type(seed) == "string" then local hash = 0 for i = 1,string.len(seed) do hash = 31*$+string.byte(seed,i) end seed = hash elseif type(seed) ~= "number" then error("xrng_setSeed: incorrect variable type in 'seed' argument (expected number, string or nil)") end self.s[1],self.s[2],self.s[3],self.s[4] = seed,135478321,0,0 jump(self.s) return seed end --This function returns a random integer, generate() function wrapper local function xrng_randomSigned(self) return generate(self.s) end --This function returns a random non-negative integer local function xrng_randomUnsigned(self) return generate(self.s) >> 1 end --This function returns a random integer between 0 and 65535 (FRACUNIT-1) local function xrng_randomFixed(self) return generate(self.s) >> 16 end --This function returns a random integer between 0 and 255 local function xrng_randomByte(self) return generate(self.s) >> 24 end --This function returns a random integer between 1 and a, made for accessing a random element in Lua arrays local function xrng_randomKey(self,a) return ((generate(self.s) >> 1) % a) + 1 end --This function returns a random integer between a and b - the difference should not be bigger than INT32_MAX (2147483647) local function xrng_randomRange(self,a,b) a = a or 0 b = b or 0 if a > b then a,b = b,a end local range = (b-a+1) local result = generate(self.s) >> 1 return (result % (range or 1)) + a end --This function returns true p% of the time (0 is 0%, FRACUNIT/2 is 50%, FRACUNIT is 100%, etc.) local function xrng_randomChance(self,p) p = $ or 0 local result = generate(self.s) >> 16 return result < p end --This function creates a new RNG instance (if seed value is present, the RNG is seeded with it) --Returns the RNG instance and the RNG seed local function xrng_new(seed) local newrng = {} newrng.s = {0,0,0,0} newrng.setSeed = xrng_setSeed newrng.randomNumber = xrng_randomSigned newrng.randomUnsigned = xrng_randomUnsigned newrng.randomFixed = xrng_randomFixed newrng.randomByte = xrng_randomByte newrng.randomKey = xrng_randomKey newrng.randomRange = xrng_randomRange newrng.randomChance = xrng_randomChance local seed = xrng_setSeed(newrng,seed) return newrng,seed end rawset(_G,"newXRNG",xrng_new)