@scm-js/plugin-api 1.3.0 → 1.5.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.
- package/index.d.ts +445 -4
- 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
|
*
|
|
@@ -683,6 +902,8 @@ export interface ImagesDat {
|
|
|
683
902
|
lo: Uint32Array[];
|
|
684
903
|
}
|
|
685
904
|
export interface WeaponsDat {
|
|
905
|
+
/** The weapon's name: a 1-based `stat_txt.tbl` index, 0 for none. */
|
|
906
|
+
label: Uint16Array;
|
|
686
907
|
damage: Uint16Array;
|
|
687
908
|
/** Added per upgrade level. */
|
|
688
909
|
bonus: Uint16Array;
|
|
@@ -701,6 +922,8 @@ export interface UpgradesDat {
|
|
|
701
922
|
maxRepeats: Uint8Array;
|
|
702
923
|
/** 1 for upgrades only Brood War has. */
|
|
703
924
|
broodWar: Uint8Array;
|
|
925
|
+
/** The upgrade's name: a 1-based `stat_txt.tbl` index, 0 for none. */
|
|
926
|
+
label: Uint16Array;
|
|
704
927
|
}
|
|
705
928
|
/** The columns Technology Settings shows as defaults. */
|
|
706
929
|
export interface TechdataDat {
|
|
@@ -711,6 +934,8 @@ export interface TechdataDat {
|
|
|
711
934
|
energyCost: Uint16Array;
|
|
712
935
|
/** 1 for abilities only Brood War has. */
|
|
713
936
|
broodWar: Uint8Array;
|
|
937
|
+
/** The technology's name: a 1-based `stat_txt.tbl` index, 0 for none. */
|
|
938
|
+
label: Uint16Array;
|
|
714
939
|
}
|
|
715
940
|
export interface SpriteGroup {
|
|
716
941
|
label: string;
|
|
@@ -1659,33 +1884,62 @@ export interface PluginInfo {
|
|
|
1659
1884
|
export interface PluginApi {
|
|
1660
1885
|
readonly apiVersion: number;
|
|
1661
1886
|
readonly plugin: PluginInfo;
|
|
1887
|
+
/**
|
|
1888
|
+
* The open map: what it says, and the three ways of writing to it — `edit` (terrain and
|
|
1889
|
+
* objects, one undo entry), `update` (the tables every dialog's OK writes) and
|
|
1890
|
+
* `sections` (raw bytes). Opening, saving, exporting and closing are here too.
|
|
1891
|
+
*/
|
|
1662
1892
|
readonly document: DocumentApi;
|
|
1663
1893
|
/** The settings dialogs' tables, read-only; `document.update` writes them. */
|
|
1664
1894
|
readonly settings: SettingsApi;
|
|
1665
1895
|
readonly triggers: TriggersApi;
|
|
1896
|
+
/**
|
|
1897
|
+
* Reading the terrain: the tileset's paintable types, the ISOM lattice, flood regions,
|
|
1898
|
+
* blend candidates and the symmetry mode. Painting goes through `document.edit`.
|
|
1899
|
+
*/
|
|
1666
1900
|
readonly terrain: TerrainApi;
|
|
1901
|
+
/** The loaded tileset graphics: whether they are there, and the decoded files behind them. */
|
|
1667
1902
|
readonly tileset: TilesetApi;
|
|
1903
|
+
/** What is selected on each object layer, the marked area, the active layer and the locked ones. */
|
|
1668
1904
|
readonly selection: SelectionApi;
|
|
1669
1905
|
/** Cut / Copy / Paste: the clip, its parts, and pasting — what the clipboard layer does. */
|
|
1670
1906
|
readonly clipboard: ClipboardApi;
|
|
1671
1907
|
/** The file formats behind File ▸ Import / Export: `.trg` and the strings text. */
|
|
1672
1908
|
readonly exchange: ExchangeApi;
|
|
1909
|
+
/**
|
|
1910
|
+
* The palettes' current picks — the terrain brush, the unit, sprite and doodad, the fog
|
|
1911
|
+
* mode — and the placement options a plugin that places things should honour.
|
|
1912
|
+
*/
|
|
1673
1913
|
readonly palette: PaletteApi;
|
|
1674
1914
|
readonly names: NamesApi;
|
|
1675
1915
|
/** StarCraft's `<XX>` text control codes: what they mean, and what a string looks like drawn. */
|
|
1676
1916
|
readonly text: TextApi;
|
|
1677
1917
|
readonly query: QueryApi;
|
|
1678
1918
|
readonly data: DataApi;
|
|
1919
|
+
/** Which set of game files the editor draws from — the game's own or a mod's — and installing, switching and removing sets. */
|
|
1920
|
+
readonly gameData: GameDataApi;
|
|
1679
1921
|
/** Bit masks, special unit ids and the pixels-per-tile every record is written in. */
|
|
1680
1922
|
readonly consts: ConstsApi;
|
|
1681
1923
|
readonly graphics: GraphicsApi;
|
|
1682
1924
|
readonly view: ViewApi;
|
|
1925
|
+
/**
|
|
1926
|
+
* Everything a plugin puts on the screen: the status line, toasts, dialogs, floating
|
|
1927
|
+
* panels, `confirm` / `alert` / `prompt` / `progress`, a map tool that owns the pointer,
|
|
1928
|
+
* a passive overlay drawn over the map, and picking an area or a tile.
|
|
1929
|
+
*/
|
|
1683
1930
|
readonly ui: UiApi;
|
|
1931
|
+
/** Items in the editor's menu bar. A path whose last segment names no submenu makes one. */
|
|
1684
1932
|
readonly menu: MenuApi;
|
|
1933
|
+
/** Items in the right-click menus of the map and the terrain palette. */
|
|
1685
1934
|
readonly contextMenu: ContextMenuApi;
|
|
1935
|
+
/** Key combinations, tried before the editor's own and never while a text field has focus. */
|
|
1686
1936
|
readonly hotkeys: HotkeyApi;
|
|
1687
1937
|
readonly commands: CommandsApi;
|
|
1688
1938
|
readonly events: EventsApi;
|
|
1939
|
+
/**
|
|
1940
|
+
* A small key-value store of the plugin's own, kept in the browser's local storage under
|
|
1941
|
+
* the plugin's id and listed with everything else in Preferences ▸ Browser storage.
|
|
1942
|
+
*/
|
|
1689
1943
|
readonly storage: StorageApi;
|
|
1690
1944
|
/** `console.log` with the plugin's name in front. */
|
|
1691
1945
|
log(...args: unknown[]): void;
|
|
@@ -1804,6 +2058,14 @@ export interface DocumentApi {
|
|
|
1804
2058
|
*
|
|
1805
2059
|
* `build` is synchronous — see `Sync`. Await what you need (graphics, a pick, a
|
|
1806
2060
|
* fetch) before the call, then write in one go.
|
|
2061
|
+
*
|
|
2062
|
+
* @example
|
|
2063
|
+
* // One undo entry called "Fill", however many operations it takes.
|
|
2064
|
+
* const result = api.document.edit("Fill", (tx) => {
|
|
2065
|
+
* tx.stampTerrain({ x0: 0, y0: 0, x1: 8, y1: 8 }, terrainId);
|
|
2066
|
+
* tx.placeUnit(api.consts.unit.startLocation, 0, 4 * api.consts.tile, 4 * api.consts.tile);
|
|
2067
|
+
* });
|
|
2068
|
+
* api.ui.status(`${result.tiles} tiles, ${result.units} units`);
|
|
1807
2069
|
*/
|
|
1808
2070
|
edit<R>(label: string, build: (tx: EditTransaction) => Sync<R>): EditResult;
|
|
1809
2071
|
/**
|
|
@@ -1813,6 +2075,11 @@ export interface DocumentApi {
|
|
|
1813
2075
|
* Operations apply as they are called; the commit marks the map modified and bumps
|
|
1814
2076
|
* what the chrome reads. There is no undo entry: keep your own if you need one.
|
|
1815
2077
|
* `build` is synchronous, as `edit`'s is.
|
|
2078
|
+
*
|
|
2079
|
+
* @example
|
|
2080
|
+
* api.document.update("Rename", (tx) => {
|
|
2081
|
+
* tx.properties({ name: "Lost Temple", description: "Four players." });
|
|
2082
|
+
* });
|
|
1816
2083
|
*/
|
|
1817
2084
|
update<R>(label: string, build: (tx: UpdateTransaction) => Sync<R>): UpdateResult;
|
|
1818
2085
|
undo(): string | null;
|
|
@@ -2585,10 +2852,94 @@ export interface DataApi {
|
|
|
2585
2852
|
/** The GRP path an image id draws from, relative to `unit\`. */
|
|
2586
2853
|
imagePath(imageId: number): string | null;
|
|
2587
2854
|
}
|
|
2855
|
+
/**
|
|
2856
|
+
* A data set: one set of game files the editor draws from. The default is the game's
|
|
2857
|
+
* own; any other is a mod's, installed under an id of its own, the same formats and
|
|
2858
|
+
* table sizes with some of the files replaced.
|
|
2859
|
+
*/
|
|
2860
|
+
export interface GameDataProfile {
|
|
2861
|
+
/** Lower-case letters, digits and hyphens, up to 40 characters. */
|
|
2862
|
+
id: string;
|
|
2863
|
+
/** What the dialog and the status line call it. */
|
|
2864
|
+
name: string;
|
|
2865
|
+
}
|
|
2866
|
+
/** Where the session's game data comes from. */
|
|
2867
|
+
export interface GameDataSource {
|
|
2868
|
+
/** `bundled` (this build's own files, or the desktop app's extraction), `stored` (a copy kept in the browser), or `none`. */
|
|
2869
|
+
kind: "bundled" | "stored" | "none";
|
|
2870
|
+
/** One line, as Help ▸ Game Data… shows it. */
|
|
2871
|
+
label: string;
|
|
2872
|
+
/** The data set the files belong to. */
|
|
2873
|
+
profile: GameDataProfile;
|
|
2874
|
+
/** Set when the desktop app extracted the files from a StarCraft installation. */
|
|
2875
|
+
desktop: boolean;
|
|
2876
|
+
}
|
|
2877
|
+
/** Bytes for an install: a `File` / `Blob`, or already an array. */
|
|
2878
|
+
export type GameDataBytes = Blob | Uint8Array;
|
|
2879
|
+
/** What a data set is installed from. */
|
|
2880
|
+
export interface GameDataFiles {
|
|
2881
|
+
/**
|
|
2882
|
+
* The archives, `StarDat.mpq` and `BrooDat.mpq` among them — a mod replaces files, it
|
|
2883
|
+
* does not bring the rest. The game's own are read first, then the others in the order
|
|
2884
|
+
* given, later ones winning as in the game.
|
|
2885
|
+
*/
|
|
2886
|
+
archives: readonly {
|
|
2887
|
+
name: string;
|
|
2888
|
+
data: GameDataBytes;
|
|
2889
|
+
}[];
|
|
2890
|
+
/** Loose files by member path (`arr/units.dat`, `unit/terran/marine.grp`), read before any archive. */
|
|
2891
|
+
files?: readonly {
|
|
2892
|
+
path: string;
|
|
2893
|
+
data: GameDataBytes;
|
|
2894
|
+
}[];
|
|
2895
|
+
}
|
|
2896
|
+
/**
|
|
2897
|
+
* The game data as a whole: which set of files the editor draws from, and installing,
|
|
2898
|
+
* switching and removing sets — the plugin side of Help ▸ Game Data…. What is *in* the
|
|
2899
|
+
* files is `data` (the tables), `tileset` (the graphics), `graphics` (the pictures) and
|
|
2900
|
+
* `names` (the labels, which follow the loaded set: a unit, weapon, upgrade or
|
|
2901
|
+
* technology a mod renamed shows its new name, and the rest keep StarEdit's).
|
|
2902
|
+
*
|
|
2903
|
+
* A data set is a name over files in the game's own formats; a mod that extends the
|
|
2904
|
+
* tables past the game's sizes is not covered. Installing needs the game's two archives
|
|
2905
|
+
* every time, since a mod's files are laid over them the way its loader lays them.
|
|
2906
|
+
*
|
|
2907
|
+
* @example
|
|
2908
|
+
* // A mod plugin: install its files once, then draw with them.
|
|
2909
|
+
* const sets = await api.gameData.profiles();
|
|
2910
|
+
* if (!sets.some((p) => p.id === "my-mod")) {
|
|
2911
|
+
* const files = await api.ui.pickFiles({ multiple: true });
|
|
2912
|
+
* if (files) await api.gameData.install({ id: "my-mod", name: "My Mod" }, { archives: files.map((f) => ({ name: f.name, data: f })) });
|
|
2913
|
+
* }
|
|
2914
|
+
* await api.gameData.select("my-mod");
|
|
2915
|
+
*/
|
|
2916
|
+
export interface GameDataApi {
|
|
2917
|
+
/** The session's source, or null while it is still being resolved at startup. */
|
|
2918
|
+
source(): GameDataSource | null;
|
|
2919
|
+
/** The data set in use — the game's own until another is selected. */
|
|
2920
|
+
profile(): GameDataProfile;
|
|
2921
|
+
/** Every data set with a copy here, the game's own first. */
|
|
2922
|
+
profiles(): Promise<GameDataProfile[]>;
|
|
2923
|
+
/**
|
|
2924
|
+
* Extract a data set from its files, store it under `profile.id` and switch to it. The
|
|
2925
|
+
* archives must include the game's own two; the promise rejects with the reason when
|
|
2926
|
+
* they do not or the extraction fails. `progress` is 0–1 with a label, as the dialog's bar.
|
|
2927
|
+
*/
|
|
2928
|
+
install(profile: GameDataProfile, files: GameDataFiles, progress?: (fraction: number, label: string) => void): Promise<GameDataSource>;
|
|
2929
|
+
/**
|
|
2930
|
+
* Switch to a data set. Everything decoded from the previous one is dropped and the
|
|
2931
|
+
* viewport redraws from the new files; a set with no copy here falls back to the game's
|
|
2932
|
+
* own. Resolves with the source in use afterwards.
|
|
2933
|
+
*/
|
|
2934
|
+
select(id: string): Promise<GameDataSource>;
|
|
2935
|
+
/** Remove a data set's copy (never the game's bundled files). True when there was one. */
|
|
2936
|
+
remove(id: string): Promise<boolean>;
|
|
2937
|
+
}
|
|
2588
2938
|
/**
|
|
2589
2939
|
* The constants a plugin needs to *write* a record rather than read one: the bit masks in
|
|
2590
|
-
* a UNIT / THG2 / MRGN record, the
|
|
2591
|
-
* one
|
|
2940
|
+
* a UNIT / THG2 / MRGN record, the condition, action and argument numbers of a TRIG /
|
|
2941
|
+
* MBRF one, the few unit ids the game itself treats specially, and the one conversion —
|
|
2942
|
+
* 32 pixels to a tile — every object position goes through.
|
|
2592
2943
|
*
|
|
2593
2944
|
* They are the editor's own (`sections/objects.ts`, `editor/units.ts`) and they arrive
|
|
2594
2945
|
* here at run time rather than in the typings on purpose: `@scm-js/plugin-api` is erased
|
|
@@ -2600,9 +2951,14 @@ export interface DataApi {
|
|
|
2600
2951
|
export interface ConstsApi {
|
|
2601
2952
|
/** Map pixels to a tile. UNIT and THG2 store pixels; MTXM, MRGN and the brushes count tiles. */
|
|
2602
2953
|
readonly tile: 32;
|
|
2954
|
+
/** UNIT: the special unit ids, the default resource amounts, and the record's four bit masks. */
|
|
2603
2955
|
readonly unit: UnitConsts;
|
|
2956
|
+
/** THG2: the sprite record's flag word. */
|
|
2604
2957
|
readonly sprite: SpriteConsts;
|
|
2958
|
+
/** MRGN: the Anywhere slot, and the elevation bits. */
|
|
2605
2959
|
readonly location: LocationConsts;
|
|
2960
|
+
/** TRIG / MBRF: the condition and action types, and the enumerated arguments. */
|
|
2961
|
+
readonly triggers: TriggerConsts;
|
|
2606
2962
|
/** Whether a unit type is a mineral field or a vespene geyser. */
|
|
2607
2963
|
isResource(unitId: number): boolean;
|
|
2608
2964
|
}
|
|
@@ -2680,6 +3036,56 @@ export interface LocationConsts {
|
|
|
2680
3036
|
readonly HighAir: 32;
|
|
2681
3037
|
};
|
|
2682
3038
|
}
|
|
3039
|
+
/**
|
|
3040
|
+
* The numbers a TRIG / MBRF record is written in: the condition and action types, and the
|
|
3041
|
+
* enumerated arguments the game stores as bare bytes.
|
|
3042
|
+
*
|
|
3043
|
+
* A trigger record is sixteen conditions and sixty-four actions of plain numbers — the
|
|
3044
|
+
* codec knows no types — so writing one field by field means knowing that a Countdown
|
|
3045
|
+
* Timer condition is type 1 and `AtLeast` is 0. `triggers.defs` says which *field* an
|
|
3046
|
+
* argument lives in; this says what to put in it.
|
|
3047
|
+
*
|
|
3048
|
+
* The keys of the argument groups are `ArgDef.kind`, so a generic argument editor can
|
|
3049
|
+
* look one up by the kind the def gave it (`api.consts.triggers[arg.kind]`).
|
|
3050
|
+
*
|
|
3051
|
+
* Generating a whole run of triggers is usually better done through
|
|
3052
|
+
* `tx.triggers.fromText`, which resolves names against the open map; these are for
|
|
3053
|
+
* editing a field of an existing record, and for reading one back.
|
|
3054
|
+
*/
|
|
3055
|
+
export interface TriggerConsts {
|
|
3056
|
+
/** Condition `type`. */
|
|
3057
|
+
readonly condition: typeof ConditionType;
|
|
3058
|
+
/** Action `type` in TRIG. */
|
|
3059
|
+
readonly action: typeof ActionType;
|
|
3060
|
+
/** Action `type` in MBRF, where the same byte means something else. */
|
|
3061
|
+
readonly briefingAction: typeof BriefingActionType;
|
|
3062
|
+
/** The 27 player-group values, which are also the indices of a trigger's `players`. */
|
|
3063
|
+
readonly player: typeof PlayerGroup;
|
|
3064
|
+
readonly comparison: typeof Comparison;
|
|
3065
|
+
readonly switchState: typeof SwitchState;
|
|
3066
|
+
readonly switchAction: typeof SwitchAction;
|
|
3067
|
+
/** Set Resources / Set Score / Modify …: `SetTo`, `Add`, `Subtract`. */
|
|
3068
|
+
readonly modifier: typeof SetModifier;
|
|
3069
|
+
/** Set Doodad State / Set Invincibility: `Enable`, `Disable`, `Toggle`. */
|
|
3070
|
+
readonly unitState: typeof UnitState;
|
|
3071
|
+
readonly order: typeof Order;
|
|
3072
|
+
readonly alliance: typeof AllianceStatus;
|
|
3073
|
+
readonly resource: typeof ResourceType;
|
|
3074
|
+
readonly score: typeof ScoreType;
|
|
3075
|
+
/** The unit ids past units.dat that a condition or action accepts: *Any unit*, *Men*, *Buildings*, *Factories*. */
|
|
3076
|
+
readonly unitClass: typeof UnitClass;
|
|
3077
|
+
/** A condition's `flags`. `UnitTypeUsed` is the hint bit the text format cannot carry. */
|
|
3078
|
+
readonly conditionFlags: typeof ConditionFlag;
|
|
3079
|
+
/** An action's `flags`. */
|
|
3080
|
+
readonly actionFlags: typeof ActionFlag;
|
|
3081
|
+
/** A trigger's `flags`; `Preserve` is what `triggers.isPreserved` reads. */
|
|
3082
|
+
readonly triggerFlags: typeof TriggerFlag;
|
|
3083
|
+
/**
|
|
3084
|
+
* The address of the game's death table, which is the base an EUD player value is
|
|
3085
|
+
* counted from: `epd = (address - deathsTable) / 4 + 0x2000`.
|
|
3086
|
+
*/
|
|
3087
|
+
readonly deathsTable: number;
|
|
3088
|
+
}
|
|
2683
3089
|
export interface ActiveBrush {
|
|
2684
3090
|
mode: TerrainMode;
|
|
2685
3091
|
/** The Rect / isometric brush's terrain id. */
|
|
@@ -3422,6 +3828,20 @@ export interface MenuItemSpec {
|
|
|
3422
3828
|
command?: string;
|
|
3423
3829
|
}
|
|
3424
3830
|
export interface MenuApi {
|
|
3831
|
+
/**
|
|
3832
|
+
* Items in the editor's menu bar.
|
|
3833
|
+
*
|
|
3834
|
+
* @example
|
|
3835
|
+
* api.menu.add("Tools", {
|
|
3836
|
+
* label: "Count units\u2026",
|
|
3837
|
+
* icon: "plugin",
|
|
3838
|
+
* run: () => api.ui.alert(`Player 1 has ${api.query.unitsOf(0).length} units.`),
|
|
3839
|
+
* });
|
|
3840
|
+
*
|
|
3841
|
+
* @example
|
|
3842
|
+
* // A path whose last segment names no submenu makes one, at the end of that menu.
|
|
3843
|
+
* api.menu.add("Tools/My plugin", { label: "Settings\u2026", command: "settings" });
|
|
3844
|
+
*/
|
|
3425
3845
|
add(path: MenuPath, item: MenuItemSpec): Disposable;
|
|
3426
3846
|
}
|
|
3427
3847
|
export type ContextSurface = "viewport" | "terrainPalette";
|
|
@@ -3455,7 +3875,10 @@ export interface ContextMenuApi {
|
|
|
3455
3875
|
add(surface: ContextSurface, item: ContextItemSpec): Disposable;
|
|
3456
3876
|
}
|
|
3457
3877
|
export interface HotkeyApi {
|
|
3458
|
-
/** `"Ctrl+Shift+I"`, `"Alt+F9"`, `"F8"` — modifiers in any order, then a key name.
|
|
3878
|
+
/** `"Ctrl+Shift+I"`, `"Alt+F9"`, `"F8"` — modifiers in any order, then a key name. *
|
|
3879
|
+
* @example
|
|
3880
|
+
* api.hotkeys.add("Ctrl+Shift+W", () => handle.setVisible(!handle.visible()));
|
|
3881
|
+
*/
|
|
3459
3882
|
add(combo: string, run: (() => void) | {
|
|
3460
3883
|
command: string;
|
|
3461
3884
|
}): Disposable;
|
|
@@ -3482,7 +3905,9 @@ export type PluginEvent =
|
|
|
3482
3905
|
/** The document's file changed: its name or handle after a Save, the save options, the archive extras, the recent list. */
|
|
3483
3906
|
| "file"
|
|
3484
3907
|
/** A plugin registered or removed a command — how a plugin learns that one it calls by id has arrived. */
|
|
3485
|
-
| "commands"
|
|
3908
|
+
| "commands"
|
|
3909
|
+
/** The game data source changed: installed, switched to another data set, or a copy removed. `gameData.source()` says what it is now. */
|
|
3910
|
+
| "gameData";
|
|
3486
3911
|
/** Why the document changed. */
|
|
3487
3912
|
export type DocumentChangeReason =
|
|
3488
3913
|
/** File ▸ Open, drag-and-drop, `document.open`: a file the user chose. */
|
|
@@ -3504,10 +3929,26 @@ export interface DocumentEvent {
|
|
|
3504
3929
|
* reason `"replace"`, which every other listener sees in turn.
|
|
3505
3930
|
*/
|
|
3506
3931
|
export interface EventsApi {
|
|
3932
|
+
/**
|
|
3933
|
+
* @example
|
|
3934
|
+
* // Notifications, in activation order; a listener never intercepts what it hears.
|
|
3935
|
+
* api.events.on("document", (e) => {
|
|
3936
|
+
* if (e.reason === "open") check(e.fileName);
|
|
3937
|
+
* });
|
|
3938
|
+
* api.events.on("terrain", () => redraw());
|
|
3939
|
+
*/
|
|
3507
3940
|
on(event: "document", listener: (event: DocumentEvent) => void): Disposable;
|
|
3508
3941
|
on(event: PluginEvent, listener: () => void): Disposable;
|
|
3509
3942
|
}
|
|
3510
3943
|
export interface StorageApi {
|
|
3944
|
+
/**
|
|
3945
|
+
* A small key-value store of the plugin's own, under its id in the browser's local
|
|
3946
|
+
* storage and listed in Preferences \u25b8 Browser storage.
|
|
3947
|
+
*
|
|
3948
|
+
* @example
|
|
3949
|
+
* const opts = api.storage.get("options", { showGrid: true });
|
|
3950
|
+
* api.storage.set("options", { ...opts, showGrid: false });
|
|
3951
|
+
*/
|
|
3511
3952
|
get<T>(key: string, fallback: T): T;
|
|
3512
3953
|
set(key: string, value: unknown): void;
|
|
3513
3954
|
remove(key: string): void;
|