@scm-js/plugin-api 1.42.0 → 1.44.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 +240 -105
  2. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -671,6 +671,63 @@ export interface PaletteBand {
671
671
  min: number;
672
672
  max: number;
673
673
  }
674
+ /** A parsed `.dds.vr4`: where each megatile's compressed pixels start in `bytes`. */
675
+ export interface HdTileFile {
676
+ bytes: Uint8Array;
677
+ count: number;
678
+ /** Offset of megatile N's DXT1 data (past its DDS header). */
679
+ offsets: Uint32Array;
680
+ }
681
+ /** The 2x pictures of one tileset, decoded as they are asked for. */
682
+ export interface HdTiles {
683
+ file: HdTileFile;
684
+ /** Source pixels per megatile. */
685
+ tileSize: number;
686
+ pages: HTMLCanvasElement[];
687
+ /** Megatile → slot across the pages, or -1 while it has not been drawn. */
688
+ slot: Int32Array;
689
+ used: number;
690
+ /** One cell's pixels, reused for every decode. */
691
+ scratch: ImageData | null;
692
+ /** The tileset's moving water or lava, where the data set has the files for it. */
693
+ effects?: HdEffects | null;
694
+ }
695
+ /** One picture of a `.dds.grp`: its size, and where its DXT1 blocks start. */
696
+ export interface GrpPicture {
697
+ width: number;
698
+ height: number;
699
+ data: number;
700
+ /** The blocks' length in bytes — what a compressed upload to the graphics card takes whole. */
701
+ size: number;
702
+ }
703
+ /** How a tileset's masked ground moves: ripples over water, or shimmer over lava. */
704
+ export type HdEffectKind = "water" | "heat";
705
+ /** A sequence of pictures in one file, for the graphics card: the bytes and where each picture's blocks are. */
706
+ export interface PictureSequence {
707
+ bytes: Uint8Array;
708
+ pictures: GrpPicture[];
709
+ }
710
+ /** The textures an effect is read from, shared by every tileset that has it. */
711
+ export interface HdEffectTextures {
712
+ /** Water: the slow, large ripples and the fine ones over them. */
713
+ large?: PictureSequence;
714
+ fine?: PictureSequence;
715
+ /** Heat: the noise the shimmer follows. */
716
+ noise?: {
717
+ width: number;
718
+ height: number;
719
+ rgba: Uint8Array;
720
+ };
721
+ }
722
+ /** Everything the viewport needs to animate a tileset's water or lava. */
723
+ export interface HdEffects {
724
+ kind: HdEffectKind;
725
+ /** Megatile → picture number in `masks`, or -1 for ground that stands still. */
726
+ maskOf: Int32Array;
727
+ /** The mask pictures, decoded on first use like the tiles: white where the effect is. */
728
+ masks: HdTiles;
729
+ textures: HdEffectTextures;
730
+ }
674
731
  /**
675
732
  * All of a tileset's megatiles rendered once into a single image, so the viewport can
676
733
  * draw terrain with one `drawImage` per visible tile instead of decoding minitiles on
@@ -686,6 +743,15 @@ export interface TilesetAtlas {
686
743
  averages: Uint32Array;
687
744
  /** The cycling (water/lava) megatiles, or null when the tileset has none. */
688
745
  animation: AtlasAnimation | null;
746
+ /**
747
+ * StarCraft: Remastered's 2x pictures (`hd.ts`), when View ▸ Remastered Terrain is on
748
+ * and the data set has them. `atlasSource` then answers from these, at twice the source
749
+ * size, and nothing cycles: Remastered moves water and lava by bending the finished
750
+ * picture (`hd.effects`, `viewport/effectPass.ts`), so a megatile here is always the
751
+ * still one. `image`, `averages` and `animation` stay the classic ones — the minimap
752
+ * and the far zooms use the averages either way.
753
+ */
754
+ hd?: HdTiles | null;
689
755
  }
690
756
  /**
691
757
  * A second, small atlas holding only the megatiles that reference cycling palette
@@ -858,6 +924,18 @@ export interface UnitsDat {
858
924
  groupFlags: Uint8Array;
859
925
  /** StarEdit availability flags; all zero for the legacy layout. */
860
926
  availability: Uint16Array;
