@adatechnology/game-urban 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.d.ts +18 -9
- package/dist/index.global.js +18 -14
- package/dist/index.global.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -539,7 +539,10 @@ type PoleOptions = {
|
|
|
539
539
|
/** Adds the transformer drum (single arm). */
|
|
540
540
|
transformer?: boolean;
|
|
541
541
|
};
|
|
542
|
-
|
|
542
|
+
/** Draws a pole from its `spec`. Declared as a method so the registry can hold each builder with its own spec type (the `PoleDef` names the builder that reads its spec). */
|
|
543
|
+
type PoleShapeBuilder<TSpec extends object = object> = {
|
|
544
|
+
build(b: UrbanBuilder, spec: TSpec, o: PoleOptions): void;
|
|
545
|
+
}['build'];
|
|
543
546
|
type PoleDef = {
|
|
544
547
|
id: string;
|
|
545
548
|
/** Key of the shape builder that reads `spec`. */
|
|
@@ -926,7 +929,13 @@ type ComposeContext<TParams = Record<string, unknown>> = {
|
|
|
926
929
|
shop?: number;
|
|
927
930
|
}): void;
|
|
928
931
|
};
|
|
929
|
-
|
|
932
|
+
/**
|
|
933
|
+
* Draws a pattern from its params. Declared as a method so a registry of composers can hold each with its own params type
|
|
934
|
+
* (the pattern that names the composer carries the matching params).
|
|
935
|
+
*/
|
|
936
|
+
type Composer<TParams = Record<string, unknown>> = {
|
|
937
|
+
compose(context: ComposeContext<TParams>): void;
|
|
938
|
+
}['compose'];
|
|
930
939
|
type ComposeOptions = {
|
|
931
940
|
locale?: Locale;
|
|
932
941
|
providers?: Providers;
|
|
@@ -1134,9 +1143,9 @@ type Origin = {
|
|
|
1134
1143
|
z: number;
|
|
1135
1144
|
};
|
|
1136
1145
|
/** Draws one pattern at `origin`: its composer, then the board with the title and the caption. */
|
|
1137
|
-
declare function composePattern(kit: UrbanKitCore, pattern: NeighbourhoodPattern
|
|
1146
|
+
declare function composePattern(kit: UrbanKitCore, pattern: NeighbourhoodPattern, composer: Composer, b: UrbanBuilder, origin: Origin, options?: ComposeOptions): UrbanPlan;
|
|
1138
1147
|
/** The marker (map pin) of a pattern at an origin: where it stands, how high, and what it says. */
|
|
1139
|
-
declare function patternMarker(pattern: NeighbourhoodPattern
|
|
1148
|
+
declare function patternMarker(pattern: NeighbourhoodPattern, origin: Origin, locale?: Locale): {
|
|
1140
1149
|
x: number;
|
|
1141
1150
|
y: number;
|
|
1142
1151
|
z: number;
|
|
@@ -1196,14 +1205,14 @@ type UrbanOptions = {
|
|
|
1196
1205
|
/** Entries added to the catalogues (an entry with an existing id replaces it). */
|
|
1197
1206
|
packs?: {
|
|
1198
1207
|
poles?: readonly PoleDef[];
|
|
1199
|
-
neighbourhoods?: readonly NeighbourhoodPattern
|
|
1208
|
+
neighbourhoods?: readonly NeighbourhoodPattern[];
|
|
1200
1209
|
districtKinds?: readonly DistrictKindDef[];
|
|
1201
1210
|
cityPlans?: readonly CityPlanInput[];
|
|
1202
1211
|
};
|
|
1203
1212
|
/** Numbers changed on shipped entries, by id (objects merge, arrays replace). */
|
|
1204
1213
|
patch?: {
|
|
1205
1214
|
poles?: Record<string, DeepPartial<PoleDef>>;
|
|
1206
|
-
neighbourhoods?: Record<string, DeepPartial<NeighbourhoodPattern
|
|
1215
|
+
neighbourhoods?: Record<string, DeepPartial<NeighbourhoodPattern>>;
|
|
1207
1216
|
districtKinds?: Record<string, DeepPartial<DistrictKindDef>>;
|
|
1208
1217
|
cityPlans?: Record<string, DeepPartial<CityPlanInput>>;
|
|
1209
1218
|
};
|
|
@@ -1277,7 +1286,7 @@ declare function createUrban(options?: UrbanOptions): {
|
|
|
1277
1286
|
neighbourhoods: {
|
|
1278
1287
|
ids: () => string[];
|
|
1279
1288
|
get(id: string): {
|
|
1280
|
-
pattern: NeighbourhoodPattern
|
|
1289
|
+
pattern: NeighbourhoodPattern;
|
|
1281
1290
|
/** Draws the pattern at `origin` and gives back what it put there. */
|
|
1282
1291
|
compose: (b: UrbanBuilder, origin: Origin, o?: ComposeOptions) => UrbanPlan;
|
|
1283
1292
|
marker: (origin: Origin, locale?: Locale) => {
|
|
@@ -1768,7 +1777,7 @@ declare const DEFAULT_PLANT_CONTEXTS: Readonly<Record<PlantRequest['kind'], stri
|
|
|
1768
1777
|
declare function createPlantProvider(options?: PlantProviderOptions): PlantProvider;
|
|
1769
1778
|
|
|
1770
1779
|
/** The ten patterns of the Galeria's sample sheet, in the order the page builds them. */
|
|
1771
|
-
declare const DEFAULT_PATTERNS: readonly NeighbourhoodPattern
|
|
1780
|
+
declare const DEFAULT_PATTERNS: readonly NeighbourhoodPattern[];
|
|
1772
1781
|
/** Where the sample sheet puts each pattern: a 3 x 3 grid 80 by 56 m apart, and the military cell off to the east. */
|
|
1773
1782
|
declare const SAMPLE_CELLS: Readonly<Record<string, {
|
|
1774
1783
|
x: number;
|
|
@@ -1776,7 +1785,7 @@ declare const SAMPLE_CELLS: Readonly<Record<string, {
|
|
|
1776
1785
|
}>>;
|
|
1777
1786
|
|
|
1778
1787
|
/** The patterns of the tower pack. */
|
|
1779
|
-
declare const TOWER_PATTERNS: readonly NeighbourhoodPattern
|
|
1788
|
+
declare const TOWER_PATTERNS: readonly NeighbourhoodPattern[];
|
|
1780
1789
|
/** Where the sample sheet puts them (pass it as `cells`). */
|
|
1781
1790
|
declare const TOWER_SAMPLE_CELLS: Readonly<Record<string, {
|
|
1782
1791
|
x: number;
|
package/dist/index.global.js
CHANGED
|
@@ -650,6 +650,7 @@ var GameUrban = (() => {
|
|
|
650
650
|
var MAX_CANDIDATES = 80;
|
|
651
651
|
function carCandidates(slot, item, car) {
|
|
652
652
|
const front = [slot.frontU, slot.frontV];
|
|
653
|
+
if (!slot._cell) throw new Error("Slot without a cell: " + slot.id);
|
|
653
654
|
const zone = slot._cell.R;
|
|
654
655
|
const alongV = Math.abs(front[1]) === 1;
|
|
655
656
|
const [extentU, extentV] = extent([item.w, item.d], front);
|
|
@@ -869,6 +870,7 @@ var GameUrban = (() => {
|
|
|
869
870
|
}
|
|
870
871
|
function itemRect(slot, it, shift) {
|
|
871
872
|
const c = slot._cell;
|
|
873
|
+
if (!c) throw new Error("Slot without a cell: " + slot.id);
|
|
872
874
|
const f = c.f;
|
|
873
875
|
const [extentU, extentV] = extent([it.w, it.d], f);
|
|
874
876
|
const R = c.R;
|
|
@@ -973,7 +975,7 @@ var GameUrban = (() => {
|
|
|
973
975
|
if (!parent) return null;
|
|
974
976
|
for (const { it } of cands) {
|
|
975
977
|
if (it.w > parent.w + EPS || it.d > parent.d + EPS) continue;
|
|
976
|
-
const f = [parent.frontU, parent.frontV];
|
|
978
|
+
const f = [parent.frontU ?? 0, parent.frontV ?? 1];
|
|
977
979
|
const r = parent.aabb;
|
|
978
980
|
const [extentU, extentV] = extent([it.w, it.d], f);
|
|
979
981
|
const cu = (r[0] + r[2]) / 2 - f[0] * (parent.d / 2 - it.d / 2);
|
|
@@ -1007,7 +1009,7 @@ var GameUrban = (() => {
|
|
|
1007
1009
|
if (!car && !relax && s.clearance > 0 && !it.low) {
|
|
1008
1010
|
cl2 = clearRect(r3, f, s.clearance);
|
|
1009
1011
|
if (!insideUnion(cl2, inners)) continue;
|
|
1010
|
-
if (items.some((m2) => !m2.low && !m2.flat && !m2.on && overlaps(cl2, m2._r))) continue;
|
|
1012
|
+
if (items.some((m2) => !m2.low && !m2.flat && !m2.on && overlaps(cl2, m2._r ?? m2.aabb))) continue;
|
|
1011
1013
|
}
|
|
1012
1014
|
if (!it.low && reserves.some((q) => overlaps(r3, q))) continue;
|
|
1013
1015
|
let rimRect2 = null;
|
|
@@ -1191,7 +1193,7 @@ var GameUrban = (() => {
|
|
|
1191
1193
|
if (!(opts.without && opts.without(r))) return r;
|
|
1192
1194
|
continue;
|
|
1193
1195
|
}
|
|
1194
|
-
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;
|
|
1196
|
+
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;
|
|
1195
1197
|
if (opts.without && opts.without(r)) continue;
|
|
1196
1198
|
if (!reachable(opts.railing || gridOf(room), solidList.concat([r]), room.outdoor ? 0.16 : plan.playerRadius)) continue;
|
|
1197
1199
|
return r;
|
|
@@ -1452,7 +1454,7 @@ var GameUrban = (() => {
|
|
|
1452
1454
|
const far = m.built / area;
|
|
1453
1455
|
if (far > zone.maxFar + 1e-9) out.push({ rule: "far", actual: r2(far), limit: zone.maxFar });
|
|
1454
1456
|
let permeable = 0;
|
|
1455
|
-
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]);
|
|
1457
|
+
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]);
|
|
1456
1458
|
const permeability = permeable / area;
|
|
1457
1459
|
if (permeability < zone.permeableMin - 1e-9) out.push({ rule: "permeable", actual: r2(permeability), limit: zone.permeableMin });
|
|
1458
1460
|
return out;
|
|
@@ -1495,12 +1497,12 @@ var GameUrban = (() => {
|
|
|
1495
1497
|
const [u0, v0, u1, v1] = lot.rect;
|
|
1496
1498
|
const area = (u1 - u0) * (v1 - v0);
|
|
1497
1499
|
const areaOfZone = (z) => z.parts.reduce((s, p) => s + (p[2] - p[0]) * (p[3] - p[1]), 0);
|
|
1498
|
-
let permeable = zones.filter((z) => registries().PERMEABLE_GROUNDS.has(z.ground)).reduce((s, z) => s + areaOfZone(z), 0);
|
|
1500
|
+
let permeable = zones.filter((z) => z.ground != null && registries().PERMEABLE_GROUNDS.has(z.ground)).reduce((s, z) => s + areaOfZone(z), 0);
|
|
1499
1501
|
if (permeable / area >= zone.permeableMin) return;
|
|
1500
|
-
const candidates = zones.filter((z) => ADJUSTABLE_ZONES.has(z.type) && !registries().PERMEABLE_GROUNDS.has(z.ground)).sort((a, b) => areaOfZone(b) - areaOfZone(a));
|
|
1502
|
+
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));
|
|
1501
1503
|
for (const z of candidates) {
|
|
1502
1504
|
if (permeable / area >= zone.permeableMin) break;
|
|
1503
|
-
adjustments.push({ field: "ground:" + z.id, from: z.ground, to: target, reason: "permeable_min" });
|
|
1505
|
+
adjustments.push({ field: "ground:" + z.id, from: z.ground ?? "", to: target, reason: "permeable_min" });
|
|
1504
1506
|
z.ground = target;
|
|
1505
1507
|
permeable += areaOfZone(z);
|
|
1506
1508
|
}
|
|
@@ -1767,9 +1769,9 @@ var GameUrban = (() => {
|
|
|
1767
1769
|
height: type === "pedestrian" ? style.height : Math.min(style.height, 2.2),
|
|
1768
1770
|
side,
|
|
1769
1771
|
to: toTarget || null,
|
|
1770
|
-
material: "iron"
|
|
1772
|
+
material: "iron",
|
|
1773
|
+
zones: openingZones(u, v, "u", width, openingDepth(width, type === "pedestrian" ? width : 0))
|
|
1771
1774
|
};
|
|
1772
|
-
g.zones = openingZones(u, v, "u", width, openingDepth(width, type === "pedestrian" ? width : 0));
|
|
1773
1775
|
gates.push(g);
|
|
1774
1776
|
return g;
|
|
1775
1777
|
};
|
|
@@ -2052,7 +2054,7 @@ var GameUrban = (() => {
|
|
|
2052
2054
|
};
|
|
2053
2055
|
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 });
|
|
2054
2056
|
if (def.anchor === "on" || def.anchor === "inside") {
|
|
2055
|
-
const parent = byId2[def.parent];
|
|
2057
|
+
const parent = def.parent ? byId2[def.parent] : void 0;
|
|
2056
2058
|
if (!parent || !parent.valid) return invalid("invalid_parent");
|
|
2057
2059
|
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 });
|
|
2058
2060
|
}
|
|
@@ -2093,9 +2095,10 @@ var GameUrban = (() => {
|
|
|
2093
2095
|
const windowList = windowsOfRoom(plan, room);
|
|
2094
2096
|
win = windowList[def.n];
|
|
2095
2097
|
if (!win) return invalid("no_window");
|
|
2098
|
+
const found2 = win;
|
|
2096
2099
|
side = room.outdoor ? SIDE_OPPOSITE[win.side] : WINDOW_SIDE[win.side];
|
|
2097
2100
|
const cand = room.parts.map(inner).find(
|
|
2098
|
-
(r) => (
|
|
2101
|
+
(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))
|
|
2099
2102
|
);
|
|
2100
2103
|
if (!cand) return invalid("window_outside_room");
|
|
2101
2104
|
R = cand;
|
|
@@ -2287,7 +2290,7 @@ var GameUrban = (() => {
|
|
|
2287
2290
|
if (m.category) out.color = colorOf(m, seed);
|
|
2288
2291
|
return out;
|
|
2289
2292
|
});
|
|
2290
|
-
const
|
|
2293
|
+
const base = {
|
|
2291
2294
|
template: tpl.id,
|
|
2292
2295
|
name: translate("templates", tpl.id, locale),
|
|
2293
2296
|
use: useOf(tpl),
|
|
@@ -2324,8 +2327,8 @@ var GameUrban = (() => {
|
|
|
2324
2327
|
building: tpl.building ? tpl.building(plan.w, plan.d, op) : null,
|
|
2325
2328
|
missing
|
|
2326
2329
|
};
|
|
2327
|
-
if (tpl.singleFloor)
|
|
2328
|
-
result.partyWalls
|
|
2330
|
+
if (tpl.singleFloor) base.floorNumber = op.floor || 3;
|
|
2331
|
+
const result = Object.assign(base, { partyWalls: tpl.partyWalls || [] });
|
|
2329
2332
|
if (plan.config) result.config = plan.config;
|
|
2330
2333
|
runResultExtensions(plan, result, seed, op);
|
|
2331
2334
|
if (zone) {
|
|
@@ -13533,6 +13536,7 @@ var GameUrban = (() => {
|
|
|
13533
13536
|
hood: true
|
|
13534
13537
|
},
|
|
13535
13538
|
function(c) {
|
|
13539
|
+
c.meta.armor = "III";
|
|
13536
13540
|
const f = 3.75, W = 2.32, len = 1.85, ax = 2.5, wr = 0.506, ww = 0.28, col = "#56616b";
|
|
13537
13541
|
c.meta.bullet = true;
|
|
13538
13542
|
c.meta.cabLength = len + 0.15;
|