Module:Sprite: Difference between revisions

From Official Gamemode 4 Wiki
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),
__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))
}
}
local lSet = self.__settings


setmetatable(lSet, {__index=defaultSettings})
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


styles = {}
end
--[[styles["background-image"] = (settings.url and "url(" .. settings.url .. ")") or mw.getCurrentFrame():expandTemplate{
title = 'FileUrl',
args = { settings.image}
} ]]
styles["background-size"] = lSet.sheetWidth * lSet.scale .. 'px auto'


local t = lSet.size * lSet.scale .. 'px'
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


styles.height = t
if aliases[item].name ~= nil then
styles.width = t
local itemName = aliases[item].name
styles["vertical-align"] = lSet.align
self:setPosition(self.__source.ids[itemName].pos)
self.__styles = styles
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;


function Sprite:setItem(item)
if self.__source.ids[item] then
if self.__source.ids[item] then
self:setPosition(self.__source.ids[item].pos)
self:setPosition(self.__source.ids[item].pos)
if self.__source.ids[item].spriteSheet then
else
              local newSettings = require(types[self.__source.ids[item].spriteSheet]).settings
self:setPosition(nil) --will use default
              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


local pos = (pos or settings.pos) - 1
-- 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
self.__styles["background-position"] = '-' .. left .. 'px -' .. top .. 'px'
append("background-position", '-' .. left .. 'px -' .. top .. 'px')
append("mask-position", '-' .. left .. 'px -' .. top .. 'px')
append("-webkit-mask-position", '-' .. left .. 'px -' .. top .. 'px')


settings.pos = pos + 1
return table.concat( styles, "; " )
return self
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


local styles = {}
if self.__settings.enchanted == "true" then
for k,v in pairs(self.__styles) do
sprite:addClass("enchanted")
styles[#styles + 1] = k .. ":" .. v
end
end


sprite:cssText( table.concat( styles, "; " ) )
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

-- 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