927
+ /**
928
+ * The unit's voice, as sfxdata.dat ids (0 for none): the one it says when trained, and
929
+ * first–last ranges for a click, repeated clicks and an order. Only the first
930
+ * `VOICED_UNITS` have ready / annoyed / yes sounds; every unit has a "what".
931
+ */
932
+ readySound: Uint16Array;
933
+ whatSoundStart: Uint16Array;
934
+ whatSoundEnd: Uint16Array;
935
+ annoyedSoundStart: Uint16Array;
936
+ annoyedSoundEnd: Uint16Array;
937
+ yesSoundStart: Uint16Array;
938
+ yesSoundEnd: Uint16Array;
861
939
  }
862
940
  export interface FlingyDat {
863
941
  /** sprites.dat index. */
@@ -979,6 +1057,127 @@ export interface LocationPatch {
979
1057
  bottom?: number;
980
1058
  elevationFlags?: number;
981
1059
  }
1060
+ export interface WireListChange<T> {
1061
+ index: number;
1062
+ before: T | null;
1063
+ after: T | null;
1064
+ }
1065
+ export interface WireLocationChange {
1066
+ index: number;
1067
+ after: LocationRecord;
1068
+ /** The name as text (`after.nameIndex` is resolved again where it lands); null for none. */
1069
+ name: string | null;
1070
+ /** The slot was empty before: a new location, which moves to a free slot if someone else took this one. */
1071
+ created: boolean;
1072
+ }
1073
+ /**
1074
+ * One undo step's worth of terrain and objects. The grids are flat number lists: terrain
1075
+ * `[at, mtxm, tile, …]`, the others `[at, value, …]`. `reverse` marks the undo of an edit:
1076
+ * its parts go in the reverse of the usual order, as undo walks them.
1077
+ */
1078
+ export interface SyncEditOp {
1079
+ kind: "edit";
1080
+ label: string;
1081
+ /** The map size the cells index; a grid part is skipped on a map of another size. */
1082
+ width: number;
1083
+ height: number;
1084
+ reverse?: boolean;
1085
+ terrain?: number[];
1086
+ isom?: number[];
1087
+ doodadTiles?: number[];
1088
+ fog?: number[];
1089
+ /** The whole ISOM lattice (base64 of the u16 cells) the edit gave the map, or null for taking it away. */
1090
+ isomWhole?: string | null;
1091
+ maskWhole?: string | null;
1092
+ units?: WireListChange<UnitRecord>[];
1093
+ doodads?: WireListChange<DoodadRecord>[];
1094
+ sprites?: WireListChange<SpriteRecord>[];
1095
+ locations?: WireLocationChange[];
1096
+ }
1097
+ declare const SYNC_FIELDS: readonly [
1098
+ "type",
1099
+ "fileVersion",
1100
+ "nameIndex",
1101
+ "descriptionIndex",
1102
+ "playerTypes",
1103
+ "editorPlayerTypes",
1104
+ "playerRaces",
1105
+ "playerColors",
1106
+ "playerRgb",
1107
+ "forces",
1108
+ "unitSettings",
1109
+ "unitAvailability",
1110
+ "upgradeSettings",
1111
+ "upgradeRestrictions",
1112
+ "techSettings",
1113
+ "techRestrictions",
1114
+ "wavs",
1115
+ "cuwp",
1116
+ "cuwpUsed",
1117
+ "triggers",
1118
+ "briefing",
1119
+ "switchNames"
1120
+ ];
1121
+ export type SyncField = (typeof SYNC_FIELDS)[number];
1122
+ export interface SyncFieldsOp {
1123
+ kind: "fields";
1124
+ /** Each changed field's new value, packed (`pack`). */
1125
+ set: Partial<Record<SyncField, unknown>>;
1126
+ /** String slots that changed: `[index, before, after]`. */
1127
+ strings?: [
1128
+ number,
1129
+ string | null,
1130
+ string | null
1131
+ ][];
1132
+ /** The table's length afterwards (trailing blank slots are dropped). */
1133
+ stringsLength?: number;
1134
+ /** The table's width and text encoding, when they changed. */
1135
+ stringsFormat?: {
1136
+ extended: boolean;
1137
+ encoding: TextEncoding;
1138
+ };
1139
+ }
1140
+ export interface SyncExtrasOp {
1141
+ kind: "extras";
1142
+ /** `[member name, base64 bytes]`, or null bytes for a member taken out. */
1143
+ set: [
1144
+ string,
1145
+ string | null
1146
+ ][];
1147
+ }
1148
+ export interface SyncResetOp {
1149
+ kind: "reset";
1150
+ label: string;
1151
+ /** The whole scenario, base64. */
1152
+ chk: string;
1153
+ }
1154
+ export type SyncOp = SyncEditOp | SyncFieldsOp | SyncExtrasOp | SyncResetOp;
1155
+ export type ListField = "triggers" | "briefing";
1156
+ export type ValueField = Exclude<SyncField, ListField>;
1157
+ export interface StringsFormat {
1158
+ extended: boolean;
1159
+ encoding: TextEncoding;
1160
+ }
1161
+ export interface Change<T> {
1162
+ before: T;
1163
+ after: T;
1164
+ }
1165
+ /** What one dialog commit changed, each part with both of its sides. */
1166
+ export interface TablesEdit {
1167
+ /** The changed tables as JSON text (`pack`ed). */
1168
+ values?: Partial<Record<ValueField, Change<string>>>;
1169
+ lists?: Partial<Record<ListField, Change<TriggerRecord[]>>>;
1170
+ /** String slots that changed: `[index, before, after]`. */
1171
+ strings?: [
1172
+ number,
1173
+ string | null,
1174
+ string | null
1175
+ ][];
1176
+ stringsLength?: Change<number>;
1177
+ stringsFormat?: Change<StringsFormat>;
1178
+ /** The archive's files, when the commit changed them too (the Sound Editor). */
1179
+ extras?: Change<Map<string, Uint8Array>>;
1180
+ }
982
1181
  /** The change lists of one edit; `HistoryEntry` adds the label. */
983
1182
  export interface HistoryEdit {
984
1183
  changes: TileChange[];
@@ -1017,10 +1216,16 @@ export interface HistoryEdit {
1017
1216
  * on such a map). Undo removes the section again.
1018
1217
  */
1019
1218
  createdMask?: Uint8Array;
1219
+ /**
1220
+ * What a dialog wrote — settings, triggers, the briefing, strings (editor/tableHistory.ts).
1221
+ * An entry with this part has no other: `applyEntry` leaves it alone, and the undo and
1222
+ * redo atoms apply it with `applyTables`.
1223
+ */
1224
+ tables?: TablesEdit;
1020
1225
  }
1021
1226
  /**
1022
1227
  * Why the map changed: an edit recorded in the history, an undo or redo of one, a dialog
1023
- * writing its tables (settings, triggers, strings — outside the history), a change to the
1228
+ * writing its tables (settings, triggers, strings), a change to the
1024
1229
  * whole document (resize, tileset change, raw section edit), or other people's edits on a
1025
1230
  * shared map.
1026
1231
  */
@@ -1104,6 +1309,8 @@ export interface ViewFlags {
1104
1309
  animateWater: boolean;
1105
1310
  /** Run the units' iscript idle animations (turrets, pulsing buildings, fires, smoke). */
1106
1311
  animateUnits: boolean;
1312
+ /** Draw terrain and sprites from StarCraft: Remastered's 2x pictures, where the data set in use has them. */
1313
+ hdGraphics: boolean;
1107
1314
  }
1108
1315
  /**
1109
1316
  * A short notice over the map that leaves by itself — what a save says when it is done,
@@ -1217,7 +1424,7 @@ export interface StackedLine {
1217
1424
  pieces: number;
1218
1425
  }
1219
1426
  /** Every built-in dialog, by the id `openDialogAtom` takes; `DialogHost` maps each to its component. */
1220
- export type DialogId = "newMap" | "openMap" | "saveAs" | "exportImage" | "mapProperties" | "resizeMap" | "mapRevision" | "playerSettings" | "forceSettings" | "playerColors" | "unitSettings" | "upgradeSettings" | "techSettings" | "stringEditor" | "soundEditor" | "switches" | "locationList" | "unitProperties" | "locationProperties" | "spriteProperties" | "triggerEditor" | "missionBriefing" | "cuwpEditor" | "replaceTerrain" | "autoStarts" | "testMap" | "symmetry" | "gridSettings" | "preferences" | "shortcuts" | "validateMap" | "statistics" | "importTriggers" | "exportTriggers" | "importStrings" | "exportStrings" | "find" | "about" | "confirmClose" | "recovery" | "previousVersions" | "plugins" | "confirmPlugin" | "pluginDialog" | "gameData" | "update";
1427
+ export type DialogId = "newMap" | "openMap" | "saveAs" | "exportImage" | "mapProperties" | "resizeMap" | "mapRevision" | "playerSettings" | "forceSettings" | "playerColors" | "unitSettings" | "upgradeSettings" | "techSettings" | "stringEditor" | "soundEditor" | "switches" | "locationList" | "unitProperties" | "locationProperties" | "spriteProperties" | "triggerEditor" | "missionBriefing" | "cuwpEditor" | "replaceTerrain" | "autoStarts" | "testMap" | "symmetry" | "gridSettings" | "preferences" | "shortcuts" | "validateMap" | "statistics" | "importTriggers" | "exportTriggers" | "importStrings" | "exportStrings" | "find" | "about" | "confirmClose" | "recovery" | "previousVersions" | "plugins" | "confirmPlugin" | "pluginDialog" | "gameData" | "update" | "whatsNew";
1221
1428
  export interface MapImageOptions {
1222
1429
  /** Output pixels per map tile. 32 matches the game's art 1:1; 1 is a minimap. */
1223
1430
  pixelsPerTile: number;
@@ -1854,101 +2061,6 @@ export interface ChangeTilesetResult {
1854
2061
  spritesDropped: number;
1855
2062
  refilled: boolean;
1856
2063
  }
1857
- export interface WireListChange<T> {
1858
- index: number;
1859
- before: T | null;
1860
- after: T | null;
1861
- }
1862
- export interface WireLocationChange {
1863
- index: number;
1864
- after: LocationRecord;
1865
- /** The name as text (`after.nameIndex` is resolved again where it lands); null for none. */
1866
- name: string | null;
1867
- /** The slot was empty before: a new location, which moves to a free slot if someone else took this one. */
1868
- created: boolean;
1869
- }
1870
- /**
1871
- * One undo step's worth of terrain and objects. The grids are flat number lists: terrain
1872
- * `[at, mtxm, tile, …]`, the others `[at, value, …]`. `reverse` marks the undo of an edit:
1873
- * its parts go in the reverse of the usual order, as undo walks them.
1874
- */
1875
- export interface SyncEditOp {
1876
- kind: "edit";
1877
- label: string;
1878
- /** The map size the cells index; a grid part is skipped on a map of another size. */
1879
- width: number;
1880
- height: number;
1881
- reverse?: boolean;
1882
- terrain?: number[];
1883
- isom?: number[];
1884
- doodadTiles?: number[];
1885
- fog?: number[];
1886
- /** The whole ISOM lattice (base64 of the u16 cells) the edit gave the map, or null for taking it away. */
1887
- isomWhole?: string | null;
1888
- maskWhole?: string | null;
1889
- units?: WireListChange<UnitRecord>[];
1890
- doodads?: WireListChange<DoodadRecord>[];
1891
- sprites?: WireListChange<SpriteRecord>[];
1892
- locations?: WireLocationChange[];
1893
- }
1894
- declare const SYNC_FIELDS: readonly [
1895
- "type",
1896
- "fileVersion",
1897
- "nameIndex",
1898
- "descriptionIndex",
1899
- "playerTypes",
1900
- "editorPlayerTypes",
1901
- "playerRaces",
1902
- "playerColors",
1903
- "playerRgb",
1904
- "forces",
1905
- "unitSettings",
1906
- "unitAvailability",
1907
- "upgradeSettings",
1908
- "upgradeRestrictions",
1909
- "techSettings",
1910
- "techRestrictions",
1911
- "wavs",
1912
- "cuwp",
1913
- "cuwpUsed",
1914
- "triggers",
1915
- "briefing",
1916
- "switchNames"
1917
- ];
1918
- export type SyncField = (typeof SYNC_FIELDS)[number];
1919
- export interface SyncFieldsOp {
1920
- kind: "fields";
1921
- /** Each changed field's new value, packed (`pack`). */
1922
- set: Partial<Record<SyncField, unknown>>;
1923
- /** String slots that changed: `[index, before, after]`. */
1924
- strings?: [
1925
- number,
1926
- string | null,
1927
- string | null
1928
- ][];
1929
- /** The table's length afterwards (trailing blank slots are dropped). */
1930
- stringsLength?: number;
1931
- /** The table's width and text encoding, when they changed. */
1932
- stringsFormat?: {
1933
- extended: boolean;
1934
- encoding: TextEncoding;
1935
- };
1936
- }
1937
- export interface SyncExtrasOp {
1938
- kind: "extras";
1939
- /** `[member name, base64 bytes]`, or null bytes for a member taken out. */
1940
- set: [
1941
- string,
1942
- string | null
1943
- ][];
1944
- }
1945
- export interface SyncResetOp {
1946
- kind: "reset";
1947
- label: string;
1948
- /** The whole scenario, base64. */
1949
- chk: string;
1950
- }
1951
- export type SyncOp = SyncEditOp | SyncFieldsOp | SyncExtrasOp | SyncResetOp;
1952
2064
  export type SymmetryMode = "none" | "h" | "v" | "hv" | "rot180" | "rot90" | "diag" | "adiag";
1953
2065
  export type StartLayout = "ring" | "corners";
1954
2066
  export interface StartPlacementResult {
@@ -2039,6 +2151,25 @@ export type Locale = "en" | "ko";
2039
2151
  export type LanguagePreference = "auto" | Locale;
2040
2152
  /** What `Preferences.hotkeys` holds: the commands the user changed, each with its whole list (`[]` = no keys). */
2041
2153
  export type HotkeyOverrides = Record<string, string[]>;
2154
+ /**
2155
+ * The adjustable part of Remastered's moving water and lava (`viewport/effectPass.ts`).
2156
+ * How far the picture bends and how the ripple layers drift are the game's own figures;
2157
+ * how large the ripples lie on the map and how fast their pictures change are not in its
2158
+ * files, so these start from values set by eye and can be moved.
2159
+ */
2160
+ export interface RemasteredEffects {
2161
+ /** How far water bends the ground under it, as a multiple of the game's amount. 0 leaves it still. */
2162
+ bend: number;
2163
+ /** How much the ripples catch the light. 0 is none. */
2164
+ glint: number;
2165
+ /** The size of the large, slow ripples and of the fine ones over them, in map pixels a repeat. */
2166
+ large: number;
2167
+ fine: number;
2168
+ /** How many ripple pictures go by a second. */
2169
+ rate: number;
2170
+ /** How far lava's heat reaches, in map pixels at its strongest. 0 leaves it still. */
2171
+ heat: number;
2172
+ }
2042
2173
  export interface Preferences {
2043
2174
  /** The editor's own language: `"auto"` follows the browser's (the system's, in the desktop app), else one of `LOCALES`. Applied live. */
2044
2175
  language: LanguagePreference;
@@ -2120,6 +2251,10 @@ export interface Preferences {
2120
2251
  /** Initial View ▸ Animate Water / Animate Units. */
2121
2252
  animateWater: boolean;
2122
2253
  animateUnits: boolean;
2254
+ /** Initial View ▸ Remastered Graphics: the 2x terrain and sprites, where the data set in use has them. */
2255
+ hdGraphics: boolean;
2256
+ /** How Remastered's water and lava move — the part of the effect the game's files do not fix. */
2257
+ remasteredEffects: RemasteredEffects;
2123
2258
  /**
2124
2259
  * How fast the two animations run, as a multiple of the game's own speed (1 = the
2125
2260
  * game's "Fastest"). One of `ANIMATION_SPEEDS`; applied live, not just at startup.
@@ -2678,16 +2813,16 @@ export interface DocumentApi {
2678
2813
  */
2679
2814
  edit<R>(label: string, build: (tx: EditTransaction) => Sync<R>): EditResult;
2680
2815
  /**
2681
- * The second kind of write: the tables and settings that live outside the undo model
2682
- * — triggers, the string table, switch names, the scenario's own properties — as one
2683
- * transaction, the way a settings dialog's OK applies its whole form at once.
2684
- * Operations apply as they are called; the commit marks the map modified and bumps
2685
- * what the chrome reads. There is no undo entry: keep your own if you need one.
2816
+ * The second kind of write: the tables and settings the dialogs edit — triggers, the
2817
+ * string table, switch names, the scenario's own properties — as one transaction, the
2818
+ * way a settings dialog's OK applies its whole form at once. Operations apply as they
2819
+ * are called; the commit marks the map modified, bumps what the chrome reads and
2820
+ * records what changed as one undo entry under `label`.
2686
2821
  * `build` is synchronous, as `edit`'s is, and closed when it returns.
2687
2822
  *
2688
- * There is nothing to roll an update back with, so a builder that throws leaves what
2689
- * it wrote: the sections it touched are committed — the map is modified and the
2690
- * chrome re-reads — and the error reaches you.
2823
+ * An update is not rolled back, so a builder that throws leaves what it wrote: the
2824
+ * sections it touched are committed — the map is modified, the chrome re-reads, the
2825
+ * undo entry holds what was written — and the error reaches you.
2691
2826
  *
2692
2827
  * @example
2693
2828
  * api.document.update("Rename", (tx) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scm-js/plugin-api",
3
- "version": "1.42.0",
3
+ "version": "1.44.0",
4
4
  "description": "Type declarations for the scmJS plugin API",
5
5
  "license": "MIT",
6
6
  "types": "index.d.ts",