afnm-types 0.6.50 → 0.6.51

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.
@@ -1 +1 @@
1
- export type GameScreen = 'location' | 'recipe' | 'mission' | 'craftingHall' | 'manual' | 'cultivation' | 'map' | 'healer' | 'market' | 'favour' | 'herbField' | 'mine' | 'recipeLibrary' | 'requestBoard' | 'compendium' | 'library' | 'altar' | 'research' | 'reforge' | 'pillarGrid' | 'fallenStar' | 'trainingGround' | 'tenThousandFlames' | 'lifeScreen' | 'soulShardDelve' | 'enchantmentShop';
1
+ export type GameScreen = 'location' | 'recipe' | 'mission' | 'craftingHall' | 'manual' | 'cultivation' | 'map' | 'healer' | 'market' | 'favour' | 'herbField' | 'mine' | 'recipeLibrary' | 'requestBoard' | 'compendium' | 'library' | 'altar' | 'research' | 'reforge' | 'pillarGrid' | 'fallenStar' | 'trainingGround' | 'tenThousandFlames' | 'lifeScreen' | 'soulShardDelve' | 'enchantmentShop' | 'challengeBoard';
@@ -0,0 +1,111 @@
1
+ import { BreakthroughState } from './breakthrough';
2
+ import { PhysicalStatistic } from './stat';
3
+ import { KnownTechnique } from './technique';
4
+ import { StoredStance, StoredStyle } from './entity';
5
+ import { TechniqueElement } from './element';
6
+ import { ItemDesc } from './item';
7
+ /**
8
+ * Optional combat modifiers chosen by the submitter when posting a challenge seal.
9
+ * Applied symmetrically to both sides when the challenge is accepted.
10
+ */
11
+ export interface ChallengeModifiers {
12
+ /** Number of grace period rounds both sides get damage reduction at the start of combat (0 or undefined = no grace period). */
13
+ gracePeriodRounds?: number;
14
+ /** Restrict both sides to a single technique school — all other schools are disabled (null or undefined = no restriction). */
15
+ schoolVow?: TechniqueElement | null;
16
+ /** Disable auto-use items (pills/concoctions) for both sides. */
17
+ disableItems?: boolean;
18
+ /** Disable qi droplets for both sides — techniques with droplet costs cannot be used. */
19
+ disableDroplets?: boolean;
20
+ /** Both sides gain 1 stack of Shadow Sickness at the start of each round. */
21
+ shadowSickness?: boolean;
22
+ }
23
+ export interface SubmittedEquipment {
24
+ clothing: string | ItemDesc | undefined;
25
+ mount: string | ItemDesc | undefined;
26
+ talismans: (string | ItemDesc | undefined)[];
27
+ artefacts: (string | ItemDesc | undefined)[];
28
+ }
29
+ /**
30
+ * Serialisable representation of a player build, ready to send to the server.
31
+ * Stored temporarily in GameEventState.pendingBuildSubmission until dispatched.
32
+ *
33
+ * Stat normalisation:
34
+ * physicalStatRelativeRatios — each stat's share of the player's total
35
+ * physical stat pool (all values sum to 1.0). On the server the NPC
36
+ * rebuild allocates `getExpectedPhysicalStat(realm) × 6` points distributed
37
+ * according to these ratios, so modded absolute values never inflate the NPC.
38
+ */
39
+ export interface NormalizedBuildSubmission {
40
+ /** Game version that produced the submission. */
41
+ version: string;
42
+ /** Stable per-save UUID that identifies the submitting player. */
43
+ playerId: string;
44
+ /** Player-chosen display name for the board entry. */
45
+ displayName: string;
46
+ realm: string;
47
+ realmProgress: string;
48
+ /**
49
+ * Relative distribution of physical stats. Each value is the fraction of
50
+ * the player's *total* physical stat pool allocated to that stat
51
+ * (values sum to 1.0 across all six stats).
52
+ */
53
+ physicalStatRelativeRatios: Record<PhysicalStatistic, number>;
54
+ /** Raw battlesense value. */
55
+ battlesense: number;
56
+ /** All techniques known by the player at time of submission. */
57
+ knownTechniques: KnownTechnique[];
58
+ /** The active style at time of submission, or null. */
59
+ currentStyle: StoredStyle | null;
60
+ /** Equipment item names at time of submission. */
61
+ equipment: SubmittedEquipment;
62
+ submittedAt: string;
63
+ /** Player sex — used to select the appropriate default NPC sprite when images are not yet approved. */
64
+ sex?: string;
65
+ /**
66
+ * Portrait index into the player sprite array for this sex.
67
+ * Indices < MALE/FEMALE_BUILT_IN_COUNT refer to base-game portraits and are
68
+ * used directly at roster load time. Indices >= the built-in count indicate a
69
+ * mod sprite; these are serialised to base64 and sent through the custom image
70
+ * approval flow the same way user-uploaded images are.
71
+ */
72
+ imageIndex: number;
73
+ /** Background IDs — resolved via backgroundMap at roster load time. */
74
+ background: string[];
75
+ /** Destiny IDs — resolved via destiniesMap for combat stat bonuses. */
76
+ destiny?: string[];
77
+ /** Names of consumed stat pills — resolved via itemMap for permanent rawStats bonuses. */
78
+ consumedStatPills?: string[];
79
+ /** Full breakthrough state — used for condensation art, pillar shards, figments, etc. */
80
+ breakthrough: BreakthroughState;
81
+ /** Technique affinities — used to apply the player's affinity multipliers in combat. */
82
+ affinities?: Partial<Record<string, number>>;
83
+ /** Pills per round from socialStats — applied directly to the combat entity. */
84
+ pillsPerRound?: number;
85
+ /** Qi droplets at time of submission — applied directly to the combat entity. */
86
+ qiDroplets?: number;
87
+ /**
88
+ * Custom combat image filenames (locally stored, not base64).
89
+ * Resolved to base64 before submission by the useBuildSubmission hook.
90
+ */
91
+ customImages?: {
92
+ idle?: string;
93
+ hit?: string;
94
+ support?: string;
95
+ defensive?: string;
96
+ utility?: string;
97
+ offensive?: string;
98
+ aggressive?: string;
99
+ };
100
+ /** Optional combat modifiers chosen by the submitter — applied symmetrically to both sides. */
101
+ combatModifiers?: ChallengeModifiers;
102
+ /** Manifested figment (lifeform companion) at time of submission — added as a party member during challenge fights. */
103
+ lifeform?: {
104
+ primarySpecies: string;
105
+ secondarySpecies: string;
106
+ /** Display name (custom or auto-generated). */
107
+ name?: string;
108
+ stances: StoredStance[];
109
+ currentStyle?: StoredStyle;
110
+ };
111
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -273,6 +273,13 @@ export interface CharacterEncounter {
273
273
  max: number;
274
274
  };
275
275
  locations?: string[];
276
+ /**
277
+ * Marks this encounter as part of the global pity pool.
278
+ * Works the same way as `pity` on location events: the encounter's selection
279
+ * weight is multiplied by the global pity counter, and a successful pity
280
+ * encounter resets the counter.
281
+ */
282
+ pity?: true;
276
283
  }
