@scm-js/plugin-api 1.3.0 → 1.4.0

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.
Files changed (2) hide show
  1. package/index.d.ts +351 -3
  2. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -271,6 +271,225 @@ export interface TriggerRecord {
271
271
  /** The game's bookkeeping byte (offset 2399); StarEdit writes 0. */
272
272
  currentAction: number;
273
273
  }
274
+ declare const ConditionType: {
275
+ readonly None: 0;
276
+ readonly CountdownTimer: 1;
277
+ readonly Command: 2;
278
+ readonly Bring: 3;
279
+ readonly Accumulate: 4;
280
+ readonly Kill: 5;
281
+ readonly CommandTheMost: 6;
282
+ readonly CommandTheMostAt: 7;
283
+ readonly MostKills: 8;
284
+ readonly HighestScore: 9;
285
+ readonly MostResources: 10;
286
+ readonly Switch: 11;
287
+ readonly ElapsedTime: 12;
288
+ readonly Briefing: 13;
289
+ readonly Opponents: 14;
290
+ readonly Deaths: 15;
291
+ readonly CommandTheLeast: 16;
292
+ readonly CommandTheLeastAt: 17;
293
+ readonly LeastKills: 18;
294
+ readonly LowestScore: 19;
295
+ readonly LeastResources: 20;
296
+ readonly Score: 21;
297
+ readonly Always: 22;
298
+ readonly Never: 23;
299
+ };
300
+ declare const ActionType: {
301
+ readonly None: 0;
302
+ readonly Victory: 1;
303
+ readonly Defeat: 2;
304
+ readonly PreserveTrigger: 3;
305
+ readonly Wait: 4;
306
+ readonly PauseGame: 5;
307
+ readonly UnpauseGame: 6;
308
+ readonly Transmission: 7;
309
+ readonly PlayWav: 8;
310
+ readonly DisplayText: 9;
311
+ readonly CenterView: 10;
312
+ readonly CreateUnitWithProperties: 11;
313
+ readonly SetMissionObjectives: 12;
314
+ readonly SetSwitch: 13;
315
+ readonly SetCountdownTimer: 14;
316
+ readonly RunAiScript: 15;
317
+ readonly RunAiScriptAt: 16;
318
+ readonly LeaderboardControl: 17;
319
+ readonly LeaderboardControlAt: 18;
320
+ readonly LeaderboardResources: 19;
321
+ readonly LeaderboardKills: 20;
322
+ readonly LeaderboardPoints: 21;
323
+ readonly KillUnit: 22;
324
+ readonly KillUnitAt: 23;
325
+ readonly RemoveUnit: 24;
326
+ readonly RemoveUnitAt: 25;
327
+ readonly SetResources: 26;
328
+ readonly SetScore: 27;
329
+ readonly MinimapPing: 28;
330
+ readonly TalkingPortrait: 29;
331
+ readonly MuteUnitSpeech: 30;
332
+ readonly UnmuteUnitSpeech: 31;
333
+ readonly LeaderboardComputerPlayers: 32;
334
+ readonly LeaderboardGoalControl: 33;
335
+ readonly LeaderboardGoalControlAt: 34;
336
+ readonly LeaderboardGoalResources: 35;
337
+ readonly LeaderboardGoalKills: 36;
338
+ readonly LeaderboardGoalPoints: 37;
339
+ readonly MoveLocation: 38;
340
+ readonly MoveUnit: 39;
341
+ readonly LeaderboardGreed: 40;
342
+ readonly SetNextScenario: 41;
343
+ readonly SetDoodadState: 42;
344
+ readonly SetInvincibility: 43;
345
+ readonly CreateUnit: 44;
346
+ readonly SetDeaths: 45;
347
+ readonly Order: 46;
348
+ readonly Comment: 47;
349
+ readonly GiveUnits: 48;
350
+ readonly ModifyHitPoints: 49;
351
+ readonly ModifyEnergy: 50;
352
+ readonly ModifyShields: 51;
353
+ readonly ModifyResourceAmount: 52;
354
+ readonly ModifyHangarCount: 53;
355
+ readonly PauseTimer: 54;
356
+ readonly UnpauseTimer: 55;
357
+ readonly Draw: 56;
358
+ readonly SetAllianceStatus: 57;
359
+ readonly DisableDebugMode: 58;
360
+ readonly EnableDebugMode: 59;
361
+ };
362
+ declare const BriefingActionType: {
363
+ readonly None: 0;
364
+ readonly Wait: 1;
365
+ readonly PlayWav: 2;
366
+ readonly TextMessage: 3;
367
+ readonly MissionObjectives: 4;
368
+ readonly ShowPortrait: 5;
369
+ readonly HidePortrait: 6;
370
+ readonly DisplaySpeakingPortrait: 7;
371
+ readonly Transmission: 8;
372
+ readonly SkipTutorialEnabled: 9;
373
+ };
374
+ declare const PlayerGroup: {
375
+ readonly Player1: 0;
376
+ readonly Player2: 1;
377
+ readonly Player3: 2;
378
+ readonly Player4: 3;
379
+ readonly Player5: 4;
380
+ readonly Player6: 5;
381
+ readonly Player7: 6;
382
+ readonly Player8: 7;
383
+ readonly Player9: 8;
384
+ readonly Player10: 9;
385
+ readonly Player11: 10;
386
+ readonly Player12: 11;
387
+ readonly None: 12;
388
+ readonly CurrentPlayer: 13;
389
+ readonly Foes: 14;
390
+ readonly Allies: 15;
391
+ readonly NeutralPlayers: 16;
392
+ readonly AllPlayers: 17;
393
+ readonly Force1: 18;
394
+ readonly Force2: 19;
395
+ readonly Force3: 20;
396
+ readonly Force4: 21;
397
+ readonly Unused1: 22;
398
+ readonly Unused2: 23;
399
+ readonly Unused3: 24;
400
+ readonly Unused4: 25;
401
+ readonly NonAlliedVictoryPlayers: 26;
402
+ };
403
+ declare const Comparison: {
404
+ readonly AtLeast: 0;
405
+ readonly AtMost: 1;
406
+ readonly Exactly: 10;
407
+ };
408
+ declare const SwitchState: {
409
+ readonly Set: 2;
410
+ readonly Cleared: 3;
411
+ };
412
+ declare const SwitchAction: {
413
+ readonly Set: 4;
414
+ readonly Clear: 5;
415
+ readonly Toggle: 6;
416
+ readonly Randomize: 11;
417
+ };
418
+ declare const SetModifier: {
419
+ readonly SetTo: 7;
420
+ readonly Add: 8;
421
+ readonly Subtract: 9;
422
+ };
423
+ declare const UnitState: {
424
+ readonly Enable: 4;
425
+ readonly Disable: 5;
426
+ readonly Toggle: 6;
427
+ };
428
+ declare const Order: {
429
+ readonly Move: 0;
430
+ readonly Patrol: 1;
431
+ readonly Attack: 2;
432
+ };
433
+ declare const AllianceStatus: {
434
+ readonly Enemy: 0;
435
+ readonly Ally: 1;
436
+ readonly AlliedVictory: 2;
437
+ };
438
+ declare const ResourceType: {
439
+ readonly Ore: 0;
440
+ readonly Gas: 1;
441
+ readonly OreAndGas: 2;
442
+ };
443
+ declare const ScoreType: {
444
+ readonly Total: 0;
445
+ readonly Units: 1;
446
+ readonly Buildings: 2;
447
+ readonly UnitsAndBuildings: 3;
448
+ readonly Kills: 4;
449
+ readonly Razings: 5;
450
+ readonly KillsAndRazings: 6;
451
+ readonly Custom: 7;
452
+ };
453
+ declare const UnitClass: {
454
+ readonly Any: 228;
455
+ readonly Men: 229;
456
+ readonly Buildings: 230;
457
+ readonly Factories: 231;
458
+ };
459
+ declare const ConditionFlag: {
460
+ /** Game bookkeeping. */
461
+ readonly Unknown: 1;
462
+ readonly Disabled: 2;
463
+ readonly AlwaysDisplay: 4;
464
+ readonly UnitPropertiesUsed: 8;
465
+ readonly UnitTypeUsed: 16;
466
+ readonly UnitIdUsed: 32;
467
+ };
468
+ declare const ActionFlag: {
469
+ /** Ignore a Wait / Transmission once (game bookkeeping). */
470
+ readonly IgnoreWaitOnce: 1;
471
+ readonly Disabled: 2;
472
+ readonly AlwaysDisplay: 4;
473
+ readonly UnitPropertiesUsed: 8;
474
+ readonly UnitTypeUsed: 16;
475
+ readonly UnitIdUsed: 32;
476
+ };
477
+ declare const TriggerFlag: {
478
+ /** Game bookkeeping: every condition was met this cycle. */
479
+ readonly ConditionsMet: 1;
480
+ /** Ignore Defeat / Draw for this trigger. */
481
+ readonly IgnoreGameEnd: 2;
482
+ /** Same as a Preserve Trigger action. */
483
+ readonly Preserve: 4;
484
+ /** The trigger never runs. */
485
+ readonly Disabled: 8;
486
+ /** Skip Wait / text / view actions for the rest of this loop (game bookkeeping). */
487
+ readonly IgnoreDisplay: 16;
488
+ /** Game bookkeeping. */
489
+ readonly Paused: 32;
490
+ /** Game bookkeeping. */
491
+ readonly WaitSkipDisabled: 64;
492
+ };
274
493
  /**
275
494
  * A parsed scenario.
276
495
  *
@@ -1659,17 +1878,32 @@ export interface PluginInfo {
1659
1878
  export interface PluginApi {
1660
1879
  readonly apiVersion: number;
1661
1880
  readonly plugin: PluginInfo;
1881
+ /**
1882
+ * The open map: what it says, and the three ways of writing to it — `edit` (terrain and
1883
+ * objects, one undo entry), `update` (the tables every dialog's OK writes) and
1884
+ * `sections` (raw bytes). Opening, saving, exporting and closing are here too.
1885
+ */
1662
1886
  readonly document: DocumentApi;
