All files / src/shared/lib/tiles sceneTilemapReferences.ts

94.11% Statements 32/34
75% Branches 6/8
100% Functions 3/3
100% Lines 27/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69                        93x         25x 25x 25x 29x 3x   26x 9523x 9523x 7730x       25x     93x     5x 5x   5x   5x   5x 5x 7x   5x     5x     93x       5x 5x 5x 5x   5x            
import type { SceneTilemapData } from "shared/lib/resources/types";
 
interface SceneTilesetIndexEntry {
  tilesetId: string;
  tilesetIndex: number;
  offset: number;
}
 
interface SceneTilesetLookup {
  entryByAbsoluteIndex: Array<SceneTilesetIndexEntry | undefined>;
}
 
export const flattenTilemapLayers = (
  tilemap: SceneTilemapData,
  width: number,
  height: number,
): number[] => {
  const size = width * height;
  const tiles = new Array<number>(size).fill(0);
  for (const layer of tilemap.layers) {
    if (!layer.visible) {
      continue;
    }
    for (let index = 0; index < size; index++) {
      const tile = layer.tiles[index];
      if (tile) {
        tiles[index] = tile;
      }
    }
  }
  return tiles;
};
 
export const buildSceneTilesetReferenceLookup = (
  tilemap: Pick<SceneTilemapData, "tilesets">,
): SceneTilesetLookup => {
  let offset = 0;
  const entryByAbsoluteIndex: Array<SceneTilesetIndexEntry | undefined> = [];
 
  for (const [tilesetIndex, tileset] of tilemap.tilesets.entries()) {
    const count =
      Math.max(0, Math.floor(tileset.width)) *
      Math.max(0, Math.floor(tileset.height));
    const entry = { tilesetId: tileset.id, tilesetIndex, offset };
    for (let index = 0; index < count; index++) {
      entryByAbsoluteIndex[offset + index] = entry;
    }
    offset += count;
  }
 
  return { entryByAbsoluteIndex };
};
 
export const decodeSceneTileReference = (
  value: number,
  lookup: SceneTilesetLookup,
) => {
  Iif (!value) return undefined;
  const absoluteIndex = value - 1;
  const entry = lookup.entryByAbsoluteIndex[absoluteIndex];
  Iif (!entry) return undefined;
 
  return {
    tilesetIndex: entry.tilesetIndex,
    tileIndex: absoluteIndex - entry.offset,
    tilesetId: entry.tilesetId,
  };
};