Module:Inventory slot: Difference between revisions

Remove old class
Update to allow aliases to be pre-split, for better performance; also avoid splitting and stringifying input twice
Line 8: Line 8:
'Damaged'
'Damaged'
}
}
local function mergeList( parentTable, content )
if content[1] then
-- Merge list into table
for _, v in ipairs( content ) do
table.insert( parentTable, v )
end
else
-- Add strings or tables to table
table.insert( parentTable, content )
end
end
local function cloneTable( origTable )
local newTable = {}
for k, v in pairs( origTable ) do
if type( v ) == 'table' then
v = cloneTable( v )
end
newTable[k] = v
end
return newTable
end


function p.slot( f )
function p.slot( f )
Line 31: Line 54:
randomise = false
randomise = false
end
end
if aliases or modAliases then
local frames = {}
local frames = {}
for frameText in mw.text.gsplit( args[1], '%s*;%s*' ) do
for frame in mw.text.gsplit( args[1], '%s*;%s*' ) do
local frame = p.makeFrame( frameText, args.mod )
local frameParts = p.getParts( frame, args.mod )
local id = frame.name
local id = frameParts.name
if frame.mod then
if frameParts.mod then
id = frame.mod .. ':' .. id
id = frameParts.mod .. ':' .. id
end
end
local alias
local alias
if modAliases and modAliases[id] then
if modAliases and modAliases[id] then
alias = modAliases[id]
alias = modAliases[id]
elseif aliases and aliases[id] then
elseif aliases and aliases[id] then
alias = aliases[id]
alias = aliases[id]
end
if alias then
table.insert( frames, p.expandAlias( frameParts, alias ) )
else
table.insert( frames, frame )
end
-- Randomise starting frame for "Any *" aliases, as long as the alias is the only frame
-- and this isn't an output slot
if randomise ~= false and frameParts.name:match( '^Any ' ) then
randomise = true
else
randomise = false
end
end
end
args[1] = table.concat( frames, ';' )
if alias then
mergeList( frames, p.expandAlias( alias, frame ) )
else
table.insert( frames, frame )
end
-- Randomise starting frame for "Any *" aliases, as long as the alias is the only frame
-- and this isn't an output slot
if randomise ~= false and frame.name:match( '^Any ' ) then
randomise = true
else
randomise = false
end
end
end
Line 68: Line 87:
local ids = mw.loadData( [[Module:InvSprite/IDs]] ).ids
local ids = mw.loadData( [[Module:InvSprite/IDs]] ).ids
local modIds = {}
local modIds = {}
local animated = args[1]:find( ';' )
local animated = #frames > 1
local pageName = mw.title.getCurrentTitle().text
local pageName = mw.title.getCurrentTitle().text
local imgClass = args.imgclass
local imgClass = args.imgclass
Line 87: Line 106:
end
end
local frames = mw.text.split( args[1], '%s*;%s*' )
local activeFrame = randomise and math.random( #frames ) or 1
local activeFrame = randomise and math.random( #frames ) or 1
for i, frame in ipairs( frames ) do
for i, frame in ipairs( frames ) do
local item
local item
if frame ~= '' or frame == '' and animated then
if frame ~= '' or frame.name == '' and animated then
item = body:tag( 'span' ):addClass( 'invslot-item' )
item = body:tag( 'span' ):addClass( 'invslot-item' )
if imgClass then
if imgClass then
Line 98: Line 116:
end
end
if frame == '' then
if frame == '' or frame.name == '' then
( item or body ):tag( 'br' )
( item or body ):tag( 'br' )
else
else
local category
local category
local parts = p.getParts( frame, args.mod )
local title = frame.title or mw.text.trim( args.title or '' )
local title = parts.title or mw.text.trim( args.title or '' )
local mod = frame.mod
local mod = parts.mod
local name = frame.name
local name = parts.name
local num = frame.num
local num = parts.num
local description = frame.text
local description = parts.text
local img, idData
local img, idData
Line 232: Line 249:
end
end


function p.expandAlias( frameParts, alias )
function p.getAlias( alias, parentFrame )
-- If the frame has no parts, we can just return the alias as-is
local aliasFrames
if not frameParts.title and not frameParts.mod and not frameParts.num and not frameParts.text then
if type( alias ) == 'string' then
return alias
aliasFrames = {}
for frameText in mw.text.gsplit( alias, '%s*;%s*' ) do
table.insert( aliasFrames, p.makeFrame( frameText ) )
end
else
aliasFrames = alias
end
-- If alias is just a name, return the original frame with the new name
if type( aliasFrames ) == 'string' then
local aliasParts = mw.clone( parentFrame )
aliasParts.name = aliasFrames
return aliasParts
end
-- Single frame alias, put in list
if aliasFrames.name then
aliasFrames = { aliasFrames }
end
end
local expandedFrames = {}
local expandedFrames = {}
for aliasFrame in mw.text.gsplit( alias, '%s*;%s*' ) do
for i, aliasFrame in ipairs( aliasFrames ) do
local aliasParts = p.getParts( aliasFrame )
local aliasParts
aliasParts.title = frameParts.title or aliasParts.title or ''
if type( aliasFrame ) == 'string' then
aliasParts.mod = frameParts.mod or aliasParts.mod or 'Minecraft'
aliasParts = { name = aliasFrame }
aliasParts.num = frameParts.num or aliasParts.num or ''
else
aliasParts.text = frameParts.text or aliasParts.text or ''
aliasParts = cloneTable( aliasFrame )
end
aliasParts.title = parentFrame.title or aliasParts.title
aliasParts.mod = parentFrame.mod or aliasParts.mod
aliasParts.num = parentFrame.num or aliasParts.num
aliasParts.text = parentFrame.text or aliasParts.text
table.insert( expandedFrames, string.format(
expandedFrames[i] = aliasParts
'[%s]%s:%s,%s[%s]',
aliasParts.title, aliasParts.mod, aliasParts.name, aliasParts.num, aliasParts.text
) )
end
end
return table.concat( expandedFrames, ';' )
return expandedFrames
end
function p.expandAlias( parentFrame, alias )
return p.getAlias( alias, parentFrame )
end
 
function p.stringifyFrame( frame )
if not frame.name then
return ''
end
return string.format(
'[%s]%s:%s,%s[%s]',
frame.title or '',
frame.mod or 'Minecraft',
frame.name,
frame.num or '',
frame.text or ''
)
end
end


function p.getParts( frame, mod )
function p.stringifyFrames( frames )
local parts = {}
for i, frame in ipairs( frames ) do
parts.title = frame:match( '^%[%s*([^%]]+)%s*%]' )
frames[i] = p.stringifyFrame( frame )
end
return table.concat( frames, ';' )
end
 
function p.makeFrame( frameText, mod )
-- Simple frame with no parts
if not frameText:match( '[%[:,]' ) then
return {
mod = mod,
name = mw.text.trim( frameText ),
}
end
parts.mod = mw.text.trim( frame:match( '([^:%]]+):' ) or mod or '' )
frameText = frameText:gsub( '%s*([%[%]:,;])%s*', '%1' )
local frame = {}
frame.title = frameText:match( '^%[([^%]]+)%]' )
frame.mod = frameText:match( '([^:%]]+):' ) or mod
local vanilla = { v = 1, vanilla = 1, mc = 1, minecraft = 1 }
local vanilla = { v = 1, vanilla = 1, mc = 1, minecraft = 1 }
if parts.mod == '' or vanilla[mw.ustring.lower( parts.mod )] then
if frame.mod == '' or vanilla[mw.ustring.lower( frame.mod )] then
parts.mod = nil
frame.mod = nil
end
end
local nameStart = ( frame:find( ':' ) or frame:find( '%]' ) or 0 ) + 1
local nameStart = ( frameText:find( ':' ) or frameText:find( '%]' ) or 0 ) + 1
if nameStart - 1 == #frame then
if nameStart - 1 == #frameText then
nameStart = 1
nameStart = 1
end
end
parts.name = mw.text.trim( frame:sub( nameStart, ( frame:find( '[,%[]', nameStart ) or 0 ) - 1 ) )
frame.name = frameText:sub( nameStart, ( frameText:find( '[,%[]', nameStart ) or 0 ) - 1 )
parts.num = math.floor( frame:match( ',%s*(%d+)' ) or 0 )
frame.num = math.floor( frameText:match( ',(%d+)' ) or 0 )
if parts.num == 0 then
if frame.num == 0 then
parts.num = nil
frame.num = nil
end
end
parts.text = frame:match( '%[%s*([^%]]+)%s*%]$' )
frame.text = frameText:match( '%[([^%]]+)%]$' )
return parts
return frame
end
function p.getParts( frameText, mod )
return p.makeFrame( frameText, mod )
end
end
   
   
return p
return p