VOOZH about

URL: https://minecraft.wiki/w/Module:Inventory_slot

⇱ Module:Inventory slot – Minecraft Wiki


Module:Inventory slot

From Minecraft Wiki
Jump to navigation Jump to search
Documentation[view] [edit] [history] [purge]Jump to code ↴

This module implements {{inventory slot}}.

Dependencies

[view] [edit] [history] [purge]The above documentation is transcluded from Module:Inventory slot/doc.
localp={}
-- Internationalization data
locali18n={
-- Name formats for pages and files
filename='Invicon $1',
legacyFilename='Grid $1',
modLink='Mods/$1/$2',
-- Dependencies
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)
-- When localizing, you might want to use a separate list of patterns
-- matching the prefixes’ grammatical forms depending on the language
prefixes={
any='Any',
matching='Matching',
damaged='Damaged',
unwaxed='Unwaxed',
},
-- List of suffixes that are usually stripped from links and tooltips
suffixes={
rev='Revision %d+',
-- berev = 'BE%d+',
-- jerev= 'JE%d+',
be='BE',
lce='LCE',
sm='SM',
damage='%d+'
},
}
p.i18n=i18n
-- Global dependencies and constants
localrandom=require(i18n.moduleRandom).random
localaliases=mw.loadData(i18n.moduleAliases)
localpageName=mw.title.getCurrentTitle().text
localvanilla={v=1,vanilla=1,mc=1,minecraft=1}
-- Auxilliary functions --
-- Performs a simple recursive clone of a table’s values.
-- Probably exists due to mw.clone() being unusable on tables from mw.loadData()
-- at the time (see the link to help.fandom.com above)
localfunctioncloneTable(origTable)
localnewTable={}
fork,vinpairs(origTable)do
iftype(v)=='table'then
v=cloneTable(v)
end
newTable[k]=v
end
returnnewTable
end
-- Merges a list, or inserts a string or table into a table,
-- depending on what the second argument happens to be
localfunctionmergeList(parentTable,content)
locali=#parentTable+1
ifcontent[1]then
-- Merge list into table
for_,vinipairs(content)do
parentTable[i]=v
i=i+1
end
else
-- Add strings or tables to table
parentTable[i]=content
end
end
-- Creates the HTML node for a given item.
-- The actual icon file is found and added here
localfunctionmakeItem(frame,args)
localitem=(mw.html.create('span')
:addClass('invslot-item')
:addClass(args.imgclass)
:cssText(args.imgstyle)
)
if(frame.nameor'')==''then
-- Empty frame, no icon to add
returnitem
end
-- Frame parameters
localtitle=frame.titleormw.text.trim(args.titleor'')
localmod=frame.mod
localname=frame.name
localnum=frame.num
localdescription=frame.text
-- Split the extension out of the frame’s name
localextension
ifname:match('%.gif')orname:match('%.png')then
extension=name:sub(-4)
name=name:sub(0,-5)
elseifname:match('%.webp')then
extension='.webp'
name=name:sub(0,-6)
else
extension='.png'
end
-- Determine the file name
localimg
ifmodthen
-- Legacy mod support
-- Comment out instead of deleting, as other wikis may find it useful
img=i18n.legacyFilename:gsub('%$1',name..' ('..mod..')')
else
-- Fall back to an individual image if the sprite is lacking
img=i18n.filename:gsub('%$1',name)
end
img=img..extension
-- Strip suffixes out
for_,suffixinpairs(i18n.suffixes)do
name=name:gsub(' '..suffix..'$','')
end
-- Determine the link’s target
locallink=args.linkor''
iflink==''then
ifmodthen
link=i18n.modLink:gsub('%$1',mod):gsub('%$2',name)
else
-- Strip the “Damaged” prefix out
link=name:gsub('^'..i18n.prefixes.damaged..' ','')
end
elseiflink:lower()=='none'then
-- Disable the link
link=nil
end
iflinkandlink:gsub('^%l',string.upper)==pageNamethen
link=nil
end
-- Tooltip titles. If JavaScript is not enabled, the slot will gracefully
-- degrade to a simplified title without minetip formatting
localformattedTitle
localplainTitle
iftitle==''then
-- If the title is not set, default to the slot’s name
plainTitle=name
elseiftitle:lower()~='none'then
-- Special character escapes
plainTitle=title:gsub('\\\\','\'):gsub('\\&','&')
-- The default title will have special formatting code stripped out
localformatPatterns={'&[0-9a-jl-qs-vyzr]','&#%x%x%x%x%x%x','&$%x%x%x'}
for_,formatPatterninipairs(formatPatterns)do
ifplainTitle:match(formatPattern)then
formattedTitle=title
plainTitle=plainTitle:gsub(formatPattern,'')
end
end
ifplainTitle==''then
-- If the title field only has formatting code, the frame’s name
-- is automatically used. For minetips it’s done by JavaScript
-- by appending the plain title.
plainTitle=name
else
-- Re-encode the 
plainTitle=plainTitle:gsub('\','\\'):gsub('&','&')
end
elseiflinkthen
-- Disable the tooltip that will otherwise appear with a link
formattedTitle=''
end
-- Minetips are controlled by custom HTML attributes.
-- See [[MediaWiki:Common.js]] for implementation in JavaScript
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.
localescapedTitle=(plainTitleor''):gsub('&','&')
-- Alt text
localaltText=img..': Inventory sprite for '..name..' in Minecraft as shown in-game'
iflinkthen
altText=altText..' linking to '..link
end
ifformattedTitleorplainTitleorlinkthen
altText=altText..' with description: '..(formattedTitleorplainTitleorlink)
ifdescriptionthen
altText=altText..' '..description:gsub('/',' ')
end
altText=altText:gsub('&[0-9a-jl-qs-wr]','')
end
-- Add the image
item:addClass('invslot-item-image')
:wikitext('[[File:',img,'|32x32px|link=',linkor'','|alt=',altText,'|',escapedTitle,']]')
-- Add the stack number, if present and in 2-999 range
ifnumandnum>1andnum<1000then
iflinkthen
item:wikitext('[[',link,'|')
end
localnumber=item
:tag('span')
:addClass('invslot-stacksize')
:attr{title=plainTitle}
:wikitext(num)
ifargs.numstylethen
number:cssText(args.numstyle)
end
iflinkthen
item:wikitext(']]')
end
end
-- The HTML node is now ready
returnitem
end
-- Publicly available functions --
-- Main entry point: Creates the whole slot
functionp.slot(f)
-- Incoming arguments
localargs=f.argsorf
iff==mw.getCurrentFrame()andargs[1]==nilthen
args=f:getParent().args
end
-- TODO: Add support for unexpanded frame sequences in table format
ifnotargs.parsedthen
-- Assumed to be a string, trim it
args[1]=mw.text.trim(args[1]or'')
end
-- Legacy mod support. Comment out instead of deleting; might be useful
-- for other wikis
-- TODO: Support multiple mod alias tables at once (like on RuMCW)
localmodData={
aliases=args.modaliasesor'',
default=args.mod
}
ifmodData.aliases~=''then
modData.aliases=mw.loadData('Module:'..modData.aliases)
else
modData.aliases=nil
end
ifargs.mod==''then
modData.default=nil
end
-- Get the frame sequence in table format
localframes
ifargs.parsedthen
-- Already parsed in some other module, such as Recipe table
frames=args[1]
elseifargs[1]~=''then
-- Parse the frame string
-- TODO: Make the “randomise” flag not hard-coded to invslot-large CSS class
-- (ostensibly for output slots) as not all output slots are large
localrandomise=args.class=='invslot-large'and'never'ornil
frames=p.parseFrameText(args[1],randomise,false,modData)
end
-- Create the slot node and add applicable styles
localbody=mw.html.create('span'):addClass('invslot'):css{['vertical-align']=args.align}
-- Is the slot animated?
localanimated=framesand#frames>1
ifanimatedthen
body:addClass('animated')
end
-- Default background
if(args.defaultor'')~=''then-- default background
body:addClass('invslot-default-'..string.lower(args.default):gsub(' ','-'))
end
-- Custom styles
body:addClass(args.class)
body:cssText(args.style)
--mw.logObject( frames )
ifnotframesor#frames==0then
-- Empty slot
returntostring(body)
end
-- We have frames, add them
localactiveFrame=frames.randomise==trueandrandom(#frames)or1
fori,frameinipairs(frames)do
localitem
ifframe[1]then
-- This is a subframe container. Each animation cycle of the slot
-- will show a subframe, one at a time.
-- Create a container node for subframes
item=body:tag('span'):addClass('animated-subframe')
localsubActiveFrame=frame.randomise==trueandrandom(#frame)or1
-- Add subframes to the note
forsI,sFrameinipairs(frame)do
localsItem=makeItem(sFrame,args)
item:node(sItem)
-- Set this subframe as active
ifsI==subActiveFramethen
sItem:addClass('animated-active')
end
end
else
-- A simple frame
item=makeItem(frame,args)
body:node(item)
end
ifi==activeFrameandanimatedthen
-- Set this frame as active, if we have multiple of them
item:addClass('animated-active')
end
end
-- The slot is ready
returntostring(body)
end
-- Splits a given text into fragments separated by semicolons that are not
-- inside square brackets. Originally written by AttemptToCallNil for the
-- Russian wiki.
-- It processes the text byte-by-byte due to being written under a much stricter
-- Lua runtime budget, with no LuaSandbox and mw.text.split being unperformant.
-- See also https://help.fandom.com/wiki/Extension:Scribunto#Known_issues_and_solutions
functionp.splitOnUnenclosedSemicolons(text)
localsemicolon,lbrace,rbrace=(";[]"):byte(1,3)
localnesting=false
localsplitStart=1
localframeIndex=1
localframes={}
forindex=1,text:len()do
localbyte=text:byte(index)
ifbyte==semicolonandnotnestingthen
frames[frameIndex]=text:sub(splitStart,index-1)
frameIndex=frameIndex+1
splitStart=index+1
elseifbyte==lbracethen
assert(notnesting,"Excessive square brackets found")
nesting=true
elseifbyte==rbracethen
assert(nesting,"Unbalanced square brackets found")
nesting=false
end
end
assert(notnesting,"Unbalanced square brackets found")
frames[frameIndex]=text:sub(splitStart,text:len())
forindex=1,#framesdo
frames[index]=(frames[index]:gsub("^%s+",""):gsub("%s+$",""))-- faster than mw.text.trim
end
returnframes
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.
-- Alias references are used in [[Module:Recipe table]] to create links and
-- lists of unique items.
functionp.parseFrameText(framesText,randomise,aliasReference,modData)
-- Frame sequences
localframes={randomise=randomise}
localsubframes={}
-- Is the current frame a subframe?
localsubframe
-- The list of expanded aliases, will be added to the frame sequence
-- if aliasReference is set to true AND if there are any aliases to expand.
localexpandedAliases
-- Split the frame string by semicolons (respecting square brackets)
localsplitFrames=p.splitOnUnenclosedSemicolons(framesText)
-- Iterate on frame fragments
fori,frameTextinipairs(splitFrames)do
-- Subframes are grouped by curly braces
frameText=frameText:gsub('^%s*{%s*',function()
subframe=true
return''
end)
ifsubframethen
-- Closing brace found
frameText=frameText:gsub('%s*}%s*$',function()
subframe='last'
return''
end)
end
-- Convert the frame text into table format, applying the default mod
-- if needed.
localframe=p.makeFrame(frameText,modDataandmodData.default)
-- Alias processing
-- TODO: Rework mod support to automatically load relevant alias tables,
-- for use on other wikis that may want it. This will allow supporting
-- multiple mod alias tables at once. Comment out instead of deleting!
localnewFrame=frame
ifaliasesormodData.aliasesthen
localid=frame.name
ifframe.modthen
-- is this really needed? RuMCW doesn’t add mod prefixes in mod aliases
id=frame.mod..':'..id
end
localalias=modDataandmodData.aliasesandmodData.aliases[id]or
aliasesandaliases[id]
ifaliasthen
-- Alias found, expand it
newFrame=p.getAlias(alias,frame)
-- Save the alias references, if asked
ifaliasReferencethen
-- The alias data includes the original unexpanded frame
-- and the number of frames it has expanded to.
-- The alias reference table is not sequential — indices for
-- each alias data object correspond to that alias’ first
-- (or only) expanded frame. Which is not added to the frame
-- sequence yet
localcurFrame=#frames+1
localaliasData={frame=frame,length=#newFrame}
ifsubframethen
-- Subframe containers will have their own
-- alias reference tables
ifnotsubframes.aliasReferencethen
subframes.aliasReference={}
end
subframes.aliasReference[#subframes+1]=aliasData
else
ifnotexpandedAliasesthen
expandedAliases={}
end
expandedAliases[curFrame]=aliasData
end
end
end
end
-- Alias processing ends here
-- Add frames and control randomization
ifsubframethen
-- Add the frame to the current subframe container
mergeList(subframes,newFrame)
-- Randomise starting frame for "Any *" aliases, as long as the
-- alias is the only subframe (and randomization is not disabled)
ifframes.randomise~='never'andsubframes.randomise==niland
frame.name:match('^'..i18n.prefixes.any..' ')
then
subframes.randomise=true
else
subframes.randomise=false
end
-- Disable randomization
ifframes.randomise~='never'then
frames.randomise=false
end
ifsubframe=='last'then
if#subframes==1or#splitFrames==iand#frames==0then
-- If the subframe container only has one expanded frame or
-- is the only frame in the whole sequence, its contents are
-- extracted into the main frame sequence
locallastFrame=#frames
mergeList(frames,subframes)
-- Inherit the randomise flag if it’s the only frame
if#splitFrames==1then
frames.randomise=subframes.randomise
end
-- Append alias reference data, if present
ifaliasReferenceandsubframes.aliasReferencethen
ifnotexpandedAliasesthen
expandedAliases={}
end
fori,aliasRefDatainpairs(subframes.aliasReference)do
expandedAliases[lastFrame+i]=aliasRefData
end
end
else
-- Add the subframe container to the frame sequence
table.insert(frames,subframes)
end
-- Finished processing this subframe container
subframes={}
subframe=nil
end
else
-- Randomize starting frame for "Any *" aliases, as long as the alias is the only frame
ifframes.randomise~='never'andframe.name:match('^'..i18n.prefixes.any..' ')then
frames.randomise=true
else
frames.randomise=false
end
-- Add the expanded frame(s) to the frame sequence
mergeList(frames,newFrame)
end
end
-- Add the alias reference, if we’re compiling one
frames.aliasReference=expandedAliases
-- The frame sequence is ready
returnframes
end
-- Applies parameters from the parent frame (such as title or text)
-- to the alias’ expansion
functionp.getAlias(aliasFrames,parentFrame)
-- If alias is just a name, return the parent frame with the new name
iftype(aliasFrames)=='string'then
localexpandedFrame=mw.clone(parentFrame)
expandedFrame.name=aliasFrames
return{expandedFrame}
end
-- Single frame alias, put in list
ifaliasFrames.namethen
aliasFrames={aliasFrames}
end
-- Common case: group alias
localexpandedFrames={}
fori,aliasFrameinipairs(aliasFrames)do
localexpandedFrame
iftype(aliasFrame)=='string'then
-- Simple expansion frame in string format
expandedFrame={name=aliasFrame}
else
-- Expansion frame in table format
-- As it’s loaded with mw.loadData, it must be cloned
-- before changing
expandedFrame=cloneTable(aliasFrame)
end
-- Apply the parent frame’s settings
expandedFrame.title=parentFrame.titleorexpandedFrame.title
expandedFrame.num=parentFrame.numorexpandedFrame.num
expandedFrame.text=parentFrame.textorexpandedFrame.text
-- Legacy mod support. Comment out instead of deleting
-- TODO: invert the priority for mod parameter, to allow
-- group mod aliases with vanilla items?
expandedFrame.mod=parentFrame.modorexpandedFrame.mod
expandedFrames[i]=expandedFrame
end
returnexpandedFrames
end
-- Convert the frame object back into string format
functionp.stringifyFrame(frame)
ifnotframe.namethen
return''
end
returnstring.format(
'[%s]%s:%s,%s[%s]',
frame.titleor'',
frame.modor'Minecraft',
frame.name,
frame.numor'',
frame.textor''
)
end
-- Convert the frame sequence into string format
functionp.stringifyFrames(frames)
fori,frameinipairs(frames)do
ifframe[1]then
-- Subframe container
-- As the format and the syntax are the same, process it recursively
frames[i]='{'..p.stringifyFrames(frame)..'}'
else
frames[i]=p.stringifyFrame(frame)
end
end
returntable.concat(frames,';')
end
-- Converts the frame text into a frame object
-- Full syntax: [Title]Mod:Name,Number[Text]
functionp.makeFrame(frameText,defaultMod)
-- Simple frame with no parts
ifnotframeText:match('[%[:,]')then
return{
mod=defaultMod,
name=mw.text.trim(frameText),
}
end
-- Complex frame
localframe={}
-- Title
localtitle,rest=frameText:match('^%s*%[([^%]]*)%]%s*(.*)')
iftitlethen
frame.title=title
frameText=rest
end
-- Additional tooltip text
localrest,text=frameText:match('([^%]]*)%s*%[([^%]]*)%]%s*$')
iftextthen
frame.text=text
frameText=rest
end
-- Legacy mod support
-- Comment out instead of deleting
localmod,rest=frameText:match('^([^:]+):%s*(.*)')
ifmodthen
ifnotvanilla[mod:lower()]then
frame.mod=mod
end
frameText=rest
else
frame.mod=defaultMod
frameText=frameText:gsub('^:','')
end
-- Name and stack size
-- The pattern will match the last comma, so you can use names with commas
-- like so: “Potatiesh, Greatstaff of the Peasant,1”
localname,num=frameText:match('(.*),%s*(%d+)')
ifnumthen
-- Number is set
frame.name=mw.text.trim(name)
frame.num=math.floor(num)
ifframe.num<2then
frame.num=nil
end
else
-- No number
frame.name=mw.text.trim(frameText)
end
-- The frame object is ready
returnframe
end
-- This line should be the last one:
returnp
Retrieved from "https://minecraft.wiki/w/Module:Inventory_slot?oldid=3634104"

Navigation menu