1663
1887
  /** The settings dialogs' tables, read-only; `document.update` writes them. */
1664
1888
  readonly settings: SettingsApi;
1665
1889
  readonly triggers: TriggersApi;
1890
+ /**
1891
+ * Reading the terrain: the tileset's paintable types, the ISOM lattice, flood regions,
1892
+ * blend candidates and the symmetry mode. Painting goes through `document.edit`.
1893
+ */
1666
1894
  readonly terrain: TerrainApi;
1895
+ /** The loaded tileset graphics: whether they are there, and the decoded files behind them. */
1667
1896
  readonly tileset: TilesetApi;
1897
+ /** What is selected on each object layer, the marked area, the active layer and the locked ones. */
1668
1898
  readonly selection: SelectionApi;
1669
1899
  /** Cut / Copy / Paste: the clip, its parts, and pasting — what the clipboard layer does. */
1670
1900
  readonly clipboard: ClipboardApi;
1671
1901
  /** The file formats behind File ▸ Import / Export: `.trg` and the strings text. */
1672
1902
  readonly exchange: ExchangeApi;
1903
+ /**
1904
+ * The palettes' current picks — the terrain brush, the unit, sprite and doodad, the fog
1905
+ * mode — and the placement options a plugin that places things should honour.
1906
+ */
1673
1907
  readonly palette: PaletteApi;
