Toggle search
Search
Toggle menu
Notifications
Toggle personal menu
Editing
Module:Inventory slot
From WoopMC
Views
Read
Edit
View history
associated-pages
Module
Discussion
More actions
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
local p = {} local i18n = { filename = 'Invicon $1', legacyFilename = 'Grid $1.png', modLink = 'Mods/$1/$2', moduleAliases = [[Module:Inventory slot/Aliases]], moduleRandom = [[Module:Random]], -- List of special prefixes which should be handled by -- other modules (such as being moved outside links) prefixes = { any = 'Any', matching = 'Matching', damaged = 'Damaged', unwaxed = 'Unwaxed', }, suffixes = { be = 'BE', lce = 'LCE', }, } p.i18n = i18n local random = require( i18n.moduleRandom ).random local aliases = mw.loadData( i18n.moduleAliases ) local pageName = mw.title.getCurrentTitle().text --[[Splits a given text into fragments separated by semicolons that are not inside square brackets. Written by AttemptToCallNil for the Russian wiki --]] local function splitOnUnenclosedSemicolons(text) local semicolon, lbrace, rbrace = (";[]"):byte(1, 3) local nesting = false local splitStart = 1 local frameIndex = 1 local frames = {} for index = 1, text:len() do local byte = text:byte(index) if byte == semicolon and not nesting then frames[frameIndex] = text:sub(splitStart, index - 1) frameIndex = frameIndex + 1 splitStart = index + 1 elseif byte == lbrace then assert(not nesting, "Excessive square brackets found") nesting = true elseif byte == rbrace then assert(nesting, "Unbalanced square brackets found") nesting = false end end assert(not nesting, "Unbalanced square brackets found") frames[frameIndex] = text:sub(splitStart, text:len()) for index = 1, #frames do frames[index] = (frames[index]:gsub("^%s+", ""):gsub("%s+$", "")) -- faster mw.text.trim end return frames end -- Performs a simple recursive clone of a table's values 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 --[[Merges a list, or inserts a string or table into a table --]] local function mergeList( parentTable, content ) local i = #parentTable + 1 if content[1] then -- Merge list into table for _, v in ipairs( content ) do parentTable[i] = v i = i + 1 end else -- Add strings or tables to table parentTable[i] = content end end -- Creates the HTML for an item local function makeItem( frame, i, args ) local item = mw.html.create( 'span' ):addClass( 'invslot-item' ) if args.imgclass then item:addClass( args.imgclass ) end if frame.name == '' then return item end local category local title = frame.title or mw.text.trim( args.title or '' ) local mod = frame.mod local name = frame.name or '' local num = frame.num local description = frame.text local img if mod then img = i18n.legacyFilename:gsub( '%$1', name .. ' (' .. mod .. ')' ) elseif name:match( '%.gif$' ) or name:match( '%.png$' ) then img = i18n.filename:gsub( '%$1', name ) -- Remove file extension from name name = name:sub( 0, -5 ) else -- Fall back to an individual image if the sprite is lacking img = i18n.filename:gsub( '%$1', name .. '.png' ) end local link = args.link or '' if link == '' then if mod then link = i18n.modLink:gsub( '%$1', mod ):gsub( '%$2', name ) else link = name:gsub( '^' .. i18n.prefixes.damaged .. ' ', '' ) for _, suffix in pairs( i18n.suffixes ) do link = link:gsub( ' ' .. suffix .. '$', '' ) end end elseif link:lower() == 'none' then link = nil end if link == pageName then link = nil end local formattedTitle local plainTitle if title == '' then plainTitle = name elseif title:lower() ~= 'none' then plainTitle = title:gsub( '\\\\', '\' ):gsub( '\\&', '&' ) local formatPattern = '&[0-9a-fk-or]' if plainTitle:match( formatPattern ) then formattedTitle = title plainTitle = plainTitle:gsub( formatPattern, '' ) end if plainTitle == '' then plainTitle = name else plainTitle = plainTitle:gsub( '\', '\\' ):gsub( '&', '&' ) end elseif link then formattedTitle = '' end item:attr{ ['data-minetip-title'] = formattedTitle, ['data-minetip-text'] = description } -- & is re-escaped because mw.html treats attributes -- as plain text, but MediaWiki doesn't local escapedTitle = ( plainTitle or '' ):gsub( '&', '&' ) local altText = img .. ': Inventory sprite for ' .. name .. ' in Minecraft as shown in-game' if link then altText = altText .. ' linking to ' .. link end if formattedTitle or plainTitle or link then altText = altText .. ' with description: ' .. ( formattedTitle or plainTitle or link ) if description then altText = altText .. ' ' .. description:gsub( '/', ' ' ) end altText = altText:gsub( '&[0-9a-fk-or]', '' ) end item:addClass( 'invslot-item-image' ) :wikitext( '[[File:', img, '|32x32px|link=', link or '', '|alt=', altText, '|', escapedTitle, ']]' ) if num and num > 1 and num < 1000 then if link then item:wikitext( '[[', link, '|' ) end local number = item :tag( 'span' ) :addClass( 'invslot-stacksize' ) :attr{ title = plainTitle } :wikitext( num ) if args.numstyle then number:cssText( args.numstyle ) end if link then item:wikitext( ']]' ) end end item:wikitext( category ) return item end -- Main entry point function p.slot( f ) local args = f.args or f if f == mw.getCurrentFrame() and args[1] == nil then args = f:getParent().args end if not args.parsed then args[1] = mw.text.trim( args[1] or '' ) end local modData = { aliases = args.modaliases or '', default = args.mod } if modData.aliases ~= '' then modData.aliases = mw.loadData( 'Module:' .. modData.aliases ) else modData.aliases = nil end if args.mod == '' then modData.default = nil end local frames if args.parsed then frames = args[1] elseif args[1] ~= '' then local randomise = args.class == 'invslot-large' and 'never' or nil frames = p.parseFrameText( args[1], randomise, false, modData ) end local animated = frames and #frames > 1 local imgClass = args.imgclass local numStyle = args.numstyle local body = mw.html.create( 'span' ):addClass( 'invslot' ):css{ ['vertical-align'] = args.align } if animated then body:addClass( 'animated' ) end if args.class then body:addClass( args.class ) end if args.style then body:cssText( args.style ) end if ( args.default or '' ) ~= '' then body:addClass( 'invslot-default-' .. string.lower( args.default ):gsub( ' ', '-' ) ) end --mw.logObject( frames ) if not frames then return tostring( body ) end local activeFrame = frames.randomise == true and random( #frames ) or 1 for i, frame in ipairs( frames ) do local item -- Table is a list, must contain subframes if frame[1] then item = body:tag( 'span' ):addClass( 'animated-subframe' ) local subActiveFrame = frame.randomise and random( #frame ) or 1 for sI, sFrame in ipairs( frame ) do local sItem = makeItem( sFrame, sI, args ) item:node( sItem ) if sI == subActiveFrame then sItem:addClass( 'animated-active' ) end end else item = makeItem( frame, i, args ) body:node( item ) end if i == activeFrame and animated then item:addClass( 'animated-active' ) end end return tostring( body ) end --[[Parses the frame text into a table of frames and subframes, expanding aliases (and optionally retaining a reference), and deciding if the slot can be randomised --]] function p.parseFrameText( framesText, randomise, aliasReference, modData ) local frames = { randomise = randomise } local subframes = {} local subframe local expandedAliases local splitFrames = splitOnUnenclosedSemicolons( framesText ) for i, frameText in ipairs( splitFrames ) do frameText = frameText:gsub( '^%s*{%s*', function() subframe = true return '' end ) if subframe then frameText = frameText:gsub( '%s*}%s*$', function() subframe = 'last' return '' end ) end local frame = p.makeFrame( frameText, modData and modData.default ) local newFrame = frame if aliases or modData.aliases then local id = frame.name if frame.mod then id = frame.mod .. ':' .. id end local alias = modData and modData.aliases and modData.aliases[id] or aliases and aliases[id] if alias then newFrame = p.getAlias( alias, frame ) if aliasReference then local curFrame = #frames + 1 local aliasData = { frame = frame, length = #newFrame } if subframe then if not subframes.aliasReference then subframes.aliasReference = {} end subframes.aliasReference[#subframes + 1] = aliasData else if not expandedAliases then expandedAliases = {} end expandedAliases[curFrame] = aliasData end end end end if subframe then mergeList( subframes, newFrame ) -- Randomise starting frame for "Any *" aliases, as long as the alias is the only subframe if frames.randomise ~= 'never' and subframes.randomise == nil and frame.name:match( '^' .. i18n.prefixes.any .. ' ' ) then subframes.randomise = true else subframes.randomise = false end if frames.randomise ~= 'never' then frames.randomise = false end if subframe == 'last' then -- No point having a subframe containing a single frame, -- or the subframe being the only frame if #subframes == 1 or #splitFrames == i and #frames == 0 then mergeList( frames, subframes ) else table.insert( frames, subframes ) end subframes = {} subframe = nil end else -- Randomise starting frame for "Any *" aliases, as long as the alias is the only frame if frames.randomise == nil and frame.name:match( '^' .. i18n.prefixes.any .. ' ' ) then frames.randomise = true elseif frames.randomise ~= 'never' then frames.randomise = false end mergeList( frames, newFrame ) end end frames.aliasReference = expandedAliases return frames end --[[Returns a new table with the parts of the parent frame added to the alias --]] function p.getAlias( aliasFrames, parentFrame ) -- If alias is just a name, return the parent frame with the new name if type( aliasFrames ) == 'string' then local expandedFrame = mw.clone( parentFrame ) expandedFrame.name = aliasFrames return { expandedFrame } end -- Single frame alias, put in list if aliasFrames.name then aliasFrames = { aliasFrames } end local expandedFrames = {} for i, aliasFrame in ipairs( aliasFrames ) do local expandedFrame if type( aliasFrame ) == 'string' then expandedFrame = { name = aliasFrame } else expandedFrame = cloneTable( aliasFrame ) end expandedFrame.title = parentFrame.title or expandedFrame.title expandedFrame.mod = parentFrame.mod or expandedFrame.mod expandedFrame.num = parentFrame.num or expandedFrame.num expandedFrame.text = parentFrame.text or expandedFrame.text expandedFrames[i] = expandedFrame end 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 function p.stringifyFrames( frames ) for i, frame in ipairs( frames ) do frames[i] = p.stringifyFrame( frame ) end return table.concat( frames, ';' ) end -- Splits up the frame text into its parts function p.makeFrame( frameText, mod ) -- Simple frame with no parts if not frameText:match( '[%[:,]' ) then return { mod = mod, name = mw.text.trim( frameText ), } end 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 } if frame.mod and vanilla[mw.ustring.lower( frame.mod )] or frame.mod == '' then frame.mod = nil end local nameStart = ( frameText:find( ':' ) or frameText:find( '%]' ) or 0 ) + 1 if nameStart - 1 == #frameText then nameStart = 1 end frame.name = frameText:sub( nameStart, ( frameText:find( '[,%[]', nameStart ) or 0 ) - 1 ) frame.num = math.floor( frameText:match( ',(%d+)' ) or 0 ) if frame.num == 0 then frame.num = nil end frame.text = frameText:match( '%[([^%]]+)%]$' ) return frame end function p.getParts( frameText, mod ) return p.makeFrame( frameText, mod ) end return p
Summary:
Please note that all contributions to WoopMC may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
WoopMC:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Templates used on this page:
Template:Template link general
(
edit
)
Template:Template link general
(
edit
)
Module:Arguments
(
edit
)
Module:Inventory slot/doc
(
edit
)
Module:Template link general
(
edit
)