@rickyzhangca/fpsr 0.0.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/CHANGELOG.md +10 -0
- package/LICENSE +21 -0
- package/README.md +267 -0
- package/dist/abort-CrgARaZd.js +43 -0
- package/dist/abort-CrgARaZd.js.map +1 -0
- package/dist/assets-Dy4fqZBV.d.ts +85 -0
- package/dist/assets-Dy4fqZBV.d.ts.map +1 -0
- package/dist/canvas.d.ts +98 -0
- package/dist/canvas.d.ts.map +1 -0
- package/dist/canvas.js +3 -0
- package/dist/execute-CRZV5zw1.js +963 -0
- package/dist/execute-CRZV5zw1.js.map +1 -0
- package/dist/host-DdX4g1YM.d.ts +34 -0
- package/dist/host-DdX4g1YM.d.ts.map +1 -0
- package/dist/index.d.ts +463 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1776 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +16 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +101 -0
- package/dist/node.js.map +1 -0
- package/dist/planner.d.ts +418 -0
- package/dist/planner.d.ts.map +1 -0
- package/dist/planner.js +96 -0
- package/dist/planner.js.map +1 -0
- package/dist/profile-CTN1Q5SI.d.ts +365 -0
- package/dist/profile-CTN1Q5SI.d.ts.map +1 -0
- package/dist/profile-DR4i6HDp.js +610 -0
- package/dist/profile-DR4i6HDp.js.map +1 -0
- package/dist/render-db-BFQIspDB.d.ts +426 -0
- package/dist/render-db-BFQIspDB.d.ts.map +1 -0
- package/dist/render-db.d.ts +2 -0
- package/dist/render-db.js +1 -0
- package/dist/tiled-draw-list-Dc-5Ledi.js +3990 -0
- package/dist/tiled-draw-list-Dc-5Ledi.js.map +1 -0
- package/dist/types-CHgZBSra.d.ts +105 -0
- package/dist/types-CHgZBSra.d.ts.map +1 -0
- package/dist/upgrade-planner-CNjnMHPJ.d.ts +385 -0
- package/dist/upgrade-planner-CNjnMHPJ.d.ts.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import { d as EntityRenderDef, g as LayerGroup, h as FrameMeta, v as RenderDb } from "./render-db-BFQIspDB.js";
|
|
2
|
+
import { C as WireCmd, S as TrainChainCmd, T as serializeDrawList, _ as RENDER_LAYERS, a as PlanProfile, b as SpriteCmd, f as DrawCmd, g as IconCmd, h as FACTORIO_RENDER_LAYERS, m as DrawListBounds, p as DrawList, v as RectCmd, w as compareDrawCmd, x as TextCmd, y as SnapGridCmd } from "./profile-CTN1Q5SI.js";
|
|
3
|
+
import { F as BlueprintEntity, W as Color, i as planDeconstructionPlannerDrawList, j as Blueprint, n as planUpgradePlannerDrawList, q as SignalId, r as DECONSTRUCTION_PLANNER_COLUMNS, t as UPGRADE_PLANNER_COLUMNS } from "./upgrade-planner-CNjnMHPJ.js";
|
|
4
|
+
|
|
5
|
+
//#region src/alt-mode-signals.d.ts
|
|
6
|
+
/** Ordered render-db icon keys for a Blueprint SignalID (UI lookup chain). */
|
|
7
|
+
declare function signalIconKeys(signal: SignalId): string[];
|
|
8
|
+
/** Resolve Blueprint SignalID namespaces and tolerate older/default item shapes. */
|
|
9
|
+
declare function altSignalFrame(db: RenderDb, signal: SignalId): number | undefined;
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/alt-mode-request-pin.d.ts
|
|
12
|
+
/**
|
|
13
|
+
* Build insert-plan request-pin icons (sub 20–49). Always shown, not gated by alt mode.
|
|
14
|
+
* Y matches the Factorio layout used when recipe/primary icons are present: pins sit
|
|
15
|
+
* below those icons when the entity has primary signals, otherwise at the entity anchor.
|
|
16
|
+
*/
|
|
17
|
+
declare function planRequestPinCommands(entity: BlueprintEntity, def: EntityRenderDef, db: RenderDb): IconCmd[];
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/alt-mode.d.ts
|
|
20
|
+
/** Build deterministic alt-mode (entity-info) commands for one blueprint entity. */
|
|
21
|
+
declare function planAltModeCommands(entity: BlueprintEntity, def: EntityRenderDef, db: RenderDb, opts?: {
|
|
22
|
+
insertCommands?: IconCmd[];
|
|
23
|
+
}): IconCmd[];
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/plan-diagnostics.d.ts
|
|
26
|
+
interface UnsupportedBlueprintContent {
|
|
27
|
+
name: string;
|
|
28
|
+
count: number;
|
|
29
|
+
entityNumbers?: number[];
|
|
30
|
+
}
|
|
31
|
+
interface PlanDiagnostics {
|
|
32
|
+
entities: {
|
|
33
|
+
total: number;
|
|
34
|
+
resolved: number;
|
|
35
|
+
unsupported: UnsupportedBlueprintContent[];
|
|
36
|
+
};
|
|
37
|
+
tiles: {
|
|
38
|
+
total: number;
|
|
39
|
+
resolved: number;
|
|
40
|
+
unsupported: UnsupportedBlueprintContent[];
|
|
41
|
+
};
|
|
42
|
+
drawList: {
|
|
43
|
+
commandCount: number;
|
|
44
|
+
byKind: Record<string, number>;
|
|
45
|
+
uniqueFrames: number;
|
|
46
|
+
uniqueLayers: number;
|
|
47
|
+
atlasIndices: number[];
|
|
48
|
+
};
|
|
49
|
+
checks: {
|
|
50
|
+
finiteBounds: boolean;
|
|
51
|
+
finiteCommands: boolean;
|
|
52
|
+
sortedCommands: boolean;
|
|
53
|
+
validFrameReferences: boolean;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Summarize plan/resolve coverage and draw-list integrity for a blueprint.
|
|
58
|
+
* Pure: needs render-db for entity/tile/frame lookups, no images.
|
|
59
|
+
*/
|
|
60
|
+
declare function analyzePlan(blueprint: Blueprint, drawList: DrawList, db: RenderDb): PlanDiagnostics;
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region src/plan/tiles.d.ts
|
|
63
|
+
/**
|
|
64
|
+
* Deterministic integer hash of tile coordinates for picking among tile frame
|
|
65
|
+
* variants. Stable across runs / platforms for the same (x, y).
|
|
66
|
+
*/
|
|
67
|
+
declare function tileVariantHash(x: number, y: number): number;
|
|
68
|
+
/** Positive modulo for tile grid coordinates (handles negatives). */
|
|
69
|
+
declare function tileMod(n: number, m: number): number;
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/plan/unsupported.d.ts
|
|
72
|
+
/** Render-db icon key for the fpsr-owned unsupported mod entity marker. */
|
|
73
|
+
declare const UNSUPPORTED_ENTITY_ICON_KEY = "utility/unsupported-entity";
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/plan/index.d.ts
|
|
76
|
+
/** Normalize blueprint/proto color to 0–1 RGBA (Factorio may export 0–255). */
|
|
77
|
+
declare function normalizeEntityColor(color: Color): [number, number, number, number];
|
|
78
|
+
interface PlanOptions {
|
|
79
|
+
/** Emit blueprint-derived entity-info overlays (recipes, filters, signals, quality). */
|
|
80
|
+
altMode?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Emit belt starting/ending cap sprites. Default true.
|
|
83
|
+
* Caps use a full-tile shift behind/ahead of the belt (FBE-aligned).
|
|
84
|
+
*/
|
|
85
|
+
beltEndings?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* When true, attach phase timings on the returned {@link PlanResult.profile}.
|
|
88
|
+
* Near-zero overhead when omitted/false.
|
|
89
|
+
*/
|
|
90
|
+
profile?: boolean;
|
|
91
|
+
}
|
|
92
|
+
interface PlanResult {
|
|
93
|
+
drawList: DrawList;
|
|
94
|
+
/** Present when {@link PlanOptions.profile} was true. */
|
|
95
|
+
profile?: PlanProfile;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Pure draw planner: blueprint + render-db -> sorted DrawList.
|
|
99
|
+
* Profiling details are available via {@link planDrawListWithOptions}.
|
|
100
|
+
*/
|
|
101
|
+
declare function planDrawList(bp: Blueprint, db: RenderDb, opts?: PlanOptions): DrawList;
|
|
102
|
+
/**
|
|
103
|
+
* Plan a draw list, optionally collecting phase timings when `opts.profile` is true.
|
|
104
|
+
* Accepts only the public {@link PlanOptions} surface.
|
|
105
|
+
*/
|
|
106
|
+
declare function planDrawListWithOptions(bp: Blueprint, db: RenderDb, opts?: PlanOptions): PlanResult;
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region src/resolve/belts.d.ts
|
|
109
|
+
/**
|
|
110
|
+
* Verified against belt_animation_set defaults: X=east_index-1=0,
|
|
111
|
+
* west_index-1=1, north_index-1=2, south_index-1=3.
|
|
112
|
+
* Prototype defaults are 1-based; values here are 0-based rows into the 20-slot table.
|
|
113
|
+
*/
|
|
114
|
+
declare const BELT_STRAIGHT_INDEX: Record<0 | 4 | 8 | 12, number>;
|
|
115
|
+
/** Curve when the sole feeder is on the belt's right (FBE "right"). */
|
|
116
|
+
declare const BELT_CURVE_RIGHT: Record<0 | 4 | 8 | 12, number>;
|
|
117
|
+
/** Curve when the sole feeder is on the belt's left (FBE "left"). */
|
|
118
|
+
declare const BELT_CURVE_LEFT: Record<0 | 4 | 8 | 12, number>;
|
|
119
|
+
/**
|
|
120
|
+
* Starting-cap row for a belt facing `dir`.
|
|
121
|
+
* FBE maps north-facing → starting_south (back-edge art), etc.
|
|
122
|
+
*/
|
|
123
|
+
declare const BELT_START_INDEX: Record<0 | 4 | 8 | 12, number>;
|
|
124
|
+
/** Ending-cap row for a belt facing `dir`. */
|
|
125
|
+
declare const BELT_END_INDEX: Record<0 | 4 | 8 | 12, number>;
|
|
126
|
+
/**
|
|
127
|
+
* UG/loader structure sheets pack horizontal columns N,E,S,W (same as direction4).
|
|
128
|
+
* Kept as an explicit table so distill/resolve stay aligned if packing changes.
|
|
129
|
+
* Outputs use the opposite flow direction so paired hoods face away from each other
|
|
130
|
+
* (same-column direction_in/direction_out art faces the same way).
|
|
131
|
+
*/
|
|
132
|
+
declare const UG_STRUCTURE_INDEX: readonly [number, number, number, number];
|
|
133
|
+
/** Structure column for UG/loader hood sprites (object layer only). */
|
|
134
|
+
declare function undergroundStructureIndex(direction: number, type: BlueprintEntity["type"]): number;
|
|
135
|
+
interface BeltOccupant {
|
|
136
|
+
entity: BlueprintEntity;
|
|
137
|
+
def: EntityRenderDef;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Map every occupied tile-center to belt-connectable entities on that tile.
|
|
141
|
+
* Splitters cover two tiles (tileSize [2,1] = long × short; 1×2 when facing N/S).
|
|
142
|
+
*/
|
|
143
|
+
declare function buildBeltTileIndex(entities: BlueprintEntity[], db: RenderDb): Map<string, BeltOccupant[]>;
|
|
144
|
+
/**
|
|
145
|
+
* Circuit-connector topology variation for a transport belt (0–6).
|
|
146
|
+
* Factorio order: X, H, V, SE, SW, NE, NW.
|
|
147
|
+
*
|
|
148
|
+
* Uses the same neighbor model as beltCurveIndex. Both perpendicular feeders → X;
|
|
149
|
+
* straight belts → H (E/W) or V (N/S); curves map via belt animation corner names.
|
|
150
|
+
*/
|
|
151
|
+
declare function beltCircuitConnectorVariation(entity: BlueprintEntity, beltIndex: Map<string, BeltOccupant[]>): number;
|
|
152
|
+
/** Back-patch row for connector variation: straights/X → 0; SE/SW → 1; NE/NW → 2. */
|
|
153
|
+
declare function beltConnectorBackPatchIndex(variation: number): number;
|
|
154
|
+
/**
|
|
155
|
+
* Belt-reader sheet layout (Factorio binary validation):
|
|
156
|
+
* - bands (rows): StraightSolidBand=0, StraightOpenBand=1, CurvedSolidBand=2, Ending=3
|
|
157
|
+
* - frames: North=0, East=1, South=2, West=3 (tile-edge pieces)
|
|
158
|
+
*/
|
|
159
|
+
declare const BELT_READER_BAND: {
|
|
160
|
+
readonly solid: 0;
|
|
161
|
+
readonly open: 1;
|
|
162
|
+
readonly curved: 2;
|
|
163
|
+
readonly ending: 3;
|
|
164
|
+
};
|
|
165
|
+
declare const BELT_READER_FRAME: {
|
|
166
|
+
readonly north: 0;
|
|
167
|
+
readonly east: 1;
|
|
168
|
+
readonly south: 2;
|
|
169
|
+
readonly west: 3;
|
|
170
|
+
};
|
|
171
|
+
type BeltReaderSlot = {
|
|
172
|
+
band: number;
|
|
173
|
+
frame: number; /** Mirror Ending across the open tip so the outer half of the fancy cap appears. */
|
|
174
|
+
flipX?: boolean;
|
|
175
|
+
flipY?: boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Extra tile-space shift on top of the sprite variant shift.
|
|
178
|
+
* Used to hang the mirrored Ending half past the open tip.
|
|
179
|
+
*/
|
|
180
|
+
shift?: [number, number];
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Which belt-reader sheet cells to paint for one belt on an entire_belt_hold line.
|
|
184
|
+
* Straights: SolidBand on both long-side edges; open line ends also get Ending
|
|
185
|
+
* short-edge caps so the rail "grabs" the belt tip (in-game).
|
|
186
|
+
* Curves: one CurvedSolidBand corner frame.
|
|
187
|
+
*
|
|
188
|
+
* Ending sprites are inward hooks flush to the tip edge — also emit a mirrored
|
|
189
|
+
* copy one tile past the tip so the outer half of the fancy cap appears.
|
|
190
|
+
*/
|
|
191
|
+
declare function beltReaderSlots(entity: BlueprintEntity, def: EntityRenderDef, beltIndex: Map<string, BeltOccupant[]>, readerEntities: Set<number>): BeltReaderSlot[];
|
|
192
|
+
/** `defines.control_behavior.transport_belt.content_read_mode.entire_belt_hold` */
|
|
193
|
+
declare const BELT_CONTENT_READ_ENTIRE = 2;
|
|
194
|
+
/** Enable/disable (write/output) — horizontal red/green LEDs on the belt cage. */
|
|
195
|
+
declare function isBeltCircuitOutputEnabled(entity: BlueprintEntity): boolean;
|
|
196
|
+
/** Read belt contents (input) — vertical blue LED on the belt cage. */
|
|
197
|
+
declare function isBeltCircuitInputEnabled(entity: BlueprintEntity): boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Connector-frame state used by Factorio's four-frame belt connector sheet.
|
|
200
|
+
* The frames are a behavior bitmask, not belt directions:
|
|
201
|
+
* none=0, enable/output=1, read/input=2, both=3.
|
|
202
|
+
*/
|
|
203
|
+
declare function beltCircuitConnectorFrame(entity: BlueprintEntity): number;
|
|
204
|
+
/**
|
|
205
|
+
* Belts that should show whole-belt-reader skirts: the wired reader with
|
|
206
|
+
* entire_belt_hold, plus every transport-belt and underground-belt on its
|
|
207
|
+
* contiguous line (through UGs; stops at splitters / side-loads).
|
|
208
|
+
*/
|
|
209
|
+
declare function collectBeltReaderEntities(bp: Blueprint, db: RenderDb, beltIndex: Map<string, BeltOccupant[]>): Set<number>;
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/resolve/shared.d.ts
|
|
212
|
+
/**
|
|
213
|
+
* Map a 16-way blueprint direction to a layer variant index per the indexing
|
|
214
|
+
* contract in render-db.ts.
|
|
215
|
+
*/
|
|
216
|
+
declare function dir16ToIndex(direction: number, indexing: LayerGroup["indexing"]): number;
|
|
217
|
+
declare function cardinalDirection(direction: number | undefined): 0 | 4 | 8 | 12;
|
|
218
|
+
/** Rotate a local (north-facing) offset by entity direction. */
|
|
219
|
+
declare function rotateOffset(x: number, y: number, dir: 0 | 4 | 8 | 12): [number, number];
|
|
220
|
+
type NeighborGrid = Map<string, BlueprintEntity[]>;
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region src/resolve/context.d.ts
|
|
223
|
+
interface LayerSelection {
|
|
224
|
+
/** Index into def.graphics. */
|
|
225
|
+
group: number;
|
|
226
|
+
variantKey: string;
|
|
227
|
+
index: number;
|
|
228
|
+
/**
|
|
229
|
+
* Extra tile-space shift applied on top of the sprite variant's shift
|
|
230
|
+
* (used for belt starting/ending caps).
|
|
231
|
+
*/
|
|
232
|
+
shift?: [number, number];
|
|
233
|
+
}
|
|
234
|
+
interface ResolvedEntity {
|
|
235
|
+
entity: BlueprintEntity;
|
|
236
|
+
def: EntityRenderDef;
|
|
237
|
+
selections: LayerSelection[];
|
|
238
|
+
}
|
|
239
|
+
interface ResolveOptions {
|
|
240
|
+
/** Emit belt starting/ending cap selections. Default true. */
|
|
241
|
+
beltEndings?: boolean;
|
|
242
|
+
}
|
|
243
|
+
/** Shared neighbor indexes for one blueprint planning pass. */
|
|
244
|
+
interface ResolveContext {
|
|
245
|
+
blueprint: Blueprint;
|
|
246
|
+
db: RenderDb;
|
|
247
|
+
entities: BlueprintEntity[];
|
|
248
|
+
grid: NeighborGrid;
|
|
249
|
+
beltIndex: Map<string, BeltOccupant[]>;
|
|
250
|
+
fluidPipeSides: Map<string, Set<string>>;
|
|
251
|
+
/** Heat-pipe tile -> sides connected to a non-heat-pipe entity's heat port. */
|
|
252
|
+
heatPipeSides?: Map<string, Set<string>>;
|
|
253
|
+
poleDirs: Map<number, number>;
|
|
254
|
+
/** Use platform cargo-bay body/connection art (hub or space-platform tiles). */
|
|
255
|
+
preferPlatformGraphics: boolean;
|
|
256
|
+
}
|
|
257
|
+
/** Space-platform hub or foundation tiles → use platform cargo-bay art. */
|
|
258
|
+
declare function blueprintPrefersPlatformGraphics(blueprint: Blueprint, entities?: BlueprintEntity[]): boolean;
|
|
259
|
+
/** Build indexes for an already migrated blueprint. */
|
|
260
|
+
declare function createResolveContext(blueprint: Blueprint, db: RenderDb): ResolveContext;
|
|
261
|
+
//#endregion
|
|
262
|
+
//#region src/resolve/trains.d.ts
|
|
263
|
+
/**
|
|
264
|
+
* Vehicle RotatedAnimation art is already authored in oblique screen angles.
|
|
265
|
+
* Convert the world-space orientation back into that authored ellipse before
|
|
266
|
+
* selecting a pose. This is the inverse axis scaling of rolling-stock
|
|
267
|
+
* projection; vehicles also have no rail/bogie geometry.
|
|
268
|
+
*/
|
|
269
|
+
declare function projectVehicleOrientation(orientation: number): number;
|
|
270
|
+
/**
|
|
271
|
+
* Map continuous blueprint `orientation` ∈ [0,1) to a distilled pose index.
|
|
272
|
+
* `round(orientation * N) % N` — orientation 0 → pose 0 (north).
|
|
273
|
+
*
|
|
274
|
+
* With `backEqualsFront` (cargo/fluid wagons): the sheet only authors half a
|
|
275
|
+
* turn; Factorio indexes as `round(o * 2N) % N` so east and west share a pose.
|
|
276
|
+
* @see FBSR FPRotatedSprite.getIndex
|
|
277
|
+
*/
|
|
278
|
+
declare function trainOrientationIndex(orientation: number, poseCount: number, backEqualsFront?: boolean): number;
|
|
279
|
+
/**
|
|
280
|
+
* Factorio's camera is a 45° orthographic tilt: circular orientations project
|
|
281
|
+
* onto an ellipse (Y scaled by 1/√2) before picking rotated sprites.
|
|
282
|
+
* @see https://forums.factorio.com/viewtopic.php?t=109695
|
|
283
|
+
*/
|
|
284
|
+
declare function projectTrainOrientation(orientation: number): number;
|
|
285
|
+
/**
|
|
286
|
+
* Rolling-stock "rail shift": FBSR stores this as height and flattens with
|
|
287
|
+
* `y - height`. Equivalent forum form: `-(0.25 * abs(cos(o*TAU + PI/2)))`.
|
|
288
|
+
* @see https://forums.factorio.com/viewtopic.php?t=109695
|
|
289
|
+
*/
|
|
290
|
+
declare function trainRailShiftY(orientation: number): number;
|
|
291
|
+
/**
|
|
292
|
+
* Artillery-wagon cannon mount offset (tile units, before rail-shift Y).
|
|
293
|
+
* Ports FBSR ArtilleryWagonRendering.calculateCannonPosition for slope=0.
|
|
294
|
+
*/
|
|
295
|
+
declare function artilleryCannonShift(orientation: number, opts: {
|
|
296
|
+
cannonBaseHeight?: number;
|
|
297
|
+
cannonBaseShiftWhenVertical?: number;
|
|
298
|
+
cannonBaseShiftWhenHorizontal?: number; /** Distilled pose count; used to snap orientation like FBSR getAlignedOrientation. */
|
|
299
|
+
orientationCount?: number;
|
|
300
|
+
}): [number, number];
|
|
301
|
+
/** Dual bogie shifts for a rolling-stock entity (tile units relative to center). */
|
|
302
|
+
declare function trainWheelShifts(orientation: number, jointDistance: number): {
|
|
303
|
+
shift: [number, number];
|
|
304
|
+
orientation: number;
|
|
305
|
+
}[];
|
|
306
|
+
/**
|
|
307
|
+
* Map blueprint rail direction (0..15) to a direction8 picture index.
|
|
308
|
+
* Straight / half-diagonal pieces only author 4 of 8 keys; fold 4..7 → 0..3.
|
|
309
|
+
*/
|
|
310
|
+
declare function railDirectionIndex(direction: number, foldTo4: boolean): number;
|
|
311
|
+
//#endregion
|
|
312
|
+
//#region src/resolve/index.d.ts
|
|
313
|
+
declare function resolve(bp: Blueprint, db: RenderDb, opts?: ResolveOptions): ResolveResult;
|
|
314
|
+
interface ResolveResult {
|
|
315
|
+
entities: ResolvedEntity[];
|
|
316
|
+
warnings: string[];
|
|
317
|
+
}
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region src/pole-orientation.d.ts
|
|
320
|
+
interface Point2 {
|
|
321
|
+
x: number;
|
|
322
|
+
y: number;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Average neighbor bearings into a cardinal direction 0|4|8|12 (FBE).
|
|
326
|
+
* Y is inverted to match Factorio's screen-space angle convention.
|
|
327
|
+
*/
|
|
328
|
+
declare function powerPoleRotationFromNeighbors(centre: Point2, points: Point2[]): number;
|
|
329
|
+
/**
|
|
330
|
+
* Effective pole direction: explicit blueprint `direction` when set, else FBE
|
|
331
|
+
* inference from wire-neighbor positions. Returns 0|4|8|12 (or 0 if alone).
|
|
332
|
+
*/
|
|
333
|
+
declare function effectivePowerPoleDirection(entity: BlueprintEntity, bp: Blueprint, byNumber: Map<number, BlueprintEntity>): number;
|
|
334
|
+
/**
|
|
335
|
+
* Precompute effective directions for every electric-pole entity in the blueprint.
|
|
336
|
+
*/
|
|
337
|
+
declare function buildPowerPoleDirections(bp: Blueprint, entities: BlueprintEntity[], isElectricPole: (entity: BlueprintEntity) => boolean): Map<number, number>;
|
|
338
|
+
//#endregion
|
|
339
|
+
//#region src/train-chains.d.ts
|
|
340
|
+
/** Default Factorio RollingStock connection_distance when not distilled. */
|
|
341
|
+
declare const DEFAULT_CONNECTION_DISTANCE = 3;
|
|
342
|
+
/** Default Factorio RollingStock joint_distance when not distilled. */
|
|
343
|
+
declare const DEFAULT_JOINT_DISTANCE = 4;
|
|
344
|
+
/** Hollow joint circle radius in tiles — segments stop at this edge. */
|
|
345
|
+
declare const TRAIN_CHAIN_JOINT_RADIUS = 0.3;
|
|
346
|
+
interface TrainJointPoints {
|
|
347
|
+
/** Joint in the +orientation direction (±joint/2). */
|
|
348
|
+
front: [number, number];
|
|
349
|
+
/** Joint in the −orientation direction. */
|
|
350
|
+
back: [number, number];
|
|
351
|
+
}
|
|
352
|
+
interface TrainChainGeometry {
|
|
353
|
+
segments: {
|
|
354
|
+
x1: number;
|
|
355
|
+
y1: number;
|
|
356
|
+
x2: number;
|
|
357
|
+
y2: number;
|
|
358
|
+
}[];
|
|
359
|
+
joints: {
|
|
360
|
+
x: number;
|
|
361
|
+
y: number;
|
|
362
|
+
}[];
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* World-space front/back joint positions for a rolling-stock entity.
|
|
366
|
+
* Matches bogie placement from `trainWheelShifts` (index 0 = front/+half).
|
|
367
|
+
*/
|
|
368
|
+
declare function trainJointWorldPoints(entity: BlueprintEntity, jointDistance: number): TrainJointPoints;
|
|
369
|
+
/**
|
|
370
|
+
* Build train-chain overlay geometry for all coupled rolling stock in a blueprint.
|
|
371
|
+
*
|
|
372
|
+
* Draws hollow circles only at coupled joints (free ends omitted), and straight
|
|
373
|
+
* segments between those facing joints. Segment endpoints are inset to the
|
|
374
|
+
* circle perimeter so strokes meet the rings instead of crossing through them.
|
|
375
|
+
*
|
|
376
|
+
* Isolated single wagons with no neighbors are omitted.
|
|
377
|
+
*/
|
|
378
|
+
declare function buildTrainChainGeometry(bp: Blueprint, byNumber: Map<number, {
|
|
379
|
+
entity: BlueprintEntity;
|
|
380
|
+
def: EntityRenderDef;
|
|
381
|
+
}>): TrainChainGeometry | null;
|
|
382
|
+
//#endregion
|
|
383
|
+
//#region src/wire-connectors.d.ts
|
|
384
|
+
/**
|
|
385
|
+
* Factorio 2.x `defines.wire_connector_id` numeric values used in blueprint
|
|
386
|
+
* `wires` tuples: [src_entity, src_connector, dst_entity, dst_connector].
|
|
387
|
+
*
|
|
388
|
+
* Confirmed against runtime docs / wiki talk / draftsman (values are not unique
|
|
389
|
+
* across names — circuit_red and combinator_input_red both equal 1).
|
|
390
|
+
*/
|
|
391
|
+
declare const WIRE_CONNECTOR_ID: {
|
|
392
|
+
readonly circuit_red: 1;
|
|
393
|
+
readonly circuit_green: 2;
|
|
394
|
+
readonly combinator_input_red: 1;
|
|
395
|
+
readonly combinator_input_green: 2;
|
|
396
|
+
readonly combinator_output_red: 3;
|
|
397
|
+
readonly combinator_output_green: 4;
|
|
398
|
+
readonly pole_copper: 5;
|
|
399
|
+
readonly power_switch_left_copper: 5;
|
|
400
|
+
readonly power_switch_right_copper: 6;
|
|
401
|
+
};
|
|
402
|
+
type WireColor = "copper" | "red" | "green";
|
|
403
|
+
/**
|
|
404
|
+
* Map a blueprint wire_connector_id to the drawn wire color.
|
|
405
|
+
* Combinator output connectors use the same color as the matching input.
|
|
406
|
+
*/
|
|
407
|
+
declare function wireConnectorColor(connectorId: number): WireColor | undefined;
|
|
408
|
+
//#endregion
|
|
409
|
+
//#region src/tiled-draw-list.d.ts
|
|
410
|
+
/**
|
|
411
|
+
* Retain commands that can affect one viewport while preserving shadow-run
|
|
412
|
+
* boundaries. The transparent separators prevent independently composited
|
|
413
|
+
* shadow runs from becoming adjacent after culling.
|
|
414
|
+
*/
|
|
415
|
+
declare function drawListForTile(list: DrawList, frames: FrameMeta[], frame: DrawListBounds, bleedTiles?: number): DrawList;
|
|
416
|
+
//#endregion
|
|
417
|
+
export { BELT_CONTENT_READ_ENTIRE, BELT_CURVE_LEFT, BELT_CURVE_RIGHT, BELT_END_INDEX, BELT_READER_BAND, BELT_READER_FRAME, BELT_START_INDEX, BELT_STRAIGHT_INDEX, type BeltOccupant, type BeltReaderSlot, DECONSTRUCTION_PLANNER_COLUMNS, DEFAULT_CONNECTION_DISTANCE, DEFAULT_JOINT_DISTANCE, type DrawCmd, type DrawList, type DrawListBounds, FACTORIO_RENDER_LAYERS, type IconCmd, type LayerSelection, type PlanDiagnostics, type PlanOptions, type PlanProfile, type PlanResult, RENDER_LAYERS, type RectCmd, type ResolveOptions, type ResolveResult, type ResolvedEntity, type SnapGridCmd, type SpriteCmd, TRAIN_CHAIN_JOINT_RADIUS, type TextCmd, type TrainChainCmd, type TrainChainGeometry, type TrainJointPoints, UG_STRUCTURE_INDEX, UNSUPPORTED_ENTITY_ICON_KEY, UPGRADE_PLANNER_COLUMNS, type UnsupportedBlueprintContent, WIRE_CONNECTOR_ID, type WireCmd, type WireColor, altSignalFrame, analyzePlan, artilleryCannonShift, beltCircuitConnectorFrame, beltCircuitConnectorVariation, beltConnectorBackPatchIndex, beltReaderSlots, blueprintPrefersPlatformGraphics, buildBeltTileIndex, buildPowerPoleDirections, buildTrainChainGeometry, cardinalDirection, collectBeltReaderEntities, compareDrawCmd, createResolveContext, dir16ToIndex, drawListForTile, effectivePowerPoleDirection, isBeltCircuitInputEnabled, isBeltCircuitOutputEnabled, normalizeEntityColor, planAltModeCommands, planDeconstructionPlannerDrawList, planDrawList, planDrawListWithOptions, planRequestPinCommands, planUpgradePlannerDrawList, powerPoleRotationFromNeighbors, projectTrainOrientation, projectVehicleOrientation, railDirectionIndex, resolve, rotateOffset, serializeDrawList, signalIconKeys, tileMod, tileVariantHash, trainJointWorldPoints, trainOrientationIndex, trainRailShiftY, trainWheelShifts, undergroundStructureIndex, wireConnectorColor };
|
|
418
|
+
//# sourceMappingURL=planner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.d.ts","names":[],"sources":["../src/alt-mode-signals.ts","../src/alt-mode-request-pin.ts","../src/alt-mode.ts","../src/plan-diagnostics.ts","../src/plan/tiles.ts","../src/plan/unsupported.ts","../src/plan/index.ts","../src/resolve/belts.ts","../src/resolve/shared.ts","../src/resolve/context.ts","../src/resolve/trains.ts","../src/resolve/index.ts","../src/pole-orientation.ts","../src/train-chains.ts","../src/wire-connectors.ts","../src/tiled-draw-list.ts"],"mappings":"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"}
|
package/dist/planner.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { C as compareDrawCmd, S as RENDER_LAYERS, _ as railDirectionIndex, a as DEFAULT_JOINT_DISTANCE, b as trainWheelShifts, c as trainJointWorldPoints, g as projectVehicleOrientation, h as projectTrainOrientation, i as DEFAULT_CONNECTION_DISTANCE, m as artilleryCannonShift, o as TRAIN_CHAIN_JOINT_RADIUS, s as buildTrainChainGeometry, v as trainOrientationIndex, w as serializeDrawList, x as FACTORIO_RENDER_LAYERS, y as trainRailShiftY } from "./profile-DR4i6HDp.js";
|
|
2
|
+
import { $ as beltCircuitConnectorFrame, B as createResolveContext, G as BELT_CURVE_LEFT, H as effectivePowerPoleDirection, J as BELT_READER_BAND, K as BELT_CURVE_RIGHT, L as planAltModeCommands, Q as UG_STRUCTURE_INDEX, R as resolve, U as powerPoleRotationFromNeighbors, V as buildPowerPoleDirections, W as BELT_CONTENT_READ_ENTIRE, X as BELT_START_INDEX, Y as BELT_READER_FRAME, Z as BELT_STRAIGHT_INDEX, a as planDrawListWithOptions, at as isBeltCircuitInputEnabled, bt as signalIconKeys, c as tileVariantHash, ct as cardinalDirection, d as DECONSTRUCTION_PLANNER_COLUMNS, et as beltCircuitConnectorVariation, f as planDeconstructionPlannerDrawList, gt as wireConnectorColor, ht as WIRE_CONNECTOR_ID, it as collectBeltReaderEntities, l as UPGRADE_PLANNER_COLUMNS, lt as dir16ToIndex, n as normalizeEntityColor, nt as beltReaderSlots, o as UNSUPPORTED_ENTITY_ICON_KEY, ot as isBeltCircuitOutputEnabled, q as BELT_END_INDEX, r as planDrawList, rt as buildBeltTileIndex, s as tileMod, st as undergroundStructureIndex, t as drawListForTile, tt as beltConnectorBackPatchIndex, u as planUpgradePlannerDrawList, ut as rotateOffset, vt as planRequestPinCommands, yt as altSignalFrame, z as blueprintPrefersPlatformGraphics } from "./tiled-draw-list-Dc-5Ledi.js";
|
|
3
|
+
//#region src/plan-diagnostics.ts
|
|
4
|
+
const countUnsupported = (values, isSupported) => {
|
|
5
|
+
const counts = /* @__PURE__ */ new Map();
|
|
6
|
+
for (const value of values) {
|
|
7
|
+
if (isSupported(value.name)) continue;
|
|
8
|
+
const entry = counts.get(value.name) ?? {
|
|
9
|
+
count: 0,
|
|
10
|
+
entityNumbers: []
|
|
11
|
+
};
|
|
12
|
+
entry.count += 1;
|
|
13
|
+
if (value.entity_number != null) entry.entityNumbers.push(value.entity_number);
|
|
14
|
+
counts.set(value.name, entry);
|
|
15
|
+
}
|
|
16
|
+
return [...counts.entries()].map(([name, value]) => ({
|
|
17
|
+
name,
|
|
18
|
+
count: value.count,
|
|
19
|
+
...value.entityNumbers.length > 0 ? { entityNumbers: value.entityNumbers } : {}
|
|
20
|
+
})).sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));
|
|
21
|
+
};
|
|
22
|
+
const hasOnlyFiniteNumbers = (value) => {
|
|
23
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
24
|
+
if (Array.isArray(value)) return value.every(hasOnlyFiniteNumbers);
|
|
25
|
+
if (value && typeof value === "object") return Object.values(value).every(hasOnlyFiniteNumbers);
|
|
26
|
+
return true;
|
|
27
|
+
};
|
|
28
|
+
const countValues = (values) => {
|
|
29
|
+
return values.reduce((sum, value) => sum + value.count, 0);
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Summarize plan/resolve coverage and draw-list integrity for a blueprint.
|
|
33
|
+
* Pure: needs render-db for entity/tile/frame lookups, no images.
|
|
34
|
+
*/
|
|
35
|
+
function analyzePlan(blueprint, drawList, db) {
|
|
36
|
+
const entities = blueprint.entities ?? [];
|
|
37
|
+
const tiles = blueprint.tiles ?? [];
|
|
38
|
+
const unsupportedEntities = countUnsupported(entities, (name) => db.entities[name] != null);
|
|
39
|
+
const unsupportedTiles = countUnsupported(tiles, (name) => db.tiles[name] != null);
|
|
40
|
+
const byKind = {};
|
|
41
|
+
const frames = /* @__PURE__ */ new Set();
|
|
42
|
+
const layers = /* @__PURE__ */ new Set();
|
|
43
|
+
const atlases = /* @__PURE__ */ new Set();
|
|
44
|
+
let validFrameReferences = true;
|
|
45
|
+
for (const command of drawList.commands) {
|
|
46
|
+
byKind[command.kind] = (byKind[command.kind] ?? 0) + 1;
|
|
47
|
+
layers.add(command.layer);
|
|
48
|
+
if (command.kind !== "sprite" && command.kind !== "icon") continue;
|
|
49
|
+
const frameIds = [command.frame];
|
|
50
|
+
if (command.kind === "icon" && command.backingFrame != null) frameIds.push(command.backingFrame);
|
|
51
|
+
for (const frameId of frameIds) {
|
|
52
|
+
frames.add(frameId);
|
|
53
|
+
const frame = db.frames[frameId];
|
|
54
|
+
if (!frame) {
|
|
55
|
+
validFrameReferences = false;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
atlases.add(frame.a);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const { bounds } = drawList;
|
|
62
|
+
const finiteBounds = hasOnlyFiniteNumbers(bounds) && bounds.minX <= bounds.maxX && bounds.minY <= bounds.maxY;
|
|
63
|
+
const sortedCommands = drawList.commands.every((command, index) => {
|
|
64
|
+
const previous = drawList.commands[index - 1];
|
|
65
|
+
return !previous || compareDrawCmd(previous, command) <= 0;
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
entities: {
|
|
69
|
+
total: entities.length,
|
|
70
|
+
resolved: entities.length - countValues(unsupportedEntities),
|
|
71
|
+
unsupported: unsupportedEntities
|
|
72
|
+
},
|
|
73
|
+
tiles: {
|
|
74
|
+
total: tiles.length,
|
|
75
|
+
resolved: tiles.length - countValues(unsupportedTiles),
|
|
76
|
+
unsupported: unsupportedTiles
|
|
77
|
+
},
|
|
78
|
+
drawList: {
|
|
79
|
+
commandCount: drawList.commands.length,
|
|
80
|
+
byKind,
|
|
81
|
+
uniqueFrames: frames.size,
|
|
82
|
+
uniqueLayers: layers.size,
|
|
83
|
+
atlasIndices: [...atlases].sort((a, b) => a - b)
|
|
84
|
+
},
|
|
85
|
+
checks: {
|
|
86
|
+
finiteBounds,
|
|
87
|
+
finiteCommands: drawList.commands.every(hasOnlyFiniteNumbers),
|
|
88
|
+
sortedCommands,
|
|
89
|
+
validFrameReferences
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
export { BELT_CONTENT_READ_ENTIRE, BELT_CURVE_LEFT, BELT_CURVE_RIGHT, BELT_END_INDEX, BELT_READER_BAND, BELT_READER_FRAME, BELT_START_INDEX, BELT_STRAIGHT_INDEX, DECONSTRUCTION_PLANNER_COLUMNS, DEFAULT_CONNECTION_DISTANCE, DEFAULT_JOINT_DISTANCE, FACTORIO_RENDER_LAYERS, RENDER_LAYERS, TRAIN_CHAIN_JOINT_RADIUS, UG_STRUCTURE_INDEX, UNSUPPORTED_ENTITY_ICON_KEY, UPGRADE_PLANNER_COLUMNS, WIRE_CONNECTOR_ID, altSignalFrame, analyzePlan, artilleryCannonShift, beltCircuitConnectorFrame, beltCircuitConnectorVariation, beltConnectorBackPatchIndex, beltReaderSlots, blueprintPrefersPlatformGraphics, buildBeltTileIndex, buildPowerPoleDirections, buildTrainChainGeometry, cardinalDirection, collectBeltReaderEntities, compareDrawCmd, createResolveContext, dir16ToIndex, drawListForTile, effectivePowerPoleDirection, isBeltCircuitInputEnabled, isBeltCircuitOutputEnabled, normalizeEntityColor, planAltModeCommands, planDeconstructionPlannerDrawList, planDrawList, planDrawListWithOptions, planRequestPinCommands, planUpgradePlannerDrawList, powerPoleRotationFromNeighbors, projectTrainOrientation, projectVehicleOrientation, railDirectionIndex, resolve, rotateOffset, serializeDrawList, signalIconKeys, tileMod, tileVariantHash, trainJointWorldPoints, trainOrientationIndex, trainRailShiftY, trainWheelShifts, undergroundStructureIndex, wireConnectorColor };
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=planner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.js","names":[],"sources":["../src/plan-diagnostics.ts"],"sourcesContent":["import type { Blueprint } from \"./types/blueprint.js\";\nimport { compareDrawCmd, type DrawList } from \"./types/draw-list.js\";\nimport type { RenderDb } from \"./types/render-db.js\";\n\nexport interface UnsupportedBlueprintContent {\n name: string;\n count: number;\n entityNumbers?: number[];\n}\n\nexport interface PlanDiagnostics {\n entities: {\n total: number;\n resolved: number;\n unsupported: UnsupportedBlueprintContent[];\n };\n tiles: {\n total: number;\n resolved: number;\n unsupported: UnsupportedBlueprintContent[];\n };\n drawList: {\n commandCount: number;\n byKind: Record<string, number>;\n uniqueFrames: number;\n uniqueLayers: number;\n atlasIndices: number[];\n };\n checks: {\n finiteBounds: boolean;\n finiteCommands: boolean;\n sortedCommands: boolean;\n validFrameReferences: boolean;\n };\n}\n\nconst countUnsupported = (\n values: readonly { name: string; entity_number?: number }[],\n isSupported: (name: string) => boolean,\n): UnsupportedBlueprintContent[] => {\n const counts = new Map<string, { count: number; entityNumbers: number[] }>();\n for (const value of values) {\n if (isSupported(value.name)) continue;\n const entry = counts.get(value.name) ?? { count: 0, entityNumbers: [] };\n entry.count += 1;\n if (value.entity_number != null) entry.entityNumbers.push(value.entity_number);\n counts.set(value.name, entry);\n }\n return [...counts.entries()]\n .map(([name, value]) => ({\n name,\n count: value.count,\n ...(value.entityNumbers.length > 0 ? { entityNumbers: value.entityNumbers } : {}),\n }))\n .sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));\n};\n\nconst hasOnlyFiniteNumbers = (value: unknown): boolean => {\n if (typeof value === \"number\") return Number.isFinite(value);\n if (Array.isArray(value)) return value.every(hasOnlyFiniteNumbers);\n if (value && typeof value === \"object\") {\n return Object.values(value as Record<string, unknown>).every(hasOnlyFiniteNumbers);\n }\n return true;\n};\n\nconst countValues = (values: readonly UnsupportedBlueprintContent[]): number => {\n return values.reduce((sum, value) => sum + value.count, 0);\n};\n\n/**\n * Summarize plan/resolve coverage and draw-list integrity for a blueprint.\n * Pure: needs render-db for entity/tile/frame lookups, no images.\n */\nexport function analyzePlan(\n blueprint: Blueprint,\n drawList: DrawList,\n db: RenderDb,\n): PlanDiagnostics {\n const entities = blueprint.entities ?? [];\n const tiles = blueprint.tiles ?? [];\n const unsupportedEntities = countUnsupported(entities, (name) => db.entities[name] != null);\n const unsupportedTiles = countUnsupported(tiles, (name) => db.tiles[name] != null);\n const byKind: Record<string, number> = {};\n const frames = new Set<number>();\n const layers = new Set<number>();\n const atlases = new Set<number>();\n let validFrameReferences = true;\n\n for (const command of drawList.commands) {\n byKind[command.kind] = (byKind[command.kind] ?? 0) + 1;\n layers.add(command.layer);\n if (command.kind !== \"sprite\" && command.kind !== \"icon\") continue;\n const frameIds = [command.frame];\n if (command.kind === \"icon\" && command.backingFrame != null) {\n frameIds.push(command.backingFrame);\n }\n for (const frameId of frameIds) {\n frames.add(frameId);\n const frame = db.frames[frameId];\n if (!frame) {\n validFrameReferences = false;\n continue;\n }\n atlases.add(frame.a);\n }\n }\n\n const { bounds } = drawList;\n const finiteBounds =\n hasOnlyFiniteNumbers(bounds) && bounds.minX <= bounds.maxX && bounds.minY <= bounds.maxY;\n const sortedCommands = drawList.commands.every((command, index) => {\n const previous = drawList.commands[index - 1];\n return !previous || compareDrawCmd(previous, command) <= 0;\n });\n\n return {\n entities: {\n total: entities.length,\n resolved: entities.length - countValues(unsupportedEntities),\n unsupported: unsupportedEntities,\n },\n tiles: {\n total: tiles.length,\n resolved: tiles.length - countValues(unsupportedTiles),\n unsupported: unsupportedTiles,\n },\n drawList: {\n commandCount: drawList.commands.length,\n byKind,\n uniqueFrames: frames.size,\n uniqueLayers: layers.size,\n atlasIndices: [...atlases].sort((a, b) => a - b),\n },\n checks: {\n finiteBounds,\n finiteCommands: drawList.commands.every(hasOnlyFiniteNumbers),\n sortedCommands,\n validFrameReferences,\n },\n };\n}\n"],"mappings":"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"}
|