1674
1908
  readonly names: NamesApi;
1675
1909
  /** StarCraft's `<XX>` text control codes: what they mean, and what a string looks like drawn. */
@@ -1680,12 +1914,24 @@ export interface PluginApi {
1680
1914
  readonly consts: ConstsApi;
1681
1915
  readonly graphics: GraphicsApi;
1682
1916
  readonly view: ViewApi;
1917
+ /**
1918
+ * Everything a plugin puts on the screen: the status line, toasts, dialogs, floating
1919
+ * panels, `confirm` / `alert` / `prompt` / `progress`, a map tool that owns the pointer,
1920
+ * a passive overlay drawn over the map, and picking an area or a tile.
1921
+ */
1683
1922
  readonly ui: UiApi;
1923
+ /** Items in the editor's menu bar. A path whose last segment names no submenu makes one. */
1684
1924
  readonly menu: MenuApi;
1925
+ /** Items in the right-click menus of the map and the terrain palette. */
1685
1926
  readonly contextMenu: ContextMenuApi;
1927
+ /** Key combinations, tried before the editor's own and never while a text field has focus. */
1686
1928
  readonly hotkeys: HotkeyApi;
1687
1929
  readonly commands: CommandsApi;
1688
1930
  readonly events: EventsApi;
1931
+ /**
1932
+ * A small key-value store of the plugin's own, kept in the browser's local storage under
1933
+ * the plugin's id and listed with everything else in Preferences ▸ Browser storage.
1934
+ */
1689
1935
  readonly storage: StorageApi;
1690
1936
  /** `console.log` with the plugin's name in front. */
1691
1937
  log(...args: unknown[]): void;
@@ -1804,6 +2050,14 @@ export interface DocumentApi {
1804
2050
  *
1805
2051
  * `build` is synchronous — see `Sync`. Await what you need (graphics, a pick, a
1806
2052
  * fetch) before the call, then write in one go.
2053
+ *
2054
+ * @example
2055
+ * // One undo entry called "Fill", however many operations it takes.
2056
+ * const result = api.document.edit("Fill", (tx) => {
2057
+ * tx.stampTerrain({ x0: 0, y0: 0, x1: 8, y1: 8 }, terrainId);
2058
+ * tx.placeUnit(api.consts.unit.startLocation, 0, 4 * api.consts.tile, 4 * api.consts.tile);
2059
+ * });
2060
+ * api.ui.status(`${result.tiles} tiles, ${result.units} units`);
1807
2061
  */
1808
2062
  edit<R>(label: string, build: (tx: EditTransaction) => Sync<R>): EditResult;
1809
2063
  /**
@@ -1813,6 +2067,11 @@ export interface DocumentApi {
1813
2067
  * Operations apply as they are called; the commit marks the map modified and bumps
1814
2068
  * what the chrome reads. There is no undo entry: keep your own if you need one.
1815
2069
  * `build` is synchronous, as `edit`'s is.
2070
+ *
2071
+ * @example
2072
+ * api.document.update("Rename", (tx) => {
2073
+ * tx.properties({ name: "Lost Temple", description: "Four players." });
2074
+ * });
1816
2075
  */
1817
2076
  update<R>(label: string, build: (tx: UpdateTransaction) => Sync<R>): UpdateResult;
1818
2077
  undo(): string | null;
@@ -2587,8 +2846,9 @@ export interface DataApi {
2587
2846
  }
2588
2847
  /**
2589
2848
  * The constants a plugin needs to *write* a record rather than read one: the bit masks in
2590
- * a UNIT / THG2 / MRGN record, the few unit ids the game itself treats specially, and the
2591
- * one conversion — 32 pixels to a tile — every object position goes through.
2849
+ * a UNIT / THG2 / MRGN record, the condition, action and argument numbers of a TRIG /
2850
+ * MBRF one, the few unit ids the game itself treats specially, and the one conversion —
2851
+ * 32 pixels to a tile — every object position goes through.
2592
2852
  *
2593
2853
  * They are the editor's own (`sections/objects.ts`, `editor/units.ts`) and they arrive
2594
2854
  * here at run time rather than in the typings on purpose: `@scm-js/plugin-api` is erased
@@ -2600,9 +2860,14 @@ export interface DataApi {
2600
2860
  export interface ConstsApi {
2601
2861
  /** Map pixels to a tile. UNIT and THG2 store pixels; MTXM, MRGN and the brushes count tiles. */
2602
2862
  readonly tile: 32;
2863
+ /** UNIT: the special unit ids, the default resource amounts, and the record's four bit masks. */
2603
2864
  readonly unit: UnitConsts;
2865
+ /** THG2: the sprite record's flag word. */
2604
2866
  readonly sprite: SpriteConsts;
2867
+ /** MRGN: the Anywhere slot, and the elevation bits. */
2605
2868
  readonly location: LocationConsts;
2869
+ /** TRIG / MBRF: the condition and action types, and the enumerated arguments. */
2870
+ readonly triggers: TriggerConsts;
2606
2871
  /** Whether a unit type is a mineral field or a vespene geyser. */
2607
2872
  isResource(unitId: number): boolean;
2608
2873
  }
@@ -2680,6 +2945,56 @@ export interface LocationConsts {
2680
2945
  readonly HighAir: 32;
2681
2946
  };
2682
2947
  }
