local Tinkr, Bastion = ... local NAN = math.huge * 0 local IS_NAN_GT_INF = (NAN or 0 ) > math.huge local NAN_STR = tostring(NAN) Bastion:RegisterLibrary(Bastion.Library:New({ name = 'Math', exports = { default = function(self) -- Function exports are called when the library is loaded -- Return default first, and then the remaining exports local Math = {} Math.__index = Math ---Returns NAN ---@return number function Math.GetNan() assert(NAN) return NAN end ---checks if a value is NAN ---@param value number ---@return boolean @whether or not the value is NAN function Math.IsNan(value) if not NAN then error("NAN not set") end if IS_NAN_GT_INF then -- if NAN > math.huge (which it is in Wow's version of lua) return value > math.huge and tostring(value) == NAN_STR else return tostring(value) == NAN_STR end end ---Rounds a number to the nearest significant value ---@param value number The number to be rounded ---@param sig number The value to round to the nearest multiple of (defaults to 1) ---@return number function Math.Round(value, sig) sig = sig or 1 return math.floor((value / sig) + 0.5) * sig end ---Rounds a value down to a specified significant value. ---@param value number The number to be rounded ---@param sig? number The value to round down to the nearest multiple of (defaults to 1) ---@return number function Math.Floor(value, sig) sig = sig or 1 return math.floor(value / sig) * sig end ---Rounds a value up to a specified significant value. ---@param value number The number to be rounded ---@param sig? number The value to round up to the nearest multiple of (defaults to 1) ---@return number function Math.Ceil(value, sig) sig = sig or 1 return math.ceil(value / sig) * sig end ---Scales a value from one range to another. ---@param value number The number to be scaled ---@param fromStart number The start value of the range to scale from ---@param fromEnd number The end value of the range to scale from (can be less than fromStart) ---@param toStart number The start value of the range to scale to ---@param toEnd number The end value of the range to scale to (can be less than toStart) ---@return number function Math.Scale(value, fromStart, fromEnd, toStart, toEnd) assert(value >= math.min(fromStart, fromEnd) and value <= math.max(fromStart, fromEnd)) return toStart + ((value - fromStart) / (fromEnd - fromStart)) * (toEnd - toStart) end ---Bounds a number between a min and max value. ---@param value number The number to be bounded ---@param minValue number The min value ---@param maxValue number The max value ---@return number function Math.Bound(value, minValue, maxValue) return math.min(math.max(value, minValue), maxValue) end ---This code is a method that generates a random number within a given range. ---It ensures that there are at least 50 possible choices by making multiple copies of the range if necessary. --- It also allows for the number to be divided by a specified divisor for decimals ---@param lowRange number The low end of the range ---@param highRange number The high end of the range ---@param divisor? number The divisor to divide the number by ---@return number function Math.RandomNumberGenerator(lowRange, highRange, divisor) local lowNum, highNum if not highRange then highNum = lowRange lowNum = 1 else lowNum = lowRange highNum = highRange end local total = 1 if math.abs(highNum - lowNum + 1) < 50 then -- if total values is less than 50 total = math.modf(50/math.abs(highNum - lowNum + 1)) -- make x copies required to be above 50 end local choices = {} for i = 1, total do -- iterate required number of times for x = lowNum, highNum do -- iterate between the range choices[#choices +1] = x -- add each entry to a table end end local rtnVal = math.random(#choices) -- will now do a math.random of at least 50 choices for i = 1, 10 do rtnVal = math.random(#choices) -- iterate a few times for random randomness end if divisor then return choices[rtnVal] / divisor end return choices[rtnVal] end return Math end } }))