forked from Bastion/Bastion
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
5.3 KiB
123 lines
5.3 KiB
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
|
|
}
|
|
}))
|
|
|