2948
+ /**
2949
+ * The numbers a TRIG / MBRF record is written in: the condition and action types, and the
2950
+ * enumerated arguments the game stores as bare bytes.
2951
+ *
2952
+ * A trigger record is sixteen conditions and sixty-four actions of plain numbers — the
2953
+ * codec knows no types — so writing one field by field means knowing that a Countdown
2954
+ * Timer condition is type 1 and `AtLeast` is 0. `triggers.defs` says which *field* an
2955
+ * argument lives in; this says what to put in it.
2956
+ *
2957
+ * The keys of the argument groups are `ArgDef.kind`, so a generic argument editor can
2958
+ * look one up by the kind the def gave it (`api.consts.triggers[arg.kind]`).
2959
+ *
2960
+ * Generating a whole run of triggers is usually better done through
2961
+ * `tx.triggers.fromText`, which resolves names against the open map; these are for
2962
+ * editing a field of an existing record, and for reading one back.
2963
+ */
2964
+ export interface TriggerConsts {
2965
+ /** Condition `type`. */
2966
+ readonly condition: typeof ConditionType;
2967
+ /** Action `type` in TRIG. */
2968
+ readonly action: typeof ActionType;
2969
+ /** Action `type` in MBRF, where the same byte means something else. */
2970
+ readonly briefingAction: typeof BriefingActionType;
2971
+ /** The 27 player-group values, which are also the indices of a trigger's `players`. */
2972
+ readonly player: typeof PlayerGroup;
2973
+ readonly comparison: typeof Comparison;
2974
+ readonly switchState: typeof SwitchState;
2975
+ readonly switchAction: typeof SwitchAction;
2976
+ /** Set Resources / Set Score / Modify …: `SetTo`, `Add`, `Subtract`. */
2977
+ readonly modifier: typeof SetModifier;
2978
+ /** Set Doodad State / Set Invincibility: `Enable`, `Disable`, `Toggle`. */
2979
+ readonly unitState: typeof UnitState;
2980
+ readonly order: typeof Order;
2981
+ readonly alliance: typeof AllianceStatus;
2982
+ readonly resource: typeof ResourceType;
2983
+ readonly score: typeof ScoreType;
2984
+ /** The unit ids past units.dat that a condition or action accepts: *Any unit*, *Men*, *Buildings*, *Factories*. */
2985
+ readonly unitClass: typeof UnitClass;
2986
+ /** A condition's `flags`. `UnitTypeUsed` is the hint bit the text format cannot carry. */
2987
+ readonly conditionFlags: typeof ConditionFlag;
2988
+ /** An action's `flags`. */
2989
+ readonly actionFlags: typeof ActionFlag;
2990
+ /** A trigger's `flags`; `Preserve` is what `triggers.isPreserved` reads. */
2991
+ readonly triggerFlags: typeof TriggerFlag;
2992
+ /**
2993
+ * The address of the game's death table, which is the base an EUD player value is
2994
+ * counted from: `epd = (address - deathsTable) / 4 + 0x2000`.
2995
+ */
2996
+ readonly deathsTable: number;
2997
+ }
2683
2998
  export interface ActiveBrush {
2684
2999
  mode: TerrainMode;
2685
3000
  /** The Rect / isometric brush's terrain id. */
@@ -3422,6 +3737,20 @@ export interface MenuItemSpec {
3422
3737
  command?: string;
3423
3738
  }
3424
3739
  export interface MenuApi {
3740
+ /**
3741
+ * Items in the editor's menu bar.
3742
+ *
3743
+ * @example
3744
+ * api.menu.add("Tools", {
3745
+ * label: "Count units\u2026",
3746
+ * icon: "plugin",
3747
+ * run: () => api.ui.alert(`Player 1 has ${api.query.unitsOf(0).length} units.`),
3748
+ * });
3749
+ *
3750
+ * @example
3751
+ * // A path whose last segment names no submenu makes one, at the end of that menu.
3752
+ * api.menu.add("Tools/My plugin", { label: "Settings\u2026", command: "settings" });
3753
+ */
3425
3754
  add(path: MenuPath, item: MenuItemSpec): Disposable;
3426
3755
  }
3427
3756
  export type ContextSurface = "viewport" | "terrainPalette";
@@ -3455,7 +3784,10 @@ export interface ContextMenuApi {
3455
3784
  add(surface: ContextSurface, item: ContextItemSpec): Disposable;
3456
3785
  }
3457
3786
  export interface HotkeyApi {
3458
- /** `"Ctrl+Shift+I"`, `"Alt+F9"`, `"F8"` — modifiers in any order, then a key name. */
3787
+ /** `"Ctrl+Shift+I"`, `"Alt+F9"`, `"F8"` — modifiers in any order, then a key name. *
3788
+ * @example
3789
+ * api.hotkeys.add("Ctrl+Shift+W", () => handle.setVisible(!handle.visible()));
3790
+ */
3459
3791
  add(combo: string, run: (() => void) | {
3460
3792
  command: string;
3461
3793
  }): Disposable;
@@ -3504,10 +3836,26 @@ export interface DocumentEvent {
3504
3836
  * reason `"replace"`, which every other listener sees in turn.
3505
3837
  */
3506
3838
  export interface EventsApi {
3839
+ /**
3840
+ * @example
3841
+ * // Notifications, in activation order; a listener never intercepts what it hears.
3842
+ * api.events.on("document", (e) => {
3843
+ * if (e.reason === "open") check(e.fileName);
3844
+ * });
3845
+ * api.events.on("terrain", () => redraw());
3846
+ */
3507
3847
  on(event: "document", listener: (event: DocumentEvent) => void): Disposable;
3508
3848
  on(event: PluginEvent, listener: () => void): Disposable;
3509
3849
  }
3510
3850
  export interface StorageApi {
3851
+ /**
3852
+ * A small key-value store of the plugin's own, under its id in the browser's local
3853
+ * storage and listed in Preferences \u25b8 Browser storage.
3854
+ *
3855
+ * @example
3856
+ * const opts = api.storage.get("options", { showGrid: true });
3857
+ * api.storage.set("options", { ...opts, showGrid: false });
3858
+ */
3511
3859
  get<T>(key: string, fallback: T): T;
3512
3860
  set(key: string, value: unknown): void;
3513
3861
  remove(key: string): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scm-js/plugin-api",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Type declarations for the scmJS plugin API",
5
5
  "license": "MIT",
6
6
  "types": "index.d.ts",