#!/usr/bin/env lua editor_sprites= {foliage={{sprite=192, height=2}, -- Regular European shrub 1 {sprite=193, height=2}, -- Ground plant, green 1 {sprite=194, height=2}, -- Bush {sprite=195, height=2}, -- Ground plant, red flowers {sprite=196, height=2}, -- Shrub {sprite=197, height=4}, -- Dead tree (very high) {sprite=198, height=2}, -- Low ground plant {sprite=199, height=2}, -- Regular European shrub 2 {sprite=200, height=2}, -- Ground plant, flowers {sprite=201, height=1}, -- Flowerbed East/South {sprite=202, height=1}, -- Flowerbed West/South {sprite=203, height=1}, -- Flowerbed West/North {sprite=204, height=1} -- Flowerbed North/South }, hederow={{sprite=176, height=2}, -- Hedge West-North {sprite=177, height=2}, -- Hedge West-South {sprite=178, height=2}, -- Hedge East-South {sprite=179, height=2}, -- Hedge East-North {sprite=180, height=2}, -- Hedge West-East {sprite=181, height=2}, -- Hedge North-South {sprite=182, height=2}, -- Hedge East-West-South {sprite=183, height=2}, -- Hedge East-West-North {sprite=184, height=2}, -- Hedge West-North-South {sprite=185, height=2}, -- Hedge East-North-South {sprite=186, height=2}, -- Hedge East-West-North-South {sprite=187, height=2}, -- Hedge North-South with shrub {sprite=188, height=2}, -- Hedge North-South with holes {sprite=189, height=2}, -- Hedge East-West with shrub 1 {sprite=190, height=2}, -- Hedge East-West with holes {sprite=191, height=2}, -- Hedge East-West with shrub 2 }, pond={{sprite= 60, height=1}, -- South edge of a pond {sprite= 65, height=1}, -- West edge of a pond {sprite= 68, height=1}, -- North edge of a pond {sprite= 78, height=1}, -- East edge of a pond {sprite= 59, height=1}, -- South-West corner of a pond {sprite= 77, height=1}, -- North-East corner of a pond {sprite= 79, height=1}, -- South-East corner of a pond {sprite= 80, height=1}, -- North-West corner of a pond {sprite= 69, height=1}, -- Water tile of a pond {sprite= 71, height=1}, -- Water tile of a pond with water lilies {sprite= 72, height=2}, -- Water tile of a pond with water plant 1 {sprite= 73, height=2} -- Water tile of a pond with water plant 2 }, inside={{sprite= 16, height=1}, -- Dark big checker pattern tile {sprite= 17, height=1}, -- Dark blue/purple carpet tile {sprite= 70, height=1}, -- Duplicate of 017 {sprite= 18, height=1}, -- Red-Blue floor tile 1 {sprite= 19, height=1}, -- Red-Blue floor tile 2 {sprite= 23, height=1}, -- Red-Blue floor tile 3 {sprite= 20, height=1}, -- Wooden floor tile {sprite= 21, height=1}, -- Small checker pattern tile {sprite= 22, height=1}, -- Big checker pattern tile {sprite= 66, height=1}, -- Floor tile with light center {sprite= 76, height=1} -- Floor tile with light center and corners }, outside={{sprite= 1, height=1}, -- Grass tile 1 {sprite= 2, height=1}, -- Grass tile 2 {sprite= 3, height=1}, -- Grass tile 3 {sprite= 4, height=1}, -- Light concrete tile {sprite= 15, height=1}, -- Concrete tile {sprite= 5, height=1}, -- Dark concrete tile {sprite= 6, height=1}, -- Grass tile with South-East concrete corner {sprite= 8, height=1}, -- Grass tile with South-West concrete corner {sprite= 10, height=1}, -- Grass tile with North-West concrete corner {sprite= 12, height=1}, -- Grass tile with North-East concrete corner {sprite= 7, height=1}, -- Grass tile with South concrete edge {sprite= 9, height=1}, -- Grass tile with West concrete edge {sprite= 11, height=1}, -- Grass tile with North concrete edge {sprite= 13, height=1}, -- Grass tile with East concrete edge {sprite= 14, height=1}, -- Concrete tile with North-East grass corner {sprite= 61, height=1}, -- Concrete tile with South-West grass corner {sprite= 62, height=1}, -- Concrete tile with South-East grass corner {sprite= 63, height=1}, -- Concrete tile with North-West grass corner {sprite= 64, height=1}, -- Grass tile with rocks {sprite=205, height=1}, -- Fully cracked garden marble tile {sprite=206, height=1}, -- Broken garden marble tile {sprite=207, height=1}, -- Partially cracked garden marble tile {sprite=208, height=1}, -- Garden marble tile {sprite=209, height=2}, -- Lamp post pointing East {sprite=210, height=2}, -- Lamp post pointing South }, road={{sprite= 41, height=1}, -- Road with white discontinuous line North-South {sprite= 42, height=1}, -- Road with double yellow lines at West with black orthogonal lines {sprite= 43, height=1}, -- Road with double yellow lines at West edge {sprite= 44, height=1}, -- Road with double yellow lines at West edge merging at North {sprite= 45, height=1}, -- Road with double yellow lines at West edge merging at South {sprite= 46, height=1}, -- Duplicate of 045 {sprite= 47, height=1}, -- Road with red line at East linked to yellow discontinuous line at South {sprite= 48, height=1}, -- Road with red line at East linked to yellow discontinuous line at North {sprite= 49, height=1}, -- Road with red braking line at the East pointing to the West {sprite= 50, height=1}, -- Road with grey edge at the East {sprite= 51, height=1}, -- Road with double yellow lines at East edge {sprite= 52, height=1}, -- Road with double yellow lines at East with black orthogonal lines {sprite= 53, height=1}, -- Road with double yellow lines at East edge merging at the south {sprite= 54, height=1}, -- Duplicate of 052 {sprite= 55, height=1}, -- Road with red braking line at the West pointing to the East {sprite= 56, height=1}, -- Road with red line at West linked to yellow discontinuous line at North {sprite= 57, height=1}, -- Road with red line at West linked to yellow discontinuous line at South {sprite= 58, height=1}, -- Road with grey edge at the West }, ["north wall"]={{sprites={{sprite=159, xpos=1, ypos=1}, -- External doorway North outside left part {sprite=157, xpos=3, ypos=1}, -- External doorway North outside right part }, height=3}, {sprites={{sprite=163, xpos=1, ypos=1}, -- External doorway North inside left part {sprite=161, xpos=3, ypos=1}, -- External doorway North inside right part }, height=3}, {sprite=114, height=2}, -- External North wall outside {sprite=116, height=2}, -- External North wall outside left part of window {sprite=120, height=2}, -- External North wall with window glass {sprite=118, height=2}, -- External North wall outside right part of window {sprite=122, height=2}, -- External North wall inside {sprite=124, height=2}, -- External North wall inside left part of window {sprite=126, height=2}, -- External North wall inside right part of window }, ["west wall"]={{sprites={{sprite=158, xpos=1, ypos=3}, -- External doorway West outside left part {sprite=160, xpos=1, ypos=1}, -- External doorway West outside right part }, height=3}, {sprites={{sprite=162, xpos=1, ypos=3}, -- External doorway West inside left part {sprite=164, xpos=1, ypos=1}, -- External doorway West inside right part }, height=3}, {sprite=115, height=2}, -- External West wall outside {sprite=119, height=2}, -- External West wall outside left part of window {sprite=121, height=2}, -- External West wall with window glass {sprite=117, height=2}, -- External West wall outside right part of window {sprite=123, height=2}, -- External West wall inside {sprite=127, height=2}, -- External West wall inside left part of window {sprite=125, height=2}, -- External West wall inside right part of window }, helipad={{sprites={{sprite=5, xpos=1, ypos=1}, {sprite=5, xpos=2, ypos=1}, {sprite=5, xpos=3, ypos=1}, {sprite=5, xpos=4, ypos=1}, {sprite=5, xpos=5, ypos=1}, {sprite=5, xpos=1, ypos=2}, {sprite=5, xpos=1, ypos=3}, {sprite=5, xpos=1, ypos=4}, {sprite=5, xpos=1, ypos=5}, {sprite=5, xpos=2, ypos=5}, {sprite=5, xpos=3, ypos=5}, {sprite=5, xpos=4, ypos=5}, {sprite=5, xpos=5, ypos=5}, {sprite=5, xpos=5, ypos=2}, {sprite=5, xpos=5, ypos=3}, {sprite=5, xpos=5, ypos=4}, {sprite=5, xpos=3, ypos=2}, {sprite=5, xpos=3, ypos=4}, {sprite=4, xpos=2, ypos=2}, {sprite=4, xpos=2, ypos=3}, {sprite=4, xpos=2, ypos=4}, {sprite=4, xpos=4, ypos=2}, {sprite=4, xpos=4, ypos=3}, {sprite=4, xpos=4, ypos=4}, {sprite=4, xpos=3, ypos=3} }, height=3} } } local MAX_HEIGHT = 4 -- Biggest height in above sprites --! Normalize the editor sprite in the table to always have a 'sprites' field, as well as have sizes and a column width (for the display). --!param (table) Sprite from the editor_sprites table. --!return (table 'sprites', 'xsize', 'ysize', 'width', and 'height') function normalize_edit_sprite(spr) assert(MAX_HEIGHT >= spr.height) -- Verify that sprite fits in the maximum height. if spr.sprites == nil then -- {spritex=xxx, height=y} case return {sprites={sprite=spr.sprite, xpos=1, ypos=1}, xsize=1, ysize=1, width=2, height=spr.height} else -- {sprites={...}, height=y} case, compute sizes, and width local xsize=1 local ysize=1 for _, sp in ipairs(spr.sprites) do if sp.xpos > xsize then xsize = sp.xpos end if sp.ypos > ysize then ysize = sp.ypos end end local width = xsize if width < ysize then width = ysize end return {sprites=spr.sprites, xsize=xsize, ysize=ysize, width = width + 1, height=spr.height} end end --!Decide the highest possible placement for 'width' columns. --!param cols (list int) First available position in each column, higher number is lower. --!param width (int) Required width as number of columns. --!return (int, int) Starting column and placement height. function get_highest_rowcol(cols, width) local best = cols[1] + 100000 local best_col = 0 for left = 1, #cols - width + 1 do -- Try starting in each column. if cols[left] < best then -- First column is potentially better. local top = cols[left] for i = 1, width - 1 do if top < cols[left + i] then top = cols[left + i] if top >= best then break end -- i-th column breaks improvement. end end if top < best then best = top best_col = left end end end return best_col, best end --! Layout buttons from a tab of editor sprites. --!param esprs (list) Editor sprite tab to layout. --!param num_cols (int) Number of columns available in the layout. --!return (list) Sprites with button positions in ('column', 'row'). function layout_buttons(esprs, num_cols) local buttons = {} local cols = {} for i = 1, num_cols do cols[i] = 1 end for hgt = MAX_HEIGHT, 1, -1 do -- Fit highest sprites first. for _, espr in ipairs(esprs) do espr = normalize_edit_sprite(espr) if espr.height == hgt then local spr_col, spr_height = get_highest_rowcol(cols, espr.width) buttons[#buttons + 1] = espr buttons[#buttons].column = spr_col buttons[#buttons].row = spr_height for i = spr_col, spr_col + espr.width - 1 do -- Update height in the affected columns assert(cols[i] <= spr_height) cols[i] = spr_height + hgt end end end end return buttons end for name, sprs in pairs(editor_sprites) do local buttons = layout_buttons(sprs, 6) print(name) for _, button in ipairs(buttons) do print("col " .. button.column .. " y " .. button.row .. " width " .. button.width .. " height " .. button.height) end end