afnm-types 0.6.54 → 0.6.55

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.
@@ -11,83 +11,83 @@
11
11
  // Replicates the hand-authored glitch art style: strong persistent chromatic
12
12
  // aberration (cyan/magenta fringing always visible), periodic brightness
13
13
  // washout, and horizontal scanline tears during burst events.
14
- const GLITCH_FRAG_SRC = `#version 300 es
15
- precision mediump float;
16
- in vec2 v_uv;
17
- uniform sampler2D u_texA;
18
- uniform sampler2D u_texB;
19
- uniform float u_mix;
20
- uniform float u_aspectA;
21
- uniform float u_aspectB;
22
- uniform float u_canvasAspect;
23
- uniform float u_time;
24
- out vec4 fragColor;
25
-
26
- float hash(float n) {
27
- return fract(sin(n) * 43758.5453);
28
- }
29
-
30
- vec4 sampleContain(sampler2D tex, vec2 uv, float texAspect) {
31
- float rel = texAspect / u_canvasAspect;
32
- vec2 scale;
33
- if (rel > 1.0) {
34
- scale = vec2(1.0, 1.0 / rel);
35
- } else {
36
- scale = vec2(rel, 1.0);
37
- }
38
- vec2 offset = (1.0 - scale) * 0.5;
39
- vec2 mapped = (uv - offset) / scale;
40
- if (mapped.x < 0.0 || mapped.x > 1.0 || mapped.y < 0.0 || mapped.y > 1.0) {
41
- return vec4(0.0);
42
- }
43
- return texture(tex, mapped);
44
- }
45
-
46
- void main() {
47
- vec2 uv = v_uv;
48
-
49
- // Glitch burst timing — ~0.8 event slots per second, 35% chance each.
50
- float eventT = floor(u_time * 0.8);
51
- float isGlitching = step(0.65, hash(eventT * 1.618));
52
- // Sharp onset, slow decay — the burst lingers before fading.
53
- float slotFrac = fract(u_time * 0.8);
54
- float decay = (1.0 - smoothstep(0.1, 0.9, slotFrac)) * isGlitching;
55
-
56
- // Band-based horizontal displacement (scanline tearing) during bursts.
57
- float band = floor(uv.y * 24.0);
58
- float bandActive = step(0.55, hash(band + eventT * 23.7));
59
- float bandShift = (hash(band * 5.2 + eventT * 7.1) * 2.0 - 1.0) * 0.025;
60
- float shift = bandShift * bandActive * decay;
61
-
62
- // Occasional large block tears.
63
- float bigTear = step(0.92, hash(band * 3.7 + eventT * 11.3));
64
- shift += (hash(band * 9.1 + eventT * 4.7) * 2.0 - 1.0) * 0.08 * bigTear * decay;
65
-
66
- vec2 shiftedUv = vec2(uv.x + shift, uv.y);
67
-
68
- // Chromatic aberration: strong baseline always present, amplified by bursts.
69
- float aberr = 0.012 + 0.018 * decay;
70
-
71
- float rA = sampleContain(u_texA, vec2(shiftedUv.x + aberr, shiftedUv.y), u_aspectA).r;
72
- float gA = sampleContain(u_texA, shiftedUv, u_aspectA).g;
73
- float bA = sampleContain(u_texA, vec2(shiftedUv.x - aberr, shiftedUv.y), u_aspectA).b;
74
- float aA = sampleContain(u_texA, shiftedUv, u_aspectA).a;
75
- vec4 colA = vec4(rA, gA, bA, aA);
76
-
77
- float rB = sampleContain(u_texB, vec2(shiftedUv.x + aberr, shiftedUv.y), u_aspectB).r;
78
- float gB = sampleContain(u_texB, shiftedUv, u_aspectB).g;
79
- float bB = sampleContain(u_texB, vec2(shiftedUv.x - aberr, shiftedUv.y), u_aspectB).b;
80
- float aB = sampleContain(u_texB, shiftedUv, u_aspectB).a;
81
- vec4 colB = vec4(rB, gB, bB, aB);
82
-
83
- vec4 col = mix(colA, colB, u_mix);
84
-
85
- // Brightness washout during bursts — push toward overexposed white,
86
- // scaled by alpha so transparent edges don't bloom.
87
- float blowout = decay * 0.45;
88
- col.rgb = mix(col.rgb, vec3(1.0), blowout * col.a);
89
-
90
- fragColor = col;
14
+ const GLITCH_FRAG_SRC = `#version 300 es
15
+ precision mediump float;
16
+ in vec2 v_uv;
17
+ uniform sampler2D u_texA;
18
+ uniform sampler2D u_texB;
19
+ uniform float u_mix;
20
+ uniform float u_aspectA;
21
+ uniform float u_aspectB;
22
+ uniform float u_canvasAspect;
23
+ uniform float u_time;
24
+ out vec4 fragColor;
25
+
26
+ float hash(float n) {
27
+ return fract(sin(n) * 43758.5453);
28
+ }
29
+
30
+ vec4 sampleContain(sampler2D tex, vec2 uv, float texAspect) {
31
+ float rel = texAspect / u_canvasAspect;
32
+ vec2 scale;
33
+ if (rel > 1.0) {
34
+ scale = vec2(1.0, 1.0 / rel);
35
+ } else {
36
+ scale = vec2(rel, 1.0);
37
+ }
38
+ vec2 offset = (1.0 - scale) * 0.5;
39
+ vec2 mapped = (uv - offset) / scale;
40
+ if (mapped.x < 0.0 || mapped.x > 1.0 || mapped.y < 0.0 || mapped.y > 1.0) {
41
+ return vec4(0.0);
42
+ }
43
+ return texture(tex, mapped);
44
+ }
45
+
46
+ void main() {
47
+ vec2 uv = v_uv;
48
+
49
+ // Glitch burst timing — ~0.8 event slots per second, 35% chance each.
50
+ float eventT = floor(u_time * 0.8);
51
+ float isGlitching = step(0.65, hash(eventT * 1.618));
52
+ // Sharp onset, slow decay — the burst lingers before fading.
53
+ float slotFrac = fract(u_time * 0.8);
54
+ float decay = (1.0 - smoothstep(0.1, 0.9, slotFrac)) * isGlitching;
55
+
56
+ // Band-based horizontal displacement (scanline tearing) during bursts.
57
+ float band = floor(uv.y * 24.0);
58
+ float bandActive = step(0.55, hash(band + eventT * 23.7));
59
+ float bandShift = (hash(band * 5.2 + eventT * 7.1) * 2.0 - 1.0) * 0.025;
60
+ float shift = bandShift * bandActive * decay;
61
+
62
+ // Occasional large block tears.
63
+ float bigTear = step(0.92, hash(band * 3.7 + eventT * 11.3));
64
+ shift += (hash(band * 9.1 + eventT * 4.7) * 2.0 - 1.0) * 0.08 * bigTear * decay;
65
+
66
+ vec2 shiftedUv = vec2(uv.x + shift, uv.y);
67
+
68
+ // Chromatic aberration: strong baseline always present, amplified by bursts.
69
+ float aberr = 0.012 + 0.018 * decay;
70
+
71
+ float rA = sampleContain(u_texA, vec2(shiftedUv.x + aberr, shiftedUv.y), u_aspectA).r;
72
+ float gA = sampleContain(u_texA, shiftedUv, u_aspectA).g;
73
+ float bA = sampleContain(u_texA, vec2(shiftedUv.x - aberr, shiftedUv.y), u_aspectA).b;
74
+ float aA = sampleContain(u_texA, shiftedUv, u_aspectA).a;
75
+ vec4 colA = vec4(rA, gA, bA, aA);
76
+
77
+ float rB = sampleContain(u_texB, vec2(shiftedUv.x + aberr, shiftedUv.y), u_aspectB).r;
78
+ float gB = sampleContain(u_texB, shiftedUv, u_aspectB).g;
79
+ float bB = sampleContain(u_texB, vec2(shiftedUv.x - aberr, shiftedUv.y), u_aspectB).b;
80
+ float aB = sampleContain(u_texB, shiftedUv, u_aspectB).a;
81
+ vec4 colB = vec4(rB, gB, bB, aB);
82
+
83
+ vec4 col = mix(colA, colB, u_mix);
84
+
85
+ // Brightness washout during bursts — push toward overexposed white,
86
+ // scaled by alpha so transparent edges don't bloom.
87
+ float blowout = decay * 0.45;
88
+ col.rgb = mix(col.rgb, vec3(1.0), blowout * col.a);
89
+
90
+ fragColor = col;
91
91
  }`;
92
92
  // ─── Registry ─────────────────────────────────────────────────────────────────
93
93
  /**
@@ -357,9 +357,6 @@ async function main() {
357
357
  console.log(` 1. Open ${templatePath}`);
358
358
  console.log(' 2. Copy it to a new language file, e.g. translations/ru.json');
359
359
  console.log(' 3. Fill in the translated values for each key');
360
- console.log(' 4. Register the translations in your mod:');
361
- console.log(" import ruTranslations from './translations/ru.json';");
362
- console.log(" api.addTranslation('ru', ruTranslations);");
363
360
  }
364
361
  main().catch((error) => {
365
362
  console.error('Fatal error:', error);
@@ -15,4 +15,4 @@
15
15
  * };
16
16
  * }
17
17
  */
18
- export declare const GAME_VERSION = "0.6.54";
18
+ export declare const GAME_VERSION = "0.6.55";
@@ -15,4 +15,4 @@
15
15
  * };
16
16
  * }
17
17
  */
18
- export const GAME_VERSION = "0.6.54";
18
+ export const GAME_VERSION = "0.6.55";
@@ -1,14 +1,22 @@
1
1
  export type KeybindingCategory = 'general' | 'navigation' | 'ui' | 'world' | 'combat' | 'crafting' | 'dialogs' | 'gamepad';
2
2
  export type KeybindingAction = 'confirm' | 'cancel' | 'pause' | 'alternateConfirm' | 'moveUp' | 'moveDown' | 'moveLeft' | 'moveRight' | 'openInventory' | 'openQuests' | 'openCharacterStats' | 'openTechniques' | 'openCalendar' | 'openWorldMap' | 'combatSelectStance0' | 'combatSelectStance1' | 'combatSelectStance2' | 'combatSelectStance3' | 'combatSelectStance4' | 'combatSelectStance5' | 'combatSelectStance6' | 'combatSelectStance7' | 'combatSelectStance8' | 'combatSelectStance9' | 'combatToggleSpeed' | 'combatToggleLog' | 'combatShowStats' | 'combatAutoBattle' | 'combatUseItem' | 'combatCancel' | 'craftingAction1' | 'craftingAction2' | 'craftingAction3' | 'craftingAction4' | 'craftingAction5' | 'craftingAction6' | 'craftingAction7' | 'craftingAction8' | 'craftingAction9' | 'craftingAction10' | 'craftingAction11' | 'craftingAction12' | 'craftingAction13' | 'craftingAction14' | 'craftingAction15' | 'craftingAction16' | 'craftingAction17' | 'craftingAction18' | 'craftingAction19' | 'craftingAction20' | 'craftingAction21' | 'craftingAction22' | 'craftingAction23' | 'craftingAction24' | 'craftingAction25' | 'craftingAction26' | 'craftingAction27' | 'craftingAction28' | 'craftingAction29' | 'craftingAction30' | 'craftingAction31' | 'craftingAction32' | 'craftingAction33' | 'craftingAction34' | 'craftingAction35' | 'craftingAction36' | 'craftingAction37' | 'craftingAction38' | 'craftingAction39' | 'craftingAction40' | 'craftingAction41' | 'craftingAction42' | 'craftingAction43' | 'craftingAction44' | 'craftingAction45' | 'craftingAction46' | 'craftingAction47' | 'craftingAction48' | 'craftingAction49' | 'craftingAction50' | 'dialogChoice1' | 'dialogChoice2' | 'dialogChoice3' | 'dialogChoice4' | 'dialogChoice5' | 'dialogChoice6' | 'dialogChoice7' | 'dialogChoice8' | 'dialogChoice9' | 'gamepadConfirm' | 'gamepadCancel' | 'gamepadUp' | 'gamepadDown' | 'gamepadLeft' | 'gamepadRight';
3
3
  export interface KeybindingDefinition {
4
- action: KeybindingAction;
4
+ action: KeybindingAction | string;
5
5
  category: KeybindingCategory;
6
6
  displayName: string;
7
7
  description: string;
8
8
  defaultKey: string;
9
9
  allowRebind: boolean;
10
+ modName?: string;
10
11
  }
11
12
  export type KeybindingsMap = Record<KeybindingAction | string, string>;
13
+ export interface RegisteredKeybind {
14
+ displayText: string;
15
+ code: string;
16
+ ctrlKey: boolean;
17
+ altKey: boolean;
18
+ shiftKey: boolean;
19
+ }
12
20
  export declare const keybindingDefinitions: KeybindingDefinition[];
13
21
  export declare const keybindingCategoryInfo: Record<KeybindingCategory, {
14
22
  name: string;
@@ -34,8 +42,9 @@ export declare function parseKeybindingString(keybinding: string | undefined | n
34
42
  shift: boolean;
35
43
  };
36
44
  export declare function matchesKeybinding(event: KeyboardEvent, keybinding: string): boolean;
37
- export declare function getKeyDisplayName(keybinding: string | undefined | null): string;
38
- export declare function getKeyShortDisplayName(keybinding: string | undefined | null): string;
45
+ export declare function matchKeybinding(event: KeyboardEvent, keybind: RegisteredKeybind): boolean;
46
+ export declare function getKeyDisplayName(keybinding: string | RegisteredKeybind | undefined | null): string;
47
+ export declare function getKeyShortDisplayName(keybinding: string | RegisteredKeybind | undefined | null): string;
39
48
  export declare function isModifierKey(key: string): boolean;
40
49
  export declare function isKeyAllowed(key: string): boolean;
41
50
  export declare function getKeybindingsByCategory(category: KeybindingCategory): KeybindingDefinition[];
@@ -964,6 +964,13 @@ export function matchesKeybinding(event, keybinding) {
964
964
  event.altKey === parsed.alt &&
965
965
  event.shiftKey === parsed.shift);
966
966
  }
967
+ // Check if a keyboard event matches a registered keybind
968
+ export function matchKeybinding(event, keybind) {
969
+ return (event.code === keybind.code &&
970
+ event.ctrlKey === keybind.ctrlKey &&
971
+ event.altKey === keybind.altKey &&
972
+ event.shiftKey === keybind.shiftKey);
973
+ }
967
974
  const singleKeyDisplayNames = {
968
975
  Enter: 'Enter',
969
976
  Escape: 'Esc',
@@ -986,9 +993,10 @@ const singleKeyDisplayNames = {
986
993
  // Helper to get display name for a key (full version)
987
994
  export function getKeyDisplayName(keybinding) {
988
995
  var _a;
989
- if (!keybinding)
996
+ const displayText = typeof keybinding === 'object' && keybinding !== null ? keybinding.displayText : keybinding;
997
+ if (!displayText)
990
998
  return '';
991
- const parsed = parseKeybindingString(keybinding);
999
+ const parsed = parseKeybindingString(displayText);
992
1000
  let result = '';
993
1001
  if (parsed.ctrl)
994
1002
  result += 'Ctrl+';
@@ -1002,9 +1010,10 @@ export function getKeyDisplayName(keybinding) {
1002
1010
  // Helper to get short display name for a key (compact version for UI previews)
1003
1011
  export function getKeyShortDisplayName(keybinding) {
1004
1012
  var _a;
1005
- if (!keybinding)
1013
+ const displayText = typeof keybinding === 'object' && keybinding !== null ? keybinding.displayText : keybinding;
1014
+ if (!displayText)
1006
1015
  return '';
1007
- const parsed = parseKeybindingString(keybinding);
1016
+ const parsed = parseKeybindingString(displayText);
1008
1017
  let result = '';
1009
1018
  if (parsed.ctrl)
1010
1019
  result += 'C+';
package/dist/mod.d.ts CHANGED
@@ -47,7 +47,7 @@ import type { DamageType } from './DamageType';
47
47
  import { AvatarEffectShader } from './avatarEffects';
48
48
  import type { Translatable, TranslatableString } from './translatable';
49
49
  import type { SaveFileInfo } from './electron';
50
- import type { KeybindingDefinition } from './keybindings';
50
+ import type { KeybindingDefinition, RegisteredKeybind } from './keybindings';
51
51
  import { ScreenType } from './GameScreen';
52
52
  export type SkipDialogueMode = 'flash' | 'silent';
53
53
  export type Sexuality = 'straight' | 'gay' | 'bisexual';
@@ -73,6 +73,19 @@ export interface GameSettingsProps {
73
73
  eventHistoryLimit: number;
74
74
  setEventHistoryLimit: (value: number) => void;
75
75
  }
76
+ export type InjectPosition = 'before' | 'after';
77
+ export interface NewGameIntent {
78
+ items: ItemDesc[];
79
+ techniques: string[];
80
+ recipes: string[];
81
+ destinies: string[];
82
+ quests: string[];
83
+ money: number;
84
+ favour: number;
85
+ flags: Record<string, number>;
86
+ player: PlayerEntity;
87
+ craftingActions: string[];
88
+ }
76
89
  /**
77
90
  * Sprite images for a custom player character.
78
91
  * All images should be strings (either mod:// URLs for mod assets, or data: URLs).
@@ -353,8 +366,6 @@ export interface ModReduxAPI {
353
366
  TooltipLine: TooltipLineFC;
354
367
  };
355
368
  utils: {
356
- hasSave: () => boolean;
357
- getCurrentState: () => RootState | null;
358
369
  parseTooltipLine: (tooltip: string) => React.ReactNode;
359
370
  expandTooltipTemplate: (template: string, templateValues: Map<string, string>, addPeriod?: boolean) => string;
360
371
  expandTooltipTags: (template: string) => string;
@@ -2051,14 +2062,22 @@ export interface ModAPI {
2051
2062
  * Use this to check what key is currently bound to an action, useful for
2052
2063
  * displaying key hints in custom UI or handling key events outside React components.
2053
2064
  * @param action - The action name (e.g., 'myMod.specialAction')
2054
- * @returns The current bound key string (e.g., 'F12'), or undefined if not bound
2065
+ * @returns The keybind info including displayText (e.g., 'Shift+F12'), code (e.g., 'F12'),
2066
+ * and modifier booleans (ctrlKey, altKey, shiftKey), or undefined if not bound
2055
2067
  * @example
2056
2068
  * const key = modAPI.utils.getRegisteredKeybindValue('myMod.specialAction');
2057
2069
  * if (key) {
2058
- * console.log(`Special action is bound to ${key}`);
2070
+ * console.log(`Special action is bound to ${key.displayText}`);
2071
+ * // Match against KeyboardEvent:
2072
+ * // if (event.code === key.code && event.shiftKey === key.shiftKey) { ... }
2059
2073
  * }
2060
2074
  */
2061
- getRegisteredKeybindValue: (action: string) => string | undefined;
2075
+ getRegisteredKeybindValue: (action: string) => RegisteredKeybind | undefined;
2076
+ /**
2077
+ *
2078
+ * @returns true if a save is currently loaded and game state is available, false otherwise.
2079
+ */
2080
+ getHasSaveLoaded: () => boolean;
2062
2081
  };
2063
2082
  hooks: {
2064
2083
  /**
@@ -2351,45 +2370,46 @@ export interface ModAPI {
2351
2370
  * return payload;
2352
2371
  * });
2353
2372
  */
2354
- onReduxActionPayload: (interceptor: (actionType: string, payload: unknown) => unknown | null) => void;
2373
+ onReduxActionPayload: (interceptor: (actionType: string, payload: unknown, stateBefore: RootState) => unknown | null) => void;
2355
2374
  /**
2356
- * Called before the equipment upgrade dialog is shown. Allows mutating upgrade cost items and result (but not base item).
2375
+ * Called before the equipment upgrade dialog is shown. Allows mutating upgrade cost items and
2376
+ * result item quality tier (but not base item).
2357
2377
  *
2358
2378
  * @example
2359
- * modAPI.hooks.onDeriveEquipmentUpgradeRequirement((baseItem, costItems, resultItem, flags) => {
2360
- * // Modify the cost items (e.g., add additional requirements)
2361
- * return { costItems: [...costItems, additionalItem], resultItem };
2379
+ * modAPI.hooks.onDeriveEquipmentUpgradeRequirement((baseItem, costItems, resultItemName, resultQualityTier, flags) => {
2380
+ * // Override the result quality tier
2381
+ * return { costItems, resultItemName, resultQualityTier: resultQualityTier + 2 };
2362
2382
  * });
2363
2383
  */
2364
- onDeriveEquipmentUpgradeRequirement: (interceptor: (baseItem: Item, costItems: Item[], resultItem: Item, gameFlags: Record<string, number>) => {
2384
+ onDeriveEquipmentUpgradeRequirement: (interceptor: (baseItem: Item, costItems: Item[], resultItemName: string, resultQualityTier: number, gameFlags: Record<string, number>) => {
2365
2385
  costItems?: Item[];
2366
- resultItem?: Item;
2386
+ resultItemName?: string;
2387
+ resultQualityTier?: number;
2367
2388
  } | undefined) => void;
2368
2389
  /**
2369
- * Called before the completion dialog showing the upgraded equipment. Allows mutating upgrade cost items and result (but not base item).
2390
+ * Called when an equipment upgrade completes. Read-only: cannot modify the result item.
2391
+ * Use onDeriveEquipmentUpgradeRequirement to change the result before the upgrade.
2370
2392
  *
2371
2393
  * @example
2372
2394
  * modAPI.hooks.onCompleteEquipmentUpgrade((baseItem, costItems, resultItem, flags) => {
2373
- * // Boost the result item's stats
2374
- * return { costItems, resultItem: { ...resultItem, damage: (resultItem.damage ?? 0) + 10 } };
2395
+ * // React to the upgrade (e.g., trigger a side effect)
2375
2396
  * });
2376
2397
  */
2377
- onCompleteEquipmentUpgrade: (interceptor: (baseItem: Item, costItems: Item[], resultItem: Item, gameFlags: Record<string, number>) => {
2378
- costItems?: Item[];
2379
- resultItem?: Item;
2380
- } | undefined) => void;
2398
+ onCompleteEquipmentUpgrade: (interceptor: (baseItem: Item, costItems: Item[], resultItem: Item, gameFlags: Record<string, number>) => void) => void;
2381
2399
  /**
2382
- * Called before the equipment reforge dialog is shown. Allows mutating reforge cost items and result (but not base item).
2400
+ * Called before the equipment reforge dialog is shown. Allows mutating reforge cost items and
2401
+ * result item quality tier (but not base item).
2383
2402
  *
2384
2403
  * @example
2385
- * modAPI.hooks.onDeriveEquipmentReforgeRequirement((baseItem, costItems, resultItem, flags) => {
2386
- * // Modify the result item
2387
- * return { costItems, resultItem: { ...resultItem, qualityTier: (resultItem.qualityTier ?? 0) + 1 } };
2404
+ * modAPI.hooks.onDeriveEquipmentReforgeRequirement((baseItem, costItems, resultItemName, resultQualityTier, flags) => {
2405
+ * // Override the result quality tier (e.g., set to max)
2406
+ * return { costItems, resultItemName, resultQualityTier: 10 };
2388
2407
  * });
2389
2408
  */
2390
- onDeriveEquipmentReforgeRequirement: (interceptor: (baseItem: Item, costItems: Item[], resultItem: Item, gameFlags: Record<string, number>) => {
2409
+ onDeriveEquipmentReforgeRequirement: (interceptor: (baseItem: Item, costItems: Item[], resultItemName: string, resultQualityTier: number, gameFlags: Record<string, number>) => {
2391
2410
  costItems?: Item[];
2392
- resultItem?: Item;
2411
+ resultItemName?: string;
2412
+ resultQualityTier?: number;
2393
2413
  } | undefined) => void;
2394
2414
  /**
2395
2415
  * Called before the completion dialog showing the reforged equipment. Allows mutating reforge cost items and result (but not base item).
@@ -2404,6 +2424,17 @@ export interface ModAPI {
2404
2424
  costItems?: Item[];
2405
2425
  resultItem?: Item;
2406
2426
  } | undefined) => void;
2427
+ /**
2428
+ * Intercept the full set of changes planned for a new game before they are applied.
2429
+ * Return a modified intent to change starting items, techniques, flags, etc.
2430
+ * @param interceptor - Receives the full intent and returns a modified copy
2431
+ * @example
2432
+ * modAPI.hooks.onNewGame((intent) => ({
2433
+ * ...intent,
2434
+ * flags: { ...intent.flags, my_mod_enabled: 1 },
2435
+ * }));
2436
+ */
2437
+ onNewGame: (interceptor: (intent: NewGameIntent) => NewGameIntent) => void;
2407
2438
  };
2408
2439
  /**
2409
2440
  * Inject UI into a named slot (dialog title or screen name).
@@ -2456,4 +2487,6 @@ export interface ModAPI {
2456
2487
  */
2457
2488
  getGameStateSnapshot: () => RootState | null;
2458
2489
  }
2459
- export type InjectPosition = 'inside' | 'before' | 'after';
2490
+ export type ModHooks = {
2491
+ [K in keyof ModAPI['hooks']]: Parameters<ModAPI['hooks'][K]>[0][];
2492
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "afnm-types",
3
- "version": "0.6.54",
3
+ "version": "0.6.55",
4
4
  "description": "Type definitions for Ascend From Nine Mountains",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,33 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import type { AppDispatch } from '../store';
3
- import type { BreakthroughState } from './breakthrough';
4
- import type { SoundEffectName } from './audio';
5
- import type { Item } from './item';
6
- import type { PlayerEntity } from './entity';
7
- import type { InventoryState } from './reduxState';
8
- interface OpenItem {
9
- item: Item;
10
- data: unknown;
11
- onComplete: () => void;
12
- }
13
- export interface ItemActionContext {
14
- item: Item;
15
- player: PlayerEntity;
16
- inventory: InventoryState;
17
- breakthrough: BreakthroughState;
18
- flags: Record<string, number | string | boolean>;
19
- dispatch: AppDispatch;
20
- setResult: (result: ReactNode) => void;
21
- setClicked: (clicked: boolean) => void;
22
- setOpenItem?: (openItem: OpenItem) => void;
23
- setDoEnchant?: (doEnchant: boolean) => void;
24
- setDoUpgrade?: (doUpgrade: boolean) => void;
25
- setDoAppearanceChange?: (doAppearanceChange: boolean) => void;
26
- playSfx: (sound: SoundEffectName) => void;
27
- usageRestricted: boolean;
28
- }
29
- export interface ItemActionResult {
30
- buttons: ReactNode[];
31
- }
32
- export type ItemActionHandler = (context: ItemActionContext) => ItemActionResult;
33
- export {};
@@ -1 +0,0 @@
1
- export {};
package/dist/manual.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import { Realm } from './realm';
2
- export interface Manual {
3
- name: string;
4
- icon: string;
5
- realm: Realm;
6
- techniques: string[];
7
- stance: string[];
8
- }
package/dist/manual.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,9 +0,0 @@
1
- /**
2
- * Type Tests - These files ensure type compatibility across the codebase
3
- * If any of these fail to compile, it means we have a type mismatch
4
- */
5
- import type { RootState as StoreRootState } from '../store';
6
- import type { RootState as TypesRootState } from './reduxState';
7
- type TestExactMatch = StoreRootState extends TypesRootState ? TypesRootState extends StoreRootState ? true : false : false;
8
- export type RootStateIsConsistent = TestExactMatch;
9
- export {};