mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
816 lines
18 KiB
Lua
816 lines
18 KiB
Lua
--[[
|
|
| This file was obtained through the combined efforts
|
|
| of Madbluntz & Plymouth Antiquarian Society.
|
|
|
|
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
|
| Maloy, DrPepper10 @ RIP, Atle!
|
|
|
|
|
| Visit for more: https://plymouth.thetwilightzone.ru/
|
|
--]]
|
|
|
|
|
|
function table.Pack( ... )
|
|
return { ... }, select( "#", ... )
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: Inherit( t, base )
|
|
Desc: Copies any missing data from base to t
|
|
-----------------------------------------------------------]]
|
|
function table.Inherit( t, base )
|
|
|
|
for k, v in pairs( base ) do
|
|
if ( t[ k ] == nil ) then t[ k ] = v end
|
|
end
|
|
|
|
t[ "BaseClass" ] = base
|
|
|
|
return t
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: Copy(t, lookup_table)
|
|
Desc: Taken straight from http://lua-users.org/wiki/PitLibTablestuff
|
|
and modified to the new Lua 5.1 code by me.
|
|
Original function by PeterPrade!
|
|
-----------------------------------------------------------]]
|
|
function table.Copy( t, lookup_table )
|
|
if ( t == nil ) then return nil end
|
|
|
|
local copy = {}
|
|
setmetatable( copy, debug.getmetatable( t ) )
|
|
for i, v in pairs( t ) do
|
|
if ( !istable( v ) ) then
|
|
copy[ i ] = v
|
|
else
|
|
lookup_table = lookup_table or {}
|
|
lookup_table[ t ] = copy
|
|
if ( lookup_table[ v ] ) then
|
|
copy[ i ] = lookup_table[ v ] -- we already copied this table. reuse the copy.
|
|
else
|
|
copy[ i ] = table.Copy( v, lookup_table ) -- not yet copied. copy it.
|
|
end
|
|
end
|
|
end
|
|
return copy
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: Empty( tab )
|
|
Desc: Empty a table
|
|
-----------------------------------------------------------]]
|
|
function table.Empty( tab )
|
|
for k, v in pairs( tab ) do
|
|
tab[ k ] = nil
|
|
end
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: IsEmpty( tab )
|
|
Desc: Returns whether a table has iterable items in it, useful for non-sequential tables
|
|
-----------------------------------------------------------]]
|
|
function table.IsEmpty( tab )
|
|
return next( tab ) == nil
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: CopyFromTo( FROM, TO )
|
|
Desc: Make TO exactly the same as FROM - but still the same table.
|
|
-----------------------------------------------------------]]
|
|
function table.CopyFromTo( from, to )
|
|
|
|
-- Erase values from table TO
|
|
table.Empty( to )
|
|
|
|
-- Copy values over
|
|
table.Merge( to, from )
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: Merge
|
|
Desc: xx
|
|
-----------------------------------------------------------]]
|
|
function table.Merge( dest, source, forceOverride )
|
|
|
|
for k, v in pairs( source ) do
|
|
if ( !forceOverride and istable( v ) and istable( dest[ k ] ) ) then
|
|
-- don't overwrite one table with another
|
|
-- instead merge them recurisvely
|
|
table.Merge( dest[ k ], v )
|
|
else
|
|
dest[ k ] = v
|
|
end
|
|
end
|
|
|
|
return dest
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: HasValue
|
|
Desc: Returns whether the value is in given table
|
|
-----------------------------------------------------------]]
|
|
function table.HasValue( t, val )
|
|
for k, v in pairs( t ) do
|
|
if ( v == val ) then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.Add( dest, source )
|
|
Desc: Unlike merge this adds the two tables together and discards keys.
|
|
-----------------------------------------------------------]]
|
|
function table.Add( dest, source )
|
|
-- The tables should be different otherwise this will just freeze the whole game
|
|
if ( dest == source ) then return dest end
|
|
|
|
-- At least one of them needs to be a table or this whole thing will fall on its ass
|
|
if ( !istable( source ) ) then return dest end
|
|
if ( !istable( dest ) ) then dest = {} end
|
|
|
|
for k, v in pairs( source ) do
|
|
table.insert( dest, v )
|
|
end
|
|
|
|
return dest
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.SortDesc( table )
|
|
Desc: Like Lua's default sort, but descending
|
|
-----------------------------------------------------------]]
|
|
function table.SortDesc( t )
|
|
return table.sort( t, function( a, b ) return a > b end )
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.SortByKey( table )
|
|
Desc: Returns a table sorted numerically by Key value
|
|
-----------------------------------------------------------]]
|
|
function table.SortByKey( t, desc )
|
|
|
|
local temp = {}
|
|
|
|
for key, _ in pairs( t ) do table.insert( temp, key ) end
|
|
if ( desc ) then
|
|
table.sort( temp, function( a, b ) return t[ a ] < t[ b ] end )
|
|
else
|
|
table.sort( temp, function( a, b ) return t[ a ] > t[ b ] end )
|
|
end
|
|
|
|
return temp
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.Count( table )
|
|
Desc: Returns the number of keys in a table
|
|
-----------------------------------------------------------]]
|
|
function table.Count( t )
|
|
local i = 0
|
|
for k in pairs( t ) do i = i + 1 end
|
|
return i
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.Random( table )
|
|
Desc: Return a random key
|
|
-----------------------------------------------------------]]
|
|
function table.Random( t )
|
|
local rk = math.random( 1, table.Count( t ) )
|
|
local i = 1
|
|
for k, v in pairs( t ) do
|
|
if ( i == rk ) then return v, k end
|
|
i = i + 1
|
|
end
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.Shuffle( table )
|
|
Desc: Performs an inline Fisher-Yates shuffle on the table in O(n) time
|
|
-----------------------------------------------------------]]
|
|
function table.Shuffle( t )
|
|
local n = #t
|
|
for i = 1, n - 1 do
|
|
local j = math.random( i, n )
|
|
t[ i ], t[ j ] = t[ j ], t[ i ]
|
|
end
|
|
end
|
|
|
|
--[[----------------------------------------------------------------------
|
|
Name: table.IsSequential( table )
|
|
Desc: Returns true if the tables
|
|
keys are sequential
|
|
-------------------------------------------------------------------------]]
|
|
function table.IsSequential( t )
|
|
local i = 1
|
|
for key, value in pairs( t ) do
|
|
if ( t[ i ] == nil ) then return false end
|
|
i = i + 1
|
|
end
|
|
return true
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.ToString( table,name,nice )
|
|
Desc: Convert a simple table to a string
|
|
table = the table you want to convert (table)
|
|
name = the name of the table (string)
|
|
nice = whether to add line breaks and indents (bool)
|
|
-----------------------------------------------------------]]
|
|
local function MakeTable( t, nice, indent, done )
|
|
local str = ""
|
|
done = done or {}
|
|
indent = indent or 0
|
|
|
|
local idt = ""
|
|
if ( nice ) then idt = string.rep( "\t", indent ) end
|
|
|
|
local nl, tab = "", ""
|
|
if ( nice ) then nl, tab = "\n", "\t" end
|
|
|
|
local sequential = table.IsSequential( t )
|
|
|
|
for key, value in pairs( t ) do
|
|
|
|
str = str .. idt .. tab .. tab
|
|
|
|
if !sequential then
|
|
if ( isnumber( key ) or isbool( key ) ) then
|
|
key = "[" .. tostring( key ) .. "]" .. tab .. "="
|
|
else
|
|
key = tostring( key ) .. tab .. "="
|
|
end
|
|
else
|
|
key = ""
|
|
end
|
|
|
|
if ( istable( value ) and !done[ value ] ) then
|
|
|
|
if ( IsColor( value ) ) then
|
|
done[ value ] = true
|
|
value = "Color(" .. value.r .. "," .. value.g .. "," .. value.b .. "," .. value.a .. ")"
|
|
str = str .. key .. tab .. value .. "," .. nl
|
|
else
|
|
done[ value ] = true
|
|
str = str .. key .. tab .. '{' .. nl .. MakeTable( value, nice, indent + 1, done )
|
|
str = str .. idt .. tab .. tab .. tab .. tab .. "}," .. nl
|
|
end
|
|
|
|
else
|
|
|
|
if ( isstring( value ) ) then
|
|
value = '"' .. tostring( value ) .. '"'
|
|
elseif ( isvector( value ) ) then
|
|
value = "Vector(" .. value.x .. "," .. value.y .. "," .. value.z .. ")"
|
|
elseif ( isangle( value ) ) then
|
|
value = "Angle(" .. value.pitch .. "," .. value.yaw .. "," .. value.roll .. ")"
|
|
else
|
|
value = tostring( value )
|
|
end
|
|
|
|
str = str .. key .. tab .. value .. "," .. nl
|
|
|
|
end
|
|
|
|
end
|
|
return str
|
|
end
|
|
|
|
function table.ToString( t, n, nice )
|
|
local nl, tab = "", ""
|
|
if ( nice ) then nl, tab = "\n", "\t" end
|
|
|
|
local str = ""
|
|
if ( n ) then str = n .. tab .. "=" .. tab end
|
|
return str .. "{" .. nl .. MakeTable( t, nice ) .. "}"
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.Sanitise( table )
|
|
Desc: Converts a table containing vectors, angles, bools so it can be converted to and from keyvalues
|
|
-----------------------------------------------------------]]
|
|
function table.Sanitise( t, done )
|
|
|
|
done = done or {}
|
|
local tbl = {}
|
|
|
|
for k, v in pairs ( t ) do
|
|
|
|
if ( istable( v ) and !IsColor( v ) and !done[ v ] ) then
|
|
|
|
done[ v ] = true
|
|
tbl[ k ] = table.Sanitise( v, done )
|
|
|
|
else
|
|
|
|
if ( isvector( v ) ) then
|
|
|
|
local x, y, z = v.x, v.y, v.z
|
|
if y == 0 then y = nil end
|
|
if z == 0 then z = nil end
|
|
tbl[ k ] = { __type = "Vector", x = x, y = y, z = z }
|
|
|
|
elseif ( isangle( v ) ) then
|
|
|
|
local p, y, r = v.pitch, v.yaw, v.roll
|
|
if p == 0 then p = nil end
|
|
if y == 0 then y = nil end
|
|
if r == 0 then r = nil end
|
|
tbl[ k ] = { __type = "Angle", p = p, y = y, r = r }
|
|
|
|
elseif ( IsColor( v ) ) then
|
|
|
|
local r, g, b, a = v.r, v.g, v.b, v.a
|
|
if r == 255 then r = nil end
|
|
if g == 255 then g = nil end
|
|
if b == 255 then b = nil end
|
|
if a == 255 then a = nil end
|
|
tbl[ k ] = { __type = "Color", r = r, g = g, b = b, a = a }
|
|
|
|
elseif ( isbool( v ) ) then
|
|
|
|
tbl[ k ] = { __type = "Bool", tostring( v ) }
|
|
|
|
else
|
|
|
|
tbl[ k ] = tostring( v )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return tbl
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.DeSanitise( table )
|
|
Desc: Converts a Sanitised table back
|
|
-----------------------------------------------------------]]
|
|
function table.DeSanitise( t, done )
|
|
|
|
done = done or {}
|
|
local tbl = {}
|
|
|
|
for k, v in pairs ( t ) do
|
|
|
|
if ( istable( v ) and !IsColor( v ) and !done[ v ] ) then
|
|
|
|
done[ v ] = true
|
|
|
|
if ( v.__type ) then
|
|
|
|
if ( v.__type == "Vector" ) then
|
|
|
|
tbl[ k ] = Vector( v.x or 0, v.y, v.z )
|
|
|
|
elseif ( v.__type == "Angle" ) then
|
|
|
|
tbl[ k ] = Angle( v.p or 0, v.y, v.r )
|
|
|
|
elseif ( v.__type == "Color" ) then
|
|
|
|
tbl[ k ] = Color( v.r or 255, v.g or 255, v.b or 255, v.a or 255 )
|
|
|
|
elseif ( v.__type == "Bool" ) then
|
|
|
|
tbl[ k ] = ( v[ 1 ] == "true" )
|
|
|
|
end
|
|
|
|
else
|
|
|
|
tbl[ k ] = table.DeSanitise( v, done )
|
|
|
|
end
|
|
|
|
else
|
|
|
|
tbl[ k ] = v
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return tbl
|
|
|
|
end
|
|
|
|
function table.ForceInsert( t, v )
|
|
|
|
if ( t == nil ) then t = {} end
|
|
|
|
table.insert( t, v )
|
|
|
|
return t
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.SortByMember( table )
|
|
Desc: Sorts table by named member
|
|
-----------------------------------------------------------]]
|
|
function table.SortByMember( tab, memberName, bAsc )
|
|
|
|
local TableMemberSort = function( a, b, MemberName, bReverse )
|
|
|
|
--
|
|
-- All this error checking kind of sucks, but really is needed
|
|
--
|
|
if ( !istable( a ) ) then return !bReverse end
|
|
if ( !istable( b ) ) then return bReverse end
|
|
if ( !a[ MemberName ] ) then return !bReverse end
|
|
if ( !b[ MemberName ] ) then return bReverse end
|
|
|
|
if ( isstring( a[ MemberName ] ) ) then
|
|
|
|
if ( bReverse ) then
|
|
return a[ MemberName ]:lower() < b[ MemberName ]:lower()
|
|
else
|
|
return a[ MemberName ]:lower() > b[ MemberName ]:lower()
|
|
end
|
|
|
|
end
|
|
|
|
if ( bReverse ) then
|
|
return a[ MemberName ] < b[ MemberName ]
|
|
else
|
|
return a[ MemberName ] > b[ MemberName ]
|
|
end
|
|
|
|
end
|
|
|
|
table.sort( tab, function( a, b ) return TableMemberSort( a, b, memberName, bAsc or false ) end )
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.LowerKeyNames( table )
|
|
Desc: Lowercase the keynames of all tables
|
|
-----------------------------------------------------------]]
|
|
function table.LowerKeyNames( tab )
|
|
|
|
local OutTable = {}
|
|
|
|
for k, v in pairs( tab ) do
|
|
|
|
-- Recurse
|
|
if ( istable( v ) ) then
|
|
v = table.LowerKeyNames( v )
|
|
end
|
|
|
|
OutTable[ k ] = v
|
|
|
|
if ( isstring( k ) ) then
|
|
|
|
OutTable[ k ] = nil
|
|
OutTable[ string.lower( k ) ] = v
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return OutTable
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.CollapseKeyValue( table )
|
|
Desc: Collapses a table with keyvalue structure
|
|
-----------------------------------------------------------]]
|
|
function table.CollapseKeyValue( Table )
|
|
|
|
local OutTable = {}
|
|
|
|
for k, v in pairs( Table ) do
|
|
|
|
local Val = v.Value
|
|
|
|
if ( istable( Val ) ) then
|
|
Val = table.CollapseKeyValue( Val )
|
|
end
|
|
|
|
OutTable[ v.Key ] = Val
|
|
|
|
end
|
|
|
|
return OutTable
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
Name: table.ClearKeys( table, bSaveKey )
|
|
Desc: Clears the keys, converting to a numbered format
|
|
-----------------------------------------------------------]]
|
|
function table.ClearKeys( Table, bSaveKey )
|
|
|
|
local OutTable = {}
|
|
|
|
for k, v in pairs( Table ) do
|
|
if ( bSaveKey ) then
|
|
v.__key = k
|
|
end
|
|
table.insert( OutTable, v )
|
|
end
|
|
|
|
return OutTable
|
|
|
|
end
|
|
|
|
local function keyValuePairs( state )
|
|
|
|
state.Index = state.Index + 1
|
|
|
|
local keyValue = state.KeyValues[ state.Index ]
|
|
if ( !keyValue ) then return end
|
|
|
|
return keyValue.key, keyValue.val
|
|
|
|
end
|
|
|
|
local function toKeyValues( tbl )
|
|
|
|
local result = {}
|
|
|
|
for k, v in pairs( tbl ) do
|
|
table.insert( result, { key = k, val = v } )
|
|
end
|
|
|
|
return result
|
|
|
|
end
|
|
|
|
local function getKeys( tbl )
|
|
|
|
local keys = {}
|
|
|
|
for k in pairs( tbl ) do
|
|
table.insert( keys, k )
|
|
end
|
|
|
|
return keys
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
A Pairs function
|
|
Sorted by TABLE KEY
|
|
-----------------------------------------------------------]]
|
|
function SortedPairs( pTable, Desc )
|
|
|
|
local keys = getKeys( pTable )
|
|
|
|
if ( Desc ) then
|
|
table.sort( keys, function( a, b )
|
|
return a > b
|
|
end )
|
|
else
|
|
table.sort( keys, function( a, b )
|
|
return a < b
|
|
end )
|
|
end
|
|
|
|
local i, key
|
|
return function()
|
|
i, key = next( keys, i )
|
|
return key, pTable[key]
|
|
end
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
A Pairs function
|
|
Sorted by VALUE
|
|
-----------------------------------------------------------]]
|
|
function SortedPairsByValue( pTable, Desc )
|
|
|
|
local sortedTbl = toKeyValues( pTable )
|
|
|
|
if ( Desc ) then
|
|
table.sort( sortedTbl, function( a, b ) return a.val > b.val end )
|
|
else
|
|
table.sort( sortedTbl, function( a, b ) return a.val < b.val end )
|
|
end
|
|
|
|
return keyValuePairs, { Index = 0, KeyValues = sortedTbl }
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
A Pairs function
|
|
Sorted by Member Value (All table entries must be a table!)
|
|
-----------------------------------------------------------]]
|
|
function SortedPairsByMemberValue( pTable, pValueName, Desc )
|
|
|
|
local sortedTbl = toKeyValues( pTable )
|
|
|
|
for k, v in pairs( sortedTbl ) do
|
|
v.member = v.val[ pValueName ]
|
|
end
|
|
|
|
table.SortByMember( sortedTbl, "member", !Desc )
|
|
|
|
return keyValuePairs, { Index = 0, KeyValues = sortedTbl }
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
A Pairs function
|
|
-----------------------------------------------------------]]
|
|
function RandomPairs( pTable, Desc )
|
|
|
|
local sortedTbl = toKeyValues( pTable )
|
|
|
|
for k, v in pairs( sortedTbl ) do
|
|
v.rand = math.random( 1, 1000000 )
|
|
end
|
|
|
|
-- descending/ascending for a random order, really?
|
|
if ( Desc ) then
|
|
table.sort( sortedTbl, function( a, b ) return a.rand > b.rand end )
|
|
else
|
|
table.sort( sortedTbl, function( a, b ) return a.rand < b.rand end )
|
|
end
|
|
|
|
return keyValuePairs, { Index = 0, KeyValues = sortedTbl }
|
|
|
|
end
|
|
|
|
--[[---------------------------------------------------------
|
|
GetFirstKey
|
|
-----------------------------------------------------------]]
|
|
function table.GetFirstKey( t )
|
|
local k, _ = next( t )
|
|
return k
|
|
end
|
|
|
|
function table.GetFirstValue( t )
|
|
local _, v = next( t )
|
|
return v
|
|
end
|
|
|
|
function table.GetLastKey( t )
|
|
local k, _ = next( t, table.Count( t ) - 1 )
|
|
return k
|
|
end
|
|
|
|
function table.GetLastValue( t )
|
|
local _, v = next( t, table.Count( t ) - 1 )
|
|
return v
|
|
end
|
|
|
|
function table.FindNext( tab, val )
|
|
local bfound = false
|
|
for k, v in pairs( tab ) do
|
|
if ( bfound ) then return v end
|
|
if ( val == v ) then bfound = true end
|
|
end
|
|
|
|
return table.GetFirstValue( tab )
|
|
end
|
|
|
|
function table.FindPrev( tab, val )
|
|
|
|
local last = table.GetLastValue( tab )
|
|
for k, v in pairs( tab ) do
|
|
if ( val == v ) then return last end
|
|
last = v
|
|
end
|
|
|
|
return last
|
|
|
|
end
|
|
|
|
function table.GetWinningKey( tab )
|
|
|
|
local highest = -math.huge
|
|
local winner = nil
|
|
|
|
for k, v in pairs( tab ) do
|
|
if ( v > highest ) then
|
|
winner = k
|
|
highest = v
|
|
end
|
|
end
|
|
|
|
return winner
|
|
|
|
end
|
|
|
|
function table.KeyFromValue( tbl, val )
|
|
for key, value in pairs( tbl ) do
|
|
if ( value == val ) then return key end
|
|
end
|
|
end
|
|
|
|
function table.RemoveByValue( tbl, val )
|
|
|
|
local key = table.KeyFromValue( tbl, val )
|
|
if ( !key ) then return false end
|
|
|
|
if ( isnumber( key ) ) then
|
|
table.remove( tbl, key )
|
|
else
|
|
tbl[ key ] = nil
|
|
end
|
|
|
|
return key
|
|
|
|
end
|
|
|
|
function table.KeysFromValue( tbl, val )
|
|
local res = {}
|
|
for key, value in pairs( tbl ) do
|
|
if ( value == val ) then res[ #res + 1 ] = key end
|
|
end
|
|
return res
|
|
end
|
|
|
|
function table.MemberValuesFromKey( tab, key )
|
|
local res = {}
|
|
for k, v in pairs( tab ) do
|
|
if ( istable( v ) and v[ key ] != nil ) then res[ #res + 1 ] = v[ key ] end
|
|
end
|
|
return res
|
|
end
|
|
|
|
function table.Reverse( tbl )
|
|
|
|
local len = #tbl
|
|
local ret = {}
|
|
|
|
for i = len, 1, -1 do
|
|
ret[ len - i + 1 ] = tbl[ i ]
|
|
end
|
|
|
|
return ret
|
|
|
|
end
|
|
|
|
function table.ForEach( tab, funcname )
|
|
|
|
for k, v in pairs( tab ) do
|
|
funcname( k, v )
|
|
end
|
|
|
|
end
|
|
|
|
function table.GetKeys( tab )
|
|
|
|
local keys = {}
|
|
local id = 1
|
|
|
|
for k, v in pairs( tab ) do
|
|
keys[ id ] = k
|
|
id = id + 1
|
|
end
|
|
|
|
return keys
|
|
|
|
end
|
|
|
|
function table.Flip( tab )
|
|
|
|
local res = {}
|
|
|
|
for k, v in pairs( tab ) do
|
|
res[ v ] = k
|
|
end
|
|
|
|
return res
|
|
|
|
end
|
|
|
|
-- Polyfill for table.move on 32-bit
|
|
-- Don't forget to remove this when it's no longer necessary
|
|
if ( !table.move ) then
|
|
function table.move( sourceTbl, from, to, dest, destTbl )
|
|
|
|
if ( !istable( sourceTbl ) ) then error( "bad argument #1 to 'move' (table expected, got " .. type( sourceTbl ) .. ")" ) end
|
|
if ( !isnumber( from ) ) then error( "bad argument #2 to 'move' (number expected, got " .. type( from ) .. ")" ) end
|
|
if ( !isnumber( to ) ) then error( "bad argument #3 to 'move' (number expected, got " .. type( to ) .. ")" ) end
|
|
if ( !isnumber( dest ) ) then error( "bad argument #4 to 'move' (number expected, got " .. type( dest ) .. ")" ) end
|
|
if ( destTbl != nil ) then
|
|
if ( !istable( destTbl ) ) then error( "bad argument #5 to 'move' (table expected, got " .. type( destTbl ) .. ")" ) end
|
|
else
|
|
destTbl = sourceTbl
|
|
end
|
|
|
|
local buffer = { unpack( sourceTbl, from, to ) }
|
|
|
|
dest = math.floor( dest - 1 )
|
|
for i, v in ipairs( buffer ) do
|
|
destTbl[ dest + i ] = v
|
|
end
|
|
|
|
return destTbl
|
|
|
|
end
|
|
end
|