277
284
  export type CharacterDefinition = NeutralCharacterDefinition | EnemyCharacterDefinition | CompanionCharacterDefinition;
278
285
  interface BaseCharacterDefinition {
package/dist/element.js CHANGED
@@ -23,7 +23,7 @@ export const elementToTint = {
23
23
  celestial: 'white',
24
24
  cloud: '#45d1d1',
25
25
  blossom: '#ff63dd',
26
- none: 'grey',
26
+ none: 'rgb(73, 73, 73)',
27
27
  };
28
28
  export const elementToColour = {
29
29
  weapon: 'radial-gradient(steelblue 50%, black)',
@@ -32,7 +32,7 @@ export const elementToColour = {
32
32
  celestial: 'radial-gradient(white 30%, black)',
33
33
  cloud: 'radial-gradient(teal 50%, black)',
34
34
  blossom: 'radial-gradient(#d654b9 50%, black)',
35
- none: 'radial-gradient(darkgrey 50%, black)',
35
+ none: 'radial-gradient(rgb(14, 14, 14) 50%, black)',
36
36
  };
37
37
  export const elementToColourRaw = {
38
38
  weapon: 'steelblue',
@@ -41,5 +41,5 @@ export const elementToColourRaw = {
41
41
  celestial: 'white',
42
42
  cloud: 'teal',
43
43
  blossom: '#d654b9',
44
- none: 'darkgrey',
44
+ none: 'rgb(15, 15, 15)',
45
45
  };
package/dist/entity.d.ts CHANGED
@@ -35,6 +35,10 @@ export interface PlayerEntity {
35
35
  utility?: string;
36
36
  offensive?: string;
37
37
  aggressive?: string;
38
+ craftingSupport?: string;
39
+ craftingStabilize?: string;
40
+ craftingRefine?: string;
41
+ craftingFusion?: string;
38
42
  };
39
43
  realm: Realm;
40
44
  realmOverride?: Realm;
@@ -181,6 +185,9 @@ export interface EnemyEntity {
181
185
  phases?: EnemyEntity[];
182
186
  party?: PartyMemberConfig[];
183
187
  preservePartyMembers?: boolean;
188
+ /** When set, stance selection uses the full player-style algorithm instead of stanceRotation/rotationOverrides. */
189
+ playerStyleStances?: StoredStance[];
190
+ playerStyleCycles?: ConditionalCycle[];
184
191
  }
185
192
  export type PartyMemberConfig = EnemyEntity;
186
193
  export interface CombatMessage {
@@ -295,6 +302,13 @@ export interface CombatEntity {
295
302
  usedOverrides: boolean[];
296
303
  usedPills: boolean[];
297
304
  defenseFactor: number;
305
+ /** Tracks per-combat state for enemies using playerStyleStances. Mirrors PlayerStanceData. */
306
+ enemyStanceData?: {
307
+ playerStanceIndex: number;
308
+ usedPlayerStanceOpeners: boolean[];
309
+ lastPlayerStance: string;
310
+ lastCycleKey?: string;
311
+ };
298
312
  battlesenseBonus?: number;
299
313
  spawnRoar?: SoundEffectName;
300
314
  buffs: Buff[];
@@ -315,6 +329,8 @@ export interface CombatEntity {
315
329
  partyId?: string;
316
330
  /** When true, critchance is forced to 0 for this entity (used in training ground) */
317
331
  noCrit?: boolean;
332
+ /** Cached hash for getVariablesFromEntity — cleared whenever stats or buffs mutate */
333
+ _cachedHash?: string;
318
334
  }
319
335
  export type StanceRule = SingleStance | RandomStance;
320
336
  export interface SingleStance {
@@ -15,4 +15,4 @@
15
15
  * };
16
16
  * }
17
17
  */
18
- export declare const GAME_VERSION = "0.6.50";
18
+ export declare const GAME_VERSION = "0.6.51";
@@ -15,4 +15,4 @@
15
15
  * };
16
16
  * }
17
17
  */
18
- export const GAME_VERSION = "0.6.50";
18
+ export const GAME_VERSION = "0.6.51";
package/dist/item.d.ts CHANGED
@@ -13,7 +13,7 @@ import type { Realm, RealmProgress } from './realm';
13
13
  import type { RecipeDifficulty } from './RecipeDifficulty';
14
14
  import type { CombatStatistic, CombatStatsMap, CraftingStatistic, CraftingStatsMap, PhysicalStatistic, Scaling, SocialStatistic } from './stat';
15
15
  import type { Technique, TechniqueEffect } from './technique';
16
- export declare const itemKinds: readonly ["clothing", "talisman", "artefact", "mount", "cauldron", "flame", "upgrade", "fruit", "elixir", "recipe", "technique", "action", "transport_seal", "enchantment", "pill", "reagent", "concoction", "consumable", "recuperation", "formation", "breakthrough", "pillar_shard", "material", "flare", "mystical_key", "condensation_art", "blueprint", "trophy", "treasure", "token", "life_essence", "device", "manual", "pillar_pattern"];
16
+ export declare const itemKinds: readonly ["clothing", "talisman", "artefact", "mount", "cauldron", "flame", "upgrade", "fruit", "elixir", "recipe", "technique", "action", "transport_seal", "enchantment", "pill", "reagent", "concoction", "consumable", "recuperation", "formation", "breakthrough", "pillar_shard", "material", "flare", "mystical_key", "condensation_art", "blueprint", "trophy", "treasure", "token", "life_essence", "device", "manual", "pillar_pattern", "local_map"];
17
17
  export type ItemKind = (typeof itemKinds)[number];
18
18
  export declare const itemKindToName: {
19
19
  [key in ItemKind]: string;
@@ -26,7 +26,7 @@ export type ItemCostMap = {
26
26
  };
27
27
  export declare const buyItemCostMap: ItemCostMap;
28
28
  export declare const sellItemCostMap: ItemCostMap;
29
- export type Item = TechniqueItem | TechniqueCrystalItem | TechniqueShardItem | TechniqueEnhancementDust | TransportSealItem | SpiritFruitItem | RecipeItem | ElixirItem | TreasureItem | CraftingItem | ClothingItem | TalismanItem | ArtefactItem | PillItem | ConcoctionItem | CombatItem | CauldronItem | FlameItem | BreakthroughItem | RecuperationItem | MountItem | FlareItem | CraftingTechniqueItem | EnchantmentItem | MysticalKeyItem | CondensationArtItem | FormationItem | PillarShardItem | TrophyItem | BlueprintItem | TokenItem | UpgradeItem | CraftingReagentItem | LifeEssenceItem | DeviceItem | ManualItem | PillarPatternItem;
29
+ export type Item = TechniqueItem | TechniqueCrystalItem | TechniqueShardItem | TechniqueEnhancementDust | TransportSealItem | SpiritFruitItem | RecipeItem | ElixirItem | TreasureItem | CraftingItem | ClothingItem | TalismanItem | ArtefactItem | PillItem | ConcoctionItem | CombatItem | CauldronItem | FlameItem | BreakthroughItem | RecuperationItem | MountItem | FlareItem | CraftingTechniqueItem | EnchantmentItem | MysticalKeyItem | CondensationArtItem | FormationItem | PillarShardItem | TrophyItem | BlueprintItem | TokenItem | UpgradeItem | CraftingReagentItem | LifeEssenceItem | DeviceItem | ManualItem | PillarPatternItem | LocalMapItem;
30
30
  interface ItemBase {
31
31
  kind: ItemKind;
32
32
  name: string;
@@ -96,6 +96,7 @@ export interface ManualItem extends ItemBase {
96
96
  }
97
97
  export interface ManualStyle {
98
98
  name: string;
99
+ displayName?: Translatable;
99
100
  stances: ManualStance[];
100
101
  }
101
102
  export interface ManualStance {
@@ -528,4 +529,37 @@ export interface PillarPatternItem extends ItemBase {
528
529
  };
529
530
  }[];
530
531
  }
532
+ /** Describes the enemy modifier and reward scaling applied during a local map run. */
533
+ export interface LocalMapModifier {
534
+ /** Display name shown in the UI (e.g. "Bulwark", "Frenzied"). */
535
+ name: string;
536
+ displayName?: Translatable;
537
+ /** Yield multiplier applied to drops and shards. */
538
+ yieldMult: number;
539
+ /** HP stat multiplier bonus added to the enemy's base. */
540
+ hpBonus: number;
541
+ /** Power stat multiplier bonus added to the enemy's base. */
542
+ powerBonus: number;
543
+ /** Pool of buffs to draw from. A random subset is applied to each enemy. */
544
+ buffPool: Buff[];
545
+ /** Minimum number of buffs selected from the pool. */
546
+ minBuffs: number;
547
+ /** Maximum number of buffs selected from the pool. */
548
+ maxBuffs: number;
549
+ }
550
+ export interface LocalMapItem extends ItemBase {
551
+ kind: 'local_map';
552
+ /** The cultivation realm this map applies to (must match the location's realm). */
553
+ realm: Realm;
554
+ /** Number of sequential fights triggered when this map is used. */
555
+ encounterCount: {
556
+ min: number;
557
+ max: number;
558
+ };
559
+ /**
560
+ * If present, enemies are modified and drop rates are scaled.
561
+ * Absent on standard/scout maps — plain fights, no modifiers.
562
+ */
563
+ modifier?: LocalMapModifier;
564
+ }
531
565
  export {};
package/dist/item.js CHANGED
@@ -33,6 +33,7 @@ export const itemKinds = [
33
33
  'device',
34
34
  'manual',
35
35
  'pillar_pattern',
36
+ 'local_map',
36
37
  ];
37
38
  export const itemKindToName = {
38
39
  clothing: 'Clothing',
@@ -69,6 +70,7 @@ export const itemKindToName = {
69
70
  device: 'Device',
70
71
  manual: 'Manual',
71
72
  pillar_pattern: 'Pillar Pattern',
73
+ local_map: 'Local Map',
72
74
  };
73
75
  export const itemKindPluralToName = {
74
76
  clothing: 'Clothing',
@@ -105,6 +107,7 @@ export const itemKindPluralToName = {
105
107
  device: 'Devices',
106
108
  manual: 'Manuals',
107
109
  pillar_pattern: 'Pillar Patterns',
110
+ local_map: 'Local Maps',
108
111
  };
109
112
  export const buyItemCostMap = {
110
113
  technique: 3000,
@@ -141,6 +144,7 @@ export const buyItemCostMap = {
141
144
  device: 2500,
142
145
  manual: 15000,
143
146
  pillar_pattern: 3000,
147
+ local_map: 200,
144
148
  };
145
149
  export const sellItemCostMap = {
146
150
  technique: 400,
@@ -177,6 +181,7 @@ export const sellItemCostMap = {
177
181
  device: 600,
178
182
  manual: 0,
179
183
  pillar_pattern: 500,
184
+ local_map: 20,
180
185
  };
181
186
  export const pillKindToName = {
182
187
  combat: 'Combat Pill',
@@ -38,4 +38,5 @@ export const itemTypeToHarmonyType = {
38
38
  life_essence: 'resonance',
39
39
  manual: 'resonance',
40
40
  pillar_pattern: 'resonance',
41
+ local_map: 'resonance',
41
42
  };
@@ -146,8 +146,8 @@ export interface CraftingMission {
146
146
  condition: string;
147
147
  }
148
148
  export declare const exploresPerUnlock = 3;
149
- export type BuildingType = 'cultivation' | 'manual' | 'crafting' | 'mission' | 'craftingHall' | 'healer' | 'market' | 'favourExchange' | 'vault' | 'custom' | 'herbField' | 'mine' | 'recipe' | 'requestBoard' | 'compendium' | 'mysticalRegion' | 'expedition' | 'trainingGround' | 'library' | 'house' | 'altar' | 'research' | 'reforge' | 'guild' | 'tenThousandFlames' | 'soulShardDelve' | 'enchantmentShop' | 'modBuilding';
150
- export type LocationBuilding = CultivationBuilding | ManualBuilding | CraftingBuilding | MissionBuilding | CraftingHallBuilding | HealerBuilding | MarketBuilding | VaultBuilding | FavourExchangeBuilding | CustomBuilding | HerbFieldBuilding | MineBuilding | RecipeLibraryBuilding | RequestBoardBuilding | CompendiumBuilding | MysticalRegionBuilding | TrainingGroundBuilding | LibraryBuilding | HouseBuilding | CompressionAltarBuilding | ResearchBuilding | ReforgeBuilding | GuildBuilding | TenThousandFlamesBuilding | SoulShardDelveBuilding | EnchantmentShopBuilding | ModBuilding;
149
+ export type BuildingType = 'cultivation' | 'manual' | 'crafting' | 'mission' | 'craftingHall' | 'healer' | 'market' | 'favourExchange' | 'vault' | 'custom' | 'herbField' | 'mine' | 'recipe' | 'requestBoard' | 'compendium' | 'mysticalRegion' | 'expedition' | 'trainingGround' | 'library' | 'house' | 'altar' | 'research' | 'reforge' | 'guild' | 'tenThousandFlames' | 'soulShardDelve' | 'enchantmentShop' | 'challengeBoard' | 'modBuilding';
150
+ export type LocationBuilding = CultivationBuilding | ManualBuilding | CraftingBuilding | MissionBuilding | CraftingHallBuilding | HealerBuilding | MarketBuilding | VaultBuilding | FavourExchangeBuilding | CustomBuilding | HerbFieldBuilding | MineBuilding | RecipeLibraryBuilding | RequestBoardBuilding | CompendiumBuilding | MysticalRegionBuilding | TrainingGroundBuilding | LibraryBuilding | HouseBuilding | CompressionAltarBuilding | ResearchBuilding | ReforgeBuilding | GuildBuilding | TenThousandFlamesBuilding | SoulShardDelveBuilding | EnchantmentShopBuilding | ChallengeBoardBuilding | ModBuilding;
151
151
  export type LocationBuildingState = MissionBuildingState | CraftingHallBuildingState | ShopBuildingState | RequestBoardBuildingState | HouseBuildingState | CompressionAltarBuildingState;
152
152
  interface BuildingBase {
153
153
  kind: BuildingType;
@@ -269,6 +269,9 @@ export interface MysticalRegionBuilding extends BuildingBase {
269
269
  export interface TrainingGroundBuilding extends BuildingBase {
270
270
  kind: 'trainingGround';
271
271
  }
272
+ export interface ChallengeBoardBuilding extends BuildingBase {
273
+ kind: 'challengeBoard';
274
+ }
272
275
  export interface TenThousandFlamesBuilding extends BuildingBase {
273
276
  kind: 'tenThousandFlames';
274
277
  }
package/dist/location.js CHANGED
@@ -27,5 +27,6 @@ export const buildingTypeToName = {
27
27
  tenThousandFlames: 'Furnace of Ten Thousand Flames',
28
28
  soulShardDelve: 'Soul Shard',
29
29
  enchantmentShop: 'Enchantment Shop',
30
+ challengeBoard: 'Challenge Board',
30
31
  modBuilding: '',
31
32
  };
package/dist/mod.d.ts CHANGED
@@ -43,6 +43,7 @@ import type { Tutorial } from './tutorial';
43
43
  import type { Sex } from './entity';
44
44
  import type { DamageType } from './DamageType';
45
45
  import { AvatarEffectShader } from './avatarEffects';
46
+ import type { Translatable, TranslatableString } from '../types/translatable';
46
47
  /**
47
48
  * Sprite images for a custom player character.
48
49
  * All images should be strings (either mod:// URLs for mod assets, or data: URLs).
@@ -1874,6 +1875,42 @@ export interface ModAPI {
1874
1875
  * const bonusStacks = entity.buffs.find(b => b.name === completionBonusBuffName)?.stacks ?? 0;
1875
1876
  */
1876
1877
  completionBonusBuffName: string;
1878
+ /**
1879
+ * Translate a string or translatable value to the current language.
1880
+ * @param value - The string or translatable object to translate
1881
+ * @param variables - Optional variables to substitute in the translation
1882
+ * @param context - Optional context key for disambiguation
1883
+ * @returns The translated string
1884
+ * @example
1885
+ * t('Hello world');
1886
+ * t('You have {count} items', { count: 5 });
1887
+ */
1888
+ t: (value: Translatable, variables?: Record<string, Translatable | number>, context?: string) => string;
1889
+ /**
1890
+ * Translate a string with pluralization support.
1891
+ * @param count - The count to determine singular/plural
1892
+ * @param one - Translation key for count === 1 (singular)
1893
+ * @param other - Translation key for count !== 1 (plural), should use {count} placeholder
1894
+ * @param variables - Additional variables to substitute
1895
+ * @returns The translated string with pluralization applied
1896
+ * @example
1897
+ * tPlural(days, '1 day remaining', '{count} days remaining');
1898
+ */
1899
+ tPlural: (count: number, one: string, other: string, variables?: Record<string, string | number>) => string;
1900
+ /**
1901
+ * Create a deferred translation object. Use this in data definitions instead of t().
1902
+ * The translation is resolved at render time, not at module load time.
1903
+ * @param key - The English text (also serves as the translation key)
1904
+ * @param variables - Optional variables to substitute when resolved
1905
+ * @param context - Optional context key for disambiguation
1906
+ * @returns A TranslatableString object to be resolved later
1907
+ * @example
1908
+ * const item = {
1909
+ * name: 'Spirit Core',
1910
+ * description: tr('A dense crystallisation of pure qi.'),
1911
+ * };
1912
+ */
1913
+ tr: (key: string, variables?: Record<string, Translatable | number>, context?: string) => TranslatableString;
1877
1914
  };
1878
1915
  hooks: {
1879
1916
  /**
@@ -88,6 +88,12 @@ export interface CombatState {
88
88
  };
89
89
  /** Snapshot of entire event state when combat started, restored on completion */
90
90
  eventStateSnapshot?: GameEventState;
91
+ /** Set before a challenge board spar; survives cleanupCombat so the screen can process the result on remount */
92
+ pendingChallengeResult?: {
93
+ enemyName: string;
94
+ buildId: string | null;
95
+ prevWins: number;
96
+ };
91
97
  }
92
98
  export type CraftingSliceState = ExistingCraftingState;
93
99
  export interface ResetFlag {
@@ -318,6 +324,13 @@ export interface FallenStarState {
318
324
  export interface ExpeditionState {
319
325
  activeExpeditionKey?: string;
320
326
  }
327
+ /** A single build entry submitted to the challenge board. */
328
+ export interface SubmittedBuild {
329
+ /** Server-assigned ID for this submission. */
330
+ id: string;
331
+ /** Display name chosen by the player for this board entry. */
332
+ name: string;
333
+ }
321
334
  export interface NewGameState {
322
335
  characterCreated: boolean;
323
336
  forename: string;
@@ -333,6 +346,10 @@ export interface NewGameState {
333
346
  utility?: string;
334
347
  offensive?: string;
335
348
  aggressive?: string;
349
+ craftingSupport?: string;
350
+ craftingStabilize?: string;
351
+ craftingRefine?: string;
352
+ craftingFusion?: string;
336
353
  };
337
354
  birthBackground: Background | undefined;
338
355
  childBackground: Background | undefined;
@@ -340,6 +357,11 @@ export interface NewGameState {
340
357
  createdAt: number;
341
358
  playtime: number;
342
359
  lastPlayed?: number;
360
+ /**
361
+ * Currently submitted challenge builds (up to 9).
362
+ * Each has its own server-assigned ID and player-chosen display name.
363
+ */
364
+ submittedBuilds: SubmittedBuild[];
343
365
  }
344
366
  export interface GameDataState {
345
367
  flags: Record<string, number>;
@@ -410,12 +432,20 @@ export interface RecipeFilters {
410
432
  recipeFilter: string;
411
433
  selectedRecipe: string;
412
434
  pinnedRecipes: string[];
413
- category: 'all' | ItemKind;
435
+ category: 'all' | 'pinned' | 'pinned-upgrades' | ItemKind;
414
436
  realmFilter: 'all' | Realm;
415
437
  }
438
+ export interface PinnedReforgeItem {
439
+ itemName: string;
440
+ qualityTier: number;
441
+ enchantmentKind?: string;
442
+ enchantmentRarity?: string;
443
+ mode: 'upgrade' | 'reforge';
444
+ }
416
445
  export interface CharacterUiPreferencesState {
417
446
  techniqueFilter: string;
418
447
  recipeFilters: RecipeFilters;
448
+ pinnedReforgeItems: PinnedReforgeItem[];
419
449
  }
420
450
  export interface RootState {
421
451
  gameData: GameDataState;
package/dist/stat.d.ts CHANGED
@@ -3,7 +3,7 @@ import type { TechniqueElement } from './element';
3
3
  export declare const physicalStatistics: readonly ["eyes", "meridians", "dantian", "muscles", "digestion", "flesh"];
4
4
  export declare const socialStatistics: readonly ["age", "lifespan", "charisma", "battlesense", "craftskill", "artefactslots", "talismanslots", "condenseEfficiency", "pillsPerRound"];
5
5
  export declare const craftingStatistics: readonly ["maxpool", "pool", "maxtoxicity", "toxicity", "resistance", "itemEffectiveness", "control", "intensity", "critchance", "critmultiplier", "pillsPerRound", "poolCostPercentage", "stabilityCostPercentage", "successChanceBonus", "poolCostFlat"];
6
- export declare const combatStatistics: readonly ["maxhp", "hp", "maxbarrier", "barrier", "maxtoxicity", "toxicity", "resistance", "pillsPerRound", "itemEffectiveness", "power", "artefactpower", "critchance", "defense", "protection", "dr", "barrierMitigation", "lifesteal", "critmultiplier", "vulnerability", "weakness", "fistBoost", "blossomBoost", "weaponBoost", "cloudBoost", "bloodBoost", "celestialBoost", "fistAffinity", "blossomAffinity", "weaponAffinity", "cloudAffinity", "bloodAffinity", "celestialAffinity", "noneAffinity", "qiDroplets", "fistDisabled", "bloodDisabled", "blossomDisabled", "cloudDisabled", "celestialDisabled", "weaponDisabled", "noneDisabled", "fistResistance", "blossomResistance", "weaponResistance", "cloudResistance", "bloodResistance", "celestialResistance", "damageBoost", "healingBoost", "barrierBoost", "overheal", "barrierBleed", "formationPartRecovery", "overcrit"];
6
+ export declare const combatStatistics: readonly ["maxhp", "hp", "maxbarrier", "barrier", "maxtoxicity", "toxicity", "resistance", "pillsPerRound", "itemEffectiveness", "power", "artefactpower", "critchance", "defense", "protection", "dr", "barrierMitigation", "lifesteal", "critmultiplier", "vulnerability", "weakness", "fistBoost", "blossomBoost", "weaponBoost", "cloudBoost", "bloodBoost", "celestialBoost", "fistAffinity", "blossomAffinity", "weaponAffinity", "cloudAffinity", "bloodAffinity", "celestialAffinity", "noneAffinity", "qiDroplets", "fistDisabled", "bloodDisabled", "blossomDisabled", "cloudDisabled", "celestialDisabled", "weaponDisabled", "noneDisabled", "pillsDisabled", "dropletsDisabled", "fistResistance", "blossomResistance", "weaponResistance", "cloudResistance", "bloodResistance", "celestialResistance", "damageBoost", "healingBoost", "barrierBoost", "overheal", "barrierBleed", "formationPartRecovery", "overcrit"];
7
7
  export type PhysicalStatistic = (typeof physicalStatistics)[number];
8
8
  export type SocialStatistic = (typeof socialStatistics)[number];
9
9
  export type CraftingStatistic = (typeof craftingStatistics)[number];
package/dist/stat.js CHANGED
@@ -76,6 +76,8 @@ export const combatStatistics = [
76
76
  'celestialDisabled',
77
77
  'weaponDisabled',
78
78
  'noneDisabled',
79
+ 'pillsDisabled',
80
+ 'dropletsDisabled',
79
81
  'fistResistance',
80
82
  'blossomResistance',
81
83
  'weaponResistance',
@@ -142,6 +144,8 @@ export const combatStatToName = {
142
144
  celestialDisabled: '<n>Celestial</n> techniques are disabled',
143
145
  weaponDisabled: '<n>Weapon</n> techniques are disabled',
144
146
  noneDisabled: '<n>Neutral</n> techniques are disabled',
147
+ pillsDisabled: 'Items are disabled',
148
+ dropletsDisabled: 'Qi Droplets are disabled',
145
149
  pillsPerRound: 'Items Per Round',
146
150
  itemEffectiveness: 'Item Effectiveness',
147
151
  fistResistance: 'Fist Resistance',
@@ -198,6 +202,8 @@ export const combatStatToDescription = {
198
202
  celestialDisabled: '',
199
203
  weaponDisabled: '',
200
204
  noneDisabled: '',
205
+ pillsDisabled: '',
206
+ dropletsDisabled: '',
201
207
  fistResistance: '',
202
208
  blossomResistance: '',
203
209
  weaponResistance: '',
@@ -261,7 +267,7 @@ export const craftingStatToDescription = {
261
267
  critmultiplier: 'The effectiveness of your critical actions.',
262
268
  successChanceBonus: '',
263
269
  itemEffectiveness: 'The effectiveness of your pills and reagents.',
264
- poolCostFlat: 'A flat amount added to the Qi Pool cost of every crafting action.',
270
+ poolCostFlat: '',
265
271
  };
266
272
  export const socialStatToName = {
267
273
  charisma: 'Charisma',
@@ -159,7 +159,7 @@ export interface PermanentStatChangeTechniqueEffect extends BaseTechniqueEffect
159
159
  stat: PhysicalStatistic | SocialStatistic;
160
160
  amount: Scaling;
161
161
  }
162
- export type TechniqueMastery = PowerTechniqueMastery | EffectTechniqueMastery | CritChanceTechniqueMastery | CritMultiplierTechniqueMastery | UpgradeTechniqueMastery;
162
+ export type TechniqueMastery = PowerTechniqueMastery | EffectTechniqueMastery | CritChanceTechniqueMastery | CritMultiplierTechniqueMastery | UpgradeTechniqueMastery | OverwriteEffectsTechniqueMastery;
163
163
  interface BaseTechniqueMastery {
164
164
  condition?: TechniqueCondition;
165
165
  tooltip?: Translatable;
@@ -188,6 +188,11 @@ export interface UpgradeTechniqueMastery extends BaseTechniqueMastery {
188
188
  change: number;
189
189
  shouldMultiply?: boolean;
190
190
  }
191
+ export interface OverwriteEffectsTechniqueMastery extends BaseTechniqueMastery {
192
+ kind: 'overwriteEffects';
193
+ tooltip: Translatable;
194
+ newEffects: TechniqueEffect[];
195
+ }
191
196
  export type TechniqueMasteryRarityMap = {
192
197
  [key in Rarity]: TechniqueMastery | undefined;
193
198
  } & {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "afnm-types",
3
- "version": "0.6.50",
3
+ "version": "0.6.51",
4
4
  "description": "Type definitions for Ascend From Nine Mountains",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",