@adatechnology/game-floorplan 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -460,6 +460,7 @@ var STEP = 0.05;
460
460
  var MAX_CANDIDATES = 80;
461
461
  function carCandidates(slot, item, car) {
462
462
  const front = [slot.frontU, slot.frontV];
463
+ if (!slot._cell) throw new Error("Slot without a cell: " + slot.id);
463
464
  const zone = slot._cell.R;
464
465
  const alongV = Math.abs(front[1]) === 1;
465
466
  const [extentU, extentV] = extent([item.w, item.d], front);
@@ -685,6 +686,7 @@ function candidatesOf(cats) {
685
686
  }
686
687
  function itemRect(slot, it, shift) {
687
688
  const c = slot._cell;
689
+ if (!c) throw new Error("Slot without a cell: " + slot.id);
688
690
  const f = c.f;
689
691
  const [extentU, extentV] = extent([it.w, it.d], f);
690
692
  const R = c.R;
@@ -789,7 +791,7 @@ function fillRoom(plan, room, slots2, rng) {
789
791
  if (!parent) return null;
790
792
  for (const { it } of cands) {
791
793
  if (it.w > parent.w + EPS || it.d > parent.d + EPS) continue;
792
- const f = [parent.frontU, parent.frontV];
794
+ const f = [parent.frontU ?? 0, parent.frontV ?? 1];
793
795
  const r = parent.aabb;
794
796
  const [extentU, extentV] = extent([it.w, it.d], f);
795
797
  const cu = (r[0] + r[2]) / 2 - f[0] * (parent.d / 2 - it.d / 2);
@@ -823,7 +825,7 @@ function fillRoom(plan, room, slots2, rng) {
823
825
  if (!car && !relax && s.clearance > 0 && !it.low) {
824
826
  cl2 = clearRect(r3, f, s.clearance);
825
827
  if (!insideUnion(cl2, inners)) continue;
826
- if (items.some((m2) => !m2.low && !m2.flat && !m2.on && overlaps(cl2, m2._r))) continue;
828
+ if (items.some((m2) => !m2.low && !m2.flat && !m2.on && overlaps(cl2, m2._r ?? m2.aabb))) continue;
827
829
  }
828
830
  if (!it.low && reserves.some((q) => overlaps(r3, q))) continue;
829
831
  let rimRect2 = null;
@@ -1011,7 +1013,7 @@ function createPlacementContext(plan, items) {
1011
1013
  if (!(opts.without && opts.without(r))) return r;
1012
1014
  continue;
1013
1015
  }
1014
- if (occupied.some((m) => !m.low && !m.flat && !m.on && !m.decor && m.clearance > 0 && overlaps(r, clearRect(m._r, [m.frontU, m.frontV], m.clearance)))) continue;
1016
+ if (occupied.some((m) => !m.low && !m.flat && !m.on && !m.decor && (m.clearance ?? 0) > 0 && overlaps(r, clearRect(m._r, [m.frontU ?? 0, m.frontV ?? 1], m.clearance ?? 0)))) continue;
1015
1017
  if (opts.without && opts.without(r)) continue;
1016
1018
  if (!reachable(opts.railing || gridOf(room), solidList.concat([r]), room.outdoor ? 0.16 : plan.playerRadius)) continue;
1017
1019
  return r;
@@ -1278,7 +1280,7 @@ function checkLot(zoneIn, lot, plan) {
1278
1280
  const far = m.built / area;
1279
1281
  if (far > zone.maxFar + 1e-9) out.push({ rule: "far", actual: r2(far), limit: zone.maxFar });
1280
1282
  let permeable = 0;
1281
- for (const z of lot.zones) if (registries().PERMEABLE_GROUNDS.has(z.ground)) for (const p of z.parts) permeable += (p[2] - p[0]) * (p[3] - p[1]);
1283
+ for (const z of lot.zones) if (z.ground && registries().PERMEABLE_GROUNDS.has(z.ground)) for (const p of z.parts) permeable += (p[2] - p[0]) * (p[3] - p[1]);
1282
1284
  const permeability = permeable / area;
1283
1285
  if (permeability < zone.permeableMin - 1e-9) out.push({ rule: "permeable", actual: r2(permeability), limit: zone.permeableMin });
1284
1286
  return out;
@@ -1321,12 +1323,12 @@ function enforcePermeability(lot, zones, zone, adjustments) {
1321
1323
  const [u0, v0, u1, v1] = lot.rect;
1322
1324
  const area = (u1 - u0) * (v1 - v0);
1323
1325
  const areaOfZone = (z) => z.parts.reduce((s, p) => s + (p[2] - p[0]) * (p[3] - p[1]), 0);
1324
- let permeable = zones.filter((z) => registries().PERMEABLE_GROUNDS.has(z.ground)).reduce((s, z) => s + areaOfZone(z), 0);
1326
+ let permeable = zones.filter((z) => z.ground != null && registries().PERMEABLE_GROUNDS.has(z.ground)).reduce((s, z) => s + areaOfZone(z), 0);
1325
1327
  if (permeable / area >= zone.permeableMin) return;
1326
- const candidates = zones.filter((z) => ADJUSTABLE_ZONES.has(z.type) && !registries().PERMEABLE_GROUNDS.has(z.ground)).sort((a, b) => areaOfZone(b) - areaOfZone(a));
1328
+ const candidates = zones.filter((z) => ADJUSTABLE_ZONES.has(z.type) && !(z.ground != null && registries().PERMEABLE_GROUNDS.has(z.ground))).sort((a, b) => areaOfZone(b) - areaOfZone(a));
1327
1329
  for (const z of candidates) {
1328
1330
  if (permeable / area >= zone.permeableMin) break;
1329
- adjustments.push({ field: "ground:" + z.id, from: z.ground, to: target, reason: "permeable_min" });
1331
+ adjustments.push({ field: "ground:" + z.id, from: z.ground ?? "", to: target, reason: "permeable_min" });
1330
1332
  z.ground = target;
1331
1333
  permeable += areaOfZone(z);
1332
1334
  }
@@ -1595,9 +1597,9 @@ function buildLot(plan, tpl, w, d, op, style, styleId, bc) {
1595
1597
  height: type === "pedestrian" ? style.height : Math.min(style.height, 2.2),
1596
1598
  side,
1597
1599
  to: toTarget || null,
1598
- material: "iron"
1600
+ material: "iron",
1601
+ zones: openingZones(u, v, "u", width, openingDepth(width, type === "pedestrian" ? width : 0))
1599
1602
  };
1600
- g.zones = openingZones(u, v, "u", width, openingDepth(width, type === "pedestrian" ? width : 0));
1601
1603
  gates.push(g);
1602
1604
  return g;
1603
1605
  };
@@ -1884,7 +1886,7 @@ function resolveSlot(plan, room, def, byId, zones) {
1884
1886
  };
1885
1887
  const invalid = (m) => Object.assign(base, { valid: false, reason: m, x: 0, z: 0, ry: 0, w: 0, d: 0, frontU: 0, frontV: 1, aabb: [0, 0, 0, 0], _cell: null });
1886
1888
  if (def.anchor === "on" || def.anchor === "inside") {
1887
- const parent = byId[def.parent];
1889
+ const parent = def.parent ? byId[def.parent] : void 0;
1888
1890
  if (!parent || !parent.valid) return invalid("invalid_parent");
1889
1891
  return Object.assign(base, { x: parent.x, z: parent.z, ry: parent.ry, w: parent.w, d: parent.d, frontU: parent.frontU, frontV: parent.frontV, aabb: parent.aabb, _cell: parent._cell });
1890
1892
  }
@@ -1925,9 +1927,10 @@ function resolveSlot(plan, room, def, byId, zones) {
1925
1927
  const windowList = windowsOfRoom(plan, room);
1926
1928
  win = windowList[def.n];
1927
1929
  if (!win) return invalid("no_window");
1930
+ const found2 = win;
1928
1931
  side = room.outdoor ? SIDE_OPPOSITE[win.side] : WINDOW_SIDE[win.side];
1929
1932
  const cand = room.parts.map(inner).find(
1930
- (r) => (win.axis === "u" ? win.u >= r[0] - TOL && win.u <= r[2] + TOL : win.v >= r[1] - TOL && win.v <= r[3] + TOL) && (side === "left" && eq(r[0], win.pos + MARGIN) || side === "right" && eq(r[2], win.pos - MARGIN) || side === "front" && eq(r[1], win.pos + MARGIN) || side === "back" && eq(r[3], win.pos - MARGIN))
1933
+ (r) => (found2.axis === "u" ? found2.u >= r[0] - TOL && found2.u <= r[2] + TOL : found2.v >= r[1] - TOL && found2.v <= r[3] + TOL) && (side === "left" && eq(r[0], found2.pos + MARGIN) || side === "right" && eq(r[2], found2.pos - MARGIN) || side === "front" && eq(r[1], found2.pos + MARGIN) || side === "back" && eq(r[3], found2.pos - MARGIN))
1931
1934
  );
1932
1935
  if (!cand) return invalid("window_outside_room");
1933
1936
  R = cand;
@@ -2121,7 +2124,7 @@ function generate(template, options) {
2121
2124
  if (m.category) out.color = colorOf(m, seed);
2122
2125
  return out;
2123
2126
  });
2124
- const result = {
2127
+ const base = {
2125
2128
  template: tpl.id,
2126
2129
  name: translate("templates", tpl.id, locale),
2127
2130
  use: useOf(tpl),
@@ -2158,8 +2161,8 @@ function generate(template, options) {
2158
2161
  building: tpl.building ? tpl.building(plan.w, plan.d, op) : null,
2159
2162
  missing
2160
2163
  };
2161
- if (tpl.singleFloor) result.floorNumber = op.floor || 3;
2162
- result.partyWalls = tpl.partyWalls || [];
2164
+ if (tpl.singleFloor) base.floorNumber = op.floor || 3;
2165
+ const result = Object.assign(base, { partyWalls: tpl.partyWalls || [] });
2163
2166
  if (plan.config) result.config = plan.config;
2164
2167
  runResultExtensions(plan, result, seed, op);
2165
2168
  if (zone) {