Flattening nested layered icons

Place to post guides, observations, things related to modding that are not mods themselves.
AndrolGenhald
Long Handed Inserter
Long Handed Inserter
Posts: 61
Joined: Tue Mar 22, 2016 6:35 pm
Contact:

Flattening nested layered icons

Post by AndrolGenhald »

So in 0.15 I checked out the way barreling is implemented with the icons property instead of icon (apparently this has actually been around for a while, there's just no documentation), long story short I did some testing and it doesn't support nesting. I thought about doing a feature request, but after some thought I decided that with a little math and a little trial and error I could just flatten it myself:

Code: Select all

local function flatten_icons(icons, scale, shift)
	local icons_new = {}
	for i,spec in pairs(icons) do
		spec = table.deepcopy(spec)

		if not spec.scale then
			spec.scale = 1
		end
		spec.scale = scale * spec.scale

		if not spec.shift then
			spec.shift = {0, 0}
		end
		spec.shift = {shift[1] + spec.shift[1] * scale, shift[2] + spec.shift[2] * scale}

		if type(spec.icon) == "table" then
			for j,flattened in pairs(flatten_icons(spec.icon, spec.scale, spec.shift)) do
				table.insert(icons_new, flattened)
			end
		else
			table.insert(icons_new, spec)
		end
	end
	return icons_new
end

function flatten_icons_spec(icons)
	return flatten_icons(icons, 1, {0, 0})
end
Usage:

Code: Select all

data:extend({
	{
		type = "item",
		...
		icons = flatten_icons_spec({
			{
				icon = "some icon",
			},
			{
				icon = {
					{icon = "some icon, scale = 0.75},
				},
				scale = 0.5,
				shift = {4, -4},
			},
			{
				icon = data.raw.item.someitem.icons,
				scale = 0.9,
				shift = {-1, 2},
			},
			etc,
		}),
		...,
	},
})
(I wrote half of that off the top of my head, hopefully it's correct, but you should at least get the idea)

So if anyone else ever ends up wanting to use a layered icon as a layer in another layered icon maybe you'll find that useful. I tested nesting 2 layers deep and it worked well (although sometimes there where pixels off by 1, not sure if that's fixable without a base game implementation). I didn't bother doing anything with tints as I didn't need it (do they even support alpha? I would expect them to but I didn't test), but if anyone would find it useful I wouldn't mind having an excuse to complete it.

As a side note, I fully expected barreling to break if I made a fluid with a layered icon, but it looks like someone thought ahead:

Code: Select all

if (fluid.auto_barrel == nil or fluid.auto_barrel) and fluid.icon then
Unfortunately that still means that you can't barrel a fluid with a layered icon, so I may make a feature request after all.
Post Reply

Return to “Modding discussion”