Module:Sprite: Difference between revisions
Jump to navigation
Jump to search
(Removed bug that resulted in using the wrong sprite if the name was unkown and setPosition calculating the right position and changing the css accordingly but storing it wrong internaly (of by 1)) |
m (hm) |
||
(94 intermediate revisions by 4 users not shown) | |||
Line 2: | Line 2: | ||
local Sprite = {} | local Sprite = {} | ||
local aliasData = { | |||
vanillaAliases = [[Module:InventorySlot/Aliases]], | |||
gm4Aliases = [[Module:Gm4Sprite/Aliases]], | |||
effectAliases = [[Module:EffectSprite/Aliases]], | |||
trophyAliases = [[Module:TrophySprite/Aliases]] | |||
} | |||
Sprite.aliasData = aliasData | |||
local vanillaAliases = mw.loadData( aliasData.vanillaAliases ) | |||
local gm4Aliases = mw.loadData( aliasData.gm4Aliases ) | |||
local effectAliases = mw.loadData( aliasData.effectAliases ) | |||
local trophyAliases = mw.loadData( aliasData.trophyAliases ) | |||
local aliases | |||
local types = { | local types = { | ||
inventory = [[Module:InvSprite]], | inventory = [[Module:InvSprite]], | ||
gm4 = [[Module:Gm4Sprite]], | |||
effect = [[Module:EffectSprite]], | |||
trophy = [[Module:TrophySprite]], | |||
gm4RP = [[Module:Gm4RPSprite]] | |||
} | } | ||
Line 14: | Line 32: | ||
align = 'text-top' | align = 'text-top' | ||
} | } | ||
function getImage( image ) | |||
if not(image) then return nil end | |||
local file = mw.title.new(image,"File").file | |||
if not(file.exists) then return nil end | |||
local f = mw.getCurrentFrame() | |||
local t = { | |||
url = f:expandTemplate{ | |||
title = 'FileUrl', | |||
args = {image} | |||
} | |||
} | |||
setmetatable(t, {__index = file}) | |||
return t | |||
end | |||
function getSpriteSheet( image ) | |||
if not(image) then return nil end | |||
local f = mw.getCurrentFrame() | |||
local t = { | |||
url = f:expandTemplate{ | |||
title = 'SpriteSheet', | |||
args = {image} | |||
} | |||
} | |||
if t == "" then return nil end | |||
return t | |||
end | |||
function Sprite:new (type) | function Sprite:new (type) | ||
source = types[type] | local source = types[type] | ||
if not(source) then | if not(source) then | ||
error("Unknown type: " .. tostring(type)) | error("Unknown type: " .. tostring(type)) | ||
end | end | ||
o = { | o = { | ||
__source = require(source), | |||
} | } | ||
setmetatable(o, {__index = self}) | setmetatable(o, {__index = self}) | ||
o:load() | o:load() | ||
return o | |||
end | |||
Sprite.Custom = {} | |||
setmetatable(Sprite.Custom, {__index = Sprite}) | |||
local CustomSprite = Sprite.Custom | |||
function CustomSprite:new(name, imagename) | |||
local image = getImage(imagename) | |||
if not(image) then | |||
error("Couldn't find image: " .. tostring(imagename)) | |||
end | |||
local size = image.width | |||
o = { | |||
__source = { | |||
settings = {} | |||
}, | |||
__settings={ | |||
size = size, | |||
sheetsize = 1, | |||
image = image, | |||
sheetWidth = size, | |||
tiles = 1, | |||
name = name, | |||
title = title, | |||
lore = lore, | |||
enchanted = enchanted, | |||
link = link | |||
} | |||
} | |||
setmetatable(o, {__index = self}) | |||
setmetatable(o.__settings, {__index=defaultSettings}) | |||
return o | return o | ||
end | end | ||
Line 36: | Line 125: | ||
scale = settings.scale, | scale = settings.scale, | ||
autoScale = settings.autoscale, | autoScale = settings.autoscale, | ||
image = (settings.image and getImage(settings.image)) | |||
-- or (settings.spriteSheet and getSpriteSheet(settings.spriteSheet)) | |||
} | } | ||
setmetatable( | setmetatable(self.__settings, {__index=defaultSettings}) | ||
end | |||
function Sprite:setItem(item, type) | |||
-- set aliases | |||
if type == "gm4" or type == "gm4RP" then | |||
aliases = gm4Aliases | |||
elseif type == "effect" then | |||
aliases = effectAliases | |||
elseif type == "trophy" then | |||
aliases = trophyAliases | |||
else | |||
aliases = vanillaAliases | |||
end | |||
-- js-less plaintext title | |||
self.__settings.name = item | |||
-- js-modified color title with lore | |||
if aliases[item] then | |||
if aliases[item].text then | |||
self.__settings.lore = aliases[item].text | |||
end | |||
if aliases[item].title then | |||
if #aliases[item].title == 2 then | |||
self.__settings.title= aliases[item].title .. aliases[item].name | |||
else | |||
self.__settings.title = aliases[item].title | |||
end | |||
elseif aliases[item].name then | |||
self.__settings.title = aliases[item].name | |||
end | |||
if aliases[item].enchanted then | |||
self.__settings.enchanted = aliases[item].enchanted | |||
end | |||
if aliases[item].name ~= nil then | |||
local itemName = aliases[item].name | |||
self:setPosition(self.__source.ids[itemName].pos) | |||
if self.__source.ids[itemName].spriteSheet then | |||
end | local newSettings = require(types[self.__source.ids[itemName].spriteSheet]).settings | ||
self.__settings.classname = newSettings.classname | |||
self.__settings.size = newSettings.size | |||
self.__settings.tiles = newSettings.sheetsize / newSettings.size | |||
self.__settings.scale = newSettings.scale | |||
self.__settings.autoScale = newSettings.autoscale | |||
end | |||
end | |||
else | |||
self.__settings.title = item; | |||
if self.__source.ids[item] then | |||
self:setPosition(self.__source.ids[item].pos) | |||
if self.__source.ids[item].spriteSheet then | |||
local newSettings = require(types[self.__source.ids[item].spriteSheet]).settings | |||
self.__settings.classname = newSettings.classname | |||
self.__settings.size = newSettings.size | |||
self.__settings.tiles = newSettings.sheetsize / newSettings.size | |||
self.__settings.scale = newSettings.scale | |||
self.__settings.autoScale = newSettings.autoscale | |||
end | |||
else | |||
self:setPosition(nil) --will use default | |||
end | |||
end | end | ||
return self | return self | ||
end | end | ||
function Sprite:Item(item) | function Sprite:Item(item, type) | ||
local sprite = {} | local sprite = {} | ||
setmetatable(sprite, {__index = self}) | setmetatable(sprite, {__index = self}) | ||
Line 72: | Line 206: | ||
setmetatable(settings, {__index = self.__settings}) | setmetatable(settings, {__index = self.__settings}) | ||
sprite.__settings = settings | sprite.__settings = settings | ||
return sprite:setItem(item) | return sprite:setItem(item, type) | ||
end | end | ||
function Sprite:setPosition(pos) | function Sprite:setPosition(pos) | ||
self.__settings.pos = pos or self.__settings.pos | |||
return self | |||
end | |||
function Sprite:SetScale(scale) | |||
self.__settings.scale = scale | |||
return self | |||
end | |||
function Sprite:SetSize(size) | |||
self.__settings.scale = size / self.__settings.size | |||
return self | |||
end | |||
function Sprite:SetTitle(name) | |||
self.__settings.title = name | |||
return self | |||
end | |||
function Sprite:SetLore(text) | |||
self.__settings.lore = text | |||
return self | |||
end | |||
function Sprite:HideTooltip() | |||
self.__settings.hideTooltip = true | |||
return self | |||
end | |||
function Sprite:calculateStyles() | |||
styles = {} | |||
function append(key, value) if value ~= nil then styles[#styles+1]=key .. ": " .. value end end | |||
local settings = self.__settings | local settings = self.__settings | ||
-- has to be done first, otherwise the possition is overriden in chrome | |||
if settings.image then | |||
append("background", settings.image.url) | |||
append("mask-image", settings.image.url) | |||
append("-webkit-mask-image", settings.image.url) | |||
end | |||
append ("background-size", settings.sheetWidth * settings.scale .. 'px auto') | |||
append ("mask-size", settings.sheetWidth * settings.scale .. 'px auto') | |||
append ("-webkit-mask-size", settings.sheetWidth * settings.scale .. 'px auto') | |||
local t = settings.size * settings.scale .. 'px' | |||
append ("height", t) | |||
append ("width", t) | |||
append ("vertical-align", settings.align) | |||
local pos = self.__settings.pos - 1 | |||
local left = pos % settings.tiles * settings.size * settings.scale | local left = pos % settings.tiles * settings.size * settings.scale | ||
local top = math.floor( pos / settings.tiles ) * settings.size * settings.scale | local top = math.floor( pos / settings.tiles ) * settings.size * settings.scale | ||
append("background-position", '-' .. left .. 'px -' .. top .. 'px') | |||
append("mask-position", '-' .. left .. 'px -' .. top .. 'px') | |||
append("-webkit-mask-position", '-' .. left .. 'px -' .. top .. 'px') | |||
return table.concat( styles, "; " ) | |||
end | end | ||
Line 91: | Line 274: | ||
local sprite | local sprite | ||
if html then | if html then | ||
sprite = html:tag("div") | if type(html) == "string" then | ||
sprite = mw.html.create(html) | |||
else | |||
sprite = html:tag("div") | |||
end | |||
else | else | ||
sprite = mw.html.create("div") | sprite = mw.html.create("div") | ||
Line 97: | Line 284: | ||
sprite:addClass("sprite") | sprite:addClass("sprite") | ||
if self.__settings.hideTooltip ~= true then | |||
sprite:addClass("masterTooltip") | |||
end | |||
local source = self.__source | local source = self.__source | ||
sprite:addClass(source.settings.classname) | sprite:addClass(self.__settings.classname or source.settings.classname) | ||
if self.__settings.hideTooltip ~= true then | |||
sprite:attr( "title", self.__settings.name ) | |||
end | |||
sprite:attr( "data-title", self.__settings.title ) | |||
if self.__settings.lore then | |||
sprite:attr( "data-lore", self.__settings.lore ) | |||
end | |||
if self.__settings.enchanted == "true" then | |||
sprite:addClass("enchanted") | |||
end | end | ||
sprite:cssText( | local styles = self:calculateStyles() | ||
sprite:cssText( styles ) | |||
if self.__settings.link then | |||
sprite = html:tag("span") | |||
local link = self.__settings.link | |||
if link:sub ( 1,1 ) == '[' then | |||
local parentDiv = mw.html.create("a"):attr("href",link:sub ( 2,#link-1 )) | |||
elseif link:sub ( 1,1 ) == '#' then | |||
local section_id = self.__source.ids[itemName].section | |||
for index, tab in pairs(self.__source.sections) do | |||
if tab.id == section_id then | |||
local parentDiv = mw.html.create("a"):attr("href","/" .. tab.name .. "/" .. link:sub ( 2,#link )) | |||
end | |||
end | |||
elseif string.match(link, "%#") then | |||
local parentDiv = mw.html.create("a"):attr("href","/" .. link) | |||
else | |||
local parentDiv = mw.html.create("a"):attr("href","/#" .. link) | |||
end | |||
parentDiv:node(sprite) | |||
return parentDiv | |||
end | |||
return sprite | return sprite |
Latest revision as of 23:50, 3 March 2024
See Also
-- Based on work by the MC wiki: https://minecraft.gamepedia.com/ and https://minecraft.gamepedia.com/Module:Sprite
local Sprite = {}
local aliasData = {
vanillaAliases = [[Module:InventorySlot/Aliases]],
gm4Aliases = [[Module:Gm4Sprite/Aliases]],
effectAliases = [[Module:EffectSprite/Aliases]],
trophyAliases = [[Module:TrophySprite/Aliases]]
}
Sprite.aliasData = aliasData
local vanillaAliases = mw.loadData( aliasData.vanillaAliases )
local gm4Aliases = mw.loadData( aliasData.gm4Aliases )
local effectAliases = mw.loadData( aliasData.effectAliases )
local trophyAliases = mw.loadData( aliasData.trophyAliases )
local aliases
local types = {
inventory = [[Module:InvSprite]],
gm4 = [[Module:Gm4Sprite]],
effect = [[Module:EffectSprite]],
trophy = [[Module:TrophySprite]],
gm4RP = [[Module:Gm4RPSprite]]
}
local defaultSettings = {
scale = 1,
sheetsize = 256,
size = 16,
pos = 1,
align = 'text-top'
}
function getImage( image )
if not(image) then return nil end
local file = mw.title.new(image,"File").file
if not(file.exists) then return nil end
local f = mw.getCurrentFrame()
local t = {
url = f:expandTemplate{
title = 'FileUrl',
args = {image}
}
}
setmetatable(t, {__index = file})
return t
end
function getSpriteSheet( image )
if not(image) then return nil end
local f = mw.getCurrentFrame()
local t = {
url = f:expandTemplate{
title = 'SpriteSheet',
args = {image}
}
}
if t == "" then return nil end
return t
end
function Sprite:new (type)
local source = types[type]
if not(source) then
error("Unknown type: " .. tostring(type))
end
o = {
__source = require(source),
}
setmetatable(o, {__index = self})
o:load()
return o
end
Sprite.Custom = {}
setmetatable(Sprite.Custom, {__index = Sprite})
local CustomSprite = Sprite.Custom
function CustomSprite:new(name, imagename)
local image = getImage(imagename)
if not(image) then
error("Couldn't find image: " .. tostring(imagename))
end
local size = image.width
o = {
__source = {
settings = {}
},
__settings={
size = size,
sheetsize = 1,
image = image,
sheetWidth = size,
tiles = 1,
name = name,
title = title,
lore = lore,
enchanted = enchanted,
link = link
}
}
setmetatable(o, {__index = self})
setmetatable(o.__settings, {__index=defaultSettings})
return o
end
function Sprite:load()
local settings = self.__source.settings
self.__settings = {
size = settings.size,
sheetWidth = settings.sheetsize,
tiles = settings.sheetsize / settings.size,
scale = settings.scale,
autoScale = settings.autoscale,
image = (settings.image and getImage(settings.image))
-- or (settings.spriteSheet and getSpriteSheet(settings.spriteSheet))
}
setmetatable(self.__settings, {__index=defaultSettings})
end
function Sprite:setItem(item, type)
-- set aliases
if type == "gm4" or type == "gm4RP" then
aliases = gm4Aliases
elseif type == "effect" then
aliases = effectAliases
elseif type == "trophy" then
aliases = trophyAliases
else
aliases = vanillaAliases
end
-- js-less plaintext title
self.__settings.name = item
-- js-modified color title with lore
if aliases[item] then
if aliases[item].text then
self.__settings.lore = aliases[item].text
end
if aliases[item].title then
if #aliases[item].title == 2 then
self.__settings.title= aliases[item].title .. aliases[item].name
else
self.__settings.title = aliases[item].title
end
elseif aliases[item].name then
self.__settings.title = aliases[item].name
end
if aliases[item].enchanted then
self.__settings.enchanted = aliases[item].enchanted
end
if aliases[item].name ~= nil then
local itemName = aliases[item].name
self:setPosition(self.__source.ids[itemName].pos)
if self.__source.ids[itemName].spriteSheet then
local newSettings = require(types[self.__source.ids[itemName].spriteSheet]).settings
self.__settings.classname = newSettings.classname
self.__settings.size = newSettings.size
self.__settings.tiles = newSettings.sheetsize / newSettings.size
self.__settings.scale = newSettings.scale
self.__settings.autoScale = newSettings.autoscale
end
end
else
self.__settings.title = item;
if self.__source.ids[item] then
self:setPosition(self.__source.ids[item].pos)
if self.__source.ids[item].spriteSheet then
local newSettings = require(types[self.__source.ids[item].spriteSheet]).settings
self.__settings.classname = newSettings.classname
self.__settings.size = newSettings.size
self.__settings.tiles = newSettings.sheetsize / newSettings.size
self.__settings.scale = newSettings.scale
self.__settings.autoScale = newSettings.autoscale
end
else
self:setPosition(nil) --will use default
end
end
return self
end
function Sprite:Item(item, type)
local sprite = {}
setmetatable(sprite, {__index = self})
local settings = {}
setmetatable(settings, {__index = self.__settings})
sprite.__settings = settings
return sprite:setItem(item, type)
end
function Sprite:setPosition(pos)
self.__settings.pos = pos or self.__settings.pos
return self
end
function Sprite:SetScale(scale)
self.__settings.scale = scale
return self
end
function Sprite:SetSize(size)
self.__settings.scale = size / self.__settings.size
return self
end
function Sprite:SetTitle(name)
self.__settings.title = name
return self
end
function Sprite:SetLore(text)
self.__settings.lore = text
return self
end
function Sprite:HideTooltip()
self.__settings.hideTooltip = true
return self
end
function Sprite:calculateStyles()
styles = {}
function append(key, value) if value ~= nil then styles[#styles+1]=key .. ": " .. value end end
local settings = self.__settings
-- has to be done first, otherwise the possition is overriden in chrome
if settings.image then
append("background", settings.image.url)
append("mask-image", settings.image.url)
append("-webkit-mask-image", settings.image.url)
end
append ("background-size", settings.sheetWidth * settings.scale .. 'px auto')
append ("mask-size", settings.sheetWidth * settings.scale .. 'px auto')
append ("-webkit-mask-size", settings.sheetWidth * settings.scale .. 'px auto')
local t = settings.size * settings.scale .. 'px'
append ("height", t)
append ("width", t)
append ("vertical-align", settings.align)
local pos = self.__settings.pos - 1
local left = pos % settings.tiles * settings.size * settings.scale
local top = math.floor( pos / settings.tiles ) * settings.size * settings.scale
append("background-position", '-' .. left .. 'px -' .. top .. 'px')
append("mask-position", '-' .. left .. 'px -' .. top .. 'px')
append("-webkit-mask-position", '-' .. left .. 'px -' .. top .. 'px')
return table.concat( styles, "; " )
end
function Sprite:GenerateHTML (html)
local sprite
if html then
if type(html) == "string" then
sprite = mw.html.create(html)
else
sprite = html:tag("div")
end
else
sprite = mw.html.create("div")
end
sprite:addClass("sprite")
if self.__settings.hideTooltip ~= true then
sprite:addClass("masterTooltip")
end
local source = self.__source
sprite:addClass(self.__settings.classname or source.settings.classname)
if self.__settings.hideTooltip ~= true then
sprite:attr( "title", self.__settings.name )
end
sprite:attr( "data-title", self.__settings.title )
if self.__settings.lore then
sprite:attr( "data-lore", self.__settings.lore )
end
if self.__settings.enchanted == "true" then
sprite:addClass("enchanted")
end
local styles = self:calculateStyles()
sprite:cssText( styles )
if self.__settings.link then
sprite = html:tag("span")
local link = self.__settings.link
if link:sub ( 1,1 ) == '[' then
local parentDiv = mw.html.create("a"):attr("href",link:sub ( 2,#link-1 ))
elseif link:sub ( 1,1 ) == '#' then
local section_id = self.__source.ids[itemName].section
for index, tab in pairs(self.__source.sections) do
if tab.id == section_id then
local parentDiv = mw.html.create("a"):attr("href","/" .. tab.name .. "/" .. link:sub ( 2,#link ))
end
end
elseif string.match(link, "%#") then
local parentDiv = mw.html.create("a"):attr("href","/" .. link)
else
local parentDiv = mw.html.create("a"):attr("href","/#" .. link)
end
parentDiv:node(sprite)
return parentDiv
end
return sprite
end
return Sprite