diff --git a/data/voxel_heights.lua b/data/voxel_heights.lua index 55bec61..a3f6975 100644 --- a/data/voxel_heights.lua +++ b/data/voxel_heights.lua @@ -2140,6 +2140,85 @@ return { -- placement. buildings = { OVERWORLD = { + -- assets/docs/buildings/B30: the POKEMON TOWER -- the one drawing + -- in the catalogue that STRADDLES A MAP BOUNDARY. Twelve of its + -- twenty rows stand in ROUTE_10's last rows (the 64px purple roof + -- band plus two window courses); the other eight -- five more + -- courses and the base with the door -- are on LAVENDER_TOWN, + -- where the tower begins at tile row 0. Modelled per map it came + -- out as two buildings, one per half. + -- + -- `topRows` composites ROUTE_10's twelve rows ABOVE the matched + -- grid, so the model is built from the COMPLETE twenty-row drawing + -- -- 96px of facade under the real 64px roof -- while placement + -- still matches only the eight Lavender rows. Its `claimOnly` + -- twin below claims the ROUTE_10 rows and stamps nothing, so the + -- roof half does not also stand as its own building. + -- + -- BOTH COME FIRST IN THIS LIST ON PURPOSE. The tower's upper + -- twelve rows are `gabled_block_6x6` tile for tile -- the artist + -- drew the top of the tower as an ordinary six-cell block -- so + -- that template matches at ROUTE_10 (24,132) too. Placement is + -- first-claim-wins (see Buildings.build), so claiming here before + -- the generic block reaches it is what keeps the second tower from + -- being stamped behind this one. + -- + -- The 13-id last row is kept from the first attempt: the bare + -- 12-wide body grid is B14's lower two-thirds tile for tile, and + -- the extra id stops this template stamping inside + -- `flat_block_6x6`'s three placements (`matches` walks a row to + -- its own length, while `read` composites only #tiles[1] columns, + -- so a 13th id constrains placement without entering the drawing). + { + id = "pokemon_tower", + topRows = { + { 5, 6, 83, 83, 83, 83, 83, 83, 83, 83, 8, 9 }, + { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, + { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, + { 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 25 }, + { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, + { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, + { 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 25 }, + { 37, 38, 34, 34, 34, 34, 34, 34, 34, 34, 40, 41 }, + { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, + { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, + { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, + { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, + }, + tiles = { + { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, + { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, + { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, + { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, + { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, + { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, + { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, + { 78, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 79, 17 }, + }, + roofRows = 64, roofBack = 8, roofFront = 8, roofCycle = { 8, 31 }, + slab = 4, frontEave = 4, ledge = nil, + }, + -- the tower's roof half, where it actually stands on ROUTE_10: + -- claimed flat so the drawing does not ALSO fold up as a building + -- behind the modelled tower (see topRows above) + { + id = "pokemon_tower_top", + claimOnly = true, + tiles = { + { 5, 6, 83, 83, 83, 83, 83, 83, 83, 83, 8, 9 }, + { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, + { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, + { 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 25 }, + { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, + { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, + { 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 25 }, + { 37, 38, 34, 34, 34, 34, 34, 34, 34, 34, 40, 41 }, + { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, + { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, + { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, + { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, + }, + }, -- assets/docs/buildings/B07: the two-storey gabled house. Coursed cap over -- a gable wall, an awning with its double black underline, then the -- ground floor with the door. 7 placements, Red's and Blue's among @@ -2731,75 +2810,6 @@ return { roofRows = 64, roofBack = 8, roofFront = 8, roofCycle = { 8, 31 }, slab = 4, frontEave = 4, ledge = nil, seal = "s", }, - -- assets/docs/buildings/B30: the POKEMON TOWER. The one drawing - -- in the catalogue that STRADDLES A MAP BOUNDARY: its purple roof - -- band and top two window courses stand in ROUTE_10's last eight - -- tile rows, and only the lower eight rows -- six more courses and - -- the base with the door -- are on LAVENDER_TOWN, where the - -- building begins at tile row 0. Modelled per map it came out as - -- two half-buildings: Lavender's half wearing a fabricated flat - -- cap (art row 0 stretched into a yellow slab), Route 10's half a - -- low volume of roof drawing folded at ground level behind it. - -- - -- `topRows` is the fix, built for this template: the eight - -- ROUTE_10 rows are composited ABOVE the matched grid, so the - -- model is the COMPLETE 16-row drawing -- 96px of facade under a - -- real 32px roof band -- while placement still matches only the - -- Lavender rows. Its twin `pokemon_tower_top` below claims the - -- Route 10 rows and stamps nothing, so the roof half no longer - -- also stands as its own building behind the tower. - -- - -- The old silhouette problem is gone with the roof back: the band - -- closes the drawing's north outline the way it does on every - -- sibling, so no `seal` is needed. The 13-id last row survives - -- from the first attempt: the bare 12-wide grid is B14's lower - -- two-thirds tile for tile, and the extra id keeps this template - -- from stamping inside flat_block_6x6's three placements - -- (`matches` walks a row to its own length; `read` composites - -- only #tiles[1] columns, so the 13th id constrains placement - -- without entering the drawing). - { - id = "pokemon_tower", - topRows = { - { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, - { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, - { 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 25 }, - { 37, 38, 34, 34, 34, 34, 34, 34, 34, 34, 40, 41 }, - { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, - { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, - { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, - { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, - }, - tiles = { - { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, - { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, - { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, - { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, - { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, - { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, - { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, - { 78, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 79, 17 }, - }, - roofRows = 32, roofBack = 7, roofFront = 8, roofCycle = { 5, 12 }, - slab = 4, frontEave = 4, ledge = nil, - }, - -- the tower's roof half, where it actually stands on ROUTE_10: - -- claimed flat so the drawing does not ALSO fold up as a second - -- building behind the modelled tower (see topRows above) - { - id = "pokemon_tower_top", - claimOnly = true, - tiles = { - { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, - { 21, 56, 18, 18, 18, 18, 18, 18, 18, 18, 56, 25 }, - { 21, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 25 }, - { 37, 38, 34, 34, 34, 34, 34, 34, 34, 34, 40, 41 }, - { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, - { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, - { 15, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 31 }, - { 15, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 31 }, - }, - }, }, FOREST = { diff --git a/lib/Buildings.lua b/lib/Buildings.lua index 244943a..7bfc6e0 100644 --- a/lib/Buildings.lua +++ b/lib/Buildings.lua @@ -627,7 +627,27 @@ function Buildings.build(S, map, data, perRow) for ty = 0, th - bh do Budget.tick() for tx = 0, tw - bw do - if S.tileAt[keyOf(tx, ty)] == first and matches(S, t, tx, ty) then + -- A placement never stamps into cells another template already + -- claimed. Templates are matched independently, and one + -- drawing can satisfy two grids: the Pokemon Tower's upper + -- twelve rows on ROUTE_10 are a standard 6-cell block tile for + -- tile, so `gabled_block_6x6` matched there and stood a whole + -- second building behind the tower. First claim wins, so the + -- list order below is the priority order -- the tower's own + -- templates come first precisely so they take those cells. + local free = S.tileAt[keyOf(tx, ty)] == first + if free then + for r = 0, bh - 1 do + for c = 0, bw - 1 do + if S.skip[keyOf(tx + c, ty + r)] then + free = false + break + end + end + if not free then break end + end + end + if free and matches(S, t, tx, ty) then if not built then local key = tileset.id .. ":" .. index if not models[key] then diff --git a/tests/voxel_mound_probe.lua b/tests/voxel_mound_probe.lua index 3bbcb2a..11ad540 100644 --- a/tests/voxel_mound_probe.lua +++ b/tests/voxel_mound_probe.lua @@ -30,7 +30,8 @@ return function(game) Pipelines.setLevel("tiltshift", 0) U.teleport(game, mapId, tonumber(sx), tonumber(sy), facing) U.wait(20) - Pipelines.setLevel("voxel", 3) + Pipelines.setLevel("voxel", + math.floor(tonumber(os.getenv("MOUND_LEVEL")) or 3)) U.wait(30) local V = game.mods.exports["DRAMATIC_SHAPE"]