afnm-types 0.6.31 → 0.6.34

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' | 'lifeScreen';
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';
@@ -27,9 +27,8 @@ export interface AlternativeStart {
27
27
  */
28
28
  rootEvent: GameEvent;
29
29
  /**
30
- * The starting location name. This becomes the root for location discovery
31
- * (used by discoverUnlockedLocations). All location searches will branch
32
- * from this location.
30
+ * The starting location name. This location will be registered as a root
31
+ * for discovery (if not already) and the player will start here.
33
32
  */
34
33
  startLocation: string;
35
34
  /**
@@ -13,33 +13,22 @@ export interface Position {
13
13
  export interface PositionAndRotation extends Position {
14
14
  rotation: number;
15
15
  }
16
- /** Tracks which of the 6 core essences have been placed in the gate */
17
- export interface EssenceGate {
18
- breath: boolean;
19
- pulse: boolean;
20
- echo: boolean;
21
- growth: boolean;
22
- marrow: boolean;
23
- scar: boolean;
24
- }
25
- /** A lifeform stored in the player's soul realm */
26
- export interface StoredLifeform {
16
+ /** A figment stored in the player's soul realm */
17
+ export interface StoredFigment {
27
18
  id: string;
28
- baseForm: string;
29
- currentForm: string;
30
- slottedEssences: string[];
19
+ primarySpecies?: string;
20
+ secondarySpecies?: string;
21
+ customName?: string;
22
+ autoName?: string;
31
23
  stances: StoredStance[];
32
24
  currentStyle?: StoredStyle;
33
25
  storedStyles?: StoredStyle[];
34
- evolutionPath: string[];
35
26
  }
36
27
  /** State for the Life Flourishing breakthrough system */
37
28
  export interface LifeFlourishingState {
38
- essenceGate: EssenceGate;
39
- storedLifeforms: StoredLifeform[];
40
- manifestedLifeformId?: string;
41
- fightsInstead?: boolean;
42
- creatingNewLifeform?: boolean;
29
+ unlockedSpecies: string[];
30
+ storedFigments: StoredFigment[];
31
+ manifestedFigmentId?: string;
43
32
  }
44
33
  export interface BreakthroughState {
45
34
  mundane?: {
package/dist/buff.d.ts CHANGED
@@ -2,6 +2,7 @@ import { Translatable } from './translatable';
2
2
  import { TechniqueElement } from './element';
3
3
  import { CombatStatistic, Scaling } from './stat';
4
4
  import { DamageType } from './DamageType';
5
+ import type { CombatEntity } from './entity';
5
6
  export type TechniqueCondition = ChanceTechniqueCondition | BuffTechniqueCondition | HpTechniqueCondition | ConditionTechniqueCondition;
6
7
  export type DamageModifier = MultiplyDamageModifier | ReduceDamageModifier | ExpressionDamageModifier;
7
8
  interface MultiplyDamageModifier {
@@ -39,6 +40,7 @@ interface ConditionTechniqueCondition {
39
40
  }
40
41
  export interface Buff {
41
42
  name: string;
43
+ displayName?: Translatable;
42
44
  icon: string;
43
45
  colour?: string;
44
46
  canStack: boolean;
@@ -55,11 +57,10 @@ export interface Buff {
55
57
  charisma?: number;
56
58
  masteryPoints?: number;
57
59
  speed?: number;
58
- applicationStats?: Record<CombatStatistic, number>;
59
- applicationVariables?: Record<string, number>;
60
- appliedByOpponent?: boolean;
60
+ applicationEntity?: CombatEntity;
61
61
  allowMultipleInstances?: boolean;
62
62
  storedVariables?: Record<string, string>;
63
+ storedValues?: Record<string, number>;
63
64
  uniqueId?: string;
64
65
  internalState?: Record<string, number>;
65
66
  initialState?: Record<string, string>;
@@ -195,7 +196,7 @@ export interface FormationCombatImage extends BaseCombatImage {
195
196
  scale?: number;
196
197
  showSingleInstance?: boolean;
197
198
  }
198
- export type BuffEffect = DamageEffect | DamageSelfEffect | HealEffect | BarrierEffect | CreateBuffSelfEffect | ConsumeBuffSelfEffect | CreateBuffTargetEffect | ConsumeBuffTargetEffect | NegateEffect | AddEffect | MultiplyEffect | MergeEffect | TriggerEffect | ModifyBuffGroupEffect | CleanseToxicityEffect | SetStateEffect;
199
+ export type BuffEffect = DamageEffect | DamageSelfEffect | HealEffect | BarrierEffect | CreateBuffSelfEffect | ConsumeBuffSelfEffect | CreateBuffTargetEffect | ConsumeBuffTargetEffect | NegateEffect | AddEffect | MultiplyEffect | MergeEffect | TriggerEffect | ModifyBuffGroupEffect | CleanseToxicityEffect | SetStateEffect | ConvertSelfEffect;
199
200
  interface BaseBuff {
200
201
  condition?: TechniqueCondition;
201
202
  triggerKey?: string;
@@ -290,4 +291,10 @@ interface SetStateEffect extends BaseBuff {
290
291
  value: Scaling;
291
292
  mode?: 'set' | 'add';
292
293
  }
294
+ interface ConvertSelfEffect extends BaseBuff {
295
+ kind: 'convertSelf';
296
+ source: Buff;
297
+ target: Buff;
298
+ amount: Scaling;
299
+ }
293
300
  export {};
@@ -9,4 +9,6 @@ export interface CalendarEvent {
9
9
  location?: string;
10
10
  recurrenceYears: number;
11
11
  realm?: Realm;
12
+ /** If true, event can be re-entered multiple times during its active month */
13
+ reentrant?: boolean;
12
14
  }
@@ -1,5 +1,6 @@
1
1
  import { Realm } from './realm';
2
2
  import { CraftingStatistic, Scaling } from './stat';
3
+ import { Translatable } from './translatable';
3
4
  export type CraftingTechniqueCondition = BuffTechniqueCondition | StateTechniqueCondition | ConditionTechniqueCondition | ChanceTechniqueCondition;
4
5
  interface BuffTechniqueCondition {
5
6
  kind: 'buff';
@@ -23,6 +24,7 @@ interface ChanceTechniqueCondition {
23
24
  export type CraftingBuffDisplayLocation = 'none' | 'avatar' | 'stabilityLeft' | 'stabilityRight' | 'perfectionLeft' | 'perfectionRight' | 'completionLeft' | 'completionRight';
24
25
  export interface CraftingBuff {
25
26
  name: string;
27
+ displayName?: Translatable;
26
28
  icon: string;
27
29
  canStack: boolean;
28
30
  effectHint?: string;
@@ -2,6 +2,7 @@ import { CraftingTechniqueType, CraftingRecipeStats } from './craftingTechnique'
2
2
  import { CraftingCondition } from './crafting';
3
3
  import { CraftingEntity } from './entity';
4
4
  import { RecipeItem, ItemDesc } from './item';
5
+ import type { GameEventState } from './reduxState';
5
6
  export interface ForgeWorksData {
6
7
  heat: number;
7
8
  }
@@ -69,6 +70,12 @@ export interface SuccessCraftingResult {
69
70
  refund: ItemDesc[];
70
71
  }
71
72
  export type CraftingResult = FailedCraftingResult | SuccessCraftingResult;
73
+ export interface CraftingTrainingMode {
74
+ flagKey: string;
75
+ tier: number;
76
+ recipeTypeId: string;
77
+ conditionName?: string;
78
+ }
72
79
  export interface CraftingState {
73
80
  player?: CraftingEntity;
74
81
  recipe?: RecipeItem;
@@ -77,4 +84,7 @@ export interface CraftingState {
77
84
  consumedPills: number;
78
85
  craftingLog: string[];
79
86
  craftResult?: CraftingResult;
87
+ trainingMode?: CraftingTrainingMode;
88
+ /** Snapshot of entire event state when crafting started, restored on completion */
89
+ eventStateSnapshot?: GameEventState;
80
90
  }
@@ -62,6 +62,7 @@ export interface CraftingTechnique {
62
62
  currentCooldown: number;
63
63
  justClicked?: true;
64
64
  mastery?: CraftingTechniqueMastery[];
65
+ masteryKindPools?: CraftingTechniqueEffectKind[];
65
66
  upgradeMasteries?: {
66
67
  [key: string]: CraftingTechniqueMasteryRarityMap;
67
68
  };
@@ -3,8 +3,10 @@ declare const intimateStats: readonly ["satisfaction", "energy", "painThreshold"
3
3
  export type IntimateStat = (typeof intimateStats)[number];
4
4
  declare const intimateResources: readonly ["pain", "harmony", "excitement", "rhythm"];
5
5
  export type IntimateResource = (typeof intimateResources)[number];
6
- declare const intimateTechniqueTypes: string[];
6
+ declare const intimateTechniqueTypes: readonly ["rough", "tender", "passionate"];
7
7
  export type IntimateTechniqueType = (typeof intimateTechniqueTypes)[number];
8
+ export declare const intimateTechniqueTypeToName: Record<IntimateTechniqueType, string>;
9
+ export declare const intimateResourceToName: Record<IntimateResource, string>;
8
10
  export type IntimateTrait = {
9
11
  name: string;
10
12
  description: Translatable;
@@ -1,4 +1,14 @@
1
1
  const intimateStats = ['satisfaction', 'energy', 'painThreshold'];
2
2
  const intimateResources = ['pain', 'harmony', 'excitement', 'rhythm'];
3
3
  const intimateTechniqueTypes = ['rough', 'tender', 'passionate'];
4
- export {};
4
+ export const intimateTechniqueTypeToName = {
5
+ rough: 'Rough',
6
+ tender: 'Tender',
7
+ passionate: 'Passionate',
8
+ };
9
+ export const intimateResourceToName = {
10
+ pain: 'Pain',
11
+ harmony: 'Harmony',
12
+ excitement: 'Excitement',
13
+ rhythm: 'Rhythm',
14
+ };
package/dist/entity.d.ts CHANGED
@@ -79,6 +79,7 @@ export type EnemyDifficulty = 'veryeasy' | 'easy' | 'mediumEasy' | 'medium' | 'm
79
79
  export type BattleLength = 'halfround' | '1round' | 'veryshort' | 'short' | 'medium' | 'long' | 'verylong' | 'verylong+' | 'verylong++' | 'verylong+++' | 'verylong++++';
80
80
  export interface EnemyEntity {
81
81
  name: string;
82
+ displayName?: Translatable;
82
83
  image: string;
83
84
  supportImage?: {
84
85
  image: string;
@@ -227,6 +228,7 @@ export interface CombatArtefact extends ArtefactItem {
227
228
  export interface CombatEntity {
228
229
  entityType: EntityType;
229
230
  name?: string;
231
+ displayName?: Translatable;
230
232
  image: string;
231
233
  supportImage?: {
232
234
  image: string;
package/dist/item.d.ts CHANGED
@@ -14,6 +14,9 @@ import { CombatStatsMap, CraftingStatsMap, PhysicalStatistic, Scaling, SocialSta
14
14
  import { Technique, TechniqueEffect } from './technique';
15
15
  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"];
16
16
  export type ItemKind = (typeof itemKinds)[number];
17
+ export declare const itemKindToName: {
18
+ [key in ItemKind]: string;
19
+ };
17
20
  export type ItemCostMap = {
18
21
  [key in ItemKind]: number;
19
22
  };
@@ -23,6 +26,7 @@ export type Item = TechniqueItem | TechniqueCrystalItem | TechniqueShardItem | T
23
26
  interface ItemBase {
24
27
  kind: ItemKind;
25
28
  name: string;
29
+ displayName?: Translatable;
26
30
  description: Translatable;
27
31
  icon: string;
28
32
  stacks: number;
@@ -157,16 +161,23 @@ export interface ArtefactTechnique {
157
161
  effects: TechniqueEffect[];
158
162
  i?: number;
159
163
  }
160
- export type PillKind = 'combat' | 'crafting' | 'advancement' | 'consumable';
164
+ export type PillKind = 'combat' | 'crafting' | 'advancement' | 'consumable' | 'appearance_change';
165
+ export declare const pillKindToName: {
166
+ [key in PillKind]: string;
167
+ };
161
168
  interface BasePillItem extends ItemBase {
162
169
  kind: 'pill';
163
170
  pillKind: PillKind;
164
171
  }
165
- export type PillItem = CombatPillItem | CraftingPillItem | MiscPillItem | ConsumablePillItem;
172
+ export type PillItem = CombatPillItem | CraftingPillItem | MiscPillItem | ConsumablePillItem | AppearanceChangePillItem;
166
173
  export interface MiscPillItem extends BasePillItem {
167
174
  pillKind: 'advancement';
168
175
  toxicity?: undefined;
169
176
  }
177
+ export interface AppearanceChangePillItem extends BasePillItem {
178
+ pillKind: 'appearance_change';
179
+ toxicity?: undefined;
180
+ }
170
181
  export interface CombatPillItem extends BasePillItem {
171
182
  pillKind: 'combat';
172
183
  toxicity: number;
@@ -249,6 +260,11 @@ export interface MountItem extends ItemBase {
249
260
  masteryPoints?: number;
250
261
  qiAbsorption?: number;
251
262
  customTransform?: string;
263
+ explorationBonus?: number;
264
+ buffs?: {
265
+ buff: Buff;
266
+ buffStacks: Scaling;
267
+ }[];
252
268
  }
253
269
  export interface ElixirItem extends ItemBase {
254
270
  kind: 'elixir';
@@ -319,6 +335,11 @@ export interface MountEnchantment extends Enchantment {
319
335
  speed?: number;
320
336
  masteryPoints?: number;
321
337
  qiAbsorption?: number;
338
+ explorationBonus?: number;
339
+ buffs?: {
340
+ buff: Buff;
341
+ buffStacks: Scaling;
342
+ }[];
322
343
  }
323
344
  export interface RegionMonsters {
324
345
  mob: EnemyEntity[];
@@ -380,6 +401,7 @@ export interface CondensationArtEnchantment extends Enchantment {
380
401
  masteryPoints?: number;
381
402
  speed?: number;
382
403
  restoredDroplets?: number;
404
+ combatStats?: Partial<CombatStatsMap>;
383
405
  }
384
406
  export type FormationKind = 'qiDensity';
385
407
  export type FormationItem = QiDensityFormationItem;
package/dist/item.js CHANGED
@@ -33,6 +33,41 @@ export const itemKinds = [
33
33
  'device',
34
34
  'manual',
35
35
  ];
36
+ export const itemKindToName = {
37
+ clothing: 'Clothing',
38
+ talisman: 'Talisman',
39
+ artefact: 'Artefact',
40
+ mount: 'Mount',
41
+ cauldron: 'Cauldron',
42
+ flame: 'Flame',
43
+ upgrade: 'Upgrade',
44
+ fruit: 'Fruit',
45
+ elixir: 'Elixir',
46
+ recipe: 'Recipe',
47
+ technique: 'Technique',
48
+ action: 'Action',
49
+ transport_seal: 'Transport Seal',
50
+ enchantment: 'Enchantment',
51
+ pill: 'Pill',
52
+ reagent: 'Reagent',
53
+ concoction: 'Concoction',
54
+ consumable: 'Consumable',
55
+ recuperation: 'Recuperation',
56
+ formation: 'Formation',
57
+ breakthrough: 'Breakthrough',
58
+ pillar_shard: 'Pillar Shard',
59
+ material: 'Material',
60
+ flare: 'Flare',
61
+ mystical_key: 'Mystical Key',
62
+ condensation_art: 'Condensation Art',
63
+ blueprint: 'Blueprint',
64
+ trophy: 'Trophy',
65
+ treasure: 'Treasure',
66
+ token: 'Token',
67
+ life_essence: 'Life Essence',
68
+ device: 'Device',
69
+ manual: 'Manual',
70
+ };
36
71
  export const buyItemCostMap = {
37
72
  technique: 3000,
38
73
  artefact: 3500,
@@ -103,3 +138,10 @@ export const sellItemCostMap = {
103
138
  device: 600,
104
139
  manual: 0,
105
140
  };
141
+ export const pillKindToName = {
142
+ combat: 'Combat Pill',
143
+ crafting: 'Crafting Pill',
144
+ advancement: 'Advancement Pill',
145
+ consumable: 'Consumable Pill',
146
+ appearance_change: 'Appearance Change Pill',
147
+ };
package/dist/life.d.ts CHANGED
@@ -2,9 +2,24 @@ import { Buff } from './buff';
2
2
  import { StoredStance, StoredStyle } from './entity';
3
3
  import { Realm } from './realm';
4
4
  import { Technique } from './technique';
5
+ export interface LifeFormAnimationImage {
6
+ image: string;
7
+ scale?: number;
8
+ imageOffset?: {
9
+ x: number;
10
+ y: number;
11
+ };
12
+ }
5
13
  export interface LifeForm {
6
- name: string;
14
+ role: string;
15
+ species: string;
7
16
  image: string;
17
+ supportImage?: LifeFormAnimationImage;
18
+ defensiveImage?: LifeFormAnimationImage;
19
+ utilityImage?: LifeFormAnimationImage;
20
+ aggressiveImage?: LifeFormAnimationImage;
21
+ offensiveImage?: LifeFormAnimationImage;
22
+ hitImage?: LifeFormAnimationImage;
8
23
  realm: Realm;
9
24
  buffs: Buff[];
10
25
  techniques: Technique[];
@@ -36,6 +36,27 @@ export interface GameLocation {
36
36
  realmProgress?: RealmProgress;
37
37
  reputationName?: string;
38
38
  }
39
+ /**
40
+ * A root location that serves as an entry point for location discovery.
41
+ * The map system discovers all locations reachable from root locations whose
42
+ * conditions are met.
43
+ *
44
+ * Root locations that are not connected to other roots by paths can only be
45
+ * traveled to via transport seals or event steps (useful for secret/hidden areas).
46
+ *
47
+ * The main game root (Nine Mountain Sect) uses condition '1' to always be visible.
48
+ * Mod roots can use conditions to only appear after certain events/flags.
49
+ */
50
+ export interface RootLocation {
51
+ /** The name of the location to use as a discovery root (must exist in locationMap) */
52
+ locationName: string;
53
+ /**
54
+ * Condition expression that determines when this root becomes active.
55
+ * Uses the same expression syntax as other conditions (e.g., "questFlag == 1").
56
+ * Use '1' for roots that should always be discovered.
57
+ */
58
+ condition: string;
59
+ }
39
60
  interface LinkBase {
40
61
  location: GameLocation;
41
62
  distance: number;
@@ -86,8 +107,8 @@ export interface CraftingMission {
86
107
  condition: string;
87
108
  }
88
109
  export declare const exploresPerUnlock = 3;
89
- export type BuildingType = 'cultivation' | 'manual' | 'crafting' | 'mission' | 'craftingHall' | 'healer' | 'market' | 'favourExchange' | 'vault' | 'custom' | 'herbField' | 'mine' | 'recipe' | 'requestBoard' | 'compendium' | 'mysticalRegion' | 'trainingGround' | 'library' | 'house' | 'altar' | 'research' | 'reforge' | 'guild' | 'modBuilding';
90
- 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 | ModBuilding;
110
+ export type BuildingType = 'cultivation' | 'manual' | 'crafting' | 'mission' | 'craftingHall' | 'healer' | 'market' | 'favourExchange' | 'vault' | 'custom' | 'herbField' | 'mine' | 'recipe' | 'requestBoard' | 'compendium' | 'mysticalRegion' | 'trainingGround' | 'library' | 'house' | 'altar' | 'research' | 'reforge' | 'guild' | 'tenThousandFlames' | 'modBuilding';
111
+ 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 | ModBuilding;
91
112
  export type LocationBuildingState = MissionBuildingState | CraftingHallBuildingState | ShopBuildingState | RequestBoardBuildingState | HouseBuildingState | CompressionAltarBuildingState;
92
113
  interface BuildingBase {
93
114
  kind: BuildingType;
@@ -209,10 +230,14 @@ export interface MysticalRegionBuilding extends BuildingBase {
209
230
  export interface TrainingGroundBuilding extends BuildingBase {
210
231
  kind: 'trainingGround';
211
232
  }
233
+ export interface TenThousandFlamesBuilding extends BuildingBase {
234
+ kind: 'tenThousandFlames';
235
+ }
212
236
  export type CustomBuildingPosition = 'top' | 'topleft' | 'topright' | 'belowtop' | 'belowtopleft' | 'belowtopright' | 'middleleft' | 'middle' | 'middleright' | 'bottom' | 'bottomleft' | 'bottomright';
213
237
  export interface CustomBuilding extends BuildingBase {
214
238
  kind: 'custom';
215
239
  name: string;
240
+ displayName?: Translatable;
216
241
  icon: string;
217
242
  position: CustomBuildingPosition;
218
243
  condition: string;
@@ -253,6 +278,7 @@ export interface ModBuilding extends BuildingBase {
253
278
  kind: 'modBuilding';
254
279
  condition?: string;
255
280
  name: string;
281
+ displayName?: Translatable;
256
282
  icon: string;
257
283
  screen: string;
258
284
  position: CustomBuildingPosition;
package/dist/location.js CHANGED
@@ -23,5 +23,6 @@ export const buildingTypeToName = {
23
23
  research: 'Vault of Infinite Reflections',
24
24
  reforge: `Infusion Workshop`,
25
25
  guild: '',
26
+ tenThousandFlames: 'Furnace of Ten Thousand Flames',
26
27
  modBuilding: '',
27
28
  };
package/dist/mine.d.ts CHANGED
@@ -41,10 +41,13 @@ export type MineChamber = OreChamber | EventChamber | RandomDropChamber | Releas
41
41
  interface BaseChamber {
42
42
  icon: string;
43
43
  name: string;
44
+ displayName?: Translatable;
44
45
  description: Translatable;
45
46
  rarity: Rarity;
46
47
  condition: string;
47
48
  isUnique?: boolean;
49
+ /** If set, the chamber is only considered completed for pathing purposes when this game flag is truthy */
50
+ completeFlag?: string;
48
51
  }
49
52
  export interface OreChamber extends BaseChamber {
50
53
  kind: 'ore';
package/dist/mod.d.ts CHANGED
@@ -36,6 +36,40 @@ import { PuppetType } from './trainingGround';
36
36
  import { TechniqueElement } from './element';
37
37
  import { AlternativeStart } from './alternativeStart';
38
38
  import { Tutorial } from './tutorial';
39
+ import { Sex } from './entity';
40
+ /**
41
+ * Sprite images for a custom player character.
42
+ * All images should be strings (either mod:// URLs for mod assets, or data: URLs).
43
+ */
44
+ export interface PlayerSpriteImages {
45
+ /** Base/idle image shown in most UI contexts */
46
+ base: string;
47
+ /** Image shown when using aggressive stance techniques */
48
+ aggressive: string;
49
+ /** Image shown when using defensive stance techniques */
50
+ defensive: string;
51
+ /** Image shown when the player is hit */
52
+ hit: string;
53
+ /** Image shown when using offensive stance techniques */
54
+ offensive: string;
55
+ /** Image shown when using support stance techniques */
56
+ support: string;
57
+ /** Image shown when using utility stance techniques */
58
+ utility: string;
59
+ }
60
+ /**
61
+ * A custom player sprite that can be selected during character creation.
62
+ */
63
+ export interface PlayerSprite {
64
+ /** Unique identifier for this sprite */
65
+ id: string;
66
+ /** Display name shown in character creation */
67
+ name: string;
68
+ /** Which gender this sprite is available for: 'male', 'female', or 'both' */
69
+ gender: Sex | 'both';
70
+ /** The sprite images for different poses/situations */
71
+ sprites: PlayerSpriteImages;
72
+ }
39
73
  export interface ModMetadata {
40
74
  name: string;
41
75
  version: string;
@@ -483,6 +517,25 @@ export interface ModAPI {
483
517
  * linkLocations('Liang Tiao Village', { location: myLocation, distance: 5, condition: "my_unlock_flag" });
484
518
  */
485
519
  linkLocations: (existing: string, link: ConditionalLink | ExplorationLink) => void;
520
+ /**
521
+ * Register a location as a root for discovery.
522
+ * Root locations are entry points for the map discovery system - all locations
523
+ * reachable from a root will be discovered when its condition is met.
524
+ *
525
+ * Use this for secret areas or alternative starting points that aren't
526
+ * connected to the main map by paths. Players can only travel to unconnected
527
+ * roots via transport seals or event teleportation.
528
+ *
529
+ * @param locationName - Name of the location to mark as root (must already exist)
530
+ * @param condition - Condition expression for when this root is active (use '1' for always)
531
+ * @example
532
+ * // Always-active root for an alternative start area
533
+ * registerRootLocation('Hidden Valley', '1');
534
+ *
535
+ * // Conditional root that unlocks after finding a secret
536
+ * registerRootLocation('Ancient Ruins', 'foundAncientMap == 1');
537
+ */
538
+ registerRootLocation: (locationName: string, condition: string) => void;
486
539
  /**
487
540
  * Add buildings to an existing location.
488
541
  * @param location - Location key
@@ -654,6 +707,58 @@ export interface ModAPI {
654
707
  * });
655
708
  */
656
709
  addAlternativeStart: (start: AlternativeStart) => void;
710
+ /**
711
+ * Register a custom player sprite for character creation.
712
+ * Custom sprites will appear in the character creation screen alongside
713
+ * the default sprites for the specified gender.
714
+ * @param sprite - Player sprite configuration with id, name, gender, and all required images
715
+ * @example
716
+ * addPlayerSprite({
717
+ * id: 'myCustomCharacter',
718
+ * name: 'Custom Cultivator',
719
+ * gender: 'male',
720
+ * sprites: {
721
+ * base: baseImage,
722
+ * aggressive: aggressiveImage,
723
+ * defensive: defensiveImage,
724
+ * hit: hitImage,
725
+ * offensive: offensiveImage,
726
+ * support: supportImage,
727
+ * utility: utilityImage,
728
+ * }
729
+ * });
730
+ */
731
+ addPlayerSprite: (sprite: PlayerSprite) => void;
732
+ /**
733
+ * Register translations for a language.
734
+ * If the language already exists (e.g., 'ru'), mod translations will be merged
735
+ * with the base game translations, with mod translations taking precedence.
736
+ * If the language is new, it will be added to the available languages list.
737
+ *
738
+ * @param language - Language code (e.g., 'ru', 'zh', 'es', 'de')
739
+ * @param translations - Translation data in the same format as template.json
740
+ * @example
741
+ * // Add translations for a new language
742
+ * addTranslation('es', {
743
+ * "ui": {
744
+ * "buttons": {
745
+ * "[name] Continue": "Continuar",
746
+ * "[name] Cancel": "Cancelar"
747
+ * }
748
+ * }
749
+ * });
750
+ *
751
+ * // Override/add translations for an existing language
752
+ * addTranslation('ru', {
753
+ * "items": {
754
+ * "myModItem": {
755
+ * "[name] Magic Sword": "Волшебный меч",
756
+ * "[description] A sword imbued with magic.": "Меч, наполненный магией."
757
+ * }
758
+ * }
759
+ * });
760
+ */
761
+ addTranslation: (language: string, translations: Record<string, unknown>) => void;
657
762
  };
658
763
  utils: {
659
764
  /**
package/dist/quest.d.ts CHANGED
@@ -3,6 +3,7 @@ import { EventStep, GameEvent } from './event';
3
3
  import { ItemDesc } from './item';
4
4
  export interface Quest {
5
5
  name: string;
6
+ displayName?: Translatable;
6
7
  description: Translatable;
7
8
  category: 'main' | 'side' | 'missionHall' | 'craftingHall' | 'requestBoard' | 'guild';
8
9
  guild?: string;
@@ -86,6 +86,8 @@ export interface CombatState {
86
86
  flag: string;
87
87
  value: number;
88
88
  };
89
+ /** Snapshot of entire event state when combat started, restored on completion */
90
+ eventStateSnapshot?: GameEventState;
89
91
  }
90
92
  export type CraftingSliceState = ExistingCraftingState;
91
93
  export interface ResetFlag {
@@ -168,6 +170,8 @@ export interface AuctionState {
168
170
  playerItemsSold: AuctionItem[];
169
171
  totalPlayerSales: number;
170
172
  needsPlayerSellSelection: boolean;
173
+ /** Snapshot of entire event state when auction started, restored on completion */
174
+ eventStateSnapshot?: GameEventState;
171
175
  }
172
176
  export interface BreakthroughSliceState extends BreakthroughState {
173
177
  }
@@ -245,6 +249,8 @@ export interface TournamentSliceState {
245
249
  participants?: EnemyEntity[];
246
250
  previousRounds?: TournamentRound[];
247
251
  currentRound?: TournamentRound;
252
+ /** Snapshot of entire event state when tournament started, restored on completion */
253
+ eventStateSnapshot?: GameEventState;
248
254
  }
249
255
  export interface HouseState {
250
256
  inHouse: boolean;
@@ -270,6 +276,8 @@ export interface DualCultivationState {
270
276
  };
271
277
  animations: string[];
272
278
  messages: DualCultivationMessage[];
279
+ /** Snapshot of entire event state when dual cultivation started, restored on completion */
280
+ eventStateSnapshot?: GameEventState;
273
281
  }
274
282
  export interface GuildState {
275
283
  selectedGuild?: string;
@@ -288,6 +296,8 @@ export interface StoneCuttingState {
288
296
  isCutting: boolean;
289
297
  realm: Realm;
290
298
  gainedItems: ItemDesc[];
299
+ /** Snapshot of entire event state when stone cutting started, restored on completion */
300
+ eventStateSnapshot?: GameEventState;
291
301
  }
292
302
  export interface FallenStarState {
293
303
  activeSites: Record<string, FallenStarData>;
@@ -319,12 +329,6 @@ export interface NewGameState {
319
329
  export interface GameDataState {
320
330
  flags: Record<string, number>;
321
331
  mapExploration: Record<string, number>;
322
- /**
323
- * The root location name for location discovery.
324
- * Defaults to "Nine Mountain Sect" if not set.
325
- * Can be changed by alternative starts.
326
- */
327
- discoveryRoot?: string;
328
332
  }
329
333
  export interface HistoryItem {
330
334
  text: string;
@@ -366,6 +370,11 @@ export interface GameEventState {
366
370
  [key: string]: StoredEventState;
367
371
  };
368
372
  analyticsToReport: ReportAnalyticsStep[];
373
+ /**
374
+ * Hash of the event content for "skip seen dialogue" feature.
375
+ * Generated when event starts using hashEventContent().
376
+ */
377
+ eventHash?: string;
369
378
  }
370
379
  export interface RecipeFilters {
371
380
  hideCompleted: boolean;
package/dist/stat.d.ts CHANGED
@@ -3,7 +3,7 @@ import { 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"];
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", "fistResistance", "blossomResistance", "weaponResistance", "cloudResistance", "bloodResistance", "celestialResistance", "damageBoost", "healingBoost", "barrierBoost", "overheal", "barrierBleed"];
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", "fistResistance", "blossomResistance", "weaponResistance", "cloudResistance", "bloodResistance", "celestialResistance", "damageBoost", "healingBoost", "barrierBoost", "overheal", "barrierBleed", "formationPartRecovery"];
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
@@ -85,6 +85,7 @@ export const combatStatistics = [
85
85
  'barrierBoost',
86
86
  'overheal',
87
87
  'barrierBleed',
88
+ 'formationPartRecovery',
88
89
  ];
89
90
  export const baseStatNumber = 10;
90
91
  export const expectedHpPerFlesh = 1000;
@@ -150,6 +151,7 @@ export const combatStatToName = {
150
151
  barrierBoost: 'Barrier Boost',
151
152
  overheal: 'Overheal',
152
153
  barrierBleed: 'Barrier Bleed',
154
+ formationPartRecovery: 'Formation Part Recovery',
153
155
  };
154
156
  export const combatStatToDescription = {
155
157
  maxhp: 'The amount of damage you can take before you are unable to continue.',
@@ -203,6 +205,7 @@ export const combatStatToDescription = {
203
205
  barrierBoost: '',
204
206
  overheal: '',
205
207
  barrierBleed: '',
208
+ formationPartRecovery: '',
206
209
  };
207
210
  // Uncommon stats that need auxiliary tooltips when they appear on buffs
208
211
  // These descriptions only show as aux tooltips in buff tooltips, not in the stats dialog
@@ -211,10 +214,12 @@ export const uncommonStatTooltips = {
211
214
  healingBoost: '<n>Healing Boost</n> increases all healing received by a percentage.',
212
215
  barrierBoost: '<n>Barrier Boost</n> increases all barrier gained by a percentage.',
213
216
  overheal: '<n>Overheal</n> converts a percentage of healing beyond your maximum health into barrier.',
214
- protection: '<n>Protection</n> reduces damage taken to your health. Does not affect damage taken to your barrier.',
217
+ protection: '<n>Protection</n> reduces damage taken to your health with diminishing returns. Does not affect damage taken to your barrier.',
215
218
  weakness: '<n>Weakness</n> reduces your power.',
216
219
  vulnerability: '<n>Vulnerability</n> increases damage taken to your <n>health</n>. Does not affect damage taken to your barrier.',
217
- barrierBleed: '<n>Barrier Bleed</n> causes a percentage of your damage to bypass the enemy barrier and strike their health directly.',
220
+ barrierBleed: '<n>Barrier Bleed</n> causes a percentage of any damage to bypass your barrier and strike your health directly.',
221
+ formationPartRecovery: 'Each point of <n>Formation Part Recovery</n> returns a <n>Formation Part</n> used in combat back to your Spatial Ring after battle.',
222
+ dr: '<n>Damage Resistance</n> reduces damage taken to your health after defense is applied. Each point equals <num>1%</num> reduction. Does not affect damage taken to your barrier.',
218
223
  };
219
224
  export const craftingStatToName = {
220
225
  maxpool: 'Max Qi Pool',
@@ -6,7 +6,7 @@
6
6
  export interface TranslatableString {
7
7
  readonly _translatable: true;
8
8
  readonly key: string;
9
- readonly variables?: Record<string, string | number>;
9
+ readonly variables?: Record<string, Translatable | number>;
10
10
  }
11
11
  /**
12
12
  * A deferred plural translation object. Stores both singular and plural keys
@@ -18,7 +18,7 @@ export interface TranslatablePlural {
18
18
  readonly countVar: string;
19
19
  readonly one: string;
20
20
  readonly other: string;
21
- readonly variables?: Record<string, string | number>;
21
+ readonly variables?: Record<string, Translatable | number>;
22
22
  }
23
23
  /**
24
24
  * A value that can be either a plain string or a deferred translation object.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "afnm-types",
3
- "version": "0.6.31",
3
+ "version": "0.6.34",
4
4
  "description": "Type definitions for Ascend From Nine Mountains",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",